From d5d24cee0392f4169ec59c1a6b795bfe53b65222 Mon Sep 17 00:00:00 2001 From: "max.nuding" Date: Thu, 7 Jul 2022 07:42:32 +0200 Subject: [PATCH] Finish perlin noise --- src/main.rs | 2 +- src/noise.rs | 7 +++++-- src/perlin.rs | 37 ++++++++++++++++++------------------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0cdc9a9..6108429 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,7 +48,7 @@ fn two_spheres() -> HittableList { } fn two_perlin_spheres() -> HittableList { let mut world:HittableList = Vec::new(); - let noise = NoiseTexture { noise: Perlin::new() }; + let noise = NoiseTexture { noise: Perlin::new(), scale: 4.0 }; let noise_material = Arc::new(Material::Lambertian(Lambertian::textured(Arc::new(noise)))); world.push(Arc::new(Sphere { center: Point3::new(0.0, -1000.0, 0.0), diff --git a/src/noise.rs b/src/noise.rs index 2dc5eb2..dcb4287 100644 --- a/src/noise.rs +++ b/src/noise.rs @@ -3,11 +3,14 @@ use crate::{Color, Point3}; use crate::texture::Texture; pub struct NoiseTexture { - pub noise: Perlin + pub noise: Perlin, + pub scale: f64 } impl Texture for NoiseTexture { fn value(&self, _u: f64, _v: f64, point: &Point3) -> Color { - Color::new(1.0, 1.0, 1.0) * self.noise.noise(point) + Color::new(1.0, 1.0, 1.0) + * 0.5 + * (1.0 + self.noise.noise(&(*point * self.scale))) } } diff --git a/src/perlin.rs b/src/perlin.rs index f573a32..92f7925 100644 --- a/src/perlin.rs +++ b/src/perlin.rs @@ -1,9 +1,8 @@ -use rand::distributions::{Distribution, Uniform}; use rand::Rng; -use crate::Point3; +use crate::{Point3, Vec3}; pub struct Perlin { - ranfloat: Vec, + ranvec: Vec, perm_x: Vec, perm_y: Vec, perm_z: Vec, @@ -13,12 +12,10 @@ impl Perlin { const POINT_COUNT: usize = 256; pub fn new() -> Self { - let range = Uniform::from(0.0..1.0); - let mut rng = rand::thread_rng(); - let mut ranfloat = Vec::with_capacity(Perlin::POINT_COUNT); - (0..Perlin::POINT_COUNT).for_each(|_i|ranfloat.push(range.sample(&mut rng))); + let mut ranvec = Vec::with_capacity(Perlin::POINT_COUNT); + (0..Perlin::POINT_COUNT).for_each(|_i|ranvec.push(Vec3::random(-1.0, 1.0))); Perlin { - ranfloat, + ranvec, perm_x: Perlin::perlin_generate_perm(), perm_y: Perlin::perlin_generate_perm(), perm_z: Perlin::perlin_generate_perm(), @@ -29,13 +26,10 @@ impl Perlin { let u = point.x() - point.x().floor(); let v = point.y() - point.y().floor(); let w = point.z() - point.z().floor(); - let u = u * u * (3.0 - 2.0 * u); - let v = v * v * (3.0 - 2.0 * v); - let w = w * w * (3.0 - 2.0 * w); let i = point.x().floor() as i32; let j = point.y().floor() as i32; let k = point.z().floor() as i32; - let mut c: [[[f64; 2]; 2]; 2] = [[[0.0; 2]; 2]; 2]; + let mut c: [[[Vec3; 2]; 2]; 2] = [[[Vec3::default(); 2]; 2]; 2]; for di in 0..2 { for dj in 0..2 { @@ -43,11 +37,11 @@ impl Perlin { let idx = self.perm_x[((i+di) & 255) as usize] ^ self.perm_y[((j+dj) & 255) as usize] ^ self.perm_z[((k+dk) & 255) as usize]; - c[di as usize][dj as usize][dk as usize] = self.ranfloat[idx]; + c[di as usize][dj as usize][dk as usize] = self.ranvec[idx]; } } } - Perlin::trilinerar_interpolation(c, u, v, w) + Perlin::perlin_interp(c, u, v, w) } fn perlin_generate_perm() -> Vec { @@ -61,7 +55,11 @@ impl Perlin { p } - fn trilinerar_interpolation(c: [[[f64; 2]; 2]; 2], u: f64, v: f64, w: f64) -> f64 { + fn perlin_interp(c: [[[Vec3; 2]; 2]; 2], u: f64, v: f64, w: f64) -> f64 { + let uu = u * u * (3.0 - 2.0 * u); + let vv = v * v * (3.0 - 2.0 * v); + let ww = w * w * (3.0 - 2.0 * w); + let mut accum = 0.0; for i in 0..2 { for j in 0..2 { @@ -69,10 +67,11 @@ impl Perlin { let ifl = i as f64; let jfl = j as f64; let kfl = k as f64; - accum += (ifl*u + (1.0-ifl)*(1.0-u)) * - (jfl*v + (1.0-jfl)*(1.0-v)) * - (kfl*w + (1.0-kfl)*(1.0-w)) * - c[i][j][k]; + let weight_v = Vec3::new(u - ifl, v - jfl, w - kfl); + accum += (ifl*uu + (1.0-ifl)*(1.0-uu)) + * (jfl*vv + (1.0-jfl)*(1.0-vv)) + * (kfl*ww + (1.0-kfl)*(1.0-ww)) + * (c[i][j][k]).dot(&weight_v); } } }