2

There are several references to this around the web, including from stackoverflow. I have an unproject method which returns x,y coordinates which are returning in range of -1 and 1. Im wondering if these values are correct. If so, then what do i do with these values, multiply b the cameras position?

Reference: How to convert mouse coordinate on screen to 3D coordinate

Updated

I found a bug in my matrix library, where I was missing some matrix components, I think it was in the multiplication method. After fixing this, I am no longer getting the -1 to 1 range.

Now my data (freshly returned from the Unproject method) looks like this:

When I click on Canvas pixel coord's (1, 2), I get a start vector
(near value of 0) of approx. (9.660, 3.001, 8.091). A end vector (far
value of 1) of approx. (-67.002, 4.408, -107.016).

Although this seems a little better (no longer in range of -1 and 1) the vector is no longer pointing to the screen from near to far (as you can tell from the start and end vectors returned).

I hope I have another bug that can be fixed. Please let me know and I will post the relevant Math functions.

Updated w/ Vertex Shader Details

I'm adding this because im starting to wonder if my UnProject method is using the wrong matrix. My vertex shader calculates the vertex position like this:

gl_Position = projectionMatrix * viewmatrix * modelMatrix * attribPosition;

Misc. Information

  • Just FYI, my Canvas is 640 x 480.
  • I am focused on testing the unprojection by clicking on the upper left corner of the Canvas.
  • My projection is setup as: FOV = 60, Near = 0.1, Far = 100. Up = (0,1,0), LookAt = (0, 0, 0).

My UnProject Implementation This is my unproject function, which is pretty much a copy of the one posted here (note that it is not an exact copy AND I am using my own matrix functions): How to convert mouse coordinate on screen to 3D coordinate

function unProject(x, y, z) {
var mat = this.renderer.projMatrix.Clone();
mat.Multiply(this.renderer.viewMatrix);

var m = mat.GetInverseOf();
var viewPort = this.Viewport;

// invert due to opengl thing.
y = viewPort.Height - y;

var inverse = new Vertex4f();
inverse.X = (x - viewPort.X) / viewPort.Width * 2 - 1;
inverse.Y = (y - viewPort.Y) / viewPort.Height * 2 - 1;
inverse.Z = 2 * z - 1;
inverse.W = 1;

// to world coordinates.
var vector = m.MultiplyVector4(inverse);
if (vector.W == 0) {
    return null;
}

vector.W = 1 / vector.W;

var worldCoordinates = new Vertex3f();
worldCoordinates.X = vector.X * vector.W;
worldCoordinates.Y = vector.Y * vector.W;
worldCoordinates.Z = vector.Z * vector.W;

return worldCoordinates;
}
Community
  • 1
  • 1
AlvinfromDiaspar
  • 6,611
  • 13
  • 75
  • 140
  • 2
    If the X and Y coordinates are in the range [**-1**,**1**] then it sounds like you are only going as far back as NDC and/or clip-space (basically all you did was undo the viewport transform). It is possible that your other coordinates spaces are actually in that range too, but without seeing your projection matrix or any other relevant code it is impossible to say. – Andon M. Coleman Jun 14 '14 at 18:27
  • @Andon. I just updated my results due to a bug in my matrix math method. And I seriously appreciate your help in debugging this. – AlvinfromDiaspar Jun 16 '14 at 16:15
  • The original Unproject func works for me :P. Your adaptation seems OK. So it is possible that your math library has a bug somewhere. I know this is not very helpful, but maybe you should switch to a more widely used library, such as glMatrix: http://glmatrix.net/ – glampert Jun 16 '14 at 18:32
  • You should not be setting W to a constant **1** when you reverse the projection. window-space W is actually 1/clip_w. But by setting it to a constant **1.0** you can no longer undo perspective projection correctly. – Andon M. Coleman Jun 16 '14 at 20:45
  • @Andon. If you look at the original unproject (see link above), the W component (index 3) is actually set to 1. – AlvinfromDiaspar Jun 17 '14 at 17:05
  • Yeah, I just noticed you are setting ***input*** `w` to a constant **1.0**. Multiplying it by the inverse projection matrix will produce a non-const `w` (in the ***output***), so everything is good there. You can disregard that. I was not looking closely enough. – Andon M. Coleman Jun 17 '14 at 17:07
  • Regarding your issue of pointing from near to far. In OpenGL, world-space and view-space are typically right-handed. This behavior comes from the fact that while X points right and Y points up, Z points backwards. The projection matrix flips the Z-axis to produce the behavior you have probably come to expect (positive Z-axis pointing forward) for clip-, NDC- and window-spaces. So as best I can tell, the fact that your ***end*** vector has a Z value that is < your ***start*** vector is perfectly normal for world-space. – Andon M. Coleman Jun 17 '14 at 17:14
  • Thanks. But concern is that my start and end vectors have very different values for their respective X, Y components (I think the Z components seems fine). – AlvinfromDiaspar Jun 17 '14 at 17:27
  • Well, I cannot answer that part of your question without knowing your aspect ratio. The `FOV` in a function that builds a perspective projection matrix ***usually*** refers to the top-half of the vertical field of view. Thus, FOV=60 would be fovy=120. But... I cannot tell you the characteristics of your horizontal projection without the aspect ratio. – Andon M. Coleman Jun 17 '14 at 18:54
  • So at this point i shall go thru my matrix math functions. I have no idea what else i can do. Thanks all. – AlvinfromDiaspar Jun 17 '14 at 20:15
  • Please refer to my vertex shader. Perhaps i am using the wrong matrix in the UnProject function. – AlvinfromDiaspar Jun 17 '14 at 23:21

0 Answers0