おもちゃラボ

Unityで遊びを作っていきます

【Unityシェーダ入門】20行から始めるUnityミニマルシェーダ

前回は標準のシェーダを使って何が出来るかをひと通り試してみました。

nn-hokuson.hatenablog.com

今回は、一歩立ち戻って、最小限のシェーダをみてみましょう。

最小限のシェーダ

下のプログラムが、不要な要素を全てはぶいた最小限のシェーダです。まずは単純な状態から確認していくほうが分かりやすいと思います。

Shader "Custom/sample" {
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Standard fullforwardshadows
		#pragma target 3.0

		struct Input {
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutputStandard o) {
			o.Albedo = fixed4(1.0f, 1.0f, 1.0f, 1);
		}
		ENDCG
	}
	FallBack "Diffuse"
}

サーフェイスシェーダへの位置づけ

いきなりですが、Tags〜#pragmaまでの行は、前回Settingsパートとして紹介した部分です。ここはおいおい出てきた時に理解するということで、一旦見なかったことにしましょう(笑)

重要なのは struct Input と surf関数の2つです。Unityのサーフェイスシェーダにおいて、surfシェーダの位置づけは次のようになっています。Vertexシェーダから出力された値(Input構造体)を入力に取り、オブジェクトの表面色(SurfaceOutputStandard)を出力します。このSurfaceOutputStandardに対してライティングを行い最終的な絵になります。
 
f:id:nn_hokuson:20170401101047p:plain
 
Input構造体には次のような値をもたせることができます。従来のプログラムとは少し感覚が異なるかもしれませんが、このInput構造体で記述したフィールドだけがサーフェイスシェーダに渡されてきます。

入力変数名 意味
uv_MainTex テクスチャのuv座標
viewDir 視線方向
worldPos ワールド座標
screenPos スクリーン座標

また、Output構造体は次のような値を持っています。

出力変数名 意味
Albedo 基本色
Normal 法線情報

入出力のパラメータには、この他にも幾つかの値が使えます。
詳しくは下記のページを参照して下さい。

docs.unity3d.com

重要なのは、サーフェイスシェーダの後段にUnityが自動生成してくれるライティングの工程があるため、自分でライティングの処理を書く必要がないだけでなく、自動的に影などの計算もしてくれるということです。この関係はしっかりと覚えておいて下さい。

シェーダプログラムの内容

ここでは、特定の色で塗りつぶすだけなので入力としてテクスチャのuv情報(uv_MainTex)は必要はないのですが、Input structの中身が空ではコンパイルが通らないための苦肉の策です。

surf関数がサーフェイスシェーダの肝です。出力用の構造体(SurfaceOutputStandard)がもつAlbedo変数に色情報を指定しています。ここでは全ての入力について白色を指定しています。この後のLightingの工程をへて、最終的な見栄えはつぎのようになります。
 
f:id:nn_hokuson:20160927235054p:plain

シェーダの流れやアルゴリズムに関しては次の本に詳しく解説されています。参考にしてみて下さい。

DirectX 9 シェーダプログラミングブック

DirectX 9 シェーダプログラミングブック