fix: IBL 模型全黑——prefilter mip 拷贝偏移错位 + 采样器 maxLod 错误
- 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
This commit is contained in:
@@ -328,13 +328,17 @@ namespace Engine
|
|||||||
cmd.pipelineBarrier2(
|
cmd.pipelineBarrier2(
|
||||||
vk::DependencyInfo{}.setImageMemoryBarriers(toTransfer));
|
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) {
|
for (u32 mip = 0; mip < mipCount; ++mip) {
|
||||||
const u32 dim = mips[mip].faceSize;
|
const u32 dim = mips[mip].faceSize;
|
||||||
for (u32 f = 0; f < kFaceCount; ++f) {
|
for (u32 f = 0; f < kFaceCount; ++f) {
|
||||||
vk::BufferImageCopy region;
|
vk::BufferImageCopy region;
|
||||||
region.setBufferOffset(
|
region.setBufferOffset(
|
||||||
(static_cast<vk::DeviceSize>(dim) * dim * 8 *
|
offset + static_cast<vk::DeviceSize>(dim) *
|
||||||
kFaceCount) * mip)
|
dim * 8 * f)
|
||||||
.setBufferRowLength(0)
|
.setBufferRowLength(0)
|
||||||
.setBufferImageHeight(0)
|
.setBufferImageHeight(0)
|
||||||
.setImageSubresource({vk::ImageAspectFlagBits::eColor,
|
.setImageSubresource({vk::ImageAspectFlagBits::eColor,
|
||||||
@@ -345,6 +349,8 @@ namespace Engine
|
|||||||
vk::ImageLayout::eTransferDstOptimal,
|
vk::ImageLayout::eTransferDstOptimal,
|
||||||
region);
|
region);
|
||||||
}
|
}
|
||||||
|
offset += static_cast<vk::DeviceSize>(dim) * dim * 8 *
|
||||||
|
kFaceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::ImageMemoryBarrier2 toShader;
|
vk::ImageMemoryBarrier2 toShader;
|
||||||
|
|||||||
@@ -166,11 +166,14 @@ namespace Engine::Passes
|
|||||||
|
|
||||||
void SceneGpu::BindEnvironment(const Cubemap& env)
|
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) {
|
for (u32 slot = 0; slot < kMaxFramesInFlight; ++slot) {
|
||||||
m_Descriptors.UpdateTexture(shadowSets[slot], 3, shadowSampler,
|
m_Descriptors.UpdateTexture(shadowSets[slot], 3, env.GetSampler(),
|
||||||
env.GetIrradianceView());
|
env.GetIrradianceView());
|
||||||
m_Descriptors.UpdateTexture(shadowSets[slot], 4, shadowSampler,
|
m_Descriptors.UpdateTexture(shadowSets[slot], 4, env.GetSampler(),
|
||||||
env.GetPrefilteredView());
|
env.GetPrefilteredView());
|
||||||
m_Descriptors.UpdateTexture(shadowSets[slot], 5,
|
m_Descriptors.UpdateTexture(shadowSets[slot], 5,
|
||||||
env.GetBrdfLutSampler(),
|
env.GetBrdfLutSampler(),
|
||||||
|
|||||||
Reference in New Issue
Block a user