Create Screenshot Using Render Target and GUI

Hi,
I am trying to render GUI in screenshot, with no avail.
See this PG https://www.babylonjs-playground.com/#3GPEIL#29

image

last two parameters should be for renderSprites and enableStensilBuffer although intellisense doesn’t show those.

How do I go about having GUI in screenshot?

Thank you

I had to split CreateScreenshotUsingRenderTarget to avoid this error

yup gui is not avail in rendertarget.

@sebavan oh that’s quite the bummer…
May I ask you if you would know of any approach to render images with text of top of them?
Previously I was using AdvancedDynamicTexture.CreateForMesh which does work with RenderTarget, but I found that it crashes on mobile when number of images grows.

Let s check if @Evgeni_Popov has any trick ?

thank you.
To give some perpective, this is what I need to do.


Using AdvancedDynamicTexture.CreateForMesh in desktop works fine, in mobile it crashes the page.

You can’t use CreateScreenshot instead of CreateScreenshotUsingRenderTarget? You will get the texts with the former.

hey @Evgeni_Popov
I need to get images with resolutions different than canvas.
like 3000x3000 and 1920x500
CreateScreenshot doesn’t seem to handle that

Also those markers should not be visible by the user, so I use a camera just for screenshots with dedicated layerMask

We have a PR that is pending (waiting for @RaananW return in 8 days) which will allows you to set a render target to camera.outputRenderTarget, which will generates the whole scene as seen from this camera into the render target (note that you can already use this outputRenderTarget property but it is currently bugged).

It’s a lot like CreateScreenshotUsingRenderTarget except all features of Babylon are supported (post processes, GUI, …) as it is the final output that is simply generated in a specific render target texture.

thank you @Evgeni_Popov
Problem is that we are going to prod next week :sob:
Right now I am looking if there is anything I can optimize with CreateForMesh
For other controls I am using instances and repeat then tens of time, and that is fine, but for these I can’t because having numbers they are all different.

Here’s a workaround:
https://playground.babylonjs.com/#PE7MU2#2

I have overriden the CreateScreenshotUsingRenderTarget function and you can pass as the 1st parameter the advanced texture that should be rendered as part of the screenshot rendering.

1 Like

@Evgeni_Popov you rooooockkk!! :metal: :metal:
Thank you!!!

I have just adapted onEndFrameObservable for v4
https://playground.babylonjs.com/#PE7MU2#4

engine.onEndFrameObservable.addOnce(() => {
        const prom = texture.readPixels(undefined, undefined, undefined, false)
        if(prom instanceof Promise){
            //v5
            prom.then((data) => {
                BABYLON.Tools.DumpData(width, height, data, successCallback, mimeType, fileName, true);
                texture.dispose();
            });
        }else{
            //v4
            const data = prom
            BABYLON.Tools.DumpFramebuffer(width, height, {readPixels:()=>data}, successCallback, mimeType, fileName)
        }
    });

This is going to save me sooo much time and headache! Thanks a lot! :slightly_smiling_face:

1 Like

Hi @Evgeni_Popov
Sorry to bother you again.
I noticed that with different resolutions, the gui layer results stretched.
https://playground.babylonjs.com/#PE7MU2#5
Do you reckon it is possible to prevent the stretching?

Thank you

You can try something like this:
https://playground.babylonjs.com/#PE7MU2#7

1 Like

@Evgeni_Popov you are the man! :metal: :metal: :metal:

@Evgeni_Popov
Sorry… :sweat:
I realised the button, although properly sized now, it doesn’t seem to position properly.
I have linked it with the sphere, and just moved the sphere a bit left to make it more evident.
You’ll see the button in screenshot positions a bit off
https://playground.babylonjs.com/#PE7MU2#8
Very sorry to bother you again :disappointed:

Actually, I am seeing quite the difference between v5 and v4


v5 might actually be correct, given the screenshot camera is positioned on the top left.
v4 is well off. Most likely something I did wrong trying to get it to work.
Do you happen to spot something that might justify such difference?

engine.onEndFrameObservable.addOnce(() => {
        const prom = texture.readPixels(undefined, undefined, undefined, false)
        if(prom instanceof Promise){
            //v5
            prom.then((data) => {
                BABYLON.Tools.DumpData(width, height, data, successCallback, mimeType, fileName, true);
                texture.dispose();
            });
        }else{
            //v4
            const data = prom
            BABYLON.Tools.DumpFramebuffer(width, height, {readPixels:()=>data}, successCallback, mimeType, fileName)
        }
    });

v5 is wrong too, the problem is that the aspect ratio returned by the engine is not right when the GUI is regenerated.

This fixes it for 5.0:
https://playground.babylonjs.com/#PE7MU2#18

Regarding 4.2 I don’t know, the code of CreateScreenshotUsingRenderTarget I have extracted is from 5.0 and there may be some other changes in the lib that makes it fail (using linkWithMesh fails in 4.2). That will be near impossible to know what, though…

3 Likes

V5 looks pretty good indeed.
I’ll go through V4 source and see if I can adapt.

Thanks a lot for your help. Enormously appreciated!