Use GUI element as a mask for taking a snapshot of the viewport

I have a situation like this

image

I created that white rectangle using Babylon GUI. What I would like to achieve is to take a screenshot of the viewport using CreateScreenshotUsingRenderTarget. Basically I want to take a screenshot of the parts which are inside that GUI element.

Not sure if possible at all. It would be nice if I could avoid some manual math calculations for deciding what to capture in the scene.

Thanks

1 Like

Or if you have any other technique on how I could achieve something like this

My guess is you will have to do some math to get the camera view port to match up with whatever the GUI dimensions are.

As for the specific math I’m unfortunately still working that out.

You can use the stencil buffer for this. However, you won’t be able to use a GUI element, only meshes.

Basically it works like this:

  1. draw the shape you want to cut your meshes with by setting the stencil value to 1. You can use any mesh(es) you want, so the shape can be anything you want
  2. draw all the meshes of your scene by configuring the stencil buffer to only draw a mesh when the stencil value is 1

https://playground.babylonjs.com/#LRT0SD

Set disableStencil to true to see the setup with the cutting plane.

For step 1, you should draw the cutting shapes with disableDepthWrite = true and disableColorWrite = true so that it does not tamper with the scene.

Note that CreateScreenshotUsingRenderTarget does not work, the stencil is not taken into account (or the onBeforeDrawObservable observers, I don’t know). @sebavan should know what’s going on.

So I used CreateScreenshot instead.

2 Likes

I got it, it does not work with CreateScreenshotUsingRenderTarget because the stencil is not activated when creating the RenderTargetTexture

I think I can add a parameter to CreateScreenshotUsingRenderTarget to support stencil buffer.

2 Likes

Thank you for you answer again @Evgeni_Popov.

I will check it out. I was wondering if I could use something like this.

Basically I take canvas width and height, do some math to create the GUI rectangle element width and height

and then I use camera.viewport as @msDestiny14 mentioned with the same values as for rectangle

Something like new BABYLON.Viewport(x,y, w,h)?

If your cutting shape is a simple rectangle (straight lines, not curved corners as in your screenshot), yes it is the easiest way.

The stencil buffer method is useful if the cutting shape is something unusual.

Yes, that border radius is not big of a issue for me. The issue is that I am not sure how to use camera viewport. Whichever value I try to use, the model is not in the camera view.

Is there any example on how to use viewports?

Maybe in your case the scissor test would be better:

https://playground.babylonjs.com/#LRT0SD#1

This PG does not work with CreateScreenshotUsingRenderTarget because I have used some observers from the scene to enable / disable the test.

To make it work with CreateScreenshotUsingRenderTarget, I think you need to enable the test before drawing the first mesh and disable it after drawing the last mesh:

https://playground.babylonjs.com/#LRT0SD#2

Be careful that the values passed to enableScissor are in pixels, so will depend on the size you pass to CreateScreenshotUsingRenderTarget!

3 Likes

I tried several things, at the end I figured out proper math for camera.viewport, and everything works fine. I am able to take snapshots as intended. Thank you for your answers. You were helpful as always. Appreciated

2 Likes

This is also something that I would love to be able to use. Is there a ticket or anything out there for this?

Here it is:

Thank you! Going to patch that into our build