Added chunk based rendering system for all the demos
This commit is contained in:
parent
fbf41fae22
commit
cae95b0bf0
140
Cargo.lock
generated
140
Cargo.lock
generated
|
@ -1,5 +1,11 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -21,6 +27,57 @@ version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"memoffset",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cfg-if",
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
|
@ -32,6 +89,15 @@ dependencies = [
|
||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -44,6 +110,25 @@ version = "0.2.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
@ -91,14 +176,54 @@ dependencies = [
|
||||||
"rand_core",
|
"rand_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-queue",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ria-weekend"
|
name = "ria-weekend"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
|
"rayon",
|
||||||
"sdl2",
|
"sdl2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sdl2"
|
name = "sdl2"
|
||||||
version = "0.33.0"
|
version = "0.33.0"
|
||||||
|
@ -121,6 +246,21 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.9.0+wasi-snapshot-preview1"
|
version = "0.9.0+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -7,3 +7,4 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sdl2 = "0.33.0"
|
sdl2 = "0.33.0"
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
|
rayon = "1.3.0"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
demos::Demo,
|
demos::{Chunk, Demo},
|
||||||
types::{Hitable, HitableList, Ray, Sphere, Vec3},
|
types::{Hitable, HitableList, Ray, Sphere, Vec3},
|
||||||
Camera,
|
Camera,
|
||||||
},
|
},
|
||||||
|
@ -14,7 +14,16 @@ impl Demo for DiffuseMaterials {
|
||||||
"Diffuse Materials"
|
"Diffuse Materials"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, samples: u8) {
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk, samples: u8) {
|
||||||
|
let Chunk {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
} = meta;
|
||||||
|
|
||||||
let world = HitableList {
|
let world = HitableList {
|
||||||
list: vec![
|
list: vec![
|
||||||
Box::new(Sphere::new(Vec3::new(0.0, 0.0, -1.0), 0.5)),
|
Box::new(Sphere::new(Vec3::new(0.0, 0.0, -1.0), 0.5)),
|
||||||
|
@ -24,21 +33,22 @@ impl Demo for DiffuseMaterials {
|
||||||
|
|
||||||
let camera: Camera = Default::default();
|
let camera: Camera = Default::default();
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let mut offset = 0;
|
|
||||||
|
|
||||||
for j in (0..height).rev() {
|
for j in start_y..start_y + ny {
|
||||||
for i in 0..width {
|
for i in start_x..start_x + nx {
|
||||||
let mut color = Vec3::new(0.0, 0.0, 0.0);
|
let mut color = Vec3::new(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
for _s in 0..samples {
|
for _s in 0..samples {
|
||||||
let u = (i as f64 + rng.gen::<f64>()) / width as f64;
|
let u = (i as f64 + rng.gen::<f64>()) / x as f64;
|
||||||
let v = (j as f64 + rng.gen::<f64>()) / height as f64;
|
let v = (j as f64 + rng.gen::<f64>()) / y as f64;
|
||||||
|
|
||||||
let r = camera.get_ray(u, v);
|
let r = camera.get_ray(u, v);
|
||||||
color += calc_color(r, &world, &mut rng);
|
color += calc_color(r, &world, &mut rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
color /= samples as f64;
|
color /= samples as f64;
|
||||||
|
let offset = ((y - j - 1) * x + i) * 4;
|
||||||
|
|
||||||
// Without taking square root of each color, we get a picture that
|
// Without taking square root of each color, we get a picture that
|
||||||
// is quite dark
|
// is quite dark
|
||||||
// Spheres in this case are absorbing 50% of the light casted on them
|
// Spheres in this case are absorbing 50% of the light casted on them
|
||||||
|
@ -48,7 +58,6 @@ impl Demo for DiffuseMaterials {
|
||||||
buf[offset] = (255.99 * color.r().sqrt()) as u8;
|
buf[offset] = (255.99 * color.r().sqrt()) as u8;
|
||||||
buf[offset + 1] = (255.99 * color.g().sqrt()) as u8;
|
buf[offset + 1] = (255.99 * color.g().sqrt()) as u8;
|
||||||
buf[offset + 2] = (255.99 * color.b().sqrt()) as u8;
|
buf[offset + 2] = (255.99 * color.b().sqrt()) as u8;
|
||||||
offset += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
demos::Demo,
|
demos::{Chunk, Demo},
|
||||||
types::{Hitable, HitableList, Ray, Sphere, Vec3},
|
types::{Hitable, HitableList, Ray, Sphere, Vec3},
|
||||||
};
|
};
|
||||||
pub struct HitableSphere;
|
pub struct HitableSphere;
|
||||||
|
@ -9,7 +9,16 @@ impl Demo for HitableSphere {
|
||||||
"Sphere using Hit table"
|
"Sphere using Hit table"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, _samples: u8) {
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk, _samples: u8) {
|
||||||
|
let Chunk {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
} = meta;
|
||||||
|
|
||||||
let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
|
let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
|
||||||
let horizontal = Vec3::new(4.0, 0.0, 0.0);
|
let horizontal = Vec3::new(4.0, 0.0, 0.0);
|
||||||
let vertical = Vec3::new(0.0, 2.0, 0.0);
|
let vertical = Vec3::new(0.0, 2.0, 0.0);
|
||||||
|
@ -22,18 +31,17 @@ impl Demo for HitableSphere {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut offset = 0;
|
for j in start_y..start_y + ny {
|
||||||
for j in (0..height).rev() {
|
for i in start_x..start_x + nx {
|
||||||
for i in 0..width {
|
let u = i as f64 / x as f64;
|
||||||
let u = i as f64 / width as f64;
|
let v = j as f64 / y as f64;
|
||||||
let v = j as f64 / height as f64;
|
|
||||||
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
||||||
|
|
||||||
let color = calc_color(ray, &world);
|
let color = calc_color(ray, &world);
|
||||||
|
|
||||||
|
let offset = ((y - j - 1) * x + i) * 4;
|
||||||
buf[offset] = (255.99 * color.r()) as u8;
|
buf[offset] = (255.99 * color.r()) as u8;
|
||||||
buf[offset + 1] = (255.99 * color.g()) as u8;
|
buf[offset + 1] = (255.99 * color.g()) as u8;
|
||||||
buf[offset + 2] = (255.99 * color.b()) as u8;
|
buf[offset + 2] = (255.99 * color.b()) as u8;
|
||||||
offset += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ pub struct LinearGradientRectangle;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{Ray, Vec3},
|
types::{Ray, Vec3},
|
||||||
HORIZONTAL_PARTITION, VERTICAL_PARTITION,
|
|
||||||
{demos::Chunk, Demo},
|
{demos::Chunk, Demo},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,28 +10,7 @@ impl Demo for LinearGradientRectangle {
|
||||||
"Linear Gradient Rectangle"
|
"Linear Gradient Rectangle"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, _samples: u8) {
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk, _samples: u8) {
|
||||||
let nx = width / VERTICAL_PARTITION;
|
|
||||||
let ny = height / HORIZONTAL_PARTITION;
|
|
||||||
|
|
||||||
for j in 0..VERTICAL_PARTITION {
|
|
||||||
for i in 0..HORIZONTAL_PARTITION {
|
|
||||||
let start_y = j * ny;
|
|
||||||
let start_x = i * nx;
|
|
||||||
let chunk = Chunk {
|
|
||||||
x: width,
|
|
||||||
y: height,
|
|
||||||
nx,
|
|
||||||
ny,
|
|
||||||
start_x,
|
|
||||||
start_y,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.render_chunk(buf, chunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn render_chunk(&self, buf: &mut [u8], meta: Chunk) {
|
|
||||||
let Chunk {
|
let Chunk {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
|
@ -55,8 +33,7 @@ impl Demo for LinearGradientRectangle {
|
||||||
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
||||||
|
|
||||||
let c = color(ray);
|
let c = color(ray);
|
||||||
|
let offset = ((y - j - 1) * x + i) * 4;
|
||||||
let offset = (j * x + i) * 4;
|
|
||||||
buf[offset] = (255.99 * c.r()) as u8;
|
buf[offset] = (255.99 * c.r()) as u8;
|
||||||
buf[offset + 1] = (255.99 * c.g()) as u8;
|
buf[offset + 1] = (255.99 * c.g()) as u8;
|
||||||
buf[offset + 2] = (255.99 * c.b()) as u8;
|
buf[offset + 2] = (255.99 * c.b()) as u8;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
demos::Demo,
|
demos::{Chunk, Demo},
|
||||||
types::{material, Hitable, HitableList, Ray, Sphere, Vec3},
|
types::{material, Hitable, HitableList, Ray, Sphere, Vec3},
|
||||||
Camera,
|
Camera,
|
||||||
},
|
},
|
||||||
|
@ -14,7 +14,16 @@ impl Demo for Materials {
|
||||||
"Metal Material"
|
"Metal Material"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, samples: u8) {
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk, samples: u8) {
|
||||||
|
let Chunk {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
} = meta;
|
||||||
|
|
||||||
let world = HitableList {
|
let world = HitableList {
|
||||||
list: vec![
|
list: vec![
|
||||||
Box::new(Sphere::with_material(
|
Box::new(Sphere::with_material(
|
||||||
|
@ -42,25 +51,25 @@ impl Demo for Materials {
|
||||||
|
|
||||||
let camera: Camera = Default::default();
|
let camera: Camera = Default::default();
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let mut offset = 0;
|
|
||||||
|
|
||||||
for j in (0..height).rev() {
|
for j in start_y..start_y + ny {
|
||||||
for i in 0..width {
|
for i in start_x..start_x + nx {
|
||||||
let mut color = Vec3::new(0.0, 0.0, 0.0);
|
let mut color = Vec3::new(0.0, 0.0, 0.0);
|
||||||
for _s in 0..samples {
|
for _s in 0..samples {
|
||||||
let u = (i as f64 + rng.gen::<f64>()) / width as f64;
|
let u = (i as f64 + rng.gen::<f64>()) / x as f64;
|
||||||
let v = (j as f64 + rng.gen::<f64>()) / height as f64;
|
let v = (j as f64 + rng.gen::<f64>()) / y as f64;
|
||||||
|
|
||||||
let ray = camera.get_ray(u, v);
|
let ray = camera.get_ray(u, v);
|
||||||
color += calc_color(ray, &world, 0);
|
color += calc_color(ray, &world, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
color /= samples as f64;
|
color /= samples as f64;
|
||||||
|
let offset = ((y - j - 1) * x + i) * 4;
|
||||||
|
|
||||||
// gamma 2 corrected
|
// gamma 2 corrected
|
||||||
buf[offset] = (255.99 * color.r().sqrt()) as u8;
|
buf[offset] = (255.99 * color.r().sqrt()) as u8;
|
||||||
buf[offset + 1] = (255.99 * color.g().sqrt()) as u8;
|
buf[offset + 1] = (255.99 * color.g().sqrt()) as u8;
|
||||||
buf[offset + 2] = (255.99 * color.b().sqrt()) as u8;
|
buf[offset + 2] = (255.99 * color.b().sqrt()) as u8;
|
||||||
offset += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,26 @@
|
||||||
//mod diffuse_materials;
|
mod diffuse_materials;
|
||||||
//mod hitable_sphere;
|
mod hitable_sphere;
|
||||||
mod linear_gradient_rectangle;
|
mod linear_gradient_rectangle;
|
||||||
//mod materials;
|
mod materials;
|
||||||
//mod simple_antialiasing;
|
mod simple_antialiasing;
|
||||||
mod simple_rectangle;
|
mod simple_rectangle;
|
||||||
//mod simple_sphere;
|
mod simple_sphere;
|
||||||
//mod surface_normal_sphere;
|
mod surface_normal_sphere;
|
||||||
|
|
||||||
//pub use diffuse_materials::DiffuseMaterials;
|
pub use diffuse_materials::DiffuseMaterials;
|
||||||
//pub use hitable_sphere::HitableSphere;
|
pub use hitable_sphere::HitableSphere;
|
||||||
pub use linear_gradient_rectangle::LinearGradientRectangle;
|
pub use linear_gradient_rectangle::LinearGradientRectangle;
|
||||||
//pub use materials::Materials;
|
pub use materials::Materials;
|
||||||
//pub use simple_antialiasing::SimpleAntialiasing;
|
pub use simple_antialiasing::SimpleAntialiasing;
|
||||||
pub use simple_rectangle::SimpleRectangle;
|
pub use simple_rectangle::SimpleRectangle;
|
||||||
//pub use simple_sphere::SimpleSphere;
|
pub use simple_sphere::SimpleSphere;
|
||||||
//pub use surface_normal_sphere::SurfaceNormalSphere;
|
pub use surface_normal_sphere::SurfaceNormalSphere;
|
||||||
|
|
||||||
use std::{fs::File, io::Write};
|
use {
|
||||||
|
crate::{HORIZONTAL_PARTITION, VERTICAL_PARTITION},
|
||||||
|
rayon::prelude::*,
|
||||||
|
std::{fs::File, io::Write},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Chunk {
|
pub struct Chunk {
|
||||||
|
@ -29,9 +33,31 @@ pub struct Chunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Demo {
|
pub trait Demo {
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, samples: u8);
|
fn render(&self, buf: &mut [u8], width: usize, height: usize, samples: u8) {
|
||||||
|
let nx = width / VERTICAL_PARTITION;
|
||||||
|
let ny = height / HORIZONTAL_PARTITION;
|
||||||
|
|
||||||
fn render_chunk(&self, buf: &mut [u8], meta: Chunk);
|
let v = (0..VERTICAL_PARTITION).collect::<Vec<usize>>();
|
||||||
|
|
||||||
|
for j in v {
|
||||||
|
for i in 0..HORIZONTAL_PARTITION {
|
||||||
|
let start_y = j * ny;
|
||||||
|
let start_x = i * nx;
|
||||||
|
let chunk = Chunk {
|
||||||
|
x: width,
|
||||||
|
y: height,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.render_chunk(buf, chunk, samples);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk, samples: u8);
|
||||||
|
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
demos::Demo,
|
demos::{Chunk, Demo},
|
||||||
types::{Hitable, HitableList, Ray, Sphere, Vec3},
|
types::{Hitable, HitableList, Ray, Sphere, Vec3},
|
||||||
Camera,
|
Camera,
|
||||||
},
|
},
|
||||||
|
@ -12,8 +12,16 @@ impl Demo for SimpleAntialiasing {
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
"A simple antialiasing implementation"
|
"A simple antialiasing implementation"
|
||||||
}
|
}
|
||||||
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk, samples: u8) {
|
||||||
|
let Chunk {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
} = meta;
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, samples: u8) {
|
|
||||||
let world = HitableList {
|
let world = HitableList {
|
||||||
list: vec![
|
list: vec![
|
||||||
Box::new(Sphere::new(Vec3::new(0.0, 0.0, -1.0), 0.5)),
|
Box::new(Sphere::new(Vec3::new(0.0, 0.0, -1.0), 0.5)),
|
||||||
|
@ -23,22 +31,22 @@ impl Demo for SimpleAntialiasing {
|
||||||
|
|
||||||
let camera: Camera = Default::default();
|
let camera: Camera = Default::default();
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let mut offset = 0;
|
|
||||||
for j in (0..height).rev() {
|
for j in start_y..start_y + ny {
|
||||||
for i in 0..width {
|
for i in start_x..start_x + nx {
|
||||||
let mut color = Vec3::new(0.0, 0.0, 0.0);
|
let mut color = Vec3::new(0.0, 0.0, 0.0);
|
||||||
for _s in 0..samples {
|
for _s in 0..samples {
|
||||||
let u = (i as f64 + rng.gen::<f64>()) / width as f64;
|
let u = (i as f64 + rng.gen::<f64>()) / x as f64;
|
||||||
let v = (j as f64 + rng.gen::<f64>()) / height as f64;
|
let v = (j as f64 + rng.gen::<f64>()) / y as f64;
|
||||||
|
|
||||||
let r = camera.get_ray(u, v);
|
let r = camera.get_ray(u, v);
|
||||||
color += calc_color(r, &world);
|
color += calc_color(r, &world);
|
||||||
}
|
}
|
||||||
color /= samples as f64;
|
color /= samples as f64;
|
||||||
|
let offset = ((y - j - 1) * x + i) * 4;
|
||||||
buf[offset] = (255.99 * color.r()) as u8;
|
buf[offset] = (255.99 * color.r()) as u8;
|
||||||
buf[offset + 1] = (255.99 * color.g()) as u8;
|
buf[offset + 1] = (255.99 * color.g()) as u8;
|
||||||
buf[offset + 2] = (255.99 * color.b()) as u8;
|
buf[offset + 2] = (255.99 * color.b()) as u8;
|
||||||
offset += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
demos::{Chunk, Demo},
|
demos::{Chunk, Demo},
|
||||||
types::Vec3,
|
|
||||||
HORIZONTAL_PARTITION, VERTICAL_PARTITION,
|
HORIZONTAL_PARTITION, VERTICAL_PARTITION,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +10,7 @@ impl Demo for SimpleRectangle {
|
||||||
"simple_rectangle"
|
"simple_rectangle"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, _samples: u8) {
|
fn render(&self, buf: &mut [u8], width: usize, height: usize, samples: u8) {
|
||||||
let nx = width / VERTICAL_PARTITION;
|
let nx = width / VERTICAL_PARTITION;
|
||||||
let ny = height / HORIZONTAL_PARTITION;
|
let ny = height / HORIZONTAL_PARTITION;
|
||||||
|
|
||||||
|
@ -28,12 +27,12 @@ impl Demo for SimpleRectangle {
|
||||||
start_y,
|
start_y,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.render_chunk(buf, chunk);
|
self.render_chunk(buf, chunk, samples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_chunk(&self, buf: &mut [u8], meta: Chunk) {
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk, _samples: u8) {
|
||||||
let Chunk {
|
let Chunk {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
|
@ -46,7 +45,7 @@ impl Demo for SimpleRectangle {
|
||||||
for j in start_y..start_y + ny {
|
for j in start_y..start_y + ny {
|
||||||
for i in start_x..start_x + nx {
|
for i in start_x..start_x + nx {
|
||||||
let color = [i as f64 / x as f64, j as f64 / y as f64, 0.2];
|
let color = [i as f64 / x as f64, j as f64 / y as f64, 0.2];
|
||||||
let offset = (j * x + i) * 4;
|
let offset = ((y - j - 1) * x + i) * 4;
|
||||||
|
|
||||||
buf[offset] = (255.99 * color[0]) as u8;
|
buf[offset] = (255.99 * color[0]) as u8;
|
||||||
buf[offset + 1] = (255.99 * color[1]) as u8;
|
buf[offset + 1] = (255.99 * color[1]) as u8;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
|
demos::{Chunk, Demo},
|
||||||
types::{Ray, Vec3},
|
types::{Ray, Vec3},
|
||||||
Demo,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const RADIUS: f64 = 0.5;
|
const RADIUS: f64 = 0.5;
|
||||||
|
@ -12,7 +12,7 @@ impl Demo for SimpleSphere {
|
||||||
"simple_sphere"
|
"simple_sphere"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], w: usize, h: usize, _ns: u8) {
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk, _ns: u8) {
|
||||||
// Usually, lower_left_corner should've been -1.0,-1.0,-1.0 and
|
// Usually, lower_left_corner should've been -1.0,-1.0,-1.0 and
|
||||||
// horizontal should've been 2.0,0.0,0.0
|
// horizontal should've been 2.0,0.0,0.0
|
||||||
// but we are working with a canvas that is 2:1 in size.
|
// but we are working with a canvas that is 2:1 in size.
|
||||||
|
@ -23,27 +23,34 @@ impl Demo for SimpleSphere {
|
||||||
// stretched horizontally.
|
// stretched horizontally.
|
||||||
// To prevent this from happening, Since our dimensions are in 2:1 ratio,
|
// To prevent this from happening, Since our dimensions are in 2:1 ratio,
|
||||||
// We adjust the lower_left_corner and horizontal values to scale
|
// We adjust the lower_left_corner and horizontal values to scale
|
||||||
|
let Chunk {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
} = meta;
|
||||||
let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
|
let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
|
||||||
let horizontal = Vec3::new(4.0, 0.0, 0.0);
|
let horizontal = Vec3::new(4.0, 0.0, 0.0);
|
||||||
let vertical = Vec3::new(0.0, 2.0, 0.0);
|
let vertical = Vec3::new(0.0, 2.0, 0.0);
|
||||||
// Observer's position
|
// Observer's position
|
||||||
let origin = Vec3::new(0.0, 0.0, 0.0);
|
let origin = Vec3::new(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
let mut offset = 0;
|
for j in start_y..start_y + ny {
|
||||||
for j in (0..h).rev() {
|
for i in start_x..start_x + nx {
|
||||||
for i in 0..w {
|
|
||||||
// relative offsets
|
// relative offsets
|
||||||
// current position to total width/length
|
// current position to total width/length
|
||||||
let u = i as f64 / w as f64;
|
let u = i as f64 / x as f64;
|
||||||
let v = j as f64 / h as f64;
|
let v = j as f64 / y as f64;
|
||||||
|
|
||||||
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
||||||
let color = calc_color(ray);
|
let color = calc_color(ray);
|
||||||
|
|
||||||
|
let offset = ((y - j - 1) * x + i) * 4;
|
||||||
buf[offset] = (255.99 * color.r()) as u8;
|
buf[offset] = (255.99 * color.r()) as u8;
|
||||||
buf[offset + 1] = (255.99 * color.g()) as u8;
|
buf[offset + 1] = (255.99 * color.g()) as u8;
|
||||||
buf[offset + 2] = (255.99 * color.b()) as u8;
|
buf[offset + 2] = (255.99 * color.b()) as u8;
|
||||||
offset += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
use crate::types::{Ray, Vec3};
|
use crate::{
|
||||||
|
demos::{Chunk, Demo},
|
||||||
|
types::{Ray, Vec3},
|
||||||
|
};
|
||||||
|
|
||||||
const RADIUS: f64 = 0.5;
|
const RADIUS: f64 = 0.5;
|
||||||
pub struct SurfaceNormalSphere;
|
pub struct SurfaceNormalSphere;
|
||||||
|
|
||||||
impl crate::Demo for SurfaceNormalSphere {
|
impl Demo for SurfaceNormalSphere {
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
"surface_normal_sphere"
|
"surface_normal_sphere"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], w: usize, h: usize, _ns: u8) {
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk, _samples: u8) {
|
||||||
// Usually, lower_left_corner should've been -1.0,-1.0,-1.0 and
|
// Usually, lower_left_corner should've been -1.0,-1.0,-1.0 and
|
||||||
// horizontal should've been 2.0,0.0,0.0
|
// horizontal should've been 2.0,0.0,0.0
|
||||||
// but we are working with a canvas that is 2:1 in size.
|
// but we are working with a canvas that is 2:1 in size.
|
||||||
|
@ -19,17 +22,25 @@ impl crate::Demo for SurfaceNormalSphere {
|
||||||
// stretched horizontally.
|
// stretched horizontally.
|
||||||
// To prevent this from happening, Since our dimensions are in 2:1 ratio,
|
// To prevent this from happening, Since our dimensions are in 2:1 ratio,
|
||||||
// We adjust the lower_left_corner and horizontal values to scale
|
// We adjust the lower_left_corner and horizontal values to scale
|
||||||
|
let Chunk {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
} = meta;
|
||||||
|
|
||||||
let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
|
let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
|
||||||
let horizontal = Vec3::new(4.0, 0.0, 0.0);
|
let horizontal = Vec3::new(4.0, 0.0, 0.0);
|
||||||
let vertical = Vec3::new(0.0, 2.0, 0.0);
|
let vertical = Vec3::new(0.0, 2.0, 0.0);
|
||||||
// Observer position
|
// Observer position
|
||||||
let origin = Vec3::new(0.0, 0.0, 0.0);
|
let origin = Vec3::new(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
let mut offset = 0;
|
for j in start_y..start_y + ny {
|
||||||
for j in (0..h).rev() {
|
for i in start_x..start_x + nx {
|
||||||
for i in 0..w {
|
let u = i as f64 / x as f64;
|
||||||
let u = i as f64 / w as f64;
|
let v = j as f64 / y as f64;
|
||||||
let v = j as f64 / h as f64;
|
|
||||||
|
|
||||||
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
||||||
let color = calculate_color(ray);
|
let color = calculate_color(ray);
|
||||||
|
@ -37,10 +48,10 @@ impl crate::Demo for SurfaceNormalSphere {
|
||||||
let ig = (255.99 * color.g()) as u8;
|
let ig = (255.99 * color.g()) as u8;
|
||||||
let ib = (255.99 * color.b()) as u8;
|
let ib = (255.99 * color.b()) as u8;
|
||||||
|
|
||||||
|
let offset = ((y - j - 1) * x + i) * 4;
|
||||||
buf[offset] = ir;
|
buf[offset] = ir;
|
||||||
buf[offset + 1] = ig;
|
buf[offset + 1] = ig;
|
||||||
buf[offset + 2] = ib;
|
buf[offset + 2] = ib;
|
||||||
offset += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
src/main.rs
28
src/main.rs
|
@ -24,7 +24,7 @@ fn main() -> Result<(), String> {
|
||||||
let sdl_ctx = sdl2::init()?;
|
let sdl_ctx = sdl2::init()?;
|
||||||
let video_subsys = sdl_ctx.video()?;
|
let video_subsys = sdl_ctx.video()?;
|
||||||
|
|
||||||
let (width, height) = (1280usize, 640usize);
|
let (mut width, mut height) = (1280usize, 640usize);
|
||||||
|
|
||||||
let window = video_subsys
|
let window = video_subsys
|
||||||
.window("Ray tracing in a weekend", width as u32, height as u32)
|
.window("Ray tracing in a weekend", width as u32, height as u32)
|
||||||
|
@ -72,12 +72,12 @@ fn main() -> Result<(), String> {
|
||||||
Some(Keycode::Num2) => {
|
Some(Keycode::Num2) => {
|
||||||
active_demo = Box::new(demos::LinearGradientRectangle)
|
active_demo = Box::new(demos::LinearGradientRectangle)
|
||||||
}
|
}
|
||||||
//Some(Keycode::Num3) => active_demo = Box::new(demos::SimpleSphere),
|
Some(Keycode::Num3) => active_demo = Box::new(demos::SimpleSphere),
|
||||||
//Some(Keycode::Num4) => active_demo = Box::new(demos::SurfaceNormalSphere),
|
Some(Keycode::Num4) => active_demo = Box::new(demos::SurfaceNormalSphere),
|
||||||
//Some(Keycode::Num5) => active_demo = Box::new(demos::HitableSphere),
|
Some(Keycode::Num5) => active_demo = Box::new(demos::HitableSphere),
|
||||||
//Some(Keycode::Num6) => active_demo = Box::new(demos::SimpleAntialiasing),
|
Some(Keycode::Num6) => active_demo = Box::new(demos::SimpleAntialiasing),
|
||||||
//Some(Keycode::Num7) => active_demo = Box::new(demos::DiffuseMaterials),
|
Some(Keycode::Num7) => active_demo = Box::new(demos::DiffuseMaterials),
|
||||||
//Some(Keycode::Num8) => active_demo = Box::new(demos::Materials),
|
Some(Keycode::Num8) => active_demo = Box::new(demos::Materials),
|
||||||
None => unreachable!(),
|
None => unreachable!(),
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
|
@ -87,13 +87,13 @@ fn main() -> Result<(), String> {
|
||||||
win_event: WindowEvent::Resized(w, h),
|
win_event: WindowEvent::Resized(w, h),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
//width = w as usize;
|
width = w as usize;
|
||||||
//height = h as usize;
|
height = h as usize;
|
||||||
//buffer.resize(width * height * 4, 0);
|
buffer.resize(width * height * 4, 0);
|
||||||
//texture = texture_creator
|
texture = texture_creator
|
||||||
// .create_texture_static(PixelFormatEnum::BGR888, width as u32, height as u32)
|
.create_texture_static(PixelFormatEnum::BGR888, width as u32, height as u32)
|
||||||
// .expect("error in resizing texture");
|
.expect("error in resizing texture");
|
||||||
//should_update = true;
|
should_update = true;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user