4
votes

I'm working on a project where I port my CUDA code for usage as a module in a big application which maintains its own OpenGL state. My module basically is a volume renderer. I am now facing the problem that I have to setup the rays of the volume renderer to exactly mimic the OpenGL camera, so that my volume renderering fits with the rest of the rendered scene.

At the point where my CUDA code is called there is a viewing matrix (no model-view matrix) and a projection matrix set. I already extracted the frustum parameters and the camera position in world space.

u *= -c_pp.right;
v *= -c_pp.top;

Ray eyeRay;
eyeRay.o = make_float3(c_camPosition); //origin
eyeRay.d = normalize(make_float3(u, v, -c_pp.near)); //direction

u and v are normalized screen coordinates running from -1 to 1. c_pp describes the view frustum using top, right and near. I'm now looking for the appropriate matrix I have to multiply with so that eyeRay.d shows in the right direction. So far using the viewing matrix or its transposed or inverted version failed.

Update:

Changed u *= -c_pp.right to u *= c_pp.right and everything works by multiplying eyeRay.d with the inverse viewing matrix.

Complete fixed code:

u *= c_pp.right;
v *= -c_pp.top;

Ray eyeRay;
eyeRay.o = make_float3(c_camPosition); //origin
eyeRay.d = make_float3(u, v, -c_pp.near)); //direction
eyeRay.d = mul(c_invViewMatrix, eyeRay.d);

with c_inViewMatrix being the inverse view matrix.

1
If you just want the view direction of the camera in worldspace, it should be the -Z axis of the camera's transformation matrix (minus because OpenGL's view axis points out of the screen), providing the camera itself is only described in world space terms.cmannett85
@cbamver85: Thanks to your comment I found the solution; c_pp.right has the wrong sign, changing the code to u *= c_pp.right and everything works by multiplying the eyeRay.d vector with the inverse view matrix. After comparing the viewing direction of my CUDA code with the one I calculated in CPU code I found that there was something amiss and it turned out that the X component had the wrong sign all the time.ineX

1 Answers

3
votes

This question has been answered by the original poster inline. The answer is to change u *= -c_pp.right to u *= c_pp.right (sign change). See above.

I've added this answer to reduce the number of unanswered questions in the CUDA tag to help make it more useful.