1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_IMAGING_HD_ST_MATERIAL_H
25 #define PXR_IMAGING_HD_ST_MATERIAL_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hdSt/api.h"
29 #include "pxr/imaging/hdSt/materialNetwork.h"
30 #include "pxr/imaging/hdSt/shaderCode.h"
31 #include "pxr/imaging/hd/material.h"
32 #include "pxr/imaging/hf/perfLog.h"
33 
34 #include <memory>
35 
36 PXR_NAMESPACE_OPEN_SCOPE
37 
38 using HdSt_MaterialNetworkShaderSharedPtr =
39         std::shared_ptr<class HdSt_MaterialNetworkShader>;
40 
41 class HioGlslfx;
42 
43 class HdStMaterial final: public HdMaterial
44 {
45 public:
46     HF_MALLOC_TAG_NEW("new HdStMaterial");
47 
48     /// For volumes, the corresponding draw items do not use the
49     /// HdStShaderCode produced by HdStMaterial. Instead HdStVolume is
50     /// using some data from the material to produce its own HdStShaderCode
51     /// based on the volume field bindings.
52     struct VolumeMaterialData final
53     {
54         /// glslfx source code for volume
55         std::string source;
56         HdSt_MaterialParamVector params;
57     };
58 
59     HDST_API
60     HdStMaterial(SdfPath const& id);
61     HDST_API
62     ~HdStMaterial() override;
63 
64     /// Synchronizes state from the delegate to this object.
65     HDST_API
66     void Sync(HdSceneDelegate *sceneDelegate,
67               HdRenderParam   *renderParam,
68               HdDirtyBits     *dirtyBits) override;
69 
70     HDST_API
71     void Finalize(HdRenderParam *renderParam) override;
72 
73     /// Returns the minimal set of dirty bits to place in the
74     /// change tracker for use in the first sync of this prim.
75     /// Typically this would be all dirty bits.
76     HDST_API
77     HdDirtyBits GetInitialDirtyBitsMask() const override;
78 
79     /// Obtains the GLSLFX code together with supporting information
80     /// such as material params and textures to render surfaces.
81     HDST_API
82     HdSt_MaterialNetworkShaderSharedPtr GetMaterialNetworkShader() const;
83 
84     /// Obtains the GLSLFLX code together with material params to
85     /// render volumes.
86     inline const VolumeMaterialData &GetVolumeMaterialData() const;
87 
88     /// Summary flag. Returns true if the material is bound to one or more
89     /// textures and any of those textures is a ptex texture.
90     /// If no textures are bound or all textures are uv textures, then
91     /// the method returns false.
92     inline bool HasPtex() const;
93 
94     /// Returns true if the material specifies limit surface evaluation.
95     inline bool HasLimitSurfaceEvaluation() const;
96 
97     // Returns true if the material has a displacement terminal.
98     inline bool HasDisplacement() const;
99 
100     // Returns the material's render pass tag.
101     inline const TfToken& GetMaterialTag() const;
102 
103     /// Replaces the shader code object with an externally created one
104     /// Used to set the fallback shader for prim.
105     /// This class takes ownership of the passed in object.
106     HDST_API
107     void SetMaterialNetworkShader(
108         HdSt_MaterialNetworkShaderSharedPtr &shaderCode);
109 
110 private:
111     // Processes the texture descriptors from a material network to
112     // create textures using the Storm texture system.
113     //
114     // Adds buffer specs/sources necessary for textures, e.g., bindless
115     // handles or sampling transform for field textures.
116     void _ProcessTextureDescriptors(
117         HdSceneDelegate * sceneDelegate,
118         HdStResourceRegistrySharedPtr const& resourceRegistry,
119         std::weak_ptr<HdStShaderCode> const &shaderCode,
120         HdStMaterialNetwork::TextureDescriptorVector const &descs,
121         HdStShaderCode::NamedTextureHandleVector * texturesFromStorm,
122         HdBufferSpecVector * specs,
123         HdBufferSourceSharedPtrVector * sources);
124 
125     bool
126     _GetHasLimitSurfaceEvaluation(VtDictionary const & metadata) const;
127 
128     void _InitFallbackShader();
129 
130     static HioGlslfx *_fallbackGlslfx;
131 
132     HdSt_MaterialNetworkShaderSharedPtr _materialNetworkShader;
133     VolumeMaterialData _volumeMaterialData;
134 
135     bool _isInitialized : 1;
136     bool _hasPtex : 1;
137     bool _hasLimitSurfaceEvaluation : 1;
138     bool _hasDisplacement : 1;
139 
140     TfToken _materialTag;
141     size_t _textureHash;
142 
143     HdStMaterialNetwork _networkProcessor;
144 };
145 
HasPtex()146 inline bool HdStMaterial::HasPtex() const
147 {
148     return _hasPtex;
149 }
150 
HasLimitSurfaceEvaluation()151 inline bool HdStMaterial::HasLimitSurfaceEvaluation() const
152 {
153     return _hasLimitSurfaceEvaluation;
154 }
155 
HasDisplacement()156 inline bool HdStMaterial::HasDisplacement() const
157 {
158     return _hasDisplacement;
159 }
160 
GetMaterialTag()161 inline const TfToken& HdStMaterial::GetMaterialTag() const
162 {
163     return _materialTag;
164 }
165 
166 inline const HdStMaterial::VolumeMaterialData &
GetVolumeMaterialData()167 HdStMaterial::GetVolumeMaterialData() const {
168     return _volumeMaterialData;
169 }
170 
171 
172 PXR_NAMESPACE_CLOSE_SCOPE
173 
174 #endif // PXR_IMAGING_HD_ST_MATERIAL_H
175