implement rays, lots of new stuff
This commit is contained in:
parent
21c92685a5
commit
87867df2d8
7 changed files with 540110 additions and 65562 deletions
90004
image2.ppm
Normal file
90004
image2.ppm
Normal file
File diff suppressed because it is too large
Load diff
6
src/color.rs
Normal file
6
src/color.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
use std::io::Write;
|
||||
use super::Color;
|
||||
|
||||
pub fn write_color(out: &mut impl Write, pixel_color: Color) {
|
||||
write!(out, "{} {} {}\n", (255.999*pixel_color.x()) as u32, (255.999*pixel_color.y()) as u32, (255.999*pixel_color.z()) as u32).unwrap();
|
||||
}
|
85
src/main.rs
85
src/main.rs
|
@ -1,28 +1,79 @@
|
|||
mod vec3;
|
||||
mod color;
|
||||
mod ray;
|
||||
use vec3::Vec3;
|
||||
use vec3::Color;
|
||||
use vec3::Point3;
|
||||
use ray::Ray;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::BufWriter;
|
||||
use std::io::Write;
|
||||
|
||||
fn hit_sphere(center: &Point3, radius: f64, r: &Ray) -> f64 {
|
||||
let oc = r.origin() - *center;
|
||||
let a = Vec3::dot(r.direction(), r.direction());
|
||||
let b = 2.0 * Vec3::dot(oc, r.direction());
|
||||
let c = Vec3::dot(oc, oc) - radius*radius;
|
||||
let discriminant = b*b - 4.0*a*c;
|
||||
|
||||
if discriminant < 0.0 {
|
||||
return -1.0;
|
||||
} else {
|
||||
return (-b - discriminant.sqrt()) / (2.0*a);
|
||||
}
|
||||
}
|
||||
|
||||
fn ray_color(r: &Ray) -> Color{
|
||||
let t = hit_sphere(&Point3::new(0.0, 0.0, -1.0), 0.5, r);
|
||||
if t > 0.0 {
|
||||
let n = Vec3::unit_vector(r.at(t) - Vec3::new(0.0, 0.0, -1.0));
|
||||
return 0.5*Color::new(n.x()+1.0, n.y()+1.0, n.z()+1.0);
|
||||
}
|
||||
|
||||
let unit_direction = r.direction();
|
||||
let t = 0.5*(unit_direction.y() + 1.0);
|
||||
return (1.0-t)*Color::new(1.0,1.0,1.0) + t*Color::new(0.5,0.7,1.0);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let image_width = 256;
|
||||
let image_height = 256;
|
||||
|
||||
println!("P3\n{image_width} {image_height}\n255\n");
|
||||
// File
|
||||
let mut default_file = "image.ppm";
|
||||
|
||||
for i in (0..image_height).rev() {
|
||||
eprint!("\rScanlines remaining: {i:5}");
|
||||
for j in 0..image_width {
|
||||
let r = j as f32 / (image_width - 1) as f32;
|
||||
let g = i as f32 / (image_height - 1) as f32;
|
||||
let b = 0.25;
|
||||
// Image
|
||||
let aspect_ratio = 16.0 / 9.0;
|
||||
let image_width = 800;
|
||||
let image_height = (image_width as f64 / aspect_ratio) as u64;
|
||||
|
||||
let ir = (255.999 * r) as u32;
|
||||
let ig = (255.999 * g) as u32;
|
||||
let ib = (255.999 * b) as u32;
|
||||
// Camera
|
||||
let viewport_height = 2.0;
|
||||
let viewport_width = aspect_ratio * viewport_height;
|
||||
let focal_length = 1.0;
|
||||
|
||||
println!("{ir} {ig} {ib}");
|
||||
let origin = Point3::new(0.0,0.0,0.0);
|
||||
let horizontal = Vec3::new(viewport_width, 0.0, 0.0);
|
||||
let vertical = Vec3::new(0.0, viewport_height, 0.0);
|
||||
let lower_left_corner = origin - horizontal/2.0 - vertical/2.0 - Vec3::new(0.0, 0.0, focal_length);
|
||||
|
||||
// Render
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() > 1 && args[1] != "" {
|
||||
default_file = &args[1];
|
||||
}
|
||||
let mut file = BufWriter::new(File::create(default_file).unwrap());
|
||||
writeln!(&mut file,"P3\n{image_width} {image_height}\n255\n").unwrap();
|
||||
|
||||
for j in (0..image_height).rev() {
|
||||
eprint!("\rScanlines remaining: {j:5}");
|
||||
for i in 0..image_width {
|
||||
let u = i as f64 / (image_width-1) as f64;
|
||||
let v = j as f64 / (image_height-1) as f64;
|
||||
let r = Ray::new(origin, lower_left_corner + u*horizontal + v*vertical - origin);
|
||||
let pixel_color = ray_color(&r);
|
||||
|
||||
color::write_color(&mut file, pixel_color);
|
||||
}
|
||||
}
|
||||
eprintln!("\nDone!");
|
||||
|
||||
let v = Vec3::new(1.0,2.0,3.0);
|
||||
println!("{:?}",v)
|
||||
}
|
||||
}
|
25
src/ray.rs
Normal file
25
src/ray.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use super::Point3;
|
||||
use super::Vec3;
|
||||
|
||||
pub struct Ray {
|
||||
pub orig: Point3,
|
||||
pub dir: Vec3
|
||||
}
|
||||
|
||||
impl Ray {
|
||||
pub fn new(o: Point3, d: Vec3) -> Ray {
|
||||
Ray { orig: o, dir: d }
|
||||
}
|
||||
|
||||
pub fn origin(&self) -> Point3 {
|
||||
self.orig
|
||||
}
|
||||
|
||||
pub fn direction(&self) -> Vec3 {
|
||||
self.dir
|
||||
}
|
||||
|
||||
pub fn at(&self, t: f64) -> Point3 {
|
||||
self.orig + t*self.dir
|
||||
}
|
||||
}
|
10
src/vec3.rs
10
src/vec3.rs
|
@ -1,16 +1,14 @@
|
|||
use std::ops::*;
|
||||
use std::io::Write;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Vec3 {
|
||||
pub e: [f64; 3],
|
||||
}
|
||||
|
||||
type Color = Vec3;
|
||||
type Point3 = Vec3;
|
||||
pub type Color = Vec3;
|
||||
pub type Point3 = Vec3;
|
||||
|
||||
impl Vec3 {
|
||||
|
||||
pub fn new(x: f64, y: f64, z: f64) -> Self {
|
||||
Vec3 { e: [x, y, z] }
|
||||
}
|
||||
|
@ -106,8 +104,4 @@ impl Div<f64> for Vec3 {
|
|||
fn div(self, rhs: f64) -> Vec3 {
|
||||
Vec3::new(self.x()/rhs, self.y()/rhs, self.z()/rhs)
|
||||
}
|
||||
}
|
||||
|
||||
fn write_color(out: &mut impl Write, pixel_color: Color) {
|
||||
write!(out, "{} {} {}\n", 255.999*pixel_color.x(), 255.999*pixel_color.y(), 255.999*pixel_color.z());
|
||||
}
|
Loading…
Reference in a new issue