diff --git a/src/client/game.cpp b/src/client/game.cpp index 665176982..500e0a26b 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -2984,6 +2984,10 @@ void Game::updateCameraOffset() return; if (!m_flags.disable_camera_update) { + auto *shadow = RenderingEngine::get_shadow_renderer(); + if (shadow) + shadow->getDirectionalLight().updateCameraOffset(camera); + env.getClientMap().updateCamera(camera->getPosition(), camera->getDirection(), camera->getFovMax(), camera_offset, env.getLocalPlayer()->light_color); @@ -3978,11 +3982,10 @@ void Game::updateShadows() v3f light = is_day ? sky->getSunDirection() : sky->getMoonDirection(); v3f sun_pos = light * offset_constant; - shadow->getDirectionalLight().setDirection(sun_pos); shadow->setTimeOfDay(in_timeofday); - shadow->getDirectionalLight().update_frustum(camera, client, m_camera_offset_changed); + shadow->getDirectionalLight().updateFrustum(camera, client); } void Game::drawScene(ProfilerGraph *graph, RunStats *stats) diff --git a/src/client/shadows/dynamicshadows.cpp b/src/client/shadows/dynamicshadows.cpp index a186fc41b..92aa9f893 100644 --- a/src/client/shadows/dynamicshadows.cpp +++ b/src/client/shadows/dynamicshadows.cpp @@ -36,7 +36,7 @@ void DirectionalLight::createSplitMatrices(const Camera *cam) // adjusted camera positions v3f cam_pos_world = cam->getPosition(); - // if world position is less than 1 block away from the captured + // if world position is less than 1 node away from the captured // world position then stick to the captured value, otherwise recapture. if (cam_pos_world.getDistanceFromSQ(last_cam_pos_world) < BS * BS) cam_pos_world = last_cam_pos_world; @@ -84,9 +84,16 @@ DirectionalLight::DirectionalLight(const u32 shadowMapResolution, farPlane(farValue), mapRes(shadowMapResolution), pos(position) {} -void DirectionalLight::update_frustum(const Camera *cam, Client *client, bool force) +void DirectionalLight::updateCameraOffset(const Camera *cam) { - if (dirty && !force) + createSplitMatrices(cam); + should_update_map_shadow = true; + dirty = true; +} + +void DirectionalLight::updateFrustum(const Camera *cam, Client *client) +{ + if (dirty) return; float zNear = cam->getCameraNode()->getNearValue(); @@ -106,16 +113,6 @@ void DirectionalLight::update_frustum(const Camera *cam, Client *client, bool fo getPosition(), getDirection(), future_frustum.radius, future_frustum.length); should_update_map_shadow = true; dirty = true; - - // when camera offset changes, adjust the current frustum view matrix to avoid flicker - v3s16 cam_offset = cam->getOffset(); - if (cam_offset != shadow_frustum.camera_offset) { - v3f rotated_offset = shadow_frustum.ViewMat.rotateAndScaleVect( - intToFloat(cam_offset - shadow_frustum.camera_offset, BS)); - shadow_frustum.ViewMat.setTranslation(shadow_frustum.ViewMat.getTranslation() + rotated_offset); - shadow_frustum.player += intToFloat(shadow_frustum.camera_offset - cam->getOffset(), BS); - shadow_frustum.camera_offset = cam_offset; - } } void DirectionalLight::commitFrustum() diff --git a/src/client/shadows/dynamicshadows.h b/src/client/shadows/dynamicshadows.h index 2951c0a6e..640a5479f 100644 --- a/src/client/shadows/dynamicshadows.h +++ b/src/client/shadows/dynamicshadows.h @@ -34,9 +34,9 @@ public: f32 farValue = 100.0f); ~DirectionalLight() = default; - //DISABLE_CLASS_COPY(DirectionalLight) + void updateCameraOffset(const Camera *cam); - void update_frustum(const Camera *cam, Client *client, bool force = false); + void updateFrustum(const Camera *cam, Client *client); // when set direction is updated to negative normalized(direction) void setDirection(v3f dir); diff --git a/src/client/shadows/dynamicshadowsrender.cpp b/src/client/shadows/dynamicshadowsrender.cpp index 8504eca75..b213cf12a 100644 --- a/src/client/shadows/dynamicshadowsrender.cpp +++ b/src/client/shadows/dynamicshadowsrender.cpp @@ -256,11 +256,14 @@ void ShadowRenderer::updateSMTextures() // detect if SM should be regenerated for (DirectionalLight &light : m_light_list) { - if (light.should_update_map_shadow || m_force_update_shadow_map) { - light.should_update_map_shadow = false; - m_current_frame = 0; - reset_sm_texture = true; - } + if (light.should_update_map_shadow) + m_force_update_shadow_map = true; + light.should_update_map_shadow = false; + } + + if (m_force_update_shadow_map) { + m_current_frame = 0; + reset_sm_texture = true; } video::ITexture* shadowMapTargetTexture = shadowMapClientMapFuture;