wip: perlin noise
This commit is contained in:
parent
f56947eca2
commit
aa74b321b8
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]) {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user