HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GR_Material.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GR_Material.h (GR Library, C++)
7  *
8  * COMMENTS:
9  */
10 #ifndef GR_Material_h
11 #define GR_Material_h
12 
13 #include "GR_API.h"
14 #include "GR_Defines.h"
15 #include "GR_DrawParms.h"
16 #include "GR_SceneItem.h"
17 
18 #include <UT/UT_IntrusivePtr.h>
19 #include <UT/UT_Map.h>
20 #include <UT/UT_NonCopyable.h>
21 #include <UT/UT_OptionEntry.h>
22 #include <UT/UT_RWLock.h>
23 #include <UT/UT_Set.h>
24 #include <UT/UT_StringMap.h>
25 #include <UT/UT_StringHolder.h>
26 #include <UT/UT_UniquePtr.h>
27 #include <UT/UT_VectorTypes.h>
28 #include <UT/UT_Vector2.h>
29 #include <UT/UT_Vector3.h>
30 #include <UT/UT_Matrix4.h>
31 #include <UT/UT_Debug.h>
32 #include <DEP/DEP_MicroNode.h>
33 
34 #include <RV/RV_ShaderProgram.h>
35 #include <RV/RV_TextureCache.h>
36 
37 class UT_Options;
39 class RV_Render;
40 class RV_ShaderProgram;
41 class RV_ShaderCompute;
42 class GR_MaterialParms;
43 class GR_DisplayOption;
44 
46 {
47 public:
49  {
56  MATCAP_SURFACE
57  };
59  {
60  PHONG = 0,
62  GGX,
63  SPEC_ANGLE
64  };
66  {
67  DISPLACE_NORMAL = 0,
70  DISPLACE_VECTOR_OBJECT
71  };
73  {
74  NMLMAP_TANGENT = 0,
76  NMLMAP_OBJECT
77  };
78  // Alpha blend/cutout modes (defined in glsl/block/VK/glH_Material.blk)
79  enum AlphaMode
80  {
81  ALPHA_BLEND = 0, // normal alpha blending C*A + Cbg*(1-A)
82  ALPHA_CUTOUT, // (A >= cutoff) ? C : 0
84  };
85 
86  static GR_MaterialPtr create(MaterialType type,
87  const UT_StringHolder &name);
88  MaterialType type() const { return myType; }
89 
90  // Some materials may be defined by nodes; this is the ID of that node.
91  int getNodeID() const { return myNodeID; }
92  void setNodeID(int id) { myNodeID = id; }
93  UT_StringHolder getNodePath() const;
94 
95  void setTimeDependent(bool timedep, fpreal t = 0.0);
96  void setOPTimeDependent(bool timedep, fpreal t = 0.0);
97  bool isTimeDependent() const { return myTimeDep; }
98  bool isOPTimeDependent() const { return myOPTimeDep; }
99  fpreal getCurrentTime() const { return myTime; }
100 
101 
103  {
104  if(isTextured())
105  {
106  exint cache_version = 0;
107  cache_version = RV_TextureCache::cacheRefresh();
108  if(myTexCacheVersion != cache_version)
109  return true;
110  }
111  if(myDirtyFlag || myDepNode.isDirty())
112  return true;
113  if(myTimeDep && !SYSisEqual(time, myTime))
114  return true;
115  return false;
116  }
117  void dirty(bool dirty = true)
118  {
119  myDirtyFlag = dirty;
120  if(!dirty)
121  {
122  myDepNode.update(myTime);
123  myTexCacheVersion = RV_TextureCache::cacheRefresh();
124  }
125  }
126 
127  virtual void dirtyTextures() {}
128 
129  // Returns true if this material has a texture map (diffuse, bump, etc).
130  bool isTextured() const { return myIsTextured; }
131  void setTextured(bool has_tex) { myIsTextured = has_tex; }
132 
133  bool hasUDIM() const { return myHasUDIM; }
134  void setHasUDIM(bool has_udim) { myHasUDIM = has_udim; }
135 
136  bool hasDisplacement() const { return myHasDisplacement; }
137  void setHasDisplacement(bool has_disp) {myHasDisplacement=has_disp;}
138 
139  // Requires UVs outside of texturing
140  bool needsUVs() const { return myNeedsUVs; }
141  void setNeedsUVs(bool uvs) { myNeedsUVs = uvs; }
142 
143  // Requires tangents for tangent-space generation
144  bool needsTangents() const { return myNeedsTangents; }
145  void setNeedsTangents(bool tan) { myNeedsTangents = tan; }
146 
147  bool isTransparent() const { return myIsTransparent; }
148  void setTransparent(bool has_tex) { myIsTransparent = has_tex; }
149 
150  bool texturesLoaded() const { return myTexturesLoaded; }
151  void setTexturesLoaded(bool loaded) { myTexturesLoaded = loaded; }
152 
154  const GR_DisplayOption *opts, bool for_curve = false)
155  {
156  return bindSets(r, shader, for_curve);
157  }
158 
160  const GR_DisplayOption *opts, bool for_curve = false)
161  {
162  bool created = false;
163  return (initMaterialSetForRender(r, shader, created) &&
164  initBlocks(r, opts) &&
165  bindSets(r, shader, for_curve));
166  }
167  virtual bool bindForCompute(RV_Render *r,
169  const GR_DisplayOption &opts);
170 
171  virtual void update(const GR_MaterialParms &options) = 0;
172 
173  virtual bool initMaterialSetForRender(RV_Render *r,
175  bool &created)=0;
176  virtual bool initBlocks(RV_Render *r, const GR_DisplayOption *opts) = 0;
177  bool checkCompatible(RV_Render* r, RV_ShaderProgramBase* sh, bool for_curve = false) const;
178  bool bindSets(RV_Render *r, RV_ShaderProgramBase *shader, bool for_curve);
179 
180  DEP_MicroNode &dependencies() { return myDepNode; }
181 
182  virtual RV_ShaderProgram *getSurfaceShader() const { return nullptr; }
183  virtual RV_ShaderProgram *getCurveShader() const { return nullptr; }
184  virtual RV_ShaderCompute *getDisplaceShader() const { return nullptr; }
185 
186  bool opDependenciesDirty() const { return myOpDepsDirty; }
187  void clearOpDependenciesDirty() { myOpDepsDirty = false; }
188  const UT_Set<int> opDependencies() const { return myOpNodes; }
189 
190  // Attribute overrides (mapping an attribute to a shader input)
191  void setOverrides(const UT_Options *overrides);
192  const UT_Options *getOverrides() const { return myOverrides.get(); }
193  // Attribute fallback (value to use if attribute does not exist)
194  void setFallbacks(const UT_Options *attrib_fallbacks);
195  const UT_Options *getFallbacks() const { return myFallbacks.get(); }
196 
198  {
203  IN_VEC4
204  };
205  void setExtraInputs(const UT_StringMap<InputType> &extra_inputs)
206  { myExtraInputs = extra_inputs; }
207  const UT_StringMap<InputType> &extraInputs() const { return myExtraInputs; }
208 
209  static exint getUniqueMaterialID();
210 
211 protected:
213  MaterialType type);
214  ~GR_Material() override;
216 
217  void clearOpIDs() { myOpNodes.clear(); myOpDepsDirty = true; }
218  void addOpID(int id);
219 
220  bool timeChangeCheck() const;
221 
225 
226  void initTextureParms(RV_TextureParms &parms,
227  const GR_DisplayOption *opts,
228  RV_ImageDim tex_type,
230 
233 
234 private:
235 
236  UT_Set<int> myOpNodes;
237  DEP_MicroNode myDepNode;
238  MaterialType myType;
239  int myNodeID = -999;
240  exint myTexCacheVersion = 0;
241  unsigned myTimeDep : 1,
242  myOPTimeDep : 1,
243  myIsTextured : 1,
244  myNeedsUVs : 1,
245  myHasUDIM : 1,
246  myHasDisplacement : 1,
247  myIsTransparent : 1,
248  myNeedsTangents : 1,
249  myTexturesLoaded : 1,
250  myOpDepsDirty : 1;
251  fpreal myTime = 0.0;
252  UT_UniquePtr<UT_Options> myOverrides;
253  UT_UniquePtr<UT_Options> myFallbacks;
254  UT_StringMap<InputType> myExtraInputs;
255 };
256 
257 static inline void intrusive_ptr_add_ref(GR_Material *m) { m->incref(); }
258 static inline void intrusive_ptr_release(GR_Material *m) { m->decref(); }
259 
260 
261 class GR_API GR_MaterialAtlas : public UT_Map<int,GR_MaterialPtr>
262 {
263 public:
264  // Default material for unassigned prims.
266  { return myDefault; }
267 
268  // Factory default material if materials are disabled.
270  { return myFactory; }
271 
272  // True if any of the materials in the atlas are dirty.
273  bool isDirty(fpreal time) const;
274 
275  // Fetch a material by its ID.
276  GR_MaterialPtr get(int material_id) const
277  {
278  if(myAltAtlas && material_id < 0)
279  return myAltAtlas->get(-material_id);
280  if(material_id == 0)
281  return myDefault ? myDefault : myFactory;
282  const_iterator entry = find(material_id);
283  if(entry != end())
284  return entry->second;
285  return nullptr;
286  }
287  // Fetch a material by ID, and if it doesn't exist, check the draw parms
288  // default material, then fallback to the default or factory if there is
289  // no draw parms default.
290  GR_MaterialPtr get(int material_id, const GR_DrawParms &dp) const
291  {
292  if(myAltAtlas && material_id < 0)
293  return myAltAtlas->get(-material_id);
294 
295  if(material_id == 0 && dp.vk_default_mat_id != 0)
296  material_id = dp.vk_default_mat_id;
297 
298  if(material_id == 0)
299  return myDefault ? myDefault : myFactory;
300 
301  const_iterator entry = find(material_id);
302  if(entry != end())
303  return entry->second;
304  return nullptr;
305  }
306 
307  // Add a new material to the atlas
308  void add(const GR_MaterialPtr &material)
309  { (*this)[ material->id() ] = material; }
310 
311  // Set the default material, which will be used if no other material
312  // assignments are present.
313  void setDefaultMaterial(const GR_MaterialPtr &material,bool add_list=true)
314  { myDefault = material; if(add_list && material) add(material); }
315 
316  // Sets the factory default material, which is used when all materials
317  // are turned off (as the default material may be the object material).
318  void setFactoryMaterial(const GR_MaterialPtr &material,bool add_list=true)
319  { myFactory = material; if(add_list && material) add(material); }
320 
321  // Provide another material atlas to use for material lookups. This is used
322  // for LOP materials when rendering SOPs.
324  { myAltAtlas = atlas; }
325  GR_MaterialAtlas *alternateMaterials() { return myAltAtlas; }
326  const GR_MaterialAtlas *alternateMaterials() const { return myAltAtlas; }
327 
328  bool hasMaterial(int material_id) const
329  {
330  const_iterator entry = find(material_id);
331  return (entry != end());
332  }
333 
334  void clearAtlas() { myDefault.reset(); myFactory.reset(); clear(); }
335 
336 private:
337  GR_MaterialPtr myDefault;
338  GR_MaterialPtr myFactory;
339 
340  GR_MaterialAtlas *myAltAtlas = nullptr;
341 };
342 
343 /// This is a fast, non-string access and cut-down version of UT_Options.
345 {
346 public:
348 
349  void setParmI(exint ptype, int value);
350  void setParm(exint ptype, fpreal value);
351  void setParm(exint ptype, const UT_Vector2 &value);
352  void setParm(exint ptype, const UT_Vector3 &value);
353  void setParm(exint ptype, const UT_Vector4 &value);
354  void setParm(exint ptype, const UT_Matrix4 &value);
355  void setParm(exint ptype, const UT_StringHolder &value);
356 
357  bool hasParm(exint ptype) const;
358 
359  int getParmI(exint ptype, int defval = 0) const;
360  fpreal getParmF(exint ptype, fpreal defval = 0.0) const;
361  UT_Vector2 getParmV2(exint ptype, UT_Vector2 defval = {0,0}) const;
362  UT_Vector3 getParmV3(exint ptype, UT_Vector3 defval = {0,0,0}) const;
363  UT_Vector4 getParmV4(exint ptype, UT_Vector4 defval = {0,0,0,0}) const;
364  UT_Matrix4 getParmM4(exint ptype,
366  UT_StringHolder getParmS(exint ptype, UT_StringHolder = UT_StringHolder()) const;
367 
368  void dump();
369 
370 private:
372 };
373 
374 // Cache for auto-generated shaders (MatX)
376 {
377 public:
379  ~GR_ShaderCache();
381 
382  static void initCache();
383  static void destroyCache();
384  static void clearCache();
385 
386  // return the ID assoicated with this name (0 if it doesn't exist).
387  static exint getShaderID(const UT_StringHolder &name);
388  static exint getComputeID(const UT_StringHolder &name);
389 
390  // Return the shader program assoicated with this id (nullptr if not cached)
391  static RV_ShaderProgram *getShader(exint id);
392  static RV_ShaderCompute *getComputeShader(exint id);
393 
394  // Create a cache entry to store a shader with cacheShader().
395  static exint createEntryID(const UT_StringHolder &name);
396  static exint createComputeEntryID(const UT_StringHolder &name);
397 
398  // Cache the shader by ID, handling over ownership to the cache.
399  static void cacheShader(exint entry, const GR_Material &for_material,
401  static void cacheComputeShader(exint entry, const GR_Material &for_material,
403 
404  // Add a reference to a cached shader. It must exist in the cache.
405  static void addShaderRef(exint id, const GR_Material &material);
406  static void addComputeRef(exint id, const GR_Material &material);
407 
408  // Remove the shader from the cache with the given name
409  static bool removeShader(const UT_StringHolder &name,
410  const GR_Material &for_material);
411  static bool removeComputeShader(const UT_StringHolder &name,
412  const GR_Material &for_material);
413 
414 private:
415  UT_StringMap<exint> myNameMap;
416  UT_StringMap<exint> myComputeNameMap;
417  UT_Map<exint,
418  std::pair<UT_Set<int>,UT_UniquePtr<RV_ShaderProgram>> > myShaders;
419  UT_Map<exint,
420  std::pair<UT_Set<int>,UT_UniquePtr<RV_ShaderCompute>> > myComputeShaders;
421  UT_RWLock myShaderLock;
422  exint myCurrentID = 1;
423 };
424 
425 #endif
UT_UniquePtr< RV_ShaderVariableSet > myMaterialSet
Definition: GR_Material.h:222
bool SYSisEqual(const UT_Vector2T< T > &a, const UT_Vector2T< T > &b, S tol)
Componentwise equality.
Definition: UT_Vector2.h:677
void setFactoryMaterial(const GR_MaterialPtr &material, bool add_list=true)
Definition: GR_Material.h:318
void dirty(bool dirty=true)
Definition: GR_Material.h:117
virtual RV_ShaderProgram * getSurfaceShader() const
Definition: GR_Material.h:182
virtual void dirtyTextures()
Definition: GR_Material.h:127
Unsorted map container.
Definition: UT_Map.h:114
const GR_MaterialPtr & getFactoryMaterial() const
Definition: GR_Material.h:269
Base class for various things that can appear in a scene outside of geometry.
Definition: GR_SceneItem.h:19
bool isTimeDependent() const
Definition: GR_Material.h:97
bool opDependenciesDirty() const
Definition: GR_Material.h:186
GT_API const UT_StringHolder time
bool myBlockDirtyFlag
Definition: GR_Material.h:232
int getNodeID() const
Definition: GR_Material.h:91
const UT_Options * getOverrides() const
Definition: GR_Material.h:192
GLsizei const GLfloat * value
Definition: glcorearb.h:824
void decref()
Definition: GR_SceneItem.h:33
int64 exint
Definition: SYS_Types.h:125
bool isOPTimeDependent() const
Definition: GR_Material.h:98
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2138
void clear()
Definition: UT_Map.h:191
UT_NON_COPYABLE(GR_SceneItem)
UT_UniquePtr< RV_ShaderVariableSet > myTexMaterialSet
Definition: GR_Material.h:223
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
bool texturesLoaded() const
Definition: GR_Material.h:150
const GR_MaterialAtlas * alternateMaterials() const
Definition: GR_Material.h:326
fpreal getCurrentTime() const
Definition: GR_Material.h:99
void setTransparent(bool has_tex)
Definition: GR_Material.h:148
bool isTransparent() const
Definition: GR_Material.h:147
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
Compute shader object.
bool bindWithoutUpdate(RV_Render *r, RV_ShaderProgramBase *shader, const GR_DisplayOption *opts, bool for_curve=false)
Definition: GR_Material.h:153
bool hasUDIM() const
Definition: GR_Material.h:133
bool needsTangents() const
Definition: GR_Material.h:144
const UT_StringMap< InputType > & extraInputs() const
Definition: GR_Material.h:207
const UT_Options * getFallbacks() const
Definition: GR_Material.h:195
static const UT_Matrix4T< float > & getIdentityMatrix()
MaterialType type() const
Definition: GR_Material.h:88
GLuint GLuint end
Definition: glcorearb.h:475
void setHasDisplacement(bool has_disp)
Definition: GR_Material.h:137
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
const UT_Set< int > opDependencies() const
Definition: GR_Material.h:188
void add(const GR_MaterialPtr &material)
Definition: GR_Material.h:308
virtual RV_ShaderCompute * getDisplaceShader() const
Definition: GR_Material.h:184
#define GR_API
Definition: GR_API.h:10
void setNeedsTangents(bool tan)
Definition: GR_Material.h:145
static exint cacheRefresh()
bool needsUVs() const
Definition: GR_Material.h:140
bool myDirtyFlag
Definition: GR_Material.h:231
bool isDirty(fpreal time)
Definition: GR_Material.h:102
GLuint const GLchar * name
Definition: glcorearb.h:786
void setNodeID(int id)
Definition: GR_Material.h:92
bool bind(RV_Render *r, RV_ShaderProgramBase *shader, const GR_DisplayOption *opts, bool for_curve=false)
Definition: GR_Material.h:159
void clearOpDependenciesDirty()
Definition: GR_Material.h:187
RV_TextureFilter
Definition: RV_Type.h:136
GLdouble t
Definition: glad.h:2397
UT_UniquePtr< RV_ShaderVariableSet > myTexCurveMaterialSet
Definition: GR_Material.h:224
GLuint shader
Definition: glcorearb.h:785
A map of string to various well defined value types.
Definition: UT_Options.h:87
GA_API const UT_StringHolder parms
DEP_MicroNode & dependencies()
Definition: GR_Material.h:180
void setTextured(bool has_tex)
Definition: GR_Material.h:131
void setNeedsUVs(bool uvs)
Definition: GR_Material.h:141
void setHasUDIM(bool has_udim)
Definition: GR_Material.h:134
fpreal64 fpreal
Definition: SYS_Types.h:283
void setTexturesLoaded(bool loaded)
Definition: GR_Material.h:151
virtual RV_ShaderProgram * getCurveShader() const
Definition: GR_Material.h:183
void setDefaultMaterial(const GR_MaterialPtr &material, bool add_list=true)
Definition: GR_Material.h:313
void clearOpIDs()
Definition: GR_Material.h:217
bool hasMaterial(int material_id) const
Definition: GR_Material.h:328
bool hasDisplacement() const
Definition: GR_Material.h:136
GR_MaterialAtlas * alternateMaterials()
Definition: GR_Material.h:325
bool isTextured() const
Definition: GR_Material.h:130
ImageBuf OIIO_API add(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLboolean r
Definition: glcorearb.h:1222
This is a fast, non-string access and cut-down version of UT_Options.
Definition: GR_Material.h:344
void setAlternateMaterials(GR_MaterialAtlas *atlas)
Definition: GR_Material.h:323
const GR_MaterialPtr & getDefaultMaterial() const
Definition: GR_Material.h:265
Reader/Writer mutex class.
Definition: UT_RWLock.h:48
RV_ImageDim
Definition: RV_Type.h:120
Base::const_iterator const_iterator
Definition: UT_Map.h:125
void incref()
Definition: GR_SceneItem.h:31
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
exint id() const
Definition: GR_SceneItem.h:24
void setExtraInputs(const UT_StringMap< InputType > &extra_inputs)
Definition: GR_Material.h:205