**0**

# how to encode the depth value in a 32bit RGBA texture

###
#1
Members - Reputation: **122**

Posted 27 November 2008 - 04:56 PM

###
#2
Crossbones+ - Reputation: **5782**

Posted 28 November 2008 - 03:19 PM

To find the value to store in R, take (frac( Depth / 2^5 ) * 2^5). Then, similarly for B you would take (frac( Depth / 2^10 ) * 2^5), and for G it would be (frac( Depth / 2^15 ) * 2^5). That should properly parse out the bits that you are looking for.

If you are going to use the top few bits of each channel, make sure that you only add values that will affect the upper few bits and ADD the values to the depth values we mentioned above.

Have you tried something similar to this before?

Jason Zink :: DirectX MVP

Direct3D 11 engine on CodePlex: Hieroglyph 3

Direct3D Books: Practical Rendering and Computation with Direct3D 11, Programming Vertex, Geometry, and Pixel Shaders

Articles: Dual-Paraboloid Mapping Article :: Parallax Occlusion Mapping Article (original):: Fast Silhouettes Article

Games: Lunar Rift

###
#4
Members - Reputation: **303**

Posted 29 November 2008 - 02:33 PM

So say your depth value is N*3 bits and we'll call it d.

Then just store it as follows:

mask = (pow(2, N)-1)

r = d & mask

g = (d << N) & mask

b = (d << (N*2)) & mask

To get d back do:

d = r & mask

d = d >> N

d = d+(g & mask)

d = d >> N

d = d+(b & mask)

-CProgrammer

###
#5
Crossbones+ - Reputation: **5782**

Posted 30 November 2008 - 07:39 AM

Quote:

Original post by CProgrammer

Well to do what you explained you simply use bitwise operations.

So say your depth value is N*3 bits and we'll call it d.

Then just store it as follows:

mask = (pow(2, N)-1)

r = d & mask

g = (d << N) & mask

b = (d << (N*2)) & mask

To get d back do:

d = r & mask

d = d >> N

d = d+(g & mask)

d = d >> N

d = d+(b & mask)

-CProgrammer

That would work ok if he is using integer values, but that is frequently not the case in a pixel shader.

However, the concept is fairly close to what CProgrammer describes - the only real difference is how to get at the bits you want. In the technique I mentioned above, taking the fractional remainder after dividing by the bit range that you are interested in, then multiplying by the range that you can store, you are effectively doing the same thing that CProgrammer did. The only thing I forgot to mention is that you need to put the value into the [0,1] range to store in the render target anyways, so you would only need to do: frac( Depth / 2^x ) where x is determined by which channel you are working on.

To get the depth value back, you would take the compressed R value (which represents the lowest 5 bits, and is stored in the range of [0,1]) then multiply it by 2^5, and then multiply it by the range offset. Since this is the lowest 5 bits, then you don't need to multiply by an offset (2^0 = 1).

Then do the same for G - multiply by 2^5, then multiply by an offset to put the value into the correct range. In this case it would be to multiply by 2^5 to put this number into the range for bits 5-9.

Finally for B, multiply by 2^5 and then 2^10 to put the values into the range of bits 10-14. The reconstructed depth value is simply the sum of these three products.

Once again, I haven't tried this myself, but the theory should be sound - you may lose a little precision here and there in converting between integer and floating point, but it should be a pretty good representation of what you are trying to do.

Jason Zink :: DirectX MVP

Direct3D 11 engine on CodePlex: Hieroglyph 3

Direct3D Books: Practical Rendering and Computation with Direct3D 11, Programming Vertex, Geometry, and Pixel Shaders

Articles: Dual-Paraboloid Mapping Article :: Parallax Occlusion Mapping Article (original):: Fast Silhouettes Article

Games: Lunar Rift

###
#6
Members - Reputation: **122**

Posted 30 November 2008 - 01:01 PM

I have tried your method, it seems doesn't work.

here is the shader to encode the depth value:

float scalar = 32.0f;

float3 OutColor;

OutColor.x = frac( DepthValue / scalar ) * scalar;

OutColor.y = frac( DepthValue / (scalar * scalar) ) * scalar;

OutColor.z = (frac( DepthValue / (scalar * scalar * scalar) ) * scalar);

here is the shader to get the value back:

float4 f= tex2D(Tex, In.texCoord);

float scalar = 32.0f;

float depth = f.x *scalar + f.y*scalar*scalar + f.z*scalar*scalar*scalar;

Did i do something wrong?

What i am confused is the floating point value in the shader. Will the bit shifting work for floating point value?

Thanks!

###
#7
Crossbones+ - Reputation: **5782**

Posted 30 November 2008 - 03:05 PM

The only thing that I see is that the storage doesn't need to be multplied after taking the fraction. I mentioned it in my second post, but forgot it in the first post (sorry...).

What this will do is put the values into the [0,1] range, which is required to store the value in the RGB channels. The reconstruction that you showed is what I had envisioned, so hopefully that works for you!

Jason Zink :: DirectX MVP

Direct3D 11 engine on CodePlex: Hieroglyph 3

Direct3D Books: Practical Rendering and Computation with Direct3D 11, Programming Vertex, Geometry, and Pixel Shaders

Articles: Dual-Paraboloid Mapping Article :: Parallax Occlusion Mapping Article (original):: Fast Silhouettes Article

Games: Lunar Rift

###
#8
Members - Reputation: **122**

Posted 01 December 2008 - 01:31 PM

But it doesn't work. :(

I guess maybe it is because the result is too small to be saved in the 8bit texture?

OutColor.x = frac( DepthValue / scalar );

OutColor.y = frac( DepthValue / (scalar * scalar) ;

OutColor.z = frac( DepthValue / (scalar * scalar * scalar) ) ;

###
#9
Crossbones+ - Reputation: **5782**

Posted 01 December 2008 - 03:27 PM

I am assuming that you have an integer distance - something like a D32 value. Can you try to take a PIX reading (or the OGL equivalent if needed) of the resulting render target so that I can check out what you are getting? Unfortunately I don't have the time to check it out until at least Thursday, but I would be interested to see what you are getting out...

Jason Zink :: DirectX MVP

Direct3D 11 engine on CodePlex: Hieroglyph 3

Articles: Dual-Paraboloid Mapping Article :: Parallax Occlusion Mapping Article (original):: Fast Silhouettes Article

Games: Lunar Rift