Assigning new materials with a textureAsset to multiple meshinstances fails

I have an entity with two meshInstances. I create a new material and assign a texture to that material and apply that material to both meshinstances in the same frame. This fails sometimes, not every time, causing the FIRST of the two meshinstances to have no material / the default material WITHOUT the texture.

If I assign the textureasset to each mesinstance in SEPARATE FRAMES, e.g. I wait any amount of time before assigning the second one, this issue is solved and that is my current workaround.

Question: Why would creating a new material, assigning a textureasset, then applying that material to one meshinstance cause this issue, when waiting and applying them in two separate frames resolves it?

I recorded a 5 minute thorough walkthrough to illustrate this issue: https://youtu.be/W_iQCoJwXpo

Here is my code:

function ApplyTextureAssetToMeshInstance(options){
    const {meshInstance, textureAsset} = options;
    const material = new pc.StandardMaterial();

    material.diffuseMap = textureAsset.resource;
    material.opacityMap = textureAsset.resource; // Set opacity map to the same texture
    material.blendType = pc.BLEND_NORMAL; //pc.BLEND_ADDITIVE_ALPHA;// BLEND_NORMAL; 
    meshInstance.material = material; 
    material.update();
    return material;
}

Here is me calling the function.

// FAILS: causes meshInstances[0] to have a default material
ApplyTextureAssetToMeshInstance({ 
    meshInstance:hoop.children[0].render.meshInstances[0],
    textureAsset:assets.textures.hoop
});
ApplyTextureAssetToMeshInstance({ 
    meshInstance:hoop.children[0].render.meshInstances[1],
    textureAsset:assets.textures.hoop
});

and

// WORKS:
ApplyTextureAssetToMeshInstance({ 
    meshInstance:hoop.children[0].render.meshInstances[0],
    textureAsset:assets.textures.hoop
});
setTimeout(function(){ ApplyTextureAssetToMeshInstance({ 
    meshInstance:hoop.children[0].render.meshInstances[1],
    textureAsset:assets.textures.hoop
});}, 100);

Thanks for any insight! :pray:

If you are using batching, then the batch group is not updated after the texture is fetched from server and loaded. You’d need to manually reset the batch group. If you don’t use batching, then your issue has to do with the texture being not yet available at the time it was needed. You can change your logic to do what you need to do with it on your texture asset load callback. Or mark it to be preloaded in Editor.

3 Likes

This makes sense! Thanks for the clear reply. We aren’t using batching yet, at least I have not configured anything, so I’m not sure about batching. The texture is definitely loaded already, since I’m creating these at runtime. (Or do I need to wait for an additional “load” of the texture once I’m calling on the same resource?) Will have to point my dev team back to this post when we look into batching and correct texture/material instantiation for the game :slightly_smiling_face:

There is no additional “load”. If you are creating the texture at runtime, then it is available and something else is not. Perhaps, the material or mesh? If those are ok too, then your code snippet is not enough and a simple repro project would help identifying the cause.