こんにちは、学部3年ゲーム部VFX班の森口です。
今日はShurikenの設定項目であるCustomVetexStreamsを使ってシェーダーに値を渡す方法を紹介したいと思います。
目次
初めに
今回の記事は技術評論社さんから出版されているUnityゲームエフェクトマスターガイドを主に参考にしており作成するエフェクトの一部にその本で使われているアセットを用いています。そのあたりの説明は本題とは異なるため省略させていただきますのでご了承ください。 この本は非常に参考になる本ですのでエフェクト制作に興味がある方はぜひ購入してみてください。 Unityゲームエフェクトマスターガイドはこちら www.amazon.co.jp
CustomVertexStreamsとは
CustomVetexStreamsとはUnity5.5から追加された機能で簡単に言うとユーザが定義した各パーティクルが持つデータをシェーダーに渡すことができる機能です。
詳しい機能などは公式リファレンスを参照してください。
例えばテクスチャをUVスクロールするようなエフェクトを作ろうとしたときにUVスクロールを実装したシェーダーをそのまま適応するとすべてのパーティクルが同じようにスクロールしてしまいあまり見栄えのいいものではなくなってしまいます。
ブログ用
— グッチー (@guchimoriVR82) August 27, 2019
思ってたのと違うUVスクロールの例 pic.twitter.com/vEPFoxZKBf
そこでCustomVertexStreamsを使うとパーティクルごとに違う値を割り当て、それぞれが違う動きをしてくれるようになります。
ブログ用その2
— グッチー (@guchimoriVR82) August 27, 2019
いい感じになったUVスクロールの例 pic.twitter.com/9VzomQMrI1
今回はこの機能を使って雷のチャージエフェクトを作成していきたいと思います。
CustomVetexStreamsからデータをシェーダーに送る
では実際に実装していきます。
まずはShurikenのRendererモジュールを見てください。そこにCustomVetexStreamsのチェックボックスがありますのでチェックを入れてください。すると項目が増えたかと思います。
おそらく何も設定していない状態ですと上の画像よりも薄いグレーの中の項目が少ないと思います。その中の項目がシェーダーに送られるデータたちです。上の画像にある項目の中で今回主に使うのはCustom1とCustom2の二つになります。
これらの項目は右下にある「+」をクリックしCustom->Custom1(または2).xyzwをクリックすることで追加できます。
これでデータを送る準備はできたのでシェーダー側にうつってどのように受け取るか見ていきましょう。
まずは頂点シェーダーとフラグメントシェーダーに入力として渡す構造体です。
struct appdata {//頂点シェーダーへの入力 float4 vertex : POSITION; float4 uv : TEXCOORD0; fixed4 color : COLOR; float4 custom1 : TEXCOORD1; fixed4 custom2 : TEXCOORD2; }; struct v2f {//フラグメントシェーダーへの入力 float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 uv : TEXCOORD0; float4 custom1 : TEXCOORD1; float4 custom2 : TEXCOORD2; };
custom1、custom2という変数に先ほどのものが入る形になります。
今回はCustom1にUVスクロールのスピードとEmissionを、Custom2にパーティクルのベースカラーにかけ合わせる色情報を持たせています。
次に頂点シェーダーとフラグメントシェーダーです
v2f vert(appdata v){ v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.color = v.color; o.custom1 = v.custom1; o.custom2 = v.custom2; return o; } fixed4 frag(v2f i) : SV_TARGET{ i.uv.y = i.uv.y+_Time.y*i.custom1.y; //y軸方向のUVスクロール fixed4 c = tex2D(_MainTex, i.uv)*i.color*i.custom2*i.custom1.w; //パーティクルの色にcustom2で指定した色を掛けてEmissionを掛けている return c; }
今回はあらかじめ雷用のテクスチャを作成してから使用しているのでy軸方向のUVスクロールのみですがプロシージャルに作成している場合はx軸方向のスクロールも入れることでさらにいい感じになると思います。
できたシェーダーの全体はこちらです
Shader "Custom/Lightning" { Properties { _MainTex ("MainTex", 2D) = "white" {} } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent"} Blend SrcAlpha OneMinusSrcAlpha Cull off LOD 100 Pass{ CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma vertex vert #pragma fragment frag #pragma multi_compile_fog #include "UnityCG.cginc" // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 struct appdata { float4 vertex : POSITION; float4 uv : TEXCOORD0; fixed4 color : COLOR; float4 custom1 : TEXCOORD1; fixed4 custom2 : TEXCOORD2; }; struct v2f{ float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 uv : TEXCOORD0; float4 custom1 : TEXCOORD1; float4 custom2 : TEXCOORD2; }; 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; o.custom1 = v.custom1; o.custom2 = v.custom2; return o; } fixed4 frag(v2f i) : SV_TARGET{ i.uv.y = i.uv.y+_Time.y*i.custom1.y; fixed4 c = tex2D(_MainTex, i.uv)*i.color*i.custom2*i.custom1.w; return c; } ENDCG } } FallBack "Diffuse" }
Shurikenの設定
次にShurikenのほうの設定を行います。Mainモジュールなどは皆さんの好みに変えてくれればと思います。 ちなみに私はこんな感じに設定してます。 特に肝心なのが次の設定項目でRendererモジュールの一つ上にあるCustomDataというモジュールにチェックを入れます。このモジュールに設定した項目が先ほどのCustom1,2に対応しています。なのでここの値を変化させることでパーティクルごとのUVスクロールのスピードを変えたりすることができるわけです。 Custom1はVector形でx~wに値を割り振ってあります。今回はyの値がUVスクロールのy軸方向の速度でwがEmissionの値です(別に割り振りには特に意味はないので自由に割り振ってください)。 今回はスクロールスピードをRandomBetweenTwoCurvesにしているのでかなり速度がばらけるようになっています。 後は先ほど作成したシェーダーから作成したマテリアルを割り当ててRenderModeをMeshにして平面を少しねじったようなメッシュを割り当てて中央のコアを作成すれば完成!
ゲームエフェクトマスターガイドの雷シェーダーをShaderGraphからShaderlabのほうに移植した
— グッチー (@guchimoriVR82) August 27, 2019
CustomVetexStreamsの使い方に戸惑ったけどいい感じに移植できてる希ガス pic.twitter.com/SBAdnKAOfE
最後のほうが少し雑になってしまいましたが使うメッシュはシンプルな長方形でもきれいに見えます。
最後に
いかがだったでしょうか。まだまだシェーダーは勉強中なので今回テクスチャの作成は事前に行いましたがもう少し勉強してより良いエフェクトを作れるようになりたいです。 今回の記事はここまでにしたいと思います。ご覧いただきありがとうございました。