92 lines
3 KiB
Rust
92 lines
3 KiB
Rust
use crate::core::spectrum::SPECTRUM_CACHE;
|
|
use crate::core::texture::FloatTexture;
|
|
use crate::{Arena, FileLoc, ParameterDictionary};
|
|
use anyhow::{anyhow, Result};
|
|
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::spectra::{DenselySampledSpectrum, RGBColorSpace};
|
|
use shared::Transform;
|
|
use std::sync::Arc;
|
|
|
|
pub fn lookup_spectrum(s: &Spectrum) -> Arc<DenselySampledSpectrum> {
|
|
let cache = &SPECTRUM_CACHE;
|
|
let dense_spectrum = DenselySampledSpectrum::from_spectrum(s);
|
|
cache.lookup(dense_spectrum)
|
|
}
|
|
|
|
fn dummy_shape() -> Shape {
|
|
Shape::default()
|
|
}
|
|
|
|
fn dummy_alpha() -> FloatTexture {
|
|
FloatTexture::default()
|
|
}
|
|
|
|
/// Create a non-area light. Returns a Light value — the caller decides
|
|
/// whether to wrap it in Arc (host ownership) or arena.alloc (GPU).
|
|
pub fn create_light(
|
|
name: &str,
|
|
render_from_light: Transform,
|
|
medium: Option<Medium>,
|
|
parameters: &ParameterDictionary,
|
|
loc: &FileLoc,
|
|
camera_transform: CameraTransform,
|
|
arena: &Arena,
|
|
) -> Result<Light> {
|
|
let shape = dummy_shape();
|
|
let alpha = dummy_alpha();
|
|
match name {
|
|
"point" => crate::lights::point::create(
|
|
render_from_light, medium, parameters, loc,
|
|
&shape, &alpha, None, arena,
|
|
),
|
|
"spot" => crate::lights::spot::create(
|
|
render_from_light, medium, parameters, loc,
|
|
&shape, &alpha, None, arena,
|
|
),
|
|
"distant" => crate::lights::distant::create(
|
|
render_from_light, medium, parameters, loc,
|
|
&shape, &alpha, None, arena,
|
|
),
|
|
"goniometric" => crate::lights::goniometric::create(
|
|
render_from_light, medium, parameters, loc,
|
|
&shape, &alpha, None, arena,
|
|
),
|
|
"projection" => crate::lights::projection::create(
|
|
render_from_light, medium, parameters, loc,
|
|
&shape, &alpha, None, arena,
|
|
),
|
|
"infinite" => crate::lights::infinite::create(
|
|
render_from_light, medium, camera_transform,
|
|
parameters, None, loc, arena,
|
|
),
|
|
"diffuse" => Err(anyhow!(
|
|
"{}: \"diffuse\" is an area light; use create_area_light with a shape",
|
|
loc
|
|
)),
|
|
_ => Err(anyhow!("{}: unknown light type \"{}\"", loc, name)),
|
|
}
|
|
}
|
|
|
|
/// Create a diffuse area light bound to a specific shape.
|
|
/// Returns a Light value. The individual light constructor still uses
|
|
/// the arena internally for sub-allocations (shape, image, spectra),
|
|
/// but the Light itself is returned as a value for the caller to place.
|
|
pub fn create_area_light(
|
|
render_from_light: Transform,
|
|
medium: Option<Medium>,
|
|
parameters: &ParameterDictionary,
|
|
loc: &FileLoc,
|
|
shape: &Shape,
|
|
alpha_tex: &FloatTexture,
|
|
colorspace: Option<&RGBColorSpace>,
|
|
arena: &Arena,
|
|
) -> Result<Light> {
|
|
crate::lights::diffuse::create(
|
|
render_from_light, medium, parameters, loc,
|
|
shape, alpha_tex, colorspace, arena,
|
|
)
|
|
}
|