Face ordering problems when replacing material on GLTF-imported mesh

I’ve been struggling when changing the material on a GLTF-imported mesh. I couldn’t get my test scene to work in the playground, so I posted it at http://durrantlab.bio.pitt.edu/tmp/babylon_gltf_test/ instead.

The object initially displays without any problems, just like it appeared in Blender (using vertex colors). Wait 5 seconds, and my code replaces the GLTF-imported material on the mesh with a StandardMaterial. My thinking in doing this is that I’d like to use baked shadows, though that’s not relevant to this test scene. It’s great that babylonjs still respects the vertex colors, even though the material has changed. But these’s a problem. The object now looks like this:

Notice the numbs that appear where the cylinders intersect. This is because portions of the mesh that should be occluded (on the inside of the mesh) are showing through the surface. I haven’t for the life of me been able to figure out how to fix this problem.

Thanks for your help.

pinging @bghgary :slight_smile:

This is a coordinate system issue. Babylon by default uses a left-handed coordinate system while glTF uses a right-handed coordinate system. The glTF loader by default will add a __root__ mesh with a negative scale transform to convert the coordinate systems and flip all of the winding orders (sideOrientation) of all the materials. For your case, you can fix this issue by either changing the default coordinate system to right handed or set the new material you created to the correct sideOrientation. In your test scene link, after loading the page, you can run the following to fix:

BABYLON.Engine.LastCreatedScene.materials.forEach(material => material.sideOrientation = BABYLON.Material.ClockWiseSideOrientation)

Works great! Much thanks for your help with this.

Looks material.sideOrientation doesn’t affect the texture. as pic 1. I’ve to flip the vertical direction of images in PS, as pic 2. I’m looking for a programmatic way to do this. Any suggestion will be appreciated.

Have you tried inverting the texture with invertY?

Hi bghgary, thanks for your reply. Yes I added invertY as below, but it doesn’t matter.

this.bodyMaterial.baseTexture = new BABYLON.Texture("assets/models/doggy/doggy.jpg", this._core.scene, true);
this.bodyMaterial.metallicRoughnessTexture = new BABYLON.Texture("assets/models/doggy/doggy_rough.jpg", this._core.scene, true);

bodyMaterial is PBRMetallicRoughnessMaterial

Okay, if you can set up a playground, that will help with debugging the problem.

EDIT: invertY is the fourth parameter of the texture constructor. Currently, you are passing true to the 3rd parameter which is for noMipMap.

My fault, should set invertY to false, not true or default value. Many thanks for your help!

1 Like