MatCap - saitocastel1900/UnityShader GitHub Wiki

  • ライティング済みテクスチャから、いい感じにサンプリングして、実際はライティングしていないがライティングしているかのように見せる手法のこと

  • 仕組みとしては、法線をもとにサンプリングするテクスチャを選択している。カメラと法線が水平なら手前にあると判断し、テクスチャの中心の色をとる。垂直になるになるにつれて、取る色をずらす感じ

  • しかし、カメラは動くので物体の法線だけだと色がおかしくなる。そのため。カメラが動いたらテクスチャも動かすようにする(ワールド空間からカメラ空間に治すことで、カメラ基準で法線を取得する)

  • mul((float3x3)UNITY_MATRIX_V, normal):ビュー行列(カメラの位置と姿勢を示している)✖️法線で現在のカメラの回転を考慮した法線を取得できる

  • normal * 0.5 + 0.5:法線は-1〜1なので、uvの0〜1に直している

Shader "Unlit/MatCapUnlitShader"
{
    Properties
    {
        _MatCap ("Mat Cap", 2D) = "white" {}
    }

    Subshader
    {
        Tags { "RenderType"="Opaque" }
        
        Pass
        {
            CGPROGRAM
           #include "UnityCG.cginc"
           #pragma vertex vert
           #pragma fragment frag

            sampler2D _MatCap;
                
            struct v2f
            {
                float4 pos  : SV_POSITION;
                half2 uv    : TEXCOORD0;
            };
                
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos (v.vertex);

                float3 normal = mul((float3x3)UNITY_MATRIX_V,UnityObjectToWorldNormal(v.normal));
                o.uv = normal.xy * 0.5 + 0.5;
                
                return o;
            }
                
            float4 frag (v2f i) : COLOR
            {
                return tex2D(_MatCap, i.uv);
            }

            ENDCG
        }
    }
}