Yeah you use a single z value for each triangle, which means that large triangles on glancing angles don't act as effective occluders.
How you are sorting triangles? How about intersections? Or do sort by using max z and raster whole triangle with that? Sound great technique but I want to hear more details.
To ensure conservative results (no false occlusion), you use the maximum z value for occluder triangles and the minimum z value for occludee triangles, which allows intersecting triangles to work without errors.
First you project all the triangles into screen space, determine their z values as above, bucket them into the "tiles", then sort the triangle lists in each tile according to their z value. And then rasterize the tiles
When rasterizing a triangle, you iterate through the scanlines generating a bitmask of the pixels covered by the triangle on that line. Occluders then simply OR this mask with the framebuffer. Occludees AND this mask with "NOT framebuffer" and if the result is true, they write a non-zero value into some address indicating this object is visible (when submitting a group of occludee triangles, you also pass an int*, etc, where this value will be written to if the object is visible. The int at this address is initialized to zero beforehand).
P.S. I didn't come up with this, I've shamelessly taken the idea from Vadim Shcherbakov, who got it from another guy, IronPeter. There's a full explanation and a demo with source code on his blog. His code uses SSE intrinsics so it's a bit unreadable in places, and it contains a few bugs, but it's very fast Eventually, I'd like to release my own open source version of this algorithm, but I've got other things to be working on at the moment.
P.P.S. I contacted Vadim about the copyright on his demo, because there is no explicit licensed contained in the ZIP, and got this response:
On 05/10/13 8:11 AM, Vadim Shcherbakov wrote:
Hey, you can use the code as you like, there is no license or any limitations.