Horde3D http://www.horde3d.org/forums/ |
|
Reconstructing fragment position from depth http://www.horde3d.org/forums/viewtopic.php?f=1&t=569 |
Page 1 of 1 |
Author: | DarkAngel [ 30.11.2008, 13:47 ] |
Post subject: | Reconstructing fragment position from depth |
I'm currently attempting to create a more optimal deferred renderer using mostly 8-bit RBGA textures. I've become stuck trying to reconstruct positions from depth though: marciano wrote: As stated in another thread, the deferred shading implementation could quite easily be optimized using 8 bit targets and reconstructing fragment position from depth (google for this). Has anyone done this before, and could provide me with advice? I'm using the following modifications to write depth to the G-Buffer: Code: <VertexShader> ... varying vec4 vsPos; void main( void ) { ... // Calc eye space pos vsPos = calcViewPos( pos ); ... </VertexShader> <FragmentShader> ... varying vec4 vsPos; void main( void ) { ... setDepth( -vsPos.z / 1000.0 ); // setPos( vsPos ); // <-- for debugging ... </FragmentShader> ... ... float getDepth( const vec2 coord ) { return texture2D( tex9, coord ).a; } void setDepth( const float depth ) { gl_FragData[1].a = depth; } The above code works fine. I'm having trouble in the lighting shader reconstructing a (view space) position from these depth values. My (attempted, but incorrect) algorithm is to construct a ray that passes through the current pixel, and then scale that ray by the depth value. When I compare my results against the actual view-space position though, my results are slightly wrong. Code: vec4 ray; ray.w = 1.0;
float fov = radians(45.0); float off = 0.5; float sca = 2.0; vec2 screen = vec2( 640.0, 480.0 ); float aspect = screen.x / screen.y; float farPlane = 1000.0; float xratio = gl_FragCoord.x/screen.x; float yratio = gl_FragCoord.y/screen.y; ray.x = (xratio-off) * sca * sin(fov); ray.y = (yratio-off) * sca * sin(fov / aspect); ray.z = cos( asin(ray.y) ); ray *= getDepth(texCoords) * farPlane; // ray.rgb = getPos(texCoords); ray.z = ray.z * -1.0; // <-- for debugging gl_FragColor = ray; |
Author: | marciano [ 30.11.2008, 16:11 ] |
Post subject: | Re: Reconstructing fragment position from depth |
Honestly I have not yet tried it myself but maybe this thread has some helpful information: http://www.gamedev.net/community/forums/topic.asp?topic_id=506573 |
Author: | Mikmacer [ 30.11.2008, 17:51 ] |
Post subject: | Re: Reconstructing fragment position from depth |
Ive used this code to get the eye position in one of my project. It is taken from an NVidia example. Code: const float fovy = 40.0 * 3.14159265 / 180.0; // 40 deg in radian const float invFocalLenX = tan(fovy * 0.5) * width / height; const float invFocalLenY = tan(fovy * 0.5); vec3 uv_to_eye(vec2 uv, float eye_z) { uv = (uv * vec2(2.0, -2.0) - vec2(1.0, -1.0)); return vec3(uv * vec2(invFocalLenX, invFocalLenY) * eye_z, eye_z); } vec3 fetch_eye_pos(vec2 uv) { float z = texture2D(tex1, uv).a; // Depth/Normal buffer return uv_to_eye(uv, z); } |
Author: | DarkAngel [ 01.12.2008, 02:49 ] |
Post subject: | Re: Reconstructing fragment position from depth |
Thanks, that works perfectly. |
Author: | DarkAngel [ 01.12.2008, 07:45 ] |
Post subject: | Re: Reconstructing fragment position from depth |
I'm now able to reconstruct world-space positions from the depth data as well, using the following: Code: vec4 vsPos = vec4( uv_to_eye( texCoords, depth ), 1.0 ); vec4 wsPos = gl_ModelViewMatrixInverse * vsPos; But to get this to work, I had to change some C++ code in Renderer::drawFSQuad to make the camera's Model-View-Matrix available to full-screen-quads: Code: glMatrixMode( GL_MODELVIEW ); // glLoadIdentity(); //I removed this line glLoadMatrixf( _curCamera->_invTrans.x );//new code As far as I know, this change shouldn't break anything, because none of the shaders used on full-screen quads use the Model-View-Matrix at all anyway. Picture: World-positions reconstructed from depth |
Author: | marciano [ 06.12.2008, 22:07 ] |
Post subject: | Re: Reconstructing fragment position from depth |
It really makes sense to give access to the camera tranformation for post processing effects. We will add that... |
Author: | DarkAngel [ 08.03.2010, 13:28 ] |
Post subject: | Re: Reconstructing fragment position from depth |
I was asked in a PM about my depth-reconstruction code, so I'll post it here. N.B. there is a hard-coded FOV of 45 degrees in this code -- you will most likely want to change that for a real demo/game ![]() Code: vec4 floatToRGBA8(const float value) { const vec4 bitSh = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0); const vec4 mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); vec4 res = fract(value * bitSh);//error on ATI here? res -= res.xxyz * mask; return res; } void setDepth( const float depth ) { vec4 pAcked = floatToRGBA8( depth / 1000.0 ); gl_FragData[1] = pAcked; } void setPos( const vec3 pos ) { float depth = (gl_ModelViewMatrix * vec4(pos,1)).z * -1.0; setDepth( depth ); } Code: float getFloatFromRGBA8(const vec4 value)
{ const vec4 bitSh = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0); return(dot(value, bitSh)); } float getDepth( const vec2 coord ) { vec4 vec = texture2D( buf1, coord ); return getFloatFromRGBA8(vec) * 1000.0; } vec3 uv_to_eye(vec2 uv, float eye_z) { float fovy = radians(45.0); float aspect = frameBufSize.x / frameBufSize.y; float invFocalLenX = tan(fovy * 0.5) * aspect; float invFocalLenY = tan(fovy * 0.5); uv = (uv * vec2(2.0, 2.0) - vec2(1.0, 1.0)); return vec3(uv * vec2(invFocalLenX, invFocalLenY) * eye_z, eye_z); } vec3 getPos( const vec2 coord ) { float depth = getDepth( coord ); vec3 pos = uv_to_eye( coord, depth ); pos.z *= -1.0; return (gl_ModelViewMatrixInverse * vec4(pos,1.0)).xyz; } |
Page 1 of 1 | All times are UTC + 1 hour |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |