Load Draco_ Gltf has serious performance issues

When I load a larger model, the loading time is about 30 seconds, and testing the same model using Threejs only takes two seconds All tested without cache


cc @bghgary, I think we are using the same wasm as Threejs to decode draco?

I think if you can share your glb file, it will be easier for us to look for the problem.

Can you provide an email?

Ps: Will the Draco decoder of Threejs directly convert the GLB file into grid data, while Babylonjs only decodes it into regular GLB, and then uses JavaScript to load it again

You can send it to me by PM in this forum (AFAIK, we don’t create a temporary glb file when decoding draco compressed data).

Sent via private message, please check


The same model has obvious lag in Babylonjs and is relatively smooth in Threejs

Are you saying both the frame rate is low and the loading is slow?

First, your model has really a lot of meshes: 31000+!

Also, there’s no instancing, so there are more than 31000+ draw calls each frame, which is killing the framerate.

Babylon.js does not optimize the scene by default, for ease of use. I’m running at 10fps in Babylon.js and 13fps in Threejs. If I freeze the active meshes (scene.freezeActiveMeshes()), I get around 14fps in Babylon.js.

That’s not what I experience:

I would say that it’s not so bad, but maybe we can still optimize a bit…

I really don’t see how Threejs could load the file you sent me in 2s while at the same time it would take 30s in Babylon.js… Can you test with other glTF viewers, like the ones I mentioned above?

4 Likes

I recorded the video because it had already started recording before importing. You can pay attention to the timing of the import time and end time. Babylonjs took more than 1 minute and three seconds

chrome 113beta

device :cpu 6800u 16g+512g
@Evgeni_Popov

Slow loading and running speed

Could you please use (three.js editor chrome 113beta ) to test it

It takes 7s - 7.5s to load it into the three.js editor on my computer, so a little better than the 8.5s in the Threejs glTF viewer, but not that different.

See my answer regarding slow running speed:

Regarding the slow loading I don’t really know… Do you have some messages in the console log?

@bghgary Can you reproduce the problem regarding the loading time or do you have a similar experience to mine?

Probably not related, but I wonder why you don’t have the default env map in the sandbox…

After testing, the loading time on Chrome version: 113 beta and webview2 is many times longer than that on Edge. Can we increase the parameters? When the grid is loaded, even if the material is not loaded, it can still run normally, allowing the material to load in the background and reducing waiting time

Perhaps you have extensions that interact badly with the sandbox? Try using an incognito window to rule out this possibility.

What are the parameters you want to increase?

Add a parameter to enable progressive loading. When the parameter is true, it does not require the grid and materials to be fully loaded before the normal interface can be displayed. It can be displayed while loading. When it is false, it is necessary to wait for the grid and materials to be loaded before the normal page can be displayed (currently, the loading section interface must be completed before it disappears and users can control the page) @Evgeni_Popov

It’s not really possible, I don’t think we can load from a separate thread to free the main UI thread.

Anyway, the Sandbox is not an editor (like the Threejs editor is), there is no point in having access to the UI (the inspector) if the scene is not loaded.

No, it works similarly for all the scenarios I tried.

I tried using performancePriorityBABYLON.ScenePerformancePriority.Aggregative, but the model became invisible during roaming. What should I do to resolve this issue

I’m not sure I understand what you mean by “become invisible during roaming”, because when you use aggressive mode, the frustum clipping check is disabled, so all meshes are considered visible and are rendered on the screen. The scene is no longer cleared, however, which can produce artifacts if you don’t have a background that fills the entire rendering scene. Try setting scene.autoClear = true after switching to aggressive mode, to see if this is the problem.

1 Like

The following is my code for implementing a walkthrough. Given a series of coordinates, position x y z, alpha beta radius, define a small ball, use an animation group to move the ball and camera coordinates, and a continuous animation will be formed. It works well in BackwardCompatible and Intermediate, but there are no images in Aggregate and the model is not visible

    let defaultcamera = this.scene.getCameraByName("default camera")
        defaultcamera.alpha = Roam.frame[0].alpha
        defaultcamera.beta = Roam.frame[0].beta
        defaultcamera.radius = Roam.frame[0].radius
        let myMaterial = new BABYLON.StandardMaterial("NMY", this.scene);
        let target = BABYLON.MeshBuilder.CreateSphere("MY", { diameter: 1 })
        myMaterial.alpha = 0
        target.material = myMaterial
        target.position = new BABYLON.Vector3(Roam.frame[0].position.x, Roam.frame[0].position.y, Roam.frame[0].position.z)
        defaultcamera.target = target
        defaultcamera.lockedTarget = target
        let animation1 = new BABYLON.Animation("alpha", "alpha", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
            BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
        let animation2 = new BABYLON.Animation("beta", "beta", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
            BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
        let animation3 = new BABYLON.Animation("radius", "radius", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
            BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
        let animation4 = new BABYLON.Animation("x", "position.x", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
            BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
        let animation5 = new BABYLON.Animation("y", "position.y", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
            BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
        let animation6 = new BABYLON.Animation("z", "position.z", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
            BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);


        let keys1 = [];
        let keys2 = [];
        let keys3 = [];

        let keys4 = [];
        let keys5 = [];
        let keys6 = [];
        for (let index in Roam.frame) {
            keys1.push({
                frame: index * 60 * 6,
                value: Roam.frame[index].alpha
            })
            keys2.push({
                frame: index * 60 * 6,
                value: Roam.frame[index].beta
            })
            keys3.push({
                frame: index * 60 * 6,
                value: Roam.frame[index].radius
            })
            keys4.push({
                frame: index * 60 * 6,
                value: Roam.frame[index].position.x
            })
            keys5.push({
                frame: index * 60 * 6,
                value: Roam.frame[index].position.y
            })
            keys6.push({
                frame: index * 60 * 6,
                value: Roam.frame[index].position.z
            })
        }
        animation1.setKeys(keys1);
        animation2.setKeys(keys2);
        animation3.setKeys(keys3);
        animation4.setKeys(keys4);
        animation5.setKeys(keys5);
        animation6.setKeys(keys6);
        let animationGroup = new BABYLON.AnimationGroup("defaultcameraAnimationGroup");
        animationGroup.addTargetedAnimation(animation1, defaultcamera);
        animationGroup.addTargetedAnimation(animation2, defaultcamera);
        animationGroup.addTargetedAnimation(animation3, defaultcamera);
        animationGroup.addTargetedAnimation(animation4, target);
        animationGroup.addTargetedAnimation(animation5, target);
        animationGroup.addTargetedAnimation(animation6, target);
        animationGroup.normalize(0, Roam.frame.length * 60 * 6);
        animationGroup.speedRatio = this.option?.config?.roam?.speed ?? 3
        animationGroup.play(true);