Material.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #pragma once
  4. #include "../Graphics/Light.h"
  5. #include "../GraphicsAPI/GraphicsDefs.h"
  6. #include "../Math/Vector4.h"
  7. #include "../Resource/Resource.h"
  8. #include "../Scene/ValueAnimationInfo.h"
  9. namespace Urho3D
  10. {
  11. class Material;
  12. class Pass;
  13. class Scene;
  14. class Technique;
  15. class Texture;
  16. class Texture2D;
  17. class TextureCube;
  18. class ValueAnimationInfo;
  19. class JSONFile;
  20. static constexpr i8 DEFAULT_RENDER_ORDER = 0;
  21. /// %Material's shader parameter definition.
  22. struct MaterialShaderParameter
  23. {
  24. /// Name.
  25. String name_;
  26. /// Value.
  27. Variant value_;
  28. };
  29. /// %Material's technique list entry.
  30. struct TechniqueEntry
  31. {
  32. /// Construct with defaults.
  33. TechniqueEntry() noexcept;
  34. /// Construct with parameters.
  35. TechniqueEntry(Technique* tech, MaterialQuality qualityLevel, float lodDistance) noexcept;
  36. /// Destruct.
  37. ~TechniqueEntry() noexcept = default;
  38. /// Technique.
  39. SharedPtr<Technique> technique_;
  40. /// Original technique, in case the material adds shader compilation defines. The modified clones are requested from it.
  41. SharedPtr<Technique> original_;
  42. /// Quality level.
  43. MaterialQuality qualityLevel_;
  44. /// LOD distance.
  45. float lodDistance_;
  46. };
  47. /// Material's shader parameter animation instance.
  48. class ShaderParameterAnimationInfo : public ValueAnimationInfo
  49. {
  50. public:
  51. /// Construct.
  52. ShaderParameterAnimationInfo
  53. (Material* material, const String& name, ValueAnimation* attributeAnimation, WrapMode wrapMode, float speed);
  54. /// Copy construct.
  55. ShaderParameterAnimationInfo(const ShaderParameterAnimationInfo& other);
  56. /// Destruct.
  57. ~ShaderParameterAnimationInfo() override;
  58. /// Return shader parameter name.
  59. const String& GetName() const { return name_; }
  60. protected:
  61. /// Apply new animation value to the target object. Called by Update().
  62. void ApplyValue(const Variant& newValue) override;
  63. private:
  64. /// Shader parameter name.
  65. String name_;
  66. };
  67. /// TextureUnit hash function.
  68. template <> inline hash32 MakeHash(const TextureUnit& value)
  69. {
  70. return (hash32)value;
  71. }
  72. /// Describes how to render 3D geometries.
  73. class URHO3D_API Material : public Resource
  74. {
  75. URHO3D_OBJECT(Material, Resource);
  76. public:
  77. /// Construct.
  78. explicit Material(Context* context);
  79. /// Destruct.
  80. ~Material() override;
  81. /// Register object factory.
  82. /// @nobind
  83. static void RegisterObject(Context* context);
  84. /// Load resource from stream. May be called from a worker thread. Return true if successful.
  85. bool BeginLoad(Deserializer& source) override;
  86. /// Finish resource loading. Always called from the main thread. Return true if successful.
  87. bool EndLoad() override;
  88. /// Save resource. Return true if successful.
  89. bool Save(Serializer& dest) const override;
  90. using Resource::Load;
  91. /// Load from an XML element. Return true if successful.
  92. bool Load(const XMLElement& source);
  93. /// Save to an XML element. Return true if successful.
  94. bool Save(XMLElement& dest) const;
  95. /// Load from a JSON value. Return true if successful.
  96. bool Load(const JSONValue& source);
  97. /// Save to a JSON value. Return true if successful.
  98. bool Save(JSONValue& dest) const;
  99. /// Set number of techniques.
  100. /// @property
  101. void SetNumTechniques(i32 num);
  102. /// Set technique.
  103. void SetTechnique(i32 index, Technique* tech, MaterialQuality qualityLevel = QUALITY_LOW, float lodDistance = 0.0f);
  104. /// Set additional vertex shader defines. Separate multiple defines with spaces. Setting defines at the material level causes technique(s) to be cloned as necessary.
  105. /// @property
  106. void SetVertexShaderDefines(const String& defines);
  107. /// Set additional pixel shader defines. Separate multiple defines with spaces. Setting defines at the material level causes technique(s) to be cloned as necessary.
  108. /// @property
  109. void SetPixelShaderDefines(const String& defines);
  110. /// Set shader parameter.
  111. /// @property{set_shaderParameters}
  112. void SetShaderParameter(const String& name, const Variant& value);
  113. /// Set shader parameter animation.
  114. void
  115. SetShaderParameterAnimation(const String& name, ValueAnimation* animation, WrapMode wrapMode = WM_LOOP, float speed = 1.0f);
  116. /// Set shader parameter animation wrap mode.
  117. void SetShaderParameterAnimationWrapMode(const String& name, WrapMode wrapMode);
  118. /// Set shader parameter animation speed.
  119. void SetShaderParameterAnimationSpeed(const String& name, float speed);
  120. /// Set texture.
  121. /// @property{set_textures}
  122. void SetTexture(TextureUnit unit, Texture* texture);
  123. /// Set texture coordinate transform.
  124. void SetUVTransform(const Vector2& offset, float rotation, const Vector2& repeat);
  125. /// Set texture coordinate transform.
  126. void SetUVTransform(const Vector2& offset, float rotation, float repeat);
  127. /// Set culling mode.
  128. /// @property
  129. void SetCullMode(CullMode mode);
  130. /// Set culling mode for shadows.
  131. /// @property
  132. void SetShadowCullMode(CullMode mode);
  133. /// Set polygon fill mode. Interacts with the camera's fill mode setting so that the "least filled" mode will be used.
  134. /// @property
  135. void SetFillMode(FillMode mode);
  136. /// Set depth bias parameters for depth write and compare. Note that the normal offset parameter is not used and will not be saved, as it affects only shadow map sampling during light rendering.
  137. /// @property
  138. void SetDepthBias(const BiasParameters& parameters);
  139. /// Set alpha-to-coverage mode on all passes.
  140. /// @property
  141. void SetAlphaToCoverage(bool enable);
  142. /// Set line antialiasing on/off. Has effect only on models that consist of line lists.
  143. /// @property
  144. void SetLineAntiAlias(bool enable);
  145. /// Set 8-bit render order within pass. Default 0. Lower values will render earlier and higher values later, taking precedence over e.g. state and distance sorting.
  146. /// @property
  147. void SetRenderOrder(i8 order);
  148. /// Set whether to use in occlusion rendering. Default true.
  149. /// @property
  150. void SetOcclusion(bool enable);
  151. /// Associate the material with a scene to ensure that shader parameter animation happens in sync with scene update, respecting the scene time scale. If no scene is set, the global update events will be used.
  152. /// @property
  153. void SetScene(Scene* scene);
  154. /// Remove shader parameter.
  155. void RemoveShaderParameter(const String& name);
  156. /// Reset all shader pointers.
  157. void ReleaseShaders();
  158. /// Clone the material.
  159. SharedPtr<Material> Clone(const String& cloneName = String::EMPTY) const;
  160. /// Ensure that material techniques are listed in correct order.
  161. void SortTechniques();
  162. /// Mark material for auxiliary view rendering.
  163. void MarkForAuxView(i32 frameNumber);
  164. /// Return number of techniques.
  165. /// @property
  166. i32 GetNumTechniques() const { return techniques_.Size(); }
  167. /// Return all techniques.
  168. const Vector<TechniqueEntry>& GetTechniques() const { return techniques_; }
  169. /// Return technique entry by index.
  170. const TechniqueEntry& GetTechniqueEntry(i32 index) const;
  171. /// Return technique by index.
  172. /// @property{get_techniques}
  173. Technique* GetTechnique(i32 index) const;
  174. /// Return pass by technique index and pass name.
  175. Pass* GetPass(i32 index, const String& passName) const;
  176. /// Return texture by unit.
  177. /// @property{get_textures}
  178. Texture* GetTexture(TextureUnit unit) const;
  179. /// Return all textures.
  180. const HashMap<TextureUnit, SharedPtr<Texture>>& GetTextures() const { return textures_; }
  181. /// Return additional vertex shader defines.
  182. /// @property
  183. const String& GetVertexShaderDefines() const { return vertexShaderDefines_; }
  184. /// Return additional pixel shader defines.
  185. /// @property
  186. const String& GetPixelShaderDefines() const { return pixelShaderDefines_; }
  187. /// Return shader parameter.
  188. /// @property{get_shaderParameters}
  189. const Variant& GetShaderParameter(const String& name) const;
  190. /// Return shader parameter animation.
  191. ValueAnimation* GetShaderParameterAnimation(const String& name) const;
  192. /// Return shader parameter animation wrap mode.
  193. WrapMode GetShaderParameterAnimationWrapMode(const String& name) const;
  194. /// Return shader parameter animation speed.
  195. float GetShaderParameterAnimationSpeed(const String& name) const;
  196. /// Return all shader parameters.
  197. const HashMap<StringHash, MaterialShaderParameter>& GetShaderParameters() const { return shaderParameters_; }
  198. /// Return normal culling mode.
  199. /// @property
  200. CullMode GetCullMode() const { return cullMode_; }
  201. /// Return culling mode for shadows.
  202. /// @property
  203. CullMode GetShadowCullMode() const { return shadowCullMode_; }
  204. /// Return polygon fill mode.
  205. /// @property
  206. FillMode GetFillMode() const { return fillMode_; }
  207. /// Return depth bias.
  208. /// @property
  209. const BiasParameters& GetDepthBias() const { return depthBias_; }
  210. /// Return alpha-to-coverage mode.
  211. /// @property
  212. bool GetAlphaToCoverage() const { return alphaToCoverage_; }
  213. /// Return whether line antialiasing is enabled.
  214. /// @property
  215. bool GetLineAntiAlias() const { return lineAntiAlias_; }
  216. /// Return render order.
  217. /// @property
  218. i8 GetRenderOrder() const { return renderOrder_; }
  219. /// Return last auxiliary view rendered frame number.
  220. i32 GetAuxViewFrameNumber() const { return auxViewFrameNumber_; }
  221. /// Return whether should render occlusion.
  222. /// @property
  223. bool GetOcclusion() const { return occlusion_; }
  224. /// Return whether should render specular.
  225. bool GetSpecular() const { return specular_; }
  226. /// Return the scene associated with the material for shader parameter animation updates.
  227. /// @property
  228. Scene* GetScene() const;
  229. /// Return shader parameter hash value. Used as an optimization to avoid setting shader parameters unnecessarily.
  230. hash32 GetShaderParameterHash() const { return shaderParameterHash_; }
  231. /// Return name for texture unit.
  232. static String GetTextureUnitName(TextureUnit unit);
  233. /// Parse a shader parameter value from a string. Retunrs either a bool, a float, or a 2 to 4-component vector.
  234. static Variant ParseShaderParameterValue(const String& value);
  235. private:
  236. /// Helper function for loading JSON files.
  237. bool BeginLoadJSON(Deserializer& source);
  238. /// Helper function for loading XML files.
  239. bool BeginLoadXML(Deserializer& source);
  240. /// Reset to defaults.
  241. void ResetToDefaults();
  242. /// Recalculate shader parameter hash.
  243. void RefreshShaderParameterHash();
  244. /// Recalculate the memory used by the material.
  245. void RefreshMemoryUse();
  246. /// Reapply shader defines to technique index. By default reapply all.
  247. void ApplyShaderDefines(i32 index = NINDEX);
  248. /// Return shader parameter animation info.
  249. ShaderParameterAnimationInfo* GetShaderParameterAnimationInfo(const String& name) const;
  250. /// Update whether should be subscribed to scene or global update events for shader parameter animation.
  251. void UpdateEventSubscription();
  252. /// Update shader parameter animations.
  253. void HandleAttributeAnimationUpdate(StringHash eventType, VariantMap& eventData);
  254. /// Techniques.
  255. Vector<TechniqueEntry> techniques_;
  256. /// Textures.
  257. HashMap<TextureUnit, SharedPtr<Texture>> textures_;
  258. /// %Shader parameters.
  259. HashMap<StringHash, MaterialShaderParameter> shaderParameters_;
  260. /// %Shader parameters animation infos.
  261. HashMap<StringHash, SharedPtr<ShaderParameterAnimationInfo>> shaderParameterAnimationInfos_;
  262. /// Vertex shader defines.
  263. String vertexShaderDefines_;
  264. /// Pixel shader defines.
  265. String pixelShaderDefines_;
  266. /// Normal culling mode.
  267. CullMode cullMode_{};
  268. /// Culling mode for shadow rendering.
  269. CullMode shadowCullMode_{};
  270. /// Polygon fill mode.
  271. FillMode fillMode_{};
  272. /// Depth bias parameters.
  273. BiasParameters depthBias_{};
  274. /// Render order value.
  275. i8 renderOrder_{};
  276. /// Last auxiliary view rendered frame number.
  277. i32 auxViewFrameNumber_{};
  278. /// Shader parameter hash value.
  279. hash32 shaderParameterHash_{};
  280. /// Alpha-to-coverage flag.
  281. bool alphaToCoverage_{};
  282. /// Line antialiasing flag.
  283. bool lineAntiAlias_{};
  284. /// Render occlusion flag.
  285. bool occlusion_{true};
  286. /// Specular lighting flag.
  287. bool specular_{};
  288. /// Flag for whether is subscribed to animation updates.
  289. bool subscribed_{};
  290. /// Flag to suppress parameter hash and memory use recalculation when setting multiple shader parameters (loading or resetting the material).
  291. bool batchedParameterUpdate_{};
  292. /// XML file used while loading.
  293. SharedPtr<XMLFile> loadXMLFile_;
  294. /// JSON file used while loading.
  295. SharedPtr<JSONFile> loadJSONFile_;
  296. /// Associated scene for shader parameter animation updates.
  297. WeakPtr<Scene> scene_;
  298. };
  299. }