diff --git a/src/image.rs b/src/image.rs index c5a5515..f18b0bf 100644 --- a/src/image.rs +++ b/src/image.rs @@ -1,4 +1,4 @@ -use crate::vec3; +use crate::{ray::Ray, vec3::{self, Vec3}}; pub type Color = vec3::Vec3; @@ -10,6 +10,40 @@ impl Color { } } +pub fn gen_ray_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); + + for j in 0..height { + println!("scan line {}/{} ", j + 1, height); + for i in 0..width { + // every pixcel's position + let pixel_center = viewport_top_left_pixel_center + (i as f32 * viewport_u_delta) + (j as f32 * viewport_v_delta); + // Vector(camera, pixcel) + let ray_direction = pixel_center - camera_center; + // ray + let r = Ray::new(camera_center, ray_direction); + // determind color + let color = ray_color(r); + + // content + img_content.push_str(color.to_color().as_str()); + img_content.push('\n'); + } + } + + img_content +} + +/* +get color of this ray; background +*/ +fn ray_color(r: Ray) -> Color { + // v / |v| + let unit_direction = r.direction / r.direction.length(); + let a = 0.5*(unit_direction.y + 1.0); + return (1.0-a)*Color::new(1.0, 1.0, 1.0) + a*Color::new(0.5, 0.7, 1.0); +} + /* * -------width(i)------- diff --git a/src/main.rs b/src/main.rs index 2dccd4d..1a15395 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use write_file_util::{write_image}; -use image::{gen_gradient_ppm_p3, Color}; +use image::{gen_gradient_ppm_p3, gen_ray_ppm_p3, Color}; use vec3::{Vec3}; use point::{Point}; use ray::{Ray}; @@ -14,6 +14,7 @@ fn main() { gen_gradient_ppm(); println!("=================================="); ray_scene_render(); + println!("=================================="); } @@ -26,7 +27,31 @@ fn ray_scene_render() { let viewport_height = 2.0; let viewport_width = viewport_height * (image_width as f32 / image_height as f32); - println!("set image({},{}), viewport({},{})", image_width, image_height, viewport_width, viewport_height) + println!("set image({},{}), viewport({},{})", image_width, image_height, viewport_width, viewport_height); + let viewport_u = Vec3::new(viewport_width, 0.0, 0.0); + // image x--> right + // | + // y + // space: y up , x right , z back, -z front + let viewport_v = Vec3::new(0.0, -viewport_height, 0.0); + + // width per pix + let viewport_u_delta = viewport_u / (image_width as f32); + // height per pix + let viewport_v_delta = viewport_v / (image_height as f32); + + // camerea position + let camera_center = Point::new(0.0, 0.0, 0.0); + // -z 1.0 viewport to camera + let focal_length = Vec3::new(0.0, 0.0, -1.0); + // camera position --> viewport center ---> top center --> top left + let viewport_top_left_pixel = camera_center + focal_length - viewport_u / 2.0 - viewport_v / 2.0; + // padding 0.5* delta u/v + let viewport_top_left_pixel_center = viewport_top_left_pixel - viewport_u_delta / 2.0 - viewport_v_delta / 2.0; + + let ppm_content = gen_ray_ppm_p3(image_width, image_height, camera_center, viewport_top_left_pixel_center, viewport_u_delta, viewport_v_delta); + + write_image(ppm_content, "./target/ray_scene_render.ppm".to_string()) } @@ -45,5 +70,5 @@ fn gen_gradient_ppm() { let ray = Ray::new(Point::new(1.0, 1.0, 1.0), Vec3 { x: 0.0, y: 1.0, z: 0.0 }); println!("Ray: {:#} => {:#}", ray, ray.at(2.0)); - write_image(ppm_content, "./target/test.ppm".to_string()) + write_image(ppm_content, "./target/gen_gradient_ppm.ppm".to_string()) } \ No newline at end of file diff --git a/src/ray.rs b/src/ray.rs index f187f2e..17d04a8 100644 --- a/src/ray.rs +++ b/src/ray.rs @@ -9,8 +9,8 @@ fn: P(t) = t*b */ #[derive(Debug)] pub struct Ray { - point: Point, - direction: Vec3 + pub point: Point, + pub direction: Vec3 } impl Ray { diff --git a/src/vec3.rs b/src/vec3.rs index 99f26b0..6b2ba95 100644 --- a/src/vec3.rs +++ b/src/vec3.rs @@ -35,6 +35,15 @@ impl Vec3 { z: self.x * other.y - self.y * other.x, } } + + pub fn length_squared(self) -> f32 { + return self.x * self.x + self.y * self.y + self.z * self.z; + } + + pub fn length(self) -> f32 { + return self.length_squared().sqrt(); + } + } impl Add for Vec3 {