const ShadingPoint& Tracer::do_trace( const Vector3d& origin, const Vector3d& direction, const double time, const ShadingRay::Type ray_type, const ShadingRay::DepthType ray_depth, double& transmission, const ShadingPoint* parent_shading_point) { transmission = 1.0; const ShadingPoint* shading_point_ptr = parent_shading_point; size_t shading_point_index = 0; Vector3d point = origin; size_t iterations = 0; while (true) { // Put a hard limit on the number of iterations. if (++iterations >= m_max_iterations) { RENDERER_LOG_WARNING( "reached hard iteration limit (%s), breaking trace loop.", pretty_int(m_max_iterations).c_str()); break; } // Construct the visibility ray. const ShadingRay ray( point, direction, time, m_ray_dtime, ray_type, ray_depth); // ray depth does not increase when passing through an alpha-mapped surface // Trace the ray. m_shading_points[shading_point_index].clear(); m_intersector.trace( ray, m_shading_points[shading_point_index], shading_point_ptr); // Update the pointers to the shading points. shading_point_ptr = &m_shading_points[shading_point_index]; shading_point_index = 1 - shading_point_index; // Stop if the ray escaped the scene. if (!shading_point_ptr->hit()) break; // Retrieve the material at the shading point. const Material* material = shading_point_ptr->get_material(); if (material == 0) break; Alpha alpha; evaluate_alpha(*material, *shading_point_ptr, alpha); // Stop at the first fully opaque occluder. if (alpha[0] >= 1.0f) break; // Update the transmission factor. transmission *= 1.0 - static_cast<double>(alpha[0]); // Stop once we hit full opacity. if (transmission < m_transmission_threshold) break; // Move past this partial occluder. point = shading_point_ptr->get_point(); } return *shading_point_ptr; }
const ShadingPoint& Tracer::do_trace_between( const Vector3d& origin, const Vector3d& target, const ShadingRay::Time& ray_time, const VisibilityFlags::Type ray_flags, const ShadingRay::DepthType ray_depth, float& transmission, const ShadingPoint* parent_shading_point) { transmission = 1.0f; const ShadingPoint* shading_point_ptr = parent_shading_point; size_t shading_point_index = 0; Vector3d point = origin; size_t iterations = 0; while (true) { // Put a hard limit on the number of iterations. if (++iterations >= m_max_iterations) { RENDERER_LOG_WARNING( "reached hard iteration limit (%s), breaking trace loop.", pretty_int(m_max_iterations).c_str()); break; } // Construct the visibility ray. const Vector3d direction = target - point; const double dist = norm(direction); const ShadingRay ray( point, direction / dist, 0.0, // ray tmin dist * (1.0 - 1.0e-6), // ray tmax ray_time, ray_flags, ray_depth); // ray depth does not increase when passing through an alpha-mapped surface // Trace the ray. m_shading_points[shading_point_index].clear(); m_intersector.trace( ray, m_shading_points[shading_point_index], shading_point_ptr); // Update the pointers to the shading points. shading_point_ptr = &m_shading_points[shading_point_index]; shading_point_index = 1 - shading_point_index; // Stop if the ray reached the target point. if (!shading_point_ptr->hit()) break; // Retrieve the material at the shading point. const Material* material = shading_point_ptr->get_material(); if (material == 0) break; // Evaluate the alpha map at the shading point. Alpha alpha; evaluate_alpha(*material, *shading_point_ptr, alpha); // Stop at the first fully opaque occluder. if (alpha[0] >= 1.0f) break; // Update the transmission factor. transmission *= 1.0f - alpha[0]; // Stop once we hit full opacity. if (transmission < m_transmission_threshold) break; // Move past this partial occluder. point = shading_point_ptr->get_point(); } return *shading_point_ptr; }