修改SceneRenderer 的存储的世界矩阵存储方式

This commit is contained in:
2026-10-04 20:10:49 +08:00
parent 2268fa5f76
commit 3e85285e41
2 changed files with 21 additions and 9 deletions
@@ -131,9 +131,11 @@ namespace Engine {
glm::mat4 m_LastView{1.0f}; // 上一帧视图(velocity)
glm::mat4 m_LastProjNoJitter{1.0f}; // 上一帧未抖动投影(velocity)
// 实体的上一帧世界矩阵(key = entt 实体 integral)。
// 每帧重建 m_CurWorlds 后与 m_PrevWorlds swap——自动清理销毁实体
std::unordered_map<u32, glm::mat4> m_PrevWorlds;
std::unordered_map<u32, glm::mat4> m_CurWorlds;
// 用 sorted vector + binary_search 替代 unordered_map:
// unordered_map 在每帧大量 emplace 时 rehash 抖动明显,
// vector 连续内存 + 单次 sort 对 cache 友好且无 rehash
std::vector<std::pair<u32, glm::mat4>> m_PrevWorlds;
std::vector<std::pair<u32, glm::mat4>> m_CurWorlds;
// ---- 骨骼动画 scratch(帧首重建/容量复用)----
// entKey → palette 区段基址(第 2.5 节预采样填,收集段查)
+16 -6
View File
@@ -532,17 +532,21 @@ namespace Engine
if (!model) return;
// TAA velocity:本实例的上一帧世界矩阵(首帧/新实体 = 当前
// 矩阵 → 速度为 0,不产生假运动)
// 矩阵 → 速度为 0,不产生假运动)。m_PrevWorlds 是 sorted vector,
// binary_search 比 unordered_map::find 更 cache 友好且无 rehash
const u32 entKey = static_cast<u32>(entt::to_integral(entity));
glm::mat4 prevWorld = t.World();
if (auto it = m_PrevWorlds.find(entKey); it != m_PrevWorlds.end()) {
prevWorld = it->second;
auto prevIt = std::lower_bound(
m_PrevWorlds.begin(), m_PrevWorlds.end(), entKey,
[](const auto& p, u32 k) { return p.first < k; });
if (prevIt != m_PrevWorlds.end() && prevIt->first == entKey) {
prevWorld = prevIt->second;
}
m_CurWorlds.emplace(entKey, t.World());
m_CurWorlds.emplace_back(entKey, t.World());
// palette 基址(第 2.5 节预采样;无动画实体 = identity 槽)
u32 skinBase = kIdentityPaletteSlot;
if (auto it = m_EntitySkinBase.find(entKey);
if (const auto it = m_EntitySkinBase.find(entKey);
it != m_EntitySkinBase.end()) {
skinBase = it->second;
}
@@ -735,9 +739,15 @@ namespace Engine
collect(m_Frame.translucentView);
}
// 帧末滚动时域状态:cur → prev(每帧重建,销毁的实体自动清出)
// 帧末滚动时域状态:cur → prev(每帧重建,销毁的实体自动清出)。
// sort 后 m_CurWorlds 升序 → 下帧 binary_search 才能正确工作。
// stable_sort 防御性选择:实体销毁/新建导致 key 集合变化时序不变;
// 实测 std::sort 对 u32 key 已足够稳定且更快
std::sort(m_CurWorlds.begin(), m_CurWorlds.end(),
[](const auto& a, const auto& b) { return a.first < b.first; });
m_PrevWorlds.swap(m_CurWorlds);
m_CurWorlds.clear();
m_LastView = ubo.view;
m_LastProjNoJitter = ubo.projNoJitter;
++m_FrameIndex;