mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Distribute shadow map update over multiple frames to reduce stutter (#11422)
Reduces stutter and freezes when playing. * Maintains double SM and SM Color textures * Light frustum update triggers incremental generation of shadow map into secondary 'future' textures. * Every incremental update renders a portion of the shadow draw list (split equally). * After defined number of frames (currently, 4), 'future' and 'current' textures are swapped, and DirectionalLight 'commits' the new frustum to use when rendering shadows on screen. Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
parent
ff2d2a6e93
commit
bf3acbf388
10 changed files with 224 additions and 72 deletions
|
@ -636,7 +636,7 @@ void ClientMap::PrintInfo(std::ostream &out)
|
|||
}
|
||||
|
||||
void ClientMap::renderMapShadows(video::IVideoDriver *driver,
|
||||
const video::SMaterial &material, s32 pass)
|
||||
const video::SMaterial &material, s32 pass, int frame, int total_frames)
|
||||
{
|
||||
bool is_transparent_pass = pass != scene::ESNRP_SOLID;
|
||||
std::string prefix;
|
||||
|
@ -650,7 +650,23 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
|
|||
|
||||
MeshBufListList drawbufs;
|
||||
|
||||
int count = 0;
|
||||
int low_bound = is_transparent_pass ? 0 : m_drawlist_shadow.size() / total_frames * frame;
|
||||
int high_bound = is_transparent_pass ? m_drawlist_shadow.size() : m_drawlist_shadow.size() / total_frames * (frame + 1);
|
||||
|
||||
// transparent pass should be rendered in one go
|
||||
if (is_transparent_pass && frame != total_frames - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto &i : m_drawlist_shadow) {
|
||||
// only process specific part of the list & break early
|
||||
++count;
|
||||
if (count <= low_bound)
|
||||
continue;
|
||||
if (count > high_bound)
|
||||
break;
|
||||
|
||||
v3s16 block_pos = i.first;
|
||||
MapBlock *block = i.second;
|
||||
|
||||
|
@ -705,6 +721,7 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
|
|||
local_material.MaterialType = material.MaterialType;
|
||||
local_material.BackfaceCulling = material.BackfaceCulling;
|
||||
local_material.FrontfaceCulling = material.FrontfaceCulling;
|
||||
local_material.BlendOperation = material.BlendOperation;
|
||||
local_material.Lighting = false;
|
||||
driver->setMaterial(local_material);
|
||||
|
||||
|
@ -720,6 +737,12 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
|
|||
}
|
||||
}
|
||||
|
||||
// restore the driver material state
|
||||
video::SMaterial clean;
|
||||
clean.BlendOperation = video::EBO_ADD;
|
||||
driver->setMaterial(clean); // reset material to defaults
|
||||
driver->draw3DLine(v3f(), v3f(), video::SColor(0));
|
||||
|
||||
g_profiler->avg(prefix + "draw meshes [ms]", draw.stop(true));
|
||||
g_profiler->avg(prefix + "vertices drawn [#]", vertex_count);
|
||||
g_profiler->avg(prefix + "drawcalls [#]", drawcall_count);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue