波打際のブログさん

主に、プログラミング備忘録など。

シェーダー入門したくないけど書いてみたい その6 ライティング編

はじめに

 この記事ではシェーダに関して入門することができません。とりえあずUnityでシェーダを書いて見たい人向けのブログです。

今回はライティングに対応したシェーダを書いてみます。

事前準備

 事前準備が済んでいない方は、第一回目の事前準備の項目を参考に事前準備を行ってください。
シェーダー入門したくないけど書いてみたい その1 - 波打際のブログさん

06.LightingShader

`06.LightingShader/LightingShader.unity` を開いてみてください。今までの演習ではライトが全く影響しないシェーダーでしたが、このシェーダではライトがきちんと反映されて影もレンダリングされています。
f:id:alfa-jpn:20150816184857p:plain

このシェーダは次のように実装されています。

Shader "ShaderLesson/06.LightingShader/Question" {
    SubShader {
        Pass {
            Tags { "RenderType" = "Opaque" "LightMode" = "ForwardBase" }
        
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase

            #include "UnityCG.cginc"
            #include "AutoLight.cginc"

            uniform fixed4 _LightColor0;

            struct v2f {
                float4 pos      : SV_POSITION;
                float3 lightDir : TEXCOORD0;
                float3 normal   : TEXCOORD1;
                LIGHTING_COORDS(3, 4)
            };

            v2f vert(appdata_base v) {
                v2f o;
                
                o.pos      = mul(UNITY_MATRIX_MVP, v.vertex);
                o.lightDir = normalize(ObjSpaceLightDir(v.vertex));
                o.normal   = normalize(v.normal).xyz;

                TRANSFER_VERTEX_TO_FRAGMENT(o);
                TRANSFER_SHADOW(o);

                return o;
            }

            fixed4 frag(v2f i) : SV_Target {
                fixed atten = LIGHT_ATTENUATION(i);
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT;
                fixed4 lightColor = _LightColor0 * saturate(dot(i.lightDir, i.normal));

                fixed4 c = fixed4(1, 0, 0, 1);
                c.rgb = (c * lightColor * atten) + ambient;
                return c;
            }
            ENDCG
        }
    }
    Fallback "Diffuse"
}

このシェーダのポイント

 このシェーダのポイントは、AutoLight.cgincをインクルードしていること、DiffuseをFallbackに指定していることです。

AutoLight.cginc

 ライティングを実装するために必要なモジュールです。このモジュールのおかげでほとんど計算式を書かずにライティングを実装しています。今回使用したマクロは次のとおりです。

LIGHTING_COORDS(a, b)マクロ
 ライティングに必要なメンバをv2f構造体に定義します。引数でメンバをTEXCOORDの何番に格納するか指定し、頂点シェーダからTRANSFER_VERTEX_TO_FRAGMENTマクロとTRANSFER_SHADOWマクロを使用してセットしています。

LIGHT_ATTENUATIONマクロ
 ライトの減衰率を計算します。

Fallback

 このシェーダでは自分自身に対するライトの影響と映り込む影の処理しか実装していません。面倒くさい処理は書きたくないのでFallbackを指定して処理を委託しています。

演習

 ライティングシェーダを書き換えてオブジェクトに映り込む影の色を青色にするシェーダを作ってください。
f:id:alfa-jpn:20150816195718p:plain