PDA

View Full Version : Linear interpolation of depth value between front and back face depth values

RealtimeSlave
05-15-2016, 11:56 AM
Hello,

I have a cube for which the depth values of the back-faces are stored in a depth buffer A
and the depth values of the front-faces are stored in another depth buffer B.

Now I render something that lies in this cube. In the fragment shader for each fragment I know:
1. depth value of the cube back-face (texture lookup in depth buffer A at current fragment xy position)
2. depth value of the cube front-face (texture lookup in depth buffer B at current fragment xy position)
3. depth value of the current fragment

Is there a way to linear interpolate between 1. and 2. using 3. so that I get a value in range [0.0,1.0]?

I know a formular to linearize a depth buffer based on zNear and ZFar but I wonder
if there is a similar formular to do this for the use case described here?

Not sure if this fancy GLSL built-in smoothstep function is handy for this...

Help is really appreciated!

GClements
05-15-2016, 05:29 PM
I have a cube for which the depth values of the back-faces are stored in a depth buffer A
and the depth values of the front-faces are stored in another depth buffer B.

Now I render something that lies in this cube. In the fragment shader for each fragment I know:
1. depth value of the cube back-face (texture lookup in depth buffer A at current fragment xy position)
2. depth value of the cube front-face (texture lookup in depth buffer B at current fragment xy position)
3. depth value of the current fragment

Is there a way to linear interpolate between 1. and 2. using 3. so that I get a value in range [0.0,1.0]?

t = (cur_depth - front_depth) / (back_depth - front_depth)

If you want to interpolate based upon eye-space Z, then you need to first convert all three depth values to eye-space Z using ....

I know a formular to linearize a depth buffer based on zNear and ZFar

... that.

I.e. Zeye = -B/(2*depth+A-1), where A and B are the [2][2] and [2][3] elements from the projection matrix, typically:
A=(near+far)/(near-far)
B=2*near*far/(near-far)

You can reduce the overall equation to:

t = ((front_depth - cur_depth)*(A + 2*back_depth - 1))/((front_depth - back_depth)*(A + 2*cur_depth - 1))

Not sure if this fancy GLSL built-in smoothstep function is handy for this...

Not useful here.

RealtimeSlave
05-16-2016, 05:39 AM
Thank you!

Actually I was using the eye-space Z approach before asking here but I had some flickering noise in my debug output.

That is why I asked here because I was not sure if I missed some important point or if my formula is wrong causing this flickering.

BUT I just found out what caused the flickering...

In my current use case I bound two textures to my shader:
1. The depth texture handle of the main FBO where I am about to render to
2. The depth texture which contains back face depth values of the cube

I was rendering red color when (depth value from 1.) > (depth value from 2.), otherwise white color. And it created flickering noise.

I figured out this noise comes from the main FBO depth texture lookup because
I forgot to disable depth write. That means I was writing to the main FBO depth
buffer while reading from it. I simply disabled depth write and now it works.

BUT... NEW QUESTION:
Although it is working now, I wonder if it is legal to read in the fragment shader
from a depth texture which is attached as depth buffer to the current bound
FBO when depth write is disabled via glDepthMask(false)? IMHO it should be
legal because I read from a texture without writing to it, no?

It perfectly works on my AMD Radeon HD 5850 but could it break with another graphics card/driver?
Thanks!