Rendering order of meshes within the same rendering group

Hi,

I am looking for a way to manage specific rendering order of meshes within the same rendering group.
Here is a simple playground illustrating what I am trying to do: https://playground.babylonjs.com/#W4ZIRJ#1

I am clipping a sphere with a clipping plane and also have ground that partially goes into the sphere. I want to be able to see the sphere “in front of” the ground, even though they intersect. I can do this with renderingGroupIds by un-commenting lines 47 and 48, but I want to be able to do it within the same rendering group, and I was hoping line 45 would do it, but it doesn’t.

Can I achieve the same effect within a single rendering group?

Thanks!

1 Like

It’s been a while @Anton :slight_smile:

Yes you can. YOu can get the rendering group you want and use that:
Babylon.js/renderingManager.ts at master · BabylonJS/Babylon.js (github.com)

By controlling the sort function you will be able to display the meshes the way you want

1 Like

Hi @Deltakosh - yes it has :slight_smile: Glad to be back here learning more about Babylon

I am using this exact function on line 45:
scene.setRenderingOrder(0, BABYLON.RenderingGroup.frontToBackSortCompare);

I was expecting that this would render meshes that are “in front” last. But it seems to have no effect on my scene - e.g. my plauground results are the same with line 45 present and commented out.

Is my expectation wrong here?

front to back means this will render front first (so it gets a lot of pixels discarded thanks to the depth buffer)

It is the default behavior

Also, the default front to back sorting is using the bounding box center as the sorting key. So, depending on the position of objects, you may have the sphere coming before the ground or the other way around.

You should provide your own sorting function and make sure that your sphere will always come after the ground by this function (maybe set a sortkey property on the sub meshes, ground.subMeshes[0].sortkey=0, sphere.subMeshes[0].sortkey=1 and sortfunction = (a,b) => a.sortkey < b.sortkey ? -1 : a.sortkey > b.sortkey ? 1 : 0).

Note however that it won’t change the display as the zbuffer will do its job. You could disable the zbuffer testing when rendering the sphere so that what has been rendered prior to the sphere does not interfere, but it won’t work because the triangles of the sphere not being tested against the zbuffer, triangles farther away could occlude triangles closer if they are drawn last:

One way to achieve this would be to actually render the sphere first and update the stencil buffer with some value where the sphere is drawn (say value 1) and when rendering the other objects (the ground), setup the stencil buffer test so that those objects don’t write to the screen where the stencil value is 1.

[UPDATE] I don’t know if it’s an option, but if you create the ground first and apply a material to it that does not write to the zbuffer, it will also work:

1 Like

Thank you @Deltakosh and @Evgeni_Popov for the suggestions.

I guess my question is now evolving. I think I have an idea on how to solve this if I can get over this next hurdle. It’s related to basic understanding of front and back faces of a mesh and how to show/hide them.

I have a clipped sphere with both front (external) and back (internal) faces visible here: https://playground.babylonjs.com/#N27VC3#2
image

I am able to make just the “front” faces visible by changing mat.backFaceCulling to true:
https://playground.babylonjs.com/#N27VC3#3
image

And I am able to make just the “back” faces visible by changing mat.sideOrientation to BABYLON.Mesh.FRONTSIDE:
https://playground.babylonjs.com/#N27VC3#4
image

Is there a combination of parameters for material/mesh that I can use to see “back minus the front”, so just the inside of the sphere that is visible when both front and back faces are visible (oval part outlined in red):
image

Thanks!

I don’t see another way to do it than drawing two times the sphere (in fact, you need two identical spheres):

  • draw the first sphere with back face culling enabled and disable color writing, so that the zbuffer is updated with the front faces but the color buffer is left untouched
  • draw the second sphere with front face culling enabled

https://playground.babylonjs.com/#W4ZIRJ#12

1 Like

Thank you @Evgeni_Popov. So the solution to my original problem - slicing the top sphere as if it’s a solid geometry even though the bottom sphere runs into it would be this:

  • draw the top sphere (“sphere”) in rendering group 0
  • draw the bottom sphere (“sphere2”) in rendering group 0
  • clone the top sphere as “sphereOutside” and “sphereInside”
  • draw “sphereOutside” with disabled color write in rendering group 1
  • draw “sphereInside” with ClockWiseSideOrientation in rendering group 1

Now you cannot see the bottom sphere inside of the top sphere as if the top sphere is solid:
https://playground.babylonjs.com/#N27VC3#7

Thank you for your help. Now I have to see if this approach flies in my project :slight_smile:

An illustration of this is in this PG (Babylon.js Playground). If you drag the green box across the red box you will see the green and red boxes appear to swap z’s. I assume that the default front to back ordering compares the distance to the camera to the bounding box center and therefore for large angles with respect to the camera and small z separation, it is possible that the bounding box center of the further object is actually closer to the camera.