I have been doing some investigations into scene management (inspired by the same reasons in the discussion linked at the end )
There might be a bug in the following use case:
If the same textures are used on different materials
and one of the materials is unloaded and then one of the shared textures is loaded
then the bound _onTextureLoad() method is called for the unloaded material causing an error.
eg “TypeError: Cannot set property ‘emissiveMap’ of undefined”
Here is a project that displays the issue, and in assetHelper.js there is a potential workaround.
Here are some more details on the issue. I think this is what is happening.
When the material’s asset references are created these callbacks are set:
When the material is unloaded the callbacks for the assetReferences aren’t removed:
So when a texture from the assetReference is subsequently loaded the callback is called for the now unloaded material asset:
and this causes the error as the material asset is undefined.
So you probably want to either remove the callbacks, which is what I did in my hack workaround ( but then they need to be recreated later when the material is reloaded) or check that the material is not undefined in these callbacks.
I got around the issue by patching the MaterialHandler. I also made an AssetHelper class that will download all the scene’s json files and parse to get all the asset dependencies per scene. It’s work in progress ( Javascript is not my first language )
Thanks for investigating into this and glad that you had found a workaround, I will add this to our internal tracker and try to schedule an engine level fix
Oh cool, nice job tracking this down. In my project I unload models and textures, but don’t unload materials because of this. Wasn’t a blocker, but cool to see someone was able to figure this one out.
So it looks like with the latest engine release, the app no longer crashes when unloading assets on scene destroy and then reloading them on reload, but I am getting a bit of strange behavior.
Now when returning to the scene, it seems that none of my textures actually get applied to the material. The runtime lightmaps still appear to work, but none of the other maps appear to load. Looking at the console, I’m getting a warning of:
Ignoring unsupported input property to standard material: validated
for each material with a texture that gets loaded.
I made a repro of the behavior, but strangely, the warning doesn’t appear in the repro, so I could be doing something wrong in general.
To see the behavior, just click to go to scene 2 then scene 1 then scene 2 once more. You will see that the material unloaded from the Earth Sphere, does not get applied on reload. The moon’s textures get unloaded, but the material does not.
Also, one more observation. It appears that the same unloading and reloading material issue also applies to cubemaps that get unloaded. The app crashes and presents the error:
facetextures[0] undefined
Simply not unloading the cubemap prevents crashing even when textures are unloaded.
On line 235 when reloading the material, data[name] is a Texture (from the previous load I think) and so the IF test fails and the code to assign textures doesn’t get executed. In a previous test when I forced data[name] to be the id of the texture asset it did force the texture to load. Could be something related to this.