Return 'loops' occlusion culler under a setting (#13352)

* Add occlusion_culler setting to minetest.conf.example
* Add raytraced occlusion culling to 'loops' algorithm

---------

Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
x2048 2023-03-30 00:10:23 +02:00 committed by GitHub
parent bd88d299b9
commit 93898957b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 2 deletions

View File

@ -629,6 +629,11 @@ update_last_checked (Last update check) string
# Ex: 5.5.0 is 005005000 # Ex: 5.5.0 is 005005000
update_last_known (Last known version update) int 0 update_last_known (Last known version update) int 0
# Type of occlusion_culler
# "loops" is the legacy algorithm with nested loops and O(N^3) complexity
# "bfs" is the new algorithm based on breadth-first-search and side culling
occlusion_culler (Occlusion Culler) enum bfs bfs,loops
# Use raytraced occlusion culling in the new culler. # Use raytraced occlusion culling in the new culler.
# This flag enables use of raytraced occlusion culling test for # This flag enables use of raytraced occlusion culling test for
# client mesh sizes smaller than 4x4x4 map blocks. # client mesh sizes smaller than 4x4x4 map blocks.

View File

@ -695,6 +695,12 @@
# type: int # type: int
# update_last_known = 0 # update_last_known = 0
# Type of occlusion_culler
# "loops" is the legacy algorithm with nested loops and O(N^3) complexity
# "bfs" is the new algorithm based on breadth-first-search and side culling
# type: enum values: bfs, loops
# occlusion_culler = bfs
# Use raytraced occlusion culling in the new culler. # Use raytraced occlusion culling in the new culler.
# This flag enables use of raytraced occlusion culling test # This flag enables use of raytraced occlusion culling test
# type: bool # type: bool

View File

@ -103,18 +103,23 @@ ClientMap::ClientMap(
m_cache_bilinear_filter = g_settings->getBool("bilinear_filter"); m_cache_bilinear_filter = g_settings->getBool("bilinear_filter");
m_cache_anistropic_filter = g_settings->getBool("anisotropic_filter"); m_cache_anistropic_filter = g_settings->getBool("anisotropic_filter");
m_cache_transparency_sorting_distance = g_settings->getU16("transparency_sorting_distance"); m_cache_transparency_sorting_distance = g_settings->getU16("transparency_sorting_distance");
m_loops_occlusion_culler = g_settings->get("occlusion_culler") == "loops";
g_settings->registerChangedCallback("occlusion_culler", on_settings_changed, this);
m_enable_raytraced_culling = g_settings->getBool("enable_raytraced_culling"); m_enable_raytraced_culling = g_settings->getBool("enable_raytraced_culling");
g_settings->registerChangedCallback("enable_raytraced_culling", on_settings_changed, this); g_settings->registerChangedCallback("enable_raytraced_culling", on_settings_changed, this);
} }
void ClientMap::onSettingChanged(const std::string &name) void ClientMap::onSettingChanged(const std::string &name)
{ {
if (name == "occlusion_culler")
m_loops_occlusion_culler = g_settings->get("occlusion_culler") == "loops";
if (name == "enable_raytraced_culling") if (name == "enable_raytraced_culling")
m_enable_raytraced_culling = g_settings->getBool("enable_raytraced_culling"); m_enable_raytraced_culling = g_settings->getBool("enable_raytraced_culling");
} }
ClientMap::~ClientMap() ClientMap::~ClientMap()
{ {
g_settings->deregisterChangedCallback("occlusion_culler", on_settings_changed, this);
g_settings->deregisterChangedCallback("enable_raytraced_culling", on_settings_changed, this); g_settings->deregisterChangedCallback("enable_raytraced_culling", on_settings_changed, this);
} }
@ -298,7 +303,7 @@ void ClientMap::updateDrawList()
When range_all is enabled, enumerate all blocks visible in the When range_all is enabled, enumerate all blocks visible in the
frustum and display them. frustum and display them.
*/ */
if (m_control.range_all) { if (m_control.range_all || m_loops_occlusion_culler) {
MapBlockVect sectorblocks; MapBlockVect sectorblocks;
for (auto &sector_it : m_sectors) { for (auto &sector_it : m_sectors) {
@ -339,6 +344,14 @@ void ClientMap::updateDrawList()
continue; continue;
} }
// Raytraced occlusion culling - send rays from the camera to the block's corners
if (occlusion_culling_enabled && m_enable_raytraced_culling &&
mesh &&
isMeshOccluded(block, mesh_grid.cell_size, cam_pos_nodes)) {
blocks_occlusion_culled++;
continue;
}
if (mesh_grid.cell_size > 1) { if (mesh_grid.cell_size > 1) {
// Block meshes are stored in the corner block of a chunk // Block meshes are stored in the corner block of a chunk
// (where all coordinate are divisible by the chunk size) // (where all coordinate are divisible by the chunk size)
@ -582,6 +595,9 @@ void ClientMap::updateDrawList()
void ClientMap::touchMapBlocks() void ClientMap::touchMapBlocks()
{ {
if (!m_loops_occlusion_culler)
return;
v3s16 cam_pos_nodes = floatToInt(m_camera_position, BS); v3s16 cam_pos_nodes = floatToInt(m_camera_position, BS);
v3s16 p_blocks_min; v3s16 p_blocks_min;

View File

@ -215,6 +215,6 @@ private:
bool m_cache_anistropic_filter; bool m_cache_anistropic_filter;
u16 m_cache_transparency_sorting_distance; u16 m_cache_transparency_sorting_distance;
bool m_new_occlusion_culler; bool m_loops_occlusion_culler;
bool m_enable_raytraced_culling; bool m_enable_raytraced_culling;
}; };

View File

@ -65,6 +65,7 @@ void set_default_settings()
settings->setDefault("max_out_chat_queue_size", "20"); settings->setDefault("max_out_chat_queue_size", "20");
settings->setDefault("pause_on_lost_focus", "false"); settings->setDefault("pause_on_lost_focus", "false");
settings->setDefault("enable_split_login_register", "true"); settings->setDefault("enable_split_login_register", "true");
settings->setDefault("occlusion_culler", "bfs");
settings->setDefault("enable_raytraced_culling", "true"); settings->setDefault("enable_raytraced_culling", "true");
settings->setDefault("chat_weblink_color", "#8888FF"); settings->setDefault("chat_weblink_color", "#8888FF");