どーも、ぐるたか@guru_takaです。
VFX Graph で Kyle くんのボクセル化に成功しました。ポイントは各メッシュの頂点におけるキューブに対し、テクスチャのカラーを適用させたことです。
備忘録として、モデルのテクスチャにおけるカラーを VFX Graph でうまく適用させる方法を紹介します!
Point Cache や動的 Position Map で頂点のポジション情報を扱う方法は以下記事を御覧ください!
【Unity】VFX Graph で Point Cache(ポイントキャッシュ)を使い、メッシュをパーティクル化する
- Unity:2020.3.2f1
- Visual Effect Graph:10.4.0
全体像
実は 2021/5/10 時点で、モデルのテクスチャにおけるカラーを VFX Graph でうまく適用するデフォルトの機能はありません。
そのため、以下の手順でモデルのテクスチャから、適切にカラー情報を反映させます。
Position
にセットPosition
からモデルのテクスチャを参照し、カラー適用Position
に対し、Texture2D に保存された ポジション情報に上書き方法については、以下の記事を参考にしています!
参考 VFX Graph の可能性を探る!PointCache動的生成、VAT拡張|fuqunaganote【Unity】VFX Graph で 動的に Attribute Map を生成し、Position Map にセットする方法
VFX Graph のノード構成
VFX Graph のノード構成は下図の通りです。
UVMap
を通じて、UV 値をポジション情報に書き込み、そこからテクスチャのカラー情報を取得。最後に PositionMap
を通じて、正しいポジション情報に書き換えています!
全体のコード
各頂点の UV 値を Texture2D に保存し、VFX Graph の UVMap
渡すコードは以下の通りです。
下記事で紹介している全体のコードに対し、ポジション情報に加えて UV 値も取得しています。基本的なコードは殆ど変わりません。詳細は下記事をチェックしてみてください!
また、差分となる追記コードはコメントしています。
【Unity】VFX Graph で 動的に Attribute Map を生成し、Position Map にセットする方法using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.VFX;
[RequireComponent(typeof(VisualEffect))]
public class BakeMeshToTexture : MonoBehaviour
{
public Texture2D BakedTexture { get; private set; }
private VisualEffect _vfx = null;
private Mesh _mesh = null;
private Color[] _colorBuffer = null;
// 追加
private Color[] _colorUVBuffer = null;
public Texture2D BakedUVTexture { get; private set; }
private void Awake()
{
Initialize();
_vfx = GetComponent();
_vfx.SetTexture($"PositionMap", BakedTexture);
// 追加
_vfx.SetTexture($"UVMap", BakedUVTexture);
}
public void Initialize()
{
_mesh = GetComponent().mesh;
Vector3[] vertices = _mesh.vertices;
int count = vertices.Length;
float r = Mathf.Sqrt(count);
int size = (int)Mathf.Floor(r);
_colorBuffer = new Color[size * size];
BakedTexture = new Texture2D(size, size, TextureFormat.RGBAFloat, false);
BakedTexture.filterMode = FilterMode.Point;
BakedTexture.wrapMode = TextureWrapMode.Clamp;
// 追加
_colorUVBuffer = new Color[size * size];
BakedUVTexture = new Texture2D(size, size, TextureFormat.RGBAFloat, false);
BakedUVTexture.filterMode = FilterMode.Point;
BakedUVTexture.wrapMode = TextureWrapMode.Clamp;
UpdatePositionMap();
// 追加
UpdateUVMap();
}
private void UpdatePositionMap()
{
int idx = 0;
foreach (Vector3 vert in _mesh.vertices.Take(_colorBuffer.Length))
{
_colorBuffer[idx] = VectorToColor(vert);
idx++;
}
BakedTexture.SetPixels(_colorBuffer);
BakedTexture.Apply();
}
// 追加
private void UpdateUVMap()
{
int idx = 0;
foreach (Vector3 uv in _mesh.uv.Take(_colorUVBuffer.Length))
{
_colorUVBuffer[idx] = VectorToColor(uv);
idx++;
}
BakedUVTexture.SetPixels(_colorUVBuffer);
BakedUVTexture.Apply();
}
private Color VectorToColor(Vector3 v)
{
return new Color(v.x, v.y, v.z, 0.0f);
}
}
オブジェクトのインスペクター
あとは下図のように、オブジェクトのインスペクターを設定すれば完成です!
下 GIF のように、Kyle くんがボクセル化すれば成功になります!
最後に
以上です。
モデルのテクスチャにおけるカラーも VFX Graph で扱うことで、より表現の幅が広がるように感じます!
VFX Graph 学習者の参考になれば幸いです
コメントを残す