GLB rendering freeze optimization

Hi guys,

First of all thank you again for your great work!

This is going to be an open question but maybe you guys have an idea on how to make things better here.

We are basically loading and rendering at runtime GLBs (which can be of any source - so this is not something under our control).

To do this we’re using the function we found in the GLB loading example project you guys provide:

        utils.loadGlbContainerFromUrl(data.url_3d, null, null, function (err, asset) {
            var renderRootEntity = asset.resource.instantiateRenderEntity();
            var app = pc.Application.getApplication();
            .....
            app.root.addChild(renderRootEntity);
        });

This is causing the application to freeze (bigger or lower freeze time depending on the imported GLB) - following some research I guess this is because the shaders need to compile when the GLB is rendered (but is it?)

You can see it happening here at the beginning: here

Is there any way to optimize this or make it async so that it doesnt freeze (even if that means a bigger rendering time, it doesnt really matter to us) - or any workaround to avoid (or highly reduce) this freeze (even ugly workarounds)? We could just hide this during loading screen but we’d like to know if there’s a better workaround if we didn’t have any loading screen available to hide the problem (open world for example). For your information (this might help?) we know in advance how many GLB we’ll be loading in the scene (but not which ones and from where).

Thanks in advance for your help,
Theo

Depending on the GLB, it has to create the meshes and models, create the entities/nodes for the model in the scene, upload textures to the GPU and compile shaders.

Unfortunately, there’s no real way around this besides loading the GLB and creating the enabled entity ahead of time (eg between levels).

To reduce the effect/freezing, such as in the open world example, you may want to create the entities from the GLBs over several frames/time instead of the same frame.

1 Like

Thank you for your response, I really appreciate!

“To reduce the effect/freezing, such as in the open world example, you may want to create the entities from the GLBs over several frames/time instead of the same frame.” => Not really sure about this - would you have an example code that I could look into?

The lag you get when an object comes into view for the first is definitely shader compilation, that happens the first time that shader is requested by a material/mesh instance coming into view.

Related post: Asynchronous loading of game assets - #10 by Leonidas

There isn’t a straightforward to precompile all those shaders, what usually developers do is force all materials/models into view for a single frame, at application start time. One way to do that is to have your camera render the full scene with frustum culling disabled and all entities enabled, for a single frame.

1 Like

If you have multiple entities to spawn into the world that are using different GLBs, don’t spawn them in the same frame and instead spawn them over the next N frames.

Thank you both for helping!

I’ll try to find documentation in regards to frame management as it doesn’t ring any bell (is it actually rendering a glb (using the function I’ve shown in first post) one by one in the update function at successive calls? I’m understanding things better where looking at code so if you guys have any example that could help me or future readers of this post I’d take it happily - but otherwise I’ll just RTFM :slight_smile: ).

“One way to do that is to have your camera render the full scene with frustum culling disabled and all entities enabled, for a single frame.” => didn’t understand this but I’ll try to read docs about frustum culling, thanks!

So I guess in an open-world scenario I would have to accept the fact that sometimes we’d have to get some kind of lag when loading specific zones if this involves dynamically-retrieved GLBs, right? Is there any long-term plan to allow this kind of scenario to run in an async fashion to avoid this (is the following related? Async Shader Compilation (KHR_parallel_shader_compile) · Issue #1474 · playcanvas/engine · GitHub)