UE5.8 后期处理体积:把画面从能看调到耐看

📑 目录

UE5.8 后期处理体积:把画面从能看调到耐看

你站在一个未打光的灰色关卡里,所有材质都是默认值,Directional Light 强度 3.16,Sky Atmosphere 勉强给天空涂了点颜色。按下 Play,角色跑起来,世界能看,但就是没有那层让你觉得它真实存在的薄膜。这层薄膜在影视行业里叫 look,在引擎里很大一部份由 Post Process Volume 负责。它不是特效,而是摄影师调色、镜头光学、人眼适应三件事在实时管线里的集合体。

UE5.8 的后处理管线比 5.4 时期更强调模块化。Lumen 和 Nanite 解决了几何与光照,Post Process Volume 解决的是光进入镜头之后发生的事情。很多人刚接触 UE 时会把后处理当成滤镜,觉得它是渲染最后一步的美化。实际上它的很多参数在还原物理成像。相机有光圈、快门、ISO,镜头有色散、暗角、炫光,人眼有瞳孔缩放和神经适应。Post Process Volume 把这些东西打包成可在场景里放置、混合、动态控制的 Actor。

flowchart TD
    subgraph engine ["虚幻引擎 5.8"]
        renderer["场景渲染器"]
        ppv["Post Process Volume"]
        ppm["后处理材质"]
        comp["最终合成"]
    end
    subgraph output ["显示输出"]
        screen["屏幕帧缓冲"]
    end
    renderer --> ppv
    ppv --> ppm
    ppm --> comp
    comp --> screen

Post Process Volume 基础

在编辑器左侧放置 Actor 菜单里搜 Post Process Volume,拖进场景。它默认是一个带 Box Collision 的体积,玩家摄像机进入这个 Box 后,体积里的参数才会生效。把 Details 面板拉到最下面,Lens、Color Grading、Exposure、Depth of Field、Motion Blur、Bloom 都在 Post Process Volume 分类下。

每个体积有一个 Blend Weight,0 到 1 之间,表示当前体积对最终画面的贡献。还有一个 Priority,数值越高越优先。多个体积重叠时,UE 会按距离、权重和优先级做插值,而不是简单覆盖。这个特性在后面做局部调色时非常关键。

默认场景里通常已经有一个覆盖全图的 Global Post Process Volume。你可以在 World Settings 里找到它,也可以自己放一个并把 Infinite Extent (Unbound) 勾上,让它不受 Box 限制,全局生效。全局体积负责基础 look,局部体积负责进入特定区域时的气氛切换。

Details 面板里每个参数左侧都有一个复选框,叫 Override。只有勾上 Override,这个参数才会被当前体积写入。没勾 Override 的参数保持默认值或者继承全局体积。这个设计避免了一个局部体积不小心把全局精心调好的 Exposure 覆盖掉。做大型关卡时,建议只 Override 确实需要改的那几项。

flowchart TD
    A["玩家进入某个区域"] --> B{该区域是否存在局部 PPV}
    B -->|"否"| C["只使用全局 PPV 参数"]
    B -->|"是"| D["按距离计算局部 PPV 权重"]
    D --> E{是否存在重叠体积}
    E -->|"否"| F["单一局部参数生效"]
    E -->|"是"| G["按 Priority 与 Blend Weight 混合"]
    G --> H["输出最终后处理画面"]
    C --> H
    F --> H

Exposure 与 Eye Adaptation

想象玩家从洞穴深处走到洞口。洞里的平均亮度可能只有 0.1 cd/m²,洞口外面的天空是 8000 cd/m²。如果 Exposure 固定,洞内黑成一片,洞外一片死白。人眼会在几秒内适应亮度变化,这个生理现象在引擎里叫 Eye Adaptation

Post Process Volume 的 Exposure 分组下,把 Metering Mode 改成 Histogram,UE 会统计当前画面的亮度直方图,然后计算一个目标曝光值。目标曝光值用 EV100 表示,公式是

EV100=log2(LSK)\text{EV}_{100} = \log_2\left(\frac{L \cdot S}{K}\right)

其中 LL 是场景平均亮度,SS 是 ISO 灵敏度,KK 是反射测光常数。在 UE 里你不需要手动算,但要理解数值方向:EV 越大,画面越暗。洞穴里的 EV 可能是 9,户外晴天可能是 15。

Eye Adaptation Speed 分 Up 和 Down 两个参数,Up 负责画面变亮时的适应速度,Down 负责画面变暗时的适应速度。洞穴到洞口是 Up,洞口回到洞穴是 Down。通常情况下 Down 可以比 Up 慢一点,因为人眼适应黑暗需要更长时间。把这两个值调得太快会产生闪烁感,调得太慢玩家会看不清路。

