DOUBLESIDE vs. backFaceCulling

I want to confirm my understanding of sideOrientation and backFaceCulling.

Both control if a mesh appears one-sided or two-sided, in different ways.

The geometry builders have the sideOrientation option. They use this function:

It will duplicate vertices and triangles for the DOUBLESIDE case to physically generate two sides.

This means that even with backFaceCulling on both sides will be rendered in this case.

With backFaceCulling off the FRONTSIDE case will also lead to rendering of both sides. But here it may instead be the result from the shader now ignoring the normal direction.

backFaceCulling off and DOUBLESIDE may actually render each side twice.

Is that about right ?

Finally, the material.sideOrientation property is about which side is considered FRONT or BACK. It has the same name but is really about something else though related.

For the geometry builder:

  • BACKSIDE is inverting the winding (and also the normals, to match the new winding). That means a face that was a front face is now a back face and a face that was a back face is now a front face
  • DOUBLESIDE is duplicating data so that each front face has now a corresponding back face (that is, a face with the same vertex positions but with inverted winding) and each back face has now a corresponding front face

Note that a front face is a face whose indices are given in a counter clock wise order.

If you set backFaceCulling to false it means the back faces are not culled anymore and are displayed instead: all faces are displayed (front+back). For the DOUBLESIDE case, as we created a duplicate of each face, it does mean we are rendering twice the number of faces. But there’s no point to using backFaceCulling = false in the DOUBLESIDE case.

The sideOrientation property of the material indicates to the engine which winding is considered to be a front face. By default it is a counter clock wise order which defines a front face.

Note that you also have the Material.cullBackFaces property (new in 5.0) which indicates which type of face must be culled: if true back faces are culled, else front faces are culled. You still need to set backFaceCulling=true for culling to take place (with the new cullBackFaces property, backFaceCulling would be better renamed culling but we can’t do a breaking change).


Thanks for the detailed explanation of the different options and how they interact. I think it confirms what my understanding was. The team may consider adding much of this verbiage to the technical documentation, perhaps as API comments ? There are probably higher priorities.

One simple takeaway is that it does not make sense to use DOUBLESIDE with backFaceCulling off which may not be obvious to some.

For my own benefit let me also note that FRONTSIDE with backFaceCulling off means that the back side is rendered the same as the front side in the current lighting conditions, eg. with normals facing backwards. This is probably rarely the desired effect. For example, a head lamp, eg. a forward shining directional light attached to the camera, results in the back side being black when looking at it.

1 Like