feat: Shadow pass 接入 RenderGraph,支持 SRT 变换与程序化平面
阴影(本修正的核心根因):
- Shadow pass 光源正交写深度(2048 D32),Forward 采样比较;
写入与采样共用同一 lightSpace 矩阵,杜绝姿态/镜像不一致
- 修复:push constant range 64B→128B(原 Shadow pass 推 {lightVP,model}
超出 layout 声明范围 = UB,阴影中模型矩阵读到垃圾导致旋转错乱)
- 修复:ShadowFactor 缺少 NDC→UV 映射(*0.5+0.5),采样区域整体错位
- 修复:RG ShaderRead stage 位值直转(eFragment=0x10 在 PipelineStage2
是 TESSELLATION_CONTROL),改为逐位显式映射
- Camera perspective 深度重映射到 Vulkan [0,1](公式与 ortho 不同:
M22=M22*0.5-0.5, M32*=0.5);光源 ortho remap 用 M32=M32*0.5+0.5
引擎配套:
- TransformComponent 重构为 position/rotation/scale + Compose()
- Texture::CreateSolidColor / Model::CreatePlane 程序化资产
(两段式上传公共路径),AssetManager.CreatePlane 带缓存入口
- RG 新增 GetPhysicalView(h, slot):按帧槽位把 RG 资源绑进外部描述符
(阴影图 per-slot 物理镜像各自绑定)
验证:validation 0 error 0 warning,阴影随实体旋转正确
This commit is contained in:
@@ -28,8 +28,31 @@ namespace Engine
|
||||
return;
|
||||
}
|
||||
|
||||
m_Width = static_cast<u32>(width);
|
||||
m_Height = static_cast<u32>(height);
|
||||
InitFromPixels(pixels, static_cast<u32>(width), static_cast<u32>(height));
|
||||
|
||||
stbi_image_free(pixels);
|
||||
|
||||
ENGINE_INFO("Texture loaded: {} ({}x{})", path, m_Width, m_Height);
|
||||
}
|
||||
|
||||
Texture::Texture(Device& device, MemoryAllocator& allocator, ProceduralTag,
|
||||
const std::array<u8, 4>& rgba)
|
||||
: m_Device(device) , m_Allocator(allocator)
|
||||
{
|
||||
const u8 pixels[4] = { rgba[0], rgba[1], rgba[2], rgba[3] };
|
||||
InitFromPixels(pixels, 1, 1);
|
||||
}
|
||||
|
||||
Scope<Texture> Texture::CreateSolidColor(Device& device, MemoryAllocator& allocator,
|
||||
u8 r, u8 g, u8 b)
|
||||
{
|
||||
return Scope<Texture>(new Texture(device, allocator, ProceduralTag{}, {r, g, b, 255}));
|
||||
}
|
||||
|
||||
void Texture::InitFromPixels(const void* pixels, u32 width, u32 height)
|
||||
{
|
||||
m_Width = width;
|
||||
m_Height = height;
|
||||
vk::DeviceSize imageSize = static_cast<vk::DeviceSize>(width) *
|
||||
static_cast<vk::DeviceSize>(height) * 4; // RGBA8
|
||||
|
||||
@@ -42,7 +65,7 @@ namespace Engine
|
||||
vk::Buffer stagingBuffer = m_Device.GetDevice().createBuffer(stagingInfo);
|
||||
|
||||
auto stagingReqs = m_Device.GetDevice().getBufferMemoryRequirements(stagingBuffer);
|
||||
auto stagingAlloc = allocator.Allocate(
|
||||
auto stagingAlloc = m_Allocator.Allocate(
|
||||
stagingReqs,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||
@@ -52,8 +75,6 @@ namespace Engine
|
||||
// 3. 拷贝像素到 Staging Buffer
|
||||
std::memcpy(stagingAlloc.MappedPtr, pixels, static_cast<size_t>(imageSize));
|
||||
|
||||
stbi_image_free(pixels);
|
||||
|
||||
// 4. 创建 Device Local Image
|
||||
vk::ImageCreateInfo imageInfo;
|
||||
imageInfo.setImageType(vk::ImageType::e2D)
|
||||
@@ -70,7 +91,7 @@ namespace Engine
|
||||
m_Image = m_Device.GetDevice().createImage(imageInfo);
|
||||
|
||||
auto imageReqs = m_Device.GetDevice().getImageMemoryRequirements(m_Image);
|
||||
auto imageAlloc = allocator.Allocate(imageReqs, vk::MemoryPropertyFlagBits::eDeviceLocal);
|
||||
auto imageAlloc = m_Allocator.Allocate(imageReqs, vk::MemoryPropertyFlagBits::eDeviceLocal);
|
||||
|
||||
m_ImageAllocation = imageAlloc;
|
||||
|
||||
@@ -185,12 +206,9 @@ namespace Engine
|
||||
m_Device.GetDevice().destroyFence(fence);
|
||||
m_Device.GetDevice().destroyCommandPool(pool);
|
||||
m_Device.GetDevice().destroyBuffer(stagingBuffer);
|
||||
allocator.Free(stagingAlloc);
|
||||
m_Allocator.Free(stagingAlloc);
|
||||
// staging 内存由 MemoryAllocator 统一释放
|
||||
|
||||
ENGINE_INFO("Texture loaded: {} ({}x{})", path, m_Width, m_Height);
|
||||
|
||||
|
||||
// 显存占用 = 宽 * 高 * 4 字节(RGBA8)
|
||||
m_TextureBytes = static_cast<u64>(m_Width) * m_Height * 4;
|
||||
STATS.AddTexture(m_TextureBytes);
|
||||
|
||||
Reference in New Issue
Block a user