【Unity】【シェーダ】Particle SystemのCustom Vertex StreamsとCustom Dataの使い方まとめ

Particle SystemのCustom Vertex StreamsとCustom Dataの使い方をまとめました。

Unity2019.4.0

Custom Vertex Streamsとは?

Custom Vertex StreamsはParticle Systemがシェーダに渡す頂点情報を独自に定義できるものです。
Particle SystemのRendererモジュールから設定できます。

例えば以下のようにパーティクルのスピードや、メッシュの頂点IDを渡したりできます。

f:id:halya_11:20200625230650p:plain
Custom Vertex Streams

こうして渡された値を使ってシェーダを書けば、例えばスピードによって大きさを変えたり頂点IDに応じて色を変えたりといったことができます。

Custom Vertex Streamsを実際に使ってみる

それでは実際にCustom Vertex Streamsを使ったパーティクルを作成してみます。

適当なパーティクルを作っておく

まず検証用に適当なパーティクルを作っておきます。

f:id:halya_11:20200625231509g:plain
適当なパーティクル

シェーダを書く

次に頂点情報がParticle Systemから渡されることを前提としたシェーダを書きます。

Shader "Unlit/VertexStreamExample"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Transform" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float4 color : COLOR;
                float2 uv : TEXCOORD0;
                // TEXCOORD1でcolorSourceを受け取るようにする
                float3 colorSource : TEXCOORD1;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 color : Color;
                float2 uv : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.color = v.color;

                // colorSourceの値を使っていい感じに色を変える
                // https://light11.hatenadiary.com/entry/2019/10/26/231903
                float3 oscilateTimes = float3(1.0f, 1.0f, 1.0f);
                float3 phases = float3(0.25f, 0.43f, 0.82f);
                o.color.rgb *= 0.5 + 0.5 * cos(6.28 * (oscilateTimes * v.colorSource + phases.r));

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv) * i.color;
                return col;
            }
            ENDCG
        }
    }
}

今回はTEXCOORD1に渡される値を使っていい感じに色を加工しています。
加工方法の詳細については以下を参照してください。

light11.hatenadiary.com

適用する

シェーダが書けたら先ほどのParticle Systemのマテリアルに適用します。
そしてCustom Vertex Streamsのチェックボックスにチェックを入れ、まずUV2を追加します。

f:id:halya_11:20200625232328p:plain
UV2を追加

今回はTEXCOORD1に値を渡したいのですが、Custom Vertex StreamsはTEXCOORDを順番に埋めていくため、
TEXCOORD1を指定するにはTEXCOORD0を上記のUV2のようなダミーの値で埋めておく必要があります。

UV2でTEXCOORD0を埋めることができたらTEXCOORD1に値を入れていきます。
今回はNoiseSum.xyzを追加してノイズの値を渡すことにしました。

f:id:halya_11:20200625232539p:plain
NoiseSum.xyzを追加

ノイズの値を使うのでNoiseモジュールにもチェックを入れておきます。

f:id:halya_11:20200625232625p:plain
Noiseモジュール

結果

ここまでの設定をすると以下のような結果が得られます。

f:id:halya_11:20200625232933g:plain
結果

ノイズの値がシェーダにうまく渡されて色が変わっていることが確認できました。

Custom Data

さて前節ではノイズモジュールが生成した値を頂点情報として渡しましたが、
自分で定義した値をCustom Vertex Streamsに渡せるCustom Dataという機能があります。

Custom Dataを使うにはまずCustom Vertex SteamsにCustom > Custom1.xyzを追加します。

f:id:halya_11:20200625233555p:plain
Custom1.xyzを追加

そしてCustom Dataモジュールを有効化して、Custom1のxyzを好きなように設定します。
以下のようにカーブなどを指定してLifetimeに応じて変化する値を渡すこともできます。

f:id:halya_11:20200625234023p:plain
Custom Data

これでCustom Dataで定義した値を頂点情報としてシェーダに渡せます。
レンダリング結果は以下のようになります。

f:id:halya_11:20200625234135g:plain
結果2

関連

light11.hatenadiary.com

light11.hatenadiary.com

参考

docs.unity3d.com