diff options
author | Keuin <[email protected]> | 2022-04-20 19:01:56 +0800 |
---|---|---|
committer | Keuin <[email protected]> | 2022-04-20 19:01:56 +0800 |
commit | bfc5e815e6e157291ad653b9ea97bb12ca8bc835 (patch) | |
tree | ff5eb194aeded46f10d50250b71c90bbc8ab875c /viewport.h | |
parent | e0d03c77578c244df2db42a0f0509a2ed16d02e6 (diff) |
Add vup (vector up), which controls the rotation of a camera (viewport). If vup is set to {0, 1, 0} (y=1), the camera should behave exactly the same as in previous versions.
Diffstat (limited to 'viewport.h')
-rw-r--r-- | viewport.h | 18 |
1 files changed, 11 insertions, 7 deletions
@@ -58,6 +58,7 @@ class basic_viewport { // double fov_h; // horizontal FOV, determined if screen_width or screen_height is known // double focus_length; // distance between the focus point and the image screen hitlist &world; + vec3<V> vup{0, 1, 0}; // vector determine the camera rotating public: basic_viewport(const vec3<V> &cxyz, const vec3<V> &screen_center, @@ -94,23 +95,26 @@ public: V bx, by; const auto r = screen_center - cxyz; const int img_hw = image_width / 2, img_hh = image_height / 2; + // screen plane is determined by coord system x`Vy`, where V is screen_center + // for variable name we let u := x`, v := y` + const auto u = cross(r, vup).unit_vec() * screen_hw, v = cross(u, r).unit_vec() * screen_hh; + assert(dot(u, v) < 1e-8); + assert(dot(u, r) < 1e-8); // iterate over every pixel on the image - for (int j = -img_hh + 1; j <= img_hh; ++j) { // axis y, transformation is needed + for (int j = -img_hh; j < img_hh; ++j) { // axis y, transformation is needed for (int i = -img_hw; i < img_hw; ++i) { // axis x bias(bx, by); // get a random bias (bx, by) for sub-pixel sampling assert(0 <= bx); assert(0 <= by); assert(bx < 1.0); assert(by < 1.0); - const vec3d off{ - .x=(1.0 * i + bx) / img_hw * screen_hw, - .y=(1.0 * j + by) / img_hh * screen_hh, - .z=0.0 - }; // offset on screen plane + const auto off_u = (1.0 * i + bx) / img_hw; + const auto off_v = (1.0 * j + by) / img_hh; + const auto off = off_u * u + off_v * v; // offset on screen plane const auto dir = r + off; // direction vector from camera to current pixel on screen ray3d ray{cxyz, dir}; // from camera to pixel (on the viewport) const auto pixel = world.color<U>(ray, ruvg); - const auto x_ = i + img_hw, y_ = -j + img_hh; + const auto x_ = i + img_hw, y_ = j + img_hh; image.set(x_, y_, pixel); #ifdef LOG_TRACE |