OpenGL dumb mistakes: the mysterious Perfect Circular Hole

I’ve got a long-running project around rendering 3D Earth in interesting ways. It’s being used in a game project, and some non-game stuff too. Here’s a recent screenshot:

I added a particle system that uses Vector Fields to move the particles based on arbitrary incoming data, and then wraps it round a globe. Yay!:

(click image for larger version)

…and then I increased the size of each particle, and something very strange happened. I wanted to splurge them out to be huge, but

The mysterious Holes Of Doom

… these weird holes appeared in the middle:

(click image for larger version)

WTF? I must have done something stupid. I double checked everything. I removed the textures. I switched from quads to basic tris, with vertex colours … but still, this perfect circle cut out of the center! My vertex and fragment shaders by this point were exactly one line of code!

(click image for larger version)

…I spent ages looking at this, trying to understand what could possibly create “holes” in my geometry. They were obviously holes – you can see through them!

Eventually, tired, and with lots of more important work to do, I gave up, shelved it, went off to do other things. Then today I suddenly realised the problem. I’m sure it’s obvious to most of you, but it’s taken me ages to figure it out.

When a hole is not a hole

And this is what makes it worth posting: the hole is not a hole.

My particles are on a 2D plane, so that I can calculate simple x/y coords from a vector-field. Great. My shader wraps the corners to a sphere. I’m rendering quads / tris like this:

Great. But GL doesn’t “bend” the edges – it draws straight lines between corners. So … when I made my tris larger … the corners were still slightly above the surface of the globe.

…and the EDGES were still slightly above

…but the centers … slightly interesected the globe. And so, of course, the depth-test cut them out. In the diagram below, it looks as if the quad moved closer to the center of the globe – but it hasn’t. The corners are all still the same height above the surface – only the middle has (implicitly) gone “inwards”.

Lesson to self: sometimes, it’s not a triangle-with-a-hole-that-I-can-see-through … instead, it’s a triangle-that-has-a-sphere-poking-through-the-middle