Merged geometry + shared material - individual face opacity?


I have a merged geometry (2000 faces) that’s using 15 texture atlases for face textures, is there anyway to selectively control opacity (i.e. tween) an individual faces’ texture ‘tile’? The materialindex would only retrieve the current shared texture which would’nt work as it would affect all faces using that material.


What type of geometry? Geometry or BufferGeometry.

the merged geometry is bufferGeometry,
i saw that the default materialIndex of a face (0) could be used to turn a specific face invisible (setting to materialIndex(1), but this wont work as a tween which is something I need

here’s a youtube video of the effect before I implemented the texture atlases, when each plane had its own material/texture that i could target and tween via materialIndex.

I wrote an example where you can operate with opacity for individual part in a merged buffer geometry:

Click an individual plane and see how the other planes’ opacity fades out and in.


Amazing, thank you so much for this.

I’m still green around shader code, so my understanding:

  1. the merged geometry gets the planeIndices as an attribute
  2. the vertex shader has this available and sets it as a varying variable vPlaneIndex to pass to the fragment shader
  3. The fragment shader has access to the currentIndex and for each pixels’ vPlaneIndex checks it against the currentIndex, forcing opacity to stay at 1 instead of the material’s opacity value.

I assume the floors in:
gl_FragColor.a = floor(currentIndex + 0.01) == floor(vPlaneIndex + 0.01) ? 1. : gl_FragColor.a;

Are needed to ensure the value remains a float, recently read that but took a minute to recall :slight_smile:

Will implement this as soon as I can, I assume the material using a compressed .basis texturemap will cause no problems?

Huge thanks again.

Finally implemented this, thanks again @prisoner849

I added bufferGeometry groups as I had several atlases, nicely lowers drawcalls/texture swapping for another big bump in fps.

What threw me for a long time was the vertex counting when creating groups needs to be 6 instead of 4 for a plane, of course as 3 vertices per face.

  let startCounter = 0;
  let verticesCounter = 0;
  let materialCounter = 0; => {
    if (marker.materialIndex !== materialCounter) {
        verticesCounter - startCounter,
      materialCounter = marker.materialIndex;
      startCounter = verticesCounter;
    verticesCounter = verticesCounter + 6; //Each vertex needs to appear once per face
  finalGeometry.addGroup(startCounter, verticesCounter, materialCounter);

What I’m still trying to picture is how the 6x vertex geometry associates to the 4x attribute arrays your example showed me -
is it simply threeJS ‘recognizing’ the 2 ‘duplicate’ vertex references per plane and just matching them to the 4 x UV and planeIndex attributes via unique vertex index? Or is there another property in the geometry keeping track of this that I missed?


thanks for this example. amazing