Add Rainbow material based on normal
This commit is contained in:
		
							parent
							
								
									acbb572dcd
								
							
						
					
					
						commit
						c787724541
					
				
					 4 changed files with 132 additions and 15 deletions
				
			
		
							
								
								
									
										76
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										76
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| 
						 | 
					@ -61,6 +61,20 @@ version = "1.1.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
 | 
					checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "console"
 | 
				
			||||||
 | 
					version = "0.15.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "encode_unicode",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "once_cell",
 | 
				
			||||||
 | 
					 "terminal_size",
 | 
				
			||||||
 | 
					 "unicode-width",
 | 
				
			||||||
 | 
					 "winapi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "crc32fast"
 | 
					name = "crc32fast"
 | 
				
			||||||
version = "1.3.2"
 | 
					version = "1.3.2"
 | 
				
			||||||
| 
						 | 
					@ -130,6 +144,12 @@ version = "1.7.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
 | 
					checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "encode_unicode"
 | 
				
			||||||
 | 
					version = "0.3.6"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "getrandom"
 | 
					name = "getrandom"
 | 
				
			||||||
version = "0.2.7"
 | 
					version = "0.2.7"
 | 
				
			||||||
| 
						 | 
					@ -165,6 +185,17 @@ dependencies = [
 | 
				
			||||||
 "png",
 | 
					 "png",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "indicatif"
 | 
				
			||||||
 | 
					version = "0.17.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "fcc42b206e70d86ec03285b123e65a5458c92027d1fb2ae3555878b8113b3ddf"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "console",
 | 
				
			||||||
 | 
					 "number_prefix",
 | 
				
			||||||
 | 
					 "unicode-width",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "jpeg-decoder"
 | 
					name = "jpeg-decoder"
 | 
				
			||||||
version = "0.2.6"
 | 
					version = "0.2.6"
 | 
				
			||||||
| 
						 | 
					@ -235,6 +266,12 @@ dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "number_prefix"
 | 
				
			||||||
 | 
					version = "0.4.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "once_cell"
 | 
					name = "once_cell"
 | 
				
			||||||
version = "1.13.0"
 | 
					version = "1.13.0"
 | 
				
			||||||
| 
						 | 
					@ -318,6 +355,7 @@ name = "renderer"
 | 
				
			||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "image",
 | 
					 "image",
 | 
				
			||||||
 | 
					 "indicatif",
 | 
				
			||||||
 "rand",
 | 
					 "rand",
 | 
				
			||||||
 "rayon",
 | 
					 "rayon",
 | 
				
			||||||
 "tobj",
 | 
					 "tobj",
 | 
				
			||||||
| 
						 | 
					@ -329,6 +367,16 @@ version = "1.1.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 | 
					checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "terminal_size"
 | 
				
			||||||
 | 
					version = "0.1.17"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "winapi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tobj"
 | 
					name = "tobj"
 | 
				
			||||||
version = "3.2.3"
 | 
					version = "3.2.3"
 | 
				
			||||||
| 
						 | 
					@ -338,6 +386,12 @@ dependencies = [
 | 
				
			||||||
 "ahash",
 | 
					 "ahash",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "unicode-width"
 | 
				
			||||||
 | 
					version = "0.1.9"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "version_check"
 | 
					name = "version_check"
 | 
				
			||||||
version = "0.9.4"
 | 
					version = "0.9.4"
 | 
				
			||||||
| 
						 | 
					@ -349,3 +403,25 @@ name = "wasi"
 | 
				
			||||||
version = "0.11.0+wasi-snapshot-preview1"
 | 
					version = "0.11.0+wasi-snapshot-preview1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 | 
					checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "winapi"
 | 
				
			||||||
 | 
					version = "0.3.9"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "winapi-i686-pc-windows-gnu",
 | 
				
			||||||
 | 
					 "winapi-x86_64-pc-windows-gnu",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "winapi-i686-pc-windows-gnu"
 | 
				
			||||||
 | 
					version = "0.4.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "winapi-x86_64-pc-windows-gnu"
 | 
				
			||||||
 | 
					version = "0.4.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ edition = "2021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
image = { version = "0.24.2", default-features = false, features = ["jpeg", "png", "pnm"] }
 | 
					image = { version = "0.24.2", default-features = false, features = ["jpeg", "png", "pnm"] }
 | 
				
			||||||
 | 
					indicatif = "0.17.0"
 | 
				
			||||||
rand = { version = "0.8.5", features = ["small_rng"] }
 | 
					rand = { version = "0.8.5", features = ["small_rng"] }
 | 
				
			||||||
rayon = "1.5.3"
 | 
					rayon = "1.5.3"
 | 
				
			||||||
tobj = "3.2.3"
 | 
					tobj = "3.2.3"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										35
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								src/main.rs
									
									
									
									
									
								
							| 
						 | 
					@ -13,11 +13,11 @@ use camera::Camera;
 | 
				
			||||||
use hittable::{HitRecord, Hittable, Sphere, Triangle};
 | 
					use hittable::{HitRecord, Hittable, Sphere, Triangle};
 | 
				
			||||||
use hittable_list::HittableList;
 | 
					use hittable_list::HittableList;
 | 
				
			||||||
use image::{Rgb, RgbImage};
 | 
					use image::{Rgb, RgbImage};
 | 
				
			||||||
use material::{Dielectric, Lambertian, Material, Metal};
 | 
					use indicatif::ProgressBar;
 | 
				
			||||||
 | 
					use material::{Dielectric, Lambertian, Material, Metal, Rainbow};
 | 
				
			||||||
use ray::Ray;
 | 
					use ray::Ray;
 | 
				
			||||||
use rayon::prelude::*;
 | 
					use rayon::prelude::*;
 | 
				
			||||||
use std::env;
 | 
					use std::env;
 | 
				
			||||||
use std::sync::atomic::{AtomicU32, Ordering};
 | 
					 | 
				
			||||||
use std::sync::Arc;
 | 
					use std::sync::Arc;
 | 
				
			||||||
use tobj;
 | 
					use tobj;
 | 
				
			||||||
use vec3::{Color, Point3, Vec3};
 | 
					use vec3::{Color, Point3, Vec3};
 | 
				
			||||||
| 
						 | 
					@ -170,6 +170,7 @@ fn random_world() -> HittableList {
 | 
				
			||||||
fn from_obj(path: &str) -> HittableList {
 | 
					fn from_obj(path: &str) -> HittableList {
 | 
				
			||||||
    let mut world = HittableList::new();
 | 
					    let mut world = HittableList::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
    let material_ground = Arc::new(Lambertian::new(&Color::new(
 | 
					    let material_ground = Arc::new(Lambertian::new(&Color::new(
 | 
				
			||||||
        29.0 / 255.0,
 | 
					        29.0 / 255.0,
 | 
				
			||||||
        71.0 / 255.0,
 | 
					        71.0 / 255.0,
 | 
				
			||||||
| 
						 | 
					@ -180,14 +181,16 @@ fn from_obj(path: &str) -> HittableList {
 | 
				
			||||||
        5000.0,
 | 
					        5000.0,
 | 
				
			||||||
        material_ground.clone(),
 | 
					        material_ground.clone(),
 | 
				
			||||||
    )));
 | 
					    )));
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let material = Arc::new(Lambertian::new(&Color::new(
 | 
					    //let material = Arc::new(Lambertian::new(&Color::new(
 | 
				
			||||||
        26.0 / 255.0,
 | 
					    //    77.0 / 255.0,
 | 
				
			||||||
        82.0 / 255.0,
 | 
					    //    77.0 / 255.0,
 | 
				
			||||||
        118.0 / 255.0,
 | 
					    //    118.0 / 255.0,
 | 
				
			||||||
    )));
 | 
					    //)));
 | 
				
			||||||
    //let material = Arc::new(Dielectric::new(2.0));
 | 
					    //let material = Arc::new(Dielectric::new(2.0));
 | 
				
			||||||
    //let material = Arc::new(Metal::new(&Color::new(0.9, 0.9, 0.7), 1.0));
 | 
					    //let material = Arc::new(Metal::new(&Color::new(0.9, 0.9, 0.7), 1.0));
 | 
				
			||||||
 | 
					    let material = Arc::new(Rainbow::new());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let cornell_box = tobj::load_obj(path, &tobj::OFFLINE_RENDERING_LOAD_OPTIONS);
 | 
					    let cornell_box = tobj::load_obj(path, &tobj::OFFLINE_RENDERING_LOAD_OPTIONS);
 | 
				
			||||||
    let (models, materials) = cornell_box.expect("Failed to load OBJ file");
 | 
					    let (models, materials) = cornell_box.expect("Failed to load OBJ file");
 | 
				
			||||||
| 
						 | 
					@ -295,10 +298,10 @@ fn main() {
 | 
				
			||||||
    let mut default_file = "image.ppm";
 | 
					    let mut default_file = "image.ppm";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Image
 | 
					    // Image
 | 
				
			||||||
    let aspect_ratio = 16.0 / 9.0;
 | 
					    let aspect_ratio = 10.0/7.5; //16.0 / 9.0;
 | 
				
			||||||
    let image_width = 1200;
 | 
					    let image_width = 1000;
 | 
				
			||||||
    let image_height = (image_width as f64 / aspect_ratio) as u32;
 | 
					    let image_height = (image_width as f64 / aspect_ratio) as u32;
 | 
				
			||||||
    let samples_per_pixel = 50_u32;
 | 
					    let samples_per_pixel = 100_u32;
 | 
				
			||||||
    let max_depth = 50;
 | 
					    let max_depth = 50;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let vfov = 40.0;
 | 
					    let vfov = 40.0;
 | 
				
			||||||
| 
						 | 
					@ -315,6 +318,7 @@ fn main() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // World
 | 
					    // World
 | 
				
			||||||
 | 
					    eprintln!("[1/3] Loading meshes from file...");
 | 
				
			||||||
    let world = from_obj("obj/suzanne.obj");
 | 
					    let world = from_obj("obj/suzanne.obj");
 | 
				
			||||||
    // let world = random_world();
 | 
					    // let world = random_world();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -335,16 +339,17 @@ fn main() {
 | 
				
			||||||
        default_file = &args[1];
 | 
					        default_file = &args[1];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eprintln!("[2/3] Gerenating image...");
 | 
				
			||||||
 | 
					    let bar = ProgressBar::new(image_height as u64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut image = RgbImage::new(image_width, image_height);
 | 
					    let mut image = RgbImage::new(image_width, image_height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let atomic_counter = Arc::new(AtomicU32::new(0));
 | 
					 | 
				
			||||||
    let color_lines: Vec<_> = (0..image_height)
 | 
					    let color_lines: Vec<_> = (0..image_height)
 | 
				
			||||||
        .into_par_iter() // threadded/parallel variant
 | 
					        .into_par_iter() // threadded/parallel variant
 | 
				
			||||||
        //.into_iter()  // iterative variant
 | 
					        //.into_iter()  // iterative variant
 | 
				
			||||||
        .rev()
 | 
					        .rev()
 | 
				
			||||||
        .map(|j| {
 | 
					        .map(|j| {
 | 
				
			||||||
            let v = atomic_counter.fetch_add(1, Ordering::Relaxed);
 | 
					            bar.inc(1);
 | 
				
			||||||
            eprint!("\rScanlines remaining: {:5}", image_height - v);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let mut colors = Vec::new();
 | 
					            let mut colors = Vec::new();
 | 
				
			||||||
            for i in 0..image_width {
 | 
					            for i in 0..image_width {
 | 
				
			||||||
| 
						 | 
					@ -367,8 +372,9 @@ fn main() {
 | 
				
			||||||
            return colors;
 | 
					            return colors;
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .collect();
 | 
					        .collect();
 | 
				
			||||||
    eprint!("\rScanlines remaining: {:5}", 0);
 | 
					    bar.finish_and_clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eprintln!("[3/3] Exporting image to disk...");
 | 
				
			||||||
    (0..image_height).into_iter().rev().for_each(|j| {
 | 
					    (0..image_height).into_iter().rev().for_each(|j| {
 | 
				
			||||||
        (0..image_width).into_iter().for_each(|i| {
 | 
					        (0..image_width).into_iter().for_each(|i| {
 | 
				
			||||||
            color::put_color(
 | 
					            color::put_color(
 | 
				
			||||||
| 
						 | 
					@ -382,5 +388,4 @@ fn main() {
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    image.save(default_file).unwrap();
 | 
					    image.save(default_file).unwrap();
 | 
				
			||||||
    eprintln!("\nDone!");
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,10 @@ pub struct Dielectric {
 | 
				
			||||||
    ir: f64,
 | 
					    ir: f64,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct Rainbow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait Material: Sync + Send {
 | 
					pub trait Material: Sync + Send {
 | 
				
			||||||
    fn scatter(
 | 
					    fn scatter(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
| 
						 | 
					@ -157,3 +161,34 @@ impl Material for Dielectric {
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Rainbow {
 | 
				
			||||||
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
 | 
					        Rainbow {}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Material for Rainbow {
 | 
				
			||||||
 | 
					    fn scatter(
 | 
				
			||||||
 | 
					        &self,
 | 
				
			||||||
 | 
					        r_in: &Ray,
 | 
				
			||||||
 | 
					        rec: &HitRecord,
 | 
				
			||||||
 | 
					        attenuation: &mut Color,
 | 
				
			||||||
 | 
					        scattered: &mut Ray,
 | 
				
			||||||
 | 
					    ) -> bool {
 | 
				
			||||||
 | 
					        let mut scatter_direction = rec.normal + Vec3::random_unit_vector();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if scatter_direction.near_zero() {
 | 
				
			||||||
 | 
					            scatter_direction = rec.normal;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        *scattered = Ray::new(rec.p, scatter_direction);
 | 
				
			||||||
 | 
					        let color = 0.5*Color::new(
 | 
				
			||||||
 | 
					            rec.normal.x()+1.0,
 | 
				
			||||||
 | 
					            rec.normal.y()+1.0,
 | 
				
			||||||
 | 
					            rec.normal.z()+1.0
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        *attenuation = color;
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in a new issue