Can you help me to fully understand stencil buffer?

Hey hey :slight_smile:

I took a look again at stencil buffers, and found that that you credited me in you example :heart: Thanks for that.

I wanted to ask whether you can explain to me why it is necessary to set the layer of the mesh instances to world layer - 1?

model.meshInstances[i].layer = pc.LAYER_WORLD - 1;
...

render.meshInstances[i].layer = pc.LAYER_WORLD - 1;
...

In my original project I applied it to any meshinstance, on models, sprites, spines and particle systems. After some more investigation it seems to me though that it is only necessary for renders and models. And here I’m wondering what this does exactly, because I don’t fully understand what happens when I set the layer on a mesh instance. Also the layer property seems to be marked as legacy in the engine, so is this even necessary to be used?

Thanks
Alex

Have a look here, I’ve done similar thing but using layers:
https://playcanvas.github.io/#/graphics/portal

Which is a more correct way to do this in PlayCanvas. Read the comments, it might give you what you need. As you mentioned, the MeshInstance.layer is something that was used before the Layer system was developed, and even though it mostly works, I would not guarantee all cases.

The reason you need to render geometry to stencil buffer first, is that the stencil needs to be initialised first, before you render the geometry that depends on it. Layers is a way to say ‘update stencil buffer first’ and then ‘render meshes that use stencil buffer values to test’.

3 Likes

That was quick, thanks.

Doesn’t that mean though that we are rendering the stencil buffer into a different layer, which could be drawn by a camera? If I’m not using the world layer, but instead custom layers, would I need to be careful to not render the layer of the stencil buffer?

It seems though that this is no longer necessary for render components anyway, and the example is very helpful. I will see if there are any more uncertainties when I port it to my project :slight_smile:

I don’t think there’s any difference between Render or Model component here. Under the hood they use MeshInstances, and those render the same way.

It’s all about the order. In the same way you render opaque meshes first, and then transparent - the reason being that transparent blend on top. You update stencil buffer first, and then use it.

Stencil buffer is essentially a separate buffer. You have color buffer, depth buffer and stencil buffer. So here you render your meshes to stencil buffer to mark some areas … for portal you mark the area where the portal itself is.

And then you render meshes on both sides of the portal, but when you render them, you test each pixel to see if it is portal of not, and based on that you either render the pixel or not. This allows you to render some meshes that are only visible inside the portal (so they only render where stencil buffer says ‘portal here’, and render other meshes that are only visible outside the portal (stencil says ‘no portal here’)

You can see stencil as a mask texture. At the start of the frame, you update this mask texture, and then meshes that render later can use it as a mask to render or not.

3 Likes