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:
@@ -0,0 +1,44 @@
|
||||
#version 450
|
||||
|
||||
// IBL ③:环境 cube → pre-filtered cube(GGX 重要性采样,split-sum 镜面端)。
|
||||
// R(N) ≈ Σ L·NdotL / Σ NdotL。每 mip 一次 dispatch(storage view 必须
|
||||
// 单 mip),roughness 经 push constant 传入;256 采样统一(高 roughness
|
||||
// 分布更宽,取 CPU 版采样数上限保证收敛)。
|
||||
|
||||
#include "ibl_common.glsl"
|
||||
|
||||
layout(local_size_x = 8, local_size_y = 8) in;
|
||||
|
||||
layout(set = 0, binding = 0) uniform samplerCube env;
|
||||
layout(set = 0, binding = 1, rgba16f) uniform restrict writeonly image2DArray outCube;
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
float roughness;
|
||||
} pc;
|
||||
|
||||
const uint SAMPLES = 256;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec3 gid = ivec3(gl_GlobalInvocationID);
|
||||
ivec2 size = imageSize(outCube).xy;
|
||||
if (gid.x >= size.x || gid.y >= size.y) return;
|
||||
|
||||
vec2 uv = (vec2(gid.xy) + 0.5) / vec2(size);
|
||||
vec3 N = iblFaceDir(uint(gid.z), uv.x, uv.y);
|
||||
vec3 V = N; // split-sum 约定:V 沿 N
|
||||
|
||||
vec3 acc = vec3(0.0);
|
||||
float weight = 0.0;
|
||||
for (uint i = 0u; i < SAMPLES; ++i) {
|
||||
vec3 H = iblImportanceSampleGGX(iblHammersley(i, SAMPLES), N, pc.roughness);
|
||||
vec3 L = normalize(2.0 * dot(V, H) * H - V);
|
||||
float nDotL = max(dot(N, L), 0.0);
|
||||
if (nDotL > 0.0) {
|
||||
acc += texture(env, L).rgb * nDotL;
|
||||
weight += nDotL;
|
||||
}
|
||||
}
|
||||
|
||||
imageStore(outCube, gid, vec4(weight > 0.0 ? acc / weight : vec3(0.0), 1.0));
|
||||
}
|
||||
Reference in New Issue
Block a user