1
0

completed perlin textures

This commit is contained in:
Ishan Jain 2021-03-05 20:54:25 +05:30
parent aa74b321b8
commit 7468ba1112
No known key found for this signature in database
GPG Key ID: F261A0E73038D89D
4 changed files with 67 additions and 40 deletions

View File

@ -23,11 +23,11 @@ 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;
const HEIGHT: usize = 1080;
const WIDTH: usize = 2560;
const HEIGHT: usize = 1440;
fn main() -> Result<(), String> {
run(WIDTH, HEIGHT)
@ -134,9 +134,9 @@ 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);

View File

@ -1,10 +1,10 @@
use crate::types::Vec3;
use rand::{distributions::Uniform, Rng};
use rand::Rng;
const POINT_COUNT: usize = 256;
pub struct Perlin {
points: Vec<f64>,
points: Vec<Vec3>,
permute_x: Vec<usize>,
permute_y: Vec<usize>,
@ -13,10 +13,9 @@ pub struct Perlin {
impl Perlin {
pub fn new<R: Rng + ?Sized>(rng: &mut R) -> Self {
let points = rng
.sample_iter(Uniform::from(0.0..=1.0))
.take(POINT_COUNT)
.collect::<Vec<f64>>();
let points = (0..POINT_COUNT)
.map(|_| Vec3::random(rng).unit_vector())
.collect::<Vec<Vec3>>();
let permute_x = Self::perlin_generate_permutation(rng);
let permute_y = Self::perlin_generate_permutation(rng);
@ -37,41 +36,57 @@ impl Perlin {
}
pub fn noise(&self, p: Vec3) -> f64 {
let mut smooth_grid = [[[Vec3::new(0.0, 0.0, 0.0); 2]; 2]; 2];
{
let i = p.x().floor() as i32;
let j = p.y().floor() as i32;
let k = p.z().floor() as i32;
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();
let u = p.x() - p.x().floor();
let v = p.y() - p.y().floor();
let 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);
perlin_interpolate(smooth_grid, u, v, w)
}
return trilinear_interpolate(smooth_grid, u, v, w);
pub fn turbulence(&self, p: Vec3, depth: u32) -> f64 {
let mut acc = 0.0f64;
let mut weight = 1.0;
let mut temp_p = p;
for _i in 0..depth {
acc += weight * self.noise(temp_p);
weight *= 0.5;
temp_p *= 2.0;
}
acc.abs()
}
}
fn trilinear_interpolate(smooth_grid: [[[f64; 2]; 2]; 2], u: f64, v: f64, w: f64) -> f64 {
fn perlin_interpolate(smooth_grid: [[[Vec3; 2]; 2]; 2], u: f64, v: f64, w: f64) -> f64 {
// 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
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 acc = 0.0;
for (di, a) in smooth_grid.iter().enumerate() {
@ -80,10 +95,13 @@ fn trilinear_interpolate(smooth_grid: [[[f64; 2]; 2]; 2], u: f64, v: f64, w: f64
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;
let wt = Vec3::new(u - di, v - dj, w - dk);
acc += (di * uu + (1.0 - di) * (1.0 - uu))
* (dj * vv + (1.0 - dj) * (1.0 - vv))
* (dk * ww + (1.0 - dk) * (1.0 - ww))
* c.dot(&wt);
}
}
}

View File

@ -26,6 +26,8 @@ impl PerlinNoise {
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 * self.scale)
Vec3::new(1.0, 1.0, 1.0)
* 0.5
* (1.0 + (self.scale * p.z() + 10.0 * self.noise.turbulence(p, 7)).sin())
}
}

View File

@ -3,6 +3,8 @@ use std::{
ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign},
};
use rand::Rng;
#[derive(Debug, Copy, Clone)]
pub struct Vec3([f64; 3]);
@ -73,6 +75,11 @@ impl Vec3 {
let length = self.length();
Vec3([self[0] / length, self[1] / length, self[2] / length])
}
#[inline]
pub fn random<R: Rng + ?Sized>(rng: &mut R) -> Vec3 {
Vec3([rng.gen(), rng.gen(), rng.gen()])
}
}
impl Add for Vec3 {