根据三角形相似性计算每个顶点的阴影位置


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
浙公网安备 33010602011771号