[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] determining depth of z-buffer



I've used the two-pass trick and I like it.  In practice I found that
I had to leave like 10% overlap in z to avoid the possibility of a
visible crack, but this was around 10 years ago; maybe GPUs don't need
so much margin anymore.

Note that the ideal zmid value is NOT halfway between znear and zfar;
instead you want znear/zmid == zmid/zfar, so zmid = sqrt(znear*zfar)

For the case where you have distinct bands, Steve's scaling trick is
clever.  I suspect you can also get the same effect by playing with
the projection matrix.  And, there is gl.depthRange to kind of do the
same thing.  I've never used it but I think it's equivalent to playing
with the projection matrix.  The big drawback of course is it doesn't
help if your data is continuous throughout the z range.

I revisited this problem in Jan 2010, and the crazy thing is, there is
a simple hardware solution!  If, instead of writing a value based on z
or 1/z into the depth buffer, the hardware wrote:

  log(view_z / z_near) / log(z_far / z_near)

you would get constant relative precision throughout the z range, and
16-bit z-buffers would be more or less adequate for planetary scale
rendering!  24 bits would be enough for pretty much any imaginable
purpose!

I did some experiments at the time using WebGL and the gl_FragDepth
feature, and it appears to work great in practice.  However,
gl_FragDepth didn't work at all on one of my machines, and apparently
it is no longer valid in WebGL.  The other problem is that if you used
it, the driver would need to disable any hardware hierarchical z,
which would be bad for performance.

I went looking for corroboration of my results and discovered that
Brano Kemen had recently written a couple of great blog posts on
Gamasutra exploring the same phenomenon:
http://www.gamasutra.com/blogs/BranoKemen/20090812/2725/Logarithmic_Depth_Buffer.php
http://www.gamasutra.com/blogs/BranoKemen/20091231/3972/Floating_Point_Depth_Buffers.php

His conclusion is that you can get the positive effects of a log depth
buffer by using a floating-point depth buffer, and running the values
backwards (1 == near, 0 == far).

I wonder why log depth buffer wasn't written into the original OpenGL
spec?  Did nobody discover it before Brano Kemen in 2009?  Or was it
just too expensive to have to do a log() on every pixel?

-T

On Feb 2, 2011 11:03 PM, "Giles Thomas" <giles.thomas@gmail.com> wrote:
> You may already be familiar with this trick, but just in case: if you're
> finding that the depth buffer's not deep enough to handle your scene's level
> of detail (say, skybox/sphere 10,000,000,000 units away, Sun 100,000,000
> units away, planet 90,000 units away and spaceship 0.1 units away), you can
> avoid having to worry at least about the distance of the sky by drawing it
> at -- say -- half the far clipping distance and then clearing the depth
> buffer so that whatever you draw next will wind up on top of it, using
> gl.clear(gl.DEPTH_BUFFER_BIT); I did something like this in my
> (long-unupdated) <http://learningwebgl.com/spacelike/>
>
> In general, I think (experts please correct me if I'm wrong here!) that if
> you have various objects at very distinct bands of distances, where no
> object intersects two bands, you can draw each band, most distant band
> first, closest last, using a different projection matrix each time -- same
> fov and aspect, but appropriately-adjusted near and far clipping distances
> -- thus being able to get maximum use of the depth buffer's precision each
> time. You just need to clear the depth buffer after each band, so that each
> closer level is always drawn on top of the previous one.
>
> This is something I've inferred from lots of reading rather than read
> specifically, however, so it could absolutely standard practice, with a
> well-known name that I just don't know, or it could be utter nonsense. Or
> possibly some combination of the two.
>
>
> Cheers,
>
> Giles
>
>
>
>
>
>
> On 2 February 2011 21:22, <steve@sjbaker.org> wrote:
>
>>
>> In practical terms, you'll almost always find 24 bit Z on the desktop and
>> 16 bits on things like cellphones.
>>
>> There have been a few machines with 32 bit Z in the past - but they are
>> rare.
>>
>> -- Steve
>>
>> >
>> > Yep, you can call
>> >
>> > gl.getParameter(gl.DEPTH_BITS)
>> >
>> > to obtain the number of bits of depth precision. (Similarly with
>> > RED/GREEN/BLUE/ALPHA.) Note that this returns the bits of the currently
>> > bound FBO, so if you're using FBOs, make sure that you're querying the
>> > right FBO (or null to get the backbuffer).
>> >
>> > - Vlad
>> >
>> > ----- Original Message -----
>> >> Following up on my clipping problem setting the far clip plane I was
>> >> wondering how to tell how many bits the Z-buffer has and
>> >> whether I can find out using WebGL directly.
>> >>
>> >> I've just started using the GLView Extensions Viewer
>> >> (http://www.realtech-vr.com/glview/) to browse a great deal of OpenGL
>> >> and
>> >> video card data and while lookingto see if I can see what my Z-buffer
>> >> depth is I found the following:
>> >>
>> >> Pixel Formats:Depth Buffer Modes
>> >> 0 bpp
>> >> 16 bpp
>> >> 24 bpp
>> >>
>> >> Are these the available Z-buffer depths?
>> >>
>> >> Is there a way I can find the Z-buffer depth using WebGL so I can
>> >> either collect forensic data from deployments or optionally
>> >> use different near and far clipping planes?
>> >> -----------------------------------------------------------
>> >> You are currently subscribed to public_webgl@khronos.org.
>> >> To unsubscribe, send an email to majordomo@khronos.org with
>> >> the following command in the body of your email:
>> >> unsubscribe public_webgl
>> >> -----------------------------------------------------------
>> > -----------------------------------------------------------
>> > You are currently subscribed to public_webgl@khronos.org.
>> > To unsubscribe, send an email to majordomo@khronos.org with
>> > the following command in the body of your email:
>> > unsubscribe public_webgl
>> > -----------------------------------------------------------
>> >
>> >
>>
>>
>>
>> -----------------------------------------------------------
>> You are currently subscribed to public_webgl@khronos.org.
>> To unsubscribe, send an email to majordomo@khronos.org with
>> the following command in the body of your email:
>> unsubscribe public_webgl
>> -----------------------------------------------------------
>>
>>
>
>
> --
> Giles Thomas
> giles@giles.net
> http://www.gilesthomas.com/
> http://projectdirigible.com/
> http://learningwebgl.com/

-----------------------------------------------------------
You are currently subscribed to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email:
unsubscribe public_webgl
-----------------------------------------------------------