Unity Shader投影的问题

时间:2023-02-17   阅读次数:

Shader投影时,除了第一个基础的Pass中要加入有关投影的宏之外,还在需要添加第二个投影的Pass。否则会有穿透的错误效果,如下图右侧球体,除了地表上没有球体的投影外,自身也透过去了。

shader_shadow.png


//基础光照
        Pass
        {
            Tags{"LightMode"="ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal:NORMAL;
                float2 uv : TEXCOORD0;
            };
            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 worldNormal:TEXCOORD0;
                float3 worldPos:TEXCOORD1;
                float2 uv : TEXCOORD2;
                SHADOW_COORDS(3)
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.worldNormal=UnityObjectToWorldNormal(v.vertex);
                o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
                o.uv = v.uv;
                TRANSFER_SHADOW(o)
                return o;
            }

            sampler2D _MainTex;
            float _Gloss;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 N=normalize(i.worldNormal);
                fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
                fixed3 lightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
                fixed3 viewDir=normalize(UnityWorldSpaceViewDir(i.worldPos));
                fixed3 col = tex2D(_MainTex, i.uv).rgb;
                //投影采样
                fixed shadow=SHADOW_ATTENUATION(i);
                fixed3 dif=_LightColor0.rgb*col.rgb*max(0,dot(N,lightDir))*shadow;

                fixed3 halfDir=normalize(lightDir+viewDir);
                fixed3 specular=_LightColor0.rgb*pow(max(0,dot(N,halfDir)),_Gloss);
                
                return fixed4(ambient+dif+specular,1);
            }
            ENDCG
        }
        //投射阴影
        Pass{
            Tags{"LightMode"="ShadowCaster"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_shadowcaster
            #include "UnityCG.cginc"
            struct v2f{
                V2F_SHADOW_CASTER;
            };
            v2f vert(appdata_base v){
                v2f o;
                TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
                return o;
            }
            float4 frag(v2f i):SV_TARGET{
                SHADOW_CASTER_FRAGMENT(i);
            }
            ENDCG
        }

   


其它文章