锅炉信息网 > 锅炉知识 > 锅炉资讯

14 相机

发布时间:

目标完善相机类,支持视野(fov),位置,朝向和散焦模糊。第八版渲染器结构如下:光源:无。场景:地面,一个漫反射材质的球,一个金属球,一个中空玻

目标

完善相机类,支持视野(fov),位置,朝向和散焦模糊。第八版渲染器结构如下:

  • 光源:无。
  • 场景:地面,一个漫反射材质的球,一个金属球,一个中空玻璃球。
  • 摄像机:参数可调。
  • 光线:每像素16个。
  • 渲染算法:光线多次弹射,颜色依据物体材质计算。
  • 输出:400 * 225像素的无锯齿图像。

数学模型

视野

  • 视野指一个镜头能覆盖的范围,用角度来表示。
  • 根据视野和焦距,可以求出视窗大小。

位置和朝向

  • 相机的位置和朝向决定了如何将相机坐标变换到世界坐标系中。
  • 相机坐标系的原点映射到世界坐标系的相机位置(lookfrom)。
  • 相加坐标系的z轴映射到-w,也就是lookfrom - lookat
  • x轴映射到u
  • y轴映射到v
  • 一般指定一个相机朝上的大概方向vup,然后计算与wvup所在平面垂直的朝右方向u,再利用wu的叉积求出v

散焦模糊

  • 真实相机不是完美的小孔,只能清晰成像景深范围内的物体。
  • 渲染器的镜头是完美的小孔,需要模拟镜头模糊效果。

计算模型

  • 添加新参数到Camera类。
  • 修改坐标变换
  • 光线起点做随机偏移,模拟焦散。

代码

camera.rs

  1. 根据fov和焦距求出视窗尺寸
  2. 求出uvw向量
  3. 将相机坐标系映射到世界坐标系下。
  4. 在光圈范围内随机一个发射点,从这里发射光线到成像平面

use crate::math::random;nuse crate::math::ray;nuse crate::math::vector;npub struct Camera {n origin: vector::Point3,n lower_left_corner_world: vector::Point3,n horizontal: vector::Point3,n vertical: vector::Point3,n u : vector::Point3,n v : vector::Point3,n lens_radius: f64,n}nimpl Camera {n pub fn new(n look_from: vector::Point3,n look_at: vector::Point3,n vup: vector::Dir3,n vfov: f64,n aspect_ratio: f64,n aperture: f64,n focus_dist: f64,n ) -> Camera {n // 1n let theta = vfov * std::f64::consts::PI / 180.0;n let h = (theta * 0.5).tan() * focus_dist;n let viewport_height = 2.0 * h;n let viewport_width = viewport_height * aspect_ratio;n // 2 n let mut w = look_from.clone() - look_at;n w.normalize();n let mut u = vector::Vec3::cross(&vup, &w);n u.normalize();n let v = vector::Vec3::cross(&w, &u);n // 3n let horizontal = u.clone() * viewport_width;n let vertical = v.clone() * viewport_height;n let origin = look_from;n let lower_left_corner_view =n -horizontal.clone() / 2.0 - vertical.clone() / 2.0 - w * focus_dist;n let lower_left_corner_world = origin.clone() + lower_left_corner_view;n Camera {n origin: origin,n lower_left_corner_world: lower_left_corner_world,n horizontal: horizontal,n vertical: vertical,n u : u,n v : v,n lens_radius: aperture / 2.0,n }n }n pub fn get_ray(&self, s: f64, t: f64) -> ray::Ray {n // 4n let rd = Camera::random_in_unit_disk() * self.lens_radius;n let offset = self.u.clone() * rd.x() + self.v.clone() * rd.y();n let p = self.lower_left_corner_world.clone()n + self.horizontal.clone() * sn + self.vertical.clone() * t;n let dir = p - &self.origin - &offset;n ray::Ray::new(self.origin.clone() + offset, dir)n }n fn random_in_unit_disk() -> vector::Vec3 {n loop {n let p = vector::Vec3::new(n random::generate_range(-1.0, 1.0),n random::generate_range(-1.0, 1.0),n 0.0,n );n if p.length_squared() < 1.0 {n return p;n }n }n }n

main.rs

设置参数

let look_from = vector::Point3::new(3.0, 3.0, 2.0);n let look_at = vector::Point3::new(0.0, 0.0, -1.0);n let focus_dist = (look_from.clone() - &look_at).length();n let cam = camera::Camera::new(look_from, look_at, vector::Dir3::new(0.0, 1.0, 0.0), 20.0, aspect_ratio, 2.0, focus_dist);n

完整代码

https://github.com/thomation/rePleuX/releases/tag/v0.0.8

运行结果

挑战

  • 修改main.rs中的camera参数,观察运行结果的变化
  • 修改第4章的矩阵,加入相机的位置和朝向。

延伸阅读

《Ray Tracing in One Weekend》11

《Ray Tracing in One Weekend》 12

上一篇:14线

下一篇:漂亮的矿物14

精选推荐

  • 如何正确选择白板供应商
    如何正确选择白板供应商

    目前在无锡想采购一块白板不管是实体店铺,还是网络平台都有很多选择,想要到专业的无锡白板公司采购还需要掌握一定的方式技巧。现

  • 柴油发电机组供应商
    柴油发电机组供应商

      t 扬州华东动力机械有限公司,位于江苏省扬州市江都区仙城工业园,是专业从事发电机、柴油及燃气发电机组研发、制造、销售、服务于

  • 高温辐射炉
    高温辐射炉

    5.2.2高温辐射炉5.2.2.1温度控制★(1)样品温度范围:常温~1400℃。★(2)均温区:长度不小于80mm。★(3)中心区:长度不小于10mm。(4)温度梯度(均

  • 高压锅在什么情况下会爆炸?
    高压锅在什么情况下会爆炸?

    近日,多地发生高压锅爆炸事故,给不少家庭带来了伤害和财产损失。那么,什么情况下会导致高压锅爆炸呢?首先,当高压锅内部压力过高时,如果

0