Compare commits
2 commits
38fd5264cd
...
8ec807c147
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ec807c147 | |||
| 993136ea9e |
4 changed files with 61 additions and 38 deletions
14
src/main.rs
14
src/main.rs
|
|
@ -9,7 +9,7 @@ use render::{World,Camera};
|
|||
use vec3::{Point3,Vec3};
|
||||
|
||||
use material::{Metal,Lambertian,Material};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
||||
fn main() {
|
||||
|
|
@ -21,21 +21,17 @@ fn main() {
|
|||
|
||||
|
||||
let m = Lambertian::new(Vec3::new(0.5,0.5,0.5));
|
||||
let b: Box <dyn Material> = Box::new(m);
|
||||
let world_m = std::rc::Rc::new(b);
|
||||
let world_m: Arc <dyn Material> = Arc::new(m);
|
||||
|
||||
let m = Lambertian::new(Vec3::new(0.1, 0.2, 0.5));
|
||||
let b: Box <dyn Material> = Box::new(m);
|
||||
let center_m = std::rc::Rc::new(b);
|
||||
let center_m: Arc <dyn Material> = Arc::new(m);
|
||||
|
||||
let m = Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.3);
|
||||
let b: Box <dyn Material> = Box::new(m);
|
||||
let left_m = std::rc::Rc::new(b);
|
||||
let left_m: Arc <dyn Material> = Arc::new(m);
|
||||
|
||||
|
||||
let m = Metal::new(Vec3::new(0.8, 0.6, 0.2), 0.5);
|
||||
let b: Box <dyn Material> = Box::new(m);
|
||||
let right_m = std::rc::Rc::new(b);
|
||||
let right_m: Arc <dyn Material> = Arc::new(m);
|
||||
|
||||
let mut camera = Camera::new(aspect_ratio,image_width,focal_length,viewport_height,camera_center);
|
||||
let mut world = World::new();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub struct Scatter {
|
|||
pub ray: Ray,
|
||||
}
|
||||
|
||||
pub trait Material {
|
||||
pub trait Material: Send + Sync {
|
||||
fn scatter(&self, r_in: &Ray, rec: &HitRecord, rng: &mut ThreadRng) -> Option<Scatter>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ use crate::vec3::{Point3, Ray, Vec3, Interval};
|
|||
use crate::material::{Material,Scatter};
|
||||
|
||||
use rand::prelude::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
||||
pub trait Hittable {
|
||||
pub trait Hittable: Send + Sync{
|
||||
fn hit(&self, ray: Ray, interval:Interval) -> Option<HitRecord>;
|
||||
}
|
||||
|
||||
|
|
@ -13,7 +14,7 @@ pub struct HitRecord {
|
|||
normal: Vec3,
|
||||
root: f64,
|
||||
front_face: bool,
|
||||
material: std::rc::Rc<Box<dyn Material>>,
|
||||
material: Arc<dyn Material>,
|
||||
}
|
||||
|
||||
impl HitRecord {
|
||||
|
|
@ -43,11 +44,11 @@ impl HitRecord {
|
|||
pub struct Sphere {
|
||||
radius: f64,
|
||||
center: Point3,
|
||||
material: std::rc::Rc<Box<dyn Material>>
|
||||
material: Arc<dyn Material>
|
||||
}
|
||||
|
||||
impl Sphere {
|
||||
pub fn new(radius: f64, center: Point3, material:std::rc::Rc<Box<dyn Material>>) -> Self {
|
||||
pub fn new(radius: f64, center: Point3, material: Arc<dyn Material>) -> Self {
|
||||
Sphere { radius, center , material}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
use crate::object::{HitRecord, Hittable};
|
||||
use crate::vec3::{Interval, Ray, Vec3, Point3};
|
||||
use crate::image::Image;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use rand::prelude::*;
|
||||
|
||||
pub struct World {
|
||||
pub objects: Vec<Box<dyn Hittable>>,
|
||||
pub objects: Vec<Arc<dyn Hittable>>,
|
||||
}
|
||||
|
||||
impl World {
|
||||
|
|
@ -16,7 +18,7 @@ impl World {
|
|||
}
|
||||
|
||||
pub fn add(&mut self, object: impl Hittable + 'static) {
|
||||
self.objects.push(Box::new(object));
|
||||
self.objects.push(Arc::new(object));
|
||||
}
|
||||
|
||||
pub fn hit(&self, ray: Ray, interval:Interval) -> Option<HitRecord> {
|
||||
|
|
@ -69,29 +71,53 @@ impl Camera {
|
|||
|
||||
|
||||
pub fn render(&mut self, world: &World){
|
||||
let thread_count = thread::available_parallelism().unwrap().get() as i32;
|
||||
let height = self.img.height;
|
||||
let width = self.img.width;
|
||||
let total_pixels = height*width;
|
||||
let num_samples = 5;
|
||||
|
||||
//cast to const ref
|
||||
let const_self = &*self;
|
||||
|
||||
let threads:Vec<Vec<((i32,i32),(f64,f64,f64))>> = thread::scope(|s|{
|
||||
(0..thread_count).map(|i|{
|
||||
s.spawn(move ||{
|
||||
let mut rng:ThreadRng = rand::rng();
|
||||
for y in 0..self.img.height {
|
||||
for x in 0..self.img.width {
|
||||
let start = (i*total_pixels)/thread_count;
|
||||
let end = ((i+1)*total_pixels)/thread_count;
|
||||
(start..end).map(|i|{
|
||||
let x = i%width;
|
||||
let y = i/width;
|
||||
let (mut r,mut g,mut b) = (0.0,0.0,0.0);
|
||||
let num_samples=10.0;
|
||||
let depth=10;
|
||||
for _ in 0..num_samples as i32{
|
||||
let ray = self.get_ray(x,y,&mut rng);
|
||||
let (tr,tg,tb)= trace(ray, &world,depth,&mut rng);
|
||||
let ray = const_self.get_ray(x,y,&mut rng);
|
||||
for _ in 0..num_samples{
|
||||
let (tr,tg,tb) = trace(ray, &world,10,&mut rng);
|
||||
r+=tr;
|
||||
g+=tg;
|
||||
b+=tb;
|
||||
}
|
||||
r /= num_samples;
|
||||
g /= num_samples;
|
||||
b /= num_samples;
|
||||
|
||||
r/=num_samples as f64;
|
||||
g/=num_samples as f64;
|
||||
b/=num_samples as f64;
|
||||
|
||||
r = r.clamp(0.0,1.0).sqrt();
|
||||
g = g.clamp(0.0,1.0).sqrt();
|
||||
b = b.clamp(0.0,1.0).sqrt();
|
||||
if let Some(px) = self.img.get_pixel(x,y){
|
||||
|
||||
((x,y),(r,g,b))
|
||||
}).collect::<Vec<_>>()
|
||||
})
|
||||
}).collect::<Vec<_>>().into_iter().map(|t|{t.join().unwrap()}).collect()
|
||||
});
|
||||
|
||||
for t in threads {
|
||||
for c in t {
|
||||
let ((x,y),rgb) = c;
|
||||
let px = self.img.get_pixel(x,y).unwrap();
|
||||
let (r,g,b)= rgb;
|
||||
px.set_color(r,g,b);
|
||||
} else{/*ignore*/}
|
||||
}
|
||||
}
|
||||
self.img.save("./foo.ppm").unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue