TAA 时域速度链路贯通:天空盒补写 velocity(此前恒 0,相机移动时天空/背景重投影错误 → 闪烁);skyPrevVP(上一帧未抖动 proj × 去平移视图)落帧;TAA 加去遮挡深度检测(重投影点历史深度与当前像素比对,新暴露区拒历史,需 near/far + 投影模式落帧);移除 min-depth dilation(把前景速度泄漏给轮廓旁背景像素 → 边界闪);Forward 不透明段 velocity 附件 Clear→Load 承接天空结果;velocity 不入抖动注释订正(抖动进 velocity = 静止画面持续亚纹素重采样发糊)
This commit is contained in:
@@ -35,7 +35,8 @@ namespace Engine {
|
||||
// env 可为空(HDR 资产缺失):仅承担清屏,天空保持清屏色
|
||||
SkyboxPass(Device& device, ShaderManager& shaders,
|
||||
DescriptorManager& descriptors, FrameSceneData& frame,
|
||||
RG::TextureHandle hdrColor, const Cubemap* env);
|
||||
RG::TextureHandle hdrColor, RG::TextureHandle velocity,
|
||||
const Cubemap* env);
|
||||
~SkyboxPass();
|
||||
|
||||
SkyboxPass(const SkyboxPass&) = delete;
|
||||
@@ -49,10 +50,11 @@ namespace Engine {
|
||||
DescriptorManager& m_Descriptors;
|
||||
FrameSceneData& m_Frame;
|
||||
RG::TextureHandle m_HDRColor;
|
||||
RG::TextureHandle m_Velocity; // 天空 velocity 附件(TAA)
|
||||
const Cubemap* m_Env; // 可空
|
||||
|
||||
vk::DescriptorSetLayout m_SetLayout; // Set0 = {samplerCube}
|
||||
vk::PipelineLayout m_Layout; // push = invVP 64B
|
||||
vk::PipelineLayout m_Layout; // push = {invVP, prevVP} 128B
|
||||
ShaderManager::ShaderRef m_Vert, m_Frag; // 析构自动销毁
|
||||
std::array<vk::DescriptorSet, kMaxFramesInFlight> m_Sets{};
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Engine::Passes {
|
||||
public:
|
||||
TAAPass(FullscreenGpu& gpu, FrameSceneData& frame, f32 historyAlpha,
|
||||
RG::TextureHandle hdrColor, RG::TextureHandle velocity,
|
||||
RG::TextureHandle taaColor);
|
||||
RG::TextureHandle depth, RG::TextureHandle taaColor);
|
||||
~TAAPass() override = default;
|
||||
|
||||
void Register(RG::RenderGraph& rg) override;
|
||||
@@ -34,6 +34,7 @@ namespace Engine::Passes {
|
||||
f32 m_HistoryAlpha; // 开启时的历史权重
|
||||
RG::TextureHandle m_HDR;
|
||||
RG::TextureHandle m_Velocity;
|
||||
RG::TextureHandle m_Depth; // 场景深度(深度感知 dilation 用)
|
||||
RG::TextureHandle m_TAAColor; // 输出 = 下一帧的历史
|
||||
|
||||
std::vector<vk::DescriptorSet> m_Sets; // per-slot
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace Engine {
|
||||
// ---- TAA 时域状态 ----
|
||||
u64 m_FrameIndex = 0; // 抖动序列游标(Halton 2,3 ×8 采样)
|
||||
glm::mat4 m_LastView{1.0f}; // 上一帧视图(velocity)
|
||||
glm::mat4 m_LastProjNoJitter{1.0f}; // 上一帧未抖动投影(velocity)
|
||||
glm::mat4 m_LastProjNoJitter{1.0f}; // 上一帧未抖动投影(velocity 用)
|
||||
// 实体的上一帧世界矩阵(key = entt 实体 integral)。
|
||||
// 用 sorted vector + binary_search 替代 unordered_map:
|
||||
// unordered_map 在每帧大量 emplace 时 rehash 抖动明显,
|
||||
|
||||
@@ -164,9 +164,9 @@ namespace Engine {
|
||||
LightData lights[kMaxLights];
|
||||
|
||||
// ---- TAA(velocity 在 vertex 里算)----
|
||||
glm::mat4 projNoJitter; // 未抖动投影(velocity 当前帧 clip 用)
|
||||
glm::mat4 projNoJitter; // 未抖动投影(天空盒反投影/折射同位采样/静态预览)
|
||||
glm::mat4 prevView; // 上一帧视图(velocity)
|
||||
glm::mat4 prevProj; // 上一帧未抖动投影(velocity)
|
||||
glm::mat4 prevProj; // 上一帧"已抖动"投影(velocity 历史 UV 对齐)
|
||||
glm::vec4 cameraPos; // 相机世界位置(高光 V 向量)
|
||||
};
|
||||
|
||||
@@ -183,6 +183,13 @@ namespace Engine {
|
||||
struct FrameSceneData {
|
||||
UniformBufferObject ubo{};
|
||||
|
||||
// 相机裁剪面 + 投影模式(TAA 去遮挡检测用:把 [0,1] 深度线性化为
|
||||
// 视图空间距离再比较。透视深度非线性,需 n·f/(f−d(f−n));正交
|
||||
// 深度本身线性,用 cameraOrtho 分支)
|
||||
f32 cameraNearZ = 0.1f;
|
||||
f32 cameraFarZ = 10000.0f;
|
||||
bool cameraOrtho = false;
|
||||
|
||||
glm::vec4 ClearColor{0.1, 0.1, 0.1, 1.0};
|
||||
bool DrawSkybox = true;
|
||||
// 本帧生效的环境贴图资产路径(来自第一个 active 的
|
||||
@@ -194,6 +201,12 @@ namespace Engine {
|
||||
//(视图去平移只留旋转 → 反投影结果即世界方向;Skybox pass push)
|
||||
glm::mat4 skyInvVP{1.0f};
|
||||
|
||||
// 天空盒 velocity 用:上一帧未抖动 proj × 上一帧视图(去平移)。
|
||||
// 天空是"无限远"表面,只受相机旋转影响:frag 把当前世界方向过
|
||||
// 此矩阵得上一帧屏幕位置,差即天空的运动向量(相机移动时天空/
|
||||
// 背景不再闪烁的根治点——此前天空从不写 velocity = 恒 0)
|
||||
glm::mat4 skyPrevVP{1.0f};
|
||||
|
||||
// 实例矩阵数组 = [主视图段 | 阴影视图段](共享同一 per-slot SSBO)
|
||||
std::vector<glm::mat4> instanceModels;
|
||||
// 上一帧世界矩阵,与 instanceModels 平行对齐(同一下标 = 同一
|
||||
|
||||
Reference in New Issue
Block a user