0
$\begingroup$

So I am making a raytracer following the very helpful online book of Gabriel Gambetta but I stumble on the rotation matrix part.

My linear algebra background is 3Blue1Brown video series "The essence of Linear Algebra".

I simulate a camera placed at the origin that's looking forward ie whose direction is the vector {0,0,1}. Let's say I am given another camera direction with direction {a,b,c}. From what I understand if I find the rotation matrix R that takes as an input {0,0,1} and spits out a normalized {a,b,c} as an output. Then I can apply that rotation matrix to all my rays in order to rotate them. I can't get my head around on how to find R. Any help/explanation/correction much welcome.

I am in a similar situation than the person asking this question except that he seems to know already what needs be done and is just asking about if his rationale is good.

Thanks

EDIT : The answer below is valid considering how I framed my problem but note that if you were like me trying to compute a camera to world rotation matrix and expected the viewport of your camera to follow along, you need an additional step because the answer below only gives you a shear matrix. In order to get a rotation matrix you need to compute the upVector with normalize(cross_product(rightVector, forwardVector)) (in a right hand system) and feed its coordinates into the matrix instead of {0,1,0}

$\endgroup$
1
  • $\begingroup$ Here is a related question from Math SE. I don't have the time right now to give you a fully qualified answer, but you can also find the quaternion between two vectors and turn it into a matrix afterward. To find the quaternion, have a look into this question $\endgroup$
    – wychmaster
    Mar 22 at 9:36
2
$\begingroup$

You can construct a rotation matrix from an "axis", or 3 vectors. This is done by calculating 3 direction (normalized) vectors for the 3 axis of our new rotated coordinate system, they are forward, up and right vectors.

In your case let's say we have 2 vectors called v1 and v2.

we can produce a direction from them via (glsl psuedo code):

vec3 forwardVector = normalize(v2 - v1);

Then for our up vector we can pick the world-up axis (e.g. 0,1,0), although this may give you problems if the forward vector is very close to the up axis, in that case you can pick another arbitrary axis that's not nearby, like {0,0,1}. For the sake of simplicity we'll stick to the world up axis of {0,1,0}.

The last vector can be derived automatically from the other 2 vectors using a cross product.

so now we should have something like:

vec3 forwardVector = normalize(v2 - v1);
vec3 upVector = vec3(0,1,0);
vec3 rightVector = normalize(cross(forwardVector, upVector));

These 3 vectors can be directly plugged into a 3x3 matrix to form the rotation matrix.

r.x r.y r.z
u.x u.y u.z 
f.x f.y f.z 

where f=forwardVector, u=upVector and r=rightVector.

This is similar to an openGL "LookAt" matrix.

Be aware there are many rotation matrices that are valid solutions because 2 vectors cannot describe what the rotation is along the v1->v2 axis (That's what the 'up' axis fixes in this case).

$\endgroup$
0

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.