1
0

wip: perlin noise

This commit is contained in:
Ishan Jain 2021-03-05 20:03:33 +05:30
parent f56947eca2
commit aa74b321b8
No known key found for this signature in database
GPG Key ID: F261A0E73038D89D
8 changed files with 70 additions and 14 deletions

View File

@ -29,13 +29,13 @@ impl Demo for PerlinNoiseBall {
world.push(Arc::new(Sphere::new( world.push(Arc::new(Sphere::new(
Vec3::new(0.0, -1000.0, 0.0), Vec3::new(0.0, -1000.0, 0.0),
1000.0, 1000.0,
Lambertian::new(PerlinNoise::new(&mut rng)), Lambertian::new(PerlinNoise::with_scale(&mut rng, 4.0)),
))); )));
world.push(Arc::new(Sphere::new( world.push(Arc::new(Sphere::new(
Vec3::new(0.0, 2.0, 0.0), Vec3::new(0.0, 2.0, 0.0),
2.0, 2.0,
Lambertian::new(PerlinNoise::new(&mut rng)), Lambertian::new(PerlinNoise::with_scale(&mut rng, 4.0)),
))); )));
BvhNode::new(&mut rng, &mut world, 0.0, 1.0) BvhNode::new(&mut rng, &mut world, 0.0, 1.0)

View File

@ -23,7 +23,7 @@ use demos::Demo;
use std::time::Instant; use std::time::Instant;
const NUM_SAMPLES: u8 = 255; const NUM_SAMPLES: u8 = 25;
const VERTICAL_PARTITION: usize = 12; const VERTICAL_PARTITION: usize = 12;
const HORIZONTAL_PARTITION: usize = 12; const HORIZONTAL_PARTITION: usize = 12;
const WIDTH: usize = 1920; const WIDTH: usize = 1920;

View File

@ -22,7 +22,7 @@ impl<T: Texture + Send + Sync> Material for Lambertian<T> {
let scattered_ray = Ray::new(hit_rec.p, scatter_direction, ray.time()); let scattered_ray = Ray::new(hit_rec.p, scatter_direction, ray.time());
( (
self.albedo.value(hit_rec.u, hit_rec.v, &hit_rec.p), self.albedo.value(hit_rec.u, hit_rec.v, hit_rec.p),
Some(scattered_ray), Some(scattered_ray),
) )
} }

View File

@ -12,7 +12,7 @@ impl<T: Texture> Checker<T> {
} }
impl<T: Texture> Texture for Checker<T> { impl<T: Texture> Texture for Checker<T> {
fn value(&self, u: f64, v: f64, p: &Vec3) -> 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()); 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 { if sine_wave < 0.0 {

View File

@ -11,5 +11,5 @@ pub use solid::Solid;
use crate::types::Vec3; use crate::types::Vec3;
pub trait Texture { pub trait Texture {
fn value(&self, u: f64, v: f64, p: &Vec3) -> Vec3; fn value(&self, u: f64, v: f64, p: Vec3) -> Vec3;
} }

View File

@ -36,13 +36,59 @@ impl Perlin {
p p
} }
pub fn noise(&self, p: &Vec3) -> f64 { pub fn noise(&self, p: Vec3) -> f64 {
let i = ((4.0 * p.x()) as i32 & 255) as usize; let i = p.x().floor() as i32;
let j = ((4.0 * p.y()) as i32 & 255) as usize; let j = p.y().floor() as i32;
let k = ((4.0 * p.z()) as i32 & 255) as usize; let k = p.z().floor() as i32;
self.points[self.permute_x[i] ^ self.permute_y[j] ^ self.permute_z[k]] let mut smooth_grid = [[[0.0; 2]; 2]; 2];
for (di, a) in smooth_grid.iter_mut().enumerate() {
let di = di as i32;
for (dj, b) in a.iter_mut().enumerate() {
let dj = dj as i32;
for (dk, c) in b.iter_mut().enumerate() {
let dk = dk as i32;
*c = self.points[self.permute_x[((i + di) & 255) as usize]
^ self.permute_y[((j + dj) & 255) as usize]
^ self.permute_z[((k + dk) & 255) as usize]]
} }
}
}
let mut u = p.x() - p.x().floor();
let mut v = p.y() - p.y().floor();
let mut w = p.z() - p.z().floor();
// Hermitian smoothing so we don't see obvious grid features in the picture
// Those features show up when we interpolate colors. Those features are
// also called mach bands
u = u * u * (3.0 - 2.0 * u);
v = v * v * (3.0 - 2.0 * v);
w = w * w * (3.0 - 2.0 * w);
return trilinear_interpolate(smooth_grid, u, v, w);
}
}
fn trilinear_interpolate(smooth_grid: [[[f64; 2]; 2]; 2], u: f64, v: f64, w: f64) -> f64 {
let mut acc = 0.0;
for (di, a) in smooth_grid.iter().enumerate() {
let di = di as f64;
for (dj, b) in a.iter().enumerate() {
let dj = dj as f64;
for (dk, c) in b.iter().enumerate() {
let dk = dk as f64;
acc += (di * u + (1.0 - di) * (1.0 - u))
* (dj * v + (1.0 - dj) * (1.0 - v))
* (dk * w + (1.0 - dk) * (1.0 - w))
* c;
}
}
}
acc
} }
fn permute<R: Rng + ?Sized>(rng: &mut R, p: &mut [usize]) { fn permute<R: Rng + ?Sized>(rng: &mut R, p: &mut [usize]) {

View File

@ -4,18 +4,28 @@ use crate::{texture::Perlin, types::Vec3, Texture};
pub struct PerlinNoise { pub struct PerlinNoise {
noise: Perlin, noise: Perlin,
scale: f64,
} }
impl PerlinNoise { impl PerlinNoise {
#[allow(dead_code)]
pub fn new<R: Rng + ?Sized>(rng: &mut R) -> Self { pub fn new<R: Rng + ?Sized>(rng: &mut R) -> Self {
Self { Self {
noise: Perlin::new(rng), noise: Perlin::new(rng),
scale: 1.0,
}
}
pub fn with_scale<R: Rng + ?Sized>(rng: &mut R, scale: f64) -> Self {
Self {
noise: Perlin::new(rng),
scale,
} }
} }
} }
impl Texture for PerlinNoise { impl Texture for PerlinNoise {
fn value(&self, _u: f64, _v: f64, p: &Vec3) -> Vec3 { fn value(&self, _u: f64, _v: f64, p: Vec3) -> Vec3 {
Vec3::new(1.0, 1.0, 1.0) * self.noise.noise(p) Vec3::new(1.0, 1.0, 1.0) * self.noise.noise(p * self.scale)
} }
} }

View File

@ -11,7 +11,7 @@ impl Solid {
} }
impl Texture for Solid { impl Texture for Solid {
fn value(&self, _u: f64, _v: f64, _p: &Vec3) -> Vec3 { fn value(&self, _u: f64, _v: f64, _p: Vec3) -> Vec3 {
self.color self.color
} }
} }