Perlin noise with dot product.
This commit is contained in:
parent
697d056a9d
commit
415cb7be9a
@ -3,6 +3,7 @@ use rand::Rng;
|
|||||||
//use rand::SeedableRng;
|
//use rand::SeedableRng;
|
||||||
//use rand::XorShiftRng;
|
//use rand::XorShiftRng;
|
||||||
|
|
||||||
|
use vec3::dot;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -11,16 +12,23 @@ lazy_static! {
|
|||||||
//const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
//const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
||||||
|
|
||||||
pub struct Perlin {
|
pub struct Perlin {
|
||||||
ranfloat: Vec<f32>,
|
ran_vec: Vec<Vec3>,
|
||||||
perm_x: Vec<usize>,
|
perm_x: Vec<usize>,
|
||||||
perm_y: Vec<usize>,
|
perm_y: Vec<usize>,
|
||||||
perm_z: Vec<usize>,
|
perm_z: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perlin_generate() -> Vec<f32> {
|
fn perlin_generate() -> Vec<Vec3> {
|
||||||
//let mut rng: XorShiftRng = SeedableRng::from_seed(SEED);
|
//let mut rng: XorShiftRng = SeedableRng::from_seed(SEED);
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
(0..256).map(|_| rng.gen_range::<f32>(0., 1.)).collect()
|
(0..256)
|
||||||
|
.map(|_| {
|
||||||
|
Vec3::new(
|
||||||
|
rng.gen_range::<f32>(-1., 1.),
|
||||||
|
rng.gen_range::<f32>(-1., 1.),
|
||||||
|
rng.gen_range::<f32>(-1., 1.),
|
||||||
|
).unit_vector()
|
||||||
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn permute(p: &mut Vec<usize>, n: usize) {
|
fn permute(p: &mut Vec<usize>, n: usize) {
|
||||||
@ -41,18 +49,25 @@ fn perlin_generate_perm() -> Vec<usize> {
|
|||||||
p
|
p
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trilinear_interp(c: [[[f32; 2]; 2]; 2], u: f32, v: f32, w: f32) -> f32 {
|
fn perlin_interp(c: [[[Vec3; 2]; 2]; 2], u: f32, v: f32, w: f32) -> f32 {
|
||||||
|
// Hermite cubic to round off interpolation and attempt to address 'mach bands'.
|
||||||
|
let uu = u * u * (3. - 2. * u);
|
||||||
|
let vv = v * v * (3. - 2. * v);
|
||||||
|
let ww = w * w * (3. - 2. * w);
|
||||||
|
|
||||||
let mut accum = 0.;
|
let mut accum = 0.;
|
||||||
for i in 0..2 {
|
for i in 0..2 {
|
||||||
for j in 0..2 {
|
for j in 0..2 {
|
||||||
for k in 0..2 {
|
for k in 0..2 {
|
||||||
let fi = i as f32;
|
let weight_v = Vec3::new(u - i as f32, v - j as f32, w - k as f32);
|
||||||
let fj = j as f32;
|
|
||||||
let fk = k as f32;
|
let i = i as f32;
|
||||||
accum += (fi * u + (1. - fi) * (1. - u))
|
let j = j as f32;
|
||||||
* (fj * v + (1. - fj) * (1. - v))
|
let k = k as f32;
|
||||||
* (fk * w + (1. - fk) * (1. - w))
|
accum += (i * uu + (1. - i) * (1. - uu))
|
||||||
* c[i][j][k];
|
* (j * vv + (1. - j) * (1. - vv))
|
||||||
|
* (k * ww + (1. - k) * (1. - ww))
|
||||||
|
* dot(c[i as usize][j as usize][k as usize], weight_v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +77,7 @@ fn trilinear_interp(c: [[[f32; 2]; 2]; 2], u: f32, v: f32, w: f32) -> f32 {
|
|||||||
impl Perlin {
|
impl Perlin {
|
||||||
fn new() -> Perlin {
|
fn new() -> Perlin {
|
||||||
Perlin {
|
Perlin {
|
||||||
ranfloat: perlin_generate(),
|
ran_vec: perlin_generate(),
|
||||||
perm_x: perlin_generate_perm(),
|
perm_x: perlin_generate_perm(),
|
||||||
perm_y: perlin_generate_perm(),
|
perm_y: perlin_generate_perm(),
|
||||||
perm_z: perlin_generate_perm(),
|
perm_z: perlin_generate_perm(),
|
||||||
@ -70,29 +85,24 @@ impl Perlin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn noise(&self, p: Vec3) -> f32 {
|
pub fn noise(&self, p: Vec3) -> f32 {
|
||||||
let mut u = p.x - p.x.floor();
|
let u = p.x - p.x.floor();
|
||||||
let mut v = p.y - p.y.floor();
|
let v = p.y - p.y.floor();
|
||||||
let mut w = p.z - p.z.floor();
|
let w = p.z - p.z.floor();
|
||||||
|
|
||||||
// Hermite cubic to round off interpolation and attempt to address 'mach bands'.
|
|
||||||
u = u * u * (3. - 2. * u);
|
|
||||||
v = v * v * (3. - 2. * v);
|
|
||||||
w = w * w * (3. - 2. * w);
|
|
||||||
|
|
||||||
let i = p.x.floor() as usize;
|
let i = p.x.floor() as usize;
|
||||||
let j = p.y.floor() as usize;
|
let j = p.y.floor() as usize;
|
||||||
let k = p.z.floor() as usize;
|
let k = p.z.floor() as usize;
|
||||||
|
|
||||||
let mut c: [[[f32; 2]; 2]; 2] = Default::default();
|
let mut c: [[[Vec3; 2]; 2]; 2] = Default::default();
|
||||||
for di in 0..2 {
|
for di in 0..2 {
|
||||||
for dj in 0..2 {
|
for dj in 0..2 {
|
||||||
for dk in 0..2 {
|
for dk in 0..2 {
|
||||||
c[di][dj][dk] = self.ranfloat[self.perm_x[(i + di) & 255]
|
c[di][dj][dk] = self.ran_vec[self.perm_x[(i + di) & 255]
|
||||||
^ self.perm_y[(j + dj) & 255]
|
^ self.perm_y[(j + dj) & 255]
|
||||||
^ self.perm_z[(k + dk) & 255]]
|
^ self.perm_z[(k + dk) & 255]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trilinear_interp(c, u, v, w)
|
perlin_interp(c, u, v, w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,6 @@ impl NoiseTexture {
|
|||||||
|
|
||||||
impl Texture for NoiseTexture {
|
impl Texture for NoiseTexture {
|
||||||
fn value(&self, _u: f32, _v: f32, p: Vec3) -> Vec3 {
|
fn value(&self, _u: f32, _v: f32, p: Vec3) -> Vec3 {
|
||||||
Vec3::new(1., 1., 1.) * GENERATOR.noise(self.scale * p)
|
Vec3::new(1., 1., 1.) * 0.5 * (1. + GENERATOR.noise(self.scale * p))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user