阴影实现 - 面片阴影BlobShadow
最终效果

1) 两个阴影重叠的时候,基本正常
2) 在斜坡上,阴影穿插了进去
3) 跳起来的时候,阴影跟着一起起来了
4) 在平台边缘,镂空的地方也显示了阴影
using System.Collections.Generic; using UnityEditor; using UnityEngine; public class BlobShadow : MonoBehaviour { public Transform m_Player; public Camera m_Camera; //Player所在的相机, 一般为主相机 public float m_BlobHeightOffset = 0.01f; //面片高度的修正 public float m_BlobHalfSize = 0.5f; //面片一半大小 private Mesh m_ShadowMesh; private Material m_ShadowMat; private List<Vector3> m_QuadVertList = new List<Vector3>(); private List<int> m_QuadTriangleList = new List<int>(); private List<Vector2> m_QuadUVs = new List<Vector2>(); void Awake() { if (null == m_Player) m_Player = this.transform; if (null == m_Camera) m_Camera = Camera.main; } void Start() { CreateBlobShadowMesh(); m_ShadowMat = new Material(Shader.Find("My/Shadow/BlobShadow")); } private void CreateBlobShadowMesh() { m_ShadowMesh = new Mesh(); m_ShadowMesh.name = "BlobShadow"; //m_ShadowMesh.MarkDynamic(); //四边形四个角占位 m_QuadVertList.Add(Vector3.zero); m_QuadVertList.Add(Vector3.zero); m_QuadVertList.Add(Vector3.zero); m_QuadVertList.Add(Vector3.zero); m_ShadowMesh.SetVertices(m_QuadVertList); //映射整张贴图 m_QuadUVs.Add(new Vector2(0, 0)); m_QuadUVs.Add(new Vector2(0, 1)); m_QuadUVs.Add(new Vector2(1, 0)); m_QuadUVs.Add(new Vector2(1, 1)); m_ShadowMesh.SetUVs(0, m_QuadUVs); //顶点绘制顺序 m_QuadTriangleList.Add(0); m_QuadTriangleList.Add(1); m_QuadTriangleList.Add(2); m_QuadTriangleList.Add(2); m_QuadTriangleList.Add(1); m_QuadTriangleList.Add(3); m_ShadowMesh.SetTriangles(m_QuadTriangleList, 0, true); } void Update() { RenderBlobShadow(); } private void RenderBlobShadow() { Vector3 center = m_Player.position; //四个角 m_QuadVertList[0] = center + new Vector3(-m_BlobHalfSize, m_BlobHeightOffset, -m_BlobHalfSize); m_QuadVertList[1] = center + new Vector3(-m_BlobHalfSize, m_BlobHeightOffset, m_BlobHalfSize); m_QuadVertList[2] = center + new Vector3(m_BlobHalfSize, m_BlobHeightOffset, -m_BlobHalfSize); m_QuadVertList[3] = center + new Vector3(m_BlobHalfSize, m_BlobHeightOffset, m_BlobHalfSize); m_ShadowMesh.Clear(true); m_ShadowMesh.SetVertices(m_QuadVertList); m_ShadowMesh.SetUVs(0, m_QuadUVs); m_ShadowMesh.SetTriangles(m_QuadTriangleList, 0, true); Graphics.DrawMesh(m_ShadowMesh, Vector3.zero, Quaternion.identity, m_ShadowMat, 0, m_Camera); //在角色脚底绘制面片 } }
BlobShadow.shader
Shader "My/Shadow/BlobShadow" { Properties { _MainTex("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType" = "Transparent" "Queue" = "Transparent-1"} LOD 100 Pass { Blend Zero SrcColor ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } fixed4 frag(v2f i) : SV_Target { fixed4 c = tex2D(_MainTex, i.uv); return c; } ENDCG } } }
参考
GitHub - xieliujian/UnityDemo_ProjectorShadow: Unity的投影阴影
GitHub - xieliujian/UnityDemo_PlanarShadow: UnityDemo平面阴影

浙公网安备 33010602011771号