#version 450 // Tonemap pass:HDR(+bloom)→ 显示空间,兼调试视图路由上屏。 // 这是显示变换的显式建模(对齐 UE/Unity:HDR SceneColor → tonemapper → UI)。 // ACES = Narkowicz 拟合(线性域映射到 [0,1]),可经 push constant 关闭 // 退回纯 gamma(旧观感)。 // // 调试视图:pc.debugView 整型路由到已绑定的中间目标(绑定超集静态成立, // 运行时零重绑)。HDR 域资源过同一套 exposure/tonemap 保证观感可比; // LDR 类(velocity/深度)直接可视化。 layout(location = 0) in vec2 fragUV; layout(location = 0) out vec4 outColor; layout(set = 0, binding = 0) uniform sampler2D taaImage; // TAA 后 HDR(主输入) layout(set = 0, binding = 1) uniform sampler2D bloomImage; layout(set = 0, binding = 2) uniform sampler2D temporalDiffImage; layout(set = 0, binding = 3) uniform sampler2D rawHdrImage; // Forward 直出(TAA 前) layout(set = 0, binding = 4) uniform sampler2D velocityImage; layout(set = 0, binding = 5) uniform sampler2D shadowMap0Image; // D32 深度(r 分量) layout(set = 0, binding = 6) uniform sampler2D shadowMap1Image; layout(set = 0, binding = 7) uniform sampler2D shadowMap2Image; // 环境调试视图源(随环境切换重绑,静态绑定超集) layout(set = 0, binding = 8) uniform samplerCube envCubeImage; layout(set = 0, binding = 9) uniform samplerCube irradianceImage; layout(set = 0, binding = 10) uniform samplerCube prefilterImage; layout(set = 0, binding = 11) uniform sampler2D brdfLutImage; // 与 Passes::DebugView 枚举同步(FullscreenGpu.h) const int VIEW_FINAL = 0; const int VIEW_TEMPORALDIFF = 1; const int VIEW_RAW_HDR = 2; const int VIEW_TAA = 3; const int VIEW_BLOOM = 4; const int VIEW_VELOCITY = 5; const int VIEW_SHADOW0 = 6; const int VIEW_SHADOW1 = 7; const int VIEW_SHADOW2 = 8; const int VIEW_ENV_CUBE = 9; const int VIEW_IRRADIANCE = 10; const int VIEW_PREFILTER = 11; const int VIEW_BRDF_LUT = 12; // 全屏 pass 通用 push(16B,程序级统一声明,VUID-08878) layout(push_constant) uniform PushConstants { float exposure; // 曝光系数 float aces; // >0.5 启用 ACES 曲线,否则纯 gamma float bloomStrength; // bloom 叠加强度(0 = 关闭) float debugView; // 调试视图枚举(整型经 float 传) } pc; vec3 acesFilm(vec3 x) { return clamp((x * (2.51 * x + 0.03)) / (x * (2.43 * x + 0.59) + 0.14), 0.0, 1.0); } vec3 tonemap(vec3 hdr) { hdr *= pc.exposure; vec3 mapped = (pc.aces > 0.5) ? acesFilm(hdr) : clamp(hdr, 0.0, 1.0); return pow(mapped, vec3(1.0 / 2.2)); } // 深度可视化:反相(近=白,与调试截图风格一致) vec3 depthView(sampler2D depthImage) { float d = texture(depthImage, fragUV).r; return vec3(pow(1.0 - d, 2.2)); } // 全屏 uv → 球面方向(cube 调试视图的经纬展开:横向经度、纵向极角) vec3 latLongDir(vec2 uv) { float phi = (uv.x * 2.0 - 1.0) * 3.14159265358979; // -π..π 经度 float theta = (1.0 - uv.y) * 3.14159265358979; // 0..π 极角(顶=天顶) return vec3(sin(theta) * cos(phi), cos(theta), sin(theta) * sin(phi)); } // cube 视图统一走 tonemap(HDR 域,观感与场景一致); // prefilter 纵向映射 mip 链(上锐下糙,直观验证 roughness 分级) vec3 cubeView(samplerCube cube, float lod) { return tonemap(textureLod(cube, latLongDir(fragUV), lod).rgb); } void main() { int view = int(pc.debugView + 0.5); // ---- 调试视图路由 ---- if (view != VIEW_FINAL) { switch (view) { case VIEW_TEMPORALDIFF: { // 帧历史差异:静止=黑,运动边缘发光 vec3 d = clamp(texture(temporalDiffImage, fragUV).rgb, 0.0, 1.0); outColor = vec4(pow(d, vec3(1.0 / 2.2)), 1.0); return; } case VIEW_RAW_HDR: outColor = vec4(tonemap(texture(rawHdrImage, fragUV).rgb), 1.0); return; case VIEW_TAA: outColor = vec4(tonemap(texture(taaImage, fragUV).rgb), 1.0); return; case VIEW_BLOOM: outColor = vec4(tonemap(texture(bloomImage, fragUV).rgb * 4.0), 1.0); return; case VIEW_VELOCITY: { // |velocity| × 增益:静止=黑,运动越快越亮 vec2 vel = texture(velocityImage, fragUV).xy; float mag = clamp(length(vel) * 8.0, 0.0, 1.0); outColor = vec4(vec3(mag), 1.0); return; } case VIEW_SHADOW0: outColor = vec4(depthView(shadowMap0Image), 1.0); return; case VIEW_SHADOW1: outColor = vec4(depthView(shadowMap1Image), 1.0); return; case VIEW_SHADOW2: outColor = vec4(depthView(shadowMap2Image), 1.0); return; case VIEW_ENV_CUBE: outColor = vec4(cubeView(envCubeImage, 0.0), 1.0); return; case VIEW_IRRADIANCE: outColor = vec4(cubeView(irradianceImage, 0.0), 1.0); return; case VIEW_PREFILTER: outColor = vec4(cubeView(prefilterImage, fragUV.y * 4.0), 1.0); return; case VIEW_BRDF_LUT: { // LUT 是 (F 缩放, F 偏置) 双通道,R/G 直读可视化 vec2 ab = texture(brdfLutImage, fragUV).rg; outColor = vec4(ab, 0.0, 1.0); return; } } } // ---- 正常路径:TAA 后 HDR + bloom 叠加 → tonemap ---- vec4 hdrTex = texture(taaImage, fragUV); vec3 hdr = hdrTex.rgb + texture(bloomImage, fragUV).rgb * pc.bloomStrength; outColor = vec4(tonemap(hdr) * hdrTex.a, hdrTex.a); }