Add texture/color to all meshes imported as glb file

I created a scene in blender with a lot of meshes to design a game level. I used synty meshes and did not apply any textures/colors to any of the meshes to keep the file size small. I imported both the glb file and the png texture pack into my game and am attempting to add the appropriate colors to my meshes, but this doesnt seem to be working. The game level (glb file) loads fine and I can run around in it, but its just the textures/colors that I cant seem to apply; my code looks like this:

async function loadGameLevel() {
  try {
    const scene = getScene();
    const result = await BABYLON.SceneLoader.ImportMeshAsync('', 'assets/3d/', 'battle-arena-stadium.glb', scene);
    const { meshes, particleSystems, skeletons, animationGroups, transformNodes } = result;

    const imagePath = `assets/images/dungeons-texture-03-a.png`; // synty texture
    const material = new BABYLON.StandardMaterial('material', scene);
    const texture = new BABYLON.Texture(imagePath, scene);
    // not sure which one of these i need, i just want the color to show up
    material.albedoTexture = texture;
    material.diffuseTexture = texture;
    material.specularTexture = texture;
    material.emissiveTexture = texture;
    material.ambientTexture = texture;
    meshes.forEach(i => i.material = material);
  } catch (e) {
    console.log('error', e);
  }
}

any tips on what i’m doing would be appreciated. again, the glb file is a set of meshes/objects that construct my game level (they’re all UV unwrapped by synty), and the texture is png image provided by synty that maps to the meshes. when i apply the image as a texture in blender the colors show up correctly, but exporting it with the textures makes the glb file really big so i’m doing them as separate exports.

the other thing is, i want to optimize the way these things happen like applying the same texture to all the meshes so i can get the flyweight (Flyweight · Design Patterns Revisited · Game Programming Patterns) with only sending the image over to the gpu once - i’m not an expert with these things so any tips are appreciated, especially if there’s a more appropriate way to do this (in other words, if babylon provides a built-in way to handle these optimizations)

This should probably work, but it is hard to say without seeing a live example. Would you be able to reproduce this on the playground?

I will try to produce something in a playground at some point today

taking a quick look at your link , they start by talking about GPU Instancing. This is not what you then later try to refer to as being achieved by sharing a texture/material.

Mesh objects that share a material can be optimized by batching. In Engines like Unity you get static batching and dynamic batching. Which is “batching” mesh objects that share a material to reduce CPU/GPU overhead. Im not sure if Babylon does this, anyway this is still not instancing. Instancing is only for identical mesh objects (geometry) and im not sure since i have not used it myself but i think it is not automatic , meaning you have to issue specific instructions to the GPU to do instancing, i might be wrong about that though, maybe babylon auto detects this :wink:

1 Like

@duxfox I did a quick example with your code and it works:
https://playground.babylonjs.com/#W9601M#7

I’ll improve it later

1 Like

So, after load the glb file, we can get meshes and the root mesh

const mesh = meshes[0];

Then we can get all childrenMeshes from this mesh and set material or color for each one.
A color is applied to each child mesh, except the t-shirt one wich receives a texture.

mesh.getChildMeshes().forEach((childMesh, index) => {
                console.log("childMesh.name:", childMesh.name);
                const material = new BABYLON.StandardMaterial('material', scene);
                // HVGirl_primitive3 == t-shirt
                if (childMesh.name == "HVGirl_primitive10") {
                    material.diffuseTexture = texture;
                } else {
                    material.diffuseColor = BABYLON.Color3.FromHexString(colors[index])
                }
                childMesh.material = material;
            });

https://playground.babylonjs.com/#W9601M#38

3 Likes