ExtudeBufferGeometry back material

I’m currently studying how to use BufferGeometry and I now understand how the attributes work. Now, I’m trying to create a mesh with ExtrudeBufferGeometry and I noticed that the geometry has a “groups” property. I’ve noticed that there are two groups which correponds to the front face and the wide faces. Also each group has their own materialIndex. My problem is with the back face. Is there a way to assign a different materialIndex for the back face of and extruded BufferGeometry?

That’s not entirely correct. One group represents the side faces, the second group represents the lid faces (top and bottom). Groups are used in order to apply multiple materials to a single instance of BufferGeometry (hence the materialIndex).

No that’s not possible. One way to solve this problem is to render two meshes. The first “outer” mesh uses a material with Material.side set to THREE.FrontSide (default). The second “inner” mesh uses a material with Material.side set to BackSide.

Thanks for the response but I was able to find the solution for my own problem.

I’ve found out about this yesterday while checking the buffergeometry object. One group does not only contain the front faces but also the back ones.

I disagree with the “not possible” part. Because of my findings regarding the vertex grouping, I was able to loop through the group and divide them into two groups which represents the front faces and front faces. I then assigned different materialIndex for each group. I used the vertex normals to determine which of the vertices are part of the front faces and which ones are in the back faces

Here’s my code

            mesh.geometry.clearGroups();

            var group_count = [0,0,0];
            var group_start = [null, null, null];
            for (var i = 1; i <= mesh.geometry.attributes.normal.count; i++) {
                var index = 2 + ((3*i) - 3);
                var v_index = i - 1;
                var z = mesh.geometry.attributes.normal.array[index];

                switch(z) {
                    case 1: group_count[0]++;
                            group_start[0] = group_start[0] == null ? v_index: group_start[0];
                            break; //Front
                    case 0: group_count[1]++;
                            group_start[1] = group_start[1] == null ? v_index: group_start[1];
                            break; //Side
                    case -1: group_count[2]++;
                            group_start[2] = group_start[2] == null ? v_index: group_start[2];
                            break; //Back
                
                }
            }

            mesh.geometry.addGroup(group_start[0], group_count[0], 2);
            mesh.geometry.addGroup(group_start[1], group_count[1], 1);
            mesh.geometry.addGroup(group_start[2], group_count[2], 0);

Thanks for the suggestion though. I might be able to use it for a different scenario

1 Like

Sry, but it seems you misunderstand the concepts of front and back faces. In the following demo, ExtrudeBufferGeometry is rendered without the lid faces (so you can now see “into” the generated geometry). You will notice that it’s not possible to see the side face from the back. Why? Because the respective material has set Material.side to THREE.FrontSide (the default).

https://jsfiddle.net/xefg7r6d/

If you change it to THREE.DoubleSide, front and back faces are rendered but with the same material.

https://jsfiddle.net/xefg7r6d/1/

You can only render the back faces with a different material if you duplicate the mesh, choose the new material and set side to THREE.BackSide.

2 Likes

I created an account so I can say “Thank you sir!”
This just worked! amazing!