基於SDF的光照效果

基於SDF的光照效果

好久沒寫博客了,怠惰了,就當爬了一步

原神二次元風格面部渲染

效果

Show me the code

Shader "Unlit/SDF"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Texture", 2D) = "white" {}
        _SdfTex ("SdfTex", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            Tags { "LightMode"="ForwardBase" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            float4 _Color;
            sampler2D _MainTex;
            sampler2D _SdfTex;
            float4 _MainTex_ST;
            float4 _SdfTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);

                //SDF
                float4 Left_tex = tex2D(_SdfTex, i.uv);
                float4 Right_tex = tex2D(_SdfTex, float2(1-i.uv.x, i.uv.y));
                float3 lightDir = _WorldSpaceLightPos0.xyz; //光線入射向量
                float3 RightSide = UnityObjectToWorldDir(float4(1.0,0.0,0.0,1.0)); //世界空間下右向量
                float is_right = dot(lightDir.x, RightSide.x); //光線是否在右邊?
                float4 shadow = is_right > 0 ? Right_tex : Left_tex; //採樣的閾值

                float3 forward = UnityObjectToWorldDir(float4(0.0,0.0,1.0,1.0));
                float reflect_val = -0.5 * dot(forward, lightDir) + 0.5; //計算得到的閾值
                float is_shadow = shadow < reflect_val ? 1:0; //比較兩者,判斷是否在陰影內

                float4 halfShadow = 0.5 * is_shadow + 0.5;
                return col * _Color* halfShadow;
            }
            ENDCG
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章