Hi,
I am not 100% sure. I think it has to do something with PBR materials - but don’t hammer me on this.
The general flow is the following:
- Open page
- Load Textures (use onLoaded callback)
- Load Object (use onLoaded callback)
- Check if there are not pending textures/objects/etc
- Check if textures ready if not, try again later
- If everything ready, render scene and execute my ready handlers
An output of ready can look like this:
READY: tex/material/noise.metallness.png
READY: tex/material/noise.png
READY: tex/material/noise.normal.png
READY: tex/m05/polish.png
READY: tex/m05/polish.normal.png
READY: tex/m05/polish.anisotropic.png
READY: tex/m05/polish.metallness.png
READY: tex/m05/ambient.png
READY: m05.babylon
READY: tex/environment/world.env
Environment seems to be the last one always.
It’s really really hard to debug. I can only play with network throttle etc. It’s working 100% of the times for met - but not for some users. I have no specific idea.
This is my render method for state changes of the scene:
// Do a full render - incl. shadow
render(force = false) {
if (!force && !this.isReady()) {
if (this.awaitingAssets.length > 0) return;
this.scene.render(); // Trigger something?
console.log('SCENE NOT READY => Wait');
if (this.waitTrigger) {
clearTimeout(this.waitTrigger);
}
this.waitTrigger = setTimeout(
this.render.bind(this, false),
this.waitDuration
); return;
}
while (this.onReadyPromises.length)
this.onReadyPromises.pop()();
this.light.autoUpdateExtends = true;
this.light.shadowOrthoScale = 0.1;
this.light.autoCalcShadowZBounds = true;
this.scene.render();
this.light.autoCalcShadowZBounds = false;
this.light.shadowMinZ = Math.ceil(this.light.shadowMinZ);
this.light.shadowMaxZ = Math.ceil(this.light.shadowMaxZ);
this.shadowMap.refreshRate = 1;
this.scene.render();
this.shadowMap.refreshRate = 0;
this.light.autoUpdateExtends = false;
}
This the render function given to run render loop:
// Render the scene if needed
onRenderRequest() {
if (this.camera.inertialAlphaOffset ||
this.camera.inertialBetaOffset ||
this.camera.inertialRadiusOffset ||
this.camera.inertialPanningX ||
this.camera.inertialPanningY) {
this.scene.render();
}
}
I hope you understand what I am doing.
It’s working fine for me. But today got a mail with missing metallness/bumpMap/anisotropic texture on load which appears magically on rotate - but as you can see, I tried my best to firstly show the object when it’s ready. I am sure it’s a pretty small thing.
Info I even start the “isReady()” calling on the next frame, so there is at least a small amount of time for what ever Babylon/WebGL is doing internally with textures.
Like this:
onAssetReady(name) {
console.log('READY: ' + name);
this.awaitingAssets.splice(this.awaitingAssets.indexOf(name), 1);
requestAnimationFrame(this.render.bind(this, false));
}
I cannot find a complete texture checkup in the scene.isReady() function on github.
Maybe something is there that is missing. Something like texture compiled or maybe the RGB split thing of the PBR textures.
It seems only to check for pending. I don’t think that’s enough for textures?
See: Babylon.js/scene.ts at master · BabylonJS/Babylon.js · GitHub