はじめに
SRP
(Scriptable Render Pipeline)にて利用可能なShaderGraph
ですが、標準レンダリングパイプラインでは利用することができません。
私はShaderGraph
からShaderを触り始めた身なのですが、どうしてもSRP
が使えない環境(プロジェクト)もありボチボチコーディングの方の勉強もしています。
今回は簡単な頂点の移動を題材にShaderGraph
と頂点シェーダーの両側面から見ていきたいと思います。
ShaderGraph
まずは実際に作ったノード達はこちら。
ShaderGraph
を触ったことのある方ならすぐ理解できると思いますが、World座標のy座標にSinTime(-1~1)を足し合わせる処理になっています。
ShaderGraphのノードについて
ShaderGraph
のノードの詳細は以下のドキュメントにそれぞれ書かれています。
Combine Node | Shader Graph | 6.9.2
このドキュメントには全てではないですが、ノードをコードに変換したらどのようなコードになるかのサンプルが書かれています。(環境によって言語が異なったりするのでニュアンスとして捉えると良さそう)
例えばCombine
ノードのサンプルコードはこんな感じ。
void Unity_Combine_float(float R, float G, float B, float A, out float4 RGBA, out float3 RGB, out float2 RG) { RGBA = float4(R, G, B, A); RGB = float3(R, G, B); RG = float2(R, G); }
このコードから今回の場合は3つのfloat
を結合してfloat3
に変換していることが分かります。
もし私みたいにShaderGraph
から始めた人はこれを見る癖をつけると、コーディングの上達も早いと思います。
コーディングする
最初に作成したノード達はWorld座標のy座標にSinTimeを足し合わせるという処理です。
これをコードに変換するとこのようになります。
v.vertex += float4(0, _SinTime.w, 0, 0);
_SinTime
というのはShaderLabの定義済みの値で、Time
ノードのSinTime
に該当します。
Unity - マニュアル: ShaderLab 定義済みの値
_SinTime
はfloat4
で、float4(t/8, t/4, t/2, t)
となり_SinTime.w
なら等倍の時間軸で値が遷移します。(-1 ~ 1)
コードにするとかなり短くなりますよね。
コード
ただそのほかもろもろの設定が必要なので、先ほどのコードを組み込んでみましょう。
Shader "Unlit/Test" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { // ここが一番大切なところ v.vertex += float4(0, _SinTime.w, 0, 0); v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } } }
さいごに
このその他諸々が難しいんじゃないかという話だと思いますが、少し前からYoutubeにてシェーダーの仕組みを分かりやすく解説してくれている方がいらっしゃいました。
というか私はこの動画に影響されてコーディングを始めちゃいました。
かなり分かりやすく解説されているのでオススメです。
今回は本当の触りしかしませんでしたが、今後はもっと実用的なものなんかも作れたらと思うので良かったらお付き合いください。
ではまた。