根据三角形相似性计算每个顶点的阴影位置
Shader "Cg planar shadow" { Properties{ _Color("Object's Color", Color) = (0,1,0,1) _ShadowColor("Shadow's Color", Color) = (0,0,0,1) } SubShader{ Pass{ Tags{ "LightMode" = "ForwardBase" } // rendering of object CGPROGRAM #pragma vertex vert #pragma fragment frag // User-specified properties uniform float4 _Color; float4 vert(float4 vertexPos : POSITION) : SV_POSITION { return mul(UNITY_MATRIX_MVP, vertexPos); } float4 frag(void) : COLOR { return _Color; } ENDCG } Pass{ Tags{ "LightMode" = "ForwardBase" } // rendering of projected shadow Offset -2.0, -2.0 // make sure shadow polygons are on top of shadow receiver CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" uniform float4 _ShadowColor; uniform float4x4 _World2Receiver; // transformation from float4 vert(float4 vertexPos : POSITION) : SV_POSITION{ float4x4 modelMatrix = _Object2World; float4 lightDirection; if (0.0 != _WorldSpaceLightPos0.w){ lightDirection = normalize(mul(modelMatrix, vertexPos - _WorldSpaceLightPos0)); } else{ lightDirection = -normalize(_WorldSpaceLightPos0); } float4 vertexInWorldSpace = mul(modelMatrix, vertexPos); //从矩阵从获取Y轴向量 float4 world2ReceiverRow1 = float4(_World2Receiver[1][0], _World2Receiver[1][1],_World2Receiver[1][2], _World2Receiver[1][3]); //顶点向量到Y轴投影 float distanceOfVertex = dot(world2ReceiverRow1, vertexInWorldSpace); //灯光向量到Y轴的投影 float lengthOfLightDirectionInY = dot(world2ReceiverRow1, lightDirection); if (distanceOfVertex > 0.0 && lengthOfLightDirectionInY < 0.0){ //根据相似三角形定理计算出顶点延伸长度 lightDirection = lightDirection * (distanceOfVertex / (-lengthOfLightDirectionInY)); } else { lightDirection = float4(0,0,0,0); } return mul(UNITY_MATRIX_VP,vertexInWorldSpace + lightDirection); } float4 frag(void) : COLOR{ return _ShadowColor; } ENDCG } } }
参考自:https://en.wikibooks.org/wiki/GLSL_Programming/Unity/Shadows_on_Planes