Exemple #1
0
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;
}
Exemple #2
0
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;
}