Can we store scene as gif from rotating mesh

Hello Team,
I really appreciate your support system, I always get my answers.
I’m integrating archrotate camera into my scene because of that I’m able to rotate the mesh on x ,y and z axis.
I’m storing scence with different angles and then creating gif from the given set of images but
Now I have the requirement of downloading or storing the scene as a gif of rotating mesh.

I have found this playground

I exactly want like this but I want to store this rotating mesh as a gif.
is it possible ?

Thanks in advance

Here is some info from the documentation - Render Scenes To .png Files | Babylon.js Documentation
Also, the Inspector has the abitlity to record GIFs; one may always look at the source code to see how it is done there.

1 Like

Similarly to what’s been said above;
I personally use GitHub - spite/ccapture.js: A library to capture canvas-based animations at a fixed framerate + webm-writer js and some code that look like this:


function startCapture (name){
  let timeLimitInSeconds = 2
  let stopped = false

  let capturer = new CCapture({
    framerate: 50,
    verbose: true,
    timeLimit,
    name,
    format: 'webm',
  })

  capturer.start()

  function render() {
    if (stopped) {
      return
    }

    requestAnimationFrame(render)
    scene.render()
    capturer.capture(scene._engine._renderingCanvas)
  }

  scene.activeCamera.alpha = 0
  scene.activeCamera.autoRotationBehavior._idleRotationSpeed = 3.14 * 1.005

  render()

  setTimeout(() => {
    stopped = true
    capturer.stop()
    capturer.save()
  }, timeLimitInSeconds * 1000)
}

And then I use ffmpeg-static to convert the webm to gif

However maybe you could just use gif.js instead of webm-writer if you wanted to generate gifs directly (looking at the readme of ccapture.js)

1 Like

Hello folks, thanks for your reply,
I’m also using a php library GitHub - Sybio/GifCreator: GifCreator is a PHP class that creates animated GIF from multiple images, to create gif from the set of images.
But I’m stuck on how to take screenshots of rotating mesh Also when I rotate mesh and take screenshot it rotates only one item or task of the mesh, not the complete mesh.

I’m loading my mesh with AssetsManager,
using like this
manager = new BABYLON.AssetsManager(scene);
I’m attaching my playground for your reference

Here is video of my screen to understand the issue

You could rotate the camera around the object instead to take the list of screenshots ?

Thats nice idea, I’ll try surely.
Thanks

Hey @sebavan, I have looked for the camera rotation a lot in documentation and examples but have not found a proper solution yet.
can you please help me regarding this?

I have created the above PG in which I want the sofa to rotate at a consistent frequency and should never stop till I add a stop button.

In the second PG, I have used var movein = new BABYLON.Animation(“movein”,…)
to achieve the same but the mesh is not rotating completely and also doesn’t keep rotation on in a continuous loop.

This would be nice even if I can get rotation like following example

Thank you in advance

in your case you could simply:

camera.alpha += x; if it is an arcrotatecamera between every frame you want to screenshot so you will be sure to have the exact same angle for every frame of the gif.

Hello @sebavan,
Thanks for your suggestion, But I have tried this before, and I ended up with something went wrong error, because of using the callback function to save screenshot data.
If I use download it works fine but on saving it throws an error.
Adding my code and screenshot here for your reference.
Thank in advance

Code —

B
CreateScreenshot_for_gif(filename, percision,callbackfun){
let width = document.getElementById(“screenshot_width”).value;
let heigth = document.getElementById(“screenshot_heigth”).value;
let x = 0.01;
var imgNm = 0;
scene.registerAfterRender(function () {
camera.alpha += x;
if (imgNm++ < 100) {
scene.executeWhenReady(() => {
BABYLON.Tools.CreateScreenshotUsingRenderTargetAsync(engine, camera, {
width: width,
height: heigth,
precision: percision
}).then(base64Data => {
const array= {‘name’ : filename+parseInt(imgNm),‘file’ : base64Data};
callbackfun(array);
});
});
}
});
}

Another one I tried

