Shader "Custom/ImprovedPseudoShadow" { Properties { [Header(Base)] _MainTex ("Texture", 2D) = "white" {} _Color ("Main Color", Color) = (1,1,1,1) [Header(Shadow)] _ShadowColor ("Shadow Color", Color) = (0.2, 0.2, 0.3, 1) // 默认偏蓝的阴影 _ShadowThreshold ("Shadow Threshold", Range(-1,1)) = 0.0 _ShadowSmoothness ("Shadow Smoothness", Range(0,1)) = 0.1 [Header(Lighting Mode)] _UseWorldLight ("Use Fixed World Light?", Range(0,1)) = 0 _FakeLightDir ("Fake Light Dir (XYZ)", Vector) = (0.5, 1, 0.5, 0) // 模拟从右上方来的光 } SubShader { Tags { "RenderType"="Transparent" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // 开启 GPU Instancing 支持 #pragma multi_compile_instancing #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID // Instancing ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float lightFactor : TEXCOORD1; // 传递光照因子 UNITY_VERTEX_INPUT_INSTANCE_ID // Instancing ID }; sampler2D _MainTex; float4 _MainTex_ST; // 声明 Instancing 属性变量 UNITY_INSTANCING_BUFFER_START(Props) UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color) UNITY_DEFINE_INSTANCED_PROP(fixed4, _ShadowColor) UNITY_DEFINE_INSTANCED_PROP(float4, _FakeLightDir) UNITY_DEFINE_INSTANCED_PROP(float, _ShadowThreshold) UNITY_DEFINE_INSTANCED_PROP(float, _ShadowSmoothness) UNITY_DEFINE_INSTANCED_PROP(float, _UseWorldLight) UNITY_INSTANCING_BUFFER_END(Props) v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(o, v); o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); float3 normalWorld = UnityObjectToWorldNormal(v.normal); float3 lightDir; float useWorldLight = UNITY_ACCESS_INSTANCED_PROP(Props, _UseWorldLight); float3 fakeDir = normalize(UNITY_ACCESS_INSTANCED_PROP(Props, _FakeLightDir).xyz); float3 viewDir = normalize(WorldSpaceViewDir(v.vertex)); // 用lerp实现分支 lightDir = normalize(lerp(viewDir, fakeDir, useWorldLight)); float dotProduct = dot(normalWorld, lightDir); o.lightFactor = dotProduct; return o; } fixed4 frag (v2f i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); // 获取属性 fixed4 mainColor = UNITY_ACCESS_INSTANCED_PROP(Props, _Color); fixed4 shadowColor = UNITY_ACCESS_INSTANCED_PROP(Props, _ShadowColor); float threshold = UNITY_ACCESS_INSTANCED_PROP(Props, _ShadowThreshold); float smoothness = UNITY_ACCESS_INSTANCED_PROP(Props, _ShadowSmoothness); fixed4 texCol = tex2D(_MainTex, i.uv) * mainColor; // 改进2:更平滑且可控的阈值计算 (Smoothstep) // lightFactor 越大说明越直接面对光源 float lightIntensity = smoothstep(threshold, threshold + smoothness, i.lightFactor); // 改进3:基于光照强度的颜色插值 (Lerp) // 0 (背光) -> ShadowColor // 1 (受光) -> Texture Color fixed3 finalRGB = lerp(shadowColor.rgb * texCol.rgb, texCol.rgb, lightIntensity); return fixed4(finalRGB, texCol.a); } ENDCG } } FallBack "VertexLit" }