size_t generate_environment_sample( SamplingContext& sampling_context, const EnvironmentEDF* env_edf, SampleVector& samples) { // Sample the environment. sampling_context.split_in_place(2, 1); InputEvaluator input_evaluator(m_texture_cache); Vector3f outgoing; Spectrum env_edf_value; float env_edf_prob; env_edf->sample( m_shading_context, input_evaluator, sampling_context.next2<Vector2f>(), outgoing, // points toward the environment env_edf_value, env_edf_prob); // Uniformly sample the tangent disk. sampling_context.split_in_place(2, 1); const Vector2d p = m_scene_radius * sample_disk_uniform(sampling_context.next2<Vector2d>()); // Compute the origin of the light ray. const Basis3d basis(-Vector3d(outgoing)); const Vector3d ray_origin = m_scene_center - m_safe_scene_diameter * basis.get_normal() // a safe radius would have been sufficient + p[0] * basis.get_tangent_u() + + p[1] * basis.get_tangent_v(); // Compute the initial particle weight. Spectrum initial_flux = env_edf_value; initial_flux /= m_disk_point_prob * env_edf_prob; // Build the light ray. sampling_context.split_in_place(1, 1); const ShadingRay::Time time = ShadingRay::Time::create_with_normalized_time( sampling_context.next2<float>(), m_shutter_open_time, m_shutter_close_time); const ShadingRay light_ray( ray_origin, -Vector3d(outgoing), time, VisibilityFlags::LightRay, 0); // Build the path tracer. PathVisitor path_visitor( m_params, m_scene, m_frame, m_shading_context, sampling_context, samples, initial_flux); PathTracerType path_tracer( path_visitor, m_params.m_rr_min_path_length, m_params.m_max_path_length, m_params.m_max_iterations); // Trace the light path. const size_t path_length = path_tracer.trace( sampling_context, m_shading_context, light_ray); // Update path statistics. ++m_path_count; m_path_length.insert(path_length); // Return the number of samples generated when tracing this light path. return path_visitor.get_sample_count(); }
size_t generate_environment_sample( SamplingContext& sampling_context, const EnvironmentEDF* env_edf, SampleVector& samples) { // Sample the environment. sampling_context.split_in_place(2, 1); InputEvaluator input_evaluator(m_texture_cache); Vector3d outgoing; Spectrum env_edf_value; double env_edf_prob; env_edf->sample( input_evaluator, sampling_context.next_vector2<2>(), outgoing, // points toward the environment env_edf_value, env_edf_prob); // Compute the center of the tangent disk. const Vector3d disk_center = m_safe_scene_radius * outgoing; // Uniformly sample the tangent disk. sampling_context.split_in_place(2, 1); const Vector2d disk_point = m_safe_scene_radius * sample_disk_uniform(sampling_context.next_vector2<2>()); // Compute the origin of the light ray. const Basis3d basis(-outgoing); const Vector3d ray_origin = disk_center + disk_point[0] * basis.get_tangent_u() + disk_point[1] * basis.get_tangent_v(); // Compute the initial particle weight. Spectrum initial_flux = env_edf_value; initial_flux /= static_cast<float>(m_disk_point_prob * env_edf_prob); // Build the light ray. sampling_context.split_in_place(1, 1); const ShadingRay light_ray( ray_origin, -outgoing, sampling_context.next_double2(), m_ray_dtime, ShadingRay::LightRay); // Build the path tracer. PathVisitor path_visitor( m_params, m_scene, m_frame, m_shading_context, samples, initial_flux); PathTracerType path_tracer( path_visitor, m_params.m_rr_min_path_length, m_params.m_max_path_length, m_params.m_max_iterations); // Trace the light path. const size_t path_length = path_tracer.trace( sampling_context, m_shading_context, light_ray); // Update path statistics. ++m_path_count; m_path_length.insert(path_length); // Return the number of samples generated when tracing this light path. return path_visitor.get_sample_count(); }