Dynamic loading of materials?

Hello guys,

I’m having a bit of a problem here. I’m trying to achieve to load bigger textures (4K) if desktop platform is detected to get higher resolution images on a 360 sphere.

Here is a sample code

DynamicLoading.prototype.loadImage = function (url, tag, isDesktop) {

var app = this.app;
var self = this;
  
var assets = app.assets.findByTag(tag);
var material = assets[0];

if(isDesktop) {
    app.assets.loadFromUrl(url, "texture", function (err, asset) {

        if(err) {
            console.log('Error dynamically loading texture');
        } 
        else {
            // Callback function when an asset is loaded
            var onMaterialReady = function() {
                material.resource.emissiveMap = asset.resource;
                material.resource.update();
                
                //change texture on already loaded sphere
                if(tag === 'general')
                   self.sphere360.model.meshInstances[0].material = material.resource;
                

                //change textures on stored materials in switchingmaterial.js script, this is used to change material 
                //on sphere when teleporting
                for (var i = 0; i < self.sphere360.script.switchingMaterials.materials.length; ++i) { 
                    
                    if(self.sphere360.script.switchingMaterials.materials[i].tags.has(tag)) { 
                        self.sphere360.script.switchingMaterials.materials[i].resource.emissiveMap = material.resource;
                        self.sphere360.script.switchingMaterials.materials[i].resource.update();
                        break;
                    }
                }
                
                self.onAssetsLoaded(1, tag + ' Loaded!');
            };

            material.ready(onMaterialReady);
            app.assets.load(material);
        } 
    });
} 

};

Seems like I cant get the materials contained into the script switchingMaterials.js to be updated and always have the default textures (2K).

Any ideas?

Thanks for the support

Any chance of a reproducible for this one? I would be checking at runtime of the materials of the meshInstance are referencing the correct material and textures.

1 Like

sending it in private message

1 Like

I’ve forked the project and deleted the fork.

In this case, the material and 2K textures are not preloaded so therefore the order of load is the following:

Load 4K texture.
Once completed, load material. The loading of the material also triggers the loading of the default 2K texture that is assigned to it in the Editor.
Once the material is loaded, assign the 4K texture to the emissive map.
The 2K texture then finishes loading and gets assigned to the emissive map.

So now the material ends up with the 2K texture.

The best way to get around this is to not have the 2K texture assigned to the material in the Editor and instead, assign the 2K or 4K texture at runtime rather than trying to overwrite the existing mapping.

Is there are reason why the 4K textures are on cloudfront and not in the project? If it was in the project, you could create an array of a data object with material asset, desktop texture asset, mobile textures asset using JSON schema attributes.

1 Like

Ok! I’ll take a look,

the 4k assets are streamed in to keep the build smaller for mobile. they are like 20mb each. Using the big images on mobile will cause random crash for me when teleporting. I dont have this problem with smaller image.

so if everything was in the build, I would need to download double size?

its still unclear for me what is actually downloaded (size of build?) and what size it will take into memory.

thank you for the support.

If they are not preloaded, the client doesn’t download them until they are requested.

Also, I would consider using Basis texture compression for the textures to bring the VRAM usage down. This should allow you to use 4K textures on mobile.

1 Like

When I create a build, the size in mb, is alway the same regardless of if stuff is preloaded or not? or that size is not what the client will download?

That is correct as the assets still need to be uploaded to the server regardless whether the client downloads them or not.

What the client downloads is not relative to size of the build as non preloaded assets are not loaded during the initial loading screen.

1 Like

can I use basis texture compression if my texture are not square or Power of 2?

At the moment, they have to be power of 2. They don’t need to be square.

ok, ill give a try

Thanks for the support