Textures working a little bit
This commit is contained in:
parent
1196cb7758
commit
2476d2d49a
7 changed files with 407 additions and 84 deletions
74
ray-tracing-pbrt-scene/src/texture/checkerboard.rs
Normal file
74
ray-tracing-pbrt-scene/src/texture/checkerboard.rs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
use super::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct FloatCheckerboardTexture2d {
|
||||
pub(super) mapping: UVMapping,
|
||||
pub(super) tex: [ValueTexture<Float, Arc<dyn Pbrt_2d_float_texture>>; 2],
|
||||
}
|
||||
|
||||
impl Pbrt_2d_float_texture for FloatCheckerboardTexture2d {
|
||||
fn get(&self, u: Float, v: Float) -> Float {
|
||||
let (u, v) = self.mapping.map(u, v);
|
||||
|
||||
let even = if u >= 0.0 {
|
||||
u.fract() >= 0.5
|
||||
} else {
|
||||
u.fract() >= -0.5
|
||||
} ^ if v >= 0.0 {
|
||||
v.fract() >= 0.5
|
||||
} else {
|
||||
v.fract() >= -0.5
|
||||
};
|
||||
|
||||
match &self.tex[even as usize] {
|
||||
ValueTexture::Value(v) => *v,
|
||||
ValueTexture::Texture(t) => t.get(u, v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PbrtTexture for FloatCheckerboardTexture2d {
|
||||
fn get_2d_float_texture(self: Arc<Self>) -> Result<Arc<dyn Pbrt_2d_float_texture>> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn get_2d_spectrum_texture(self: Arc<Self>) -> Result<Arc<dyn Pbrt_2d_spectrum_texture>> {
|
||||
Err(miette!("Unable to use this texture as a spectrum texture"))
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub(super) struct SpectrumCheckerboardTexture2d {
|
||||
pub(super) mapping: UVMapping,
|
||||
pub(super) tex: [ValueTexture<Color, Arc<dyn Pbrt_2d_spectrum_texture>>; 2],
|
||||
}
|
||||
|
||||
impl Pbrt_2d_spectrum_texture for SpectrumCheckerboardTexture2d {
|
||||
fn get(&self, u: Float, v: Float) -> Color {
|
||||
let (u, v) = self.mapping.map(u, v);
|
||||
|
||||
let even = if u >= 0.0 {
|
||||
u.fract() >= 0.5
|
||||
} else {
|
||||
u.fract() >= -0.5
|
||||
} ^ if v >= 0.0 {
|
||||
v.fract() >= 0.5
|
||||
} else {
|
||||
v.fract() >= -0.5
|
||||
};
|
||||
|
||||
match &self.tex[even as usize] {
|
||||
ValueTexture::Value(v) => *v,
|
||||
ValueTexture::Texture(t) => t.get(u, v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PbrtTexture for SpectrumCheckerboardTexture2d {
|
||||
fn get_2d_float_texture(self: Arc<Self>) -> Result<Arc<dyn Pbrt_2d_float_texture>> {
|
||||
Err(miette!("Unable to use this texture as a float texture"))
|
||||
}
|
||||
|
||||
fn get_2d_spectrum_texture(self: Arc<Self>) -> Result<Arc<dyn Pbrt_2d_spectrum_texture>> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
128
ray-tracing-pbrt-scene/src/texture/imagemap.rs
Normal file
128
ray-tracing-pbrt-scene/src/texture/imagemap.rs
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
use std::path::Path;
|
||||
|
||||
use miette::IntoDiagnostic;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) enum ImageMapWrap {
|
||||
Repeat,
|
||||
Black,
|
||||
Clamp,
|
||||
}
|
||||
|
||||
impl ImageMapWrap {
|
||||
pub(super) fn new(x: String) -> Result<Self> {
|
||||
match x.as_str() {
|
||||
"\"repeat\"" => Ok(Self::Repeat),
|
||||
"\"black\"" => Ok(Self::Black),
|
||||
"\"clamp\"" => Ok(Self::Clamp),
|
||||
_ => Err(miette!("error image map wrap")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) enum ImageMapEncoding {
|
||||
SRGB,
|
||||
Linear,
|
||||
Gamma(Float),
|
||||
}
|
||||
|
||||
impl ImageMapEncoding {
|
||||
pub(super) fn new(x: String) -> Result<Self> {
|
||||
match x.as_str() {
|
||||
"\"sRGB\"" => Ok(Self::SRGB),
|
||||
"\"linear\"" => Ok(Self::Linear),
|
||||
s if s.starts_with("\"gamma ") => Ok(Self::Gamma(
|
||||
s.split_at(7)
|
||||
.1
|
||||
.trim_matches('\"')
|
||||
.parse()
|
||||
.into_diagnostic()?,
|
||||
)),
|
||||
_ => Err(miette!("error image map encoding")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct SpectrumImageMapTexture {
|
||||
mapping: UVMapping,
|
||||
scale: Float,
|
||||
wrap: ImageMapWrap,
|
||||
invert: bool,
|
||||
image: image::Rgb32FImage,
|
||||
}
|
||||
|
||||
fn srgb_nonlinear(x: f32) -> f32 {
|
||||
if x <= 0.04045 {
|
||||
x / 12.92
|
||||
} else {
|
||||
((x + 0.055) / 1.055).powf(2.4)
|
||||
}
|
||||
}
|
||||
|
||||
impl SpectrumImageMapTexture {
|
||||
pub(super) fn new(
|
||||
mapping: UVMapping,
|
||||
scale: Float,
|
||||
wrap: ImageMapWrap,
|
||||
encoding: ImageMapEncoding,
|
||||
invert: bool,
|
||||
path: impl AsRef<Path>,
|
||||
) -> Result<Self> {
|
||||
let image = image::open(path).unwrap();
|
||||
|
||||
let mut image = image.into_rgb32f();
|
||||
|
||||
match encoding {
|
||||
ImageMapEncoding::SRGB => {
|
||||
for pixel in image.pixels_mut() {
|
||||
pixel.0 = [
|
||||
srgb_nonlinear(pixel.0[0]),
|
||||
srgb_nonlinear(pixel.0[1]),
|
||||
srgb_nonlinear(pixel.0[2]),
|
||||
];
|
||||
}
|
||||
}
|
||||
ImageMapEncoding::Linear => (),
|
||||
ImageMapEncoding::Gamma(gamma) => {
|
||||
for pixel in image.pixels_mut() {
|
||||
pixel.0 = [
|
||||
pixel.0[0].powf(gamma),
|
||||
pixel.0[1].powf(gamma),
|
||||
pixel.0[2].powf(gamma),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Self {
|
||||
mapping,
|
||||
scale,
|
||||
invert,
|
||||
wrap,
|
||||
image,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Pbrt_2d_spectrum_texture for SpectrumImageMapTexture {
|
||||
fn get(&self, u: Float, v: Float) -> Color {
|
||||
let (u, v) = self.mapping.map(u, v);
|
||||
|
||||
let (w, h) = self.image.dimensions();
|
||||
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl PbrtTexture for SpectrumImageMapTexture {
|
||||
fn get_2d_float_texture(self: Arc<Self>) -> Result<Arc<dyn Pbrt_2d_float_texture>> {
|
||||
Err(miette!("Unable to use this texture as a float texture"))
|
||||
}
|
||||
|
||||
fn get_2d_spectrum_texture(self: Arc<Self>) -> Result<Arc<dyn Pbrt_2d_spectrum_texture>> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue