# 3D Ray Casting / Picking

I am not sure if I should post this link, but I feel this falls into game development just as much as it does math. I have a ray cast's far and near values and I am trying to calculate the end point of the ray so that I can either draw a line to show the ray, or render an object at the end of 3d mouse position.

Here is my post on the stack overflow math site, if there is a problem with me doing this just close the thread. Thank you. https://math.stackexchange.com/questions/15918/help-with-matrix-mathematica

• Please do not cross-post. And if you do, don't then link the question and instead paste it into this question box. – The Communist Duck Dec 30 '10 at 15:50
• Ok ... raycasting is definetively good for gamedev (i think). – Notabene Dec 30 '10 at 15:54
• opengl.org/wiki/GluProject_and_gluUnProject_code – user9450 Aug 24 '11 at 3:32

I think that you don't know 3D position of the clicked point, because otherwise it would be easy :).

So if you know 3D position of the clicked point in origin basis then you can calculate far and near points like this:

nearPoint3D = cameraposition3D
farPoint3D = cameraposition3D + (normalize(clickedPoint3D - cameraposition3D) * zFar)


The problematic part is clickedPoint3D. You can compute it nicely with help of view and projection matrices. As you are using opengl i suppose that you have them. view * projection matrix converts 3D points to the 2D screen space. You can use inverted viewprojection matrix and get matrix which converts 2D screen points to the 3D space.

pseudo code and some openGl:

//define matrices
Matrix4x4 g_CameraViewMatrix;
Matrix4x4 g_CameraProjectionMatrix;

glMatrixMode(GL_PROJECTION);
gluPerspective(...); //your perspective function
glGetFloatv(GL_PROJECTION_MATRIX, &g_CameraProjectionMatrix.m[0]); //returns matrix as float array

glMatrixMode(GL_MODELVIEW);
glLookAt(...); //you lookat function or whatever - NO translation,rotations or anything else for getting camera matrix!
glGetFloatv(GL_MODELVIEW_MATRIX, &g_CameraViewMatrix.m[0]);

//compute 3D position of clicked point
Matrix4x4 viewProjInv = (g_LightViewMatrix * g_CameraViewMatrix).getInverse();
vector4D clickedPointOnSreen = (x_screen,y_screen,1.0f,1.0f); // Z have to be between 0 - 1 and W have to be 1
vector4D clickedPointIn3DOrigin = viewProjInv * clickedPointOnSreen;
vector3D clickedPoint3D = clickedPointIn3DOrigin.xyz;


Note that you can use this to compute 3D points of zNear and zFar really easily:

vector4D clickedPointOnSreen = (x_screen,y_screen,1.0f,1.0f); // will produce 3D position of zFar
vector4D clickedPointOnSreen = (x_screen,y_screen,0.0f,1.0f); // will produce 3D position of zNear.


Isn't that algebra wonderful? :)

To learn something about projection matrix you can read this what-is-the-purpose-of-the-canonical-view-volume

• wow! and so this is how gluUnproject works? – nkint Feb 1 '11 at 0:00
• @nkint Yes. From glu documentation: "gluUnProject multiplies the normalized device coordinates by the inverse of model*proj". Thats exactly what this code does. – Notabene Feb 1 '11 at 0:18
• @Notabene It's actually the inverse of proj*model, like you did in your example (if I assume g_LightViewMatrix means g_CameraProjectionMatrix) – Christian Rau Aug 24 '11 at 12:09