Esempio n. 1
0
CompositeSurfaceClosure::CompositeSurfaceClosure(
    const BSDF*                 osl_bsdf,
    const OSL::ClosureColor*    ci)
  : m_osl_bsdf(osl_bsdf)
{
    assert(m_osl_bsdf);

    process_closure_tree(ci, Color3f(1.0f));
    compute_cdf();
}
Esempio n. 2
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();
}
Esempio n. 3
0
void CompositeEmissionClosure::process_closure_tree(
    const OSL::ClosureColor*    closure,
    const Color3f&              weight)
{
    if (closure == 0)
        return;

    switch (closure->type)
    {
      case OSL::ClosureColor::MUL:
        {
            const OSL::ClosureMul* c = reinterpret_cast<const OSL::ClosureMul*>(closure);
            process_closure_tree(c->closure, weight * Color3f(c->weight));
        }
        break;

      case OSL::ClosureColor::ADD:
        {
            const OSL::ClosureAdd* c = reinterpret_cast<const OSL::ClosureAdd*>(closure);
            process_closure_tree(c->closureA, weight);
            process_closure_tree(c->closureB, weight);
        }
        break;

      case OSL::ClosureColor::COMPONENT:
        {
            const OSL::ClosureComponent* c = reinterpret_cast<const OSL::ClosureComponent*>(closure);

            if (c->id == EmissionID)
                m_total_weight += weight * Color3f(c->w);
        }
        break;

      assert_otherwise;
    }
}
Esempio n. 4
0
CompositeEmissionClosure::CompositeEmissionClosure(
    const OSL::ClosureColor*    ci)
{
    m_total_weight = Color3f(0.0f);
    process_closure_tree(ci, Color3f(1.0f));

    const float max_comp = max_value(m_total_weight);

    if (max_comp != 0.0f)
    {
        m_total_weight /= max_comp;
        m_edf_values.m_radiance = m_total_weight;
        m_edf_values.m_radiance_multiplier = static_cast<double>(max_comp);
    }
    else
    {
        m_edf_values.m_radiance.set(0.0f);
        m_edf_values.m_radiance_multiplier = 1.0;
    }
}
Esempio 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;
    }
}
Esempio n. 6
0
void CompositeClosure::process_closure_tree(
    const OSL::ClosureColor*    closure, 
    const Color3f&              weight)
{
    if (closure == 0)
        return;

    switch (closure->type)
    {
      case OSL::ClosureColor::MUL:
        {
            const OSL::ClosureMul* c = reinterpret_cast<const OSL::ClosureMul*>(closure);
            const Color3f w = weight * Color3f(c->weight);
            process_closure_tree(c->closure, w);
        }
        break;

      case OSL::ClosureColor::ADD:
        {
            const OSL::ClosureAdd* c = reinterpret_cast<const OSL::ClosureAdd*>(closure);
            process_closure_tree(c->closureA, weight);
            process_closure_tree(c->closureB, weight);
        }
        break;

      case OSL::ClosureColor::COMPONENT:
        {
            const OSL::ClosureComponent* c = reinterpret_cast<const OSL::ClosureComponent*>(closure);
            const Color3f w = weight * Color3f(c->w);

            switch (c->id)
            {
              case AshikhminShirleyID:
                {
                    const AshikhminShirleyClosureParams* p = 
                        reinterpret_cast<const AshikhminShirleyClosureParams*>(c->data());

                    AshikminBRDFInputValues values;

                    linear_rgb_reflectance_to_spectrum(Color3f(p->Cd), values.m_rd);
                    values.m_rd_alpha.set(1.0f);
                    values.m_rd_multiplier = p->kd;

                    linear_rgb_reflectance_to_spectrum(Color3f(p->Cs), values.m_rg);
                    values.m_rg_alpha.set(1.0f);
                    values.m_rg_multiplier = p->ks;
                    values.m_fr_multiplier = 1.0;
                    values.m_nu = p->nu;
                    values.m_nv = p->nv;

                    add_closure<AshikminBRDFInputValues>(
                        static_cast<ClosureID>(c->id), 
                        w,
                        Vector3d(p->N),
                        Vector3d(p->T),
                        values);
                }
                break;

              case BackgroundID:
                {
                    // ignored for now.
                }
                break;

              case DebugID:
                {
                    // ignored for now.
                }
                break;

              case EmissionID:
                {
                    // TODO: implement...
                }
                break;

              case HoldoutID:
                {
                    // ignored for now.
                }
                break;
                
              case LambertID:
                {
                    const LambertClosureParams* p = 
                        reinterpret_cast<const LambertClosureParams*>(c->data());

                    LambertianBRDFInputValues values;
                    values.m_reflectance.set(1.0f);
                    values.m_reflectance_alpha.set(1.0f);
                    values.m_reflectance_multiplier = 1.0;

                    add_closure<LambertianBRDFInputValues>(
                        static_cast<ClosureID>(c->id),
                        w,
                        Vector3d(p->N),
                        values);
                }
                break;

              case MicrofacetBeckmannID:
              case MicrofacetBlinnID:
              case MicrofacetGGXID:
              case MicrofacetWardID:
                {
                    const MicrofacetBRDFClosureParams* p = 
                        reinterpret_cast<const MicrofacetBRDFClosureParams*>(c->data());

                    MicrofacetBRDFInputValues values;
                    values.m_reflectance.set(1.0f);
                    values.m_reflectance_alpha.set(1.0f);
                    values.m_reflectance_multiplier = 1.0;
                    values.m_glossiness = p->glossiness;
                    values.m_glossiness_multiplier = 1.0;
                    values.m_fr_multiplier = 1.0;

                    add_closure<MicrofacetBRDFInputValues>(
                        static_cast<ClosureID>(c->id), 
                        w,
                        Vector3d(p->N),
                        values);
                }
                break;

              case ReflectionID:
                {
                    const ReflectionClosureParams* p = 
                        reinterpret_cast<const ReflectionClosureParams*>(c->data());

                    SpecularBRDFInputValues values;
                    values.m_reflectance.set(1.0f);
                    values.m_reflectance_alpha.set(1.0f);
                    values.m_reflectance_multiplier = 1.0;

                    add_closure<SpecularBRDFInputValues>(
                        static_cast<ClosureID>(c->id), 
                        w, 
                        Vector3d(p->N),
                        values);
                }
                break;

              case RefractionID:
                {
                    const RefractionClosureParams* p = 
                        reinterpret_cast<const RefractionClosureParams*>(c->data());

                    SpecularBTDFInputValues values;
                    values.m_reflectance.set(1.0f);
                    values.m_from_ior = p->from_ior;
                    values.m_to_ior = p->to_ior;
                    values.m_reflectance_alpha = Alpha(1.0);
                    values.m_reflectance_multiplier = 1.0;

                    add_closure<SpecularBTDFInputValues>(
                        static_cast<ClosureID>(c->id), 
                        w, 
                        Vector3d(p->N),
                        values);
                }
                break;

              case TranslucentID:
                {
                    const TranslucentClosureParams* p = 
                        reinterpret_cast<const TranslucentClosureParams*>(c->data());

                    DiffuseBTDFInputValues values;
                    values.m_transmittance.set(1.0f);
                    values.m_transmittance_alpha = Alpha(1.0);
                    values.m_transmittance_multiplier = 1.0;

                    add_closure<DiffuseBTDFInputValues>(
                        static_cast<ClosureID>(c->id), 
                        w, 
                        Vector3d(p->N),
                        values);
                }
                break;

              case TransparentID:
                // Transparency is handled in another place.
                break;

              assert_otherwise;
            }
        }
        break;

      assert_otherwise;
    }
}
Esempio n. 7
0
void CompositeClosure::process_closure_tree(
    const OSL::ClosureColor*    closure,
    const Color3f&              weight)
{
    if (closure == 0)
        return;

    switch (closure->type)
    {
      case OSL::ClosureColor::MUL:
        {
            const OSL::ClosureMul* c = reinterpret_cast<const OSL::ClosureMul*>(closure);
            const Color3f w = weight * Color3f(c->weight);
            process_closure_tree(c->closure, w);
        }
        break;

      case OSL::ClosureColor::ADD:
        {
            const OSL::ClosureAdd* c = reinterpret_cast<const OSL::ClosureAdd*>(closure);
            process_closure_tree(c->closureA, weight);
            process_closure_tree(c->closureB, weight);
        }
        break;

      case OSL::ClosureColor::COMPONENT:
        {
            const OSL::ClosureComponent* c = reinterpret_cast<const OSL::ClosureComponent*>(closure);
            const Color3f w = weight * Color3f(c->w);

            switch (c->id)
            {
              case AshikhminShirleyID:
                {
                    const AshikhminShirleyBRDFClosureParams* p =
                        reinterpret_cast<const AshikhminShirleyBRDFClosureParams*>(c->data());

                    AshikminBRDFInputValues values;

                    linear_rgb_reflectance_to_spectrum(Color3f(p->Cd), values.m_rd);
                    values.m_rd_multiplier = saturate(p->kd);

                    linear_rgb_reflectance_to_spectrum(Color3f(p->Cs), values.m_rg);
                    values.m_rg_multiplier = saturate(p->ks);
                    values.m_fr_multiplier = 1.0;
                    values.m_nu = max(p->nu, 0.0f);
                    values.m_nv = max(p->nv, 0.0f);

                    add_closure<AshikminBRDFInputValues>(
                        static_cast<ClosureID>(c->id),
                        w,
                        Vector3d(p->N),
                        Vector3d(p->T),
                        values);
                }
                break;

              case DisneyID:
                {
                    const DisneyBRDFClosureParams* p =
                        reinterpret_cast<const DisneyBRDFClosureParams*>(c->data());

                    DisneyBRDFInputValues values;
                    linear_rgb_reflectance_to_spectrum(Color3f(p->base_color), values.m_base_color);
                    values.m_subsurface = saturate(p->subsurface);
                    values.m_metallic = saturate(p->metallic);
                    values.m_specular = max(p->specular, 0.0f);
                    values.m_specular_tint = saturate(p->specular_tint);
                    values.m_anisotropic = saturate(p->anisotropic);
                    values.m_roughness = clamp(p->roughness, 0.0001f, 1.0f);
                    values.m_sheen = saturate(p->sheen);
                    values.m_sheen_tint = saturate(p->sheen_tint);
                    values.m_clearcoat = max(p->clearcoat, 0.0f);
                    values.m_clearcoat_gloss = clamp(p->clearcoat_gloss, 0.0001f, 1.0f);
                    values.precompute_tint_color();

                    add_closure<DisneyBRDFInputValues>(
                        static_cast<ClosureID>(c->id),
                        w,
                        Vector3d(p->N),
                        Vector3d(p->T),
                        values);
                }
                break;

              case LambertID:
                {
                    const DiffuseBSDFClosureParams* p =
                        reinterpret_cast<const DiffuseBSDFClosureParams*>(c->data());

                    LambertianBRDFInputValues values;
                    values.m_reflectance.set(1.0f);
                    values.m_reflectance_multiplier = 1.0;

                    add_closure<LambertianBRDFInputValues>(
                        static_cast<ClosureID>(c->id),
                        w,
                        Vector3d(p->N),
                        values);
                }
                break;

              case MicrofacetID:
                {
                    const MicrofacetClosureParams* p =
                        reinterpret_cast<const MicrofacetClosureParams*>(c->data());
                    
                    if (!p->refract)
                    {
                        OSLMicrofacetBRDFInputValues values;
                        values.m_ax = max(p->xalpha, 0.0001f);
                        values.m_ay = max(p->yalpha, 0.0001f);
    
                        if (p->dist == blinn_mdf_name)
                        {
                            add_closure<OSLMicrofacetBRDFInputValues>(
                                MicrofacetBlinnReflectionID,
                                w,
                                Vector3d(p->N),
                                Vector3d(p->T),
                                values);
                        }
                        else if (p->dist == ggx_mdf_name)
                        {
                            add_closure<OSLMicrofacetBRDFInputValues>(
                                MicrofacetGGXReflectionID,
                                w,
                                Vector3d(p->N),
                                Vector3d(p->T),
                                values);
                        }
                        else // Beckmann by default.
                        {
                            add_closure<OSLMicrofacetBRDFInputValues>(
                                MicrofacetBeckmannReflectionID,
                                w,
                                Vector3d(p->N),
                                Vector3d(p->T),
                                values);
                        }                        
                    }
                    else
                    {
                        // Assume one of the media is air.
                        double from_ior, to_ior;
                        if (p->eta > 1.0)
                        {
                            from_ior = 1.0;
                            to_ior = 1.0 / p->eta;
                        }
                        else
                        {
                            from_ior = p->eta;
                            to_ior = 1.0;
                        }

                        OSLMicrofacetBTDFInputValues values;
                        values.m_ax = max(p->xalpha, 0.0001f);
                        values.m_ay = max(p->yalpha, 0.0001f);
                        values.m_from_ior = from_ior;
                        values.m_to_ior = to_ior;

                        if (p->dist == ggx_mdf_name)
                        {
                            add_closure<OSLMicrofacetBTDFInputValues>(
                                MicrofacetGGXRefractionID,
                                w,
                                Vector3d(p->N),
                                Vector3d(p->T),
                                values);
                        }
                        else // beckmann by default
                        {
                            add_closure<OSLMicrofacetBTDFInputValues>(
                                MicrofacetBeckmannRefractionID,
                                w,
                                Vector3d(p->N),
                                Vector3d(p->T),
                                values);
                        }
                    }
                }
                break;

              case OrenNayarID:
                {
                    const OrenNayarBRDFClosureParams* p =
                        reinterpret_cast<const OrenNayarBRDFClosureParams*>(c->data());

                    OrenNayarBRDFInputValues values;
                    values.m_reflectance.set(1.0f);
                    values.m_reflectance_multiplier = 1.0;
                    values.m_roughness = max(p->roughness, 0.0f);

                    add_closure<OrenNayarBRDFInputValues>(
                        static_cast<ClosureID>(c->id),
                        w,
                        Vector3d(p->N),
                        values);
                }
                break;

              case ReflectionID:
                {
                    const ReflectionBRDFClosureParams* p =
                        reinterpret_cast<const ReflectionBRDFClosureParams*>(c->data());

                    SpecularBRDFInputValues values;
                    values.m_reflectance.set(1.0f);
                    values.m_reflectance_multiplier = 1.0;

                    add_closure<SpecularBRDFInputValues>(
                        static_cast<ClosureID>(c->id),
                        w,
                        Vector3d(p->N),
                        values);
                }
                break;

              case RefractionID:
                {
                    const RefractionBTDFClosureParams* p =
                        reinterpret_cast<const RefractionBTDFClosureParams*>(c->data());

                    // Assume on of the mediums is air.
                    double from_ior, to_ior;
                    if (p->eta > 1.0)
                    {
                        from_ior = 1.0;
                        to_ior = 1.0f / p->eta;
                    }
                    else
                    {
                        from_ior = p->eta;
                        to_ior = 1.0;
                    }

                    SpecularBTDFInputValues values;
                    values.m_reflectance.set(0.0f);
                    values.m_reflectance_multiplier = 0.0;
                    values.m_transmittance.set(1.0f);
                    values.m_transmittance_multiplier = 1.0;
                    values.m_fresnel_multiplier = 0.0;
                    values.m_from_ior = from_ior;
                    values.m_to_ior = to_ior;

                    add_closure<SpecularBTDFInputValues>(
                        static_cast<ClosureID>(c->id),
                        w,
                        Vector3d(p->N),
                        values);
                }
                break;

              case TranslucentID:
                {
                    const DiffuseBSDFClosureParams* p =
                        reinterpret_cast<const DiffuseBSDFClosureParams*>(c->data());

                    DiffuseBTDFInputValues values;
                    values.m_transmittance.set(1.0f);
                    values.m_transmittance_multiplier = 1.0;

                    add_closure<DiffuseBTDFInputValues>(
                        static_cast<ClosureID>(c->id),
                        w,
                        Vector3d(p->N),
                        values);
                }
                break;

              // These are handled in another place.
              case BackgroundID:
              case DebugID:
              case EmissionID:
              case HoldoutID:
              case TransparentID:
                break;

              assert_otherwise;
            }
        }
        break;

      assert_otherwise;
    }
}
Esempio n. 8
0
void CompositeSubsurfaceClosure::process_closure_tree(
    const OSL::ClosureColor*    closure,
    const foundation::Color3f&  weight)
{
    if (closure == 0)
        return;

    switch (closure->type)
    {
      case OSL::ClosureColor::MUL:
        {
            const OSL::ClosureMul* c = reinterpret_cast<const OSL::ClosureMul*>(closure);
            process_closure_tree(c->closure, weight * Color3f(c->weight));
        }
        break;

      case OSL::ClosureColor::ADD:
        {
            const OSL::ClosureAdd* c = reinterpret_cast<const OSL::ClosureAdd*>(closure);
            process_closure_tree(c->closureA, weight);
            process_closure_tree(c->closureB, weight);
        }
        break;

      case OSL::ClosureColor::COMPONENT:
        {
            const OSL::ClosureComponent* c = reinterpret_cast<const OSL::ClosureComponent*>(closure);
            const Color3f w = weight * Color3f(c->w);

            if (c->id == SubsurfaceID)
            {
                /*
                const SubsurfaceClosureParams* p =
                    reinterpret_cast<const SubsurfaceClosureParams*>(c->data());

                if (p->profile == directional_profile_name)
                {
                    DirectionalDipoleBSSRDFInputValues values;
                    values.m_reflectance = Color3f(p->reflectance);
                    values.m_dmfp = Color3f(p->diffuse_mean_free_path);
                    values.m_dmfp_multiplier = 1.0;
                    values.m_anisotropy = 0.0;
                    values.m_outside_ior = 1.0;
                    values.m_inside_ior = 1.0 / p->eta;

                    add_closure<DirectionalDipoleBSSRDFInputValues>(
                        SubsurfaceDirectionalID,
                        w,
                        values);

                }
                else
                    assert(false);
                */
            }
        }
        break;

      assert_otherwise;
    }
}
Esempio n. 9
0
CompositeSubsurfaceClosure::CompositeSubsurfaceClosure(
    const OSL::ClosureColor*    ci)
{
    process_closure_tree(ci, Color3f(1.0f));
    compute_cdf();
}