Reconstruction position in World Space after depth packaging to RGBA8

Started by
4 comments, last by wolf 15 years, 10 months ago
Hi, I have problem with my Deferred Shading. In FBO I can't use different internal format, so I must give one format. With GL_RGBA32F_ARB for Position, Normal, DiffuseMap etc. precision is good, but my application FPS is poor, so I have question how can I store all this values: position, normal etc. in low precision texture RGBA8 without lost quality? Meybe I can use some packaging pseudo floating point values to RGBA8? For DirectX I use R32F for position, RGBA16F for Normals and RGBA8 for other values and I try build similar textures format type configuration for OpenGL, is it possible? [Edited by - carew on June 21, 2008 11:59:31 AM]
Advertisement
I remember this tutorial had some code for packing a single floating-point value in an RGBA8 buffer. That should take care of your depth...and diffuse/specular albedo can also be stored in that format no problem. The only problem really is normals...you could store them in RGBA8 but the precision won't be great. You might be better off by storing two values for your normals: either store view-space X and Y and then reconstruct Z using z = sqrt(1.0f - (normal.x*normal.x) - (normal.y*normal.y)), or store the theta and phi values of the original normal converted to a spherical coordinate. For those two methods, you could use two channels per value to get better precision.
Thanks for it. I store Position.Z component (depth) to texture RGBA8, so I have 24 (Alpha 8 bytes are free) bytes precision for it and it's enought:)
There is no such thing as depth in world space (well, there is, but it's not really "depth"). You want the depth in view space. Once you use the worldView matrix, then the other thread applies to you perfectly [wink]. (once you reconstruct the view-space position, if you need world-space then just multiply by the inverse of the view matrix)

As for reconstructing the Z part of the normal - you can't do this correctly with normal maps without knowing the sign of the Z part. When you use normal maps, Z might end up being negative - meaning, you'd have to encode its sign somewhere and use that to determine if the square root is negative or positive. Since it's hard to simply encode the sign, you might find another format useful, such as R10G10B10A2 (10-bit RGB, 2-bit alpha).
I would use the depth buffer and then re-construct like this:


gCurrDepth = tex2D(DepthMapSampler, IN.texCoord0.xy);

FLOAT2 PositionXY = IN.texCoord0.zw;

FLOAT3 screenPos = FLOAT3(PositionXY, gCurrDepth);
FLOAT4 worldPos4 = mul(FLOAT4(screenPos, 1.0f), WorldViewProjInverse);
worldPos4.xyz /= worldPos4.w;

Saves you to store depth data additionally :-)

- Wolf
upps techcord.zw the x and z value in screen-space.

This topic is closed to new replies.

Advertisement