メッシュの頂点カラーは色の表現にも使えますが,シェーダーの制御データとして利用することもできます.
Blender から頂点カラーを持ってくる
Blenderでメッシュに頂点カラーを付けます.Unityでもできますが,Blenderのほうがやりやすいです.
メッシュデータのプロパティからカラー属性を追加します.データタイプはどちらでも構いません.Blender上で 32bit Float で作成してもUnityにインポートするころには 8bit Fixed に変換されてしまいます.
頂点カラーの設定は普通頂点ペイントモードで行いますが,今回は正確な値を格納したいのでスクリプトを使います.選択している頂点にだけ指定のカラーを設定するようにします.
アルファ値は,Blender内では設定できますが,Fbxエクスポート時に1で固定されます.
import bpy
color = (
1.0 / 255.0,
2.0 / 255.0,
3.0 / 255.0,
1.0
)
currentMode = bpy.context.object.mode
bpy.ops.object.mode_set(mode="OBJECT")
for obj in bpy.context.selected_objects:
mesh = obj.data
vertex_color = mesh.color_attributes[0].data
for c, v in zip(vertex_color, mesh.vertices):
if not v.select: continue
c.color = color
bpy.ops.object.mode_set(mode=currentMode)
頂点カラーの設定が終わったらFbxでエクスポートします.
エクスポート設定で「ジオメトリ > 頂点カラー」を「リニア」に設定します.初期値は「sRGB」で,このままだとガンマ補正後の値でエクスポートされます.
Unity で頂点カラーを利用する
先ほどのFbxをUnityにインポートします.インポート設定はデフォルトで大丈夫です.
頂点カラーを利用するシェーダーを作成します.8bit精度しかないので整数データあるいはフラグとしての利用がメインになると思います.
...
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};
...
v2f vert(appdata v)
{
...
uint3 data = uint3(v.color.xyz * 255);
if (data.x == 0)
{
...
}
else
...
}
...
筆者は基本的に頂点アニメーション制御のために利用しますが,もちろんfragに渡して使うこともできます.
ちなみに,Unity内でスクリプトから頂点カラーを設定する分には 32bit Float で設定できるので,頂点ごとの細かい調整がいらないのであればUnity内で設定するほうがいいです.
雑記
Blenderからのエクスポート時に頂点カラーのアルファ値をゼロ以外の値に設定するアドオンもあるらしく,それを使えばアルファ値まで使えるそうです.また,カラーの精度については,UnityでのFbxのインポート用にカスタムのインポート設定を作成すれば 32bit Float でインポートできるらしいです.ただ,筆者はFbxのデータ構造を知らないのでとりあえず標準機能だけで済ませるようにしています.32bit Float の精度が欲しい場合は2nd以降のUVにデータを格納するようにしています.