Am Dienstag, 10. August 2021, 17:18:31 EAT schrieb Henri Verbeet:
- We translate by ε to the left, so that a triangle covering the
right half of a pixel from top to bottom exactly through the pixel centre ends up generating a fragment for that pixel, and a triangle covering the left half of that pixel doesn't.
Because we don't know what OpenGL is doing, i.e. it might generate a fragment if the pixel center is on a right edge of a triangle, either due to underspecification or driver bugs?
I was under the impression that GL guarantees a top-left filling rule (pixel is on a top edge OR on a left edge of a triangle -> generate fragment), but on further research the only place that states that (that I could find) is https://docs.microsoft.com/th-th/windows/win32/direct3d9/rasterization-rules , which isn't exactly an authoritative source on GL.
The rest of your explanation makes perfect sense to me.
The attached filling.c file is an attempt at detecting what the GL implementation does when rendering into an FBO. It correctly picks up the difference of the radeon driver on MacOS (radeon.png) - the only driver that doesn't pass the d3d9 viewport test with a precise 0.5 pixel shift. Other cards I tested result in the same output (intel.png, linux-noflip.png).
Sadly, while it does match up with with the d3d9 test, it doesn't match up with SPORE nor World of Tanks. World of Tanks wants no nudge everywhere, even the radeon card. SPORE is broken on MacOS regardless of what I try to do, but works on Linux-Radeon either with or without the nudge. I can deliberately break it everywhere by removing the half pixel offset, but that doesn't tell us anything we didn't already know.
So something else must be going on. My suspicions are that it has something to do with shaders vs fixed function or core vs legacy context. It is also possible that the issue is entirely unrelated, at least in World of Tanks.
The filling.c program also shows one place where the x nudge makes a difference when inverting the geometry: It flips the diagonal pixels back to the red triangle. The y nudge is (understandably) necessary to place the quad correctly nearer to the top of the texture rather than the bottom. I haven't yet found a card that generates a fragment when the center is on the right triangle edge.