阴影(本修正的核心根因):
- 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,阴影随实体旋转正确
71 lines
2.3 KiB
C++
71 lines
2.3 KiB
C++
//
|
||
// Created by atdunbg on 2026/9/22.
|
||
//
|
||
|
||
#include <Engine/Renderer/Camera.h>
|
||
#include <Engine/Core/Window.h>
|
||
|
||
#include <glm/gtc/matrix_transform.hpp>
|
||
|
||
#include "GLFW/glfw3.h"
|
||
|
||
namespace Engine {
|
||
|
||
void Camera::Update(Window& window, f32 deltaTime)
|
||
{
|
||
// 鼠标旋转(需显式启用,配合 cursor capture 使用)
|
||
if (m_MouseLookEnabled)
|
||
{
|
||
f32 mouseDX = 0, mouseDY = 0;
|
||
window.GetMouseDelta(mouseDX, mouseDY);
|
||
|
||
if (mouseDX != 0 || mouseDY != 0)
|
||
{
|
||
m_Yaw += mouseDX * m_MouseSensitivity;
|
||
m_Pitch -= mouseDY * m_MouseSensitivity;
|
||
m_Pitch = glm::clamp(m_Pitch, -89.0f, 89.0f);
|
||
}
|
||
}
|
||
|
||
UpdateBasis();
|
||
|
||
f32 speed = m_MoveSpeed * deltaTime;
|
||
if (window.IsKeyPressed(GLFW_KEY_W)) m_Position += m_Forward * speed;
|
||
if (window.IsKeyPressed(GLFW_KEY_S)) m_Position -= m_Forward * speed;
|
||
if (window.IsKeyPressed(GLFW_KEY_A)) m_Position -= m_Right * speed;
|
||
if (window.IsKeyPressed(GLFW_KEY_D)) m_Position += m_Right * speed;
|
||
if (window.IsKeyPressed(GLFW_KEY_SPACE)) m_Position.y += speed;
|
||
if (window.IsKeyPressed(GLFW_KEY_LEFT_SHIFT)) m_Position.y -= speed;
|
||
}
|
||
|
||
void Camera::UpdateBasis()
|
||
{
|
||
m_Forward.x = cosf(glm::radians(m_Yaw)) * cosf(glm::radians(m_Pitch));
|
||
m_Forward.y = sinf(glm::radians(m_Pitch));
|
||
m_Forward.z = sinf(glm::radians(m_Yaw)) * cosf(glm::radians(m_Pitch));
|
||
m_Forward = glm::normalize(m_Forward);
|
||
|
||
m_Right = glm::normalize(glm::cross(m_Forward, glm::vec3(0, 1, 0)));
|
||
m_Up = glm::normalize(glm::cross(m_Right, m_Forward));
|
||
}
|
||
|
||
glm::mat4 Camera::GetView() const
|
||
{
|
||
return glm::lookAt(m_Position, m_Position + m_Forward, m_Up);
|
||
}
|
||
|
||
glm::mat4 Camera::GetProjection(f32 aspect, f32 nearZ, f32 farZ) const
|
||
{
|
||
auto proj = glm::perspective(glm::radians(45.0f), aspect, nearZ, farZ);
|
||
proj[1][1] *= -1.0f; // Vulkan Y 翻转
|
||
|
||
// Vulkan clip 深度 [0,1]:z' = 0.5*z_clip + 0.5*w_clip。
|
||
// perspective 的 w_clip = -z_eye,偏移折算进 z 系数
|
||
//(注意:与 ortho 的公式不同,ortho 的 w=1 才能直接加到 [3][2])
|
||
proj[2][2] = proj[2][2] * 0.5f - 0.5f;
|
||
proj[3][2] *= 0.5f;
|
||
return proj;
|
||
}
|
||
|
||
} // namespace Engine
|