Files
atdunbg f73e52926f Reorganize directory layout: editor panels/, grouped shaders, drop stale header
- App/editor: move 7 panels into panels/ (Editor core stays at root)
- shaders/: group into pbr/ post/ debug/ env/ (runtime load paths updated)
- Delete outdated duplicate Engine/src/Renderer/VulkanAssetUploader.h
2026-10-07 09:52:17 +08:00

130 lines
5.8 KiB
GLSL
Raw Permalink 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
// Tonemap pass:HDR(+bloom)→ 显示空间,写 PresentTarget(offscreen,
// 由 ImGui::Image 呈现;输出位置可自由摆放)。
// 这是显示变换的显式建模(对齐 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;
const int VIEW_TRANSPARENT = 13;
// 全屏 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;
}
// Transparent 视图:场景侧已跳过天空盒/不透明绘制,
// raw HDR = 清屏色 + 透明队列内容(与 RAW_HDR 同一显示路径)
case VIEW_RAW_HDR:
case VIEW_TRANSPARENT:
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);
}