And the problem is always the same texture loading drops the FPS introducing a lagging experience, I know that the problem comes from javascript as it is single thread.
But what if we could just download the file without actually loading the texture, obviously the time youâll need to load the texture will be much slower than downloading the actual URL + loading the texture.
you can preload textures (or anything else), and store them as Blobs in your browser. later you can use this blob as input for any type of asset you are loading.
A very naive example:
The fetch can be done beforehand, and the URL for the blob can be stored or created when needed
Unfortunately my intention is to preload (without being applied) several cubemaps and fetching the cube sides seems to have no effect on the performance for the first loading.
prefetch only makes sense if you have the time to fetch in the background and you donât need the files for your initial display of the scene
It will improve performance if the cubemaps are displayed in a future scene.
It all depends what is the blocking part. If it is about gpu decoding for pngs for instance, it could be moved on a worker thread and shared back as an imageBitmap.
About heavy cpu process for hdr and such, you could think of moving to a worker the decode part and use a sharedArrayBuffer to share the result back (this would not work so far on every browser)
If the gpu transfer is the slow part there is not much that could be done but uploading the data in chuncks/tiles to the gpu.
This pg shows improvements from using power of 2 textures and compression . Reduced 200ms to 30ms for gpu time on smaller textures. Playground #13 has a comparison for gigantic textures and ktx compression. Ktx speedup is like 25% on gpu load, but overall feels way faster. Thanks @roland . Really first though, setting up a service worker will make everything so much better. Service workers run in another thread , and you can do preprocessing in them. For profiling , first u want to check network with cache disabled , then if u need to, go to performance and record a profile and sort by longest execution time.
Also, if u can say the file type and file size, someone will probably already know the best way to do it
Iâm using cubemaps so it makes it a bit harder since I have to download the 6 faces (jpg format) and Iâm not sure if I can use that approach maybe our gurĂș @Deltakosh could say if we could create a cubemap from 6 array buffers.
Share my experience
Loading textures after loading the scene via Texture.updateURL() lags much less than if creating a texture via new BABYLON.Texture(). On a 7MB texture, the lag time is 8ms versus 70ms.
8ms seems very fast for a 7mb texture. Is the asset prefetched? ie: using create react app or another setup with a service worker preconfigured? How are you measuring the time? Iâve seen onSceneReady or whatever the event is named say the scene ready before the textures are ready.
Compared texture adding time using chrome devtools - network
It seems to me that the indicators may be different depending on the equipment and network configuration, but in my case there was an improvement, which was noticeable visually, for example, when you quickly rotate the camera and the lag became much less
Cool, canât beat visual improvements. Itâs weird youâre fetching, doing stuff with data, then updating the url (so the assets already been fetched from the network before you update the url). Seems like the fetch isnt necessary since you arent passing in the manipulated data to the texture?
Regardless, thanks for sharing. Seems like itâd be possible to add a static createAsync to the Texture class that uses updateUrl internally. This way, main thread creates empty texture â yield to network and asset worker â finalize on main thread. Exactly what youâre doing, just codifying it. Although, its not really âcreateAsyncâ its more like, createSyncAndUpdateAsync lol