pbrt/src/films/rgb.rs
2026-02-18 19:53:13 +00:00

80 lines
2.5 KiB
Rust

use super::*;
use crate::Arena;
use crate::core::film::{CreateFilmBase, PixelSensor};
use crate::utils::containers::Array2D;
use anyhow::Result;
use shared::core::camera::CameraTransform;
use shared::core::film::{Film, FilmBase, RGBFilm, RGBPixel};
use shared::core::filter::FilterTrait;
use shared::spectra::RGBColorSpace;
struct RGBFilmStorage {
pixels: Array2D<RGBPixel>,
}
pub struct RGBFilmHost {
pub device: RGBFilm,
storage: RGBFilmStorage,
}
impl RGBFilmHost {
pub fn new(
base: FilmBase,
colorspace: &RGBColorSpace,
max_component_value: Float,
write_fp16: bool,
) -> Self {
let sensor_ptr = base.sensor;
if sensor_ptr.is_null() {
panic!("Film must have a sensor");
}
let sensor = &*sensor_ptr;
let filter_integral = base.filter.integral();
let sensor_matrix = sensor.xyz_from_sensor_rgb;
let output_rgbf_from_sensor_rgb = colorspace.rgb_from_xyz * sensor_matrix;
let width = base.pixel_bounds.p_max.x() - base.pixel_bounds.p_min.x();
let height = base.pixel_bounds.p_max.y() - base.pixel_bounds.p_min.y();
let count = (width * height) as usize;
let mut pixel_vec = Vec::with_capacity(count);
for _ in 0..count {
pixel_vec.push(RGBPixel::default());
}
let pixels: Array2D<RGBPixel> = Array2D::new(base.pixel_bounds);
let device_pixels = pixels.device.clone();
let storage = RGBFilmStorage { pixels };
let device = RGBFilm {
base,
max_component_value,
write_fp16,
filter_integral,
output_rgbf_from_sensor_rgb,
pixels: device_pixels,
};
Self { device, storage }
}
}
impl CreateFilm for RGBFilm {
fn create(
params: &ParameterDictionary,
exposure_time: Float,
filter: Filter,
_camera_transform: Option<CameraTransform>,
loc: &FileLoc,
_arena: &Arena,
) -> Result<Film> {
let colorspace = params.color_space.as_ref().unwrap();
let max_component_value = params.get_one_float("maxcomponentvalue", Float::INFINITY);
let write_fp16 = params.get_one_bool("savefp16", true);
let sensor = PixelSensor::create(params, colorspace.clone(), exposure_time, loc)?;
let film_base = FilmBase::create(params, filter, Some(&sensor.device()), loc);
let film = RGBFilmHost::new(film_base, &colorspace, max_component_value, write_fp16);
Ok(Film::RGB(film.device))
}
}