void DirectLightingIntegrator::compute_outgoing_radiance_bsdf_sampling( SamplingContext& sampling_context, const MISHeuristic mis_heuristic, const Dual3d& outgoing, Spectrum& radiance, SpectrumStack& aovs) const { radiance.set(0.0f); aovs.set(0.0f); if (m_light_sampler.get_emitting_triangle_count() == 0) return; for (size_t i = 0; i < m_bsdf_sample_count; ++i) { take_single_bsdf_sample( sampling_context, mis_heuristic, outgoing, radiance, aovs); } if (m_bsdf_sample_count > 1) { const float rcp_bsdf_sample_count = 1.0f / m_bsdf_sample_count; radiance *= rcp_bsdf_sample_count; aovs *= rcp_bsdf_sample_count; } }
void DirectLightingIntegrator::compute_outgoing_radiance_light_sampling( SamplingContext& sampling_context, const MISHeuristic mis_heuristic, const Dual3d& outgoing, Spectrum& radiance, SpectrumStack& aovs) const { radiance.set(0.0f); aovs.set(0.0f); sampling_context.split_in_place(3, m_light_sample_count); for (size_t i = 0; i < m_light_sample_count; ++i) { take_single_light_sample( sampling_context, mis_heuristic, outgoing, radiance, aovs); } if (m_light_sample_count > 1) { const float rcp_light_sample_count = 1.0f / m_light_sample_count; radiance *= rcp_light_sample_count; aovs *= rcp_light_sample_count; } }
void DirectLightingIntegrator::take_single_bsdf_or_light_sample( SamplingContext& sampling_context, Spectrum& radiance, SpectrumStack& aovs) { radiance.set(0.0f); aovs.set(0.0f); sampling_context.split_in_place(1, 1); if (sampling_context.next_double2() < 0.5) { sampling_context.split_in_place(3, m_light_sample_count); take_single_light_sample( sampling_context, DirectLightingIntegrator::mis_balance, radiance, aovs); } else { take_single_bsdf_sample( sampling_context, DirectLightingIntegrator::mis_balance, radiance, aovs); } }
void DirectLightingIntegrator::compute_outgoing_radiance_single_sample( SamplingContext& sampling_context, const Dual3d& outgoing, Spectrum& radiance, SpectrumStack& aovs) const { radiance.set(0.0f); aovs.set(0.0f); if (m_light_sampler.get_emitting_triangle_count() > 0) { sampling_context.split_in_place(1, 1); if (sampling_context.next_double2() < 0.5) { sampling_context.split_in_place(3, 1); take_single_light_sample( sampling_context, MISBalance, outgoing, radiance, aovs); } else { take_single_bsdf_sample( sampling_context, MISBalance, outgoing, radiance, aovs); } radiance *= 2.0f; aovs *= 2.0f; } else { take_single_light_sample( sampling_context, MISNone, outgoing, radiance, aovs); } }
void DirectLightingIntegrator::compute_outgoing_radiance_light_sampling_low_variance( SamplingContext& sampling_context, const MISHeuristic mis_heuristic, const Dual3d& outgoing, Spectrum& radiance, SpectrumStack& aovs) const { radiance.set(0.0f); aovs.set(0.0f); // todo: if we had a way to know that a BSDF is purely specular, we could // immediately return black here since there will be no contribution from // such a BSDF. // Sample emitting triangles. if (m_light_sampler.get_emitting_triangle_count() > 0) { sampling_context.split_in_place(3, m_light_sample_count); for (size_t i = 0; i < m_light_sample_count; ++i) { const Vector3d s = sampling_context.next_vector2<3>(); LightSample sample; m_light_sampler.sample_emitting_triangles(m_time, s, sample); add_emitting_triangle_sample_contribution( sample, mis_heuristic, outgoing, radiance, aovs); } if (m_light_sample_count > 1) { const float rcp_light_sample_count = 1.0f / m_light_sample_count; radiance *= rcp_light_sample_count; aovs *= rcp_light_sample_count; } } // Sample non-physical light sources. const size_t light_count = m_light_sampler.get_non_physical_light_count(); if (light_count > 0) { sampling_context.split_in_place(2, light_count); for (size_t i = 0; i < light_count; ++i) { const Vector2d s = sampling_context.next_vector2<2>(); LightSample sample; m_light_sampler.sample_non_physical_light(m_time, s, i, sample); add_non_physical_light_sample_contribution( sample, outgoing, radiance, aovs); } } }