pbrt/src/core/light.rs

136 lines
3.8 KiB
Rust

use crate::core::spectrum::SPECTRUM_CACHE;
use crate::core::texture::FloatTexture;
use crate::spectra::DenselySampledSpectrumBuffer;
use crate::utils::{Arena, FileLoc, ParameterDictionary};
use anyhow::{Result, anyhow};
use shared::core::camera::CameraTransform;
use shared::core::light::Light;
use shared::core::medium::Medium;
use shared::core::shape::Shape;
use shared::core::spectrum::Spectrum;
use shared::lights::*;
use shared::spectra::RGBColorSpace;
use shared::utils::Transform;
use std::sync::Arc;
pub fn lookup_spectrum(s: &Spectrum) -> Arc<DenselySampledSpectrumBuffer> {
let cache = &SPECTRUM_CACHE;
let dense_spectrum = DenselySampledSpectrumBuffer::from_spectrum(s);
cache.lookup(dense_spectrum).into()
}
pub trait CreateLight {
fn create(
arena: &mut Arena,
render_from_light: Transform,
medium: Medium,
parameters: &ParameterDictionary,
loc: &FileLoc,
shape: &Shape,
alpha_text: &FloatTexture,
colorspace: Option<&RGBColorSpace>,
) -> Result<Light>;
}
pub trait LightFactory {
fn create(
name: &str,
arena: &mut Arena,
render_from_light: Transform,
medium: Medium,
parameters: &ParameterDictionary,
loc: &FileLoc,
shape: &Shape,
alpha_tex: &FloatTexture,
colorspace: Option<&RGBColorSpace>,
camera_transform: CameraTransform,
) -> Result<Self>;
}
impl LightFactory for Light {
fn create(
name: &str,
arena: &mut Arena,
render_from_light: Transform,
medium: Medium,
parameters: &ParameterDictionary,
loc: &FileLoc,
shape: &Shape,
alpha_tex: &FloatTexture,
colorspace: Option<&RGBColorSpace>,
camera_transform: CameraTransform,
) -> Result<Self> {
match name {
"diffuse" => DiffuseAreaLight::create(
arena,
render_from_light,
medium,
parameters,
loc,
shape,
alpha_tex,
colorspace,
),
"point" => PointLight::create(
arena,
render_from_light,
medium,
parameters,
loc,
shape,
alpha_tex,
colorspace,
),
"spot" => SpotLight::create(
arena,
render_from_light,
medium,
parameters,
loc,
shape,
alpha_tex,
colorspace,
),
"goniometric" => GoniometricLight::create(
arena,
render_from_light,
medium,
parameters,
loc,
shape,
alpha_tex,
colorspace,
),
"projection" => ProjectionLight::create(
arena,
render_from_light,
medium,
parameters,
loc,
shape,
alpha_tex,
colorspace,
),
"distant" => DistantLight::create(
arena,
render_from_light,
medium,
parameters,
loc,
shape,
alpha_tex,
colorspace,
),
"infinite" => crate::lights::infinite::create(
arena,
render_from_light,
medium.into(),
camera_transform,
parameters,
colorspace,
loc,
),
_ => Err(anyhow!("{}: unknown light type: \"{}\"", loc, name)),
}
}
}