MIT 许可证 NuGet

首页 / 功能 / 后处理

后处理与 compute 特效

泛光、TAA、GTAO、天空 LUT 和调试视图都不是硬连线的阶段。 它们是针对帧阶段注册的 compute 特效,承载它们的二十行契约, 也正是你自己的特效所实现的同一个契约。

开箱自带什么

特效位于 Rendering/Effects/。每个特效注册进一个 compute 阶段,声明它产生的纹理,并且可以按名称作为 2D 精灵来查看—— 参考应用的调试模式正是这样工作的。

类型阶段用途
BloomEffectAfterScene对 HDR 场景颜色做降采样 / 升采样链。
GtaoEffectAfterScene用于间接漫反射的环境光遮蔽。
TaaEffectAfterScene带方差钳制和锐化的抖动时间解析。
DdgiEffectAfterScene探针追踪与辐照度图集更新。
SkyAtmosphereEffectFrameStart散射 LUT、云噪声和空气体积。
SceneColorCopyEffectAfterScene供需要的特效读取的场景颜色快照。
DepthViewEffectAfterScene作为可查看纹理的线性化深度。
VelocityViewEffectAfterScene可视化的运动矢量。
Sdf3DViewEffectFrameStartDDGI 所追踪的那种有符号距离场的切片。
PlasmaEffectFrameStart最小 compute 示例——写自己的特效时抄它。

其中任何一个都能用三行代码放上屏幕,因为特效输出是可寻址纹理:

AddControl(new Sprite2D
{
    Name = Season.Rendering.Effects.GtaoEffect.TextureName,
    Color = Colors.White,
    PosX = 20, PosY = 580, Width = 240
});

命名遵循一个方案:2D 纹理用 compute://,体积用 compute3d://。GTAO 发布 compute://gtao/ao,天空发布 compute://sky/skyview 和 compute3d://sky/aerial,plasma 示例发布 compute://plasma。消费它们没有任何特殊之处—— 一个 Sprite2D 或材质覆盖项接受该名称, 这就是全部接口。

特效契约

ComputeEffect 是一个有五个成员的抽象类。 这就是全部扩展面。

public abstract class ComputeEffect
{
    public abstract string Name { get; }
    public abstract ComputePhase Phase { get; }

    // Create textures and pipelines. Return false and the effect is
    // dropped with nothing left behind.
    public abstract bool Initialize(IGraphics g);

    // Dispatch. Called once per frame, in phase order.
    public abstract void Record(IGraphics g);

    // Swapchain changed size. Recreate anything resolution-dependent.
    public virtual void OnResize(IGraphics g) { }
}
契约

Initialize 返回 false 必须不留残渣—— 没有创建了一半的纹理,没有 FrameSchedule 里悬空的名字。这正是特效真正可选的保证:没有 compute 支持的 后端和关掉了该特效的用户,产生的是同样正确的帧。

编写 compute 特效 逐行讲解 PlasmaEffect。

泛光

一个阈值加拐点的软截断,随后是对 HDR 场景颜色的六级降采样与 升采样链。因为场景颜色是真正的 HDR,阈值是有意义的: 它选出比白色更亮的像素,而不是碰巧被截断的像素。

设置默认值含义
BloomEnabledon关闭则跳过该链并清空 FrameSchedule.BloomTexture。
BloomThreshold1.0像素开始贡献的辐射度阈值。
BloomKnee0.5阈值的柔和度,让泛光淡入而不是突然开启。
BloomIntensity0.3链的结果加回多少。
BloomMipCount6链深度。更多层级意味着更宽、更柔和的光晕。

抗锯齿:四个层级,诚实标注

AaMode 有四个值,它们不是同一事物的四种质量—— 它们在帧的不同位置、不同颜色空间中运作。

模式运行位置说明
Off—无滤波。
Msaa4x光栅化遗留层级,仅 D3D12。HDR 解析质量打了折扣且带宽成本高;作为 VR 回退保留。
Fxaa色调映射后 LDRFXAA 3.11,在 Post 合成和 FinalBlit 中应用。便宜且通用。
TaaHDR,色调映射前默认。需要速度和 compute;选中它会在初始化时强制开启 MotionVectors。不可用时回退到 Fxaa。

TAA 已在 D3D12、Vulkan、Metal 和 WebGPU 上实现并稳定。回退到 FXAA 是自动的而不是报错,这意味着请求 TAA 的场景在无法提供的设备上 仍然能渲染——更柔和,但能渲染。

TAA 详解

相机每帧以亚像素偏移抖动投影矩阵,解析阶段通过运动矢量重投影 上一帧结果,方差钳制决定信任多少历史。有趣的部分是抖动和历史 都位于 Camera3D 上,你可以直接读取。

设置默认值含义
MotionVectorsonScene 通道是否写入速度。TAA 强制开启它。
JitterPhaseCount7抖动序列重复前的长度。
JitterScale1.0以像素计的抖动幅度。高于 1 用稳定性换覆盖率。
TaaFeedback0.9移动像素的历史权重。
TaaStaticFeedback0.97无移动处的历史权重——更多历史,更多解析。
TaaVarianceClipGamma1.0历史被钳制到邻域的程度。越低越抗鬼影、越多混叠。
TaaSharpness0.5解析后的锐化,因为时间累积会柔化。
Camera3D 上的用途
ProjectionJittered实际用于渲染的投影,包含抖动。
PrevViewProjection上一帧的矩阵,正是它让重投影成为可能。
JitterNdc, JitterPixels本帧的偏移,两个空间都有。
UpdateTemporal, ResetTemporal推进序列,或在相机切换后丢弃历史。
传送后调用 ResetTemporal

跨不连续相机移动进行重投影,会把旧帧涂抹到新帧上, 持续时间取决于反馈权重衰减所需的时间。相机切换正是 运动矢量无法描述的情形。

已知缺口

  • 部分 GTAO 是精简变体。 半分辨率、基于地平线、使用深度重建 法线、交错梯度噪声和深度感知模糊的 AO。它不是完整的地面实况 AO, 这个名字继承自技术家族,而非声称参考实现。
  • 缺失 景深、运动模糊、色差、颜色分级 LUT。 后处理链是色调映射、泛光和抗锯齿。其余任何东西都是需要你自己写的特效。
  • 缺失 上采样器。 没有 FSR、DLSS 或时间上采样。 TAA 以原生分辨率解析。