Model Blinks when Switching Materials

Hello,
We’re developing BabylonJS for product configuration. Here is a link to a jersey demo:
http://www.david-eustice.com/Jersey_BJS/index.html

Is there a way to eliminate the model blink when switching jersey colors? We’ve had a few requests to fix this.

Here’s a snippet of code that’s linked to the Red button:

// Change to Red //
document.getElementById("Red").addEventListener("click",function () {
    myJersey.material.albedoTexture.dispose();
    myJersey.material.bumpTexture.dispose();
    myJersey.material.albedoTexture = new BABYLON.Texture("models/colored/red/Red_baseColor.jpg", scene, true, false);
    myJersey.material.bumpTexture = new BABYLON.Texture("models/colored/red/Jersey_Normal.png", scene, true, false);
});

I would recommend to just create a new material, and affect it to the mesh when ready (material.isReady())

1 Like

hi. you can create two materials, clone the mesh and animate the transparency of the materials thereby obtaining a smooth transition or blending materials in the shader, but at the moment there is no implementation of the pbr material in the shader node editor. let’s call a shader specialist)))

I don’t think that you need to create new materials. New texture is enough for this purpose.
Blinking at your example may have 2 reasons:

  1. Texture is not yet loaded when switching - so make sure it is fully loaded before switching (for example, with Asset Manager).
  2. You dispose texture, then apply new one. Try to do vise versa - first apply new one, then dispose old (if it is really needed; I don’t see any sense in it since user can click on other button and you will need to wait till disposed texture will load again…)

You may be interested to have a look at my demo Mu-so 2nd Generation 3D or more extended testing prototype Mu-so 2nd Generation 3D (there could be some short blink when you change texture for the first time but the model itself stays as it is).

These are my thoughts how to fix your problem.

Thank you all. I will try all of these suggestions and hopefully be back with a solution.

Replace them before you dispose the old ones, with the way you have it written there would be a 2ms gap minimum (if both lines only take 1ms) where the textures are blank.

I found a solution that should work, I think. My coding ability is fairly poor so forgive me if this looks rough but here’s what I came up with:

var RedJersey = new BABYLON.Texture("models/colored/red/Red_baseColor.jpg", scene, true, false);
var RedBump = new BABYLON.Texture("models/colored/red/Jersey_Normal.png", scene, true, false); 

// Color Change  //
document.getElementById("Red").addEventListener("click",function () {
    var RedJersey = new BABYLON.Texture("models/colored/red/Red_baseColor.jpg", scene, true, false);
    var RedBump = new BABYLON.Texture("models/colored/red/Jersey_Normal.png", scene, true, false); 
    myJersey.material.albedoTexture.dispose()
    myJersey.material.bumpTexture.dispose()
    myJersey.material.albedoTexture = RedJersey;
    myJersey.material.bumpTexture = RedBump;
});  

You can see an example here. The model doesn’t blink when you change materials:
http://www.david-eustice.com/Jersey_BJS_test/index.html

2 Likes

I found that material.isReady() will be false at the first call and true after that.

/// ... creating material
material = ...
console.info("material status 1: " + material.isReady()); // false
console.info("material status 2: " + material.isReady()); // true

Is it proper logic to always call isReady() after creating a material, so that it can be used at runtime later (e.g. a mesh switch to use several materials that are created before ahead)?