1
$\begingroup$

I'm trying to figure out how to reverse Eye space -> projection -> clip(divide by w) -> screen space conversion.

Basically, I want to get Screen space (still have z value for z-buffer) -> undivide? by w -> inverse projection.

I found the inverse matrix for projection but can't figure out how to get the coordinate "undivided" by w.

Thank you!

$\endgroup$
1
$\begingroup$

Object Space → World Space → Eye Space → Clip Space → Normalized Device Space → Window Space

  • You get from Object Space to World Space by multiplying by the "World Matrix" (This may actually be multiple matrices depending on the parent-child object hierarchy of the scene. Compose them all together to get a single "World Matrix" for a given object.)
  • You get from World Space to Eye Space by multiplying by the "View Matrix".
  • You get from Eye Space to Clip Space by multiplying by the "Projection Matrix".
  • You get from Clip Space to Normalized Device Space by performing the "perspective divide" (divide by w in clip space coordinates). This is a non-linear transformation requiring a divide, and is not represented by a matrix. Information can be destroyed in this step. If w is divided by w you just get 1, and there's no way to recover the original w.

    Divide by w

  • You get from Normalized Device Space to Window Space by performing the Viewport and Depth Range transform. (Simple linear relationship)

    Viewport Transform

    enter image description here

The World Matrix, View Matrix, and Projection Matrix are all just 4x4 matrices and can be inverted to get the reverse transformation.

So, to go backwards...

  • You get from Window Space to Normalized Device Space by performing the inverse of the Viewport and Depth Range transform.
  • You can get from Normalized Device Space to Clip Space by performing the inverse of the perspective divide (multiply by w). This is a non-linear transformation requiring a multiply, and is not represented by a matrix. In general this operation doesn't magically recover 3D data from 2D data. You must know something about the depth externally to be able to recover the 3D position of a point on the 2D screen.
  • You can get from Clip Space to Eye Space by multiplying by the inverse of the "Projection Matrix"
  • You can get from Eye Space to World Space by multiplying by the inverse of the "View Matrix".
  • You can get from World Space to Object Space by multiplying by the inverse of the "World Matrix".

May I suggest reading this explanation of the OpenGL Transformation.

$\endgroup$
  • $\begingroup$ Just want to point out that you sometimes see projection matrices that are singular, but the OP says this isn't case in his example. $\endgroup$ – Simon F Jan 9 '18 at 17:19
  • $\begingroup$ True, @SimonF, such is the case for an orthographic projection matrix. $\endgroup$ – Wyck Jan 9 '18 at 18:21
0
$\begingroup$

clip(divide by w) -> screen space

Be careful, if you're really in screen space. My guess is, you're doing picking or deferred rendering, in which case you're probably reading fragments in Normalized Device Space (i.e. x and y in range [-1, 1]*).

If so, you can do it like this:

Read out Normalized Device Coordinates as vec4 with depth as z value and 1.0 as w value and bring them into [0, 1] range by multiplying by 2 and subtracting 1. Convert them into Eye Space with the inverted projection matrix. Divide your new vector by its w coordinate (which is your undivide step). Now you're in Eye Space.

There are more ways to do this, you can have a look at Reconstructing Position From Depth to dive further into how.

*I'm assuming OpenGL, ranges might be different in DirectX

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.