0205-增加景深

环境

  • Time 2022-11-17
  • WSL-Ubuntu 22.04
  • Rust 1.65.0

前言

说明

参考:https://raytracing.github.io/books/RayTracingInOneWeekend.html

目标

在相机不对焦的地方,会出现模糊效果,这一节实现这种效果。

vector3.rs

    pub fn random_in_unit_disk() -> Vector3 {
        let mut rand = rand::thread_rng();
        loop {
            let p = Vector3::new(rand.gen_range(-1.0..1.0), rand.gen_range(-1.0..1.0), 0.0);
            if p.length() < 1.0 {
                return p;
            }
        }
    }

camera.rs

use super::ray::Ray;
use super::vector3::{Point3, Vector3};

pub struct Camera {
    origin: Point3,
    corner: Point3,
    horizontal: Vector3,
    vertical: Vector3,
    cu: Vector3,
    cv: Vector3,
    radius: f64,
}

pub const RATIO: f64 = 16.0 / 9.0;

impl Camera {
    pub fn new(
        origin: Point3,
        at: Point3,
        vup: Vector3,
        fov: f64,
        ratio: f64,
        aperture: f64,
        focus: f64,
    ) -> Camera {
        let theta = std::f64::consts::PI / 180.0 * fov;
        let viewport_height = 2.0 * (theta / 2.0).tan();
        let viewport_width = ratio * viewport_height;

        let cw = (origin - at).unit();
        let cu = vup.cross(cw);
        let cv = cw.cross(cu);

        let horizontal = focus * viewport_width * cu;
        let vertical = focus * viewport_height * cv;

        let corner = origin - horizontal / 2.0 - vertical / 2.0 - focus * cw;

        Camera {
            origin,
            horizontal,
            vertical,
            corner,
            cu,
            cv,
            radius: aperture / 2.0,
        }
    }

    pub fn get_ray(&self, u: f64, v: f64) -> Ray {
        let rd = self.radius * Vector3::random_in_unit_disk();
        let offset = self.cu * rd.x + self.cv * rd.y;
        let vector3 = self.corner + u * self.horizontal + v * self.vertical;

        Ray {
            origin: self.origin + offset,
            direction: vector3 - self.origin - offset,
        }
    }
}

相机

    // 相机
    let from = Point3::new(3.0, 3.0, 2.0);
    let at = Point3::new(0.0, 0.0, -1.0);
    let camera = Camera::new(
        from,
        at,
        Vector3::new(0.0, 1.0, 0.0),
        20.0,
        camera::RATIO,
        2.0,
        (from - at).length(),
    );

效果

景深

总结

实现了景深效果。

附录

posted @ 2024-07-22 09:23  波尔  阅读(5)  评论(0编辑  收藏  举报