feat: IBL 预积分 GPU compute 化 + 环境资产入 Assets 层(动态切换)
CPU 逐像素卷积(venice 4k 阻塞 7.36s)→ 4 个 compute shader 一次性 提交:equirect→cube / irradiance / prefilter×5mip / BRDF LUT。 Cubemap 瘦身为纯资源持有类,生成职责移交 IblGenerator; 环境经 AssetManager 缓存(EnvRef),Renderer::SetEnvironment 动态换绑(RenderPass::OnEnvironmentChanged 广播)。 调试视图 +4:EnvCube / Irradiance / Prefilter / BRDF LUT。 性能前后对比(RTX 5060 Laptop,venice_dawn_1_4k.hdr): - 改造前 CPU:7.36 s(主线程阻塞) - 改造后 GPU:HDR decode 127-134ms + 资源 22-35ms + compute 17-19ms ≈ 165-190ms(约 40×);Neutral 兜底 ~6ms - 运行中动态切换环境同量级(ms 级 GPU,decode 占大头) 冒烟:两构建目录 0 警告;运行期 0 validation(含两次环境切换 + 调试视图 9-12 轮播自动化验证)。
This commit is contained in:
@@ -20,6 +20,11 @@ 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;
|
||||
@@ -31,6 +36,10 @@ 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 {
|
||||
@@ -56,6 +65,19 @@ vec3 depthView(sampler2D depthImage) {
|
||||
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);
|
||||
|
||||
@@ -81,6 +103,15 @@ void main() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user