# Flat shading for non-planar polygons

I'm trying to figure out how to properly implement flat shading for meshes containing non-planar polygons (using OpenGL/GLSL). The aim is to obtain something similar to the result Blender gives (all polygons below are non-planar):

To provide a bit of context — the non-planar polygons (e.g. quads, pentagons, ...) are either present in the mesh I load or appear as a result of applying a subdivision scheme (such as Catmull-Clark) to the mesh.

In case of a triangle mesh, I'm aware of the following approaches to implement flat shading —

1. Compute the cross product of dFdx and dFdy in the fragment shader
2. Use the geometry shader to compute the triangle normal by taking the cross product of two sides of the triangle
3. When using glDrawElements, use the flat interpolation qualifier (which basically uses the normal associated with the provoking vertex for all fragments)
4. When using glDrawArrays, most vertices (usually all of them) are copied to the GPU multiple times. Therefore, a different normal can be used each time

For a mesh containing non-planar polygons the first three options don't yield the result I'm after. In my implementation (using the Qt framework) I use GL_TRIANGLE_FAN:

The fourth option could work, but isn't very elegant — I'd like to use either glDrawElements or glDrawMultiElements. One other option would be to use glDrawElements while looping over the faces one by one (instead of invoking it once using glPrimitiveRestartIndex). In that case, one could upload a uniform normal for each face. However, this does not seem very efficient. Any other ideas?

• Interesting question. If there is a specific reason that you don't want a shape with planar quads, like a rhombic dodecahedron, mentioning that reason and explaining your motivation for using non-planar quads might help give insight into what is required. – trichoplax Jan 10 '16 at 16:12
• @trichoplax Ok, updated the question :). – Ailurus Jan 10 '16 at 17:57
• You could also specify a normal for each vertex as an attribute, not a uniform, and render the mesh all in one call. – Jackalope May 11 '17 at 4:49