现代后处理
PlayCanvas 提供兼顾先进画面和性能的现代后处理工作流。主要通过 CameraFrame 的内置效果进行 HDR 后处理,也可创建完全自定义的渲染通道以获得完整控制。
功能
CameraFrame 支持以下高级渲染技术:
- 泛光:基于物理的 HDR 泛光,模拟亮光源的自然光晕,可选亮度阈值,将效果限制于最亮区域。
- 体积雾:受平行光、点光源和聚光灯照亮的高度雾与光束。
- SSAO(屏幕空间环境光遮蔽):模拟环境光遮挡,增强深度感。
- 景深(DoF):模拟对焦,模糊焦平面之外的对象。
- 时间抗锯齿(TAA):跨帧平滑锯齿,减少伪影,也可上采样低分辨率场景。
- SMAA(亚像素形态学抗锯齿):单帧平滑锯齿,不抖动相机,也无重影。
- 暗角:通过
vignette.color将边缘混合到指定颜色。 - 颜色分级:调整亮度、对比度、饱和度和色调,塑造风格,并通过通道混合器重新映射通道。
- 颜色增强:在 HDR 中调整阴影、高光、中间调、自然饱和度和去雾。
- 颜色 LUT:通过查找表进行高级颜色变换,参见 HDR 渲染 > 颜色 LUT。
- 色边:模拟颜色通道分离的色差效果。
- 色调映射:控制 HDR 颜色到可显示范围的映射。
- 锐度:增强清晰度,抵消 TAA 或上采样的模糊。
- 自动曝光:根据可见内容亮度调整曝光。
- 镜头光晕:灯光产生光晕,被场景遮挡时淡出。
- 动态天空:带云的昼夜天空,生成场景光照并同步太阳光。
除色调映射外,上述各项都是 CameraFrameEffect。大多数内置于 CameraFrame,例如 cameraFrame.bloom 和 cameraFrame.vignette。SMAA、自动曝光、镜头光晕和动态天空通过 addEffect 添加,也可编写自定义效果。
配置与使用
详细配置参见 HDR 渲染指南及 CameraFrame API。
编辑器用户可使用现成脚本,步骤参见编辑器中的 CameraFrame。
颜色增强
除 grading 的亮度、对比度、饱和度和色调外,colorEnhance 提供选择性调整:
shadows和highlights提亮或压暗阴影与高光,范围 -3 到 3,中性值 0。midtones调整中间亮度,比改变曝光更能保留阴影和高光,范围 -1 到 1。vibrance主要增强低饱和度颜色,对已有高饱和度颜色影响较小。负值降低饱和度,范围 -1 到 1。dehaze正值增加清晰度,负值添加雾感,范围 -1 到 1。这只是颜色调整;需要受场景灯光照亮的雾时,应使用体积雾。
cameraFrame.colorEnhance.enabled = true;
cameraFrame.colorEnhance.shadows = 0.5;
cameraFrame.colorEnhance.midtones = 0.1;
cameraFrame.colorEnhance.vibrance = 0.2;
cameraFrame.update();
五项默认均为 0,效果默认禁用。
通道混合器
grading 的通道混合器通过输入红、绿、蓝通道的加权组合生成各输出通道,类似图像编辑器的 Channel Mixer。mixerRed、mixerGreen 和 mixerBlue 保存每个输出通道中 RGB 输入的权重,各分量范围 -2 到 2,默认为不改变图像的单位映射。
const grading = cameraFrame.grading;
grading.enabled = true;
// swap the red and blue channels
grading.mixerRed.set(0, 0, 1);
grading.mixerBlue.set(1, 0, 0);
cameraFrame.update();
要按自定义权重转为黑白,为三个输出通道使用相同权重:
grading.mixerRed.set(0.5, 0.4, 0.1);
grading.mixerGreen.copy(grading.mixerRed);
grading.mixerBlue.copy(grading.mixerRed);
cameraFrame.update();
混合器在线性 HDR 空间、色调映射之前执行,先于颜色分级的色调、亮度、饱和度和对比度。由于是线性操作,各曝光下结果一致,也适用于自动曝光。若要精确匹配图像编辑器制作的风格,应使用在色调映射之后应用的颜色 LUT。
暗角颜色
使用 vignette.color 给边缘染色,而非淡到黑色:
cameraFrame.vignette.intensity = 0.4;
cameraFrame.vignette.color.set(0.1, 0.05, 0.2);
cameraFrame.update();
inner、outer 和 curvature 控制形状与衰减。outer 小于 inner 时反转效果,改为影响中心。
TAA 上采样
rendering.renderTargetScale 范围 0.1–1,通过低分辨率渲染优化性能。后处理也按该分辨率运行,再以双线性滤波拉伸到全分辨率,最后叠加全分辨率 UI。
启用 TAA 后,taa.upscale 改为在全分辨率累积低分辨率帧。相机抖动让每帧样本落到全分辨率像素内不同位置,恢复许多损失细节。TAA 之后的泛光和合成等效果使用全分辨率场景。
cameraFrame.rendering.renderTargetScale = 0.5;
cameraFrame.taa.enabled = true;
cameraFrame.taa.upscale = true;
cameraFrame.rendering.sharpness = 0.5;
cameraFrame.update();
上采样更依赖历史,因此移动对象可能比单纯 TAA 更模糊或更易重影。rendering.sharpness 可抵消柔化。编辑器 cameraFrame 脚本提供对应的 taa.upscale、rendering.renderTargetScale、rendering.sharpness 属性。示例中的时间抗锯齿对比全分辨率,以及双线性或 TAA 上采样的低分辨率,并展示锐化差异。
SMAA
SmaaEffect 即亚像素形态学抗锯齿,在单帧中识别锯齿边缘形状,按理想边缘覆盖面积与相邻像素混合。与 TAA 不同,它不抖动相机、不需要历史、没有重影,但无法还原小于像素的细节。
SMAA 不是内置效果,通过 addEffect 添加:
const smaa = new SmaaEffect(app.graphicsDevice);
cameraFrame.addEffect(smaa);
cameraFrame.update();
四个属性控制质量与开销,默认对应参考实现的高质量预设:
| 预设 | threshold | maxSearchSteps | maxSearchStepsDiag | cornerRounding |
|---|---|---|---|---|
| 低 | 0.15 | 4 | 0 | 100 |
| 中 | 0.1 | 8 | 0 | 100 |
| 高(默认) | 0.1 | 16 | 8 | 25 |
| 极高 | 0.05 | 32 | 16 | 25 |
threshold,0–0.5,相邻像素亮度差超过此值时识别为边缘。越低越多边缘被平滑、开销越高,也可能平滑纹理细节。maxSearchSteps,1–112,搜索水平或垂直边缘终点的最大步数,每步两个像素。更长边缘的终点找不到,平滑不够准确。maxSearchStepsDiag,0–20,对角线边缘对应步数。0 禁用对角线检测,转而按水平和垂直处理。cornerRounding,0–100,几何尖角的圆滑程度。0 最尖锐,100 像其他边缘一样平滑。
SMAA 可与 rendering.samples 多重采样结合,以更高开销进一步平滑。与 TAA 结合时默认在其之后解析,也可用 cameraFrame.insertEffectBefore(smaa, 'taa') 放到前面。smaaedges 和 smaaweights 调试视图显示边缘及混合权重。编辑器可用 smaa.mjs 的 smaaEffect 脚本添加。
此示例比较 SMAA 预设、TAA、TAA 上采样和多重采样:
调试视图
设置 cameraFrame.debug 检查中间结果:scene、ssao、bloom、vignette、dofcoc(景深弥散圆)、dofblur 或 depth。附加效果也提供视图:SMAA 的 smaaedges 和 smaaweights、自动曝光的 autoexposure、镜头光晕的 lensflare。
cameraFrame.debug = 'depth';
cameraFrame.update();
调试视图不会主动启用效果或生成额外纹理。未生成深度时深度视图为黑,效果视图需要对应效果启用。将 debug 设为 null 并调用 update() 恢复合成图像。编辑器脚本使用 Rendering > Debug,选择 None 恢复正常输出。
高斯泼溅使用雾或景深时,参见场景深度要求。
示例
- HDR 泛光与 LUT:演示 HDR 泛光和颜色查找表。
- 后处理:泛光、含通道混合器的颜色分级、颜色增强、彩色暗角、色边和 TAA。
- 环境光遮蔽:演示 SSAO。
- 景深:演示景深效果。
- 时间抗锯齿:演示 TAA。
- 体积雾:平行光照亮的高度雾。
- 体积雾局部灯光:点光源与聚光灯在雾中散射。
- 体积雾光束:有阴影的聚光灯束与灯光 cookie。
- LUT 分级:在高斯泼溅场景的两种调色之间交叉淡化。
自定义后处理
现代后处理可通过三种方式扩展,按需要选择:
自定义效果
在 CameraFrame 合成中添加自定义效果,与内置效果并列。效果向单个合成通道贡献代码块,不增加全屏通道。
**适合:**屏幕空间效果、颜色调整、风格化外观。
带通道的效果
效果拥有帧通道,在场景之前、不透明与透明几何体之间、或场景之后等阶段渲染。
**适合:**多通道效果、低分辨率效果、向场景绘制、跨帧累积。
相机通道
不用 CameraFrame,以自定义帧通道替换相机渲染,完全控制整台相机的渲染。
**适合:**完整自定义管线、特殊渲染和最大灵活性。