From 31f6d6c3d7989ee14fbb1fc5c6fcdfb9a4f70c7a Mon Sep 17 00:00:00 2001 From: Zelda Hessler Date: Sat, 24 Jul 2021 12:39:32 -0500 Subject: [PATCH] update: make DW noise more wacky --- src/noise/domain_warping_noise.rs | 121 +++++++++++++++++++++++++++--- src/noise/mod.rs | 14 ++-- 2 files changed, 120 insertions(+), 15 deletions(-) diff --git a/src/noise/domain_warping_noise.rs b/src/noise/domain_warping_noise.rs index 63f0efe..35b3cc2 100644 --- a/src/noise/domain_warping_noise.rs +++ b/src/noise/domain_warping_noise.rs @@ -1,33 +1,134 @@ +use log::trace; use noise::{Fbm, NoiseFn}; +use rand::{prelude::StdRng, Rng, SeedableRng}; pub struct DomainWarpingNoise { fbm: Fbm, + params: DomainWarpingNoiseParams, } impl DomainWarpingNoise { - pub fn new() -> Self { - Self { fbm: Fbm::new() } + pub fn new(params: DomainWarpingNoiseParams) -> Self { + Self { + fbm: Fbm::new(), + params, + } + } + + pub fn inigo() -> Self { + Self { + fbm: Fbm::new(), + params: DomainWarpingNoiseParams::inigo(), + } + } +} + +impl Default for DomainWarpingNoise { + fn default() -> Self { + Self { + fbm: Fbm::new(), + params: Default::default(), + } + } +} + +#[derive(Debug)] +pub struct DomainWarpingNoiseParams { + q: [f64; 9], + r: [f64; 9], + qn: f64, + rn: f64, +} + +impl DomainWarpingNoiseParams { + pub fn new(q: [f64; 9], r: [f64; 9], qn: f64, rn: f64) -> Self { + Self { q, r, qn, rn } + } + + pub fn random() -> Self { + // rng.gen handles arrays just fine but fills them with numbers between 0.0 and 1.0 + // gen_range allows for numbers from a larger range but it can't handle arrays :( + let mut rng = StdRng::from_entropy(); + let q_range = -100.0..100.0; + let q: [f64; 9] = [ + rng.gen_range(q_range.clone()), + rng.gen_range(q_range.clone()), + rng.gen_range(q_range.clone()), + rng.gen_range(q_range.clone()), + rng.gen_range(q_range.clone()), + rng.gen_range(q_range.clone()), + rng.gen_range(q_range.clone()), + rng.gen_range(q_range.clone()), + rng.gen_range(q_range.clone()), + ]; + + let r_range = -100.0..100.0; + let r: [f64; 9] = [ + rng.gen_range(r_range.clone()), + rng.gen_range(r_range.clone()), + rng.gen_range(r_range.clone()), + rng.gen_range(r_range.clone()), + rng.gen_range(r_range.clone()), + rng.gen_range(r_range.clone()), + rng.gen_range(r_range.clone()), + rng.gen_range(r_range.clone()), + rng.gen_range(r_range.clone()), + ]; + let qn: f64 = rng.gen_range(0.001..5.0); + let rn: f64 = rng.gen_range(0.001..5.0); + + let s = Self { q, r, qn, rn }; + + trace!( + "Creating random parameters for domain warping noise:\n{:?}", + s + ); + + s + } + + // https://www.iquilezles.org/www/articles/warp/warp.htm + fn inigo() -> Self { + Self { + q: [0.0, 0.0, 0.0, 5.2, 1.3, 0.0, 0.0, 0.0, 0.0], + r: [1.7, 9.2, 0.0, 8.3, 2.8, 0.0, 0.0, 0.0, 0.0], + qn: 4.0, + rn: 4.0, + } + } +} + +impl Default for DomainWarpingNoiseParams { + fn default() -> Self { + Self { + q: Default::default(), + r: Default::default(), + qn: 1.0, + rn: 1.0, + } } } // Image for f(p) = fbm(p+fbm(p+fbm(p))) impl NoiseFn<[f64; 3]> for DomainWarpingNoise { fn get(&self, p: [f64; 3]) -> f64 { + let [q0, q1, q2, q3, q4, q5, q6, q7, q8] = self.params.q; let q = vec3( - self.fbm.get(add(p, vec3(0.0, 0.0, 1.0))), - self.fbm.get(add(p, vec3(5.2, 1.3, 1.0))), - self.fbm.get(add(p, vec3(1.0, 1.0, 1.0))), + self.fbm.get(add(p, vec3(q0, q1, q2))), + self.fbm.get(add(p, vec3(q3, q4, q5))), + self.fbm.get(add(p, vec3(q6, q7, q8))), ); - let q = mul_n(q, 4.0); + let q = mul_n(q, self.params.qn); + let [r0, r1, r2, r3, r4, r5, r6, r7, r8] = self.params.r; let r = vec3( - self.fbm.get(add(p, add(q, vec3(1.7, 9.2, 1.0)))), - self.fbm.get(add(p, add(q, vec3(8.3, 2.8, 1.0)))), - self.fbm.get(add(p, add(q, vec3(1.0, 1.0, 1.0)))), + self.fbm.get(add(p, add(q, vec3(r0, r1, r2)))), + self.fbm.get(add(p, add(q, vec3(r3, r4, r5)))), + self.fbm.get(add(p, add(q, vec3(r6, r7, r8)))), ); - let r = mul_n(r, 4.0); + let r = mul_n(r, self.params.rn); self.fbm.get(add(p, r)) } } diff --git a/src/noise/mod.rs b/src/noise/mod.rs index c15bbad..88513a8 100644 --- a/src/noise/mod.rs +++ b/src/noise/mod.rs @@ -3,20 +3,24 @@ mod domain_warping_noise; use domain_warping_noise::DomainWarpingNoise; use noise::NoiseFn; +use crate::noise::domain_warping_noise::DomainWarpingNoiseParams; + pub fn new_noise_fn_by_index(index: usize) -> Box> { match index { 0 => { + println!("now using Domain Warping Noise generator"); + let dwn_params = DomainWarpingNoiseParams::random(); + Box::new(DomainWarpingNoise::new(dwn_params)) + } + 1 => { println!("now using Billowy Noise generator"); + // TODO allow setting frequency, lacunarity, octaves, persistence Box::new(noise::Billow::new()) } - 1 => { + 2 => { println!("now using Heterogenous Multifractal Noise generator"); Box::new(noise::BasicMulti::new()) } - 2 => { - println!("now using Domain Warping Noise generator"); - Box::new(DomainWarpingNoise::new()) - } 3 => { println!("now using Fractal Brownian Motion Noise generator"); Box::new(noise::Fbm::new())