Loading a texture without fps drop?

I’m loading a texture from web at runtime and then applying that texture to a material.

var asset = new pc.Asset(fileName, "texture", { url: url });
this.app.assets.add(asset);
this.app.assets.load(asset);
asset.on("load", function(asset) {
    entity.model.model.meshInstances[0].material.diffuseMap = asset.resource;
    entity.model.model.meshInstances[0].material.update();
});

However, there’s a very visible drop in fps every time a texture is changed by calling material.update. The textures are quite large (4k resolution, around 1mb). Is there some more efficient way of doing this?

Hi @MikkoK,

Uploading textures from the CPU to the GPU can potentially stall the renderer for a while, producing a noticable fps drop. Apart from loading all textures to the GPU beforehand there isn’t much you can do about it.

Another thing that produces a delay here is the material.update(). That forces the material to recompile its shader. You can avoid this by changing only the necessary uniform used like this:

entity.model.model.meshInstances[0].material.setParameter('texture_diffuseMap', asset.resource);

Note for this to work the original material should have a diffuse map assigned to be replaced. If this is the first time adding a diffuse map to this material, call once material.update() and after that you can safely use setParameter.

2 Likes

Unfortunately it’s apparently the first problem as I also suspected, changing to setParameter didn’t make a noticeable difference.

I’m working on a 360 panorama image viewer with a 3d map, so loading all textures beforehand isn’t really an option as the initial loading time would become too long. I have to load the images from a server in the background on demand. Fortunately the fps drop isn’t that big of a problem at least for now, just a mildly annoying stutter. I guess I’ll need to find a way to reduce the texture size/resolution without losing too much image quality.

1 Like