[SOLVED] Creating a Screenshot in PlayCanvas

Hi,

we’re trying to create a script to capture screenshots from the application canvas,
according to what we found on the web, when using a WebGL renderer, one has to tell this renderer to preserve the draw buffer, otherwise the screenshot will be empty.

This is also what we experience, here is out attempt so far:

initialize: function () 
    {
        app.keyboard.on(pc.EVENT_KEYDOWN, this.takeScreenshot, this);
    },
    
    takeScreenshot: function(event)
    {                        
        if (event.key === pc.KEY_S) 
        {       
            var canvas = document.getElementById('application-canvas');
            var context = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true});
            var dataURL = canvas.toDataURL();
            $(document.body).append("<img id='screenshot' src='" + dataURL + "'>");
            $("#screenshot").css('z-index',9999999999999999999);
            $("#screenshot").css('position','absolute');
            $("#screenshot").css('left','50%');
            $("#screenshot").css('top','50%');
            $("#screenshot").css('transform','translate(-50%, -50%)');
            $("#screenshot").css('width','50%');
            $("#screenshot").css('height','50%');
            $("#screenshot").css('border','6px solid white');      
        }            
    }

Now my question is: How could we reach the renderer?
Where is it located in the API hierarchy?

Or is there maybe a better / other sollution to this?

Thanks in advance!

EDIT: Corrected script from $("#screenshot").src = dataURL; to $(document.body).append("<img id='screenshot' src='" + dataURL + "'>");

1 Like

You are correct. The WebGL context does indeed need to be created with project:preserveDrawingBuffer set to true if you want to extract a screenshot from the canvas with toDataURL. We will aim to implement this for you as soon as we can.

Hey @Dinkelborg,

You can now go to the Settings inside the Editor and enable ‘Preserve Drawing Buffer’. Then your code should work.

3 Likes

AWESOME, guys!

Thanks a real lot, its really amazing how fast you incorporate changes like this. This is what makes working with your engine such an ease and so much fun.

Keep up the good work.

PS: Here is a screenshot we took like this in firefox, we are wondering where the greenish artifacts could come from, we suspect it has to do with the rendering of the transparency, but is there anything we could do to prevent this?
It only happens in firefox, not in chrome or edge.

In Firefox:

In Chrome:

Hey @Dinkelborg, does @vaios have access to that project? If not, can you add him? Thanks! :smile:

Hi will,

sorry unfortunately this is a commercial project, therefore we cannot grant access outside of our company,
I updated the tiling error scene to showcase both: https://playcanvas.com/project/368009/overview/bugtiling--screenshots
and invited him.

The bug seems to have to do with the HDRI and also the angle the camera looks at the meshes, try creating screenshots from different angles, it gets worse if you take one right from the starting position and better left from the starting position.

(MOVE: WASD TAKE_SCREENSHOT: P DISCARD_SCREENSHOT: X)

I’ve just tested this in a fork of your project. Looks like there are various issues where the screenshot differs from the app rendering. But this only seems to occur if you have “Transparent Canvas” enabled. In the project settings when I disable transparent canvas the screenshot matches the app in Chrome and Firefox.

2 Likes

Hey @vaios,
is there a way to set these settings from code so that we can turn the preservation of the drawing buffer on only for the time that we want to create a screenshot and then turn it off afterwards again?

It looks like it’s not possible to change preserveDrawingBuffer at runtime. It’s a setting passed when creating a WebGL context which happens in the beginning of the application only.