Rendering animation frames of imported glb model leads to inconsistent movement

As seen in this GIF, my goal is to render a sequence of pngs of the moving monsters in the scene. These monsters are imported using the SceneLoader.ImportMesh function and the file type is of gltf. The animations are built into the gltf file. The way I am animating is with the following:

public takeScreenShot(): void {
BABYLON.Tools.CreateScreenshot(this.engine, this.camera, {width: this.canvas.width, height:
this.canvas.height});
}

public createImageSequence(): void {
let imgNm = 0;
this.ngZone.runOutsideAngular(() => {
this.scene.registerAfterRender(() => {
// console.log(this.getActiveMesh().position);
if (imgNm++ < 90) {
this.takeScreenShot();
}
});
});
}

The animation’s movement is independent from the scene’s rendering time, and it looks as if this may be the issue. How would I go about synchronizing an imported gltf file’s animation to the scene’s rendering time in order to get a consistent screen shot for each animation frame?

Thank you!

I have created a playground to further demonstrate my point with this walking animation.
https://www.babylonjs-playground.com/#IQN716#151

Calling in the big guns on this one. @sebavan - Any thoughts here?

1 Like

This would not work in real time as generating the screenshot will break the timing so either you capture the canvas stream and first record as a video :slight_smile: with the mediaRecorder api or way simpler.

On every frame you do smthg like below (rough idea of what the code would be). Basically do not let play the animation automatically but manually render one frame at a time.

var frame = 0;

scene.onBeforeRender = () => {
  frame++;
  animationGroup.play(true);
  animationGroup.goToFrame(frame);
  animationGroup.pause();
}
scene.onAfterRender = () => {
  takeScreenshot();
}
2 Likes

Wow I never thought about a third party solution haha shows how much I know. Also I believe I came up with a similar solution to pause and play an animation group and capturing each frame, so I will review that. But overall these solutions look sound to me! Thank you very much!! :slight_smile:

Hey Sebavan,
I decided to try out the method suggested in the code. There doesn’t seem to be a scene.executeOnceAfterRender function. Nor are there onBeforeRender / onAfterRender functions for me to use. What exactly are the functions you would use to make sure you capturing the before and after of a single render frame?

Thanks again

onBeforeRenderObservable and onAfterRenderObservable will do :slight_smile: