Ejemplo n.º 1
0
size_t CompositeClosure::choose_closure(const double w) const
{
    assert(w >= 0.0);
    assert(w < 1.0);

    const double *i =
        upper_bound(
            m_cdf,
            m_cdf + get_num_closures(),
            w);

    assert(i < m_cdf + get_num_closures());

    return i - m_cdf;
}
Ejemplo n.º 2
0
void CompositeClosure::do_add_closure(
    const ClosureID             closure_type,
    const Color3f&              weight,
    const Vector3d&             normal,
    const bool                  has_tangent,
    const Vector3d&             tangent,
    const InputValues&          params)
{
    // Check that InputValues is included in our type list.
    typedef typename boost::mpl::contains<InputValuesTypeList,InputValues>::type value_in_list;
    BOOST_STATIC_ASSERT( value_in_list::value);
    
    // Make sure we have enough space.
    if (get_num_closures() >= MaxClosureEntries)
    {
        RENDERER_LOG_WARNING("maximum number of closures in OSL shadergroup exceeded; ignoring closure.");
        return;
    }

    assert(m_num_bytes + sizeof(InputValues) <= MaxPoolSize);

    // We use the luminance of the weight as the BSDF weight.
    const double w = luminance(weight);

    // Ignore zero or negative weights.
    if (w <= 0.0)
        return;

    m_cdf.insert(get_num_closures(), w);
    linear_rgb_reflectance_to_spectrum(weight, m_spectrum_multipliers[m_num_closures]);
    m_normals[m_num_closures] = normalize(normal);
    m_has_tangent[m_num_closures] = has_tangent;

    if (has_tangent)
        m_tangents[m_num_closures] = normalize(tangent);

    m_closure_types[m_num_closures] = closure_type;

    char* values_ptr = m_pool + m_num_bytes;
    assert(is_aligned(values_ptr, InputValuesAlignment));
    new (values_ptr) InputValues(params);
    m_input_values[m_num_closures] = values_ptr;
    m_num_bytes += align(sizeof(InputValues), InputValuesAlignment);
    ++m_num_closures;
}
Ejemplo n.º 3
0
CompositeClosure::CompositeClosure(
    const OSL::ClosureColor* ci)
  : m_num_closures(0)
  , m_num_bytes(0)
{
    assert(is_aligned(m_pool, InputValuesAlignment));

    process_closure_tree(ci, Color3f(1.0f));

    if (get_num_closures())
        m_cdf.prepare();
}
Ejemplo n.º 4
0
void CompositeSurfaceClosure::do_add_closure(
    const ClosureID             closure_type,
    const Color3f&              weight,
    const Vector3d&             normal,
    bool                        has_tangent,
    const Vector3d&             tangent,
    const InputValues&          params)
{
    // Check that InputValues is included in our type list.
    typedef typename boost::mpl::contains<InputValuesTypeList, InputValues>::type value_in_list;
    BOOST_STATIC_ASSERT(value_in_list::value);

    // Make sure we have enough space.
    if (get_num_closures() >= MaxClosureEntries)
    {
        RENDERER_LOG_WARNING("maximum number of closures in osl shader group exceeded; ignoring closure.");
        return;
    }

    assert(m_num_bytes + sizeof(InputValues) <= MaxPoolSize);

    // We use the luminance of the weight as the BSDF weight.
    const double w = luminance(weight);

    // Ignore zero or negative weights.
    if (w <= 0.0)
        return;

    m_pdf_weights[m_num_closures] = w;
    m_weights[m_num_closures] = weight;
    m_normals[m_num_closures] = normalize(normal);

    // If the tangent is zero, ignore it.
    // This can happen when using the isotropic microfacet closure overloads, for example.
    if (square_norm(tangent) == 0.0)
        has_tangent = false;

    m_has_tangent[m_num_closures] = has_tangent;

    if (has_tangent)
        m_tangents[m_num_closures] = normalize(tangent);

    m_closure_types[m_num_closures] = closure_type;

    char* values_ptr = m_pool + m_num_bytes;
    assert(is_aligned(values_ptr, InputValuesAlignment));
    new (values_ptr) InputValues(params);
    m_input_values[m_num_closures] = values_ptr;
    m_num_bytes += align(sizeof(InputValues), InputValuesAlignment);
    ++m_num_closures;
}
Ejemplo n.º 5
0
CompositeClosure::CompositeClosure(
    const OSL::ClosureColor* ci)
  : m_num_closures(0)
  , m_num_bytes(0)
{
    assert(is_aligned(m_pool, InputValuesAlignment));

    process_closure_tree(ci, Color3f(1.0f));

    if (get_num_closures())
    {
        double total_weight = 0.0;
        for (size_t i = 0, e = get_num_closures(); i < e; ++i)
        {
            total_weight += m_cdf[i];
            m_cdf[i] = total_weight;            
        }

        for (size_t i = 0, e = get_num_closures() - 1; i < e; ++i)
            m_cdf[i] /= total_weight;
        
        m_cdf[get_num_closures() - 1] = 1.0;
    }
}
Ejemplo n.º 6
0
void CompositeClosure::compute_cdf()
{
    const size_t closure_count = get_num_closures();
    if (closure_count > 0)
    {
        double total_weight = 0.0;
        for (size_t i = 0; i < closure_count; ++i)
        {
            total_weight += m_pdf_weights[i];
            m_cdf[i] = total_weight;
        }

        const double rcp_total_weight = 1.0 / total_weight;

        for (size_t i = 0; i < closure_count; ++i)
            m_pdf_weights[i] *= rcp_total_weight;

        for (size_t i = 0; i < closure_count - 1; ++i)
            m_cdf[i] *= rcp_total_weight;

        m_cdf[closure_count - 1] = 1.0;
    }
}
Ejemplo n.º 7
0
void CompositeSubsurfaceClosure::add_closure(
    const ClosureID             closure_type,
    const Color3f&              weight,
    const InputValues&          params)
{
    // Check that InputValues is included in our type list.
    typedef typename boost::mpl::contains<InputValuesTypeList, InputValues>::type value_in_list;
    BOOST_STATIC_ASSERT(value_in_list::value);

    // Make sure we have enough space.
    if (get_num_closures() >= MaxClosureEntries)
    {
        RENDERER_LOG_WARNING("maximum number of subsurface closures in osl shader group exceeded; ignoring closure.");
        return;
    }

    assert(m_num_bytes + sizeof(InputValues) <= MaxPoolSize);

    // We use the luminance of the weight as the BSSRDF weight.
    const double w = luminance(weight);

    // Ignore zero or negative weights.
    if (w <= 0.0)
        return;

    m_pdf_weights[m_num_closures] = w;
    m_weights[m_num_closures] = weight;
    m_closure_types[m_num_closures] = closure_type;

    char* values_ptr = m_pool + m_num_bytes;
    assert(is_aligned(values_ptr, InputValuesAlignment));
    new (values_ptr) InputValues(params);
    m_input_values[m_num_closures] = values_ptr;
    m_num_bytes += align(sizeof(InputValues), InputValuesAlignment);
    ++m_num_closures;
}
Ejemplo n.º 8
0
size_t CompositeClosure::choose_closure(const double w) const
{
    return sample_cdf(m_cdf, m_cdf + get_num_closures(), w);
}