8.平面阴影
public class CastShadow : MonoBehaviour {public Transform rec;//接受陰影的物體// Use this for initializationvoid Start () {GetComponent<Renderer>().sharedMaterial.SetMatrix("_World2Ground", rec.GetComponent<Renderer>().worldToLocalMatrix);GetComponent<Renderer>().sharedMaterial.SetMatrix("_Ground2World", rec.GetComponent<Renderer>().localToWorldMatrix);}void Update(){}
}
這個腳本主要是為了設(shè)置需要接受陰影的地面的坐標(biāo)系,如果沒有這個腳本,物體產(chǎn)生的陰影的坐標(biāo)系是原始坐標(biāo)系(0,0,0)
// shader,放在需要顯示陰影的對象上 Shader "Study/8_PlanarShadow" {Properties{_Instensity("Shininess", Range(2, 4)) = 2.1}SubShader{pass {Tags{ "LightMode" = "ForwardBase" }Material{ Diffuse(1,1,1,1) }Lighting On}Pass{Tags{ "LightMode" = "ForwardBase" }Blend DstColor SrcColorOffset -1,-1CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc"float4x4 _World2Ground;float4x4 _Ground2World;float _Instensity;struct v2f {float4 pos:SV_POSITION;float atten : TEXCOORD0;};v2f vert(float4 vertex:POSITION){float3 litDir;litDir = WorldSpaceLightDir(vertex);//世界空間主光照相對于當(dāng)前物體的方向float4 litDir_4 = float4(litDir,0);litDir_4 = mul(_World2Ground, litDir_4);//光源方向轉(zhuǎn)換到接受陰影的平面空間litDir_4 = normalize(litDir_4);// 歸一float4 vt;vt = mul(_Object2World,vertex); //將當(dāng)前物體轉(zhuǎn)換到世界空間vt = mul(_World2Ground,vt); // 將物體在世界空間的矩陣轉(zhuǎn)換到地面空間vt.xz = vt.xz - (vt.y / litDir_4.y)*litDir_4.xz;// 用三角形相似計(jì)算沿光源方向投射后的XZvt.y = 0;// 使陰影保持在接受平面上vt = mul(_Ground2World, vt); // 陰影頂點(diǎn)矩陣返回到世界空間vt = mul(_World2Object, vt); // 返回到物體的坐標(biāo)v2f o;o.pos = mul(UNITY_MATRIX_MVP, vt);//輸出到裁剪空間o.atten = distance(vertex, vt) / _Instensity;// 根據(jù)物體頂點(diǎn)到陰影的距離計(jì)算衰減return o;}float4 frag(v2f i) :COLOR{return smoothstep(0,1,i.atten / 2);}ENDCG}} }
這個shader只是講解下平面陰影的產(chǎn)生原理,核心的原理就是通過三角形相似,根據(jù)光照方向?qū)㈨旤c(diǎn)投影到地面上。
// shader,放在需要顯示陰影的對象上 Shader "Study/8_PlanarShadow" {Properties{_Instensity("Shininess", Range(2, 4)) = 2.1}SubShader{pass {Tags{ "LightMode" = "ForwardBase" }Material{ Diffuse(1,1,1,1) }Lighting On}Pass{Tags{ "LightMode" = "ForwardBase" }Blend DstColor SrcColorOffset -1,-1CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc"float4x4 _World2Ground;float4x4 _Ground2World;float _Instensity;struct v2f {float4 pos:SV_POSITION;float atten : TEXCOORD0;};v2f vert(float4 vertex:POSITION){float3 litDir;litDir = WorldSpaceLightDir(vertex);//世界空間主光照相對于當(dāng)前物體的方向float4 litDir_4 = float4(litDir,0);litDir_4 = mul(_World2Ground, litDir_4);//光源方向轉(zhuǎn)換到接受陰影的平面空間litDir_4 = normalize(litDir_4);// 歸一float4 vt;vt = mul(_Object2World,vertex); //將當(dāng)前物體轉(zhuǎn)換到世界空間vt = mul(_World2Ground,vt); // 將物體在世界空間的矩陣轉(zhuǎn)換到地面空間vt.xz = vt.xz - (vt.y / litDir_4.y)*litDir_4.xz;// 用三角形相似計(jì)算沿光源方向投射后的XZvt.y = 0;// 使陰影保持在接受平面上vt = mul(_Ground2World, vt); // 陰影頂點(diǎn)矩陣返回到世界空間vt = mul(_World2Object, vt); // 返回到物體的坐標(biāo)v2f o;o.pos = mul(UNITY_MATRIX_MVP, vt);//輸出到裁剪空間o.atten = distance(vertex, vt) / _Instensity;// 根據(jù)物體頂點(diǎn)到陰影的距離計(jì)算衰減return o;}float4 frag(v2f i) :COLOR{return smoothstep(0,1,i.atten / 2);}ENDCG}} }
這個shader只是講解下平面陰影的產(chǎn)生原理,核心的原理就是通過三角形相似,根據(jù)光照方向?qū)㈨旤c(diǎn)投影到地面上。
其中第一個Pass是渲染物體本體,第二個Pass渲染陰影。渲染陰影的原理是將坐標(biāo)系轉(zhuǎn)換成接受陰影的地面坐標(biāo)系后,根據(jù)三角形相似,計(jì)算出物體頂點(diǎn)在x方向和z方向的投影坐標(biāo)。
總結(jié)
- 上一篇: 代办大额度信用卡靠谱吗?警惕三个套路远离
- 下一篇: 9.球体阴影