Break texture module into multiple files.
This commit is contained in:
parent
66d599b50d
commit
f483f2905b
@ -1,160 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use image::RgbImage;
|
||||
use rand;
|
||||
|
||||
use perlin::Perlin;
|
||||
use vec3::Vec3;
|
||||
|
||||
pub trait Texture: Send + Sync {
|
||||
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3;
|
||||
}
|
||||
|
||||
impl Texture for Arc<Texture> {
|
||||
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3 {
|
||||
(**self).value(u, v, p)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ConstantTexture {
|
||||
color: Vec3,
|
||||
}
|
||||
|
||||
impl ConstantTexture {
|
||||
pub fn new<V>(color: V) -> ConstantTexture
|
||||
where
|
||||
V: Into<Vec3>,
|
||||
{
|
||||
ConstantTexture {
|
||||
color: color.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Texture for ConstantTexture {
|
||||
fn value(&self, _u: f32, _v: f32, _p: Vec3) -> Vec3 {
|
||||
self.color
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CheckerTexture<T>
|
||||
where
|
||||
T: Texture,
|
||||
{
|
||||
odd: T,
|
||||
even: T,
|
||||
}
|
||||
|
||||
impl<T> CheckerTexture<T>
|
||||
where
|
||||
T: Texture,
|
||||
{
|
||||
pub fn new(odd: T, even: T) -> CheckerTexture<T> {
|
||||
CheckerTexture { odd, even }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Texture for CheckerTexture<T>
|
||||
where
|
||||
T: Texture,
|
||||
{
|
||||
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3 {
|
||||
let sines = (10. * p.x).sin() * (10. * p.y).sin() * (10. * p.z).sin();
|
||||
if sines < 0. {
|
||||
self.odd.value(u, v, p)
|
||||
} else {
|
||||
self.even.value(u, v, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NoiseTexture {
|
||||
scale: f32,
|
||||
perlin: Perlin,
|
||||
}
|
||||
|
||||
impl NoiseTexture {
|
||||
pub fn new<R>(rng: &mut R) -> NoiseTexture
|
||||
where
|
||||
R: rand::Rng,
|
||||
{
|
||||
NoiseTexture::with_scale(rng, 1.)
|
||||
}
|
||||
pub fn with_scale<R>(rng: &mut R, scale: f32) -> NoiseTexture
|
||||
where
|
||||
R: rand::Rng,
|
||||
{
|
||||
NoiseTexture {
|
||||
scale,
|
||||
perlin: Perlin::new(rng),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Texture for NoiseTexture {
|
||||
fn value(&self, _u: f32, _v: f32, p: Vec3) -> Vec3 {
|
||||
Vec3::new(1., 1., 1.) * 0.5 * (1. + self.perlin.noise(self.scale * p))
|
||||
|
||||
//Vec3::new(1., 1., 1.) * turb(self.scale * p, 7)
|
||||
//Vec3::new(1., 1., 1.) * 0.5 * (1. + turb(self.scale * p, 7))
|
||||
//Vec3::new(1., 1., 1.) * 0.5 * (1. + (self.scale * p.z + 10. * self.perlin.turb(p, 7)).sin())
|
||||
//Vec3::new(1., 1., 1.) * 0.5 * (1. + GENERATOR.noise(self.scale * p))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ImageTexture {
|
||||
img: RgbImage,
|
||||
width: f32,
|
||||
height: f32,
|
||||
}
|
||||
|
||||
impl ImageTexture {
|
||||
pub fn new(img: RgbImage) -> ImageTexture {
|
||||
let (w, h) = img.dimensions();
|
||||
ImageTexture {
|
||||
img,
|
||||
width: f32::from(w.min(64000) as u16),
|
||||
height: f32::from(h.min(64000) as u16),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Texture for ImageTexture {
|
||||
fn value(&self, u: f32, v: f32, _p: Vec3) -> Vec3 {
|
||||
// Wrap texcoords by default.
|
||||
let x = (u % 1. * (self.width - 1.)) as u32;
|
||||
let y = ((1. - v % 1.) * (self.height - 1.)) as u32;
|
||||
if x >= self.width as u32 {
|
||||
panic!(format!(
|
||||
"u {} v {} x {} y {} w {} h {}",
|
||||
u, v, x, y, self.width, self.height
|
||||
));
|
||||
}
|
||||
if y >= self.height as u32 {
|
||||
panic!(format!(
|
||||
"u {} v {} x {} y {} w {} h {}",
|
||||
u, v, x, y, self.width, self.height
|
||||
));
|
||||
}
|
||||
let pixel = self.img.get_pixel(x, y);
|
||||
Vec3::new(
|
||||
f32::from(pixel[0]) / 255.,
|
||||
f32::from(pixel[1]) / 255.,
|
||||
f32::from(pixel[2]) / 255.,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn constant_texture_from_array() {
|
||||
assert_eq!(
|
||||
ConstantTexture::new(Vec3::new(1., 2., 3.)),
|
||||
ConstantTexture::new([1., 2., 3.])
|
||||
);
|
||||
}
|
||||
}
|
||||
33
rtiow/src/texture/checker.rs
Normal file
33
rtiow/src/texture/checker.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use texture::Texture;
|
||||
use vec3::Vec3;
|
||||
|
||||
pub struct CheckerTexture<T>
|
||||
where
|
||||
T: Texture,
|
||||
{
|
||||
odd: T,
|
||||
even: T,
|
||||
}
|
||||
|
||||
impl<T> CheckerTexture<T>
|
||||
where
|
||||
T: Texture,
|
||||
{
|
||||
pub fn new(odd: T, even: T) -> CheckerTexture<T> {
|
||||
CheckerTexture { odd, even }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Texture for CheckerTexture<T>
|
||||
where
|
||||
T: Texture,
|
||||
{
|
||||
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3 {
|
||||
let sines = (10. * p.x).sin() * (10. * p.y).sin() * (10. * p.z).sin();
|
||||
if sines < 0. {
|
||||
self.odd.value(u, v, p)
|
||||
} else {
|
||||
self.even.value(u, v, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
24
rtiow/src/texture/constant.rs
Normal file
24
rtiow/src/texture/constant.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use texture::Texture;
|
||||
use vec3::Vec3;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ConstantTexture {
|
||||
color: Vec3,
|
||||
}
|
||||
|
||||
impl ConstantTexture {
|
||||
pub fn new<V>(color: V) -> ConstantTexture
|
||||
where
|
||||
V: Into<Vec3>,
|
||||
{
|
||||
ConstantTexture {
|
||||
color: color.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Texture for ConstantTexture {
|
||||
fn value(&self, _u: f32, _v: f32, _p: Vec3) -> Vec3 {
|
||||
self.color
|
||||
}
|
||||
}
|
||||
47
rtiow/src/texture/image.rs
Normal file
47
rtiow/src/texture/image.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use image::RgbImage;
|
||||
|
||||
use texture::Texture;
|
||||
use vec3::Vec3;
|
||||
|
||||
pub struct ImageTexture {
|
||||
img: RgbImage,
|
||||
width: f32,
|
||||
height: f32,
|
||||
}
|
||||
|
||||
impl ImageTexture {
|
||||
pub fn new(img: RgbImage) -> ImageTexture {
|
||||
let (w, h) = img.dimensions();
|
||||
ImageTexture {
|
||||
img,
|
||||
width: f32::from(w.min(64000) as u16),
|
||||
height: f32::from(h.min(64000) as u16),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Texture for ImageTexture {
|
||||
fn value(&self, u: f32, v: f32, _p: Vec3) -> Vec3 {
|
||||
// Wrap texcoords by default.
|
||||
let x = (u % 1. * (self.width - 1.)) as u32;
|
||||
let y = ((1. - v % 1.) * (self.height - 1.)) as u32;
|
||||
if x >= self.width as u32 {
|
||||
panic!(format!(
|
||||
"u {} v {} x {} y {} w {} h {}",
|
||||
u, v, x, y, self.width, self.height
|
||||
));
|
||||
}
|
||||
if y >= self.height as u32 {
|
||||
panic!(format!(
|
||||
"u {} v {} x {} y {} w {} h {}",
|
||||
u, v, x, y, self.width, self.height
|
||||
));
|
||||
}
|
||||
let pixel = self.img.get_pixel(x, y);
|
||||
Vec3::new(
|
||||
f32::from(pixel[0]) / 255.,
|
||||
f32::from(pixel[1]) / 255.,
|
||||
f32::from(pixel[2]) / 255.,
|
||||
)
|
||||
}
|
||||
}
|
||||
35
rtiow/src/texture/mod.rs
Normal file
35
rtiow/src/texture/mod.rs
Normal file
@ -0,0 +1,35 @@
|
||||
mod checker;
|
||||
mod constant;
|
||||
mod image;
|
||||
mod noise;
|
||||
pub use texture::checker::CheckerTexture;
|
||||
pub use texture::constant::ConstantTexture;
|
||||
pub use texture::image::ImageTexture;
|
||||
pub use texture::noise::NoiseTexture;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use vec3::Vec3;
|
||||
|
||||
pub trait Texture: Send + Sync {
|
||||
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3;
|
||||
}
|
||||
|
||||
impl Texture for Arc<Texture> {
|
||||
fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3 {
|
||||
(**self).value(u, v, p)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn constant_texture_from_array() {
|
||||
assert_eq!(
|
||||
ConstantTexture::new(Vec3::new(1., 2., 3.)),
|
||||
ConstantTexture::new([1., 2., 3.])
|
||||
);
|
||||
}
|
||||
}
|
||||
39
rtiow/src/texture/noise.rs
Normal file
39
rtiow/src/texture/noise.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use rand;
|
||||
|
||||
use perlin::Perlin;
|
||||
use texture::Texture;
|
||||
use vec3::Vec3;
|
||||
|
||||
pub struct NoiseTexture {
|
||||
scale: f32,
|
||||
perlin: Perlin,
|
||||
}
|
||||
|
||||
impl NoiseTexture {
|
||||
pub fn new<R>(rng: &mut R) -> NoiseTexture
|
||||
where
|
||||
R: rand::Rng,
|
||||
{
|
||||
NoiseTexture::with_scale(rng, 1.)
|
||||
}
|
||||
pub fn with_scale<R>(rng: &mut R, scale: f32) -> NoiseTexture
|
||||
where
|
||||
R: rand::Rng,
|
||||
{
|
||||
NoiseTexture {
|
||||
scale,
|
||||
perlin: Perlin::new(rng),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Texture for NoiseTexture {
|
||||
fn value(&self, _u: f32, _v: f32, p: Vec3) -> Vec3 {
|
||||
Vec3::new(1., 1., 1.) * 0.5 * (1. + self.perlin.noise(self.scale * p))
|
||||
|
||||
//Vec3::new(1., 1., 1.) * turb(self.scale * p, 7)
|
||||
//Vec3::new(1., 1., 1.) * 0.5 * (1. + turb(self.scale * p, 7))
|
||||
//Vec3::new(1., 1., 1.) * 0.5 * (1. + (self.scale * p.z + 10. * self.perlin.turb(p, 7)).sin())
|
||||
//Vec3::new(1., 1., 1.) * 0.5 * (1. + GENERATOR.noise(self.scale * p))
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user