Technique.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. /// \file
  4. #pragma once
  5. #include "../GraphicsAPI/GraphicsDefs.h"
  6. #include "../Resource/Resource.h"
  7. namespace Urho3D
  8. {
  9. class ShaderVariation;
  10. /// Lighting mode of a pass.
  11. enum PassLightingMode
  12. {
  13. LIGHTING_UNLIT = 0,
  14. LIGHTING_PERVERTEX,
  15. LIGHTING_PERPIXEL
  16. };
  17. /// %Material rendering pass, which defines shaders and render state.
  18. class URHO3D_API Pass : public RefCounted
  19. {
  20. public:
  21. /// Construct.
  22. explicit Pass(const String& name);
  23. /// Destruct.
  24. ~Pass() override;
  25. /// Set blend mode.
  26. /// @property
  27. void SetBlendMode(BlendMode mode);
  28. /// Set culling mode override. By default culling mode is read from the material instead. Set the illegal culling mode MAX_CULLMODES to disable override again.
  29. /// @property
  30. void SetCullMode(CullMode mode);
  31. /// Set depth compare mode.
  32. /// @property
  33. void SetDepthTestMode(CompareMode mode);
  34. /// Set pass lighting mode, affects what shader variations will be attempted to be loaded.
  35. /// @property
  36. void SetLightingMode(PassLightingMode mode);
  37. /// Set depth write on/off.
  38. /// @property
  39. void SetDepthWrite(bool enable);
  40. /// Set alpha-to-coverage on/off.
  41. /// @property
  42. void SetAlphaToCoverage(bool enable);
  43. /// Set whether requires desktop level hardware.
  44. /// @property{set_desktop}
  45. void SetIsDesktop(bool enable);
  46. /// Set vertex shader name.
  47. /// @property
  48. void SetVertexShader(const String& name);
  49. /// Set pixel shader name.
  50. /// @property
  51. void SetPixelShader(const String& name);
  52. /// Set vertex shader defines. Separate multiple defines with spaces.
  53. /// @property
  54. void SetVertexShaderDefines(const String& defines);
  55. /// Set pixel shader defines. Separate multiple defines with spaces.
  56. /// @property
  57. void SetPixelShaderDefines(const String& defines);
  58. /// Set vertex shader define excludes. Use to mark defines that the shader code will not recognize, to prevent compiling redundant shader variations.
  59. /// @property
  60. void SetVertexShaderDefineExcludes(const String& excludes);
  61. /// Set pixel shader define excludes. Use to mark defines that the shader code will not recognize, to prevent compiling redundant shader variations.
  62. /// @property
  63. void SetPixelShaderDefineExcludes(const String& excludes);
  64. /// Reset shader pointers.
  65. void ReleaseShaders();
  66. /// Mark shaders loaded this frame.
  67. void MarkShadersLoaded(i32 frameNumber);
  68. /// Return pass name.
  69. const String& GetName() const { return name_; }
  70. /// Return pass index. This is used for optimal render-time pass queries that avoid map lookups.
  71. i32 GetIndex() const { return index_; }
  72. /// Return blend mode.
  73. /// @property
  74. BlendMode GetBlendMode() const { return blendMode_; }
  75. /// Return culling mode override. If pass is not overriding culling mode (default), the illegal mode MAX_CULLMODES is returned.
  76. /// @property
  77. CullMode GetCullMode() const { return cullMode_; }
  78. /// Return depth compare mode.
  79. /// @property
  80. CompareMode GetDepthTestMode() const { return depthTestMode_; }
  81. /// Return pass lighting mode.
  82. /// @property
  83. PassLightingMode GetLightingMode() const { return lightingMode_; }
  84. /// Return last shaders loaded frame number.
  85. i32 GetShadersLoadedFrameNumber() const { return shadersLoadedFrameNumber_; }
  86. /// Return depth write mode.
  87. /// @property
  88. bool GetDepthWrite() const { return depthWrite_; }
  89. /// Return alpha-to-coverage mode.
  90. /// @property
  91. bool GetAlphaToCoverage() const { return alphaToCoverage_; }
  92. /// Return whether requires desktop level hardware.
  93. /// @property
  94. bool IsDesktop() const { return isDesktop_; }
  95. /// Return vertex shader name.
  96. /// @property
  97. const String& GetVertexShader() const { return vertexShaderName_; }
  98. /// Return pixel shader name.
  99. /// @property
  100. const String& GetPixelShader() const { return pixelShaderName_; }
  101. /// Return vertex shader defines.
  102. /// @property
  103. const String& GetVertexShaderDefines() const { return vertexShaderDefines_; }
  104. /// Return pixel shader defines.
  105. /// @property
  106. const String& GetPixelShaderDefines() const { return pixelShaderDefines_; }
  107. /// Return vertex shader define excludes.
  108. /// @property
  109. const String& GetVertexShaderDefineExcludes() const { return vertexShaderDefineExcludes_; }
  110. /// Return pixel shader define excludes.
  111. /// @property
  112. const String& GetPixelShaderDefineExcludes() const { return pixelShaderDefineExcludes_; }
  113. /// Return vertex shaders.
  114. Vector<SharedPtr<ShaderVariation>>& GetVertexShaders() { return vertexShaders_; }
  115. /// Return pixel shaders.
  116. Vector<SharedPtr<ShaderVariation>>& GetPixelShaders() { return pixelShaders_; }
  117. /// Return vertex shaders with extra defines from the renderpath.
  118. Vector<SharedPtr<ShaderVariation>>& GetVertexShaders(const StringHash& extraDefinesHash);
  119. /// Return pixel shaders with extra defines from the renderpath.
  120. Vector<SharedPtr<ShaderVariation>>& GetPixelShaders(const StringHash& extraDefinesHash);
  121. /// Return the effective vertex shader defines, accounting for excludes. Called internally by Renderer.
  122. String GetEffectiveVertexShaderDefines() const;
  123. /// Return the effective pixel shader defines, accounting for excludes. Called internally by Renderer.
  124. String GetEffectivePixelShaderDefines() const;
  125. private:
  126. /// Pass index.
  127. i32 index_;
  128. /// Blend mode.
  129. BlendMode blendMode_;
  130. /// Culling mode.
  131. CullMode cullMode_;
  132. /// Depth compare mode.
  133. CompareMode depthTestMode_;
  134. /// Lighting mode.
  135. PassLightingMode lightingMode_;
  136. /// Last shaders loaded frame number.
  137. i32 shadersLoadedFrameNumber_;
  138. /// Depth write mode.
  139. bool depthWrite_;
  140. /// Alpha-to-coverage mode.
  141. bool alphaToCoverage_;
  142. /// Require desktop level hardware flag.
  143. bool isDesktop_;
  144. /// Vertex shader name.
  145. String vertexShaderName_;
  146. /// Pixel shader name.
  147. String pixelShaderName_;
  148. /// Vertex shader defines.
  149. String vertexShaderDefines_;
  150. /// Pixel shader defines.
  151. String pixelShaderDefines_;
  152. /// Vertex shader define excludes.
  153. String vertexShaderDefineExcludes_;
  154. /// Pixel shader define excludes.
  155. String pixelShaderDefineExcludes_;
  156. /// Vertex shaders.
  157. Vector<SharedPtr<ShaderVariation>> vertexShaders_;
  158. /// Pixel shaders.
  159. Vector<SharedPtr<ShaderVariation>> pixelShaders_;
  160. /// Vertex shaders with extra defines from the renderpath.
  161. HashMap<StringHash, Vector<SharedPtr<ShaderVariation>>> extraVertexShaders_;
  162. /// Pixel shaders with extra defines from the renderpath.
  163. HashMap<StringHash, Vector<SharedPtr<ShaderVariation>>> extraPixelShaders_;
  164. /// Pass name.
  165. String name_;
  166. };
  167. /// %Material technique. Consists of several passes.
  168. class URHO3D_API Technique : public Resource
  169. {
  170. URHO3D_OBJECT(Technique, Resource);
  171. friend class Renderer;
  172. public:
  173. /// Construct.
  174. explicit Technique(Context* context);
  175. /// Destruct.
  176. ~Technique() override;
  177. /// Register object factory.
  178. /// @nobind
  179. static void RegisterObject(Context* context);
  180. /// Load resource from stream. May be called from a worker thread. Return true if successful.
  181. bool BeginLoad(Deserializer& source) override;
  182. /// Set whether requires desktop level hardware.
  183. /// @property{set_desktop}
  184. void SetIsDesktop(bool enable);
  185. /// Create a new pass.
  186. Pass* CreatePass(const String& name);
  187. /// Remove a pass.
  188. void RemovePass(const String& name);
  189. /// Reset shader pointers in all passes.
  190. void ReleaseShaders();
  191. /// Clone the technique. Passes will be deep copied to allow independent modification.
  192. SharedPtr<Technique> Clone(const String& cloneName = String::EMPTY) const;
  193. /// Return whether requires desktop level hardware.
  194. /// @property
  195. bool IsDesktop() const { return isDesktop_; }
  196. /// Return whether technique is supported by the current hardware.
  197. /// @property
  198. bool IsSupported() const { return !isDesktop_ || desktopSupport_; }
  199. /// Return whether has a pass.
  200. bool HasPass(i32 passIndex) const
  201. {
  202. assert(passIndex >= 0);
  203. return passIndex < passes_.Size() && passes_[passIndex].Get() != nullptr;
  204. }
  205. /// Return whether has a pass by name. This overload should not be called in time-critical rendering loops; use a pre-acquired pass index instead.
  206. bool HasPass(const String& name) const;
  207. /// Return a pass, or null if not found.
  208. Pass* GetPass(i32 passIndex) const
  209. {
  210. assert(passIndex >= 0);
  211. return passIndex < passes_.Size() ? passes_[passIndex].Get() : nullptr;
  212. }
  213. /// Return a pass by name, or null if not found. This overload should not be called in time-critical rendering loops; use a pre-acquired pass index instead.
  214. Pass* GetPass(const String& name) const;
  215. /// Return a pass that is supported for rendering, or null if not found.
  216. Pass* GetSupportedPass(i32 passIndex) const
  217. {
  218. assert(passIndex >= 0);
  219. Pass* pass = passIndex < passes_.Size() ? passes_[passIndex].Get() : nullptr;
  220. return pass && (!pass->IsDesktop() || desktopSupport_) ? pass : nullptr;
  221. }
  222. /// Return a supported pass by name. This overload should not be called in time-critical rendering loops; use a pre-acquired pass index instead.
  223. Pass* GetSupportedPass(const String& name) const;
  224. /// Return number of passes.
  225. /// @property
  226. i32 GetNumPasses() const;
  227. /// Return all pass names.
  228. /// @property
  229. Vector<String> GetPassNames() const;
  230. /// Return all passes.
  231. /// @property
  232. Vector<Pass*> GetPasses() const;
  233. /// Return a clone with added shader compilation defines. Called internally by Material.
  234. SharedPtr<Technique> CloneWithDefines(const String& vsDefines, const String& psDefines);
  235. /// Return a pass type index by name. Allocate new if not used yet.
  236. static i32 GetPassIndex(const String& passName);
  237. /// Index for base pass. Initialized once GetPassIndex() has been called for the first time.
  238. static i32 basePassIndex;
  239. /// Index for alpha pass. Initialized once GetPassIndex() has been called for the first time.
  240. static i32 alphaPassIndex;
  241. /// Index for prepass material pass. Initialized once GetPassIndex() has been called for the first time.
  242. static i32 materialPassIndex;
  243. /// Index for deferred G-buffer pass. Initialized once GetPassIndex() has been called for the first time.
  244. static i32 deferredPassIndex;
  245. /// Index for per-pixel light pass. Initialized once GetPassIndex() has been called for the first time.
  246. static i32 lightPassIndex;
  247. /// Index for lit base pass. Initialized once GetPassIndex() has been called for the first time.
  248. static i32 litBasePassIndex;
  249. /// Index for lit alpha pass. Initialized once GetPassIndex() has been called for the first time.
  250. static i32 litAlphaPassIndex;
  251. /// Index for shadow pass. Initialized once GetPassIndex() has been called for the first time.
  252. static i32 shadowPassIndex;
  253. private:
  254. /// Require desktop GPU flag.
  255. bool isDesktop_;
  256. /// Cached desktop GPU support flag.
  257. bool desktopSupport_;
  258. /// Passes.
  259. Vector<SharedPtr<Pass>> passes_;
  260. /// Cached clones with added shader compilation defines.
  261. HashMap<Pair<StringHash, StringHash>, SharedPtr<Technique>> cloneTechniques_;
  262. /// Pass index assignments.
  263. static HashMap<String, i32> passIndices;
  264. };
  265. }