Ray intersection from the invisible (culled) side

I am trying to show some ray-traced rays. For the actual tracing the main bits are worked out, but I am left with the trouble to find the ray intersections when leaving the mesh.
I tried all kinds of tricks, like modifying normal orientations and enabling/disabling backFaceCulling. All of this seems to work fine for the actual visualization, but not so for the rays that are probed by testing for intersections:

Note that the wanted intersection coordinate should be positive (not negative) one.
Any ideas? My current (ugly) solution is to first define a new origin outside the object (but how large of a disctance to go?) and trace the ray backwards. But this is not a good solution.

Another problem is that if you start a ray in a dynamic scene form a point, it sometimes hits the same surface again. Any idea how to elegantly prevent this? Also here the current solution is to give it some head start distance, but that is also not nice. If I could simple change the mesh-orientation (inside-out) and the intersections would accept this, all would be fine as also this ray would not hit the wrong side.

You can use the triangle picking predicate to check for the dot product between the triangle normal and the ray’s direction: The inverse box | Babylon.js Playground (babylonjs.com)

1 Like

Thanks a lot. This is really great and exactly what I need. Is this a undocumented feature?
To make it a little more userfriedly, I wrapped your code in a function:

    function pickBackfaceWithRay(scene, ray) {
        return scene.pickWithRay(ray, undefined, false, (p0, p1, p2, ray) => {
            const p0p1 = p1.subtract(p0);
            const p2p0 = p2.subtract(p0);
            const normal = BABYLON.Vector3.Cross(p0p1, p2p0);
            const dot = BABYLON.Vector3.Dot(normal, ray.direction)
            
            return dot > 0;
        }); 
    }    

see also the playground:

Thanks again for the great help!

… is there also a way of using such a triangle predicate with the intersectsMesh method? I would guess this could save precious computational time, since only a single mesh need to be checked?

Just to be sure that there is no misunderstanding for future users:
for normal (not inside-out) objects, the code to use to probe from the inside is:

    function pickBackfaceMeshWithRay(scene, mesh, ray) {
        return scene.pickWithRay(ray, (m)=>(m == mesh), false, (p0, p1, p2, ray) => {
            const p0p1 = p1.subtract(p0);
            const p2p0 = p2.subtract(p0);
            const normal = BABYLON.Vector3.Cross(p0p1, p2p0);
            const dot = BABYLON.Vector3.Dot(normal, ray.direction)
            
            return dot < 0;
        }); 
    }

Here is the playground:

We have a mention of that here: Mesh Picking | Babylon.js Documentation (babylonjs.com)

It was not added to the Ray.intersectsMesh function, but it is on the Mesh.intersects so you could do this: The inverse box | Babylon.js Playground (babylonjs.com)
Which is more work than it should so I’ll look into adding the rest of the parameters to the Ray function :sweat_smile:

1 Like

I like this approach. This should presumably be fastest. Here is the same with the closed box and intersecting for the inside-out surface:

Adding a predicate to the ray.instectsMesh function would simplify the use. Also it would be really good, if the documentation of pickWithRay include a statement making clear that the picking without the trangle predicate does NOT care about the mesh rendering predicates such as sideOrientation at all.

Merged yesterday so it will be on the next release: [Ray] Add same parameters from AbstractMesh.intersects to Ray.intersectsMesh by carolhmj · Pull Request #13954 · BabylonJS/Babylon.js (github.com) :smiley:

1 Like

Also added some clarifications on the codedoc: [Documentation] Add some clarification about picking triangles from b… by carolhmj · Pull Request #13963 · BabylonJS/Babylon.js (github.com)