]> git.lizzy.rs Git - minetest.git/commitdiff
Add mesh-holding blocks to shadow drawlist. (#13203)
authorlhofhansl <larsh@apache.org>
Fri, 17 Feb 2023 01:43:08 +0000 (15:43 -1000)
committerGitHub <noreply@github.com>
Fri, 17 Feb 2023 01:43:08 +0000 (15:43 -1000)
When mesh chunking and shadows are enabled, make sure that the mesh-holding blocks are added to the shadow drawlist.
Otherwise those portions of the shadows will not be rendered.

src/client/clientmap.cpp

index af77e5ab2afb9b223577325e10d8be2eae366d82..39c811b85f7a15acdd6c862b975176e7dcb09fc8 100644 (file)
@@ -1121,6 +1121,9 @@ void ClientMap::updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir,
        // Number of blocks occlusion culled
        u32 blocks_occlusion_culled = 0;
 
+       std::set<v3s16> shortlist;
+       MeshGrid mesh_grid = m_client->getMeshGrid();
+
        for (auto &sector_it : m_sectors) {
                MapSector *sector = sector_it.second;
                if (!sector)
@@ -1134,8 +1137,8 @@ void ClientMap::updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir,
                        Loop through blocks in sector
                */
                for (MapBlock *block : sectorblocks) {
-                       if (!block->mesh) {
-                               // Ignore if mesh doesn't exist
+                       if (mesh_grid.cell_size == 1 && !block->mesh) {
+                               // fast out in the case of no mesh chunking
                                continue;
                        }
 
@@ -1144,6 +1147,17 @@ void ClientMap::updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir,
                        if (projection.getDistanceFrom(block_pos) > radius)
                                continue;
 
+                       if (mesh_grid.cell_size > 1) {
+                               // Block meshes are stored in the corner block of a chunk
+                               // (where all coordinate are divisible by the chunk size)
+                               // Add them to the de-dup set.
+                               shortlist.emplace(mesh_grid.getMeshPos(block->getPos()));
+                       }
+                       if (!block->mesh) {
+                               // Ignore if mesh doesn't exist
+                               continue;
+                       }
+
                        blocks_in_range_with_mesh++;
 
                        // This block is in range. Reset usage timer.
@@ -1155,6 +1169,12 @@ void ClientMap::updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir,
                        }
                }
        }
+       for (auto pos : shortlist) {
+               MapBlock * block = getBlockNoCreateNoEx(pos);
+               if (block && block->mesh && m_drawlist_shadow.emplace(pos, block).second) {
+                       block->refGrab();
+               }
+       }
 
        g_profiler->avg("SHADOW MapBlock meshes in range [#]", blocks_in_range_with_mesh);
        g_profiler->avg("SHADOW MapBlocks occlusion culled [#]", blocks_occlusion_culled);