I'm playing with sun implementation in my engine and I correctly built model matrix using below order of matrix operations:
- Translate to camera position.
- Calculate x and y axis of rotation matrix using cross product. Z axis is equal to sun direction.
However I'd like to use function which takes into account two unit vectors and based on them build rotation matrix (explanation here). When I replace 2nd step with function call the sun is in completely different position on the sky (but correctly oriented). As a input vectors I set direction vector and [0, 1, 0] vector.
Could someone provide a solution/hint/explanation of that topic?
Code
Working solution:
Matrix matrix; matrix.setPosition(ActiveCamera.getInversedMatrix().pos);
Vector xaxis = Cross(Vector(0,1,0), direction);
xaxis.normalize();
Vector yaxis = Cross(direction, xaxis);
yaxis.normalize();
matrix.x.x = xaxis.x;
matrix.y.x = yaxis.x;
matrix.z.x = direction.x;
matrix.x.y = xaxis.y;
matrix.y.y = yaxis.y;
matrix.z.y = direction.y;
matrix.x.z = xaxis.z;
matrix.y.z = yaxis.z;
matrix.z.z = direction.z;
Not working solution:
Matrix matrix; matrix.setPosition(ActiveCamera.getInversedMatrix().pos);
matrix.setRotation(Vector(0, 1, 0), direction);
Matrix3& Matrix3::setRotation(const Vector &u, const Vector &v) {
Vector cross = Cross(u, v);
float sin = cross.magnitude(); // sine of angle
cross.normalize();
float cos = Dot(u, v); // cosine of angle
this->x.x = cross.x * cross.x * (1 - cos) + cos;
this->x.y = cross.x * cross.y * (1 - cos) + sin * cross.z;
this->x.z = cross.x * cross.z * (1 - cos) - sin * cross.y;
this->y.x = cross.x * cross.y * (1 - cos) - sin * cross.z;
this->y.y = cross.y * cross.y * (1 - cos) + cos;
this->y.z = cross.y * cross.z * (1 - cos) + sin * cross.x;
this->z.x = cross.x * cross.z * (1 - cos) + sin * cross.y;
this->z.y = cross.y * cross.z * (1 - cos) - sin * cross.x;
this->z.z = cross.z * cross.z * (1 - cos) + cos;
return (*this);
}