在 Unreal Engine 5 中实现彩色阴影半影
在高端实时渲染中,光与影之间的过渡——半影——通常只是一个简单的线性渐变。虽然在许多情况下这在物理上是合理的,但有时会显得呆板,缺乏在风格化电影或特定自然现象中出现的艺术冲击力。“彩色阴影半影”(或彩色阴影终结)效果通过在过渡区域添加饱和度来解决这一问题,使光与影相接的边缘更加鲜活且视觉上更具吸引力。
该技术受 Romain Durand 的工作启发,并由 Shahriar Shahrabi 在理论上记录,重点是专门在半影内操控表面颜色,以模拟更饱和的光晕或光泄漏。
在 UE5 中的技术实现
与其将其实现为后处理效果——后处理通常需要猜测光/影的数值,并且在 Lumen 或昼夜循环等动态系统中可能出现问题——此方法直接编辑引擎着色器。这样可以确保该效果适用于所有光源类型,并且计算开销极低。
对 Substrate 的实现
对于使用 Substrate 框架的用户,修改位于 Engine\Shaders\Private\Substrate\SubstrateDeferredLighting.ush。
定位包含以下内容的行(在 UE 5.7 中大约第 190 行):
float3 SpecularLuminance = BSDFEvaluate.IntegratedSpecularValue * LightData.SpecularScale;
在其后立即插入以下代码块:
// Colored shadow penumbra - Start
const float PenumbraSaturation = 4.0f; // Configure this to your liking (1.0 means no change)
float3 LuminanceFactors = float3(0.3f, 0.59f, 0.11f); // Luminance factor for desaturation
float3 PenumbraColor = dot(DiffuseLuminance, LuminanceFactors); // Desaturate
PenumbraColor = lerp(PenumbraColor, DiffuseLuminance, PenumbraSaturation); // Apply saturation
DiffuseLuminance = lerp(DiffuseLuminance, PenumbraColor, 1.0f - BSDFShadowTerms.SurfaceShadow); // Blend
// Colored shadow penumbra - End
对标准延迟光照的实现
对于未使用 Substrate 的用户,修改位于 Engine\Shaders\Private\DeferredLightPixelShaders.usf。
找到包含以下内容的行(在 UE 5.7 中大约第 397 行):
OutColor += Radiance;
在其后立即插入以下代码段:
// Colored shadow penumbra - Start
const float PenumbraSaturation = 4.0f; // configure this to your liking (1.0 means no change)
float3 LuminanceFactors = float3(0.3f, 0.59f, 0.11f); // Luminance factor for desaturation
float3 PenumbraColor = dot(OutColor.xyz, LuminanceFactors); // Desaturate
PenumbraColor = lerp(PenumbraColor, OutColor.xyz, PenumbraSaturation); // Apply saturation
OutColor.xyz = lerp(OutColor.xyz, PenumbraColor, 1.0f - SurfaceShadow); // Blend
// Colored shadow penumbra - End
保存文件后,使用 Ctrl + Shift + . 重新启动 Unreal Engine 中的着色器编译。
分析与权衡
此实现提供了若干优势和劣势,开发者应予以考虑:
优点
- 一致性: 适用于所有光源类型,避免了后处理方案中常见的“猜测”问题。
- 性能: 实现极其轻量,对像素着色器几乎没有额外开销。
- 兼容性: 可在 Launcher 版引擎中使用,无需修改引擎源码。
缺点
- 全局配置: 饱和度在全局范围内设置,无法针对单个光源或场景单独调整。
- 需要软阴影: 仅在存在宽半影时效果可见。
- 仅限动态光源: 此实现仅适用于动态光照,不适用于烘焙光照。
- 材质依赖性: 由于效果依赖于提升饱和度,对灰度或已完全饱和的表面没有可见影响。
理论背景与讨论
虽然该实现是一种实用的“技巧”,但其物理依据在技术艺术家之间仍有争议。有些人认为它模仿了某些材质在强光照射下的“发光”方式,即从受光表面向阴影部分泄漏的光比反射光本身更饱和。
正如社区成员在讨论此技术时所指出的:
“某些物体在强光照射下会‘发光’,且这种光辉比反射光更具色彩,因此如果光照边缘硬朗,半影会被更强光照部分的光辉所饱和。”
这表明,尽管该效果更像是一种风格化选择而非严格的物理模拟,但只要对 PenumbraSaturation 值进行谨慎调节以避免过于人工的外观,它就能成为在阴影过渡中添加视觉深度和“辉光”的强大工具。