Solved: Issue with Inverted Meshes and Mirrored Textures when using SceneLoader.ImportMeshAsync

Hello, dear forum members!

I’ve encountered an issue that I can’t solve, and I hope for your help. When I load GLB (gltf with binary data) models into Babylon.js using the SceneLoader.ImportMeshAsync method, I notice that all meshes are inverted, and the textures are mirrored.

Interestingly, when I load the same models with the same textures using any other editors, everything displays correctly. The problem only occurs when using SceneLoader.ImportMeshAsync in Babylon.js.

I’ve made sure that the issue is not related to the settings of the models or textures, as they work correctly in other environments. Perhaps the problem is related to how Babylon.js processes coordinates or material settings.

I would like to hear from you if anyone else has encountered this issue? And perhaps someone can share a solution or a hint on how to fix this problem?

I would appreciate any help and advice!

Thank you!

Upd.:
I am sorry. I found the problem. It was because of my scaling settings.

mesh.scaling = new Vector3(1, 1, 1)

Bug is not exists.

cc @bghgary

I didn’t realize that if I do scale as mesh.scaling = new Vector3(1, 1, 1), then it become inverted.

1 Like

Any such scaling turns the model inside out. It helps:
mesh.scaling = new BABYLON.Vector3(-100, -100, -100);
mesh.rotation = new BABYLON.Vector3( 0, 0, Math.PI);
But maybe there is some more elegant way?

I don’t know is it correct way or not, but I use this:

new Vector3(-1, 1, 1)

When animate scaling:

  async animateScaling(
    mesh: AbstractMesh,
    targetScaling: Vector3 = new Vector3(-1, 1, 1),
    animationSpeedRatio: number = 1,
  ): Promise<void> {
    return new Promise<void>((resolve) => {
      if (mesh && mesh.scaling) {
        const scalingAnimation = new Animation(
          'scalingAnimation',
          'scaling',
          this.fps,
          Animation.ANIMATIONTYPE_VECTOR3,
          Animation.ANIMATIONLOOPMODE_CONSTANT,
        )

        const keys = [
          {
            frame: 0,
            value: mesh.scaling,
          },
          {
            frame: this.fps,
            value: targetScaling,
          },
        ]

        scalingAnimation.setKeys(keys)
        mesh.animations.push(scalingAnimation)

        const onAnimationEnd = () => {
          if (scalingAnimation) {
            mesh.animations = mesh.animations.filter(
              (anim) => anim !== scalingAnimation,
            )
          }
          animation.onAnimationEndObservable.removeCallback(onAnimationEnd)
          resolve()
        }

        const animation = mesh
          .getScene()
          .beginAnimation(
            mesh,
            0,
            this.fps,
            false,
            animationSpeedRatio,
            onAnimationEnd,
          )
      }
    })
  }
2 Likes

I have this as well; imported glbs are mirrored. To solve I have to scale by -1 on the x axis.

2 Likes