PickingInfo.getNormal direction is reversed when not using vertex normals for GLTF

Having an issue where calling PickingInfo.getNormal with the useVerticesNormals (2nd argument) set to false. The returned vector direction is reversed of what it should be.

I was able to reproduce this in the playground. This is using the example provided in the gltf loader documentation. I’ve added a raycast, positioned on the x axis, directed towards -x.

(Open browser inspector console to see output)

Based on the model you would expect the normal to point roughly in the positive x direction, which it does if you use the vertex normals (useVerticesNormals=true)
Result:

Normal from Vertices:
{
    "_isDirty": true,
    "_x": 0.9620177727717718,
    "_y": 0.2599865858795387,
    "_z": 0.08323929380971969
}

However when with useVerticesNormals=false, the normal direction is reversed:

Normal from cross product calculation:
{
    "_isDirty": true,
    "_x": -0.964271446769104,
    "_y": -0.23283821473925717,
    "_z": -0.1263603684026554
}

Code ref: Babylon.js/pickingInfo.ts at master · BabylonJS/Babylon.js · GitHub

I’m still pretty new to this space but I’m guessing this has something to do with the gltf winding order?

Is this a bug or am I just missing some option to control this behavior?

pinging @bghgary

Hey, sorry for the delay. I somehow missed looking at this one. Will look at it now.

Yes, this looks like a winding order issue. It’s not specific to glTF though. This code needs to take the winding order into account, and it doesn’t. Do you mind filing a GitHub issue for this?

Thanks for verifying! Filed: PickingInfo.getNormal direction is reversed when not using vertex normals for GLTF · Issue #13115 · BabylonJS/Babylon.js · GitHub

See comment.

I opened a PR that will always return the normal towards the picking ray. The other option is to determine the winding order based on what material is being used, but I think I would always expect the normal to be towards the picking ray. Let me know if anyone disagrees.

Flip normal if picking ray is in the same direction by bghgary · Pull Request #13128 · BabylonJS/Babylon.js (github.com)

3 Likes

I’ve merged the PR.

2 Likes

This is causing issues for us. We want to get the actual normal value for the pick result. Is there an easy way to do this now?

We are seeing our normals being flipped on 5.32.1 (but not on 5.25.0) depending on the camera angle. The mesh has a local rotation. Looking at the code, I am wondering if this is related to the fact that the ray is compared against the local normal instead of the world normal? As I type this I am realizing that this code has changed a bit in newer versions. Will dig in more tomorrow.

1 Like

I think some extra fixes were done in 33 IIRC. @Evgeni_Popov might be able to confirm ?

Yes, we did some updates lately to this but I can’t remember in which version…

The PR is:

2 Likes