void DirectLightingIntegrator::take_single_light_sample( SamplingContext& sampling_context, const MISHeuristic mis_heuristic, const Dual3d& outgoing, Spectrum& radiance, SpectrumStack& aovs) const { // 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. if (!m_light_sampler.has_lights_or_emitting_triangles()) return; const Vector3d s = sampling_context.next_vector2<3>(); LightSample sample; m_light_sampler.sample(m_time, s, sample); if (sample.m_triangle) { add_emitting_triangle_sample_contribution( sample, mis_heuristic, outgoing, radiance, aovs); } else { add_non_physical_light_sample_contribution( sample, 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); } } }
void DirectLightingIntegrator::compute_outgoing_radiance_light_sampling_low_variance( SamplingContext& sampling_context, const MISHeuristic mis_heuristic, const Dual3d& outgoing, DirectShadingComponents& radiance, LightPathStream* light_path_stream) const { radiance.set(0.0f); // No light source in the scene. if (!m_light_sampler.has_lights()) return; // Check if PDF of the sampler is Dirac delta and therefore cannot contribute to the light sampling. if (!m_material_sampler.contributes_to_light_sampling()) return; if (m_light_sample_count > 0) { // Add contributions from all non-physical light sources that aren't part of the lightset. for (size_t i = 0, e = m_light_sampler.get_non_physical_light_count(); i < e; ++i) { // Sample the light. LightSample sample; m_light_sampler.sample_non_physical_light(m_time, i, sample); // Add the contribution of the chosen light. add_non_physical_light_sample_contribution( sampling_context, sample, outgoing, radiance, light_path_stream); } } // Add contributions from the light set. if (m_light_sampler.has_lightset()) { DirectShadingComponents lightset_radiance; sampling_context.split_in_place(3, m_light_sample_count); for (size_t i = 0, e = m_light_sample_count; i < e; ++i) { // Sample the light set. LightSample sample; m_light_sampler.sample_lightset( m_time, sampling_context.next2<Vector3f>(), m_material_sampler.get_shading_point(), sample); // Add the contribution of the chosen light. if (sample.m_shape) { add_emitting_shape_sample_contribution( sampling_context, sample, mis_heuristic, outgoing, lightset_radiance, light_path_stream); } else { add_non_physical_light_sample_contribution( sampling_context, sample, outgoing, lightset_radiance, light_path_stream); } } if (m_light_sample_count > 1) lightset_radiance /= static_cast<float>(m_light_sample_count); radiance += lightset_radiance; } }