1
0
mirror of https://github.com/luanti-org/luanti.git synced 2026-01-13 12:45:29 +01:00

Make camera smoothing framerate independent (#16567)

This commit is contained in:
veprogames
2026-01-12 20:37:43 +01:00
committed by GitHub
parent b80e3f0ad7
commit e047c436a8
4 changed files with 27 additions and 10 deletions

View File

@@ -115,12 +115,12 @@
[*General]
# Smooths rotation of camera, also called look or mouse smoothing. 0 to disable.
camera_smoothing (Camera smoothing) float 0.0 0.0 0.99
camera_smoothing (Camera smoothing) float 0.0 0.0 100.0
# Smooths rotation of camera when in cinematic mode, 0 to disable. Enter cinematic mode by using the key set in Controls.
#
# Requires: keyboard_mouse
cinematic_camera_smoothing (Camera smoothing in cinematic mode) float 0.7 0.0 0.99
cinematic_camera_smoothing (Camera smoothing in cinematic mode) float 0.05 0.0 100.0
# If enabled, you can place nodes at the position (feet + eye level) where you stand.
# This is helpful when working with nodeboxes in small areas.

View File

@@ -563,10 +563,22 @@ void Game::run()
processUserInput(dtime);
// Update camera before player movement to avoid camera lag of one frame
updateCameraDirection(&cam_view_target, dtime);
cam_view.camera_yaw += (cam_view_target.camera_yaw -
cam_view.camera_yaw) * m_cache_cam_smoothing;
cam_view.camera_pitch += (cam_view_target.camera_pitch -
cam_view.camera_pitch) * m_cache_cam_smoothing;
if (m_cache_cam_smoothing <= 0.0f) {
cam_view.camera_yaw = cam_view_target.camera_yaw;
cam_view.camera_pitch = cam_view_target.camera_pitch;
} else {
f32 cam_damp_lambda = 1.0f / m_cache_cam_smoothing * dtime;
cam_view.camera_yaw = damp(
cam_view.camera_yaw,
cam_view_target.camera_yaw,
cam_damp_lambda
);
cam_view.camera_pitch = damp(
cam_view.camera_pitch,
cam_view_target.camera_pitch,
cam_damp_lambda
);
}
updatePlayerControl(cam_view);
updatePauseState();
@@ -3706,11 +3718,11 @@ void Game::readSettings()
m_cache_cam_smoothing = 0;
if (g_settings->getBool("cinematic"))
m_cache_cam_smoothing = 1 - g_settings->getFloat("cinematic_camera_smoothing");
m_cache_cam_smoothing = g_settings->getFloat("cinematic_camera_smoothing");
else
m_cache_cam_smoothing = 1 - g_settings->getFloat("camera_smoothing");
m_cache_cam_smoothing = g_settings->getFloat("camera_smoothing");
m_cache_cam_smoothing = rangelim(m_cache_cam_smoothing, 0.01f, 1.0f);
m_cache_cam_smoothing = std::max(0.0f, m_cache_cam_smoothing);
m_cache_mouse_sensitivity = rangelim(m_cache_mouse_sensitivity, 0.001, 100.0);
m_invert_mouse = g_settings->getBool("invert_mouse");

View File

@@ -270,7 +270,7 @@ void set_default_settings()
settings->setDefault("video_driver", "");
settings->setDefault("cinematic", "false");
settings->setDefault("camera_smoothing", "0.0");
settings->setDefault("cinematic_camera_smoothing", "0.7");
settings->setDefault("cinematic_camera_smoothing", "0.05");
settings->setDefault("view_bobbing_amount", "1.0");
settings->setDefault("enable_3d_clouds", "true");
settings->setDefault("soft_clouds", "false");

View File

@@ -406,6 +406,11 @@ private:
float m_accumulator = 0.0f;
};
// For details about how framerate independent lerping works, see:
// https://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
inline f32 damp(f32 a, f32 b, f32 lambda) {
return core::lerp(a, b, 1.0f - std::exp(-lambda));
}
constexpr inline bool is_power_of_two(u32 n)
{