- Velocity buffer:Forward 第二颜色附件,vertex 计算 clip 空间运动向量 (UBO 尾部追加 projNoJitter/prevView/prevProj;上一帧实例矩阵 SSBO Set0 binding2,与当前实例数组平行对齐——转动的物体速度正确不鬼影) - 子像素抖动:SceneRenderer Halton(2,3)×8 序列,抖动只进光栅化投影 - TAA resolve pass:velocity 反推历史位置 + 3×3 邻域 clamp 去鬼影 + mix(cur,hist,0.9) 时域累积;TAAColor 自引用历史 - RG 历史读补 post-barrier:采样后恢复镜像 resting layout(TAA 的历史 是 ColorAttachment layout,不恢复则下帧 entry oldLayout 脱节) - 管线:Forward(HDR+Velocity) → TAA(TAAColor) → Bloom/Tonemap 改源 TAAColor - 编译零错误、validation 零警告、8 秒冒烟通过(10 pass 全活跃)
53 lines
1.9 KiB
GLSL
53 lines
1.9 KiB
GLSL
#version 450
|
||
|
||
// TAA resolve:时域抗锯齿。
|
||
// 1. velocity 反推历史像素位置,取历史累积色
|
||
// 2. 邻域 clamp(3×3 AABB)压制鬼影:历史色超出当前帧邻域范围的部分丢弃
|
||
// 3. mix(cur, hist, alpha) 时域累积
|
||
// 输出写入 TAAColor,它同时也是下一帧的历史(ReadHistory 自引用)。
|
||
|
||
layout(location = 0) in vec2 fragUV;
|
||
layout(location = 0) out vec4 outColor;
|
||
|
||
layout(set = 0, binding = 0) uniform sampler2D curImage; // 当前帧 HDR
|
||
layout(set = 0, binding = 1) uniform sampler2D velocityImage; // 运动向量(UV 空间)
|
||
layout(set = 0, binding = 2) uniform sampler2D historyImage; // 上一帧累积结果
|
||
|
||
// 全屏 pass 通用 push(16B,程序级统一声明,VUID-08878)
|
||
layout(push_constant) uniform PushConstants {
|
||
float exposure; // 与其它全屏 pass 布局一致(本 pass 不用)
|
||
float alpha; // 历史权重(0.9 = 90% 历史)
|
||
float param1;
|
||
float param2;
|
||
} pc;
|
||
|
||
void main() {
|
||
vec4 cur = texture(curImage, fragUV);
|
||
vec2 vel = texture(velocityImage, fragUV).xy;
|
||
vec2 histUV = fragUV - vel;
|
||
|
||
vec3 result = cur.rgb;
|
||
|
||
// 历史采样:越出画面(相机快速平移)直接用当前帧,不累积
|
||
if (all(greaterThanEqual(histUV, vec2(0.0))) &&
|
||
all(lessThanEqual(histUV, vec2(1.0)))) {
|
||
vec3 hist = texture(historyImage, histUV).rgb;
|
||
|
||
// 邻域 clamp:当前帧 3×3 邻域的 min/max 包围盒
|
||
vec2 ts = 1.0 / vec2(textureSize(curImage, 0));
|
||
vec3 minC = cur.rgb;
|
||
vec3 maxC = cur.rgb;
|
||
for (int y = -1; y <= 1; ++y) {
|
||
for (int x = -1; x <= 1; ++x) {
|
||
vec3 c = texture(curImage, fragUV + vec2(x, y) * ts).rgb;
|
||
minC = min(minC, c);
|
||
maxC = max(maxC, c);
|
||
}
|
||
}
|
||
vec3 clamped = clamp(hist, minC, maxC);
|
||
result = mix(cur.rgb, clamped, pc.alpha);
|
||
}
|
||
|
||
outColor = vec4(result, cur.a);
|
||
}
|