Compare commits
3 Commits
665ae244d7
...
51185e9e84
| Author | SHA1 | Date | |
|---|---|---|---|
| 51185e9e84 | |||
| 1ca903c64b | |||
| 5e7139f0ba |
@ -8,7 +8,7 @@ use rtchallenge::prelude::*;
|
|||||||
use rtchallenge::{
|
use rtchallenge::{
|
||||||
camera::RenderStrategy,
|
camera::RenderStrategy,
|
||||||
float::consts::PI,
|
float::consts::PI,
|
||||||
patterns::{test_pattern, BLACK_PAT, WHITE_PAT},
|
patterns::{BLACK_PAT, WHITE_PAT},
|
||||||
WHITE,
|
WHITE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
|
imports_granularity = "Crate"
|
||||||
format_code_in_doc_comments = true
|
format_code_in_doc_comments = true
|
||||||
|
|||||||
@ -41,7 +41,7 @@ impl Default for RenderStrategy {
|
|||||||
impl FromStr for RenderStrategy {
|
impl FromStr for RenderStrategy {
|
||||||
type Err = serde_json::error::Error;
|
type Err = serde_json::error::Error;
|
||||||
fn from_str(s: &str) -> Result<RenderStrategy, serde_json::error::Error> {
|
fn from_str(s: &str) -> Result<RenderStrategy, serde_json::error::Error> {
|
||||||
Ok(serde_json::from_str(&format!("\"{}\"", s))?)
|
serde_json::from_str(&format!("\"{}\"", s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ impl Camera {
|
|||||||
let color = self
|
let color = self
|
||||||
.supersample_rays_for_pixel(x, y, self.samples_per_pixel)
|
.supersample_rays_for_pixel(x, y, self.samples_per_pixel)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ray| w.color_at(&ray, MAX_DEPTH_RECURSION))
|
.map(|ray| w.color_at(ray, MAX_DEPTH_RECURSION))
|
||||||
.fold(BLACK, |acc, c| acc + c);
|
.fold(BLACK, |acc, c| acc + c);
|
||||||
color / self.samples_per_pixel as Float
|
color / self.samples_per_pixel as Float
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -48,7 +48,7 @@ impl Canvas {
|
|||||||
{
|
{
|
||||||
let path = Path::new(path.as_ref());
|
let path = Path::new(path.as_ref());
|
||||||
let file = File::create(path)?;
|
let file = File::create(path)?;
|
||||||
let ref mut w = BufWriter::new(file);
|
let w = &mut BufWriter::new(file);
|
||||||
|
|
||||||
let mut encoder = png::Encoder::new(w, self.width as u32, self.height as u32);
|
let mut encoder = png::Encoder::new(w, self.width as u32, self.height as u32);
|
||||||
encoder.set_color(png::ColorType::RGB);
|
encoder.set_color(png::ColorType::RGB);
|
||||||
|
|||||||
@ -40,6 +40,9 @@ impl<'i> Intersections<'i> {
|
|||||||
pub fn new(xs: Vec<Intersection<'i>>) -> Intersections {
|
pub fn new(xs: Vec<Intersection<'i>>) -> Intersections {
|
||||||
Intersections(xs)
|
Intersections(xs)
|
||||||
}
|
}
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.0.len()
|
self.0.len()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use derive_builder::Builder;
|
|||||||
use crate::{
|
use crate::{
|
||||||
intersections::Intersections,
|
intersections::Intersections,
|
||||||
materials::{Material, MaterialBuilder},
|
materials::{Material, MaterialBuilder},
|
||||||
matrices::{identity, Matrix4x4},
|
matrices::Matrix4x4,
|
||||||
rays::Ray,
|
rays::Ray,
|
||||||
tuples::Tuple,
|
tuples::Tuple,
|
||||||
};
|
};
|
||||||
@ -131,7 +131,7 @@ impl ShapeBuilder {
|
|||||||
let mut s = Shape::default();
|
let mut s = Shape::default();
|
||||||
|
|
||||||
if let Some(transform) = &self.transform {
|
if let Some(transform) = &self.transform {
|
||||||
s.set_transform(transform.clone());
|
s.set_transform(*transform);
|
||||||
}
|
}
|
||||||
if let Some(material) = &self.material {
|
if let Some(material) = &self.material {
|
||||||
s.material = material.clone();
|
s.material = material.clone();
|
||||||
@ -139,10 +139,10 @@ impl ShapeBuilder {
|
|||||||
if let Some(geometry) = &self.geometry {
|
if let Some(geometry) = &self.geometry {
|
||||||
s.geometry = geometry.clone();
|
s.geometry = geometry.clone();
|
||||||
};
|
};
|
||||||
let transform = s.transform().clone();
|
let transform = s.transform();
|
||||||
if let Geometry::Group(ref mut children) = s.geometry {
|
if let Geometry::Group(ref mut children) = s.geometry {
|
||||||
children
|
children
|
||||||
.into_iter()
|
.iter_mut()
|
||||||
.for_each(|c| c.set_transform(transform * c.transform()));
|
.for_each(|c| c.set_transform(transform * c.transform()));
|
||||||
}
|
}
|
||||||
Ok(s)
|
Ok(s)
|
||||||
@ -242,7 +242,7 @@ pub fn intersect<'s>(shape: &'s Shape, ray: &Ray) -> Intersections<'s> {
|
|||||||
Geometry::Plane => plane::intersect(shape, &local_ray),
|
Geometry::Plane => plane::intersect(shape, &local_ray),
|
||||||
Geometry::TestShape(_) => test_shape::intersect(shape, &local_ray),
|
Geometry::TestShape(_) => test_shape::intersect(shape, &local_ray),
|
||||||
Geometry::Cube => cube::intersect(shape, &local_ray),
|
Geometry::Cube => cube::intersect(shape, &local_ray),
|
||||||
Geometry::Group(_) => group::intersect(shape, &ray),
|
Geometry::Group(_) => group::intersect(shape, ray),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,8 +279,8 @@ mod sphere {
|
|||||||
return Intersections::default();
|
return Intersections::default();
|
||||||
}
|
}
|
||||||
Intersections::new(vec![
|
Intersections::new(vec![
|
||||||
Intersection::new((-b - discriminant.sqrt()) / (2. * a), &shape),
|
Intersection::new((-b - discriminant.sqrt()) / (2. * a), shape),
|
||||||
Intersection::new((-b + discriminant.sqrt()) / (2. * a), &shape),
|
Intersection::new((-b + discriminant.sqrt()) / (2. * a), shape),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,7 +298,7 @@ mod plane {
|
|||||||
}
|
}
|
||||||
Intersections::new(vec![Intersection::new(
|
Intersections::new(vec![Intersection::new(
|
||||||
-ray.origin.y / ray.direction.y,
|
-ray.origin.y / ray.direction.y,
|
||||||
&shape,
|
shape,
|
||||||
)])
|
)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,8 +343,8 @@ mod cube {
|
|||||||
return Intersections::default();
|
return Intersections::default();
|
||||||
}
|
}
|
||||||
Intersections::new(vec![
|
Intersections::new(vec![
|
||||||
Intersection::new(tmin, &shape),
|
Intersection::new(tmin, shape),
|
||||||
Intersection::new(tmax, &shape),
|
Intersection::new(tmax, shape),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
pub fn local_normal_at(point: Tuple) -> Tuple {
|
pub fn local_normal_at(point: Tuple) -> Tuple {
|
||||||
@ -435,8 +435,7 @@ mod group {
|
|||||||
if let Geometry::Group(children) = &shape.geometry {
|
if let Geometry::Group(children) = &shape.geometry {
|
||||||
let mut intersections: Vec<_> = children
|
let mut intersections: Vec<_> = children
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| super::intersect(c, ray))
|
.flat_map(|c| super::intersect(c, ray))
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
intersections.sort_by(|a, b| {
|
intersections.sort_by(|a, b| {
|
||||||
a.t.partial_cmp(&b.t)
|
a.t.partial_cmp(&b.t)
|
||||||
|
|||||||
@ -40,12 +40,7 @@ impl World {
|
|||||||
|
|
||||||
/// Intersects the ray with this world.
|
/// Intersects the ray with this world.
|
||||||
pub fn intersect(&self, r: &Ray) -> Intersections {
|
pub fn intersect(&self, r: &Ray) -> Intersections {
|
||||||
let mut xs: Vec<_> = self
|
let mut xs: Vec<_> = self.objects.iter().flat_map(|o| intersect(o, r)).collect();
|
||||||
.objects
|
|
||||||
.iter()
|
|
||||||
.map(|o| intersect(&o, &r))
|
|
||||||
.flatten()
|
|
||||||
.collect();
|
|
||||||
xs.sort_by(|i1, i2| {
|
xs.sort_by(|i1, i2| {
|
||||||
i1.t.partial_cmp(&i2.t)
|
i1.t.partial_cmp(&i2.t)
|
||||||
.expect("an intersection has a t value that is NaN")
|
.expect("an intersection has a t value that is NaN")
|
||||||
@ -62,7 +57,7 @@ impl World {
|
|||||||
let shadowed = self.is_shadowed(comps.over_point, light);
|
let shadowed = self.is_shadowed(comps.over_point, light);
|
||||||
let surface = lighting(
|
let surface = lighting(
|
||||||
&comps.object.material,
|
&comps.object.material,
|
||||||
&comps.object,
|
comps.object,
|
||||||
light,
|
light,
|
||||||
comps.over_point,
|
comps.over_point,
|
||||||
comps.eyev,
|
comps.eyev,
|
||||||
@ -86,7 +81,7 @@ impl World {
|
|||||||
let xs = self.intersect(r);
|
let xs = self.intersect(r);
|
||||||
match xs.hit() {
|
match xs.hit() {
|
||||||
Some(hit) => {
|
Some(hit) => {
|
||||||
let comps = prepare_computations(&hit, r, &xs);
|
let comps = prepare_computations(hit, r, &xs);
|
||||||
self.shade_hit(&comps, remaining)
|
self.shade_hit(&comps, remaining)
|
||||||
}
|
}
|
||||||
None => BLACK,
|
None => BLACK,
|
||||||
|
|||||||
2
rtiow/noise_explorer/rustfmt.toml
Normal file
2
rtiow/noise_explorer/rustfmt.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
imports_granularity = "Crate"
|
||||||
|
format_code_in_doc_comments = true
|
||||||
@ -11,7 +11,6 @@ use actix_web::Path;
|
|||||||
use actix_web::Query;
|
use actix_web::Query;
|
||||||
use actix_web::Result;
|
use actix_web::Result;
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use image;
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand_xorshift::XorShiftRng;
|
use rand_xorshift::XorShiftRng;
|
||||||
@ -26,7 +25,7 @@ use renderer::texture::NoiseTexture;
|
|||||||
use renderer::texture::Texture;
|
use renderer::texture::Texture;
|
||||||
use renderer::vec3::Vec3;
|
use renderer::vec3::Vec3;
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(StructOpt)]
|
||||||
#[structopt(name = "noise_explorer", about = "CLI for exploring Perlin noise")]
|
#[structopt(name = "noise_explorer", about = "CLI for exploring Perlin noise")]
|
||||||
struct Opt {
|
struct Opt {
|
||||||
/// HTTP listen address
|
/// HTTP listen address
|
||||||
|
|||||||
2
rtiow/noise_explorer_warp/rustfmt.toml
Normal file
2
rtiow/noise_explorer_warp/rustfmt.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
imports_granularity = "Crate"
|
||||||
|
format_code_in_doc_comments = true
|
||||||
2
rtiow/renderer/rustfmt.toml
Normal file
2
rtiow/renderer/rustfmt.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
imports_granularity = "Crate"
|
||||||
|
format_code_in_doc_comments = true
|
||||||
@ -130,6 +130,12 @@ impl Formatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Formatter {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Scales {
|
impl Scales {
|
||||||
/// Instantiates a new `Scales` with SI keys
|
/// Instantiates a new `Scales` with SI keys
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -199,7 +205,7 @@ impl Scales {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0;
|
0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_scaled_value(&self, value: f64) -> ScaledValue {
|
fn to_scaled_value(&self, value: f64) -> ScaledValue {
|
||||||
@ -221,3 +227,9 @@ impl Scales {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Scales {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -146,7 +146,7 @@ fn print_tree(f: &mut fmt::Formatter, depth: usize, kdt: &KDTree) -> fmt::Result
|
|||||||
impl fmt::Display for KDTree {
|
impl fmt::Display for KDTree {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
writeln!(f, "kd-tree")?;
|
writeln!(f, "kd-tree")?;
|
||||||
print_tree(f, 1, &self)
|
print_tree(f, 1, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Hit for KDTree {
|
impl Hit for KDTree {
|
||||||
|
|||||||
@ -35,7 +35,7 @@ fn perlin_generate_perm<R>(rng: &mut R) -> Vec<usize>
|
|||||||
where
|
where
|
||||||
R: Rng,
|
R: Rng,
|
||||||
{
|
{
|
||||||
let mut p: Vec<usize> = (0..256).map(|i| i).collect();
|
let mut p: Vec<usize> = (0..256).collect();
|
||||||
p.shuffle(rng);
|
p.shuffle(rng);
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,7 +98,7 @@ pub fn set_pixel(name: &str, x: usize, y: usize, pixel: Vec3) {
|
|||||||
let (_it, img) = debugger
|
let (_it, img) = debugger
|
||||||
.images
|
.images
|
||||||
.get_mut(name)
|
.get_mut(name)
|
||||||
.expect(&format!("couldn't find image named '{}'", name));
|
.unwrap_or_else(|| panic!("couldn't find image named '{}'", name));
|
||||||
let y_inv = img.h - y - 1;
|
let y_inv = img.h - y - 1;
|
||||||
img.put_pixel(x, y_inv, pixel);
|
img.put_pixel(x, y_inv, pixel);
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ pub fn set_pixel_grey(name: &str, x: usize, y: usize, grey: f32) {
|
|||||||
let (_it, img) = debugger
|
let (_it, img) = debugger
|
||||||
.images
|
.images
|
||||||
.get_mut(name)
|
.get_mut(name)
|
||||||
.expect(&format!("couldn't find image named '{}'", name));
|
.unwrap_or_else(|| panic!("couldn't find image named '{}'", name));
|
||||||
let y_inv = img.h - y - 1;
|
let y_inv = img.h - y - 1;
|
||||||
img.put_pixel(x, y_inv, [grey, grey, grey].into());
|
img.put_pixel(x, y_inv, [grey, grey, grey].into());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,17 +52,17 @@ pub enum Model {
|
|||||||
impl Model {
|
impl Model {
|
||||||
pub fn scene(&self, opt: &Opt) -> Scene {
|
pub fn scene(&self, opt: &Opt) -> Scene {
|
||||||
match self {
|
match self {
|
||||||
Model::BVH => scenes::bvh::new(&opt),
|
Model::BVH => scenes::bvh::new(opt),
|
||||||
Model::Bench => scenes::bench::new(&opt),
|
Model::Bench => scenes::bench::new(opt),
|
||||||
Model::Book => scenes::book::new(&opt),
|
Model::Book => scenes::book::new(opt),
|
||||||
Model::CornellBox => scenes::cornell_box::new(&opt),
|
Model::CornellBox => scenes::cornell_box::new(opt),
|
||||||
Model::CornellSmoke => scenes::cornell_smoke::new(&opt),
|
Model::CornellSmoke => scenes::cornell_smoke::new(opt),
|
||||||
Model::Final => scenes::final_scene::new(&opt),
|
Model::Final => scenes::final_scene::new(opt),
|
||||||
Model::Mandelbrot => scenes::mandelbrot::new(&opt),
|
Model::Mandelbrot => scenes::mandelbrot::new(opt),
|
||||||
Model::PerlinDebug => scenes::perlin_debug::new(&opt),
|
Model::PerlinDebug => scenes::perlin_debug::new(opt),
|
||||||
Model::Spheramid => scenes::spheramid::new(&opt),
|
Model::Spheramid => scenes::spheramid::new(opt),
|
||||||
Model::Test => scenes::test::new(&opt),
|
Model::Test => scenes::test::new(opt),
|
||||||
Model::Tutorial => scenes::tutorial::new(&opt),
|
Model::Tutorial => scenes::tutorial::new(opt),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ pub fn opt_hash(opt: &Opt) -> String {
|
|||||||
opt.pprof.is_some(),
|
opt.pprof.is_some(),
|
||||||
opt.model.to_string(),
|
opt.model.to_string(),
|
||||||
opt.use_accel,
|
opt.use_accel,
|
||||||
opt.output.display().to_string().replace("/", "_")
|
opt.output.display().to_string().replace('/', "_")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +378,7 @@ fn trace_pixel_random(x: usize, y: usize, scene: &Scene) -> (Vec3, usize) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, Default)]
|
||||||
struct RenderStats {
|
struct RenderStats {
|
||||||
rays: usize,
|
rays: usize,
|
||||||
pixels: usize,
|
pixels: usize,
|
||||||
@ -412,12 +412,6 @@ fn progress(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for RenderStats {
|
|
||||||
fn default() -> Self {
|
|
||||||
RenderStats { rays: 0, pixels: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Request {
|
enum Request {
|
||||||
Pixel { x: usize, y: usize },
|
Pixel { x: usize, y: usize },
|
||||||
Line { width: usize, y: usize },
|
Line { width: usize, y: usize },
|
||||||
|
|||||||
@ -57,7 +57,6 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
height: opt.height,
|
height: opt.height,
|
||||||
global_illumination: true,
|
global_illumination: true,
|
||||||
env_map: Some(EnvMap::new(skybox)),
|
env_map: Some(EnvMap::new(skybox)),
|
||||||
..Default::default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -115,6 +115,5 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
height: opt.height,
|
height: opt.height,
|
||||||
global_illumination: true,
|
global_illumination: true,
|
||||||
env_map: Some(EnvMap::new(skybox)),
|
env_map: Some(EnvMap::new(skybox)),
|
||||||
..Default::default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ use rand::Rng;
|
|||||||
use crate::texture::Texture;
|
use crate::texture::Texture;
|
||||||
use crate::vec3::Vec3;
|
use crate::vec3::Vec3;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Mandelbrot {
|
pub struct Mandelbrot {
|
||||||
palette: Vec<Vec3>,
|
palette: Vec<Vec3>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
|
imports_granularity = "Crate"
|
||||||
format_code_in_doc_comments = true
|
format_code_in_doc_comments = true
|
||||||
|
|||||||
2
rtiow/tracer/rustfmt.toml
Normal file
2
rtiow/tracer/rustfmt.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
imports_granularity = "Crate"
|
||||||
|
format_code_in_doc_comments = true
|
||||||
@ -4,7 +4,6 @@ use std::fs;
|
|||||||
#[cfg(feature = "profile")]
|
#[cfg(feature = "profile")]
|
||||||
use cpuprofiler::PROFILER;
|
use cpuprofiler::PROFILER;
|
||||||
use log::info;
|
use log::info;
|
||||||
use stderrlog;
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use renderer::renderer::render;
|
use renderer::renderer::render;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user