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(),