Same specular lighting on both tris in a quad (for "low-poly" "flat shading" look)? Here's an example of the flat shaded squares I want. But my squares are made of two triangles, and I'm getting flat shading of those triangles.



In openGLES 3.1 (android), I'm turning off interpolation in the fragment shader, and using the provoking vertex (or using the centroid/average), to get the same "low-poly" lighting throughout a tri. The specular calculation is done in the vertex shader, so it's only done once.

I have a flat sea, a mesh of squares (two triangles per quad), with a specular reflection of the sun. But instead of each square being lit the same, the two triangles forming a square get different specular values.

I worked out it's because the tris are at different locations. Although the sun's rays are parallel (with the same angle of incidence at all locations), the angle between each tri and the viewer is slightly different, depending on where the tri is relative to the viewer.




  This diagram (Intro to Computer Graphics, David J. Eck) only shows the light from one point, for observers at different locations, but you can see that light from different points would produce a shifted cone, having a similar effect on an observer at one place.


A brute force solution would be to store a special "location" for each vertex of each tri, and set "location" to the same value for each of the 4 verices of the two tris forming the square.

But that's inefficient, and I'm using a STRIP for the mesh. I don't think this brute force solution work, because any per vertex data would be used by the 4 squares sharing that vertex, wouldn't they? Or can you have per tri data?


  EDIT I currently have per vertex normals - used in the specular calc - and only the normal of the provoking vertex is used for a tri. This works out as per tri, since only one tri is provoked by each vertex. I could give the same "location" to both tris in a quad this way. But it's still brute force - is there a better way?


Or, can you tell which tri of a quad you're in, so you can decide what it's "location" should be?

It seems so simple, but doesn't fit with openGL ES's approach... is there a way to do it? Note it's openGL ES 3.1 (mobile).
If I understand you correctly, the problem is that the provoking vertex isn't the same vertex between the two triangles in a quad, due to using triangle strips. You could switch to using an indexed triangle list, and set up indices in such a way that the provoking vertex is the same in each quad. For instance, if one quad is vertices {0, 1, 2, 3} (CCW) then you might write {0, 1, 2, 3, 0, 2} in your index buffer so that 2 is the provoking vertex for both triangles. This should still be pretty efficient.

Another possibility (more involved, but more flexible) is to use the built-in gl_VertexID variable in your vertex shader to figure out which quad you're in (eg int quadID = gl_VertexID / 4), and use an appropriate shading location for that quad—the centroid of its vertices, for instance. However, for this to work, I think you would have to "un-share" the vertices so that each quad has its own 4 unique vertices (the two triangles in a quad can still share). So you would have to use primitive restarting, or again switch to indexed non-strip draws. You could also have per-quad data in an SSBO that you manually fetch using your computed quad index.