void DisneyLayeredBRDF::evaluate_inputs( const ShadingContext& shading_context, InputEvaluator& input_evaluator, const ShadingPoint& shading_point, const size_t offset) const { char* ptr = reinterpret_cast<char*>(input_evaluator.data()); DisneyBRDFInputValues* values = reinterpret_cast<DisneyBRDFInputValues*>(ptr + offset); memset(values, 0, sizeof(DisneyBRDFInputValues)); Color3d base_color(0.0); for (size_t i = 0, e = m_parent->get_layer_count(); i < e; ++i) { const DisneyMaterialLayer& layer = m_parent->get_layer(i, shading_context.get_thread_index()); layer.evaluate_expressions( shading_point, shading_context.get_oiio_texture_system(), base_color, *values); } // Colors in SeExpr are always in the sRGB color space. base_color = srgb_to_linear_rgb(base_color); values->m_base_color = Color3f(base_color); values->precompute_tint_color(); }
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; } }