Continuing cleanup. Added constructors for FloatImageTexture
This commit is contained in:
parent
aefd204577
commit
79c87a6c15
7 changed files with 96 additions and 66 deletions
|
|
@ -8,6 +8,7 @@ use core::fmt;
|
|||
use core::ops::{
|
||||
Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
|
||||
};
|
||||
use anyhow::{Result, bail};
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use num_traits::Float as NumFloat;
|
||||
|
||||
|
|
@ -680,6 +681,16 @@ pub enum ColorEncoding {
|
|||
SRGB(SRGBEncoding),
|
||||
}
|
||||
|
||||
impl ColorEncoding {
|
||||
pub fn from_name(name: &str) -> Result<Self> {
|
||||
match name {
|
||||
"sRGB" | "srgb" => Ok(ColorEncoding::SRGB(SRGBEncoding)),
|
||||
"linear" => Ok(ColorEncoding::Linear(LinearEncoding)),
|
||||
_ => bail!("Unknown color encoding: {}", name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ColorEncoding {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Encoding")
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use crate::core::color::{ColorEncoding, ColorEncodingTrait, LINEAR};
|
|||
use crate::core::geometry::{Bounds2f, Point2f, Point2fi, Point2i};
|
||||
use crate::utils::math::{f16_to_f32_software, lerp, square};
|
||||
use crate::{gvec_with_capacity, Float, GVec};
|
||||
use anyhow::{Result, bail};
|
||||
use core::hash;
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use num_traits::Float as NumFloat;
|
||||
|
|
@ -14,6 +15,18 @@ pub enum WrapMode {
|
|||
OctahedralSphere,
|
||||
}
|
||||
|
||||
impl WrapMode {
|
||||
pub fn parse(name: &str) -> Result<WrapMode> {
|
||||
match name {
|
||||
"clamp" => Ok(WrapMode::Clamp),
|
||||
"black" => Ok(WrapMode::Black),
|
||||
"repeat" => Ok(WrapMode::Repeat),
|
||||
"octahedralsphere" => Ok(WrapMode::OctahedralSphere),
|
||||
_ => bail!("{:?}: wrap mode unknown", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct WrapMode2D {
|
||||
pub uv: [WrapMode; 2],
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ pub mod fbm;
|
|||
pub mod image;
|
||||
pub mod marble;
|
||||
pub mod mix;
|
||||
pub mod ptex;
|
||||
pub mod scaled;
|
||||
pub mod windy;
|
||||
pub mod wrinkled;
|
||||
|
|
@ -19,7 +18,6 @@ pub use fbm::*;
|
|||
pub use image::*;
|
||||
pub use marble::*;
|
||||
pub use mix::*;
|
||||
pub use ptex::*;
|
||||
pub use scaled::*;
|
||||
pub use windy::*;
|
||||
pub use wrinkled::*;
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
use crate::Float;
|
||||
use crate::core::color::{ColorEncoding, RGB};
|
||||
use crate::core::spectrum::{SpectrumTrait, StandardSpectra};
|
||||
use crate::core::texture::{SpectrumType, TextureEvalContext};
|
||||
use crate::spectra::{
|
||||
DeviceStandardColorSpaces, RGBAlbedoSpectrum, RGBColorSpace, RGBIlluminantSpectrum,
|
||||
RGBUnboundedSpectrum, SampledSpectrum, SampledWavelengths,
|
||||
};
|
||||
use crate::utils::Ptr;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct GPUFloatPtexTexture {
|
||||
pub face_values: *const Float,
|
||||
}
|
||||
|
||||
impl GPUFloatPtexTexture {
|
||||
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
|
||||
unsafe { *self.face_values.add(ctx.face_index as usize) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub struct GPUSpectrumPtexTexture {
|
||||
pub face_values: Ptr<RGB>,
|
||||
pub n_faces: u32,
|
||||
pub spectrum_type: SpectrumType,
|
||||
pub colorspaces: DeviceStandardColorSpaces,
|
||||
}
|
||||
|
||||
impl GPUSpectrumPtexTexture {
|
||||
pub fn evaluate(
|
||||
&self,
|
||||
ctx: &TextureEvalContext,
|
||||
lambda: &SampledWavelengths,
|
||||
) -> SampledSpectrum {
|
||||
let index = (ctx.face_index as u32).clamp(0, self.n_faces.saturating_sub(1));
|
||||
let rgb = unsafe { &*self.face_values.add(index as usize) };
|
||||
let s_rgb = self.colorspaces.srgb;
|
||||
|
||||
match self.spectrum_type {
|
||||
SpectrumType::Unbounded => RGBUnboundedSpectrum::new(&s_rgb, *rgb).sample(lambda),
|
||||
SpectrumType::Albedo => {
|
||||
let clamped_rgb = rgb.clamp(0.0, 1.0);
|
||||
RGBAlbedoSpectrum::new(&s_rgb, clamped_rgb).sample(lambda)
|
||||
}
|
||||
SpectrumType::Illuminant => RGBIlluminantSpectrum::new(&s_rgb, *rgb).sample(lambda),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -335,9 +335,6 @@ pub trait FilmTrait: Sync {
|
|||
for x in pixel_bounds.p_min.x()..pixel_bounds.p_max.x() {
|
||||
let p = Point2i::new(x, y);
|
||||
let mut rgb = self.get_pixel_rgb(p, Some(splat_scale));
|
||||
if rgb.r > 1.0 || rgb.g > 1.0 || rgb.b > 1.0 {
|
||||
eprintln!("p={:?} get_pixel_rgb=({}, {}, {})", p, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
let mut was_clamped = false;
|
||||
if write_fp16 {
|
||||
if rgb.r > 65504.0 {
|
||||
|
|
|
|||
|
|
@ -3,16 +3,16 @@ use crate::core::texture::{
|
|||
CreateFloatTexture, CreateSpectrumTexture, FloatTexture, FloatTextureTrait, SpectrumTexture,
|
||||
SpectrumTextureTrait,
|
||||
};
|
||||
use crate::utils::mipmap::{MIPMap, MIPMapFilterOptions};
|
||||
use crate::utils::{FileLoc, TextureParameterDictionary};
|
||||
use crate::Arena;
|
||||
use crate::utils::mipmap::{FilterFunction, MIPMap, MIPMapFilterOptions};
|
||||
use crate::utils::{FileLoc, TextureParameterDictionary, resolve_filename};
|
||||
use crate::{Arena};
|
||||
use anyhow::Result;
|
||||
use shared::core::color::RGB;
|
||||
use shared::core::color::{ColorEncoding, SRGBEncoding};
|
||||
use shared::core::geometry::Vector2f;
|
||||
use shared::core::image::WrapMode;
|
||||
use shared::core::spectrum::SpectrumTrait;
|
||||
use shared::core::texture::{SpectrumType, TextureEvalContext, TextureMapping2D};
|
||||
use shared::core::texture::{SpectrumType, TexCoord2D, TextureEvalContext, TextureMapping2D};
|
||||
use shared::spectra::{
|
||||
RGBAlbedoSpectrum, RGBIlluminantSpectrum, RGBUnboundedSpectrum, SampledSpectrum,
|
||||
SampledWavelengths,
|
||||
|
|
@ -168,6 +168,7 @@ impl CreateSpectrumTexture for SpectrumImageTexture {
|
|||
|
||||
let filter_options = MIPMapFilterOptions::default();
|
||||
let wrap_str = parameters.get_one_string("wrap", "repeat")?;
|
||||
// let wrap_mode = WrapMode::parse(wrap_str)?;
|
||||
let wrap_mode = match wrap_str.as_str() {
|
||||
"repeat" => WrapMode::Repeat,
|
||||
"clamp" => WrapMode::Clamp,
|
||||
|
|
@ -222,18 +223,65 @@ impl FloatImageTexture {
|
|||
}
|
||||
|
||||
impl FloatTextureTrait for FloatImageTexture {
|
||||
fn evaluate(&self, _ctx: &TextureEvalContext) -> Float {
|
||||
todo!()
|
||||
fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
|
||||
let mut c: TexCoord2D = self.base.mapping.map(ctx);
|
||||
c.st[1] = 1. - c.st[1];
|
||||
let v: Float = self.base.scale
|
||||
* self.base.mipmap.filter::<Float>(
|
||||
c.st,
|
||||
Vector2f::new(c.dsdx, c.dtdx),
|
||||
Vector2f::new(c.dsdy, c.dtdy),
|
||||
);
|
||||
|
||||
if self.base.invert {
|
||||
(1. - v).max(0.)
|
||||
} else {
|
||||
v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CreateFloatTexture for FloatImageTexture {
|
||||
fn create(
|
||||
_render_from_texture: Transform,
|
||||
_parameters: TextureParameterDictionary,
|
||||
_loc: FileLoc,
|
||||
render_from_texture: Transform,
|
||||
parameters: TextureParameterDictionary,
|
||||
loc: FileLoc,
|
||||
_arena: &Arena,
|
||||
) -> Result<FloatTexture> {
|
||||
todo!()
|
||||
let mapping = TextureMapping2D::create(¶meters, &render_from_texture, &loc)?;
|
||||
let max_aniso = parameters.get_one_float("maxanisotropy", 8.)?;
|
||||
let filter = parameters.get_one_string("filter", "bilinear")?;
|
||||
let mut filter_options = MIPMapFilterOptions::default();
|
||||
filter_options.max_anisotropy = max_aniso;
|
||||
|
||||
let ff = FilterFunction::parse(&filter)?;
|
||||
filter_options.filter = ff;
|
||||
let wrap_string = parameters.get_one_string("wrap", "repeat")?;
|
||||
let wrap_mode = WrapMode::parse(&wrap_string)?;
|
||||
let scale = parameters.get_one_float("scale", 1.)?;
|
||||
let invert = parameters.get_one_bool("invert", false)?;
|
||||
let filename = resolve_filename(¶meters.get_one_string("filename", "")?);
|
||||
let default_encoding = if Path::new(&filename)
|
||||
.extension()
|
||||
.map_or(false, |ext| ext == "png")
|
||||
{
|
||||
"sRGB"
|
||||
} else {
|
||||
"linear"
|
||||
};
|
||||
let encoding_str = parameters.get_one_string("encoding", default_encoding)?;
|
||||
let encoding = ColorEncoding::from_name(&encoding_str)?;
|
||||
|
||||
let tex = FloatImageTexture::new(
|
||||
mapping,
|
||||
filename,
|
||||
filter_options,
|
||||
wrap_mode,
|
||||
scale,
|
||||
invert,
|
||||
encoding,
|
||||
);
|
||||
|
||||
Ok(FloatTexture::Image(tex))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use shared::core::color::{ColorEncoding, RGB};
|
|||
use shared::core::geometry::{Point2f, Point2i, Vector2f, VectorLike};
|
||||
use shared::core::image::{WrapMode, WrapMode2D};
|
||||
use shared::spectra::RGBColorSpace;
|
||||
use anyhow::{bail, Result};
|
||||
use shared::utils::math::{lerp, safe_sqrt, square};
|
||||
use shared::Float;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
|
@ -21,6 +22,19 @@ pub enum FilterFunction {
|
|||
Ewa,
|
||||
}
|
||||
|
||||
impl FilterFunction {
|
||||
pub fn parse(name: &str) -> Result<FilterFunction> {
|
||||
match name {
|
||||
"ewa" | "EWA" => Ok(FilterFunction::Ewa),
|
||||
"trilinear" => Ok(FilterFunction::Trilinear),
|
||||
"bilinear" => Ok(FilterFunction::Bilinear),
|
||||
"point" => Ok(FilterFunction::Point),
|
||||
_ => bail!("Filter function unknown")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl std::fmt::Display for FilterFunction {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let s = match self {
|
||||
|
|
|
|||
Loading…
Reference in a new issue