6.3.An Abstraction for Hittable Objects
This commit is contained in:
parent
b89ad6932d
commit
3fbe40c149
|
@ -0,0 +1,7 @@
|
|||
use crate::types_defined::Color;
|
||||
|
||||
impl Color {
|
||||
pub fn to_color(self) -> String {
|
||||
return format!("{} {} {}\n", (self.x * 256.0) as u8, (self.y * 256.0) as u8, (self.z * 256.0) as u8);
|
||||
}
|
||||
}
|
53
src/image.rs
53
src/image.rs
|
@ -1,14 +1,7 @@
|
|||
use crate::{point::Point, ray::Ray, vec3::{self, Vec3}};
|
||||
use crate::hittable::Hittable;
|
||||
use crate::types_defined::{Color, Point, Ray, Sphere, Vec3};
|
||||
|
||||
|
||||
pub type Color = vec3::Vec3;
|
||||
|
||||
|
||||
impl Color {
|
||||
pub fn to_color(self) -> String {
|
||||
return format!("{} {} {}\n", (self.x * 256.0) as u8, (self.y * 256.0) as u8, (self.z * 256.0) as u8);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gen_ray_sphere_normal_ppm_p3(width: i32, height: i32, camera_center: Vec3, viewport_top_left_pixel_center: Vec3, viewport_u_delta: Vec3, viewport_v_delta: Vec3) -> String {
|
||||
let mut img_content = format!("P3\n{} {}\n255\n", width, height);
|
||||
|
@ -26,15 +19,15 @@ pub fn gen_ray_sphere_normal_ppm_p3(width: i32, height: i32, camera_center: Vec3
|
|||
let ray_direction = pixel_center - camera_center;
|
||||
// ray
|
||||
let r = Ray::new(camera_center, ray_direction);
|
||||
|
||||
/*
|
||||
球
|
||||
*/
|
||||
let _sphere_center = Point::new(0.0, 0.0, -1.0);
|
||||
let sphere_radius = 0.5;
|
||||
let sphere = Sphere::new(_sphere_center, sphere_radius);
|
||||
|
||||
// determind color
|
||||
let color = ray_color_at_sphere_normal(&r, _sphere_center, sphere_radius);
|
||||
let color = ray_color(&r, sphere);
|
||||
// content
|
||||
img_content.push_str(color.to_color().as_str());
|
||||
img_content.push('\n');
|
||||
|
@ -44,45 +37,19 @@ pub fn gen_ray_sphere_normal_ppm_p3(width: i32, height: i32, camera_center: Vec3
|
|||
img_content
|
||||
}
|
||||
|
||||
fn hit_sphere_normal(r: &Ray, sphere_center: Point, sphere_radius: f32) -> f32 {
|
||||
let a: f32 = r.direction.length_squared();
|
||||
let h = r.direction.dot(sphere_center - r.point);
|
||||
// let b = -2.0 * r.direction.dot(sphere_center - r.point);
|
||||
let c = (sphere_center - r.point).length_squared() - sphere_radius * sphere_radius;
|
||||
|
||||
let discriminant = h*h - a*c;
|
||||
|
||||
// // 两个焦点
|
||||
let disc_sqrt = discriminant.sqrt();
|
||||
let near = (h - disc_sqrt) / a;
|
||||
let far = (h + disc_sqrt) / a;
|
||||
|
||||
// 射线起点可能在球内的情况
|
||||
if near >= 0.0 && far >= 0.0 {
|
||||
return near.min(far);
|
||||
} else if near > 0.0 {
|
||||
return near;
|
||||
} else if far > 0.0 {
|
||||
return far;
|
||||
} else {
|
||||
return -1.0
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ray color functions
|
||||
*/
|
||||
fn ray_color_at_sphere_normal(r: &Ray, sphere_center: Point, sphere_radius: f32) -> Color {
|
||||
|
||||
let t = hit_sphere_normal(r, sphere_center, sphere_radius);
|
||||
if t >= 0.0 {
|
||||
let inter_point = r.at(t);
|
||||
fn ray_color<H: Hittable>(r: &Ray, h: H) -> Color {
|
||||
let hr = h.hit(&r, 0.0, f32::MAX);
|
||||
if hr.t >= 0.0 {
|
||||
let inter_point = hr.p;
|
||||
// 单位向量
|
||||
let n = inter_point / inter_point.dot(inter_point);
|
||||
// 法向量也是 -1~1 +1再x0.5让他落到颜色的区间
|
||||
return 0.5 * (n - sphere_center + Point::new(1.0, 1.0, 1.0))
|
||||
// return 0.5 * (n - sphere_center + Point::new(1.0, 1.0, 1.0))
|
||||
return 0.5 * (hr.normal + Point::new(1.0, 1.0, 1.0))
|
||||
}
|
||||
|
||||
// v / |v|
|
||||
let unit_direction = r.direction / r.direction.length();
|
||||
let a = 0.5*(unit_direction.y + 1.0);
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use write_file_util::{write_image};
|
||||
use vec3::{Vec3};
|
||||
use point::{Point};
|
||||
|
||||
use crate::image::{gen_ray_sphere_normal_ppm_p3};
|
||||
|
||||
use crate::types_defined::{Point, Vec3};
|
||||
mod image;
|
||||
mod write_file_util;
|
||||
mod vec3;
|
||||
mod point;
|
||||
mod ray;
|
||||
mod hittable;
|
||||
mod sphere;
|
||||
mod types_defined;
|
||||
mod color;
|
||||
|
||||
fn main() {
|
||||
ray_sphere_normal_scene_render();
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
use crate::vec3;
|
||||
|
||||
pub type Point = vec3::Vec3;
|
||||
|
13
src/ray.rs
13
src/ray.rs
|
@ -1,17 +1,6 @@
|
|||
use std::fmt;
|
||||
use std::fmt::{Display};
|
||||
|
||||
use crate::{point::Point, vec3::Vec3};
|
||||
|
||||
|
||||
/*
|
||||
fn: P(t) = t*b
|
||||
*/
|
||||
#[derive(Debug)]
|
||||
pub struct Ray {
|
||||
pub point: Point,
|
||||
pub direction: Vec3
|
||||
}
|
||||
use crate::types_defined::{Point, Ray, Vec3};
|
||||
|
||||
impl Ray {
|
||||
pub fn new(p: Point, direction: Vec3) -> Ray {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* [3]
|
||||
*/
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Vec3 {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub z: f32,
|
||||
}
|
||||
pub type Point = Vec3;
|
||||
pub type Color = Vec3;
|
||||
|
||||
/*
|
||||
fn: P(t) = t*b
|
||||
*/
|
||||
#[derive(Debug)]
|
||||
pub struct Ray {
|
||||
pub point: Point,
|
||||
pub direction: Vec3
|
||||
}
|
||||
|
||||
pub struct HitRecord {
|
||||
pub t: f32,
|
||||
pub p: Vec3,
|
||||
pub normal: Vec3,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/////////////
|
||||
// for test
|
||||
/////////////
|
||||
*/
|
||||
pub struct Sphere {
|
||||
pub center: Point,
|
||||
pub radius: f32,
|
||||
}
|
10
src/vec3.rs
10
src/vec3.rs
|
@ -1,15 +1,7 @@
|
|||
|
||||
use std::{fmt::Display, ops::{Add, AddAssign, Div, Mul, MulAssign, Sub}};
|
||||
use std::fmt;
|
||||
/*
|
||||
* [3]
|
||||
*/
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Vec3 {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub z: f32,
|
||||
}
|
||||
use crate::types_defined::Vec3;
|
||||
|
||||
impl Display for Vec3 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
|
Loading…
Reference in New Issue