// // Copyright 2016 Pixar // // Licensed under the Apache License, Version 2.0 (the "Apache License") // with the following modification; you may not use this file except in // compliance with the Apache License and the following modification to it: // Section 6. Trademarks. is deleted and replaced with: // // 6. Trademarks. This License does not grant permission to use the trade // names, trademarks, service marks, or product names of the Licensor // and its affiliates, except as required to comply with Section 4(c) of // the License and to reproduce the content of the NOTICE file. // // You may obtain a copy of the Apache License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the Apache License with the above modification is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // #ifndef USDSHADE_GENERATED_MATERIAL_H #define USDSHADE_GENERATED_MATERIAL_H /// \file usdShade/material.h #include "pxr/pxr.h" #include "pxr/usd/usdShade/api.h" #include "pxr/usd/usdShade/nodeGraph.h" #include "pxr/usd/usd/prim.h" #include "pxr/usd/usd/stage.h" #include "pxr/usd/usdShade/tokens.h" #include "pxr/usd/usd/variantSets.h" #include "pxr/usd/usdGeom/subset.h" #include "pxr/usd/usdShade/connectableAPI.h" #include "pxr/base/vt/value.h" #include "pxr/base/gf/vec3d.h" #include "pxr/base/gf/vec3f.h" #include "pxr/base/gf/matrix4d.h" #include "pxr/base/tf/token.h" #include "pxr/base/tf/type.h" PXR_NAMESPACE_OPEN_SCOPE class SdfAssetPath; // -------------------------------------------------------------------------- // // MATERIAL // // -------------------------------------------------------------------------- // /// \class UsdShadeMaterial /// /// A Material provides a container into which multiple "render targets" /// can add data that defines a "shading material" for a renderer. Typically /// this consists of one or more UsdRelationship properties that target /// other prims of type \em Shader - though a target/client is free to add /// any data that is suitable. We strongly advise that all targets /// adopt the convention that all properties be prefixed with a namespace /// that identifies the target, e.g. "rel ri:surface = ". /// /// ## Binding Materials /// /// In the UsdShading model, geometry expresses a binding to a single Material or /// to a set of Materials partitioned by UsdGeomSubsets defined beneath the /// geometry; it is legal to bind a Material at the root (or other sub-prim) of /// a model, and then bind a different Material to individual gprims, but the /// meaning of inheritance and "ancestral overriding" of Material bindings is /// left to each render-target to determine. Since UsdGeom has no concept of /// shading, we provide the API for binding and unbinding geometry on the API /// schema UsdShadeMaterialBindingAPI. /// /// ## Material Variation /// /// The entire power of USD VariantSets and all the other composition /// operators can leveraged when encoding shading variation. /// UsdShadeMaterial provides facilities for a particular way of building /// "Material variants" in which neither the identity of the Materials themselves /// nor the geometry Material-bindings need to change - instead we vary the /// targeted networks, interface values, and even parameter values within /// a single variantSet. /// See \ref UsdShadeMaterial_Variations "Authoring Material Variations" /// for more details. /// /// ## Materials Encapsulate their Networks in Namespace /// /// UsdShade requires that all of the shaders that "belong" to the Material /// live under the Material in namespace. This supports powerful, easy reuse /// of Materials, because it allows us to *reference* a Material from one /// asset (the asset might be a library of Materials) into another asset: USD /// references compose all descendant prims of the reference target into the /// referencer's namespace, which means that all of the referenced Material's /// shader networks will come along with the Material. When referenced in this /// way, Materials can also be [instanced](http://openusd.org/docs/USD-Glossary.html#USDGlossary-Instancing), for ease of deduplication and compactness. /// Finally, Material encapsulation also allows us to /// \ref UsdShadeMaterial_BaseMaterial "specialize" child materials from /// parent materials. /// /// /// /// For any described attribute \em Fallback \em Value or \em Allowed \em Values below /// that are text/tokens, the actual token is published and defined in \ref UsdShadeTokens. /// So to set an attribute to the value "rightHanded", use UsdShadeTokens->rightHanded /// as the value. /// class UsdShadeMaterial : public UsdShadeNodeGraph { public: /// Compile time constant representing what kind of schema this class is. /// /// \sa UsdSchemaType static const UsdSchemaType schemaType = UsdSchemaType::ConcreteTyped; /// Construct a UsdShadeMaterial on UsdPrim \p prim . /// Equivalent to UsdShadeMaterial::Get(prim.GetStage(), prim.GetPath()) /// for a \em valid \p prim, but will not immediately throw an error for /// an invalid \p prim explicit UsdShadeMaterial(const UsdPrim& prim=UsdPrim()) : UsdShadeNodeGraph(prim) { } /// Construct a UsdShadeMaterial on the prim held by \p schemaObj . /// Should be preferred over UsdShadeMaterial(schemaObj.GetPrim()), /// as it preserves SchemaBase state. explicit UsdShadeMaterial(const UsdSchemaBase& schemaObj) : UsdShadeNodeGraph(schemaObj) { } /// Destructor. USDSHADE_API virtual ~UsdShadeMaterial(); /// Return a vector of names of all pre-declared attributes for this schema /// class and all its ancestor classes. Does not include attributes that /// may be authored by custom/extended methods of the schemas involved. USDSHADE_API static const TfTokenVector & GetSchemaAttributeNames(bool includeInherited=true); /// Return a UsdShadeMaterial holding the prim adhering to this /// schema at \p path on \p stage. If no prim exists at \p path on /// \p stage, or if the prim at that path does not adhere to this schema, /// return an invalid schema object. This is shorthand for the following: /// /// \code /// UsdShadeMaterial(stage->GetPrimAtPath(path)); /// \endcode /// USDSHADE_API static UsdShadeMaterial Get(const UsdStagePtr &stage, const SdfPath &path); /// Attempt to ensure a \a UsdPrim adhering to this schema at \p path /// is defined (according to UsdPrim::IsDefined()) on this stage. /// /// If a prim adhering to this schema at \p path is already defined on this /// stage, return that prim. Otherwise author an \a SdfPrimSpec with /// \a specifier == \a SdfSpecifierDef and this schema's prim type name for /// the prim at \p path at the current EditTarget. Author \a SdfPrimSpec s /// with \p specifier == \a SdfSpecifierDef and empty typeName at the /// current EditTarget for any nonexistent, or existing but not \a Defined /// ancestors. /// /// The given \a path must be an absolute prim path that does not contain /// any variant selections. /// /// If it is impossible to author any of the necessary PrimSpecs, (for /// example, in case \a path cannot map to the current UsdEditTarget's /// namespace) issue an error and return an invalid \a UsdPrim. /// /// Note that this method may return a defined prim whose typeName does not /// specify this schema class, in case a stronger typeName opinion overrides /// the opinion at the current EditTarget. /// USDSHADE_API static UsdShadeMaterial Define(const UsdStagePtr &stage, const SdfPath &path); protected: /// Returns the type of schema this class belongs to. /// /// \sa UsdSchemaType USDSHADE_API UsdSchemaType _GetSchemaType() const override; private: // needs to invoke _GetStaticTfType. friend class UsdSchemaRegistry; USDSHADE_API static const TfType &_GetStaticTfType(); static bool _IsTypedSchema(); // override SchemaBase virtuals. USDSHADE_API const TfType &_GetTfType() const override; public: // --------------------------------------------------------------------- // // SURFACE // --------------------------------------------------------------------- // /// Represents the universal "surface" output terminal of a /// material. /// /// | || /// | -- | -- | /// | Declaration | `token outputs:surface` | /// | C++ Type | TfToken | /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Token | USDSHADE_API UsdAttribute GetSurfaceAttr() const; /// See GetSurfaceAttr(), and also /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create. /// If specified, author \p defaultValue as the attribute's default, /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true - /// the default for \p writeSparsely is \c false. USDSHADE_API UsdAttribute CreateSurfaceAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const; public: // --------------------------------------------------------------------- // // DISPLACEMENT // --------------------------------------------------------------------- // /// Represents the universal "displacement" output terminal of a /// material. /// /// | || /// | -- | -- | /// | Declaration | `token outputs:displacement` | /// | C++ Type | TfToken | /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Token | USDSHADE_API UsdAttribute GetDisplacementAttr() const; /// See GetDisplacementAttr(), and also /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create. /// If specified, author \p defaultValue as the attribute's default, /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true - /// the default for \p writeSparsely is \c false. USDSHADE_API UsdAttribute CreateDisplacementAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const; public: // --------------------------------------------------------------------- // // VOLUME // --------------------------------------------------------------------- // /// Represents the universal "volume" output terminal of a /// material. /// /// | || /// | -- | -- | /// | Declaration | `token outputs:volume` | /// | C++ Type | TfToken | /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Token | USDSHADE_API UsdAttribute GetVolumeAttr() const; /// See GetVolumeAttr(), and also /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create. /// If specified, author \p defaultValue as the attribute's default, /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true - /// the default for \p writeSparsely is \c false. USDSHADE_API UsdAttribute CreateVolumeAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const; public: // ===================================================================== // // Feel free to add custom code below this line, it will be preserved by // the code generator. // // Just remember to: // - Close the class declaration with }; // - Close the namespace with PXR_NAMESPACE_CLOSE_SCOPE // - Close the include guard with #endif // ===================================================================== // // --(BEGIN CUSTOM CODE)-- // --------------------------------------------------------------------- // /// \name Helpful Types /// @{ // --------------------------------------------------------------------- // /// A function type that takes a path and returns a bool. typedef std::function PathPredicate; /// @} // --------------------------------------------------------------------- // /// \anchor UsdShadeMaterial_Outputs /// \name Standard Material Terminal Outputs /// A UsdShadeMaterial can have any number of "terminal" outputs. These /// outputs are generally used to point to outputs of shader prims or /// NodeGraphs that describe certain properties of the material that a /// renderer might wish to consume. There are three standard output /// terminals that are supported by the core API: surface, /// displacement and volume. /// /// Each terminal output can further be qualified by a token-valued /// renderContext. When a non-empty renderContext value is specified /// to the API, the output is considered to have a specific or restricted /// renderContext. If the renderContext value is empty (i.e. equal to /// UsdShadeTokens->universalRenderContext), then the output is considered /// to be a "universal", meaning it could apply to any render contexts. /// Render context token values is typically driven by the rendering backend /// consuming the terminal output (eg, RI or glslfx). /// @{ /// Creates and returns the "surface" output on this material for the /// specified \p renderContext. /// /// If the output already exists on the material, it is returned and no /// authoring is performed. The returned output will always have the /// requested renderContext. USDSHADE_API UsdShadeOutput CreateSurfaceOutput(const TfToken &renderContext =UsdShadeTokens->universalRenderContext) const; /// Returns the "surface" output of this material for the specified /// \p renderContext. The returned output will always have the requested /// renderContext. /// /// An invalid output is returned if an output corresponding to the /// requested specific-renderContext does not exist. /// /// \sa UsdShadeMaterial::ComputeSurfaceSource() USDSHADE_API UsdShadeOutput GetSurfaceOutput(const TfToken &renderContext =UsdShadeTokens->universalRenderContext) const; /// Computes the resolved "surface" output source for the given /// \p renderContext. /// /// If a "surface" output corresponding to the specific renderContext /// does not exist or is not connected to a valid source, then this /// checks the universal surface output. /// /// Returns an empty Shader object if there is no valid surface /// output source for the requested \p renderContext. /// The python version of this method returns a tuple containing three /// elements (the source surface shader, sourceName, sourceType). USDSHADE_API UsdShadeShader ComputeSurfaceSource( const TfToken &renderContext=UsdShadeTokens->universalRenderContext, TfToken *sourceName=nullptr, UsdShadeAttributeType *sourceType=nullptr) const; /// Creates and returns the "displacement" output on this material for the /// specified \p renderContext. /// /// If the output already exists on the material, it is returned and no /// authoring is performed. The returned output will always have the /// requested renderContext. USDSHADE_API UsdShadeOutput CreateDisplacementOutput(const TfToken &renderContext =UsdShadeTokens->universalRenderContext) const; /// Returns the "displacement" output of this material for the specified /// renderContext. The returned output will always have the requested /// renderContext. /// /// An invalid output is returned if an output corresponding to the /// requested specific-renderContext does not exist. /// /// \sa UsdShadeMaterial::ComputeDisplacementSource() USDSHADE_API UsdShadeOutput GetDisplacementOutput(const TfToken &renderContext =UsdShadeTokens->universalRenderContext) const; /// Computes the resolved "displacement" output source for the given /// \p renderContext. /// /// If a "displacement" output corresponding to the specific renderContext /// does not exist or is not connected to a valid source, then this /// checks the universal displacement output. /// /// Returns an empty Shader object if there is no valid displacement /// output source for the requested \p renderContext. /// The python version of this method returns a tuple containing three /// elements (the source displacement shader, sourceName, sourceType). USDSHADE_API UsdShadeShader ComputeDisplacementSource( const TfToken &renderContext=UsdShadeTokens->universalRenderContext, TfToken *sourceName=nullptr, UsdShadeAttributeType *sourceType=nullptr) const; /// Creates and returns the "volume" output on this material for the /// specified \p renderContext. /// /// If the output already exists on the material, it is returned and no /// authoring is performed. The returned output will always have the /// requested renderContext. USDSHADE_API UsdShadeOutput CreateVolumeOutput(const TfToken &renderContext =UsdShadeTokens->universalRenderContext) const; /// Returns the "volume" output of this material for the specified /// renderContext. The returned output will always have the requested /// renderContext. /// /// An invalid output is returned if an output corresponding to the /// requested specific-renderContext does not exist. /// /// \sa UsdShadeMaterial::ComputeVolumeSource() USDSHADE_API UsdShadeOutput GetVolumeOutput(const TfToken &renderContext =UsdShadeTokens->universalRenderContext) const; /// Computes the resolved "volume" output source for the given /// \p renderContext. /// /// If a "volume" output corresponding to the specific renderContext /// does not exist or is not connected to a valid source, then this /// checks the universal volume output. /// /// Returns an empty Shader object if there is no valid volume output /// source for the requested \p renderContext. /// The python version of this method returns a tuple containing three /// elements (the source volume shader, sourceName, sourceType). USDSHADE_API UsdShadeShader ComputeVolumeSource( const TfToken &renderContext=UsdShadeTokens->universalRenderContext, TfToken *sourceName=nullptr, UsdShadeAttributeType *sourceType=nullptr) const; /// @} private: // Helper method to compute the source of a given output, identified by its // baseName, for the specified renderContext. bool _ComputeNamedOutputSource( const TfToken &baseName, const TfToken &renderContext, UsdShadeConnectableAPI *source, TfToken *sourceName, UsdShadeAttributeType *sourceType) const; // Helper method to compute the source shader of a given output, identified // by its baseName, for the specified renderContext. UsdShadeShader _ComputeNamedOutputShader( const TfToken &baseName, const TfToken &renderContext, TfToken *sourceName, UsdShadeAttributeType *sourceType) const; public: // --------------------------------------------------------------------- // /// \anchor UsdShadeMaterial_Variations /// \name Authoring Material Variations /// Each UsdShadeMaterial prim can host data for any number of render targets /// (such as Renderman RIS, Arnold, or glslfx). /// /// A single UsdShadeMaterial group can, however, encode variations on /// appearance, varying any data authored on the material and its contents. /// For example, we might have a logo'd baseball cap that /// comes in denim, nylon, and corduroy variations. /// /// We provide methods to aid in authoring such variations on individual /// Material prims, and also a facility for creating a "master" look /// variant on another prim (e.g. a model's root prim, or another common /// ancestor of all Material prims in a model) that will be able to modify /// Materials, bindings, connections and values at once. /// /// Note on variant vs "direct" opinions. /// For any given prim's spec in a layer, opinions expressed inside a /// variant of a variantSet will be /weaker/ than any opinions expressed /// "directly" at the location, outside of any layer. /// /// Therefore, if you intend to author a default variant that is weaker than /// more explicit variants, you will need to have those opinions be weaker /// by setting them across a reference arc such as the following: /// /// \code /// def "MyMaterial" ( /// add references = /// variants = { /// string materialVariant = "SomeVariant" /// } /// add variantSets = "materialVariant" /// ) /// { /// float strongerThanVariantOpinion /// /// variantSet "materialVariant" = { /// "SomeVariant" { /// float variantOpinion /// } /// } /// } /// /// over "MyMaterial_defaultShadingVariant" /// { /// float weakerThanVariantOpinion /// } /// \endcode /// /// @{ /// // --------------------------------------------------------------------- // /// Helper function for configuring a UsdStage's UsdEditTarget to author /// Material variations. Takes care of creating the Material variantSet and /// specified variant, if necessary. /// /// Let's assume that we are authoring Materials into the Stage's current /// UsdEditTarget, and that we are iterating over the variations of a /// UsdShadeMaterial \em clothMaterial, and \em currVariant is the variant we are /// processing (e.g. "denim"). /// /// In C++, then, we would use the following pattern: /// \code /// { /// UsdEditContext ctxt(clothMaterial.GetEditContextForVariant(currVariant)); /// /// // All USD mutation of the UsdStage on which clothMaterial sits will /// // now go "inside" the currVariant of the "MaterialVariant" variantSet /// } /// \endcode /// /// In python, the pattern is: /// \code{.py} /// with clothMaterial.GetEditContextForVariant(currVariant): /// # Now sending mutations to currVariant /// \endcode /// /// If \p layer is specified, then we will use it, rather than the stage's /// current UsdEditTarget's layer as the destination layer for the /// edit context we are building. If \p layer does not actually contribute /// to the Material prim's definition, any editing will have no effect on this /// Material. /// /// Note: As just stated, using this method involves authoring /// a selection for the MaterialVariant in the stage's current EditTarget. /// When client is done authoring variations on this prim, they will likely /// want to either UsdVariantSet::SetVariantSelection() to the appropriate /// default selection, or possibly UsdVariantSet::ClearVariantSelection() /// on the UsdShadeMaterial::GetMaterialVariant() UsdVariantSet. /// \sa UsdVariantSet::GetVariantEditContext() USDSHADE_API std::pair GetEditContextForVariant(const TfToken &MaterialVariantName, const SdfLayerHandle &layer = SdfLayerHandle()) const; /// Return a UsdVariantSet object for interacting with the Material variant /// variantSet USDSHADE_API UsdVariantSet GetMaterialVariant() const; /// Create a variantSet on \p masterPrim that will set the MaterialVariant on /// each of the given \em MaterialPrims. /// /// The variantSet, whose name can be specified with \p /// masterVariantSetName and defaults to the same MaterialVariant name /// created on Materials by GetEditContextForVariant(), will have the same /// variants as the Materials, and each Master variant will set every /// \p MaterialPrims' MaterialVariant selection to the same variant as the /// master. Thus, it allows all Materials to be switched with a single /// variant selection, on \p masterPrim. /// /// If \p masterPrim is an ancestor of any given member of \p MaterialPrims, /// then we will author variant selections directly on the MaterialPrims. /// However, it is often preferable to create a master MaterialVariant in /// a separately rooted tree from the MaterialPrims, so that it can be /// layered more strongly on top of the Materials. Therefore, for any MaterialPrim /// in a different tree than masterPrim, we will create "overs" as children /// of masterPrim that recreate the path to the MaterialPrim, substituting /// masterPrim's full path for the MaterialPrim's root path component. /// /// Upon successful completion, the new variantSet we created on /// \p masterPrim will have its variant selection authored to the /// "last" variant (determined lexicographically). It is up to the /// calling client to either UsdVariantSet::ClearVariantSelection() /// on \p masterPrim, or set the selection to the desired default setting. /// /// Return \c true on success. It is an error if any of \p Materials /// have a different set of variants for the MaterialVariant than the others. USDSHADE_API static bool CreateMasterMaterialVariant( const UsdPrim &masterPrim, const std::vector &MaterialPrims, const TfToken &masterVariantSetName = TfToken()); /// @} // --------------------------------------------------------------------- // /// \anchor UsdShadeMaterial_BaseMaterial /// \name BaseMaterial /// A specialize arc describes child/parent inheritance. /// A Material that derives from a BaseMaterial will retain a live /// composition relationship to its BaseMaterial /// /// @{ // --------------------------------------------------------------------- // /// Get the path to the base Material of this Material. /// If there is no base Material, an empty Material is returned USDSHADE_API UsdShadeMaterial GetBaseMaterial() const; /// Get the base Material of this Material. /// If there is no base Material, an empty path is returned USDSHADE_API SdfPath GetBaseMaterialPath() const; /// Given a PcpPrimIndex, searches it for an arc to a parent material. /// /// This is a public static function to support applications that use /// Pcp but not Usd. Most clients should call \ref GetBaseMaterialPath, /// which uses this function when appropriate. USDSHADE_API static SdfPath FindBaseMaterialPathInPrimIndex( const PcpPrimIndex & primIndex, const PathPredicate & pathIsMaterialPredicate); /// Set the base Material of this Material. /// An empty Material is equivalent to clearing the base Material. USDSHADE_API void SetBaseMaterial(const UsdShadeMaterial& baseMaterial) const; /// Set the path to the base Material of this Material. /// An empty path is equivalent to clearing the base Material. USDSHADE_API void SetBaseMaterialPath(const SdfPath& baseMaterialPath) const; /// Clear the base Material of this Material. USDSHADE_API void ClearBaseMaterial() const; // Check if this Material has a base Material USDSHADE_API bool HasBaseMaterial() const; /// @} }; PXR_NAMESPACE_CLOSE_SCOPE #endif