Hi all,
I’m new to BabylonJS. Super impressed with it’s power so far though.
My question is in regard to rendering scenes to video. According to the docs, the built-in RecordVideo feature only produces .webm files at the same dimensions as the canvas. However, I’d like to be able to render animated scenes to a series of still frames at any resolution, then use ffmpeg or similar tool to create a video from them in any format I choose.
The following code works somewhat but it appears to skip around 5 or so frames between each capture (assuming there are 60 frames for one second of playback). This seems to be consistently the case no matter how long each capture takes. Inserting deliberate random long wait periods between each capture seems to have no effect. I’ve also tried implementing this using (un)registerAfterRender() with similar results. Nothing I do seems to produce a sequence of images that produce smooth 60 FPS animation at a speed consistent with the live, uncaptured rendering rate directly to the display.
Any insight as to what I may be doing wrong would be very much appreciated. Thanks in advance!
var scene;
var engine;
var camera;
var frameNum = 0;
var screenshot_captured = true;
function post_image_to_http_server(encoded_image)
{
var frameNumStr = ("0000" + frameNum).slice(-4);
frameNum++;
var xhttp;
var encoded_image = encoded_image.replace(/^data:image\/(png|jpg);base64,/, "");
xhttp = new XMLHttpRequest();
xhttp.open("POST", "write_encoded_image_to_disk.php", true);
xhttp.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
xhttp.send("fname=" + frameNumStr + "&fcontents=" + encodeURIComponent(encoded_image));
screenshot_captured = true;
}
function render_scene_frame_to_image_file()
{
BABYLON.Tools.CreateScreenshotUsingRenderTarget( engine, camera, {width:1920, height:1080},
function(data)
{
post_image_to_http_server(data);
}
);
}
var canvas = document.getElementById("renderCanvas");
function createScene () {
scene = new BABYLON.Scene(engine);
camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 5, new BABYLON.Vector3(0, 0, 0), scene);
camera.attachControl(canvas, true);
camera.lowerRadiusLimit = 2.5;
camera.upperRadiusLimit = 10;
camera.pinchDeltaPercentage = 0.01;
camera.wheelDeltaPercentage = 0.01;
scene.clearColor = new BABYLON.Color3(0.0, 0.0, 0.0);
BABYLON.ParticleHelper.CreateAsync("sun", scene).then((set) => {
set.start();
});
return scene;
}
engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });
createScene();
engine.runRenderLoop(function () {
if (screenshot_captured) {
screenshot_captured = false;
scene.render();
render_scene_frame_to_image_file();
}
});
// Resize
window.addEventListener("resize", function () {
engine.resize();
});