fill cost of a triangle with zero alpha at all corners

if the alpha of the 3 vertices of a triangle is 0, and alpha test is enabled, will I pay a significant fill rate penalty for drawing it if the triangle is huge in screen space? Or will the hardware disregard the triangle (what I want it to do) before trying to rasterize it?

Such a case would be rare, so it would be a waste to spend time/silicon checking for it.
Plus, a fragment program won’t necessarily pay any attention to the alpha value, so such a check could incorrectly discard triangles.
So my guess is that the triangle will be rasterized.

not the answer I wanted to hear.
I don’t agree though, alpha test is often talked about as an optimisation to save fill rate…trees and such.
It wouldn’t look out of place in the early z reject bit of the hardware, I would have thought.

True, if it’s possible to determine if a shader modifies z, it should also be possible to determine if it modifies alpha or simply forwards it from the varyings to the output.

This would lead to some sort of “early alpha test”, similar to the early z test, that is, reject fragments before executing the shader. From there it should be easy to further optimize away whole triangles before rasterization.

Sounds easy enough. Now that I think about it, wouldn’t it be possible to implement this in a geometry shader?

Yes, it can be done in the geometry shader.

Originally posted by knackered:
I don’t agree though, alpha test is often talked about as an optimisation to save fill rate…trees and such.
It is? Alpha test might save framebuffer bandwidth but not fill rate, since it happens at the end of the fragment pipeline. Interpolated vertex alpha is rarely used for alpha test, so no one optimizes for it.

pants down, knackered- why do you want to draw a large invisible triangle? did the voices in your head tell you to do so?

Originally posted by knackered:
alpha test is often talked about as an optimisation to save fill rate…trees and such.
Not by IHVs though. For the last few generations alpha test has been more of a performance killer than an optimization.

Originally posted by knackered:
It wouldn’t look out of place in the early z reject bit of the hardware, I would have thought.
Early-Z doesn’t like alpha test because it can kill pixels, while Early-Z is a monolithic operation, thus is Early-Z would be left enable with alpha test on depth and stencil could be incorrectly updated for killed pixels. You still get the large scale culling of Hierarchical-Z if alpha test is enabled, but you don’t get the fine-grained culling from Early-Z.

Originally posted by Overmind:
True, if it’s possible to determine if a shader modifies z, it should also be possible to determine if it modifies alpha or simply forwards it from the varyings to the output.
There’s no such thing as “modify alpha” since there’s no default alpha that could possibly be left untouched, unlike depth that has a default value from the rasterizer that’s used unless the shader writes to gl_FragDepth. Checking whether a shader potentially modifies depth is trivial, just check if any writes to gl_FragDepth is present in the shader. Checking for alpha would be much more complex since you’d have the track the source of the alpha value written and then track that back up to the vertex shader too. Not impossible of course, but that combined with extra hardware neccesary to optimize this case, and that this is hardly something that would benefit many applications, makes it a not too interesting optimization to implement.

Originally posted by RigidBody:
pants down, knackered- why do you want to draw a large invisible triangle? did the voices in your head tell you to do so?
Ok body…
I have a regular grid of indexed triangles that I’m toroidally updating, the bottom and right edges of which join to the top and left edges. I use the vertex shader to offset each vertex and modulate with the grid size, so as a vertex is offset off one edge it gets modulated to the other edge. I detect in the vertex shader if the vertex is at any of the edges (using some min/max jiggery pokery - no conditionals), and set the outgoing alpha to 0 if it is on the edge. This ensures that any triangles that incorrectly span the whole grid have alpha set to zero at all 3 vertices. I’m not fill-rate bound at the moment, so I can’t really tell if this is hurting me…but if what you lads are saying is correct, it is going to hurt bad.

User clip sound like it’d work better.

I really wish GLSL had defined clip distances instead of a clip vertex. Clip distances are much more flexible, and the way D3D hardware is required to operate anyway.

Does what you are doing require a z buffer?

Originally posted by cass:
User clip sound like it’d work better.
Try as I might, I can’t see how clipping planes will help here, cass.

Does what you are doing require a z buffer?
Yep, most definitely. Why?

what about simple culling? you could specify the vertices in a way so that all trias have the same winding order. the winding order of one particular tria will be inverted if one of its vertices moves across the edge.

If instead of making the alpha of the vertex 0, you made its clip distance 0 (or -epsilon), it would clip the whole triangle before shading when all the vertices were 0 (or -epsilon).

thanks for clarifying that cass…I’ll look into your suggestion (what hardware it would require etc.)

rigidbody, I really liked the backface culling idea you’ve suggested, but it’s possible the viewpoint could be under the span of the wrapping triangles (eg. in a deep valley), and therefore they would still be visible some times. I got all excited then until I thought it through.

By the way, the very simple vertex shader I described works a treat - so I think I’ll probably end up sticking with it and take the fill rate hit…whatever it ends up costing.