Good day, I have a 15 megabyte babylon file to load,
loading the scene from a mobile phone or laptop is pretty slow,
is there a way to load in stages or chunks or any other advice to show content to user fast even if load happens incrementally? thank you
You can try with incremental loading :
just tried it, its nice because it loads first the small things and later the big one,
now I just need some kind of loading graphic saying “loading…” or similar,
thank you for the help
You can use something like this:
BABYLON.SceneLoader.ImportMesh(
"",
"http://models.babylonjs.com/CornellBox/",
"cornellBox.glb",
scene,
function () {
// onSuccess
},
function (evt) {
// onProgress
var loadedPercent = 0;
if (evt.lengthComputable) {
loadedPercent = (evt.loaded * 100 / evt.total).toFixed();
} else {
var dlCount = evt.loaded / (1024 * 1024);
loadedPercent = Math.floor(dlCount * 100.0) / 100.0;
}
// assuming "loadingScreenPercent" is an existing html element
document.getElementById("loadingScreenPercent").innerHTML = loadedPercent;
// Or with Babylon.GUI
});
Doc :
thank you very much, this community is awesome, I will give it a try and report back, thank you
Gotta say, if you are going mobile & distributing to other than just yourself, you should learn about Blender’s Limited Dissolve
. Reducing your geometry has more benefits than reducing file size.
You get it in edit mode off the ‘X’ menu. It only applies to the currently selected vertices, so if there are some problem areas with doing it, undo, change your selection, & try it again.
I always delimit by UV’s, when using a material with a texture. You can play with increasing the angle till it is really noticeable.
Many people make some insanely detailed thing, then try to “fix” all the problems downstream. Of course, things may not quite so detailed, but only you know that.
-
@Dad72 David thank you very much, I added the onProgress function and I see that it works, it is returning always 100% so far, I have to test it from mobile to make sure that it returns incremental numbers, because I am using now incremental loading so hopefully will return the intermediate numbers. Now, I want to have a textBlock in 3d space changing according to the percentage loaded, this kind of text:
var label = new GUI.TextBlock();
label.text = “0.00”;
label.fontSize = 11;
rect1.addControl(label);
rect1.linkWithMesh(land1);
After it has been created, how can I refer to it from the onProgress function? how can I get its handle so that I can update it dynamically? thank you
-
@JCPalmer
Thank you very much for this suggestion, Im going to try it. In my case my models are created from scientific computations, so I don’t create them manually, they come out the way they do because of scientific computations so I have to take a lot of care not to distort their shape too much. I will give it a try to see what this Limited Dissolve can do, thank you
@JCPalmer I just tried the limited dissolve feature in blender, this is really fantastic, thank you very much for recommending it; it really helps to simplify the geometry, stunning really; this is much much better than the decimate modifier. The decimate modifier I could not use, it really destroyed the model too much, but this limited dissolve feature is a much better way to reduce some of the complexity, thank you again
@JCPalmer, what do you think of this idea
- in blender duplicate the model, have a high detail version and another duplicated version using limited dissolve that has very little detail
- then use the incremental loading feature of babylon, so that the low detail version loads first, and then once the high detail version gets loaded, the low detail version gets hidden; is it possible to detect when one of the specific messes of the incremental loading has loaded? or when the entire complete process has finished? maybe the onProgress callback gives me that, and then I guess I could hide the low detail version
@JCPalmer yes this is very promising, just tried it and both are loading so now I just have to hide the low detail one once the high detail one has loaded, this is causing me problems because I am trying to access the scene.meshes object inside the onProgress function and its strange, I can see correctly the scene.meshes object with the meshes apparently inside, but when I try to access one of them, scene.meshes[5] for example, the one i have to hide, then i get “undefined”, any tips?
also whats the easiest way to hide the mesh or even better to take it out of rendering, is it visibility?
thank you
This is strange, it seems that the code below, the onProgress function of the incremental loading always has 100% loaded from the beginning and yet never shows length more than 0 of scene.meshes;
however the onSuccess function does show all the scene.meshes data correctly; the problem is that the hiding of the meshes[5] should be done on 100% completion of loading, I just don’t see the onProgress function working correctly, it always says 100%
.................
console.log("here 1: ", scene.meshes.length);
//scene.meshes[5].visibility = 0.3;
},
function (evt) {
var loadedPercent = 0;
if (evt.lengthComputable) {
loadedPercent = ((evt.loaded * 100) / evt.total).toFixed();
} else {
var dlCount = evt.loaded / (1024 * 1024);
loadedPercent = Math.floor(dlCount * 100.0) / 100.0;
}
console.log(loadedPercent);
if (loadedPercent == 100) {
console.log("here 2: ", scene.meshes.length);
}
// assuming "loadingScreenPercent" is an existing html element
//document.getElementById("loadingScreenPercent").innerHTML = loadedPercent;
}
I’m wondering if the onProgress function is valid with the incremental system.
The scene is loaded as soon as a model is visible, so onSucess is directly called and therefore onProgress is at 100% without having loaded all the objects of the scene.
I think that’s the explanation. Maybe @Deltakosh can give us more detail with onProgrress and incremental loading ?
@Deltakosh @Dad72 @JCPalmer thank you very much for your help, so to summarize,
- I am using incremental loading, which is great, definitely I need to use it
- I am including two versions of the model, one in high detail and one in low detail created with the limited dissolve feature of blender. The high res weights 15 megabytes, the low res weights just 1 megabyte
- the objective is that the incremental loading first makes the low res version appear quickly, and this works
- seconds later the high res version is loaded and appears. This works
- I can hide the low res version using “visibility” of that mesh. The problem is that I need to detect when the entire incremental loading has completed in order to do that.
- and the onProgress function is not really working well with incremental loading as it automatically gives 100% from the beginning
so lets see if you have any ideas of how to:
- first display the loading percentage using incremental loading so that people can see how much is left to load
- detect when the entire incremental loading has completed so that I can hide the low res mesh and keep just the high res one
so far the only alternative I tried is this:
setTimeout(function () {
if (sceneHolder.meshes.length == 10) {
sceneHolder.meshes[5].visibility = 0;
}
}, 1000);
but that is also not working, the scene.meshes.length is full from the beginning so it hides the low res version immediately
thank you
@bghgary might have built in tricks for this with GLTF and the MSFT_LOD extension.
This documentation page may be useful: Progressively Load .glTF Files | Babylon.js Documentation
@bghgary @sebavan thank you very much for your support,
will that page applied if:
- I am loading a .babylon incremental file, not a gltf file
- I am using
SceneLoader.Append(
“./models/b10/b10.incremental.babylon”,
“”,
scene,
… etc
would I have to change it to async syntax?
thank you
seems like this is the structure of that method
SceneLoader.AppendAsync(
“./models/b10/b10.incremental.babylon”,
“”,
scene,
function (event) {}
);
it doesnt have a onSuccess callback, is it because all is processed in the same onProgress callback? will I have access to the scene variable from inside there?
Im not sure really how to use the info on that page, could you maybe give me a little example in code to see how I could detect the percentage being loaded of the incremental .babylon file load? thank you
@bghgary @sebavan
the same issue seems to be happening with async version, just goes to 100% directly,
SceneLoader.AppendAsync(
"./models/b10/b10.incremental.babylon",
"",
scene,
function (event) {
console.log(event.loaded);
}
);
@bghgary @sebavan
really puzzling, there should be some way to detect at least when the entire incremental loading has completed, at least that way, even if i cannot show the intermediate percentages, at least i could then hide the low res model, that would already be great, any ideas?
even better of course would be to be able to put the intermediate percentages, but if thats not possible at least there should be a way to know when the entire incremental load has completed, I would think