载入中...
搜索中...
未找到
MeshVfxRenderBatch.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5#include <unordered_map>
6
7namespace eve::stylize {
8namespace {
9
10struct PlannedDraw {
11 MeshVfxBatchKey key;
12 float viewDepth = 0.0f;
13 MeshVfxBatchedDraw draw;
14};
15
16bool keyLess(const MeshVfxBatchKey& lhs, const MeshVfxBatchKey& rhs) { return lhs < rhs; }
17
18void appendBatch(std::vector<MeshVfxRenderBatch>& batches, PlannedDraw&& planned) {
19 if (batches.empty() || batches.back().key != planned.key) {
20 batches.push_back(MeshVfxRenderBatch{planned.key, {}});
21 }
22 batches.back().draws.push_back(planned.draw);
23}
24
25} // namespace
26
27MeshVfxRenderQueue MeshVfxRenderBatchPlanner::build(std::span<const MeshVfxRenderItem> items,
28 std::span<const MeshVfxLodDecision> lodDecisions,
29 std::uint64_t frameIndex) const {
31 queue.stats.inputItems = static_cast<std::uint32_t>(items.size());
32
33 std::unordered_map<std::uint64_t, const MeshVfxLodDecision*> decisions;
34 decisions.reserve(lodDecisions.size());
35 for (const auto& decision : lodDecisions) {
36 decisions.try_emplace(decision.stableInstanceId, &decision);
37 }
38
39 std::vector<PlannedDraw> additive;
40 std::vector<PlannedDraw> alpha;
41 additive.reserve(items.size());
42 alpha.reserve(items.size());
43 for (const auto& item : items) {
44 const auto found = decisions.find(item.stableInstanceId);
45 if (found == decisions.end()) {
46 ++queue.stats.missingDecisions;
47 continue;
48 }
49 const auto& lod = *found->second;
50 if (lod.tier == MeshVfxLodTier::Culled) {
51 ++queue.stats.culledDraws;
52 continue;
53 }
54
55 const auto interval = std::max(1u, lod.meshUpdateInterval);
56 const auto refresh = frameIndex % interval == item.stableInstanceId % interval;
57 PlannedDraw planned{item.key,
58 std::isfinite(item.viewDepth) ? item.viewDepth : 0.0f,
59 {item.stableInstanceId,
60 lod.tier,
62 std::max(1u, lod.trailSampleStride)}};
63 if (refresh) {
65 }
66 (item.key.blend == MeshVfxBatchBlend::Additive ? additive : alpha).push_back(std::move(planned));
67 }
68
69 std::sort(additive.begin(), additive.end(), [](const PlannedDraw& lhs, const PlannedDraw& rhs) {
70 if (lhs.key != rhs.key) {
71 return keyLess(lhs.key, rhs.key);
72 }
73 return lhs.draw.stableInstanceId < rhs.draw.stableInstanceId;
74 });
75 std::sort(alpha.begin(), alpha.end(), [](const PlannedDraw& lhs, const PlannedDraw& rhs) {
76 if (lhs.viewDepth != rhs.viewDepth) {
77 return lhs.viewDepth > rhs.viewDepth;
78 }
79 if (lhs.key != rhs.key) {
80 return keyLess(lhs.key, rhs.key);
81 }
82 return lhs.draw.stableInstanceId < rhs.draw.stableInstanceId;
83 });
84
85 queue.batches.reserve(additive.size() + alpha.size());
86 for (auto& planned : additive) {
87 appendBatch(queue.batches, std::move(planned));
88 ++queue.stats.queuedDraws;
89 }
90 for (auto& planned : alpha) {
91 appendBatch(queue.batches, std::move(planned));
92 ++queue.stats.queuedDraws;
93 }
94 return queue;
95}
96
97} // namespace eve::stylize
std::uint32_t key
MeshVfxBatchedDraw draw
float viewDepth
int lod
bool found
MeshVfxRenderQueue build(std::span< const MeshVfxRenderItem > items, std::span< const MeshVfxLodDecision > lodDecisions, std::uint64_t frameIndex) const
Builds one frame's render queue.
Complete deterministic queue consumed by a graphics backend.