在 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 值进行谨慎调节以避免过于人工的外观,它就能成为在阴影过渡中添加视觉深度和“辉光”的强大工具。

Sources