【Ray Tracing in One Weekend】(ch10)Positionable camera

来源:互联网 发布:python 2.7 转2.6 编辑:程序博客网 时间:2024/06/03 09:54

Chapter 10: Positionable camera

我们之前的 Camera 是被固定的,放在坐标原点的,写死的 Camera,现在我们要做一个可以随意改变位置的 Camera。

先来回忆一下之前是如何表示 Camera 的:

这里写图片描述

从一点(origin),看向一个平面(z=-1),同时用u、v乘以两个向量(horizontal、vertical),并以左下角(lower_left_corner)为原点来定位平面上任一点,Ray 就由这几个参数来确定:

Ray getRay(float u, float v) {    return Ray(origin, lower_left_corner + u*horizontal + v*vertical - origin);}

当时定义:

vec3 lower_left_corner(-2.0, -1.0, -1.0);vec3 horizontal(4.0, 0.0, 0.0);vec3 vertical(0.0, 2.0, 0.0);

现在,我们要为 Camera 定义新的参数来表示上面的值,首先引入张角 theta 和画面宽高比 aspect:

这里写图片描述

设整个画面的高为 height,则半高为 half_height,宽为 width,半宽为 half_width。

则有:

half_height = tan(theta/2);half_width = aspect * half_height;vec3 lower_left_corner(-half_width, -half_height,-1.0);vec3 horizontal(2*half_width, 0.0, 0.0);vec3 vertical(0.0, 2*half_height, 0.0);

现在我们仅仅是用新的参数 theta 和 aspect 表示了原来的 Camera,现在想把 Camera 架设到任意位置上,还需要引入 lookfrom(相机位置),lookat(相机看向的点),以及view of up(即表示相机正上的向量)。

可以先确定一个最容易理解的:

origin = lookfrom;

接着看看我们还需要什么来确定画面所在的“平面”,我们还需要一个指向相机正前方的向量,以确定平面的位置:

w = unit_vector(lookfrom - lookat);

垂直于 w 与 view of up(简写为vup)的向量即为“平面上”横向的向量,垂直于横向向量与 w 的向量即为竖向向量。

u = unit_vector(cross(vup, w));v = cross(w, u);

综上,可由此五个参数,确定如下四个值:

origin = lookfrom;lower_left_corner = origin - half_width*u - half_height*v - w;horizontal = 2 * half_width*u;vertical = 2 * half_height*v;

如此一来,新的 Camera 类就写好啦~ 代码如下:

#pragma once#define _USE_MATH_DEFINES#include "Ray.h"#include <math.h>class Camera {public:    //vfov: top to bottom in degrees    Camera(Vec3 lookfrom, Vec3 lookat, Vec3 vup, float vfov, float aspect)    {        Vec3 u, v, w;        float theta = vfov*M_PI / 180;        float half_height = tan(theta / 2);        float half_width = aspect * half_height;        origin = lookfrom;        w = unit_vector(lookfrom - lookat);        u = unit_vector(cross(vup, w));        v = cross(w, u);        lower_left_corner = origin - half_width*u - half_height*v - w;        horizontal = 2 * half_width*u;        vertical = 2 * half_height*v;    }    Ray getRay(float u, float v)     {        return Ray(origin, lower_left_corner + u*horizontal + v*vertical - origin);    }    Vec3 lower_left_corner;    Vec3 origin;    Vec3 horizontal;    Vec3 vertical;};

同时修改main方法:

    Hitable *list[5];    list[0] = new Sphere(Vec3(0.0f, 0.0f, -1.0f), 0.5f, new Lambertian(Vec3(0.8f, 0.3f, 0.3f)));    list[1] = new Sphere(Vec3(0.0f, -100.5f, -1.0f), 100.0f, new Lambertian(Vec3(0.8f, 0.8f, 0.0f)));    list[2] = new Sphere(Vec3(1.0f, 0.0f, -1.0f), 0.5f, new Metal(Vec3(0.8f, 0.6f, 0.2f), 0.3f));    list[3] = new Sphere(Vec3(-1.0f, 0.0f, -1.0f), 0.5f, new Dielectric(1.5f));    list[4] = new Sphere(Vec3(-1.0f, 0.0f, -1.0f), 0.5f, new Dielectric(1.5f));    Hitable *world = new HitableList(list, 5);    Camera cam(Vec3(-2.0f,2.0f,1.0f), Vec3(0.0f,0.0f,-1.0f), Vec3(0.0f,1.0f,0.0f), 90, float(nx)/float(ny));

fov为90时,所得图片如下:

这里写图片描述

fov为40时,所得图片如下:

这里写图片描述

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 东风面包车报价及图片 东风风神面包车 东风日产七座 东风日产7座家用车 东风菱智商务车七座 东风7座商务车 东风风神汽车 东风日产商务车7座 东风商务车七座 东风风神7座商务车 东风商务面包车 东风630车七座车图片 东风商务车7座报价 东风风行七座商务车 东风日产mpv七座车 东风日产7座商务车 东风七座车报价和图片 东风日产七座商务车 东风七座商务车 东风汽车报价 东风天龙报价 东风汽车七座全部车型 东风轿车全部车型 东风越野车报价及图片 东风风度mx7图片 东风suv所有车型报价 东风汽车全部车型 东风风度mx6论坛 东风系列车型报价及图片 东风x6报价图片 东风风度mx5价格 东风系列车型 东风suv所有车型 东风轿车价格及图片 东风风度mx6价格 东风汽车报价及图片 东风卡车全部车型 东风风度mx6怎么样 东风天锦180裸车报价 东风汽车图片 东风汽车报价5到8万