Reduce server CPU consumed by occlusion culling. (#13260)

Cache blocks already occluded at a specific distance. The RemoteClient typically visits the same distance multiple time - especially at larger distances, so this saves significant CPU from recalculating the occlusion state of blocks.
This commit is contained in:
lhofhansl 2023-03-05 21:33:41 -08:00 committed by GitHub
parent 9ef3c8ce38
commit 1f0d042377
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 4 deletions

@ -328,8 +328,15 @@ void RemoteClient::GetNextBlocks (
continue; continue;
} }
/*
Check occlusion cache first.
*/
if (m_blocks_occ.find(p) != m_blocks_occ.end())
continue;
if (m_occ_cull && !block_not_found && if (m_occ_cull && !block_not_found &&
env->getMap().isBlockOccluded(block, cam_pos_nodes)) { env->getMap().isBlockOccluded(block, cam_pos_nodes)) {
m_blocks_occ.insert(p);
continue; continue;
} }
} }
@ -395,8 +402,11 @@ queue_full_break:
} }
} }
if (new_nearest_unsent_d != -1) if (new_nearest_unsent_d != -1 && m_nearest_unsent_d != new_nearest_unsent_d) {
m_nearest_unsent_d = new_nearest_unsent_d; m_nearest_unsent_d = new_nearest_unsent_d;
// if the distance has changed, clear the occlusion cache
m_blocks_occ.clear();
}
} }
void RemoteClient::GotBlock(v3s16 p) void RemoteClient::GotBlock(v3s16 p)

@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <list> #include <list>
#include <vector> #include <vector>
#include <set> #include <set>
#include <unordered_set>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
@ -379,7 +380,15 @@ private:
List of block positions. List of block positions.
No MapBlock* is stored here because the blocks can get deleted. No MapBlock* is stored here because the blocks can get deleted.
*/ */
std::set<v3s16> m_blocks_sent; std::unordered_set<v3s16> m_blocks_sent;
/*
Cache of blocks that have been occlusion culled at the current distance.
As GetNextBlocks traverses the same distance multiple times, this saves
significant CPU time.
*/
std::unordered_set<v3s16> m_blocks_occ;
s16 m_nearest_unsent_d = 0; s16 m_nearest_unsent_d = 0;
v3s16 m_last_center; v3s16 m_last_center;
v3f m_last_camera_dir; v3f m_last_camera_dir;
@ -399,7 +408,7 @@ private:
Block is removed when GOTBLOCKS is received. Block is removed when GOTBLOCKS is received.
Value is time from sending. (not used at the moment) Value is time from sending. (not used at the moment)
*/ */
std::map<v3s16, float> m_blocks_sending; std::unordered_map<v3s16, float> m_blocks_sending;
/* /*
Blocks that have been modified since blocks were Blocks that have been modified since blocks were
@ -409,7 +418,7 @@ private:
List of block positions. List of block positions.
*/ */
std::set<v3s16> m_blocks_modified; std::unordered_set<v3s16> m_blocks_modified;
/* /*
Count of excess GotBlocks(). Count of excess GotBlocks().