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?
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:
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.
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.