手动曝光模式适合室内演出或者固定机位的过场动画。把 Exposure Method 改成 Manual,然后直接填 Exposure Compensation。手动模式下没有 Eye Adaptation,画面亮度完全由你控制。

Exposure 分组里还有 Min EV100Max EV100,用来限制自动曝光的上下界。没有这对钳子,天空或者极亮光源可能把画面压到接近全黑。我一般把 Min 设为 0,Max 设为 18,留一点给太阳直射的过曝。配合 Exposure Bias 可以在自动曝光基础上整体加减 EV,比如森林场景整体欠曝半档,让树荫更浓。

还有一个容易被忽略的参数是 Histogram Log Min/Max。它决定直方图统计的亮度范围。如果场景里有一个极亮的光源,把它排除在统计范围之外可以避免整幅画面被它拉暗。这个参数配合 Lumen 的软阴影尤其重要,因为 Lumen 容易产生高亮的间接反光。

sequenceDiagram
    autonumber
    participant C as "主摄像机"
    participant V as "Post Process Volume"
    participant E as Exposure
    participant G as "Color Grading"
    participant S as "屏幕"
    C->>V: 每帧查询覆盖体积
    V->>E: 传递亮度 Histogram
    E->>E: Eye Adaptation 插值
    V->>G: 应用 LUT 与曲线
    G->>S: 合成最终像素

Color Grading 与 LUT

你正在做一个雨夜街道关卡。默认渲染下,路面反光发灰,霓虹灯招牌饱和度过高,整体像是手机相册直出。这时需要 Color Grading 给画面定一个情绪基调。Post Process Volume 里的 Color Grading 分组提供了 Global、Shadows、Midtones、Highlights 四个色轮,以及 Saturation、Contrast、Gamma、Gain、Offset 五个全局滑杆。

色轮不是单纯改变色相,而是把画面按亮度分区处理。Shadows 影响暗部,Midtones 影响中间调,Highlights 影响亮部。雨夜街道的暗部可以往青蓝色偏,中间调保持中性,高光霓虹灯往洋红或橙黄色偏,这样画面会有冷暖对比,而不会显得脏。

如果你希望调色可复用,或者需要在多个关卡保持统一 look,应该使用 Color Grading LUT。在 Photoshop 或 DaVinci Resolve 里调好一张参考图,导出 256×16 或 1024×32 的 LUT 纹理,导入 UE 后把 Texture 拖到 Post Process Volume 的 Color Grading LUT 槽里。UE 会在后处理阶段用这张 3D LUT 对画面做颜色映射。

LUT 的工作原理是把 RGB 三个通道当作三维坐标,在 LUT 纹理里查找对应输出颜色。一个 64×64×64 的 3D LUT 有 262144 个颜色映射点,足够覆盖大多数调色需求。UE5.8 对 HDR LUT 的支持比早期版本更好,配合 ACES 工作流可以减少高饱和颜色被裁切的问题。

调整 Color Grading 时建议把 Color Grading LUT Intensity 从 1 降到 0.7 左右,避免 LUT 效果太冲。你也可以用 Post Process Material 做更复杂的颜色操作,比如基于深度的雾色调或者基于世界高度的天空渐变。

UE5.8 默认使用 ACES 色调映射,它会自动把 HDR 亮度压到 SDR 显示范围,同时保护高饱和颜色。如果你切换回 sRGB 色调映射,高光会硬切,颜色容易过曝。调色时建议在引擎窗口开启 HDR 预览,或者导出到目标显示设备上看,因为 SDR 显示器上的结果和最终主机输出可能有偏差。

Vignette 与 Chromatic Aberration

真实镜头在画面边缘会有亮度衰减,这就是 Vignette。它本来是一种光学缺陷,但在游戏里常用来把注意力引向画面中心。Post Process Volume 里的 Vignette Intensity 控制暗角强度,数值越大四角越暗。 horror 游戏或者狙击瞄准镜里常用强 Vignette 制造压迫感。

Chromatic Aberration 是另一种镜头缺陷:不同波长的光折射率不同,导致画面高对比边缘出现红绿蓝分离。UE 里的 Chromatic Aberration 默认基于屏幕空间偏移实现,强度过高会产生明显的色边,看起来像廉价滤镜。大多数情况下我会把它降到 0.1 以下,或者只在过场动画里短暂使用。

这两个参数都很容易做过。建议在游戏运行时按 ~ 打开控制台,输入 showflag.postprocessing 0 关闭后处理对比原图,再输入 showflag.postprocessing 1 打开。频繁开关能帮你判断参数是否过头。

除了强度,Vignette 还有一个 FeatherRoundness 参数控制暗角过渡范围。圆形暗角适合第一人称视角,椭圆形暗角适合电影宽银幕。某些项目会用 Post Process Material 做自定义 Vignette,比如只在屏幕下方压暗,模拟角色低头看地面时的视线集中。

