I am basically importing StanfordBunny.obj into the scene (as I want to be able to do this “slicing” with imported meshes), then add a clipping plane with normal pointing in positive Y direction and an actual plane mesh, whose material I want to show only “inside” the bunny. GUI slider moves the clipping and actual mesh planes up an down in Y direction (similar to how planeY constant does for Three.js demo).
I have spent some time now trying to achieve the same effect as in Three.js and I am sure it’s possible with Babylon. Any help to guide me in the right direction would be very appreciated!
Line 81 - mesh.onBeforeDrawObservable ==> I am turning stencil writing on and setting stencil function reference for the mesh rendering group id
Line 87 - mesh.onBeforeRenderObservable ==> activating the clip plane here, since doing it in onBeforeDrawObservable above doesn’t seem to work
Line 96 - mesh.onAfterRenderObservable ==> setting up stencil testing and removing the clip plane. what I am not sure how to do is how to draw the mesh again here, but now using the meshInsideMaterial
Any chance you could have another glance at it and see how the last step can be done and if I am missing something or doing something wrong?
Ok, I think I have it implemented in the sequence you recommended, removing observers for the second drawing of the mesh (with inside color), but it’s still not there, so I’m thinking something’s wrong with my stencil setup/testing… : https://www.babylonjs-playground.com/#95MJI8#175
This basically achieves the same result as the Three.js demo from my initial post with just one clipping plane (so far) - planeY, parallel to XZ plane.
Stanford bunny mesh that I used before had holes under its feet, so what should have looked like solid geometry slice had corresponding holes in it as well, as stencil test relies on back faces of the mesh to draw the “inside” material:
This may not be the most efficient solution, but it does the job. So I will document this up, and should the solution improve in the future - I will update the docs accordingly.
Ironically, one of the biggest struggles I faced was to position GUI controls inline next to each other (e.g. along the lines of display:inline-block for CSS). Still couldn’t do it, so will leave it as is. Would love to be able to display “Helper Visible” text blocks next to checkboxes, but they always go onto a next line for me.
Later on this week will add the demo and page to the documentation.
Assign material with only front faces to the original mesh (“meshOutside”)
Assign material with only back faces to the mesh clone (“meshInside”)
For each of the 3 slicing directions create a white wireframe plane helper and a plane I will use for stencil testing (“stencilPlane”) with a distinctive (pink) material color.
Draw meshOuside first, meshInside second and stencil planes last.
For meshOutside onBeforeRender simply create scene clipping planes for X, Y, and Z directions (this will clip only this mesh)
For meshInside onBeforeRender create clipping planes as well, position corresponding plane helpers and stencil planes along those clipping planes and turn stencil testing on.
For each of the stencil planes onBeforeRender turn stencil testing on as well and set stencil function to EQUAL (to only draw stencil plane material on top of the meshInside material).
Now this works well as long as you use only one clipping plane. As soon as you have 2 or more clipping planes you get angles where stencil plane material is not drawn (and it makes sense why - there is no meshInside material behind it), for instance this situation with Y and Z clip planes used:
One of the ideas I tried was to not apply clipping planes for the meshInside material, and have back sides of stencil planes have something to render their materials against, but now I think need some combination of stencil and depth testing to not render parts of the meshInside material that are positioned “in front” of stencil planes:
I feel like I’m dancing around a solution, but still cannot fully wrap my head around stencil testing (with all its functions, pass, fail tests and its connection to depth testing).
Any help and advice is greatly appreciated.
Thank you.
I think it is a bit difficult to handle, since it creates multiple meshes and rendering groups and therefore quite some draw calls for this effect, though…
For one plane, this version takes in consideration obstacles such as a box. I think in other versions, the obstacle would have been rendered within the section otherwise. https://www.babylonjs-playground.com/#95MJI8#368