Materials : Dynamic loading & realtime switching

Hello Guys,

I have an issue here and I cant pinpoint what Im doing wrong. Maybe you can help.

I have a bunch of materials that I preload the textures based on if Im mobile or not (4K vs 2K). I search by tag to get the global material and replace the texture with the right one.

Then, in the app, I will change the material on a sphere. To achieve that I have a materialswitcher script that contain an array of material assets.

But it seems that the material array as is own copy of materials instead of referencing the global material?

Global material seem to have the right texture, but the array material stil point on the old one?

Can I have an array of material references?

Thanks

Mykel

Yes, that is possible. Difficult to tell what’s the issue without a reproducible.

Thanks! and how do I do that? Right now I have:
SwitchingMaterials.attributes.add(“materials”, {
type: “asset”,
assetType: “material”,
array: true,
title: “Materials”});

thanks for the support

Yeah, that looks fine. I can’t see anything wrong with that as they would be references

Its a confidentail project, is there a way for me to add you?

You can add yaustar

Basically, I have the big texture and the smalls, that start with S_, by default, its the S_ textures in the materials, when I detect desktop, I replace S_ by the big one.

Thus, when Im switch materials, Im expecting to find big textures and not the S_ ones.

DynamicLoading.prototype.loadImageEmissive = function (tagMat, tag) {
    
    var app = this.app;
    var self = this;
      
    var assets = app.assets.findByTag(tagMat);
    var material = assets[0];
    console.log('Found ' + assets.length + ' materials named: ' + material.name);
    app.assets.on("error:" + material.id, function (err, material) {
        console.error(err);
    });
    
    var assets2 = app.assets.findByTag(tag);
    var texture = assets2[0];
    console.log('Found ' + assets2.length + ' textures named: ' + texture.name);
    app.assets.on("error:" + texture.id, function (err, texture) {
        console.error(err);
    });
    
    var onTextureReady = function() {
        var onMaterialReady = function() {
            material.resource.emissiveMap = texture.resource;
            material.resource.update(); 
            self.onAssetsLoaded(1, tagMat + ' material Loaded!');
        };
        
        material.ready(onMaterialReady);
        app.assets.load(material);
        self.onAssetsLoaded(1, tag + ' texture Loaded!');
    };
    
    texture.ready(onTextureReady);
    
    app.assets.load(texture);
};

How do you reproduce the issue?

if you run the project, you will have a blurry texture in the 360 sphere, it should be 8k. its very pixelated right now

Is it possible that the default texture loads after the custom one?

when I get out of dynamicloading.js, materials seems to be set correctly (validated with asset ids)

I think I know what’s happening.

The material and the S_ texture are not set as preloaded.

During the startup phase, the 8K is loaded and the material is loaded. When the material has finished loading, it starts it’s texture load of the S_ (as that’s what’s it’s data lists) and that texture gets assigned back to the material after the code has assigned the 8K texture to it.

The easiest solution/workaround here would be to not have a texture assigned to the material as default.

If you go to the syau branch, this is what I’ve done to the material set for the 3D Sphere 360.

2 Likes

Youre right!

Thanks for the support!