From 6e107ac2ba204a092260a702d5a00386152434bd Mon Sep 17 00:00:00 2001 From: atdunbg Date: Wed, 23 Sep 2026 19:07:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20IBL=20=E6=A8=A1=E5=9E=8B=E5=85=A8?= =?UTF-8?q?=E9=BB=91=E2=80=94=E2=80=94prefilter=20mip=20=E6=8B=B7=E8=B4=9D?= =?UTF-8?q?=E5=81=8F=E7=A7=BB=E9=94=99=E4=BD=8D=20+=20=E9=87=87=E6=A0=B7?= =?UTF-8?q?=E5=99=A8=20maxLod=20=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UploadCube 的 mip buffer 偏移误用当前 mip 尺寸×序号(mip 面递减, 正确应为累积偏移)→ 各 mip 拷到 staging 错位数据,含未初始化 fp16 NaN → 污染 ambient 输出整屏黑 - prefilter/irradiance 绑定改用环境采样器(maxLod=mipCount-1): shadowSampler maxLod=0 会把 textureLod 显式 lod clamp 到 0, pre-filter 永远停在最锐 mip --- Engine/src/Renderer/Cubemap.cpp | 10 ++++++++-- Engine/src/Renderer/Passes/SceneGpu.cpp | 9 ++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Engine/src/Renderer/Cubemap.cpp b/Engine/src/Renderer/Cubemap.cpp index 6a3f3cc..2f59982 100644 --- a/Engine/src/Renderer/Cubemap.cpp +++ b/Engine/src/Renderer/Cubemap.cpp @@ -328,13 +328,17 @@ namespace Engine cmd.pipelineBarrier2( vk::DependencyInfo{}.setImageMemoryBarriers(toTransfer)); + // 逐 mip 逐面拷贝;buffer 偏移必须按 mips[0..mip) 字节数累积 + //(mip 面尺寸递减,用当前 dim 乘 mip 序号会错位 → 读到 + // staging 未初始化数据 → fp16 NaN 污染整屏) + vk::DeviceSize offset = 0; for (u32 mip = 0; mip < mipCount; ++mip) { const u32 dim = mips[mip].faceSize; for (u32 f = 0; f < kFaceCount; ++f) { vk::BufferImageCopy region; region.setBufferOffset( - (static_cast(dim) * dim * 8 * - kFaceCount) * mip) + offset + static_cast(dim) * + dim * 8 * f) .setBufferRowLength(0) .setBufferImageHeight(0) .setImageSubresource({vk::ImageAspectFlagBits::eColor, @@ -345,6 +349,8 @@ namespace Engine vk::ImageLayout::eTransferDstOptimal, region); } + offset += static_cast(dim) * dim * 8 * + kFaceCount; } vk::ImageMemoryBarrier2 toShader; diff --git a/Engine/src/Renderer/Passes/SceneGpu.cpp b/Engine/src/Renderer/Passes/SceneGpu.cpp index 44b35a5..2be4183 100644 --- a/Engine/src/Renderer/Passes/SceneGpu.cpp +++ b/Engine/src/Renderer/Passes/SceneGpu.cpp @@ -166,11 +166,14 @@ namespace Engine::Passes void SceneGpu::BindEnvironment(const Cubemap& env) { - // IBL 资源 view 全程稳定(不随 RG 重编译变化),绑一次即可 + // IBL 资源 view 全程稳定(不随 RG 重编译变化),绑一次即可。 + // cube 资源必须用带 mip 的环境采样器(textureLod 显式 lod 会被 + // clamp 到 maxLod;shadowSampler maxLod=0 会让 pre-filter 永远 + // 停在最锐的 mip) for (u32 slot = 0; slot < kMaxFramesInFlight; ++slot) { - m_Descriptors.UpdateTexture(shadowSets[slot], 3, shadowSampler, + m_Descriptors.UpdateTexture(shadowSets[slot], 3, env.GetSampler(), env.GetIrradianceView()); - m_Descriptors.UpdateTexture(shadowSets[slot], 4, shadowSampler, + m_Descriptors.UpdateTexture(shadowSets[slot], 4, env.GetSampler(), env.GetPrefilteredView()); m_Descriptors.UpdateTexture(shadowSets[slot], 5, env.GetBrdfLutSampler(),