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;
}