源码 / shaders/Ch23/ShadowColor.glsl
shaders/Ch23/ShadowColor.glsl
// 案例 23.6:自定义阴影颜色(GLSL 版)。 // 思路:不再用“阴影 = 光照乘一个 0~1 的系数”,而是在“受光色”和“阴影色”之间插值, // 让被遮挡区域呈现指定的色相(冷色阴影、卡通紫影等),同时保留 URP 的级联、软阴影和距离淡出。 Shader "Cookbook/Ch23/ShadowColor" { SubShader { Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" "Queue"="Geometry" } GLSLINCLUDE uniform vec4 _BaseMap_ST; uniform vec4 _BaseColor; uniform vec4 _ShadowColor; uniform float _AmbientScale; uniform float _TintTerminator; ENDGLSL Pass { Name "ForwardLit" Tags { "LightMode"="UniversalForward" } GLSLPROGRAM uniform sampler2D _BaseMap; VARYING vec2 uv; VARYING vec3 positionWS; VARYING vec3 normalWS; VARYING float fogFactor; #ifdef VERTEX void main() { VertexPositionInputs p = GetVertexPositionInputs(positionOS.xyz); gl_Position = p.positionCS; positionWS = p.positionWS; normalWS = TransformObjectToWorldNormal(normalOS); uv = TransformTex(texcoord0.xy, _BaseMap_ST); fogFactor = ComputeFogFactor(p.positionCS.z); } #endif #ifdef FRAGMENT vec4 frag() { vec3 albedo = texture(_BaseMap, uv).rgb * _BaseColor.rgb; vec3 n = normalize(normalWS); // 逐像素求阴影坐标:同时兼容单级联 / 多级联 / 屏幕空间阴影 vec4 shadowCoord = TransformWorldToShadowCoord(positionWS); // 带 positionWS 的重载会顺带处理“阴影距离淡出”(GetMainLightShadowFade) Light mainLight = GetMainLight(shadowCoord, positionWS, vec4(1, 1, 1, 1)); float NdotL = saturate(dot(n, mainLight.direction)); float shadow = mainLight.shadowAttenuation; // lit:0 = 完全不受光,1 = 完全受光 // _TintTerminator=1 时背光面(NdotL 小)也算“阴影”,整体风格更统一; // _TintTerminator=0 时只给投射阴影上色,明暗交界线保持 Lambert 的自然过渡 float lit = _TintTerminator > 0.5 ? NdotL * shadow : shadow; vec3 shadowTint = mix(vec3(0, 0, 0), _ShadowColor.rgb, _ShadowColor.a); vec3 direct = mix(shadowTint, mainLight.color, lit); if (_TintTerminator < 0.5) direct *= NdotL; // 只染投射阴影时仍需要 N·L vec3 ambient = SampleSH(n) * _AmbientScale; vec3 color = albedo * (direct + ambient); color = MixFog(color, fogFactor); return vec4(color, 1); } void main() { fragColor = frag(); } #endif ENDGLSL } Pass { Name "ShadowCaster" Tags { "LightMode"="ShadowCaster" } ZWrite On ZTest LEqual ColorMask 0 GLSLPROGRAM #define CH23_SHADOW_PASS #include "Ch23/Ch23Common.glsl" ENDGLSL } Pass { Name "DepthOnly" Tags { "LightMode"="DepthOnly" } ZWrite On ColorMask R GLSLPROGRAM #define CH23_DEPTH_PASS #include "Ch23/Ch23Common.glsl" ENDGLSL } } }