Problem Streaming Multiple Textures

I’m new to javascript and PlayCanvas and - working on a pretty complicated Project - came across a problem i don’t know how to solve:

I’ve got a scene with about 150 cloned models that are rather complex and i want to set individual textures to each of them.
These Textures (about 5 per clone) are stored in a firebase storage and downloaded at runtime.
The models themselves have LODs, they only need their textures when the camera is close to them as all other Levels of Detail look (more or less) the same.
The Problem i’m facing is that everytime i come close to one of those objects and the new materials including the downloaded textures are distributed on the mesh instances and are rendered for the first time there is a huge lag in the scene.
The only way i could get rid of this lag is by dowloading all the textures and setting all the Materials before activating the LOD scripts on each of my models. But that means i’ve got a huge amount of data loaded into VRam (~4,5 gb) at any given time, which will be problematic for many devices.

i will try to provide a generic project, but thats rather problematic as well because i dont really want to give out firebase access.

i hope that was comprehensible and you guys can help me out here.

Re VRAM, I think only the ORG accounts have access to texture compression that can help reduce the VRAM usage.

Re Huge lag, is that from downloading on demand and/or processing the texture too?

It’d be useful to profile the application (in Chrome dev tools) to see what’s causing the slowdown. How large is the slowdown? It could be related to downloading / creating the texture itself, but also compiling shader for your new material.

Okay so the Lag only occurs when the app actually renders the new Materials (compiling the shader maybe?).
Just downloading and creating a material without actually using it keeps the app running smoothly.

Is there any way to compile the new Materials when they’re not visible so they will be ready when the player come close enough for the LOD to change?

Are you able to profile the build and upload us to profile, so that we can confirm what is going on there?

One thing you could try is to set up one material the same way as final material with textures, but use tiny (4x4 pixels) white textures or similar, so that visually it works the same as without texture. Then when you download textures as needed, just replace texture, which should not rebuild shaders.

Thanks for your support guys, i really appreciate it.
Building materials with tiny textures definitely helped a bit!
Sorry that i still cant provide an example scene, but im working on it.

One thing you guys could help me out with is how i can unload/load my streamed textures at runtime.
I cant figure out how to add the textures i create at runtime to the asset.registry properly. Mind you the textures are streamed from firebase. I think being able to load/unload them via the registry will solve my problem.

You can unload any texture asset from VRAM using:

myAsset.unload();

And you can easily upload it back to VRAM using:

this.app.assets.load(myAsset);

I dont know how to acces my specific textures though.
After creating a new pc.texture in code and setting my data as resource, how can i add it to the registry?

So, if you are loading an image from a remote url you can wrap it with a pc.Asset like this:

        var asset = new pc.Asset('imageName', "texture", {
            url: 'https://myurl.com/image.png',
        });

        this.app.assets.add(asset);

        asset.ready(function () {
           // here you can execute code after the texture has been loaded
        });

        // the following line will load the asset for the first time
        // loading means both downloading it (if it's not available in the browser cache)
        // and uploading it to VRAM
        this.app.assets.load(asset);
1 Like

this did the trick, everything works now!
Once again thanks for your support!

1 Like