17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-23 00:41:11 +02:00

perf(gl46): skip shapes out of the pass frustum and the motion blur when nothing moves

This commit is contained in:
2026-10-20 15:23:03 +02:00
parent dfbe8a6d9e
commit 6a109e984c
2 changed files with 33 additions and 3 deletions

View File

@@ -743,6 +743,9 @@ bool opengl46_renderer::Render()
m_scenecommandstream->next_frame();
m_renderpass.draw_mode = rendermode::none; // force setup anew
// the vehicles which moved in the last frame (motion blur)
m_vehiclesmoved = m_vehiclesmoving;
m_vehiclesmoving = false;
m_renderpass.draw_stats = debug_stats();
m_geometry.primitives_count() = 0;
@@ -1285,11 +1288,20 @@ void opengl46_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
if (vp.main && !vp.custom_backbuffer) // TODO: update window sizes also for extra viewports
target_size = Global.fb_size;
// the motion blur only when something in the view moves: the vehicle of the camera, or a vehicle drawn in the last frame.
// with nothing moving the velocity is zero everywhere, the blur takes a single sample of each pixel and gives back the
// image it was given, so the velocity target, its resolve and the blur are left out and the picture stays the same.
// a vehicle setting off is blurred from its second frame, when its velocity is still far below a pixel
auto const motionblur{
Global.gfx_postfx_motionblur_enabled
&& (m_vehiclesmoved
|| ((Global.pCamera.m_owner != nullptr) && (Global.pCamera.m_owner->get_future_movement() != glm::dvec3{0.0})))};
if (!Global.gfx_skippipeline)
{
vp.msaa_fb->bind();
if (Global.gfx_postfx_motionblur_enabled)
if (motionblur)
vp.msaa_fb->setup_drawing(2);
else
vp.msaa_fb->setup_drawing(1);
@@ -1511,7 +1523,7 @@ if (!Global.gfx_skippipeline)
gpupart("resolve, ambient occlusion, motion blur");
// the targets of the ambient occlusion are there only when it was on at the start
auto const aomode{(vp.ssao_tex != nullptr) ? Global.gfx_postfx_ao : 0};
if (Global.gfx_postfx_motionblur_enabled)
if (motionblur)
{
vp.main_fb->clear(GL_COLOR_BUFFER_BIT);
vp.main_fb->setup_drawing(2);
@@ -1543,7 +1555,7 @@ if (!Global.gfx_skippipeline)
// (gfx.shadow.sdsm). the main framebuffer holds it resolved for the motion blur or the ambient occlusion
if (vp.main && Global.gfx_shadow_sdsm && (Shadow_Fit_Unavailable(vp) == nullptr))
{
auto const resolved{(vp.main_texd != nullptr) && (Global.gfx_postfx_motionblur_enabled || (aomode != 0))};
auto const resolved{(vp.main_texd != nullptr) && (motionblur || (aomode != 0))};
opengl46_shadow_fit::view const view{
m_colorpass.pass_camera.position(),
m_colorpass.pass_camera.projection(),
@@ -3769,6 +3781,15 @@ void opengl46_renderer::Render(scene::shape_node const &Shape, bool const Ignore
{
auto const &data{Shape.data()};
// a shape lying wholly outside the view of the pass draws nothing. the section and the cell holding it were tested as a
// whole, while a section holds the chunks of the heightmap terrain (250 m each, 16 of them) and the large shapes of the
// scenery, drawn in every pass the section is seen in: in a cascade of the sun shadows or a face of the environment map
// most of them are out of view. a shape merged from others has its radius invalidated (-1) and keeps being drawn
if ((data.area.radius > 0.f) && (false == m_renderpass.pass_camera.visible(data.area)))
{
return;
}
if (false == Ignorerange)
{
double distancesquared;
@@ -6033,6 +6054,9 @@ bool opengl46_renderer::Render(TDynamicObject *Dynamic)
glm::mat4 mv = OpenGLMatrices.data(GL_MODELVIEW);
model_ubs.future *= glm::translate(mv, glm::vec3(Dynamic->get_future_movement())) * glm::inverse(mv);
// the velocity it leaves in the colour pass keeps the motion blur on (Render_pass())
if ((m_renderpass.draw_mode == rendermode::color) && (Dynamic->get_future_movement() != glm::dvec3{0.0}))
m_vehiclesmoving = true;
::glPushMatrix();
::glTranslated(originoffset.x, originoffset.y, originoffset.z);
@@ -7259,6 +7283,9 @@ bool opengl46_renderer::Render_Alpha(TDynamicObject *Dynamic)
glm::mat4 mv = OpenGLMatrices.data(GL_MODELVIEW);
model_ubs.future *= glm::translate(mv, glm::vec3(Dynamic->get_future_movement())) * glm::inverse(mv);
// the velocity it leaves in the colour pass keeps the motion blur on (Render_pass())
if ((m_renderpass.draw_mode == rendermode::color) && (Dynamic->get_future_movement() != glm::dvec3{0.0}))
m_vehiclesmoving = true;
::glPushMatrix();

View File

@@ -852,6 +852,9 @@ class opengl46_renderer : public gfx_renderer {
// contact shadows: set up for the colour pass under way, and whether the last main view had them
bool m_contactshadows { false };
bool m_contactshadowslast { false };
// a vehicle drawn in the colour pass of the last frame moved, and one drawn in this frame did (motion blur, Render_pass())
bool m_vehiclesmoved { true };
bool m_vehiclesmoving { false };
gl::gpu_timer m_contactshadowstimer; // resolve of the depth
renderpass_config m_colorpass; // parametrs of most recent color pass
std::array<renderpass_config, 3> m_shadowpass; // parametrs of most recent shadowmap pass for each of csm stages