csci5607/assignment-0/src/turbulence.rs
2023-02-20 22:05:32 -06:00

52 lines
1.2 KiB
Rust

// Follows this algorithm:
// https://www.scratchapixel.com/lessons/procedural-generation-virtual-worlds/procedural-patterns-noise-part-1/simple-pattern-examples.html
use rand::RngCore;
use crate::image::{Image, Pixel};
use crate::value_noise::ValueNoise;
use crate::vec2::Vec2;
pub fn generate_turbulence(
width: usize,
height: usize,
rng: impl RngCore,
) -> Image {
let mut noise_map = vec![0.0; width * height];
let noise = ValueNoise::new(rng);
let frequency = 0.02;
let frequency_mult = 1.8;
let amplitude_mult = 0.35;
let num_layers = 5;
let mut max_noise_val = 0.0f64;
for j in 0..height {
for i in 0..width {
let mut noise_point = Vec2::new(i as f64, j as f64) * frequency;
let mut amplitude = 1.0;
for _ in 0..num_layers {
noise_map[j * width + i] =
(2.0 * noise.eval(noise_point) - 1.0).abs() * amplitude;
noise_point = noise_point * frequency_mult;
amplitude *= amplitude_mult;
}
max_noise_val = max_noise_val.max(noise_map[j * width + i]);
}
}
let data = noise_map
.into_iter()
.map(|f| {
let v = (f / max_noise_val * 192.0 + 32.0).floor() as u8;
Pixel(v, v, v)
})
.collect();
Image {
width,
height,
data,
}
}