Trying to figure out perlin noise
This commit is contained in:
parent
b4d7ddfc4d
commit
4f2365dbca
|
@ -4,7 +4,6 @@ version = "0.1.0"
|
|||
authors = ["ishanjain28 <ishanjain28@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
[features]
|
||||
default = ["gui"]
|
||||
gui = ["sdl2"]
|
||||
|
|
|
@ -12,9 +12,11 @@ use std::{
|
|||
};
|
||||
|
||||
mod checkered_motion_blur;
|
||||
mod perlin_noise_ball;
|
||||
mod two_spheres;
|
||||
|
||||
pub use checkered_motion_blur::CheckeredMotionBlur;
|
||||
pub use perlin_noise_ball::PerlinNoiseBall;
|
||||
pub use two_spheres::TwoSpheres;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
61
src/demos/perlin_noise_ball.rs
Normal file
61
src/demos/perlin_noise_ball.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use rand::{prelude::SmallRng, SeedableRng};
|
||||
|
||||
use crate::{
|
||||
demos::{Demo, ParallelHit},
|
||||
materials::Lambertian,
|
||||
shapes::Sphere,
|
||||
texture::PerlinNoise,
|
||||
types::Vec3,
|
||||
BvhNode, Camera,
|
||||
};
|
||||
|
||||
pub struct PerlinNoiseBall {}
|
||||
|
||||
impl Demo for PerlinNoiseBall {
|
||||
type DemoT = BvhNode<Arc<dyn ParallelHit>>;
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"perlin_noise"
|
||||
}
|
||||
|
||||
fn world(&self) -> Self::DemoT {
|
||||
let mut world: Vec<Arc<dyn ParallelHit>> = Vec::with_capacity(500);
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut rng = SmallRng::from_rng(&mut rng).unwrap();
|
||||
|
||||
world.push(Arc::new(Sphere::new(
|
||||
Vec3::new(0.0, -1000.0, 0.0),
|
||||
1000.0,
|
||||
Lambertian::new(PerlinNoise::new(&mut rng)),
|
||||
)));
|
||||
|
||||
world.push(Arc::new(Sphere::new(
|
||||
Vec3::new(0.0, 2.0, 0.0),
|
||||
2.0,
|
||||
Lambertian::new(PerlinNoise::new(&mut rng)),
|
||||
)));
|
||||
|
||||
BvhNode::new(&mut rng, &mut world, 0.0, 1.0)
|
||||
}
|
||||
|
||||
fn camera(&self, aspect_ratio: f64) -> Camera {
|
||||
let lookfrom = Vec3::new(13.0, 2.0, 3.0);
|
||||
let lookat = Vec3::new(0.0, 0.0, 0.0);
|
||||
let aperture = 0.1;
|
||||
let focus_distance = 10.0;
|
||||
Camera::new(
|
||||
lookfrom,
|
||||
lookat,
|
||||
Vec3::new(0.0, 1.0, 0.0),
|
||||
20.0,
|
||||
aspect_ratio,
|
||||
aperture,
|
||||
focus_distance,
|
||||
0.0,
|
||||
1.0,
|
||||
)
|
||||
}
|
||||
}
|
14
src/main.rs
14
src/main.rs
|
@ -23,7 +23,7 @@ use demos::Demo;
|
|||
|
||||
use std::time::Instant;
|
||||
|
||||
const NUM_SAMPLES: u8 = 25;
|
||||
const NUM_SAMPLES: u8 = 255;
|
||||
const VERTICAL_PARTITION: usize = 12;
|
||||
const HORIZONTAL_PARTITION: usize = 12;
|
||||
const WIDTH: usize = 1920;
|
||||
|
@ -68,7 +68,7 @@ fn run(mut width: usize, mut height: usize) -> Result<(), String> {
|
|||
.map_err(|e| e.to_string())?;
|
||||
|
||||
let mut active_demo: &dyn Demo<DemoT = BvhNode<Arc<dyn ParallelHit>>> =
|
||||
&demos::CheckeredMotionBlur {};
|
||||
&demos::PerlinNoiseBall {};
|
||||
let mut should_update = true;
|
||||
|
||||
loop {
|
||||
|
@ -93,6 +93,10 @@ fn run(mut width: usize, mut height: usize) -> Result<(), String> {
|
|||
active_demo = &demos::TwoSpheres {};
|
||||
should_update = true;
|
||||
}
|
||||
Some(Keycode::Num3) => {
|
||||
active_demo = &demos::PerlinNoiseBall {};
|
||||
should_update = true;
|
||||
}
|
||||
None => unreachable!(),
|
||||
_ => (),
|
||||
};
|
||||
|
@ -130,9 +134,11 @@ fn run(mut width: usize, mut height: usize) -> Result<(), String> {
|
|||
|
||||
#[cfg(not(feature = "gui"))]
|
||||
fn run(width: usize, height: usize) -> Result<(), String> {
|
||||
run_and_save_demo(demos::CheckeredMotionBlur {}, width, height);
|
||||
// run_and_save_demo(demos::CheckeredMotionBlur {}, width, height);
|
||||
|
||||
run_and_save_demo(demos::TwoSpheres {}, width, height);
|
||||
//run_and_save_demo(demos::TwoSpheres {}, width, height);
|
||||
|
||||
run_and_save_demo(demos::PerlinNoiseBall {}, width, height);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ impl<T: Texture + Send + Sync> Material for Lambertian<T> {
|
|||
let scatter_direction = hit_rec.normal + random_point_in_unit_sphere(rng);
|
||||
let scattered_ray = Ray::new(hit_rec.p, scatter_direction, ray.time());
|
||||
|
||||
let mut p = hit_rec.p;
|
||||
self.albedo.value(hit_rec.u, hit_rec.v, &mut p);
|
||||
|
||||
(p, Some(scattered_ray))
|
||||
(
|
||||
self.albedo.value(hit_rec.u, hit_rec.v, &hit_rec.p),
|
||||
Some(scattered_ray),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ impl<T: Texture> Checker<T> {
|
|||
}
|
||||
|
||||
impl<T: Texture> Texture for Checker<T> {
|
||||
fn value(&self, u: f64, v: f64, p: &mut Vec3) {
|
||||
fn value(&self, u: f64, v: f64, p: &Vec3) -> Vec3 {
|
||||
let sine_wave = f64::sin(10.0 * p.x()) * f64::sin(10.0 * p.y()) * f64::sin(10.0 * p.z());
|
||||
|
||||
if sine_wave < 0.0 {
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
mod checker;
|
||||
mod perlin;
|
||||
mod perlin_noise;
|
||||
mod solid;
|
||||
|
||||
pub use checker::Checker;
|
||||
pub use perlin::Perlin;
|
||||
pub use perlin_noise::PerlinNoise;
|
||||
pub use solid::Solid;
|
||||
|
||||
use crate::types::Vec3;
|
||||
|
||||
pub trait Texture {
|
||||
fn value(&self, u: f64, v: f64, p: &mut Vec3);
|
||||
fn value(&self, u: f64, v: f64, p: &Vec3) -> Vec3;
|
||||
}
|
||||
|
|
70
src/texture/perlin.rs
Normal file
70
src/texture/perlin.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
use crate::types::Vec3;
|
||||
use rand::{distributions::Uniform, Rng};
|
||||
|
||||
const POINT_COUNT: usize = 256;
|
||||
|
||||
pub struct Perlin {
|
||||
points: Vec<f64>,
|
||||
|
||||
permute_x: Vec<usize>,
|
||||
permute_y: Vec<usize>,
|
||||
permute_z: Vec<usize>,
|
||||
}
|
||||
|
||||
impl Perlin {
|
||||
pub fn new<R: Rng + ?Sized>(rng: &mut R) -> Self {
|
||||
let mut points = vec![0.0; POINT_COUNT];
|
||||
|
||||
for p in points.iter_mut() {
|
||||
*p = rng.gen_range(0.0..=1.0)
|
||||
}
|
||||
|
||||
let permute_x = Self::perlin_generate_permutation(rng);
|
||||
let permute_y = Self::perlin_generate_permutation(rng);
|
||||
let permute_z = Self::perlin_generate_permutation(rng);
|
||||
|
||||
Self {
|
||||
points,
|
||||
permute_x,
|
||||
permute_y,
|
||||
permute_z,
|
||||
}
|
||||
}
|
||||
|
||||
fn perlin_generate_permutation<R: Rng + ?Sized>(rng: &mut R) -> Vec<usize> {
|
||||
let mut p = (0..POINT_COUNT).collect::<Vec<usize>>();
|
||||
permute(rng, &mut p);
|
||||
p
|
||||
}
|
||||
|
||||
pub fn noise(&self, p: &Vec3) -> f64 {
|
||||
let i = (4.0 * p.x()) as usize & 255;
|
||||
let j = (4.0 * p.y()) as usize & 255;
|
||||
let k = (4.0 * p.z()) as usize & 255;
|
||||
|
||||
// if p.x() > 1.0 && p.y() > 1.0 && p.z() > 1.0 {
|
||||
// println!(
|
||||
// "p = {} i = {} j = {} k = {} pi = {} pj = {} pk = {} point = {}",
|
||||
// p,
|
||||
// i,
|
||||
// j,
|
||||
// k,
|
||||
// self.permute_x[i],
|
||||
// self.permute_x[j],
|
||||
// self.permute_x[k],
|
||||
// self.points[self.permute_x[i] ^ self.permute_y[j] ^ self.permute_z[k]]
|
||||
// );
|
||||
// }
|
||||
|
||||
self.points[self.permute_x[i] ^ self.permute_y[j] ^ self.permute_z[k]]
|
||||
}
|
||||
}
|
||||
|
||||
fn permute<R: Rng + ?Sized>(rng: &mut R, p: &mut [usize]) {
|
||||
let l = p.len();
|
||||
|
||||
for i in (0..l).rev() {
|
||||
let r = rng.gen_range(0..=i);
|
||||
p.swap(i, r);
|
||||
}
|
||||
}
|
21
src/texture/perlin_noise.rs
Normal file
21
src/texture/perlin_noise.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use rand::Rng;
|
||||
|
||||
use crate::{texture::Perlin, types::Vec3, Texture};
|
||||
|
||||
pub struct PerlinNoise {
|
||||
noise: Perlin,
|
||||
}
|
||||
|
||||
impl PerlinNoise {
|
||||
pub fn new<R: Rng + ?Sized>(rng: &mut R) -> Self {
|
||||
Self {
|
||||
noise: Perlin::new(rng),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Texture for PerlinNoise {
|
||||
fn value(&self, _u: f64, _v: f64, p: &Vec3) -> Vec3 {
|
||||
Vec3::new(1.0, 1.0, 1.0) * self.noise.noise(p)
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ impl Solid {
|
|||
}
|
||||
|
||||
impl Texture for Solid {
|
||||
fn value(&self, _u: f64, _v: f64, p: &mut Vec3) {
|
||||
*p = self.color
|
||||
fn value(&self, _u: f64, _v: f64, _p: &Vec3) -> Vec3 {
|
||||
self.color
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user