URP 渲染实战 / 第 6 章 多光源与阴影 / 案例 6.7
案例 6.7附加光阴影进阶
目标:理解点光、聚光阴影的存储方式,让多光源 Shader 正确接收它们。
附加光的阴影全部放在一张阴影图集 _AdditionalLightsShadowmapTexture 里:聚光灯占 1 个图块(透视投影),点光源占 6 个图块(立方体的 6 个面,每面 90° 多一点的透视投影,多出的角度用来给软阴影的滤波核留边)。每个图块的分辨率由灯光的 Shadow Resolution 档位(Low / Medium / High,像素数在 Asset 里设置)决定,图集放不下所有图块时 URP 会自动缩小它们(具体策略以实际版本为准)。每盏灯的阴影参数打包在 _AdditionalShadowParams[lightIndex] 里:x 是阴影强度,y 是软阴影质量,z 表示是否点光,w 是它的第一个图块的下标(−1 表示不投影)。
采样逻辑在 AdditionalLightRealtimeShadow 里:对点光源,先用 CubeMapFaceID(−lightDirection) 求出像素位于立方体的哪个面,把图块下标加上面号,再用对应的矩阵变换和采样。好消息是,这些都封装在 GetAdditionalLight(i, positionWS, shadowMask) 这个重载里——只要 Shader 声明了 _ADDITIONAL_LIGHT_SHADOWS,调用它返回的 light.shadowAttenuation 就已经是阴影结果。
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS LIGHT_LOOP_BEGIN(pixelLightCount) // 带 shadowMask 参数的重载:内部调用 AdditionalLightShadow(),还会乘上 Cookie Light light = GetAdditionalLight(lightIndex, inputData.positionWS, shadowMask); color += Shade(light, ...); // Shade 里已经乘了 light.shadowAttenuation LIGHT_LOOP_END

注意附加光阴影要同时满足:URP Asset 勾选 ;灯光组件的 Shadow Type 不是 No Shadows;灯光是逐像素光(逐顶点附加光不支持阴影);Shader 声明了
_ADDITIONAL_LIGHT_SHADOWS。点光源要渲染 6 次阴影,开销是聚光灯的 6 倍,移动端要非常克制。