Small FPS dip/stutter when loading many PBRCustomMaterials

I have a scene that starts out with 143 textures loaded (based on how the camera is facing from the starting player location) initially but when I pan around and see more of the environment more textures are loaded (to 168, as shown in the image below).

When the “total textures” number goes up, there’s a small but noticeable lag/drop in FPS I’m sure it’s due Babylonjs loading these new textures. I think it’s some optimization made to improve load time but is there a setting on the API to just have it load all 168 at the start to avoid the stuttering at playtime? Thanks


You can load the textures at start with new Texture(...) and wait for them to be loaded before going on?

What do you do when the textures are all part of .glb files though? the texture is within the file

All the textures are available in scene.textures, so you can wait for all of them to be ready after the file has been loaded.

on further check it might not be the textures from the glb files…? What are these no_name textures

these seem to be the majority of the added textures (going from 143 to ~168) if I check scene.textures

It could be the bone textures… However, these textures are generated by code and are very small, so I don’t think they are responsible for the stuttering.

yeah those do seem to relate to meshes with skeletons, if I remove all of those the texture counts starts and ends at basically 80. But there’s still a slight stutter when I pan from a spot with not as many meshes/textures to a spot with many meshes/textures for the first time. it’s only on the first time seeing those meshes too - after the initial lag spike it no longer lags when I view them

it was the PBRCustomMaterial I used. I use a lot of them for every PBRMaterial I load from .glb so I can tweak the lighting. for each material I did something like:

            customMaterial.onBindObservable.add(function() {
                if(lumTexture) {
                    customMaterial.getEffect().setTexture('lumTexture', lumTexture);
                customMaterial.getEffect().setColor3("shadeColor", scene.ambientColor);

which you can see takes its toll by making a lot of .prepareEffect calls.

I think it’s the onBindObservable that causes the initial lag spike when you pan the material(s) into view for the first time. Is there a way to just have the materials calculate the effects when the page loads (so I can put the wait behind a loading screen)?

EDIT: on further check, the lagspike will happen whether I use onBindObservable to set effect params for PBRCustomMaterial’s Fragment_Before_FragColor or not. I dont think there’s a way around it then, other than simply not using PBRCustomMaterial

Yes, the problem with PBRCustomMaterial is that we must compile each one (we create a new effect for each) even if they share the same “structure” (meaning, their inputs don’t differ). Try using a regular PBRMaterial with a material plugin instead (Material Plugins | Babylon.js Documentation).

1 Like

cool I’ll try using that then. I only really use the baseColor.rgb and finalColor.rgb in Fragment_Before_FragColor anyways.

1 Like