【Unity】頂点カラーアニメーションシェーダー
環境
- Unity 2021.2.11f1
- Build-in Rendering Pipline
はじめに
今回は、Unity で Planeに頂点カラーをつけた後に、
シェーダーで頂点カラーを可視化してアニメーションさせます。

Plane に頂点カラーをつける
以下のコードを Planeに貼り付けると、青から白のグラデーションになるような頂点カラーをセットできます。
public class VertexColor : MonoBehaviour
{
// Start is called before the first frame update
private int _vertexCount;
private Mesh _mesh;
void Start()
{
_mesh = GetComponent<MeshFilter>().sharedMesh;
_vertexCount = _mesh.vertexCount;
var colors = new Color[_vertexCount];
for (int i = 0; i < _mesh.vertexCount; i++)
{
var c = Mathf.InverseLerp(0, _vertexCount, i);
colors[i] = new Color(c, c, 1, 1);
}
_mesh.colors = colors;
}
}
hlsl
vertexCount をメッシュフィルターから取得して、その分カラーを生成しています。
今回は青から白のグラデーションを作りたかったので、 InverseLerp を使用して徐々に c が 1 に近づくようにしています。
シェーダーで頂点カラーを可視化してアニメーションする
頂点カラーを受け取って時間に応じて色を変えてあげるとカラーアニメーションができます。
以下のコードは頂点カラーをただ表示するコードです。
Shader "Custom/VertexColorAnimation"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
};
struct v2f
{
float4 vertex: SV_POSITION;
float4 color: COLOR;
};
void vert(in appdata v, out v2f o)
{
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
}
void frag(in v2f i, out float4 col : SV_Target)
{
col = i.color;
}
ENDCG
}
}
}

頂点シェーダーでは、頂点座標をオブジェクト空間からカメラの空間へ点を変換する処理と頂点カラーをフラグメントシェーダーに渡すということをしています。
フラグメントシェーダーでは、フラグメントシェーダーから受け取った頂点カラーをそのまま出力しています。
アニメーションをさせるには、そのまま出力するのではなく時間に応じて値を変化させます。
以下のようにフラグメントシェーダーを書き換えます。
void frag(in v2f i, out float4 col : SV_Target)
{
col = i.color + abs(_SinTime.z);
}
_SinTime は Unity の組み込み変数です。
レベルがロードされてからの時間をSin 関数の引数にして返ってくる値と同じになります。
_SinTime.z は波長の長さ、つまりアニメーションの速度の指定となります。
(x,y,z,w)から選んで表現に合う速度を選ぶといいと思います。
作ったシェーダーをマテリアル化して、Plane に貼り付ければ完成です。
Table of contents