Textures working a little bit

This commit is contained in:
hal8174 2025-08-16 01:35:52 +02:00
parent 1196cb7758
commit 2476d2d49a
Signed by: hal8174
SSH key fingerprint: SHA256:JwuqS+eVfISfKr+DkDQ6NWAbGd1jFAHkPpCM1yCnlTs
7 changed files with 407 additions and 84 deletions

View 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)
}
}

View 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)
}
}