Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jerkiness in smoothing #20

Open
GBagley opened this issue Sep 3, 2023 · 1 comment
Open

Jerkiness in smoothing #20

GBagley opened this issue Sep 3, 2023 · 1 comment

Comments

@GBagley
Copy link

GBagley commented Sep 3, 2023

I'm noticing that when using smoothing, and when the camera is following an object, there is jerkiness that seems to be coming from the smoothing. And any changes I make to the smoothing parameters don't seem to help.

If the object makes a single jump from point A to point B, or the object stops moving, then the camera moves smoothly to it, but when the object is in constant steady-state motion, the camera has some small jerkiness/oscillation and is not as smooth as I might expect.

Simple test exhibiting this behavior is a small modification to the nested_driver.rs example, just changing the camera rig position to follow the target, and adding a dolly arm (similar to the follow example shown in the README):

diff --git a/examples/nested_driver.rs b/examples/nested_driver.rs
index 643ad0c..9bbd1e5 100644
--- a/examples/nested_driver.rs
+++ b/examples/nested_driver.rs
@@ -20,11 +20,13 @@ impl<H: Handedness> MovableLookAt<H> {
         target_position: dolly::glam::Vec3,
     ) -> Self {
         Self(            
             CameraRig::builder()
                 // Allow moving the camera
-                .with(Position::new(camera_position))
+                .with(Position::new(target_position))
                 // Predict camera movement to make the subsequent smoothing reactive
                 .with(Smooth::new_position(1.25).predictive(true))
+                .with(Arm::new(dolly::glam::Vec3::new(0.0, 1.5, -3.5)))
                 // Smooth the predicted movement
                 .with(Smooth::new_position(2.5))
                 .with(LookAt::new(target_position + dolly::glam::Vec3::Y).tracking_smoothness(1.25))
@@ -37,7 +39,7 @@ impl<H: Handedness> MovableLookAt<H> {
         camera_position: dolly::glam::Vec3,
         target_position: dolly::glam::Vec3,
     ) {
-        self.0.driver_mut::<Position>().position = camera_position;
+        self.0.driver_mut::<Position>().position = target_position;
         self.0.driver_mut::<LookAt>().target = target_position;
     }
 }

Then if you hold down one of the WASD keys, you'll see the jerkiness. Not sure if there's some combination/ordering of smoothing drivers that can help with this, or if it's inherent in the smoother itself. Or any other ideas?

@h3r2tic
Copy link
Owner

h3r2tic commented Sep 11, 2023

Yup, could repro it on my system. Looks like the classic problem that physics engines suffer from with varying timesteps. Fixing the them makes it smooth for me:

@@ -85,7 +85,7 @@ async fn main() {
             .set_position_target(camera_position, player_position);
 
         // Update the camera rig, and get the interpolated transform
-        let camera_xform = camera.update(get_frame_time());
+        let camera_xform = camera.update(1.0 / 60.0);
 
         clear_background(LIGHTGRAY);

If you can't / don't want to use fixed timesteps, you could also try filtering the delta times before passing them to dolly (or any other simulation really).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants