[SOLVED] FPS Vs delta time

Hi want to get the smoothest animations possible.
So far, even with a single box spinning, it isn’t as smooth as I think it can be (60 fps).
Sometimes it feels like there are micro lags.

I made two boxes and I think one is animated on a frame basis while the other is animated on a time basis.

Is this done right?
If so, is the animation of box2 the smoothest animation I can get or is it still not optimal?

As I said, it seems like both are the same when previewing. Being smooth but not perfectly.

function engine(){

      const engine = new BABYLON.Engine(canvas);
                engine.setSize(canvasWidth,canvasHeight);
                engine.runRenderLoop(renderLoop);

      const scene = new BABYLON.Scene(engine);
                scene.clearColor = new BABYLON.Color3(0.95, 0.95, 0.95);
                                              new BABYLON.Layer('back','../assets/images/background.jpg', scene, true);

      const camera = new BABYLON.FreeCamera("camera",new BABYLON.Vector3(0, 0, -10),scene);
                camera.attachControl(canvas, true, true) 
                camera.setTarget(new BABYLON.Vector3(0, 0, 0));

      const light = new BABYLON.HemisphericLight("Light", new BABYLON.Vector3(0, 1, 0), scene);
                light.diffuse = new BABYLON.Color3(1, 1, 1);
                light.specular  = new BABYLON.Color3(1, 1, 1);
                light.intensity = 2;

      const box1 = new BABYLON.MeshBuilder.CreateBox("box", { width:2, height:2, depth:2 }, scene);
                box1.material = new BABYLON.StandardMaterial("material", scene);;
                box1.material.diffuseColor = new BABYLON.Color3.FromHexString("#494e5d");
                box1.position.x = -3
                box1.position.y = 0
                box1.position.a = -3    
                box1.rotation.x = 0
                box1.rotation.y = 0
                box1.rotation.z = 0

      const box2 = new BABYLON.MeshBuilder.CreateBox("box", { width:2, height:2, depth:2 }, scene);
                box2.material = new BABYLON.StandardMaterial("material", scene);
                box2.material.diffuseColor = new BABYLON.Color3.FromHexString("#494e5d");
                box2.position.x = 3
                box2.position.y = 0
                box2.position.a = 3
                box2.rotation.x = 0
                box2.rotation.y = 0
                box2.rotation.z  = 0

      function renderLoop() {

            scene.render();
            // frame-based => relative to frame rate => less smooth, can lag?
            box1.rotation.x += 0.027;
            box1.rotation.y += 0.027;

            // time based => relative to delta time => smoother, steadier?
            let delta  = engine.getDeltaTime()
            box2.rotation.x += 0.0015*delta;
            box2.rotation.y += 0.0015*delta;
      }

}

Moreover, I’m astonished that I had to change the base value of the rotation so that the two boxes seem to move at the same speed. (0.027 had to become 0.0015 to match).
Something feels odd and I want to be sure that I’m using delta time correctly.

Thanks for your help

Have you tried using scene.registerBeforeRender()?

  • Registers a function to be called before every frame render

Also in the BabylonJS documentation there are many examples of different methods for working with animation

Hope it helps

1 Like

Thanks for your answer.
I’ve seen this “registerBeforeRender” in another post alright.
But when using it, my screen goes blank.
It’s probably because of the way I encapsulated my code VS the way it is in the playground.

In the playground, everything is inside a “createScene” function and I don’t know where it is called and how it is triggered. I don’t see any mention of “scene.render();” neither.
So when I use “scene.registerBeforeRender(()” in my code, it just doesn’t work because it isn’t triggered anywhere.

So, I went with the first setup example i’ve seen in the documentation used for the very first demo of a babylon.js animation (simple renderLoop() ).

I also read the “animation” part of the documentation but this seems to be specific to keyframed animations. My animations in the future might be less predictable and scripted, which is why I dismissed this approach).

If you think using “createScene” and “registerBeforeRender” is better, where can i see how to implement them (see the whole code that triggers them)?

And last but not least : would it make a difference ? Because when I look at the playground you kindly created for this, the preview is exactly as mine => I see no difference in smoothness between both cubes and it’s still micro lagging in both cases (it’s totally acceptable but I’m trying to get the best out of the animations as I seen stuff that are way smoother than this in other examples).

Thank you.

I believe that the playground as designed integrates the scene.render() function;

I recommend that you see this example in which within an HTML it explains well how to start the scene and execute runRenderLoop

I couldn’t tell you about playback and small lags, it works smoothly on my computer, even on an old Android mobile that I’ve tested on.

What equipment specs do you have?
Have you checked if your GPU drivers are up to date?
Likewise Chrome or the browser you are using.
Also try using another browser, especially to find out if it is due to a hardware problem or possibly drives.

2 Likes

Ok, thanks to your link, I got to integrate the createScene function and to have the scene.registerBeforeRender working now.
And yes, I still get the micro-lags (not lags per se but rather the feeling it’s 24 frames per seconds, you know?).

I’m on a iMac Pro, 3,2 GHz Intel Xeon W 8 cores, with a Radeon Pro Vega 56 8 Go GPU and 64 Go 2666 MHz DDR4.

I use Chrome Canary (because I wanted to use the WebGPU features soon enough).
I just tested Firefox and it seems to provide better results in webGL as far as i’m concerned. It definitely smoother for whatever reason.

Anyway, I’m thankful for your help and I’m glad that I have a standard and optimal way to manage the animations now.
If you tell me that’s the way to go, that’s the way I will go.

Take care !

PS: my iMac is up to date so I believe the drivers are as well since everything is integrated.

1 Like

OK!

Without a doubt, it could be from using the Canary version, I couldn’t assure you since I haven’t tried it yet, but I highly doubt that it´s due to your hardware since it has plenty of power for such a simple operation

Regarding the animation, as I told you, in the BabylonJS documentation you will see different methods:

  • BABYLON.Animation
  • BABYLON.AnimationGroup
  • RenderLoop…

And also the ActionManager, it is very powerful and easy to use:

Hope it helps and Happy coding!

1 Like