1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| Shader "Custom/PlanarShadow_Circle" { Properties { _Tint("_Tint", Color) = (1,1,1,1) _MainTex("_MainTex (albedo)", 2D) = "white" {}
[Header(Alpha)] [Toggle(_CLIPPING)] _Clipping ("Alpha Clipping", Float) = 1 _Cutoff("_Cutoff (Alpha Cutoff)", Range(0.0, 1.0)) = 0.5 // alpha clip threshold [Header(Shadow)] // _GroundHeight("_GroundHeight", Range(-100, 100)) = 0 _GroundHeight("_GroundHeight", Float) = 0 _ShadowColor("_ShadowColor", Color) = (0,0,0,1) _ShadowFalloff("_ShadowFalloff", Range(0,1)) = 0.05 _LightDir("_LightDir", Vector) = (4.83,8.61,-5.33,0) _ShadowShowDis("_ShadowShowDis", Float) = 2
// Blending state [HideInInspector] _SrcBlend("__src", Float) = 1.0 [HideInInspector] _DstBlend("__dst", Float) = 0.0 [HideInInspector] _ZWrite("__zw", Float) = 1.0 [HideInInspector] _Cull("__cull", Float) = 2.0 } SubShader { // Planar Shadows平面阴影 Pass { Name "PlanarShadow"
//用使用模板测试以保证alpha显示正确 Stencil { Ref 0 Comp equal Pass incrWrap Fail keep ZFail keep }
Cull Off
//透明混合模式 Blend SrcAlpha OneMinusSrcAlpha
//关闭深度写入 ZWrite off
//深度稍微偏移防止阴影与地面穿插 Offset -1 , 0
HLSLPROGRAM #pragma shader_feature _CLIPPING #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ALPHAPREMULTIPLY_ON
#include "UnityCG.cginc"
#pragma vertex vert #pragma fragment frag float _GroundHeight; float4 _ShadowColor; float4 _LightDir; float _ShadowFalloff; half4 _Tint; sampler2D _MainTex; float4 _MainTex_ST; float _Clipping; half _Cutoff; float _ShadowShowDis;
struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; };
struct v2f { float4 vertex : SV_POSITION; float4 color : COLOR; float2 uv : TEXCOORD0; };
float3 ShadowProjectPos(float4 vertPos) { float3 shadowPos;
//得到顶点的世界空间坐标 float3 worldPos = mul(unity_ObjectToWorld , vertPos).xyz;
//灯光方向 float3 lightDir = normalize(_LightDir.xyz); //float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
//阴影的世界空间坐标(低于地面的部分不做改变) shadowPos.y = min(worldPos .y , _GroundHeight); shadowPos.xz = worldPos .xz - lightDir.xz * max(0 , worldPos .y - _GroundHeight) / lightDir.y;
return shadowPos; }
float GetAlpha (v2f i) { float alpha = _Tint.a * tex2D(_MainTex, i.uv.xy).a; return alpha; }
v2f vert (appdata v) { v2f o;
//得到阴影的世界空间坐标 float3 shadowPos = ShadowProjectPos(v.vertex);
//转换到裁切空间 o.vertex = UnityWorldToClipPos(shadowPos);
//得到中心点世界坐标 float3 center = float3(unity_ObjectToWorld[0].w , _GroundHeight , unity_ObjectToWorld[2].w); //计算阴影衰减 float falloff = 1-saturate(distance(shadowPos , center) * _ShadowFalloff); float edge_distance = distance(shadowPos , center); if(edge_distance > _ShadowShowDis) { o.color.a = 0; } else { //阴影颜色 o.color = _ShadowColor; o.color.a *= falloff; } o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o; }
fixed4 frag (v2f i) : SV_Target { if (_Clipping) { float alpha = GetAlpha(i); i.color.a *= step(_Cutoff, alpha); } return i.color; } ENDHLSL } } }
|