Transparency in multi material with sub-meshes

I have been trying all day today to get sub meshes to be transparent using a multi material.
This is the Playground I have been messing with https://playground.babylonjs.com/#6H9YT3#7.
It’s quite complicated, but essentially

  • My game is played on the surface of a planet.
  • The map is projected onto the surface of a sphere (the planet).
  • The map is divided into square tiles.
  • To begin with the player can only see terrain nearby, they have to explore to see the rest of the map.
  • There is a resource scanner that lets the player survey for hidden resources.

The way I implemented this was:

  • Build two ground meshes that are very close together, one for the terrain and the other to display the state of that map tile. I called these meshes ‘terrain’ and ‘utility’ in the PG.
  • Both meshes have one sub-mesh per map tile.
  • Both meshes have a multi material assigned so that the map tiles can be assigned any of the possible materials through the sub mesh material index.
  • Map tiles on the terrain mesh are initially set to the ‘unexplored’ material except for a small area near to the player. You can click on the ‘Explore’ button to set all of the map tiles into an explored state, in which case the sub meshes will be flipped to the relevant material index for the type of terrain.
  • Map tiles on the utility mesh are used to overlay a map tile status. Map tiles that are out of the players field of view should have a ‘fog’ material that greys out the map tile. Tiles that are within the field of view should not be obscured, i.e. the utility layer should be fully transparent.

The problem I need help with is making the utility layer map tiles fully or partially transparent. I have tried many things, including a diffuse texture with transparent pixels and setting the useAlphaFromDiffuseTexture property to true, disposing of the sub meshes and recreating them when necessary etc.

At this point I have run out of ideas. Is it actually possible to make a sub-mesh transparent or translucent whilst the other sub-meshes of the same mesh are opaque?

Sorry for the long explanation, but the PG is quite complicated.

Having some sub meshes transparent and others opaque do work, as this PG demonstrates:

https://playground.babylonjs.com/#2Q4S2S#453

You should try to make a smaller PG that shows the problem in a more obvious way, as it is difficult to understand what’s going on in your PG (there’s a 404 in the browser console, also the light is fading?).

Thanks. Having a working PG that shows this effect is really helpful.

The 404 is because there is no transparent image in PG textures, so I used a website that generated transparent images dynamically, but you have to visit the website one time to set a cookie before the image can be retrieved. The transparent bitmap shouldn’t be necessary anyhow, I was just trying every technique I could think of.

The fading light is the sun rotating around the planet creating daytime and nightime. This can be turned off by commenting out line scene.registerBeforeRender(beforeRender); in the addLights function.

Oh man, was that ever a long debug process.
I worked on it all day and finally found the answer.

When you create a mesh it automatically adds a sub-mesh that covers the whole surface of the mesh. If you don’t clear this out, then the whole mesh gets drawn twice, once with default material and then again for the sub-meshes you defined.

In my case, by transparent sub-meshes were being drawn transparently, revealing the mesh drawn with the default material.

The fix is to this line of code:
sphere.subMeshes = [];

This deletes the default sub-mesh and only draws the sub-meshes that you added.

2 Likes

For anyone following this thread, the final solution is to dispose the sub-meshes for the transparent areas - which is more efficient than drawing them with invisible material.

The version that does this is here https://playground.babylonjs.com/#6H9YT3#9

1 Like