How to NOT Clear the Stencil Buffer after UI Render

I’m trying to implement a way to render 3D objects inside/on top of a masked UI.

For this, I added a “Render Objects” Renderer Feature to the SRP, so that those 3d objects are rendered after the UI. (This is the best way I could figure out to render something after the UI)

I want to make use of the Stencil buffer filled by the UI to mask the objects appropriately.

The problem I have though, is that I think the canvas is “cleaning up behind itself”, and doing a final call to clear the stencil buffer, is there any way to prevent this?

Have you had any luck with this? I’m attempting pretty much the same; custom rendering of 3D objects in UI from SRP.

I have digged a bit into the Mask class and found the stencil material operations in the GetModifiedMaterial method:

Creating my own version of the mask class and replacing StencilOp.Zero with the StencilOp.Keep operation allows me to use the stencil value in a later pass, but it is not a viable solution when multiple masks are in use. With this change, masks won’t be cleared after use, making it possible for each subsequently rendered image to be rendered within previous (unrelated) masks.

I’m thinking it should be possible to control the rendering order within the canvas, but I haven’t been able to find out exactly how…


Edit: I ended up just using a custom mask setup, ignoring the UI mask component entirely. My approach ended up being similar to the stencil sandwich that Unity uses.

I modified the render pass to draw a quad in screen space with a specific stencil-write shader, using the RectTransform world corners to determine the position and scale of the quad.

Then I draw the 3D objects in the stenciled area, and lastly draw the quad again, with a stencil zero’ing pass. This clears up the masked area so it doesn’t interfere with the surrounding objects.