DOF(Depth of Field)

玩家走到一张桌子前,桌上放着一把钥匙。你希望玩家第一眼就看见钥匙,背景的书架和窗户自然虚化。这就是 DOF 的作用。Post Process Volume 里的 Depth of Field 分组提供了几种实现方式:Gaussian、BokehDOF、CircleDOF、Lens 等。UE5.8 默认推荐 Cinematic DOF,它在质量和性能之间取得了较好平衡。

DOF 的核心是弥散圆,公式可以简化为

C=f2(S2S1)S2(S1f)ANC = \frac{f^2 \cdot (S_2 - S_1)}{S_2 \cdot (S_1 - f)} \cdot \frac{A}{N}

其中 CC 是弥散圆直径,ff 是焦距,S1S_1 是对焦距离,S2S_2 是物体距离,AA 是光圈直径,NN 是光圈系数。你不用在引擎里套这个公式,但它解释了为什么离焦点越远的物体会越模糊。

在 UE 里,把 Focus Method 改成 Manual,然后设置 Manual Focus Distance。如果想让焦点跟随玩家注视的物体,可以改成 Tracking 并指定一个 Actor 或者使用 Depth of Field Tracking。更常见的做法是在角色摄像机里用 Line Trace 检测前方物体,然后把命中距离作为 Focus Distance 传给 Post Process Volume。

ApertureF-Stop 控制虚化程度。F-Stop 越小,光圈越大,背景越虚。特写镜头可以用 f/1.4,大场景可以用 f/8 让前后景都清晰。Blur SizeMax Bokeh Size 限制最大弥散圆,防止点光源变成巨大色块。

Cinematic DOF 把场景分成近景模糊、清晰对焦、远景模糊三个区域。近景模糊对叙事很重要,它能让前景物体变成画面框架。调 Near Blur Size 时要小心角色手部或者武器,太近会被糊掉。远景模糊则用来隐藏 LOD 切换和远处的低精度模型。

DOF 在开放世界游戏里要格外小心。远景的树木和建筑如果被过度虚化,会损失地形细节。建议在全局体积里给一个很弱的 DOF,只在特写区域用局部体积加强。

Bloom 与 Lens Flare

晚上,玩家走进一条挂满霓虹灯的巷子。招牌和路灯在高亮处应该散发出柔和的光晕,这就是 Bloom。Bloom 模拟的是强光在镜头镜片和传感器上散射的效果。Post Process Volume 的 Bloom 分组里,Intensity 控制整体强度,Threshold 决定多亮的像素才会产生泛光,Size Scale 控制泛光半径。

Threshold 的单位是亮度值。如果 Threshold 是 4,只有亮度超过 4 的像素才会进入 Bloom 计算。Lumen 和光照系统升级后,HDR 场景里高亮像素很常见,Threshold 不需要设得太低。把 Threshold 从 1 提到 3 到 4,可以避免整个画面都发雾。

Convolution Bloom 用一张自定义核函数纹理来模拟镜头光斑形状,适合追求电影感的项目。普通 Bloom 则是基于高斯模糊的近似,速度更快。UE5.8 的 Bloom 管线在 Lumen 场景里会自动处理高亮反射,但如果你的项目用静态光照,可能需要手动提亮 Emissive 材质。

很多项目会给 Bloom 加一张 Dirt Mask,模拟镜头上的灰尘对强光的散射。Dirt Mask 是一张灰度纹理,亮度高的地方会让 Bloom 更明显。UE5.8 里把 Dirt Mask 拖到 Lens 分组对应槽位即可,但要注意它的强度会随 Exposure 变化,暗场景里可能几乎不可见。

Lens Flare 是强光源在镜头内部镜片间反射产生的光斑。UE 的 Lens Flare 默认基于图像生成,不需要手动放置光源。把 Lens Flare Intensity 调低通常比调高更耐看,除非你在做太空或者霓虹主题。Lens Flare 和 Bloom 一样,容易被滥用成画面污染。

graph LR
    A["后处理参数"] --> B[Exposure]
    A --> C["Color Grading"]
    A --> D[DOF]
    A --> E[Bloom]
    C --> F[Vignette]
    D --> G["Chromatic Aberration"]
    E --> H["Lens Flare"]

全局与局部体积

一个关卡很少只用一种 look。森林入口明亮清新,洞穴深处幽暗压抑, Boss 房间用强 Vignette 和冷色调制造紧张感。这些切换如果靠一个全局体积硬切,玩家会觉得画面在跳变。正确的做法是用多个局部 Post Process Volume 叠加。

局部体积的关键参数是 Blend RadiusBlend Weight。Blend Radius 决定体积边缘的过渡范围,玩家穿过边界时参数会平滑变化。Blend Weight 是当前体积的最大贡献。把洞穴入口的 Blend Radius 拉大,玩家还没完全进洞,画面就已经开始变暗。

