rtiow: add blox with gloxy edges.
Fixed bug in kdtree that this uncovered. Marked Hit and it's dependencies as needing to implement the Debug trait.
This commit is contained in:
parent
b432e9a6dd
commit
4066bf4b85
@ -9,6 +9,7 @@ use crate::{
|
||||
ray::Ray,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum BVHNode {
|
||||
Leaf(Box<dyn Hit>),
|
||||
Branch {
|
||||
@ -178,6 +179,7 @@ impl Hit for BVHNode {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BVH {
|
||||
root: BVHNode,
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ use crate::{
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConstantMedium<H, T>
|
||||
where
|
||||
H: Hit,
|
||||
|
||||
@ -11,6 +11,7 @@ use crate::{
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Cuboid {
|
||||
p_min: Vec3,
|
||||
p_max: Vec3,
|
||||
@ -21,6 +22,9 @@ impl Cuboid {
|
||||
// This clippy doesn't work right with Arc.
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub fn new(p_min: Vec3, p_max: Vec3, material: Arc<dyn Material>) -> Cuboid {
|
||||
assert!(p_min.x <= p_max.x);
|
||||
assert!(p_min.y <= p_max.y);
|
||||
assert!(p_min.z <= p_max.z);
|
||||
Cuboid {
|
||||
p_min,
|
||||
p_max,
|
||||
|
||||
@ -4,6 +4,7 @@ use crate::{
|
||||
ray::Ray,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FlipNormals<H>
|
||||
where
|
||||
H: Hit,
|
||||
|
||||
142
rtiow/renderer/src/glowybox.rs
Normal file
142
rtiow/renderer/src/glowybox.rs
Normal file
@ -0,0 +1,142 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
aabb::AABB,
|
||||
cuboid::Cuboid,
|
||||
flip_normals::FlipNormals,
|
||||
hitable::{Hit, HitRecord},
|
||||
hitable_list::HitableList,
|
||||
material::Material,
|
||||
ray::Ray,
|
||||
rect::{XYRect, XZRect, YZRect},
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Glowybox {
|
||||
p_min: Vec3,
|
||||
p_max: Vec3,
|
||||
main: Cuboid,
|
||||
edges: [Cuboid; 12],
|
||||
}
|
||||
|
||||
impl Glowybox {
|
||||
// This clippy doesn't work right with Arc.
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub fn new(
|
||||
p_min: Vec3,
|
||||
p_max: Vec3,
|
||||
edge_thickness: f32,
|
||||
main_material: Arc<dyn Material>,
|
||||
edge_material: Arc<dyn Material>,
|
||||
) -> Glowybox {
|
||||
assert!(p_min.x < p_max.x);
|
||||
assert!(p_min.y < p_max.y);
|
||||
assert!(p_min.z < p_max.z);
|
||||
let main = Cuboid::new(p_min, p_max, main_material);
|
||||
// Top edges
|
||||
let ht = edge_thickness / 2.;
|
||||
let edges = [
|
||||
// Top edges
|
||||
Cuboid::new(
|
||||
[p_min.x - ht, p_max.y - ht, p_min.z - ht].into(),
|
||||
[p_min.x + ht, p_max.y + ht, p_max.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
Cuboid::new(
|
||||
[p_min.x - ht, p_max.y - ht, p_min.z - ht].into(),
|
||||
[p_max.x + ht, p_max.y + ht, p_min.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
Cuboid::new(
|
||||
[p_max.x - ht, p_max.y - ht, p_min.z - ht].into(),
|
||||
[p_max.x + ht, p_max.y + ht, p_max.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
Cuboid::new(
|
||||
[p_min.x - ht, p_max.y - ht, p_max.z - ht].into(),
|
||||
[p_max.x + ht, p_max.y + ht, p_max.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
// Bottom edges
|
||||
Cuboid::new(
|
||||
[p_min.x - ht, p_min.y - ht, p_min.z - ht].into(),
|
||||
[p_min.x + ht, p_min.y + ht, p_max.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
Cuboid::new(
|
||||
[p_min.x - ht, p_min.y - ht, p_min.z - ht].into(),
|
||||
[p_max.x + ht, p_min.y + ht, p_min.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
Cuboid::new(
|
||||
[p_max.x - ht, p_min.y - ht, p_min.z - ht].into(),
|
||||
[p_max.x + ht, p_min.y + ht, p_max.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
Cuboid::new(
|
||||
[p_min.x - ht, p_min.y - ht, p_max.z - ht].into(),
|
||||
[p_max.x + ht, p_min.y + ht, p_max.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
// Middle edges
|
||||
Cuboid::new(
|
||||
[p_min.x - ht, p_min.y - ht, p_min.z - ht].into(),
|
||||
[p_min.x + ht, p_max.y + ht, p_min.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
Cuboid::new(
|
||||
[p_min.x - ht, p_min.y - ht, p_max.z - ht].into(),
|
||||
[p_min.x + ht, p_max.y + ht, p_max.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
Cuboid::new(
|
||||
[p_max.x - ht, p_min.y - ht, p_min.z - ht].into(),
|
||||
[p_max.x + ht, p_max.y + ht, p_min.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
Cuboid::new(
|
||||
[p_max.x - ht, p_min.y - ht, p_max.z - ht].into(),
|
||||
[p_max.x + ht, p_max.y + ht, p_max.z + ht].into(),
|
||||
Arc::clone(&edge_material),
|
||||
),
|
||||
];
|
||||
let p_min = [p_min.x - ht, p_min.y - ht, p_min.z - ht].into();
|
||||
let p_max = [p_max.x + ht, p_max.y + ht, p_max.z + ht].into();
|
||||
Glowybox {
|
||||
p_min,
|
||||
p_max,
|
||||
main,
|
||||
edges,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hit for Glowybox {
|
||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||
let mut edge_hit = None;
|
||||
for edge in &self.edges {
|
||||
if let Some(hit) = edge.hit(r, t_min, t_max) {
|
||||
edge_hit = Some(hit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let main_hit = self.main.hit(r, t_min, t_max);
|
||||
match (edge_hit, main_hit) {
|
||||
(Some(ehit), Some(mhit)) => {
|
||||
if mhit.t < ehit.t {
|
||||
Some(mhit)
|
||||
} else {
|
||||
Some(ehit)
|
||||
}
|
||||
}
|
||||
(Some(ehit), None) => Some(ehit),
|
||||
(None, Some(mhit)) => Some(mhit),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB> {
|
||||
Some(AABB::new(self.p_min, self.p_max))
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
use std::sync::Arc;
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
|
||||
use crate::{aabb::AABB, material::Material, ray::Ray, vec3::Vec3};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HitRecord<'m> {
|
||||
pub t: f32,
|
||||
pub uv: (f32, f32),
|
||||
@ -10,7 +11,7 @@ pub struct HitRecord<'m> {
|
||||
pub material: &'m dyn Material,
|
||||
}
|
||||
|
||||
pub trait Hit: Send + Sync {
|
||||
pub trait Hit: Send + Sync + Debug {
|
||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord>;
|
||||
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB>;
|
||||
}
|
||||
@ -23,3 +24,12 @@ impl Hit for Arc<dyn Hit> {
|
||||
(**self).bounding_box(t_min, t_max)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hit for Box<dyn Hit> {
|
||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||
(**self).hit(r, t_min, t_max)
|
||||
}
|
||||
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB> {
|
||||
(**self).bounding_box(t_min, t_max)
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ use crate::{
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct HitableList {
|
||||
list: Vec<Box<dyn Hit>>,
|
||||
}
|
||||
|
||||
@ -5,9 +5,11 @@ use log::info;
|
||||
use crate::{
|
||||
aabb::{surrounding_box, AABB},
|
||||
hitable::{Hit, HitRecord},
|
||||
hitable_list::HitableList,
|
||||
ray::Ray,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum KDTree {
|
||||
Leaf(Box<dyn Hit>),
|
||||
Branch {
|
||||
@ -102,6 +104,14 @@ impl KDTree {
|
||||
}),
|
||||
_ => panic!("Unreachable"),
|
||||
};
|
||||
info!("left_half {:?}", left_half);
|
||||
info!("right_half {:?}", right_half);
|
||||
if left_half.is_empty() {
|
||||
return KDTree::Leaf(Box::new(HitableList::new(right_half)));
|
||||
};
|
||||
if right_half.is_empty() {
|
||||
return KDTree::Leaf(Box::new(HitableList::new(left_half)));
|
||||
};
|
||||
KDTree::Branch {
|
||||
left: Box::new(KDTree::new(left_half, t_min, t_max)),
|
||||
right: Box::new(KDTree::new(right_half, t_min, t_max)),
|
||||
|
||||
@ -4,6 +4,7 @@ pub mod camera;
|
||||
pub mod constant_medium;
|
||||
pub mod cuboid;
|
||||
pub mod flip_normals;
|
||||
pub mod glowybox;
|
||||
pub mod hitable;
|
||||
pub mod hitable_list;
|
||||
pub mod human;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use std::sync::Arc;
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
|
||||
use rand::{self, Rng};
|
||||
|
||||
@ -20,14 +20,14 @@ fn random_in_unit_sphere() -> Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ScatterResponse {
|
||||
pub scattered: Ray,
|
||||
pub attenutation: Vec3,
|
||||
pub reflected: bool,
|
||||
}
|
||||
|
||||
pub trait Material: Send + Sync {
|
||||
pub trait Material: Send + Sync + Debug {
|
||||
fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse;
|
||||
fn emitted(&self, _u: f32, _v: f32, _p: Vec3) -> Vec3 {
|
||||
Vec3::new(0., 0., 0.)
|
||||
@ -52,6 +52,7 @@ impl Material for Box<dyn Material> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Isotropic<T>
|
||||
where
|
||||
T: Texture,
|
||||
@ -82,6 +83,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Lambertian<T>
|
||||
where
|
||||
T: Texture,
|
||||
@ -113,6 +115,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Metal {
|
||||
albedo: Vec3,
|
||||
fuzzy: f32,
|
||||
@ -167,6 +170,7 @@ fn schlick(cosine: f32, ref_idx: f32) -> f32 {
|
||||
r0 + (1. - r0) * (1. - cosine).powf(5.)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Dielectric {
|
||||
ref_idx: f32,
|
||||
}
|
||||
@ -213,6 +217,7 @@ impl Material for Dielectric {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DiffuseLight<T>
|
||||
where
|
||||
T: Texture,
|
||||
|
||||
@ -7,6 +7,7 @@ use crate::{
|
||||
vec3::{dot, Vec3},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MovingSphere<M>
|
||||
where
|
||||
M: Material,
|
||||
|
||||
@ -5,6 +5,7 @@ use rand;
|
||||
use crate::{noise::NoiseSource, vec3::Vec3};
|
||||
|
||||
const NOISE_SIZE: usize = 128;
|
||||
#[derive(Debug)]
|
||||
pub struct Lode {
|
||||
// Using fixed array causes stack overflow.
|
||||
noise: Vec<Vec<Vec<f32>>>, //[[[f32; NOISE_SIZE]; NOISE_SIZE]; NOISE_SIZE],
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
pub mod lode;
|
||||
pub mod perlin;
|
||||
|
||||
use std::f32::consts::PI;
|
||||
use std::{f32::consts::PI, fmt::Debug};
|
||||
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
use crate::vec3::Vec3;
|
||||
|
||||
pub trait NoiseSource: Send + Sync {
|
||||
pub trait NoiseSource: Send + Sync + Debug {
|
||||
/// value returns noise on the interval [0., 1.).
|
||||
fn value(&self, p: Vec3) -> f32;
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ use crate::{
|
||||
vec3::{dot, Vec3},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Perlin {
|
||||
ran_vec: Vec<Vec3>,
|
||||
perm_x: Vec<usize>,
|
||||
|
||||
@ -8,6 +8,7 @@ use crate::{
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct XYRect<M>
|
||||
where
|
||||
M: Material,
|
||||
@ -69,6 +70,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct XZRect<M>
|
||||
where
|
||||
M: Material,
|
||||
@ -130,6 +132,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct YZRect<M>
|
||||
where
|
||||
M: Material,
|
||||
|
||||
@ -42,6 +42,7 @@ pub enum Model {
|
||||
PerlinDebug,
|
||||
Spheramid,
|
||||
Test,
|
||||
Tron,
|
||||
Tutorial,
|
||||
}
|
||||
|
||||
@ -58,6 +59,7 @@ impl Model {
|
||||
Model::PerlinDebug => scenes::perlin_debug::new(opt),
|
||||
Model::Spheramid => scenes::spheramid::new(opt),
|
||||
Model::Test => scenes::test::new(opt),
|
||||
Model::Tron => scenes::tron::new(opt),
|
||||
Model::Tutorial => scenes::tutorial::new(opt),
|
||||
}
|
||||
}
|
||||
@ -86,6 +88,7 @@ impl str::FromStr for Model {
|
||||
"perlin_debug" => Ok(Model::PerlinDebug),
|
||||
"spheramid" => Ok(Model::Spheramid),
|
||||
"test" => Ok(Model::Test),
|
||||
"tron" => Ok(Model::Tron),
|
||||
"tutorial" => Ok(Model::Tutorial),
|
||||
_ => Err(ModelParseError(s.to_owned())),
|
||||
}
|
||||
@ -105,6 +108,7 @@ impl std::string::ToString for Model {
|
||||
Model::PerlinDebug => "perlin_debug".to_string(),
|
||||
Model::Spheramid => "spheramid".to_string(),
|
||||
Model::Test => "test".to_string(),
|
||||
Model::Tron => "tron".to_string(),
|
||||
Model::Tutorial => "tutorial".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ use crate::{
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RotateY<H>
|
||||
where
|
||||
H: Hit,
|
||||
|
||||
@ -8,4 +8,5 @@ pub mod mandelbrot;
|
||||
pub mod perlin_debug;
|
||||
pub mod spheramid;
|
||||
pub mod test;
|
||||
pub mod tron;
|
||||
pub mod tutorial;
|
||||
|
||||
135
rtiow/renderer/src/scenes/tron.rs
Normal file
135
rtiow/renderer/src/scenes/tron.rs
Normal file
@ -0,0 +1,135 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use image;
|
||||
use log::info;
|
||||
use rand;
|
||||
|
||||
use crate::{
|
||||
camera::Camera,
|
||||
cuboid::Cuboid,
|
||||
glowybox::Glowybox,
|
||||
hitable::Hit,
|
||||
hitable_list::HitableList,
|
||||
kdtree::KDTree,
|
||||
material::{DiffuseLight, Lambertian},
|
||||
noise::{perlin::Perlin, NoiseType},
|
||||
rect::{XYRect, XZRect, YZRect},
|
||||
renderer::{Opt, Scene},
|
||||
sphere::Sphere,
|
||||
texture::{ConstantTexture, ImageTexture, NoiseTexture},
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
pub fn new(opt: &Opt) -> Scene {
|
||||
let lookfrom = Vec3::new(20., 20., 20.);
|
||||
let lookat = Vec3::new(0., 1., 0.);
|
||||
let dist_to_focus = 10.0;
|
||||
let aperture = 0.0;
|
||||
let time_min = 0.;
|
||||
let time_max = 1.;
|
||||
let camera = Camera::new(
|
||||
lookfrom,
|
||||
lookat,
|
||||
Vec3::new(0., 1., 0.),
|
||||
20.,
|
||||
opt.width as f32 / opt.height as f32,
|
||||
aperture,
|
||||
dist_to_focus,
|
||||
time_min,
|
||||
time_max,
|
||||
);
|
||||
let rng = &mut rand::thread_rng();
|
||||
let ground_color = if opt.use_accel {
|
||||
ConstantTexture::new(Vec3::new(1.0, 0.4, 0.4))
|
||||
} else {
|
||||
ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4))
|
||||
};
|
||||
|
||||
let world_image_bytes = include_bytes!("../../images/world.jpg");
|
||||
let it = ImageTexture::new(image::load_from_memory(world_image_bytes).unwrap().to_rgb());
|
||||
let noise_source = Perlin::new(rng);
|
||||
let noise_type = NoiseType::Scale(10.);
|
||||
|
||||
let lights: Vec<Box<dyn Hit>> = vec![
|
||||
Box::new(XZRect::new(
|
||||
-100.,
|
||||
100.,
|
||||
-100.,
|
||||
1000.,
|
||||
60.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(1., 1., 1.))),
|
||||
)),
|
||||
Box::new(YZRect::new(
|
||||
1.,
|
||||
3.,
|
||||
-1.,
|
||||
1.,
|
||||
4.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(4., 0., 4.))),
|
||||
)),
|
||||
Box::new(YZRect::new(
|
||||
1.,
|
||||
3.,
|
||||
-1.,
|
||||
1.,
|
||||
-4.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(0., 4., 0.))),
|
||||
)),
|
||||
Box::new(XZRect::new(
|
||||
-1.,
|
||||
1.,
|
||||
-1.,
|
||||
1.,
|
||||
6.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(4., 4., 0.))),
|
||||
)),
|
||||
Box::new(XYRect::new(
|
||||
-1.,
|
||||
1.,
|
||||
1.,
|
||||
3.,
|
||||
-4.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(0., 0., 4.))),
|
||||
)),
|
||||
Box::new(XYRect::new(
|
||||
-1.,
|
||||
1.,
|
||||
1.,
|
||||
3.,
|
||||
4.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(0., 4., 4.))),
|
||||
)),
|
||||
];
|
||||
let mut objects: Vec<Box<dyn Hit>> = vec![
|
||||
// Earth sized sphere
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(0., -1010., 0.),
|
||||
1000.,
|
||||
Lambertian::new(ground_color),
|
||||
// Lambertian::new(NoiseTexture::new(noise_source, noise_type)),
|
||||
)),
|
||||
Box::new(Glowybox::new(
|
||||
[-4., -4., -4.].into(),
|
||||
[4., 4., 4.].into(),
|
||||
0.01,
|
||||
Arc::new(Lambertian::new(ConstantTexture::new([0., 0., 0.]))),
|
||||
Arc::new(DiffuseLight::new(ConstantTexture::new([100., 0., 0.]))),
|
||||
)),
|
||||
];
|
||||
objects.extend(lights);
|
||||
info!("objects {:?}", objects);
|
||||
let world: Box<dyn Hit> = if opt.use_accel {
|
||||
Box::new(KDTree::new(objects, time_min, time_max))
|
||||
} else {
|
||||
Box::new(HitableList::new(objects))
|
||||
};
|
||||
Scene {
|
||||
camera,
|
||||
world,
|
||||
subsamples: opt.subsamples,
|
||||
num_threads: opt.num_threads,
|
||||
width: opt.width,
|
||||
height: opt.height,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ use crate::{
|
||||
vec3::{dot, Vec3},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Sphere<M>
|
||||
where
|
||||
M: Material,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use crate::{texture::Texture, vec3::Vec3};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CheckerTexture<T>
|
||||
where
|
||||
T: Texture,
|
||||
|
||||
@ -3,6 +3,7 @@ use rand::{self, Rng};
|
||||
|
||||
use crate::{texture::Texture, vec3::Vec3};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Mandelbrot {
|
||||
palette: Vec<Vec3>,
|
||||
}
|
||||
|
||||
@ -9,11 +9,11 @@ pub use crate::texture::{
|
||||
mandelbrot::Mandelbrot, noise::NoiseTexture,
|
||||
};
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
|
||||
use crate::vec3::Vec3;
|
||||
|
||||
pub trait Texture: Send + Sync {
|
||||
pub trait Texture: Send + Sync + Debug {
|
||||
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3;
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ use crate::{
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NoiseTexture<N>
|
||||
where
|
||||
N: NoiseSource,
|
||||
|
||||
@ -5,6 +5,7 @@ use crate::{
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Translate<H>
|
||||
where
|
||||
H: Hit,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user