本日はShader勉強枠です。
前回実際にShaderの中身を見ていきました。
今回はもっと中身を読み解いてShaderの構造をつかみます。
前回に引き続きShaderサンプルを見ながら勉強しています。
〇Diffuse SimpleShader
Shader "Example/Diffuse Simple" { SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { float4 color : COLOR; }; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = 1; } ENDCG } Fallback "Diffuse" }
〇ShaderLabシンタックスを読み解く
前回UnityのShaderは二つの言語で記述されているといいましたが、サンプルのディフューズShaderのShaderLabシンタックスの部分を抜き取ると以下のようになります。
Shader "Example/Diffuse Simple" { SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM ENDCG } Fallback "Diffuse" }
〇Name
Shader "Example/Diffuse Simple" { }
ここでこのShaderの名前が定義されています。
Unity側見てみると
Exampleの中に
Diffuse Simpleが作成されています。
つまり
Shader "XX/〇〇/▽▽" { }
という名前を付けるとしたらXXというカテゴリーグループのさらに○○というカテゴリーグループに▽▽という名前でShaderが定義されます。
〇SubShader
次にSubShader内部を見ていきます。
SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM ENDCG }
〇Tags
Tags { "RenderType" = "Opaque" }
Tagsではどのようにレンダリング(描画)を行うかを指定します。
以下のように記述することで複数持つことも可能です。
Tags { "TagName1" = "Value1" "TagName2" = "Value2" }
Diffuse SimpleではRenderTypeをOpaque(不透明)にして描画を行うように指定しています。(RGBA(Red Green Blue Alpha)のおそらく透明度を表すA値を無視する設定)
〇CGPROGRAM~ENDCGの中身を見る
#pragma surface surf Lambert struct Input { float4 color : COLOR; }; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = 1; }
〇Pragma構造体
#pragma surface surf Lambert
#pragma文ではどのようにShaderをコンパイル(出力)するかを定義します。
#pragma文は次のように記述します。
pragma surface surfaceFunction lightModel [optionalparams]
Diffuse Sampleではsurfという関数でLambertというライティングモデルを使用します。
ライティングモデルはUnityで提供される光をどのように当てるか計算をする関数です。
surfという関数はその下で定義されています。
void surf (Input IN, inout SurfaceOutput o) { o.Albedo = 1; }
Input から受け取りSurfaceOutputで出力するという形になるようです。
SurcaseOutputというのはUnityのレファレンスによると次のような定義を含んでいるようです
struct SurfaceOutput { fixed3 Albedo; // ディフューズ色 fixed3 Normal; // 書き込まれる場合は、接線空間法線 fixed3 Emission; half Specular; // 0..1 の範囲のスペキュラーパワー fixed Gloss; // スペキュラー強度 fixed Alpha; // 透明度のアルファ };
ここでAlbed(アルベド)は反射光のことで0にすると反射しない=真っ黒になります。
ではInputは?というとsurf関数の直下にあります。
〇Input構造体
struct Input { float4 color : COLOR; };
Input構造体はShaderの処理で必要とされるテクスチャ情報が記述されます。
このディフューズShaderではテクスチャは使用していませんが、テクスチャを使用する場合はテクスチャ情報
ここでは、カラーを指定しています。
Inputで記述したカラーの情報がSurf関数でAlbedo=1として処理されているようです。
〇Fallback
最後にこのShaderがデバイスで実行できなかった場合DiffuseのShaderが代わりに呼ばれます。
以上がサンプルのディフューズShaderになります。
このShaderがディフューズShaderであることを決めているのは
#pragma surface surf Lambert
のライティングモデルであるLambertであるようです。
次回からサンプルに従い勉強しながらこのShaderを変形させていきます。