diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index ec71f1998..93abd3575 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -2061,8 +2061,8 @@ liquid_update (Liquid update tick) float 1.0 0.001 # as well as sometimes on land). # Setting this to a value greater than max_block_send_distance disables this # optimization. -# Stated in mapblocks (16 nodes). -block_send_optimize_distance (Block send optimize distance) int 4 2 32767 +# Stated in MapBlocks (16 nodes). +block_send_optimize_distance (Block send optimize distance) int 4 2 2047 # If enabled, the server will perform map block occlusion culling based on # on the eye position of the player. This can reduce the number of blocks @@ -2070,6 +2070,13 @@ block_send_optimize_distance (Block send optimize distance) int 4 2 32767 # invisible blocks, so that the utility of noclip mode is reduced. server_side_occlusion_culling (Server-side occlusion culling) bool true +# At this distance the server will perform a simpler and cheaper occlusion check. +# Smaller values potentially improve performance, at the expense of temporarily visible +# rendering glitches (missing blocks). +# This is especially useful for very large viewing range (upwards of 500). +# Stated in MapBlocks (16 nodes). +block_cull_optimize_distance (Block cull optimize distance) int 20 2 2047 + [**Mapgen] # Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes). diff --git a/src/clientiface.cpp b/src/clientiface.cpp index e609c98f6..33d07364a 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -59,6 +59,7 @@ RemoteClient::RemoteClient() : g_settings->getFloat("full_block_send_enable_min_time_from_building")), m_max_send_distance(g_settings->getS16("max_block_send_distance")), m_block_optimize_distance(g_settings->getS16("block_send_optimize_distance")), + m_block_cull_optimize_distance(g_settings->getS16("block_cull_optimize_distance")), m_max_gen_distance(g_settings->getS16("max_block_generate_distance")), m_occ_cull(g_settings->getBool("server_side_occlusion_culling")) { @@ -225,6 +226,8 @@ void RemoteClient::GetNextBlocks ( wanted_range); const s16 d_opt = std::min(adjustDist(m_block_optimize_distance, prop_zoom_fov), wanted_range); + const s16 d_cull_opt = std::min(adjustDist(m_block_cull_optimize_distance, prop_zoom_fov), + wanted_range); const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE; s16 d_max_gen = std::min(adjustDist(m_max_gen_distance, prop_zoom_fov), @@ -355,7 +358,7 @@ void RemoteClient::GetNextBlocks ( continue; if (m_occ_cull && !block_not_found && - env->getMap().isBlockOccluded(block, cam_pos_nodes)) { + env->getMap().isBlockOccluded(block, cam_pos_nodes, d >= d_cull_opt)) { m_blocks_occ.insert(p); continue; } diff --git a/src/clientiface.h b/src/clientiface.h index 261c09fce..c531d743a 100644 --- a/src/clientiface.h +++ b/src/clientiface.h @@ -397,6 +397,7 @@ private: const float m_min_time_from_building; const s16 m_max_send_distance; const s16 m_block_optimize_distance; + const s16 m_block_cull_optimize_distance; const s16 m_max_gen_distance; const bool m_occ_cull; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index a815f89ed..6a48a9b40 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -393,6 +393,7 @@ void set_default_settings() // This causes frametime jitter on client side, or does it? settings->setDefault("max_block_send_distance", "12"); settings->setDefault("block_send_optimize_distance", "4"); + settings->setDefault("block_cull_optimize_distance", "20"); settings->setDefault("server_side_occlusion_culling", "true"); settings->setDefault("csm_restriction_flags", "62"); settings->setDefault("csm_restriction_noderange", "0"); diff --git a/src/map.cpp b/src/map.cpp index c44e31193..f63732cf4 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1155,7 +1155,7 @@ bool Map::isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target, return false; } -bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes) +bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes, bool simple_check) { // Check occlusion for center and all 8 corners of the mapblock // Overshoot a little for less flickering @@ -1193,6 +1193,14 @@ bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes) // this is a HACK, we should think of a more precise algorithm u32 needed_count = 2; + v3s16 random_point(myrand_range(-bs2, bs2), myrand_range(-bs2, bs2), myrand_range(-bs2, bs2)); + if (!isOccluded(cam_pos_nodes, pos_blockcenter + random_point, step, stepfac, + start_offset, end_offset, needed_count)) + return false; + + if (simple_check) + return true; + // Additional occlusion check, see comments in that function v3s16 check; if (determineAdditionalOcclusionCheck(cam_pos_nodes, block->getBox(), check)) { diff --git a/src/map.h b/src/map.h index 07f6c56e8..543e2e89b 100644 --- a/src/map.h +++ b/src/map.h @@ -305,7 +305,7 @@ public: } } - bool isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes); + bool isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes, bool simple_check = false); protected: IGameDef *m_gamedef;