I'm trying to build a raytracer and I use this article on how to build camera system. The problem is that when, after calculating ray direction in camera space, I multiply it by camera-to-world transformation matrix and my camera seems to rotate in opposite directions and works correctly if I inverse transformation matrix before multiplication.
Here is the code (I use glm library and right-handed coordinate system).
Some data
glm::vec3 origin_ = glm::vec3(0.f);// camera origin
cont glm::vec3 kDirection = glm::vec3(0.f, 0.f, -1.f);
cont glm::vec3 kUp = glm::vec3(0.f, 1.f, 0.f);
float aspect_ratio_ = (float)raster_height_ / raster_width_;
// bug !!! rotates in opposite direction (camera is actually tilted down)
glm::mat4 camera_to_world_ = glm::lookAtRH(origin_, glm::vec3(0.f, 0.2f, -1.f), kUp);
// works !!! (camera is tilted up)
glm::mat4 camera_to_world_ = glm::inverse(glm::lookAtRH(origin_, glm::vec3(0.f, 0.2f, -1.f), kUp));
And function that generates camera rays
// Calculate ray as if camera is located at 0,0,0 and pointing into negative z direction
// Then transform ray direction to desired plase
// x,y - pixel coordinates of raster image
// calculate as if raster image (screen) is 1.0 unit away from origin (eye)
Ray Camera::GenRay(const uint32_t x, const uint32_t y) {
glm::vec3 ray_direction = kDirection;
// from raster space to NDC space
glm::vec2 pixel_ndc((x + 0.5f) / raster_width_, (y + 0.5f) / raster_height_);
// from NDC space to camera space
float scale = tan(fov_ / 2.0f);
ray_direction.x = (2.0f * pixel_ndc.x - 1.0f) * scale; // *aspect_ratio_;
ray_direction.y = (1.0f - 2.0f * pixel_ndc.y) * scale * aspect_ratio_;
// apply camera-to-world rotation matrix to direction
ray_direction = camera_to_world_ * glm::vec4(ray_direction, 0.0f);
return Ray(origin_, ray_direction, Ray::Type::kPrimary);
}
I really can't understand the root of a problem so any help us appreciated.