B
CreateScreenshot_for_gif(filename, percision,callbackfun){
let width = document.getElementById(“screenshot_width”).value;
let heigth = document.getElementById(“screenshot_heigth”).value;
let sharpness = document.getElementById(“screenshot_sharpness”).value;
let x = 0.01;
var imgNm = 0;
scene.registerAfterRender(function () {
camera.alpha += x;
if (imgNm++ < 30) {
if (!filename) {
filename = this.generateFileName();
}
BABYLON.Tools.CreateScreenshotUsingRenderTarget(
engine,
camera,
{
width: width,
height: heigth,
precision: percision
},
data => {
const array= {‘name’ : filename+parseInt(imgNm),‘file’ : data};
callbackfun(array);
},
“image/png”,
sharpness
);
}
});
}

Only working is

Blockquote
CreateScreenshot_for_gif(filename, percision,callbackfun){
let width = document.getElementById(“screenshot_width”).value;
let heigth = document.getElementById(“screenshot_heigth”).value;
let x = 0.01;
var imgNm = 0;
scene.registerAfterRender(function () {

  camera.alpha += x;
  if (imgNm++ < 30) {
    BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, {
      width: width,
      height: heigth,
      precision: percision
  });
  }  

});
}

Usually that means you ran out of memory or something caused a crash like a infinite loop, try slowing down your code, and you can better see what happens.
e.g. custom renderLoop that only runs every 100 MS or more

Could you repro in the Playground @Soniya_Kukreja ?

This playground I have created this for your reference.
I have to store screenshots of this mesh on the cloud, from every angle to create a gif. For that, I have API in the callback function which gets timeout when I loop through for more than 30 images.
Also is there any way to re-registeterAfterRender function, I’m asking because I have to keep the rotation speed dynamic, I did that, by updating the value of x and rerendering the mesh, it works fine but observing in the console that the


previous rotation speed doesn’t get removed.
check attachment.
Thanks

This makes me think you’re attaching a new scene.registerAfterRender every time you change the rotateSpeed ? and not disposing of the “old” existing one ?

yes, I was looking for how to dispose the old one but couldn’t find anything and also i don’t wanna attach scene.registerAfterRender every time if there is any better way to update the speed

Adding/Removing is much easier if you use an observable

// Start taking screenshots.. register the onAfterRenderObservable
let afterRenderObserver = scene.onAfterRenderObservable.add(function(){
    // Take screenshots, etc
});

// When done taking screenshots for now, remove the observer again.
scene.onAfterRenderObservable.remove(afterRenderObserver);

Another option is to keep a single scene.registerAfterRender function that is always attached, whether it runs the screenshot code or not could be controlled by a boolean

Thanks. will try this.

Hello guys,
I still haven’t found any solution to the issue,

I have to run the following code in the loop more than 200 times, can you please help me in that, the loop runs if I don’t use the callback function but when I use the callback function to store the detail of capture in the database it runs timeout.
what else do you suggest for this, How i can run the loop over 200 times which creates a screenshot, and pass the data to the callback function which will store the data and the loop shouldn’t iterate till the callback function doesn’t get any response from API.

BABYLON.Tools.CreateScreenshotUsingRenderTarget(
engine,
camera,
{
width: width,
height: heigth,
precision: percision
},
data => {
const array= {‘name’ : ‘filename’+parseInt(imgNm),‘file’ : data};
callbackfun(array);
},
“image/png”,
sharpness
);

To be honest I recommend you create the gif first and upload the finished gif (less bandwidth usage), but it’s up to you.

Anyway, here is a repro using the webm strategy I was talking about originally:

Open the console and call “startCapture('my-webm')” in the console. You’ll see the CCapture start and instantly download the .webm file

You can easily change the speed of the rotation by playing around with line 123 :
scene.activeCamera.autoRotationBehavior._idleRotationSpeed = 3.14 * 1.005

Change 1.005 to something smaller for slower speed. To can also play around with the time.

After you have a webm, it’s pretty easy to convert to gif using ffmpeg or some other gif encoder.

CCapture also support ‘gif.js’ so you could generate a gif straight from the client, but it requires a worker js to be made, so I can’t reproduce that on the babylon playground.
This youtube video uses CCapture and gif worker to generate a gif of a canvas, just copy paste that portion of the tutorial if it interests you.

1 Like