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