feat: TAA 时域抗锯齿(velocity + 邻域 clamp + 子像素抖动)
- Velocity buffer:Forward 第二颜色附件,vertex 计算 clip 空间运动向量 (UBO 尾部追加 projNoJitter/prevView/prevProj;上一帧实例矩阵 SSBO Set0 binding2,与当前实例数组平行对齐——转动的物体速度正确不鬼影) - 子像素抖动:SceneRenderer Halton(2,3)×8 序列,抖动只进光栅化投影 - TAA resolve pass:velocity 反推历史位置 + 3×3 邻域 clamp 去鬼影 + mix(cur,hist,0.9) 时域累积;TAAColor 自引用历史 - RG 历史读补 post-barrier:采样后恢复镜像 resting layout(TAA 的历史 是 ColorAttachment layout,不恢复则下帧 entry oldLayout 脱节) - 管线:Forward(HDR+Velocity) → TAA(TAAColor) → Bloom/Tonemap 改源 TAAColor - 编译零错误、validation 零警告、8 秒冒烟通过(10 pass 全活跃)
This commit is contained in:
@@ -177,6 +177,7 @@ namespace Engine::RG {
|
||||
for (auto& pass : m_Passes) {
|
||||
pass.culled = false;
|
||||
pass.barriers.clear();
|
||||
pass.postBarriers.clear();
|
||||
}
|
||||
|
||||
for (auto& entry : m_Textures) ResolveUsage(entry);
|
||||
@@ -468,6 +469,20 @@ namespace Engine::RG {
|
||||
.setOldLayout(entry.restingLayout);
|
||||
|
||||
pass.barriers.push_back({use.resIndex, steady, first, true});
|
||||
|
||||
// 出口 barrier:采样完成后把历史镜像转回 resting layout。
|
||||
// (若 desired == resting 则是无害的空转换,但保留它以
|
||||
// 统一语义——src scope 同时给出读取完成的内存序)
|
||||
vk::ImageMemoryBarrier2 exit;
|
||||
exit.setSrcStageMask(dstStage)
|
||||
.setSrcAccessMask(dstAccess)
|
||||
.setDstStageMask(vk::PipelineStageFlagBits2::eNone)
|
||||
.setDstAccessMask(vk::AccessFlagBits2::eNone)
|
||||
.setOldLayout(desiredLayout)
|
||||
.setNewLayout(entry.restingLayout)
|
||||
.setSubresourceRange({entry.aspect, 0, 1, 0, 1});
|
||||
pass.postBarriers.push_back({use.resIndex, exit, exit, true});
|
||||
|
||||
continue; // 不推进 chain:本帧链只描述当前槽位镜像
|
||||
}
|
||||
|
||||
@@ -763,6 +778,21 @@ namespace Engine::RG {
|
||||
pass.exec(ctx);
|
||||
}
|
||||
|
||||
// 历史读出口:恢复上一帧槽位镜像的 resting layout
|
||||
if (!pass.postBarriers.empty()) {
|
||||
m_ScratchBarriers.clear();
|
||||
for (const auto& bp : pass.postBarriers) {
|
||||
auto& entry = m_Textures[bp.resIndex];
|
||||
const u32 histSlot = HistorySlot(frame.frameSlot);
|
||||
vk::ImageMemoryBarrier2 b = bp.steady;
|
||||
b.setImage(entry.physical[histSlot]->image);
|
||||
m_ScratchBarriers.push_back(b);
|
||||
}
|
||||
vk::DependencyInfo dep;
|
||||
dep.setImageMemoryBarriers(m_ScratchBarriers);
|
||||
frame.cmd.pipelineBarrier2(dep);
|
||||
}
|
||||
|
||||
if (m_QueryPool) {
|
||||
frame.cmd.writeTimestamp2(
|
||||
vk::PipelineStageFlagBits2::eBottomOfPipe,
|
||||
|
||||
Reference in New Issue
Block a user