Unprojecting...

I’m trying to go from clip space to world space and then to light clip space in a fragment shader (what you would want to do if you do shadow mapping with a deferred shader), but I can’t get it working. My generated world space coordinates don’t stand still. They get more and more misaligned the farther I move the camera from the world origin.
This is a fragment shader that only goes from clip space to world space, but it still doesn’t work very well (same problem).


uniform sampler2D depth; //The depth buffer of the scene, verified to be bound correctly and containing correct data.

uniform mat4x4 inverseProjectionMatrix, inverseViewMatrix; //Correctly set.

in vec2 position; //Interpolated from a fullscreen quad. Clip space position [-1, 1], verified to be working.

layout(location = 0) out vec4 fragColor;

void main()
{
    float z = texture2D(depth, texCoords).z; //Get depth (DEPTH_COMPONENT texture), verified to be working.
    
    vec4 eyeSpace = inverseProjectionMatrix * vec4(position.x, position.y, z, 1); 
    //eyeSpace /= eyeSpace.w; //Doesn't seem to affect it as I do a w-divide for worldSpace too.
    vec4 worldSpace = inverseViewMatrix * eyeSpace;
    worldSpace /= worldSpace.w;
    
    fragColor = vec4(worldSpace.xyz, 1); //Colors of the same point in world space change when the camera moves.
}

Am I doing something wrong?

Matrix setup:

Matrix4f.invert(projectionMatrix, null).store(matrixBuffer);
matrixBuffer.flip();
GL20.glUniformMatrix4(volumetricShader.getUniformLocation("inverseProjectionMatrix"), false, matrixBuffer);
matrixBuffer.clear();

Matrix4f.invert(viewMatrix, null).store(matrixBuffer);
matrixBuffer.flip();
GL20.glUniformMatrix4(volumetricShader.getUniformLocation("inverseViewMatrix"), false, matrixBuffer);
matrixBuffer.clear();

Jeez… Matrices are so annoying sometimes…

Jeez. Stupid OpenGL.
http://www.opengl.org/wiki/Vertex_Transformation

[quote]Step 4 : Getting to window space

Now the final stage of the transformation pipeline:
The z is transformed to the 0.0 to 1.0 range.
[/quote]
Compensating for this yields perfect results. -_- Seems like DirectX doesn’t do this.

Fullscreen pass

Okay, I’m drawing the following coordinates as a GL_QUAD (or as quads are deprecated, a GL_TRIANGLE_STRIP) to get a fullscreen quad:
0, 0
1, 0
1, 1
0, 1

Vertex shader:

#version 330

in vec2 inVertex;

out vec2 texCoords;

void main(){
    gl_Position = vec4(inVertex * 2 - 1, 0, 1); //Expand from [0,1] to [-1,1]
    texCoords = inVertex;
}

Fragment Shader:

#version 330

uniform sampler2D depth;

uniform mat4x4 inverseProjectionMatrix, inverseViewMatrix;

in vec2 texCoords;

void main()
{
    float z = texture2D(depth, texCoords).z; //Sample scene depth

    vec4 normalizedClipSpace = vec4(vec3(texCoords, z) * 2 - 1, 1); //Expand xyz from [0,1] to [-1, 1]
    
    vec4 eyeSpace = inverseProjectionMatrix * normalizedClipSpace;
    //eyeSpace /= eyeSpace.w; //If you just want eye space coordinates, uncomment this line
    vec4 worldSpace = inverseViewMatrix * eyeSpace;
    worldSpace /= worldSpace.w;
    
    //Do whatever you want with worldSpace...
}

I hope this helps someone! =D

Sorry for resurrecting old topic but I have battle with this too and I think I figured better or at least faster way to do this.

@vertex shader


v_viewRay = worldPos - camPos;

@fragment shader.


vec3 viewPos = fromEye * depth;
vec3 worldPos = viewPos + camPos;

Actually there is even better ways to do this but its dependant in which coordination system you want to do this math. More info http://mynameismjp.wordpress.com/2010/09/05/position-from-depth-3/

Currently I am doing everything in view space and got my prelight pass system work on android with real time framerates.

Yeah, getting rid of the matrix multiplication per pixel is a good idea. I can’t test it myself at the moment though since my laptop’s power jack is broken. 50 hours of abstinence and I’m already at my limit…

http://code.google.com/p/gles20prelightpass/

Full source can be found here. Maybe 6-12 months and this gonna be viable choise for mobile developing in terms of marketshare of viable devices.

Will check it out if I survive until my laptop is fixed…