mirror of
https://github.com/MorizzG/ray-tracer.git
synced 2025-12-06 04:22:42 +00:00
made camera movable
This commit is contained in:
parent
dff32371d7
commit
97784e54ae
3 changed files with 100 additions and 21 deletions
107
src/camera.h
107
src/camera.h
|
|
@ -1,30 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "raytracer.h"
|
||||
#include "vec3.h"
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
constexpr Camera(Vec3 centre, u32 image_width, u32 image_height, f64 focal_length)
|
||||
: centre_{centre}, image_width_{image_width}, image_height_{image_height} {
|
||||
constexpr f64 viewport_height = 2.0;
|
||||
f64 viewport_width = viewport_height * static_cast<f64>(image_width) / image_height;
|
||||
|
||||
Vec3 u_viewport = viewport_width * Vec3::e_x;
|
||||
Vec3 v_viewport = -viewport_height * Vec3::e_y;
|
||||
|
||||
d_u_pixel_ = u_viewport / image_width;
|
||||
d_v_pixel_ = v_viewport / image_height;
|
||||
|
||||
// upper left of viewport: move from camera centre `focal_length` in z direction, then half
|
||||
// of the viewport length in x and y direction respectively
|
||||
auto viewport_upper_left =
|
||||
centre_ - focal_length * Vec3::e_z - u_viewport / 2 - v_viewport / 2;
|
||||
|
||||
pixel_00_ = viewport_upper_left + 0.5 * d_u_pixel_ + 0.5 * d_v_pixel_;
|
||||
constexpr Camera(Point3 centre, u32 image_width, u32 image_height, f64 focal_length)
|
||||
: centre_{centre},
|
||||
focal_length_{focal_length},
|
||||
image_width_{image_width},
|
||||
image_height_{image_height} {
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
constexpr Vec3 centre() const { return centre_; }
|
||||
// can be changed, need to recalculate parameters
|
||||
|
||||
constexpr Point3 centre() const { return centre_; }
|
||||
constexpr void centre(Point3 centre) {
|
||||
centre_ = centre;
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
constexpr Vec3 u() const { return u_; }
|
||||
constexpr Vec3 v() const { return v_; }
|
||||
constexpr Vec3 w() const { return w_; }
|
||||
|
||||
constexpr void look_at(Point3 look_at, Vec3 up = Vec3::e_y) {
|
||||
w_ = (look_at - centre_).normed();
|
||||
|
||||
v_ = (up - dot(up, w_) * w_).normed();
|
||||
|
||||
u_ = cross(v_, w_);
|
||||
|
||||
focal_length_ = (look_at - centre_).norm();
|
||||
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
constexpr void rotate(f64 deg) {
|
||||
f64 rad = deg2rad(deg);
|
||||
|
||||
Vec3 u = std::cos(rad) * u_ + std::sin(rad) * v_;
|
||||
Vec3 v = -std::sin(rad) * u_ + std::cos(rad) * v_;
|
||||
|
||||
u_ = u;
|
||||
v_ = v;
|
||||
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
constexpr f64 fov_angle_v() const { return fov_deg_v_; }
|
||||
constexpr void fov_angle_v(f64 fov) {
|
||||
fov_deg_v_ = fov;
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
// const-only accessors
|
||||
|
||||
constexpr Vec3 d_u_pixel() const { return d_u_pixel_; }
|
||||
constexpr Vec3 d_v_pixel() const { return d_v_pixel_; }
|
||||
|
|
@ -37,7 +70,43 @@ class Camera {
|
|||
}
|
||||
|
||||
private:
|
||||
Vec3 centre_;
|
||||
constexpr void Recalculate() {
|
||||
const f64 aspect_ratio = static_cast<f64>(image_width_) / image_height_;
|
||||
|
||||
f64 fov_rad_v = deg2rad(fov_deg_v_);
|
||||
f64 h = std::tan(fov_rad_v / 2);
|
||||
|
||||
// constexpr f64 viewport_height = 2.0;
|
||||
const f64 viewport_height = 2 * h * focal_length_;
|
||||
|
||||
f64 viewport_width = viewport_height * aspect_ratio;
|
||||
|
||||
Vec3 u_viewport = viewport_width * u_;
|
||||
Vec3 v_viewport = -viewport_height * v_;
|
||||
|
||||
d_u_pixel_ = u_viewport / image_width_;
|
||||
d_v_pixel_ = v_viewport / image_height_;
|
||||
|
||||
// upper left of viewport: move from camera centre half the viewport length in u and v
|
||||
// direction respectively and focal_length` in negative w direction
|
||||
auto viewport_upper_left = centre_ - u_viewport / 2 - v_viewport / 2 - focal_length_ * w_;
|
||||
|
||||
pixel_00_ = viewport_upper_left + 0.5 * d_u_pixel_ + 0.5 * d_v_pixel_;
|
||||
}
|
||||
|
||||
// settable camera parameters
|
||||
|
||||
Point3 centre_ = Vec3::origin;
|
||||
|
||||
Vec3 u_ = Vec3::e_x; // points to right of camera
|
||||
Vec3 v_ = Vec3::e_y; // points to up of camera
|
||||
Vec3 w_ = Vec3::e_z; // points backward of camera
|
||||
|
||||
f64 focal_length_;
|
||||
|
||||
f64 fov_deg_v_ = 80;
|
||||
|
||||
// saved camera properties
|
||||
|
||||
// position of pixel 0, 0
|
||||
Vec3 pixel_00_;
|
||||
|
|
|
|||
12
src/main.cc
12
src/main.cc
|
|
@ -27,7 +27,7 @@ int main(int /* argc */, char* /* argv */[]) {
|
|||
|
||||
auto mat_ground = std::make_shared<Lambertian>(Colour(0.8, 0.8, 0.0));
|
||||
auto mat_lamb = std::make_shared<Lambertian>(Colour(0.1, 0.2, 0.5));
|
||||
auto mat_metal = std::make_shared<Metal>(Colour(0.8, 0.6, 0.2), 0.0);
|
||||
auto mat_metal = std::make_shared<Metal>(Colour(0.9, 0.4, 0.6), 0.0);
|
||||
auto mat_dielec = std::make_shared<Dielectric>(1.5, 0.0);
|
||||
auto mat_dielec2 = std::make_shared<Dielectric>(0.66, 0.0);
|
||||
|
||||
|
|
@ -58,6 +58,16 @@ int main(int /* argc */, char* /* argv */[]) {
|
|||
|
||||
Camera camera{camera_centre, image_width, image_height, focal_length};
|
||||
|
||||
std::clog << camera.u() << newline;
|
||||
std::clog << camera.v() << newline;
|
||||
std::clog << camera.w() << newline << newline;
|
||||
|
||||
camera.look_at(Point3{0.8, 0.0, 1.0}, Vec3::e_x);
|
||||
|
||||
std::clog << camera.u() << newline;
|
||||
std::clog << camera.v() << newline;
|
||||
std::clog << camera.w() << newline << newline;
|
||||
|
||||
// render
|
||||
|
||||
Renderer renderer{camera};
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ constexpr f64 dot(const Vec3& u, const Vec3& v) {
|
|||
|
||||
constexpr Vec3 cross(const Vec3& u, const Vec3& v) {
|
||||
return {u.y() * v.z() - u.z() - v.y(), u.z() * v.x() - u.x() * v.z(),
|
||||
u.x() * v.y() - u.y() - v.x()};
|
||||
u.x() * v.y() - u.y() * v.x()};
|
||||
}
|
||||
|
||||
constexpr f64 Vec3::squared() const { return dot(*this, *this); }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue