Depth-based blending

I really think there should be blend factors using z-buffer values.

A simple example of how this could be used is with convex fog or translucent volumes. If we draw the backfacing polygons of a convex translucent volume first (for depth buffer values only) we can then draw the front polygons using the z-buffer difference as a factor for transparency.
The result could be an object that is more opaque where thicker and viceversa. You get the idea, right?

This could also work for drawing murky water as surfaces in concavities or containers, atmospheres around planets, etc. and shouldn’t be demanding.

I have not thought of more complex situations but the technique could probably have more potential or uses…

Does this sound reasonable? Am I overseeing some technical difficulty performance-wise?

This is an absolute corker of an idea - I’d love to see it implemented.

The only complication I can see is that Z-buffer values aren’t linear; they’re more like logarithmic. So you couldn’t just use the difference as a blend factor. Still, correcting for this shouldn’t be beyond the wit of mortal man.

I’m wondering whether you could achieve something like this effect by writing pseudo-Z values into framebuffer alpha (using eye-coord texgen to get alpha values from a graduated 1D alpha texture), then using a blend function with DST_ALPHA. Even if you could get this to work, though, it would mean an extra pass and you’d probably only have 8 bits of alpha precision vs 24 bits of Z, so it wouldn’t really be a substitute.

I did a (very basic) GLUT demo of this a short while ago. I don’t have a website to upload it to but I don’t mind mailing it to anyone who’s interested (mail me at It uses BSP trees to do the sorting so it can handle arbitrary (closed) fog-volumes, but is extremely glitchy and the code is ugly. It requires EXT_blend_subtract, which means TNTs and Voodoos are out.

As a side-note, a massively improved and sort-independant version of this would be possible if we could to unsaturated blending maths on the alpha-buffer: Using texture-wrapping, you could use alpha to represent the bottom 8-bits of Z so intermediate results could go out-of-range so long as the final result was back within the valid range.
Is anyone else interested in the possibilities of doing true signed maths on the framebuffer?

Mike F

Originally posted by Mike F:
Is anyone else interested in the possibilities of doing true signed maths on the framebuffer?

Mike F[/b]

Yes, John Carmack posted a long .plan on 2000-04-29 arguing the need for 64-bpp (16-bit float per component) throughout the pipeline. So you’re in good company :slight_smile: