Files
HelloVulkan/shaders/bloom_extract.frag
T
atdunbg 6c80693618 Fix bloom glow flicker on static geometry under TAA jitter
TAA subpixel jitter makes rasterized HDR specular highlights oscillate
per frame. The old RGB min/max neighborhood clamp re-clamped the
converged history against jitter-driven extremes every frame, leaving a
periodic residual that the bloom threshold then amplified into visible
glow pulsing on static models.

- TAA: replace the RGB AABB clamp with YCoCg variance clipping
  (history clamped toward the stable neighborhood mean +/- 1.25 sigma,
  intersected with the min/max box as a ghosting upper bound)
- Bloom extract: 5-tap cross prefilter before the threshold spreads
  surviving 1px jitter energy over a ~4x4 footprint so the glow no
  longer pulses
2026-10-05 12:08:53 +08:00

35 lines
1.4 KiB
GLSL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#version 450
// Bloom 提取:从 HDR 颜色图中滤出超过阈值的部分(软阈值,保留超出比例)。
// 全屏 pass 通用 push(16B):param0 = 亮度阈值(HDR 域,1.0 = 仅高光溢出)。
layout(location = 0) in vec2 fragUV;
layout(location = 0) out vec4 outColor;
layout(set = 0, binding = 0) uniform sampler2D hdrImage;
layout(push_constant) uniform PushConstants {
float exposure; // 未用(程序级统一布局)
float threshold; // param0
float _pad0;
float _pad1;
} pc;
void main() {
// 5 tap 十字预滤波(中心 0.4 + 四邻 0.15):TAA 残留的亚像素震荡
// 在进阈值前被抹平——1px 级抖动的能量摊到 ~4×4 足印,泛光不再脉冲。
// 半分辨率输出中心的双线性已覆盖 2×2 块,此步把足印扩到近似 4×4
vec2 ts = 1.0 / vec2(textureSize(hdrImage, 0));
vec3 c = texture(hdrImage, fragUV).rgb * 0.4
+ (texture(hdrImage, fragUV + vec2(ts.x, 0.0)).rgb
+ texture(hdrImage, fragUV + vec2(-ts.x, 0.0)).rgb
+ texture(hdrImage, fragUV + vec2(0.0, ts.y)).rgb
+ texture(hdrImage, fragUV + vec2(0.0, -ts.y)).rgb) * 0.15;
float l = max(c.r, max(c.g, c.b));
// 软阈值:只保留超出 threshold 的能量比例,避免硬切产生的块状边缘
float k = max(l - pc.threshold, 0.0) / max(l, 1e-4);
outColor = vec4(c * k, 1.0);
}