BsRenderCompositor.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsRenderBeastPrerequisites.h"
  5. namespace bs { namespace ct
  6. {
  7. struct SceneInfo;
  8. class RendererViewGroup;
  9. class RenderCompositorNode;
  10. struct PooledStorageBuffer;
  11. struct FrameInfo;
  12. /** @addtogroup RenderBeast
  13. * @{
  14. */
  15. /** Inputs provided to each node in the render compositor hierarchy */
  16. struct RenderCompositorNodeInputs
  17. {
  18. RenderCompositorNodeInputs(const RendererViewGroup& viewGroup, const RendererView& view, const SceneInfo& scene,
  19. const RenderBeastOptions& options, const FrameInfo& frameInfo,
  20. const SmallVector<RenderCompositorNode*, 4>& inputNodes)
  21. : viewGroup(viewGroup), view(view), scene(scene), options(options), frameInfo(frameInfo), inputNodes(inputNodes)
  22. { }
  23. const RendererViewGroup& viewGroup;
  24. const RendererView& view;
  25. const SceneInfo& scene;
  26. const RenderBeastOptions& options;
  27. const FrameInfo& frameInfo;
  28. SmallVector<RenderCompositorNode*, 4> inputNodes;
  29. };
  30. /**
  31. * Node in the render compositor hierarchy. Nodes can be implemented to perform specific rendering tasks. Each node
  32. * can depend on other nodes in the hierarchy.
  33. *
  34. * @note Implementations must provide a getNodeId() and getDependencies() static method, which are expected to
  35. * return a unique name for the implemented node, as well as a set of nodes it depends on.
  36. */
  37. class RenderCompositorNode
  38. {
  39. public:
  40. virtual ~RenderCompositorNode() { }
  41. protected:
  42. friend class RenderCompositor;
  43. /** Executes the task implemented in the node. */
  44. virtual void render(const RenderCompositorNodeInputs& inputs) = 0;
  45. /**
  46. * Cleans up any temporary resources allocated in a render() call. Any resources lasting longer than one frame
  47. * should be kept alive and released in some other manner.
  48. */
  49. virtual void clear() = 0;
  50. };
  51. /**
  52. * Performs rendering by iterating over a hierarchy of render nodes. Each node in the hierarchy performs a specific
  53. * rendering tasks and passes its output to the dependant node. The system takes care of initializing, rendering and
  54. * cleaning up nodes automatically depending on their dependencies.
  55. */
  56. class RenderCompositor
  57. {
  58. /** Contains internal information about a single render node. */
  59. struct NodeInfo
  60. {
  61. RenderCompositorNode* node;
  62. UINT32 lastUseIdx;
  63. SmallVector<RenderCompositorNode*, 4> inputs;
  64. };
  65. public:
  66. ~RenderCompositor();
  67. /**
  68. * Rebuilds the render node hierarchy. Call this whenever some setting that may influence the render node
  69. * dependencies changes.
  70. *
  71. * @param[in] view Parent view to which this compositor belongs to.
  72. * @param[in] finalNode Identifier of the final node in the node hierarchy. This node is expected to write
  73. * to the views render target. All other nodes will be deduced from this node's
  74. * dependencies.
  75. */
  76. void build(const RendererView& view, const StringID& finalNode);
  77. /**
  78. * Performs rendering using the current render node hierarchy. This is expected to be called once per frame.
  79. *
  80. * @param[in] viewGroup Information about the current view group.
  81. * @param[in] view Information about the view this compositor belongs to.
  82. * @param[in] scene Information about the entire scene.
  83. * @param[in] frameInfo Information about the current frame.
  84. * @param[in] options Global renderer options.
  85. */
  86. void execute(const RendererViewGroup& viewGroup, const RendererView& view, const SceneInfo& scene,
  87. const FrameInfo& frameInfo, const RenderBeastOptions& options) const;
  88. private:
  89. /** Clears the render node hierarchy. */
  90. void clear();
  91. Vector<NodeInfo> mNodeInfos;
  92. bool mIsValid = false;
  93. /************************************************************************/
  94. /* NODE TYPES */
  95. /************************************************************************/
  96. public:
  97. /** Contains information about a specific node type. */
  98. struct NodeType
  99. {
  100. virtual ~NodeType() {};
  101. /** Creates a new node of this type. */
  102. virtual RenderCompositorNode* create() const = 0;
  103. /** Returns identifier for all the dependencies of a node of this type. */
  104. virtual SmallVector<StringID, 4> getDependencies(const RendererView& view) const = 0;
  105. StringID id;
  106. };
  107. /** Templated implementation of NodeType. */
  108. template<class T>
  109. struct TNodeType : NodeType
  110. {
  111. /** @copydoc NodeType::create() */
  112. RenderCompositorNode* create() const override { return bs_new<T>(); }
  113. /** @copydoc NodeType::getDependencies() */
  114. SmallVector<StringID, 4> getDependencies(const RendererView& view) const override
  115. {
  116. return T::getDependencies(view);
  117. }
  118. };
  119. /**
  120. * Registers a new type of node with the system. Each node type must first be registered before it can be used
  121. * in the node hierarchy.
  122. */
  123. template<class T>
  124. static void registerNodeType()
  125. {
  126. auto findIter = mNodeTypes.find(T::getNodeId());
  127. if (findIter != mNodeTypes.end())
  128. LOGERR("Found two render compositor nodes with the same name \"" + String(T::getNodeId().cstr()) + "\".");
  129. mNodeTypes[T::getNodeId()] = bs_new<TNodeType<T>>();
  130. }
  131. /** Releases any information about render node types. */
  132. static void cleanUp()
  133. {
  134. for (auto& entry : mNodeTypes)
  135. bs_delete(entry.second);
  136. mNodeTypes.clear();
  137. }
  138. private:
  139. static UnorderedMap<StringID, NodeType*> mNodeTypes;
  140. };
  141. /************************************************************************/
  142. /* BASE PASS NODES */
  143. /************************************************************************/
  144. /** Initializes the scene depth texture. Does not perform any rendering. */
  145. class RCNodeSceneDepth : public RenderCompositorNode
  146. {
  147. public:
  148. // Outputs
  149. SPtr<PooledRenderTexture> depthTex;
  150. static StringID getNodeId() { return "SceneDepth"; }
  151. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  152. protected:
  153. /** @copydoc RenderCompositorNode::render */
  154. void render(const RenderCompositorNodeInputs& inputs) override;
  155. /** @copydoc RenderCompositorNode::clear */
  156. void clear() override;
  157. };
  158. /**
  159. * Initializes the GBuffer textures and renders the base pass into the GBuffer. The base pass includes all the opaque
  160. * objects visible to the view.
  161. */
  162. class RCNodeGBuffer : public RenderCompositorNode
  163. {
  164. public:
  165. // Outputs
  166. SPtr<PooledRenderTexture> albedoTex;
  167. SPtr<PooledRenderTexture> normalTex;
  168. SPtr<PooledRenderTexture> roughMetalTex;
  169. SPtr<RenderTexture> renderTarget;
  170. static StringID getNodeId() { return "GBuffer"; }
  171. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  172. protected:
  173. /** @copydoc RenderCompositorNode::render */
  174. void render(const RenderCompositorNodeInputs& inputs) override;
  175. /** @copydoc RenderCompositorNode::clear */
  176. void clear() override;
  177. };
  178. /** Initializes the scene color texture and/or buffer. Does not perform any rendering. */
  179. class RCNodeSceneColor : public RenderCompositorNode
  180. {
  181. public:
  182. // Outputs
  183. /**
  184. * Contains scene color. If MSAA is used this texture will be null until the flattened data from the buffer is
  185. * first resolved into this texture.
  186. */
  187. SPtr<PooledRenderTexture> sceneColorTex;
  188. /**
  189. * Flattened, buffer version of sceneColorTex. Only available when MSAA is used, since random writes to multisampled
  190. * textures aren't supported on all render backends.
  191. */
  192. SPtr<PooledStorageBuffer> flattenedSceneColorBuffer;
  193. SPtr<RenderTexture> renderTarget;
  194. static StringID getNodeId() { return "SceneColor"; }
  195. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  196. protected:
  197. /** @copydoc RenderCompositorNode::render */
  198. void render(const RenderCompositorNodeInputs& inputs) override;
  199. /** @copydoc RenderCompositorNode::clear */
  200. void clear() override;
  201. };
  202. /************************************************************************/
  203. /* LIGHTING NODES */
  204. /************************************************************************/
  205. /** Initializes the light accumulation texture and/or buffer. Does not perform any rendering. */
  206. class RCNodeLightAccumulation : public RenderCompositorNode
  207. {
  208. public:
  209. // Outputs
  210. /**
  211. * Contains lighting information accumulated from multiple lights. If MSAA is used this texture will be null until
  212. * the flattened data from the buffer is first resolved into this texture.
  213. */
  214. SPtr<PooledRenderTexture> lightAccumulationTex;
  215. /**
  216. * Flattened, buffer version of lightAccumulationTex. Only available when MSAA is used, since random writes to
  217. * multisampled textures aren't supported on all render backends.
  218. */
  219. SPtr<PooledStorageBuffer> flattenedLightAccumBuffer;
  220. SPtr<RenderTexture> renderTarget;
  221. static StringID getNodeId() { return "LightAccumulation"; }
  222. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  223. protected:
  224. /** @copydoc RenderCompositorNode::render */
  225. void render(const RenderCompositorNodeInputs& inputs) override;
  226. /** @copydoc RenderCompositorNode::clear */
  227. void clear() override;
  228. };
  229. /**
  230. * Performs tiled deferred lighting, outputing any lighting information in the light accumulation buffer.
  231. * By default only non-shadowed lights are rendered, as shadowed ones are handled using standard deferred.
  232. */
  233. class RCNodeTiledDeferredLighting : public RenderCompositorNode
  234. {
  235. public:
  236. // Outputs
  237. RCNodeLightAccumulation* output;
  238. static StringID getNodeId() { return "TiledDeferredLighting"; }
  239. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  240. protected:
  241. /** @copydoc RenderCompositorNode::render */
  242. void render(const RenderCompositorNodeInputs& inputs) override;
  243. /** @copydoc RenderCompositorNode::clear */
  244. void clear() override;
  245. };
  246. /**
  247. * Performs standard deferred lighting, outputting any lighting information in the light accumulation buffer.
  248. * Only renders shadowed lights.
  249. */
  250. class RCNodeStandardDeferredLighting : public RenderCompositorNode
  251. {
  252. public:
  253. // Outputs
  254. RCNodeLightAccumulation* output;
  255. static StringID getNodeId() { return "StandardDeferredLighting"; }
  256. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  257. protected:
  258. /** @copydoc RenderCompositorNode::render */
  259. void render(const RenderCompositorNodeInputs& inputs) override;
  260. /** @copydoc RenderCompositorNode::clear */
  261. void clear() override;
  262. SPtr<PooledRenderTexture> mLightOcclusionTex;
  263. SPtr<RenderTexture> mRenderTarget;
  264. };
  265. /**
  266. * In case light accumulation was rendered into a buffer instead of a texture (if MSAA is used), this node will
  267. * unflatten the buffer and write its contents into the light accumulation texture.
  268. */
  269. class RCNodeUnflattenLightAccum : public RenderCompositorNode
  270. {
  271. public:
  272. // Outputs
  273. RCNodeLightAccumulation* output;
  274. static StringID getNodeId() { return "UnflattenLightAccum"; }
  275. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  276. protected:
  277. /** @copydoc RenderCompositorNode::render */
  278. void render(const RenderCompositorNodeInputs& inputs) override;
  279. /** @copydoc RenderCompositorNode::clear */
  280. void clear() override;
  281. };
  282. /**
  283. * Perform tiled deferred image based lighting, combines it with direct lighting present in the light accumulation
  284. * buffer and outputs the results to the scene color texture or buffer.
  285. */
  286. class RCNodeTiledDeferredIBL : public RenderCompositorNode
  287. {
  288. public:
  289. // Outputs
  290. RCNodeLightAccumulation* output;
  291. static StringID getNodeId() { return "TiledDeferredIBL"; }
  292. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  293. protected:
  294. /** @copydoc RenderCompositorNode::render */
  295. void render(const RenderCompositorNodeInputs& inputs) override;
  296. /** @copydoc RenderCompositorNode::clear */
  297. void clear() override;
  298. };
  299. /** Renders transparent objects using clustered forward rendering. */
  300. class RCNodeClusteredForward : public RenderCompositorNode
  301. {
  302. public:
  303. static StringID getNodeId() { return "ClusteredForward"; }
  304. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  305. protected:
  306. /** @copydoc RenderCompositorNode::render */
  307. void render(const RenderCompositorNodeInputs& inputs) override;
  308. /** @copydoc RenderCompositorNode::clear */
  309. void clear() override;
  310. };
  311. /**
  312. * In case scene color was rendered into a buffer instead of a texture (if MSAA is used), this node will
  313. * unflatten the buffer and write its contents into the scene color texture.
  314. */
  315. class RCNodeUnflattenSceneColor : public RenderCompositorNode
  316. {
  317. public:
  318. // Outputs
  319. RCNodeSceneColor* output;
  320. static StringID getNodeId() { return "UnflattenSceneColor"; }
  321. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  322. protected:
  323. /** @copydoc RenderCompositorNode::render */
  324. void render(const RenderCompositorNodeInputs& inputs) override;
  325. /** @copydoc RenderCompositorNode::clear */
  326. void clear() override;
  327. };
  328. /**
  329. * Renders the skybox into the scene color texture. If skybox texture is not available, a solid color will be rendered
  330. * instead.
  331. */
  332. class RCNodeSkybox : public RenderCompositorNode
  333. {
  334. public:
  335. static StringID getNodeId() { return "Skybox"; }
  336. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  337. protected:
  338. /** @copydoc RenderCompositorNode::render */
  339. void render(const RenderCompositorNodeInputs& inputs) override;
  340. /** @copydoc RenderCompositorNode::clear */
  341. void clear() override;
  342. };
  343. /** Moves the contents of the scene color texture into the view's output target. */
  344. class RCNodeFinalResolve : public RenderCompositorNode
  345. {
  346. public:
  347. static StringID getNodeId() { return "FinalResolve"; }
  348. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  349. protected:
  350. /** @copydoc RenderCompositorNode::render */
  351. void render(const RenderCompositorNodeInputs& inputs) override;
  352. /** @copydoc RenderCompositorNode::clear */
  353. void clear() override;
  354. };
  355. /************************************************************************/
  356. /* POST PROCESS NODES */
  357. /************************************************************************/
  358. /**
  359. * Helper node used for post-processing. Takes care of allocating and switching between textures used for post process
  360. * effects.
  361. */
  362. class RCNodePostProcess : public RenderCompositorNode
  363. {
  364. public:
  365. RCNodePostProcess();
  366. /**
  367. * Returns a texture that can be used for rendering a post-process effect, and the result of the previous
  368. * output. Switches these textures so the next call they are returned in the opposite parameters.
  369. */
  370. void getAndSwitch(const RendererView& view, SPtr<RenderTexture>& output, SPtr<Texture>& lastFrame) const;
  371. /** Returns a texture that contains the last rendererd post process output. */
  372. SPtr<Texture> getLastOutput() const;
  373. static StringID getNodeId() { return "PostProcess"; }
  374. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  375. protected:
  376. /** @copydoc RenderCompositorNode::render */
  377. void render(const RenderCompositorNodeInputs& inputs) override;
  378. /** @copydoc RenderCompositorNode::clear */
  379. void clear() override;
  380. mutable SPtr<PooledRenderTexture> mOutput[2];
  381. mutable bool mAllocated[2];
  382. mutable UINT32 mCurrentIdx = 0;
  383. };
  384. /**
  385. * Performs tone mapping on the contents of the scene color texture. At the same time resolves MSAA into a non-MSAA
  386. * scene color texture.
  387. */
  388. class RCNodeTonemapping : public RenderCompositorNode
  389. {
  390. public:
  391. SPtr<PooledRenderTexture> eyeAdaptation;
  392. SPtr<PooledRenderTexture> prevEyeAdaptation;
  393. ~RCNodeTonemapping();
  394. static StringID getNodeId() { return "Tonemapping"; }
  395. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  396. protected:
  397. /** @copydoc RenderCompositorNode::render */
  398. void render(const RenderCompositorNodeInputs& inputs) override;
  399. /** @copydoc RenderCompositorNode::clear */
  400. void clear() override;
  401. SPtr<PooledRenderTexture> mTonemapLUT;
  402. };
  403. /** Renders the depth of field effect using Gaussian blurring. */
  404. class RCNodeGaussianDOF : public RenderCompositorNode
  405. {
  406. public:
  407. static StringID getNodeId() { return "GaussianDOF"; }
  408. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  409. protected:
  410. /** @copydoc RenderCompositorNode::render */
  411. void render(const RenderCompositorNodeInputs& inputs) override;
  412. /** @copydoc RenderCompositorNode::clear */
  413. void clear() override;
  414. };
  415. /** Renders FXAA. */
  416. class RCNodeFXAA : public RenderCompositorNode
  417. {
  418. public:
  419. static StringID getNodeId() { return "FXAA"; }
  420. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  421. protected:
  422. /** @copydoc RenderCompositorNode::render */
  423. void render(const RenderCompositorNodeInputs& inputs) override;
  424. /** @copydoc RenderCompositorNode::clear */
  425. void clear() override;
  426. };
  427. /************************************************************************/
  428. /* SCREEN SPACE */
  429. /************************************************************************/
  430. /** Resolves the depth buffer (if multi-sampled). Otherwise just references the original depth buffer. */
  431. class RCNodeResolvedSceneDepth : public RenderCompositorNode
  432. {
  433. public:
  434. SPtr<PooledRenderTexture> output;
  435. static StringID getNodeId() { return "ResolvedSceneDepth"; }
  436. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  437. protected:
  438. /** @copydoc RenderCompositorNode::render */
  439. void render(const RenderCompositorNodeInputs& inputs) override;
  440. /** @copydoc RenderCompositorNode::clear */
  441. void clear() override;
  442. bool mPassThrough = false;
  443. };
  444. /** Builds the hierarchical Z buffer. */
  445. class RCNodeHiZ : public RenderCompositorNode
  446. {
  447. public:
  448. SPtr<PooledRenderTexture> output;
  449. static StringID getNodeId() { return "HiZ"; }
  450. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  451. protected:
  452. /** @copydoc RenderCompositorNode::render */
  453. void render(const RenderCompositorNodeInputs& inputs) override;
  454. /** @copydoc RenderCompositorNode::clear */
  455. void clear() override;
  456. };
  457. /** Renders screen space ambient occlusion. */
  458. class RCNodeSSAO : public RenderCompositorNode
  459. {
  460. public:
  461. SPtr<PooledRenderTexture> output;
  462. static StringID getNodeId() { return "SSAO"; }
  463. static SmallVector<StringID, 4> getDependencies(const RendererView& view);
  464. protected:
  465. /** @copydoc RenderCompositorNode::render */
  466. void render(const RenderCompositorNodeInputs& inputs) override;
  467. /** @copydoc RenderCompositorNode::clear */
  468. void clear() override;
  469. };
  470. /** @} */
  471. }}