# Indexed BufferGeometry front and back side assignment - normals or order of indices?

**URL:** <https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380>\
**Category:** Questions\
**Tags:** buffergeometry, normals\
**Created:** [March 25, 2022, 3:25pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380 "2022-03-25T15:25:30Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![rvp](https://avatars.discourse-cdn.com/v4/letter/r/e19adc/32.png) [@rvp](https://discourse.threejs.org/u/rvp)\
**Post date:** [March 25, 2022, 3:25pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/1 "2022-03-25T15:25:30Z")

</div>

Hey guys,

I am trying to understand what controls which side of a BufferedGeometry polygon is visible and which isn’t (i.e. which side is considered ‘front’ and which one is ‘back’). Please consider the following simple indexed BufferGeometry that creates a simple square made of 2 triangles.

```javascript
        const geometry = new THREE.BufferGeometry();
        const vertices = [
            { pos: [-1, -1, 1], norm: [0, 0, 1], uv: [0, 0], },
            { pos: [1, -1, 1], norm: [0, 0, 1], uv: [1, 0], },
            { pos: [-1, 1, 1], norm: [0, 0, 1], uv: [0, 1], },
            { pos: [1, 1, 1], norm: [0, 0, 1], uv: [1, 1], },
        ];

        const positionNumComponents = 3;
        const normalNumComponents = 3;
        const uvNumComponents = 2;

        const positions = new Float32Array(vertices.length * positionNumComponents);
        const normals = new Float32Array(vertices.length * normalNumComponents);
        const uvs = new Float32Array(vertices.length * uvNumComponents);

        let posIdx = 0;
        let nrmIdx = 0;
        let uvIdx = 0;
        for (const vertex of vertices) {
            positions.set(vertex.pos, posIdx);
            normals.set(vertex.norm, nrmIdx);
            uvs.set(vertex.uv, uvIdx);
            posIdx += positionNumComponents;
            nrmIdx += normalNumComponents;
            uvIdx += uvNumComponents;
        }

        geometry.setAttribute('position', new THREE.BufferAttribute(positions, positionNumComponents));
        geometry.setAttribute('normal', new THREE.BufferAttribute(normals, normalNumComponents));
        geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, uvNumComponents));

        geometry.setIndex([
            0, 1, 2, // first triangle
            2, 1, 3 // second triangle
        ]);

```

Now, it was my understanding that the vertex normals are used to interpolate the face normals and those face normals are then used when drawing the polygons on screen to determine which side should be drawn. So I expected that if I flip the normals from (0,0,1) to (0.0,-1), the polygon would face the opposite direction and I will not see it (since I have the side set to THREE.FrontSide) . Turns out that is not the case and I can remove the normals attribute altogether without any visible effect or error.

Then I tried flipping the vertex indices and I realized that if I created the second triangle counter-clockwise like so

```javascript
        geometry.setIndex([
            0, 1, 2, // first triangle
            2, 3, 1 // instead of 2,1,3
        ]);

```

this will actually flip the face so that the camera would now be facing the back side of the second triangle.

Could someone please tell me if changing the vertex index order is what should be used to control which polygon side is “front” and which side is “back” or is there a different/recommended way to achieve this?

Thanks in advance for the help!

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [March 25, 2022, 4:07pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/2 "2022-03-25T16:07:50Z")

</div>

Front/back face culling is determined by the vertex order, yes. The normals come into play later when the triangle is shaded. There’s also `material.side` available.

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [March 25, 2022, 5:00pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/3 "2022-03-25T17:00:48Z")

</div>

In this example [CircleDynamicallyFormable](https://hofk.de/main/discourse.threejs/2021/CircleDynamicallyFormable/CircleDynamicallyFormable.html) ( from the [Collection of examples from discourse.threejs.org](https://discourse.threejs.org/t/collection-of-examples-from-discourse-threejs-org/4315) ) I had made a mistake, and since I had used side: THREE.DoubleSide, I had not noticed it. Since then I make sure to test only front and back. The note about the error is still in the code:

line 103

```javascript
    const setFace = ( ) => {
    
        faceIndices[idxCount] = a;
        //faceIndices[idxCount + 1] = b;
        //faceIndices[idxCount + 2] = c;
        faceIndices[idxCount + 1] = c; // swapped here c and b
        faceIndices[idxCount + 2] = b; // otherwise, the geometry is backsided
        idxCount += 3;
        
    }

```

You can test the wrong variant. 🙂

---

<div class="post-metadata">

**Author:** ![rvp](https://avatars.discourse-cdn.com/v4/letter/r/e19adc/32.png) [@rvp](https://discourse.threejs.org/u/rvp)\
**Post date:** [March 25, 2022, 5:05pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/4 "2022-03-25T17:05:48Z")

</div>

Thanks for the reply! And do you know what logic/math is used to determine why triangle with vertex indices [2,1,3] is facing towards the negative Z-axis and [2,3,1] is facing towards the positive Z-axis?

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [March 25, 2022, 5:14pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/5 "2022-03-25T17:14:31Z")

</div>

With 3D geometries, it’s all about the view of them. Let’s assume we have a cube. If I look at one side from the outside, the order of the indices must be counterclockwise. Then the front side is outward and the back side is inward.

**UPDATE:** Take a look at these simple examples.

[BufferGeometryNormals](https://hofk.de/main/discourse.threejs/2020/BufferGeometryNormals/BufferGeometryNormals.html)

[BufferGeometryIndexed](https://hofk.de/main/discourse.threejs/2022/BufferGeometry/BufferGeometryIndexed.html)

---

<div class="post-metadata">

**Author:** ![rvp](https://avatars.discourse-cdn.com/v4/letter/r/e19adc/32.png) [@rvp](https://discourse.threejs.org/u/rvp)\
**Post date:** [March 25, 2022, 5:20pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/6 "2022-03-25T17:20:43Z")

</div>

Thanks for your replies as well! In this case I have a custom BufferGeometry which happens to be a single square plane that is made up of 2 triangles which looks like this:

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/6/4/6444ca2a14a64bf204afe5ffd0e3c384cda598ce.png)

but if I change the indices order of the second triangle from `2, 1, 3` to `2, 3, 1` and that change will flip the face direction so one half of the square looks toward the camera and the other half looks in the opposite direction

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/8/7/873540fa4871e5925ebd273a3badceb0a6d44840.png)

So my question is if anybody knows what is the math/logic that decides that this particular order should flip the face direction.

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [March 25, 2022, 5:38pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/7 "2022-03-25T17:38:00Z")

</div>

Front-faces have counter-clockwise winding order. If you’re looking at the triangle from the side where `2, 1, 3` are in CCW order, you are viewing from the front. You could also calculate that direction using [Triangle.getNormal](https://threejs.org/docs/?q=triangl#api/en/math/Triangle.getNormal).

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [March 25, 2022, 5:41pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/8 "2022-03-25T17:41:54Z")

</div>

See update previous post. Simple examples.

Here you can see the numbering of the official geometries.  
[NumberingHelperExamples](https://hofk.de/main/discourse.threejs/2022/THREEn/NumberingHelperExamples.html)

The official source code PlaneGeometry about it [three.js/PlaneGeometry.js at 8921bfaee413e809cb2d27f0aec917408d690a0f · mrdoob/three.js · GitHub](https://github.com/mrdoob/three.js/blob/8921bfaee413e809cb2d27f0aec917408d690a0f/src/geometries/PlaneGeometry.js)

Excerpt

```
	for ( let iy = 0; iy < gridY; iy ++ ) {

		for ( let ix = 0; ix < gridX; ix ++ ) {

			const a = ix + gridX1 * iy;
			const b = ix + gridX1 * ( iy + 1 );
			const c = ( ix + 1 ) + gridX1 * ( iy + 1 );
			const d = ( ix + 1 ) + gridX1 * iy;

			indices.push( a, b, d );
			indices.push( b, c, d );

		}

	}
```

---

<div class="post-metadata">

**Author:** ![rrrr\_rrrr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/rrrr_rrrr/32/7697_2.png) [@rrrr\_rrrr](https://discourse.threejs.org/u/rrrr_rrrr)\
**Post date:** [March 25, 2022, 9:16pm UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/9 "2022-03-25T21:16:47Z")

</div>

> [@rvp](#):
>
> Could someone please tell me if changing the vertex index order is what should be used to control which polygon side is “front” and which side is “back” or is there a different/recommended way to achieve this?

Which way the polygon is facing has nothing to do with vertex index order.

It’s all about vertex relative position and the winding direction [CCW is positive].

WebGL uses xyz, right hand rule.  
X runs from left to right.  
Y runs from bottom to top.  
Z runs from far to near.

---

<div class="post-metadata">

**Author:** ![rvp](https://avatars.discourse-cdn.com/v4/letter/r/e19adc/32.png) [@rvp](https://discourse.threejs.org/u/rvp)\
**Post date:** [March 28, 2022, 9:13am UTC](https://discourse.threejs.org/t/indexed-buffergeometry-front-and-back-side-assignment-normals-or-order-of-indices/36380/10 "2022-03-28T09:13:22Z")

</div>

Thanks for the help guys!
