8.平面阴影

来源:互联网 发布:绝对中立知乎 编辑:程序博客网 时间:2024/05/19 22:05
public class CastShadow : MonoBehaviour {    public Transform rec;//接受阴影的物体                         // Use this for initialization    void Start () {        GetComponent<Renderer>().sharedMaterial.SetMatrix("_World2Ground", rec.GetComponent<Renderer>().worldToLocalMatrix);        GetComponent<Renderer>().sharedMaterial.SetMatrix("_Ground2World", rec.GetComponent<Renderer>().localToWorldMatrix);    }    void Update()    {            }}
这个脚本主要是为了设置需要接受阴影的地面的坐标系,如果没有这个脚本,物体产生的阴影的坐标系是原始坐标系(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);//世界空间主光照相对于当前物体的方向float4 litDir_4 = float4(litDir,0);litDir_4 = mul(_World2Ground, litDir_4);//光源方向转换到接受阴影的平面空间litDir_4 = normalize(litDir_4);// 归一float4 vt;vt = mul(_Object2World,vertex); //将当前物体转换到世界空间vt = mul(_World2Ground,vt); // 将物体在世界空间的矩阵转换到地面空间vt.xz = vt.xz - (vt.y / litDir_4.y)*litDir_4.xz;// 用三角形相似计算沿光源方向投射后的XZvt.y = 0;// 使阴影保持在接受平面上vt = mul(_Ground2World, vt); // 阴影顶点矩阵返回到世界空间vt = mul(_World2Object, vt); // 返回到物体的坐标v2f o;o.pos = mul(UNITY_MATRIX_MVP, vt);//输出到裁剪空间o.atten = distance(vertex, vt) / _Instensity;// 根据物体顶点到阴影的距离计算衰减return o;}float4 frag(v2f i) :COLOR{return smoothstep(0,1,i.atten / 2);}ENDCG}}}

这个shader只是讲解下平面阴影的产生原理,核心的原理就是通过三角形相似,根据光照方向将顶点投影到地面上。

其中第一个Pass是渲染物体本体,第二个Pass渲染阴影。渲染阴影的原理是将坐标系转换成接受阴影的地面坐标系后,根据三角形相似,计算出物体顶点在x方向和z方向的投影坐标。


0 0
原创粉丝点击