First you may ask why is it better than "ctrl + prt scr" screenshot or the Snippet app?
There are two methods available to do this using BABYLON.Tools
which are CreateScreenshot
and the more versatile CreateScreenshotUsingRenderTarget
.
You also need to consider how you will trigger the screenshot. This can be done for example with a timer such as 'window.setTimeout' or by using the Babylon.js action manager for a keyDown or onPointerDown trigger.
A major difference between CreateScreenshot
and CreateScreenshotUsingRenderTarget
is when you try to use them directly after creating a mesh or meshes. This is because they work differently.
For example
var box = BABYLON.MeshBuilder.CreateBox("box", {}, scene);
BABYLON.Tools.CreateScreenshot(engine, camera, 400);
will produce an image of the box but
var box = BABYLON.MeshBuilder.CreateBox("box", {}, scene);
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, 400);
will only produce the scene background. This is because this method is activated before the box is actually rendered on the screen. If you want to use CreateScreenshotUsingRenderTarget
in this way then you need to ensure the scene is rendered first as in this example.
var box = BABYLON.MeshBuilder.CreateBox("box", {}, scene);
scene.render();
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, 400);
However even this will not work if the scene is very complex and has not been rendered in time. It is best to use timing or an action.
It's done by simply calling this method: BABYLON.Tools.CreateScreenshot(engine, camera, size)
.
You need to provide your BabylonJS engine, the camera you want to use for the rendering, and a size.
The size parameter is very versatile, it can be a simple number or an object.
Starting with a view of the part of the screen showing the canvas there then follows a sequence of images taken using CreateScreenshot
View of Part of Screen Showing Canvas Used
BABYLON.Tools.CreateScreenshot(engine, camera, 200)
BABYLON.Tools.CreateScreenshot(engine, camera, 800)
BABYLON.Tools.CreateScreenshot(engine, camera, 1600)
BABYLON.Tools.CreateScreenshot(engine, camera, {width:800, height:400})
canvas placed in the middle of image of given size
Precision can be used as a multiplier of the screen resolution.
BABYLON.Tools.CreateScreenshot(engine, camera, {precision: 0.5})
BABYLON.Tools.CreateScreenshot(engine, camera, {precision: 2})
As for the other method it's done by simply calling this method: BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, size)
.
You need to provide your BabylonJS engine, the camera you want to use for the rendering, and a size.
Again the size parameter is very versatile and can be a simple number or an object. However you will see differences in the results using the same parameters as before.
Starting with a view of the part of the screen showing the canvas there then follows a sequence of images taken using CreateScreenshotUsingRenderTarget
View of Part of Screen Showing Canvas Used
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, 200)
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, 800)
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, 1600)
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, {width:800, height:400})
canvas imaged sized as given.
Precision can be used as a multiplier of the screen resolution.
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, {precision: 0.5})
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, {precision: 2})
The CreateScreenshotUsingRenderTarget
has an extra facility, the camera used does not have to be the active camera.
While the active camera is showing the scene as in the above examples you can use this
var camera2 = new BABYLON.FreeCamera("camera2", new BABYLON.Vector3(0, 200, 0), scene);
camera2.setTarget(BABYLON.Vector3.Zero());
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera2, 400)
to produce
The following image of the canvas on screen and the resulting screenshot using 'precision: 8' show that although the image is 8 times larger the pixel density stays the same.
Either of the following set of codes produced a series of images that were turned into the animated gif below.
var imgNm = 0;
scene.registerAfterRender(function(){
box.rotation.y += 2 * Math.PI / 90;
if(imgNm++ < 90) {
BABYLON.Tools.CreateScreenshot(engine, camera, 200);
}
})
var imgNm = 0;
scene.registerAfterRender(function(){
box.rotation.y += 2 * Math.PI / 90;
if(imgNm++ < 90) {
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, 200);
}
})
There is a further parameter that can be added to both methods of obtaining screenshots. This is a callback function added after the size parameter. The methods become BABYLON.Tools.CreateScreenshot(engine, camera, size, onSuccessCallback)
and BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, size, onSuccessCallback)
.
This callback is a function that takes the image data provided by the method and instead of opening or saving the image allows you to manipulate it instead.
For example when you have rendered this scene
by triggering either of these
BABYLON.Tools.CreateScreenshot(engine, camera, 200, function(data) {
var mat = new BABYLON.StandardMaterial("mat", scene);
mat.diffuseTexture = new BABYLON.Texture(data, scene);
box.material = mat;
})
BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, 200, function(data) {
var mat = new BABYLON.StandardMaterial("mat", scene);
mat.diffuseTexture = new BABYLON.Texture(data, scene);
box.material = mat;
})
you obtain