修改SceneRenderer 的存储的世界矩阵存储方式
This commit is contained in:
@@ -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 节预采样填,收集段查)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user