Add perlin noise texture
This commit is contained in:
parent
6f6fc5e375
commit
de64b56b38
30
src/main.rs
30
src/main.rs
@ -2,7 +2,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use crate::camera::Camera;
|
use crate::camera::Camera;
|
||||||
use crate::hittable::{Hittable, Sphere, HittableList, HittableObject};
|
use crate::hittable::{Sphere, HittableList, HittableObject};
|
||||||
use crate::output::{Output, PNG};
|
use crate::output::{Output, PNG};
|
||||||
use crate::ray::Ray;
|
use crate::ray::Ray;
|
||||||
use crate::vec3::{Color, Point3, Vec3};
|
use crate::vec3::{Color, Point3, Vec3};
|
||||||
@ -12,7 +12,8 @@ use rand::distributions::{Distribution, Uniform};
|
|||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
use crate::material::{Dielectric, Lambertian, Material, Metal};
|
use crate::material::{Dielectric, Lambertian, Material, Metal};
|
||||||
use crate::aabb::Aabb;
|
use crate::aabb::Aabb;
|
||||||
use crate::bvh::BVH;
|
use crate::noise::NoiseTexture;
|
||||||
|
use crate::perlin::Perlin;
|
||||||
use crate::texture::CheckerTexture;
|
use crate::texture::CheckerTexture;
|
||||||
|
|
||||||
mod vec3;
|
mod vec3;
|
||||||
@ -24,6 +25,8 @@ mod output;
|
|||||||
mod aabb;
|
mod aabb;
|
||||||
mod bvh;
|
mod bvh;
|
||||||
mod texture;
|
mod texture;
|
||||||
|
mod perlin;
|
||||||
|
mod noise;
|
||||||
|
|
||||||
fn two_spheres() -> HittableList {
|
fn two_spheres() -> HittableList {
|
||||||
let mut world:HittableList = Vec::new();
|
let mut world:HittableList = Vec::new();
|
||||||
@ -43,6 +46,22 @@ fn two_spheres() -> HittableList {
|
|||||||
}));
|
}));
|
||||||
world
|
world
|
||||||
}
|
}
|
||||||
|
fn two_perlin_spheres() -> HittableList {
|
||||||
|
let mut world:HittableList = Vec::new();
|
||||||
|
let noise = NoiseTexture { noise: Perlin::new() };
|
||||||
|
let noise_material = Arc::new(Material::Lambertian(Lambertian::textured(Arc::new(noise))));
|
||||||
|
world.push(Arc::new(Sphere {
|
||||||
|
center: Point3::new(0.0, -1000.0, 0.0),
|
||||||
|
radius: 1000.0,
|
||||||
|
material: Arc::clone(&noise_material)
|
||||||
|
}));
|
||||||
|
world.push(Arc::new(Sphere {
|
||||||
|
center: Point3::new(1.0, 2.0, 1.0),
|
||||||
|
radius: 2.0,
|
||||||
|
material: noise_material
|
||||||
|
}));
|
||||||
|
world
|
||||||
|
}
|
||||||
|
|
||||||
fn random_scene() -> HittableList {
|
fn random_scene() -> HittableList {
|
||||||
let mut world: HittableList = Vec::new();
|
let mut world: HittableList = Vec::new();
|
||||||
@ -134,7 +153,7 @@ fn main() {
|
|||||||
|
|
||||||
let look_from = Point3::new(13.0, 2.0, 3.0);
|
let look_from = Point3::new(13.0, 2.0, 3.0);
|
||||||
let look_at = Point3::new(0.0, 0.0, 0.0);
|
let look_at = Point3::new(0.0, 0.0, 0.0);
|
||||||
let focus_dist = 10.0;
|
let focus_dist = 2.0;
|
||||||
|
|
||||||
// Camera
|
// Camera
|
||||||
let cam = Camera::new(
|
let cam = Camera::new(
|
||||||
@ -142,16 +161,17 @@ fn main() {
|
|||||||
look_at,
|
look_at,
|
||||||
Vec3::new(0.0, 1.0, 0.0),
|
Vec3::new(0.0, 1.0, 0.0),
|
||||||
ASPECT_RATIO,
|
ASPECT_RATIO,
|
||||||
40.0,
|
20.0,
|
||||||
0.0,
|
0.0,
|
||||||
focus_dist,
|
focus_dist,
|
||||||
0.0,
|
0.0,
|
||||||
1.0);
|
1.0);
|
||||||
|
|
||||||
// World
|
// World
|
||||||
let scene: u8 = 0;
|
let scene: u8 = 1;
|
||||||
let world = match scene {
|
let world = match scene {
|
||||||
0 => two_spheres(),
|
0 => two_spheres(),
|
||||||
|
1 => two_perlin_spheres(),
|
||||||
_ => random_scene()
|
_ => random_scene()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use std::rc::Rc;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use crate::hittable::HitRecord;
|
use crate::hittable::HitRecord;
|
||||||
|
13
src/noise.rs
Normal file
13
src/noise.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
use crate::perlin::Perlin;
|
||||||
|
use crate::{Color, Point3};
|
||||||
|
use crate::texture::Texture;
|
||||||
|
|
||||||
|
pub struct NoiseTexture {
|
||||||
|
pub noise: Perlin
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Texture for NoiseTexture {
|
||||||
|
fn value(&self, _u: f64, _v: f64, point: &Point3) -> Color {
|
||||||
|
Color::new(1.0, 1.0, 1.0) * self.noise.noise(point)
|
||||||
|
}
|
||||||
|
}
|
46
src/perlin.rs
Normal file
46
src/perlin.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use rand::distributions::{Distribution, Uniform};
|
||||||
|
use rand::Rng;
|
||||||
|
use crate::Point3;
|
||||||
|
|
||||||
|
pub struct Perlin {
|
||||||
|
ranfloat: Vec<f64>,
|
||||||
|
perm_x: Vec<usize>,
|
||||||
|
perm_y: Vec<usize>,
|
||||||
|
perm_z: Vec<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Perlin {
|
||||||
|
const POINT_COUNT: usize = 256;
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let range = Uniform::from(0.0..1.0);
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let mut ranfloat = Vec::with_capacity(Perlin::POINT_COUNT);
|
||||||
|
(0..Perlin::POINT_COUNT).for_each(|_i|ranfloat.push(range.sample(&mut rng)));
|
||||||
|
Perlin {
|
||||||
|
ranfloat,
|
||||||
|
perm_x: Perlin::perlin_generate_perm(),
|
||||||
|
perm_y: Perlin::perlin_generate_perm(),
|
||||||
|
perm_z: Perlin::perlin_generate_perm(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn noise(&self, point: &Point3) -> f64 {
|
||||||
|
let i = ((4.0 * point.x()) as i32) & 255;
|
||||||
|
let j = ((4.0 * point.y()) as i32) & 255;
|
||||||
|
let k= ((4.0 * point.z()) as i32) & 255;
|
||||||
|
let idx = self.perm_x[i as usize] ^ self.perm_y[j as usize] ^ self.perm_z[k as usize];
|
||||||
|
self.ranfloat[idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn perlin_generate_perm() -> Vec<usize> {
|
||||||
|
let mut p = Vec::with_capacity(Perlin::POINT_COUNT);
|
||||||
|
(0..Perlin::POINT_COUNT).for_each(|i| p.push(i));
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
(1..Perlin::POINT_COUNT).rev().for_each(|idx| {
|
||||||
|
let target = rng.gen_range(0..=idx);
|
||||||
|
p.swap(idx, target);
|
||||||
|
});
|
||||||
|
p
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user