当两个局部体积重叠时,UE 按 Priority 排序,然后按摄像机到各体积中心的距离和权重做混合。Priority 高的体积在冲突参数上更有话语权。注意不是所有参数都能完美混合,某些开关型参数会取优先级最高的那个值。

Priority 的数值没有固定单位,只是相对大小。常见做法是全局体积 Priority 0,区域体积 10,Boss 战或者剧情触发体积 100。这样重叠时规则清晰,不会因为某个临时体积把全局 look 冲乱。调试时可以用 showflag.postprocessbounds 1 查看体积边界。

局部体积还可以配合关卡蓝图或者 Player Character 做动态触发。例如玩家进入某个房间后,把局部体积的 Blend Weight 从 0 插值到 1,实现平滑的气氛过渡。下面是一个在 Tick 里动态修改权重的例子:

void AMyPlayer::UpdateLocalPostProcess(float DeltaTime)
{
    if (CurrentLocalVolume == nullptr)
    {
        return;
    }

    float NewWeight = FMath::FInterpTo(
        CurrentLocalVolume->BlendWeight,
        TargetBlendWeight,
        DeltaTime,
        2.0f
    );

    CurrentLocalVolume->BlendWeight = NewWeight;
}

这段代码把 Blend Weight 以每秒约 2 的速度逼近目标值。你可以根据场景节奏调整插值速度,过场动画里可以用更慢的速度,战斗区域则可以快一点。

性能与平台差异

后处理不是免费的。Bloom、DOF、Motion Blur 都会增加每帧的 GPU 开销。UE5.8 在 PC 上默认启用较高质量,但在移动平台需要大幅裁剪。

控制台变量是快速调试的好工具。常用参数如下:

r.PostProcessAAQuality=4
r.BloomQuality=5
r.DepthOfFieldQuality=3
r.EyeAdaptationQuality=2
r.LensFlareQuality=2

把 Bloom 或 DOF 的 Quality 降到 2 或 1,可以省下半分辨率 Pass 的开销。主机平台通常会把 DOF 和 Motion Blur 改成 tile-based 实现,避免全屏高斯模糊。移动平台则建议关闭 Chromatic Aberration、Lens Flare 和高强度 Bloom,只保留 Exposure 和基础 Color Grading。

全局体积因为有 Unbound 标志,每帧都会参与计算。局部体积只在摄像机进入时才生效,所以它们的开销是按需的。如果某个区域的后处理非常重,但玩家只是偶尔经过,用局部体积比全局更划算。

定位后处理开销可以用 stat gpu 命令,看 PostProcessing 一项占了多少毫秒。如果 Bloom 或者 DOF 特别高,优先降 Quality 等级。对于自定义 Post Process Material,要检查是否用了全屏采样循环或者未优化的 if 分支,这些在移动端会是致命瓶颈。

移动端还有带宽问题。Bloom 的多次下采样和上采样会频繁读写 Render Target,Tile-Based GPU 上容易产生大量内存流量。开启 r.Mobile.DOF 相关开关前,先在目标设备上跑一遍 GPU Profiler。Switch 和 Steam Deck 的内存带宽比高端 PC 低很多,参数不能按 PC 标准来。

另一个容易忽略的平台差异是 HDR 显示。PC 和主机通常支持 HDR 输出,Color Grading 需要在 HDR 空间里完成,避免颜色被错误地 clamp 到 SDR。UE5.8 的默认 ACES 流程已经考虑了这一点,但如果你自定义 Post Process Material,要特别注意中间纹理的格式是否为 RGBA16F。

小结

Post Process Volume 是 UE 里把画面从功能正确推向视觉耐看的主要工具。Exposure 解决亮度适应,Color Grading 定下情绪,DOF 引导视线,Bloom 和 Lens Flare 增强光源表现力,Vignette 和 Chromatic Aberration 则用来模拟镜头性格。全局体积提供基础 look,局部体积负责区域气氛切换。平台上要根据性能预算裁剪质量,移动和主机不能照搬 PC 参数。

实际工作中,我的习惯是先关掉所有后处理,确认基础光照和材质没有问题,再逐个开启 Exposure、Color Grading、Bloom、DOF,每开一项就对比一次。这样不会出现多个参数互相打架,调试时也更容易定位问题。UE5.8 的后处理工具链比过去更稳定,但最终画面仍然取决于你对参数的克制使用。

如果这是一个长期维护的项目,建议把每个关卡的后处理参数整理成表格,记录全局体积和局部体积的 Priority、Blend Weight、关键参数取值。新人加入时可以直接参考,避免反复试错。后期处理体积看似简单,但它往往是画面统一性的最后一道关卡。