Controlling which side of a custom face geometry gets rendered? Normals?

I am trying to do some procedural mesh generation.

I note that if I go:

        const geometry = new BufferGeometry();
const positionNumComponents = 3;
        const normalNumComponents = 3;
 let positions =  [
            2.7, 1.5,  0, // v0
            2.7, -1.5,  0, // v1
             1,  1,  0, // v2
        let normals = [
geometry.setAttribute('position', new BufferAttribute(new Float32Array(positions), positionNumComponents));
        geometry.setAttribute('normal',new BufferAttribute(new Float32Array(normals), normalNumComponents));
let material = new THREE.MeshPhongMaterial();
	material.color.setRGB(1, 1, 1);
	let mesh = new THREE.Mesh( geometry, material );
	scene.add( mesh );
  1. The order of the vertices in position changes which side gets rendered. Ie. If I switch position of V0 and V1 one side or other gets the material.

  2. I would think setting normals in either direction would override this but it doesn’t. Ie. whether I set normals to (0,0,1) or (0,0,-1) it makes no difference.

Is this typical behavior? Isn’t the idea of normals to set which side of the face gets rendered? Or how do you set that?

Is side rendered only determined by order of vertex adding? Is there any explanation for how this works in general? Ie. does clockwise render forward vs. backwards, etc. Is this something we must be mindful of then?

Related, how I do render both sides if wanted (although that is more expensive I know)? Or can I set front to render or back to render (if there is a toggle for this)?


The winding order determines which side is considered the front. The material.side property determines which side(s) are drawn, relative to that definition of “front.” Vertex normals are used by three.js in the shaders, e.g. for lighting, but the WebGL API is not aware of vertex normals and does not use them when deciding which triangles to render or cull.