Changes to PathIntegrator maxdepth and light sampling

This commit is contained in:
Wito Wiala 2026-09-04 13:10:04 +01:00
parent 5038ed8270
commit ed2caf094d
2 changed files with 28 additions and 4 deletions

View file

@ -66,8 +66,17 @@ impl CreateIntegrator for PathIntegrator {
config: PathConfig,
arena: &Arena,
) -> Result<PathIntegrator> {
let _max_depth = parameters.get_one_int("maxdepth", 5)?;
let _regularize = parameters.get_one_bool("regularize", false)?;
// pbrt (`cpu/integrators.cpp`): `maxdepth` defaults to 5, `regularize` to false.
// These were parsed and then discarded, so the hardcoded PathConfig won instead
// -- PathConfig::FULL is maxdepth 8 with regularize on, which made the path
// integrator ~2.8% brighter than the wavefront (which reads them properly).
let max_depth = parameters.get_one_int("maxdepth", 5)?;
let regularize = parameters.get_one_bool("regularize", false)?;
let config = PathConfig {
max_depth: max_depth as usize,
regularize,
..config
};
let light_sampler = create_light_sampler("power", &lights, arena);
let integrator =
PathIntegrator::new(aggregate, lights, camera, light_sampler, config, materials);

View file

@ -8,7 +8,7 @@ use shared::core::bsdf::{BSDF, BSDFSample};
use shared::core::bxdf::{BxDFFlags, FArgs, TransportMode};
use shared::core::camera::Camera;
use shared::core::film::VisibleSurface;
use shared::core::geometry::{Point2i, Ray, Vector3f, VectorLike};
use shared::core::geometry::{Point2i, Point3fi, Ray, Vector3f, VectorLike};
use shared::core::interaction::{Interaction, InteractionTrait, SurfaceInteraction};
use shared::core::light::LightTrait;
use shared::core::light::{Light, LightSampleContext};
@ -99,7 +99,22 @@ impl PathIntegrator {
lambda: &SampledWavelengths,
sampler: &mut Sampler,
) -> SampledSpectrum {
let ctx = LightSampleContext::from(intr);
let mut ctx = LightSampleContext::from(intr);
// pbrt `PathIntegrator::SampleLd`: nudge the light-sampling position to the
// correct side of the surface, otherwise light leaks at grazing angles.
// if (IsReflective(flags) && !IsTransmissive(flags))
// ctx.pi = intr.OffsetRayOrigin(intr.wo);
// else if (IsTransmissive(flags) && !IsReflective(flags))
// ctx.pi = intr.OffsetRayOrigin(-intr.wo);
// The wavefront integrator already did this; omitting it here made the path
// integrator ~2.8% brighter than the wavefront on killeroo-gold.
let flags = bsdf.flags();
let wo_nudge = intr.wo();
if flags.is_reflective() && !flags.is_transmissive() {
ctx.pi = Point3fi::new_from_point(intr.offset_ray_vector(wo_nudge));
} else if flags.is_transmissive() && !flags.is_reflective() {
ctx.pi = Point3fi::new_from_point(intr.offset_ray_vector(-wo_nudge));
}
let Some(sampled) = self.sampler.sample_with_context(&ctx, sampler.get1d()) else {
return SampledSpectrum::zero();