BsRenderCompositor.cpp 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsRenderCompositor.h"
  4. #include "BsGpuResourcePool.h"
  5. #include "BsRendererView.h"
  6. #include "Renderer/BsRendererUtility.h"
  7. #include "Mesh/BsMesh.h"
  8. #include "RenderAPI/BsGpuBuffer.h"
  9. #include "BsStandardDeferredLighting.h"
  10. #include "BsRenderBeastOptions.h"
  11. #include "Renderer/BsCamera.h"
  12. #include "BsRendererScene.h"
  13. #include "BsRenderBeast.h"
  14. #include "Utility/BsBitwise.h"
  15. #include "BsRendererTextures.h"
  16. #include "BsObjectRendering.h"
  17. #include "Material/BsGpuParamsSet.h"
  18. #include "Renderer/BsRendererExtension.h"
  19. #include "Renderer/BsSkybox.h"
  20. #include "BsLightProbes.h"
  21. namespace bs { namespace ct
  22. {
  23. UnorderedMap<StringID, RenderCompositor::NodeType*> RenderCompositor::mNodeTypes;
  24. RenderCompositor::~RenderCompositor()
  25. {
  26. clear();
  27. }
  28. void RenderCompositor::build(const RendererView& view, const StringID& finalNode)
  29. {
  30. clear();
  31. bs_frame_mark();
  32. {
  33. FrameUnorderedMap<StringID, UINT32> processedNodes;
  34. mIsValid = true;
  35. std::function<bool(const StringID&)> registerNode = [&](const StringID& nodeId)
  36. {
  37. // Find node type
  38. auto iterFind = mNodeTypes.find(nodeId);
  39. if (iterFind == mNodeTypes.end())
  40. {
  41. LOGERR("Cannot find render compositor node of type \"" + String(nodeId.cstr()) + "\".");
  42. return false;
  43. }
  44. NodeType* nodeType = iterFind->second;
  45. // Register current node
  46. auto iterFind2 = processedNodes.find(nodeId);
  47. // New node
  48. if (iterFind2 == processedNodes.end())
  49. {
  50. // Mark it as invalid for now
  51. processedNodes[nodeId] = -1;
  52. }
  53. // Register node dependencies
  54. SmallVector<StringID, 4> depIds = nodeType->getDependencies(view);
  55. for (auto& dep : depIds)
  56. {
  57. if (!registerNode(dep))
  58. return false;
  59. }
  60. // Register current node
  61. UINT32 curIdx;
  62. // New node, properly populate its index
  63. if (iterFind2 == processedNodes.end())
  64. {
  65. iterFind2 = processedNodes.find(nodeId);
  66. curIdx = (UINT32)mNodeInfos.size();
  67. mNodeInfos.push_back(NodeInfo());
  68. processedNodes[nodeId] = curIdx;
  69. NodeInfo& nodeInfo = mNodeInfos.back();
  70. nodeInfo.node = nodeType->create();
  71. nodeInfo.lastUseIdx = -1;
  72. for (auto& depId : depIds)
  73. {
  74. iterFind2 = processedNodes.find(depId);
  75. NodeInfo& depNodeInfo = mNodeInfos[iterFind2->second];
  76. nodeInfo.inputs.push_back(depNodeInfo.node);
  77. }
  78. }
  79. else // Existing node
  80. {
  81. curIdx = iterFind2->second;
  82. // Check if invalid
  83. if (curIdx == (UINT32)-1)
  84. {
  85. LOGERR("Render compositor nodes recursion detected. Node \"" + String(nodeId.cstr()) + "\" " +
  86. "depends on node \"" + String(iterFind->first.cstr()) + "\" which is not available at " +
  87. "this stage.");
  88. return false;
  89. }
  90. }
  91. // Update dependency last use counters
  92. for (auto& dep : depIds)
  93. {
  94. iterFind2 = processedNodes.find(dep);
  95. NodeInfo& depNodeInfo = mNodeInfos[iterFind2->second];
  96. if (depNodeInfo.lastUseIdx == (UINT32)-1)
  97. depNodeInfo.lastUseIdx = curIdx;
  98. else
  99. depNodeInfo.lastUseIdx = std::max(depNodeInfo.lastUseIdx, curIdx);
  100. }
  101. return true;
  102. };
  103. mIsValid = registerNode(finalNode);
  104. if (!mIsValid)
  105. clear();
  106. }
  107. bs_frame_clear();
  108. }
  109. void RenderCompositor::execute(RenderCompositorNodeInputs& inputs) const
  110. {
  111. if (!mIsValid)
  112. return;
  113. bs_frame_mark();
  114. {
  115. FrameVector<const NodeInfo*> activeNodes;
  116. UINT32 idx = 0;
  117. for (auto& entry : mNodeInfos)
  118. {
  119. inputs.inputNodes = entry.inputs;
  120. entry.node->render(inputs);
  121. activeNodes.push_back(&entry);
  122. for (UINT32 i = 0; i < (UINT32)activeNodes.size(); ++i)
  123. {
  124. if (activeNodes[i] == nullptr)
  125. continue;
  126. if (activeNodes[i]->lastUseIdx <= idx)
  127. {
  128. activeNodes[i]->node->clear();
  129. activeNodes[i] = nullptr;
  130. }
  131. }
  132. idx++;
  133. }
  134. }
  135. bs_frame_clear();
  136. if (!mNodeInfos.empty())
  137. mNodeInfos.back().node->clear();
  138. }
  139. void RenderCompositor::clear()
  140. {
  141. for (auto& entry : mNodeInfos)
  142. bs_delete(entry.node);
  143. mNodeInfos.clear();
  144. mIsValid = false;
  145. }
  146. void RCNodeSceneDepth::render(const RenderCompositorNodeInputs& inputs)
  147. {
  148. GpuResourcePool& resPool = GpuResourcePool::instance();
  149. const RendererViewProperties& viewProps = inputs.view.getProperties();
  150. UINT32 width = viewProps.viewRect.width;
  151. UINT32 height = viewProps.viewRect.height;
  152. UINT32 numSamples = viewProps.numSamples;
  153. depthTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_D32_S8X24, width, height, TU_DEPTHSTENCIL,
  154. numSamples, false));
  155. }
  156. void RCNodeSceneDepth::clear()
  157. {
  158. GpuResourcePool& resPool = GpuResourcePool::instance();
  159. resPool.release(depthTex);
  160. }
  161. SmallVector<StringID, 4> RCNodeSceneDepth::getDependencies(const RendererView& view)
  162. {
  163. return {};
  164. }
  165. void RCNodeGBuffer::render(const RenderCompositorNodeInputs& inputs)
  166. {
  167. // Allocate necessary textures & targets
  168. GpuResourcePool& resPool = GpuResourcePool::instance();
  169. const RendererViewProperties& viewProps = inputs.view.getProperties();
  170. UINT32 width = viewProps.viewRect.width;
  171. UINT32 height = viewProps.viewRect.height;
  172. UINT32 numSamples = viewProps.numSamples;
  173. // Note: Consider customizable formats. e.g. for testing if quality can be improved with higher precision normals.
  174. albedoTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA8, width, height, TU_RENDERTARGET,
  175. numSamples, true));
  176. normalTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGB10A2, width, height, TU_RENDERTARGET,
  177. numSamples, false));
  178. roughMetalTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RG16F, width, height, TU_RENDERTARGET,
  179. numSamples, false)); // Note: Metal doesn't need 16-bit float
  180. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  181. SPtr<PooledRenderTexture> sceneDepthTex = sceneDepthNode->depthTex;
  182. bool rebuildRT = false;
  183. if (renderTarget != nullptr)
  184. {
  185. rebuildRT |= renderTarget->getColorTexture(0) != albedoTex->texture;
  186. rebuildRT |= renderTarget->getColorTexture(1) != normalTex->texture;
  187. rebuildRT |= renderTarget->getColorTexture(2) != roughMetalTex->texture;
  188. rebuildRT |= renderTarget->getDepthStencilTexture() != sceneDepthTex->texture;
  189. }
  190. else
  191. rebuildRT = true;
  192. if (renderTarget == nullptr || rebuildRT)
  193. {
  194. RENDER_TEXTURE_DESC gbufferDesc;
  195. gbufferDesc.colorSurfaces[0].texture = albedoTex->texture;
  196. gbufferDesc.colorSurfaces[0].face = 0;
  197. gbufferDesc.colorSurfaces[0].numFaces = 1;
  198. gbufferDesc.colorSurfaces[0].mipLevel = 0;
  199. gbufferDesc.colorSurfaces[1].texture = normalTex->texture;
  200. gbufferDesc.colorSurfaces[1].face = 0;
  201. gbufferDesc.colorSurfaces[1].numFaces = 1;
  202. gbufferDesc.colorSurfaces[1].mipLevel = 0;
  203. gbufferDesc.colorSurfaces[2].texture = roughMetalTex->texture;
  204. gbufferDesc.colorSurfaces[2].face = 0;
  205. gbufferDesc.colorSurfaces[2].numFaces = 1;
  206. gbufferDesc.colorSurfaces[2].mipLevel = 0;
  207. gbufferDesc.depthStencilSurface.texture = sceneDepthTex->texture;
  208. gbufferDesc.depthStencilSurface.face = 0;
  209. gbufferDesc.depthStencilSurface.mipLevel = 0;
  210. renderTarget = RenderTexture::create(gbufferDesc);
  211. }
  212. // Prepare all visible objects. Note that this also prepares non-opaque objects.
  213. const VisibilityInfo& visibility = inputs.view.getVisibilityMasks();
  214. UINT32 numRenderables = (UINT32)inputs.scene.renderables.size();
  215. for (UINT32 i = 0; i < numRenderables; i++)
  216. {
  217. if (!visibility.renderables[i])
  218. continue;
  219. RendererObject* rendererObject = inputs.scene.renderables[i];
  220. rendererObject->updatePerCallBuffer(viewProps.viewProjTransform);
  221. for (auto& element : inputs.scene.renderables[i]->elements)
  222. {
  223. SPtr<GpuParams> gpuParams = element.params->getGpuParams();
  224. for(UINT32 j = 0; j < GPT_COUNT; j++)
  225. {
  226. const GpuParamBinding& binding = element.perCameraBindings[j];
  227. if(binding.slot != (UINT32)-1)
  228. gpuParams->setParamBlockBuffer(binding.set, binding.slot, inputs.view.getPerViewBuffer());
  229. }
  230. }
  231. }
  232. Camera* sceneCamera = inputs.view.getSceneCamera();
  233. // Trigger prepare callbacks
  234. if (sceneCamera != nullptr)
  235. {
  236. for(auto& extension : inputs.extPrepare)
  237. {
  238. if (extension->check(*sceneCamera))
  239. extension->render(*sceneCamera);
  240. }
  241. }
  242. // Render base pass
  243. RenderAPI& rapi = RenderAPI::instance();
  244. rapi.setRenderTarget(renderTarget);
  245. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  246. rapi.setViewport(area);
  247. // Clear all targets
  248. rapi.clearViewport(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::ZERO, 1.0f, 0);
  249. // Trigger pre-base-pass callbacks
  250. if (sceneCamera != nullptr)
  251. {
  252. for(auto& extension : inputs.extPreBasePass)
  253. {
  254. if (extension->check(*sceneCamera))
  255. extension->render(*sceneCamera);
  256. }
  257. }
  258. // Render all visible opaque elements
  259. const Vector<RenderQueueElement>& opaqueElements = inputs.view.getOpaqueQueue()->getSortedElements();
  260. for (auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
  261. {
  262. BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
  263. SPtr<Material> material = renderElem->material;
  264. if (iter->applyPass)
  265. gRendererUtility().setPass(material, iter->passIdx, renderElem->techniqueIdx);
  266. gRendererUtility().setPassParams(renderElem->params, iter->passIdx);
  267. if(renderElem->morphVertexDeclaration == nullptr)
  268. gRendererUtility().draw(renderElem->mesh, renderElem->subMesh);
  269. else
  270. gRendererUtility().drawMorph(renderElem->mesh, renderElem->subMesh, renderElem->morphShapeBuffer,
  271. renderElem->morphVertexDeclaration);
  272. }
  273. // Make sure that any compute shaders are able to read g-buffer by unbinding it
  274. rapi.setRenderTarget(nullptr);
  275. // Trigger post-base-pass callbacks
  276. if (sceneCamera != nullptr)
  277. {
  278. for(auto& extension : inputs.extPostBasePass)
  279. {
  280. if (extension->check(*sceneCamera))
  281. extension->render(*sceneCamera);
  282. }
  283. }
  284. }
  285. void RCNodeGBuffer::clear()
  286. {
  287. GpuResourcePool& resPool = GpuResourcePool::instance();
  288. resPool.release(albedoTex);
  289. resPool.release(normalTex);
  290. resPool.release(roughMetalTex);
  291. }
  292. SmallVector<StringID, 4> RCNodeGBuffer::getDependencies(const RendererView& view)
  293. {
  294. return { RCNodeSceneDepth::getNodeId() };
  295. }
  296. void RCNodeSceneColor::render(const RenderCompositorNodeInputs& inputs)
  297. {
  298. GpuResourcePool& resPool = GpuResourcePool::instance();
  299. const RendererViewProperties& viewProps = inputs.view.getProperties();
  300. UINT32 width = viewProps.viewRect.width;
  301. UINT32 height = viewProps.viewRect.height;
  302. UINT32 numSamples = viewProps.numSamples;
  303. UINT32 usageFlags = TU_RENDERTARGET;
  304. bool tiledDeferredSupported = inputs.featureSet != RenderBeastFeatureSet::DesktopMacOS;
  305. if(tiledDeferredSupported)
  306. usageFlags |= TU_LOADSTORE;
  307. // Note: Consider customizable HDR format via options? e.g. smaller PF_FLOAT_R11G11B10 or larger 32-bit format
  308. sceneColorTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width, height, usageFlags,
  309. numSamples, false));
  310. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  311. SPtr<PooledRenderTexture> sceneDepthTex = sceneDepthNode->depthTex;
  312. if (tiledDeferredSupported && viewProps.numSamples > 1)
  313. {
  314. UINT32 bufferNumElements = width * height * viewProps.numSamples;
  315. flattenedSceneColorBuffer = resPool.get(POOLED_STORAGE_BUFFER_DESC::createStandard(BF_16X4F, bufferNumElements));
  316. }
  317. else
  318. flattenedSceneColorBuffer = nullptr;
  319. bool rebuildRT = false;
  320. if (renderTarget != nullptr)
  321. {
  322. rebuildRT |= renderTarget->getColorTexture(0) != sceneColorTex->texture;
  323. rebuildRT |= renderTarget->getDepthStencilTexture() != sceneDepthTex->texture;
  324. }
  325. else
  326. rebuildRT = true;
  327. if (rebuildRT)
  328. {
  329. RENDER_TEXTURE_DESC sceneColorDesc;
  330. sceneColorDesc.colorSurfaces[0].texture = sceneColorTex->texture;
  331. sceneColorDesc.colorSurfaces[0].face = 0;
  332. sceneColorDesc.colorSurfaces[0].numFaces = 1;
  333. sceneColorDesc.colorSurfaces[0].mipLevel = 0;
  334. sceneColorDesc.depthStencilSurface.texture = sceneDepthTex->texture;
  335. sceneColorDesc.depthStencilSurface.face = 0;
  336. sceneColorDesc.depthStencilSurface.numFaces = 1;
  337. sceneColorDesc.depthStencilSurface.mipLevel = 0;
  338. renderTarget = RenderTexture::create(sceneColorDesc);
  339. }
  340. }
  341. void RCNodeSceneColor::clear()
  342. {
  343. GpuResourcePool& resPool = GpuResourcePool::instance();
  344. resPool.release(sceneColorTex);
  345. if (flattenedSceneColorBuffer != nullptr)
  346. resPool.release(flattenedSceneColorBuffer);
  347. }
  348. void RCNodeSceneColor::unflatten()
  349. {
  350. FlatFramebufferToTextureMat* material = FlatFramebufferToTextureMat::get();
  351. int readOnlyFlags = FBT_DEPTH | FBT_STENCIL;
  352. RenderAPI& rapi = RenderAPI::instance();
  353. rapi.setRenderTarget(renderTarget, readOnlyFlags, RT_DEPTH_STENCIL);
  354. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  355. rapi.setViewport(area);
  356. material->execute(flattenedSceneColorBuffer->buffer, sceneColorTex->texture);
  357. }
  358. SmallVector<StringID, 4> RCNodeSceneColor::getDependencies(const RendererView& view)
  359. {
  360. return { RCNodeSceneDepth::getNodeId() };
  361. }
  362. void RCNodeMSAACoverage::render(const RenderCompositorNodeInputs& inputs)
  363. {
  364. const RendererViewProperties& viewProps = inputs.view.getProperties();
  365. if(viewProps.numSamples <= 1)
  366. {
  367. // No need for MSAA coverage
  368. output = nullptr;
  369. return;
  370. }
  371. GpuResourcePool& resPool = GpuResourcePool::instance();
  372. UINT32 width = viewProps.viewRect.width;
  373. UINT32 height = viewProps.viewRect.height;
  374. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width, height, TU_RENDERTARGET));
  375. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[0]);
  376. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  377. GBufferTextures gbuffer;
  378. gbuffer.albedo = gbufferNode->albedoTex->texture;
  379. gbuffer.normals = gbufferNode->normalTex->texture;
  380. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  381. gbuffer.depth = sceneDepthNode->depthTex->texture;
  382. MSAACoverageMat* mat = MSAACoverageMat::getVariation(viewProps.numSamples);
  383. RenderAPI& rapi = RenderAPI::instance();
  384. rapi.setRenderTarget(output->renderTexture);
  385. mat->execute(inputs.view, gbuffer);
  386. MSAACoverageStencilMat* stencilMat = MSAACoverageStencilMat::get();
  387. rapi.setRenderTarget(sceneDepthNode->depthTex->renderTexture);
  388. stencilMat->execute(inputs.view, output->texture);
  389. rapi.setRenderTarget(nullptr);
  390. }
  391. void RCNodeMSAACoverage::clear()
  392. {
  393. if(output)
  394. {
  395. GpuResourcePool& resPool = GpuResourcePool::instance();
  396. resPool.release(output);
  397. }
  398. }
  399. SmallVector<StringID, 4> RCNodeMSAACoverage::getDependencies(const RendererView& view)
  400. {
  401. return { RCNodeGBuffer::getNodeId(), RCNodeSceneDepth::getNodeId() };
  402. }
  403. void RCNodeLightAccumulation::render(const RenderCompositorNodeInputs& inputs)
  404. {
  405. bool supportsTiledDeferred = gRenderBeast()->getFeatureSet() != RenderBeastFeatureSet::DesktopMacOS;
  406. if(!supportsTiledDeferred)
  407. {
  408. // If tiled deferred is not supported, we don't need a separate texture for light accumulation, instead we
  409. // use scene color directly
  410. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  411. lightAccumulationTex = sceneColorNode->sceneColorTex;
  412. renderTarget = sceneColorNode->renderTarget;
  413. mOwnsTexture = false;
  414. return;
  415. }
  416. GpuResourcePool& resPool = GpuResourcePool::instance();
  417. const RendererViewProperties& viewProps = inputs.view.getProperties();
  418. RCNodeSceneDepth* depthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  419. UINT32 width = viewProps.viewRect.width;
  420. UINT32 height = viewProps.viewRect.height;
  421. UINT32 numSamples = viewProps.numSamples;
  422. if (numSamples > 1)
  423. {
  424. UINT32 bufferNumElements = width * height * numSamples;
  425. flattenedLightAccumBuffer =
  426. resPool.get(POOLED_STORAGE_BUFFER_DESC::createStandard(BF_16X4F, bufferNumElements));
  427. SPtr<GpuBuffer> buffer = flattenedLightAccumBuffer->buffer;
  428. auto& bufferProps = buffer->getProperties();
  429. UINT32 bufferSize = bufferProps.getElementSize() * bufferProps.getElementCount();
  430. UINT16* data = (UINT16*)buffer->lock(0, bufferSize, GBL_WRITE_ONLY_DISCARD);
  431. {
  432. memset(data, 0, bufferSize);
  433. }
  434. buffer->unlock();
  435. }
  436. else
  437. flattenedLightAccumBuffer = nullptr;
  438. lightAccumulationTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width,
  439. height, TU_LOADSTORE | TU_RENDERTARGET, numSamples, false));
  440. bool rebuildRT;
  441. if (renderTarget != nullptr)
  442. {
  443. rebuildRT = renderTarget->getColorTexture(0) != lightAccumulationTex->texture;
  444. rebuildRT |= renderTarget->getDepthStencilTexture() != depthNode->depthTex->texture;
  445. }
  446. else
  447. rebuildRT = true;
  448. if (rebuildRT)
  449. {
  450. RENDER_TEXTURE_DESC lightAccumulationRTDesc;
  451. lightAccumulationRTDesc.colorSurfaces[0].texture = lightAccumulationTex->texture;
  452. lightAccumulationRTDesc.colorSurfaces[0].face = 0;
  453. lightAccumulationRTDesc.colorSurfaces[0].numFaces = 1;
  454. lightAccumulationRTDesc.colorSurfaces[0].mipLevel = 0;
  455. lightAccumulationRTDesc.depthStencilSurface.texture = depthNode->depthTex->texture;
  456. lightAccumulationRTDesc.depthStencilSurface.face = 0;
  457. lightAccumulationRTDesc.depthStencilSurface.numFaces = 1;
  458. lightAccumulationRTDesc.depthStencilSurface.mipLevel = 0;
  459. renderTarget = RenderTexture::create(lightAccumulationRTDesc);
  460. }
  461. mOwnsTexture = true;
  462. }
  463. void RCNodeLightAccumulation::unflatten()
  464. {
  465. FlatFramebufferToTextureMat* material = FlatFramebufferToTextureMat::get();
  466. RenderAPI& rapi = RenderAPI::instance();
  467. rapi.setRenderTarget(renderTarget, FBT_DEPTH | FBT_STENCIL, RT_DEPTH_STENCIL);
  468. material->execute(flattenedLightAccumBuffer->buffer, lightAccumulationTex->texture);
  469. }
  470. void RCNodeLightAccumulation::clear()
  471. {
  472. GpuResourcePool& resPool = GpuResourcePool::instance();
  473. if(mOwnsTexture)
  474. resPool.release(lightAccumulationTex);
  475. else
  476. {
  477. lightAccumulationTex = nullptr;
  478. renderTarget = nullptr;
  479. }
  480. if (flattenedLightAccumBuffer)
  481. resPool.release(flattenedLightAccumBuffer);
  482. }
  483. SmallVector<StringID, 4> RCNodeLightAccumulation::getDependencies(const RendererView& view)
  484. {
  485. SmallVector<StringID, 4> deps;
  486. bool supportsTiledDeferred = gRenderBeast()->getFeatureSet() != RenderBeastFeatureSet::DesktopMacOS;
  487. if(!supportsTiledDeferred)
  488. deps.push_back(RCNodeSceneColor::getNodeId());
  489. else
  490. deps.push_back(RCNodeSceneDepth::getNodeId());
  491. return deps;
  492. }
  493. void RCNodeDeferredDirectLighting::render(const RenderCompositorNodeInputs& inputs)
  494. {
  495. output = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[0]);
  496. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  497. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[2]);
  498. GBufferTextures gbuffer;
  499. gbuffer.albedo = gbufferNode->albedoTex->texture;
  500. gbuffer.normals = gbufferNode->normalTex->texture;
  501. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  502. gbuffer.depth = sceneDepthNode->depthTex->texture;
  503. const RendererViewProperties& viewProps = inputs.view.getProperties();
  504. if (!inputs.view.getRenderSettings().enableShadows)
  505. mLightOcclusionRT = nullptr;
  506. bool tiledDeferredSupported = inputs.featureSet != RenderBeastFeatureSet::DesktopMacOS;
  507. if(tiledDeferredSupported)
  508. {
  509. SPtr<Texture> msaaCoverage;
  510. if(viewProps.numSamples > 1)
  511. {
  512. RCNodeMSAACoverage* coverageNode = static_cast<RCNodeMSAACoverage*>(inputs.inputNodes[3]);
  513. msaaCoverage = coverageNode->output->texture;
  514. }
  515. TiledDeferredLightingMat* tiledDeferredMat = TiledDeferredLightingMat::getVariation(viewProps.numSamples);
  516. const VisibleLightData& lightData = inputs.viewGroup.getVisibleLightData();
  517. SPtr<GpuBuffer> flattenedLightAccumBuffer;
  518. if (output->flattenedLightAccumBuffer)
  519. flattenedLightAccumBuffer = output->flattenedLightAccumBuffer->buffer;
  520. tiledDeferredMat->execute(inputs.view, lightData, gbuffer, output->lightAccumulationTex->texture,
  521. flattenedLightAccumBuffer, msaaCoverage);
  522. if (viewProps.numSamples > 1)
  523. output->unflatten();
  524. // If shadows are disabled we handle all lights through tiled deferred so we can exit immediately
  525. if (!inputs.view.getRenderSettings().enableShadows)
  526. return;
  527. }
  528. // Standard deferred used for shadowed lights, or when tiled deferred isn't supported
  529. GpuResourcePool& resPool = GpuResourcePool::instance();
  530. UINT32 width = viewProps.viewRect.width;
  531. UINT32 height = viewProps.viewRect.height;
  532. UINT32 numSamples = viewProps.numSamples;
  533. const VisibleLightData& lightData = inputs.viewGroup.getVisibleLightData();
  534. RenderAPI& rapi = RenderAPI::instance();
  535. // Render unshadowed lights
  536. if(!tiledDeferredSupported)
  537. {
  538. rapi.setRenderTarget(output->renderTarget, FBT_DEPTH | FBT_STENCIL, RT_DEPTH_STENCIL);
  539. rapi.clearRenderTarget(FBT_COLOR, Color::ZERO);
  540. for (UINT32 i = 0; i < (UINT32)LightType::Count; i++)
  541. {
  542. LightType lightType = (LightType)i;
  543. auto& lights = lightData.getLights(lightType);
  544. UINT32 count = lightData.getNumUnshadowedLights(lightType);
  545. for (UINT32 j = 0; j < count; j++)
  546. {
  547. UINT32 lightIdx = j;
  548. const RendererLight& light = *lights[lightIdx];
  549. StandardDeferred::instance().renderLight(lightType, light, inputs.view, gbuffer, Texture::BLACK);
  550. }
  551. }
  552. }
  553. // Allocate light occlusion
  554. SPtr<PooledRenderTexture> lightOcclusionTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width,
  555. height, TU_RENDERTARGET, numSamples, false));
  556. bool rebuildRT = false;
  557. if (mLightOcclusionRT != nullptr)
  558. {
  559. rebuildRT |= mLightOcclusionRT->getColorTexture(0) != lightOcclusionTex->texture;
  560. rebuildRT |= mLightOcclusionRT->getDepthStencilTexture() != sceneDepthNode->depthTex->texture;
  561. }
  562. else
  563. rebuildRT = true;
  564. if (rebuildRT)
  565. {
  566. RENDER_TEXTURE_DESC lightOcclusionRTDesc;
  567. lightOcclusionRTDesc.colorSurfaces[0].texture = lightOcclusionTex->texture;
  568. lightOcclusionRTDesc.colorSurfaces[0].face = 0;
  569. lightOcclusionRTDesc.colorSurfaces[0].numFaces = 1;
  570. lightOcclusionRTDesc.colorSurfaces[0].mipLevel = 0;
  571. lightOcclusionRTDesc.depthStencilSurface.texture = sceneDepthNode->depthTex->texture;
  572. lightOcclusionRTDesc.depthStencilSurface.face = 0;
  573. lightOcclusionRTDesc.depthStencilSurface.numFaces = 1;
  574. lightOcclusionRTDesc.depthStencilSurface.mipLevel = 0;
  575. mLightOcclusionRT = RenderTexture::create(lightOcclusionRTDesc);
  576. }
  577. // Render shadowed lights
  578. const ShadowRendering& shadowRenderer = inputs.viewGroup.getShadowRenderer();
  579. for (UINT32 i = 0; i < (UINT32)LightType::Count; i++)
  580. {
  581. LightType lightType = (LightType)i;
  582. auto& lights = lightData.getLights(lightType);
  583. UINT32 count = lightData.getNumShadowedLights(lightType);
  584. UINT32 offset = lightData.getNumUnshadowedLights(lightType);
  585. for (UINT32 j = 0; j < count; j++)
  586. {
  587. rapi.setRenderTarget(mLightOcclusionRT, FBT_DEPTH, RT_DEPTH_STENCIL);
  588. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  589. rapi.setViewport(area);
  590. rapi.clearViewport(FBT_COLOR, Color::ZERO);
  591. UINT32 lightIdx = offset + j;
  592. const RendererLight& light = *lights[lightIdx];
  593. shadowRenderer.renderShadowOcclusion(inputs.view, light, gbuffer);
  594. rapi.setRenderTarget(output->renderTarget, FBT_DEPTH | FBT_STENCIL, RT_COLOR0 | RT_DEPTH_STENCIL);
  595. StandardDeferred::instance().renderLight(lightType, light, inputs.view, gbuffer,
  596. lightOcclusionTex->texture);
  597. }
  598. }
  599. // Makes sure light accumulation can be read by following passes
  600. rapi.setRenderTarget(nullptr);
  601. resPool.release(lightOcclusionTex);
  602. }
  603. void RCNodeDeferredDirectLighting::clear()
  604. {
  605. output = nullptr;
  606. }
  607. SmallVector<StringID, 4> RCNodeDeferredDirectLighting::getDependencies(const RendererView& view)
  608. {
  609. SmallVector<StringID, 4> deps;
  610. deps.push_back(RCNodeLightAccumulation::getNodeId());
  611. deps.push_back(RCNodeGBuffer::getNodeId());
  612. deps.push_back(RCNodeSceneDepth::getNodeId());
  613. deps.push_back(RCNodeMSAACoverage::getNodeId());
  614. return deps;
  615. }
  616. void RCNodeIndirectDiffuseLighting::render(const RenderCompositorNodeInputs& inputs)
  617. {
  618. if (!inputs.view.getRenderSettings().enableIndirectLighting)
  619. return;
  620. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[0]);
  621. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  622. RCNodeLightAccumulation* lightAccumNode = static_cast <RCNodeLightAccumulation*>(inputs.inputNodes[2]);
  623. RCNodeSSAO* ssaoNode = static_cast<RCNodeSSAO*>(inputs.inputNodes[3]);
  624. GpuResourcePool& resPool = GpuResourcePool::instance();
  625. const RendererViewProperties& viewProps = inputs.view.getProperties();
  626. const LightProbes& lightProbes = inputs.scene.lightProbes;
  627. LightProbesInfo lpInfo = lightProbes.getInfo();
  628. IrradianceEvaluateMat* evaluateMat;
  629. SPtr<PooledRenderTexture> volumeIndices;
  630. if(lightProbes.hasAnyProbes())
  631. {
  632. POOLED_RENDER_TEXTURE_DESC volumeIndicesDesc;
  633. POOLED_RENDER_TEXTURE_DESC depthDesc;
  634. TetrahedraRenderMat::getOutputDesc(inputs.view, volumeIndicesDesc, depthDesc);
  635. volumeIndices = resPool.get(volumeIndicesDesc);
  636. SPtr<PooledRenderTexture> depthTex = resPool.get(depthDesc);
  637. RENDER_TEXTURE_DESC rtDesc;
  638. rtDesc.colorSurfaces[0].texture = volumeIndices->texture;
  639. rtDesc.depthStencilSurface.texture = depthTex->texture;
  640. SPtr<RenderTexture> rt = RenderTexture::create(rtDesc);
  641. RenderAPI& rapi = RenderAPI::instance();
  642. rapi.setRenderTarget(rt);
  643. rapi.clearRenderTarget(FBT_DEPTH);
  644. gRendererUtility().clear(-1);
  645. TetrahedraRenderMat* renderTetrahedra = TetrahedraRenderMat::getVariation(viewProps.numSamples > 1, true);
  646. renderTetrahedra->execute(inputs.view, sceneDepthNode->depthTex->texture, lpInfo.tetrahedraVolume, rt);
  647. rt = nullptr;
  648. resPool.release(depthTex);
  649. evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples > 1, true, false);
  650. }
  651. else // Sky only
  652. {
  653. evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples > 1, true, true);
  654. }
  655. GBufferTextures gbuffer;
  656. gbuffer.albedo = gbufferNode->albedoTex->texture;
  657. gbuffer.normals = gbufferNode->normalTex->texture;
  658. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  659. gbuffer.depth = sceneDepthNode->depthTex->texture;
  660. SPtr<Texture> volumeIndicesTex;
  661. if (volumeIndices)
  662. volumeIndicesTex = volumeIndices->texture;
  663. evaluateMat->execute(inputs.view, gbuffer, volumeIndicesTex, lpInfo, inputs.scene.skybox, ssaoNode->output,
  664. lightAccumNode->renderTarget);
  665. if(volumeIndices)
  666. resPool.release(volumeIndices);
  667. }
  668. void RCNodeIndirectDiffuseLighting::clear()
  669. {
  670. // Do nothing
  671. }
  672. SmallVector<StringID, 4> RCNodeIndirectDiffuseLighting::getDependencies(const RendererView& view)
  673. {
  674. SmallVector<StringID, 4> deps;
  675. deps.push_back(RCNodeGBuffer::getNodeId());
  676. deps.push_back(RCNodeSceneDepth::getNodeId());
  677. deps.push_back(RCNodeLightAccumulation::getNodeId());
  678. deps.push_back(RCNodeSSAO::getNodeId());
  679. deps.push_back(RCNodeDeferredDirectLighting::getNodeId());
  680. return deps;
  681. }
  682. void RCNodeDeferredIndirectSpecularLighting::render(const RenderCompositorNodeInputs& inputs)
  683. {
  684. const RenderSettings& rs = inputs.view.getRenderSettings();
  685. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  686. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  687. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[2]);
  688. RCNodeLightAccumulation* lightAccumNode = static_cast <RCNodeLightAccumulation*>(inputs.inputNodes[3]);
  689. RCNodeSSR* ssrNode = static_cast<RCNodeSSR*>(inputs.inputNodes[4]);
  690. RCNodeSSAO* ssaoNode = static_cast<RCNodeSSAO*>(inputs.inputNodes[5]);
  691. GBufferTextures gbuffer;
  692. gbuffer.albedo = gbufferNode->albedoTex->texture;
  693. gbuffer.normals = gbufferNode->normalTex->texture;
  694. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  695. gbuffer.depth = sceneDepthNode->depthTex->texture;
  696. const RendererViewProperties& viewProps = inputs.view.getProperties();
  697. bool tiledDeferredSupported = inputs.featureSet != RenderBeastFeatureSet::DesktopMacOS;
  698. if(tiledDeferredSupported)
  699. {
  700. SPtr<Texture> msaaCoverage;
  701. if (viewProps.numSamples > 1)
  702. {
  703. RCNodeMSAACoverage* coverageNode = static_cast<RCNodeMSAACoverage*>(inputs.inputNodes[6]);
  704. msaaCoverage = coverageNode->output->texture;
  705. }
  706. TiledDeferredImageBasedLightingMat* material = TiledDeferredImageBasedLightingMat::getVariation(viewProps.numSamples);
  707. TiledDeferredImageBasedLightingMat::Inputs iblInputs;
  708. iblInputs.gbuffer = gbuffer;
  709. iblInputs.sceneColorTex = sceneColorNode->sceneColorTex->texture;
  710. iblInputs.lightAccumulation = lightAccumNode->lightAccumulationTex->texture;
  711. iblInputs.preIntegratedGF = RendererTextures::preintegratedEnvGF;
  712. iblInputs.ambientOcclusion = ssaoNode->output;
  713. iblInputs.ssr = ssrNode->output;
  714. iblInputs.msaaCoverage = msaaCoverage;
  715. if (sceneColorNode->flattenedSceneColorBuffer)
  716. iblInputs.sceneColorBuffer = sceneColorNode->flattenedSceneColorBuffer->buffer;
  717. material->execute(inputs.view, inputs.scene, inputs.viewGroup.getVisibleReflProbeData(), iblInputs);
  718. if(viewProps.numSamples > 1)
  719. sceneColorNode->unflatten();
  720. }
  721. else // Standard deferred
  722. {
  723. SPtr<RenderTexture> outputRT = lightAccumNode->renderTarget;
  724. GpuResourcePool& resPool = GpuResourcePool::instance();
  725. UINT32 width = viewProps.viewRect.width;
  726. UINT32 height = viewProps.viewRect.height;
  727. UINT32 numSamples = viewProps.numSamples;
  728. RenderAPI& rapi = RenderAPI::instance();
  729. bool isMSAA = viewProps.numSamples > 1;
  730. SPtr<PooledRenderTexture> iblRadianceTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width,
  731. height, TU_RENDERTARGET, numSamples, false));
  732. RENDER_TEXTURE_DESC rtDesc;
  733. rtDesc.colorSurfaces[0].texture = iblRadianceTex->texture;
  734. rtDesc.depthStencilSurface.texture = sceneDepthNode->depthTex->texture;
  735. SPtr<GpuParamBlockBuffer> perViewBuffer = inputs.view.getPerViewBuffer();
  736. SPtr<RenderTexture> iblRadianceRT = RenderTexture::create(rtDesc);
  737. rapi.setRenderTarget(iblRadianceRT, FBT_DEPTH | FBT_STENCIL, RT_DEPTH_STENCIL);
  738. const VisibleReflProbeData& probeData = inputs.viewGroup.getVisibleReflProbeData();
  739. ReflProbeParamBuffer reflProbeParams;
  740. reflProbeParams.populate(inputs.scene.skybox, probeData.getNumProbes(), inputs.scene.reflProbeCubemapsTex,
  741. viewProps.capturingReflections);
  742. // Prepare the texture for refl. probe and skybox rendering
  743. {
  744. DeferredIBLSetupMat* mat = DeferredIBLSetupMat::getVariation(isMSAA, true);
  745. mat->bind(gbuffer, perViewBuffer, ssrNode->output, ssaoNode->output, reflProbeParams.buffer);
  746. gRendererUtility().drawScreenQuad();
  747. // Draw pixels requiring per-sample evaluation
  748. if (isMSAA)
  749. {
  750. DeferredIBLSetupMat* msaaMat = DeferredIBLSetupMat::getVariation(true, false);
  751. msaaMat->bind(gbuffer, perViewBuffer, ssrNode->output, ssaoNode->output, reflProbeParams.buffer);
  752. gRendererUtility().drawScreenQuad();
  753. }
  754. }
  755. if (!viewProps.capturingReflections)
  756. {
  757. // Render refl. probes
  758. UINT32 numProbes = probeData.getNumProbes();
  759. for (UINT32 i = 0; i < numProbes; i++)
  760. {
  761. const ReflProbeData& probe = probeData.getProbeData(i);
  762. StandardDeferred::instance().renderReflProbe(probe, inputs.view, gbuffer, inputs.scene,
  763. reflProbeParams.buffer);
  764. }
  765. // Render sky
  766. SPtr<Texture> skyFilteredRadiance;
  767. if (inputs.scene.skybox)
  768. skyFilteredRadiance = inputs.scene.skybox->getFilteredRadiance();
  769. if (skyFilteredRadiance)
  770. {
  771. DeferredIBLSkyMat* skymat = DeferredIBLSkyMat::getVariation(isMSAA, true);
  772. skymat->bind(gbuffer, perViewBuffer, inputs.scene.skybox, reflProbeParams.buffer);
  773. gRendererUtility().drawScreenQuad();
  774. // Draw pixels requiring per-sample evaluation
  775. if (isMSAA)
  776. {
  777. DeferredIBLSkyMat* msaaMat = DeferredIBLSkyMat::getVariation(true, false);
  778. msaaMat->bind(gbuffer, perViewBuffer, inputs.scene.skybox, reflProbeParams.buffer);
  779. gRendererUtility().drawScreenQuad();
  780. }
  781. }
  782. }
  783. // Finalize rendered reflections and output them to main render target
  784. {
  785. rapi.setRenderTarget(outputRT, FBT_DEPTH | FBT_STENCIL, RT_COLOR0 | RT_DEPTH_STENCIL);
  786. DeferredIBLFinalizeMat* mat = DeferredIBLFinalizeMat::getVariation(isMSAA, true);
  787. mat->bind(gbuffer, perViewBuffer, iblRadianceTex->texture, RendererTextures::preintegratedEnvGF,
  788. reflProbeParams.buffer);
  789. gRendererUtility().drawScreenQuad();
  790. // Draw pixels requiring per-sample evaluation
  791. if (isMSAA)
  792. {
  793. DeferredIBLFinalizeMat* msaaMat = DeferredIBLFinalizeMat::getVariation(true, false);
  794. msaaMat->bind(gbuffer, perViewBuffer, iblRadianceTex->texture, RendererTextures::preintegratedEnvGF,
  795. reflProbeParams.buffer);
  796. gRendererUtility().drawScreenQuad();
  797. }
  798. }
  799. // Makes sure light accumulation can be read by following passes
  800. rapi.setRenderTarget(nullptr);
  801. }
  802. }
  803. void RCNodeDeferredIndirectSpecularLighting::clear()
  804. {
  805. output = nullptr;
  806. }
  807. SmallVector<StringID, 4> RCNodeDeferredIndirectSpecularLighting::getDependencies(const RendererView& view)
  808. {
  809. SmallVector<StringID, 4> deps;
  810. deps.push_back(RCNodeSceneColor::getNodeId());
  811. deps.push_back(RCNodeGBuffer::getNodeId());
  812. deps.push_back(RCNodeSceneDepth::getNodeId());
  813. deps.push_back(RCNodeLightAccumulation::getNodeId());
  814. deps.push_back(RCNodeSSR::getNodeId());
  815. deps.push_back(RCNodeSSAO::getNodeId());
  816. deps.push_back(RCNodeMSAACoverage::getNodeId());
  817. deps.push_back(RCNodeIndirectDiffuseLighting::getNodeId());
  818. return deps;
  819. }
  820. RCNodeClusteredForward::RCNodeClusteredForward()
  821. { }
  822. void RCNodeClusteredForward::render(const RenderCompositorNodeInputs& inputs)
  823. {
  824. const SceneInfo& sceneInfo = inputs.scene;
  825. const RendererViewProperties& viewProps = inputs.view.getProperties();
  826. const VisibleLightData& visibleLightData = inputs.viewGroup.getVisibleLightData();
  827. const VisibleReflProbeData& visibleReflProbeData = inputs.viewGroup.getVisibleReflProbeData();
  828. // Buffers used when clustered forward is available
  829. SPtr<GpuParamBlockBuffer> gridParams;
  830. SPtr<GpuBuffer> gridLightOffsetsAndSize, gridLightIndices;
  831. SPtr<GpuBuffer> gridProbeOffsetsAndSize, gridProbeIndices;
  832. // Buffers used when clustered forward is unavailable
  833. SPtr<GpuParamBlockBuffer> lightsParamBlock;
  834. SPtr<GpuParamBlockBuffer> reflProbesParamBlock;
  835. SPtr<GpuParamBlockBuffer> lightAndReflProbeParamsParamBlock;
  836. bool supportsClusteredForward = gRenderBeast()->getFeatureSet() == RenderBeastFeatureSet::Desktop;
  837. if(supportsClusteredForward)
  838. {
  839. const LightGrid& lightGrid = inputs.view.getLightGrid();
  840. lightGrid.getOutputs(gridLightOffsetsAndSize, gridLightIndices, gridProbeOffsetsAndSize, gridProbeIndices,
  841. gridParams);
  842. }
  843. else
  844. {
  845. // Note: Store these instead of creating them every time?
  846. lightsParamBlock = gLightsParamDef.createBuffer();
  847. reflProbesParamBlock = gReflProbesParamDef.createBuffer();
  848. lightAndReflProbeParamsParamBlock = gLightAndReflProbeParamsParamDef.createBuffer();
  849. }
  850. // Prepare refl. probe param buffer
  851. ReflProbeParamBuffer reflProbeParamBuffer;
  852. reflProbeParamBuffer.populate(sceneInfo.skybox, visibleReflProbeData.getNumProbes(), sceneInfo.reflProbeCubemapsTex,
  853. viewProps.capturingReflections);
  854. SPtr<Texture> skyFilteredRadiance;
  855. if(sceneInfo.skybox)
  856. skyFilteredRadiance = sceneInfo.skybox->getFilteredRadiance();
  857. // Prepare objects for rendering
  858. const VisibilityInfo& visibility = inputs.view.getVisibilityMasks();
  859. UINT32 numRenderables = (UINT32)sceneInfo.renderables.size();
  860. for (UINT32 i = 0; i < numRenderables; i++)
  861. {
  862. if (!visibility.renderables[i])
  863. continue;
  864. for (auto& element : sceneInfo.renderables[i]->elements)
  865. {
  866. bool isTransparent = (element.material->getShader()->getFlags() & (UINT32)ShaderFlags::Transparent) != 0;
  867. if (!isTransparent)
  868. continue;
  869. // Note: It would be nice to be able to set this once and keep it, only updating if the buffers actually
  870. // change (e.g. when growing).
  871. SPtr<GpuParams> gpuParams = element.params->getGpuParams();
  872. ImageBasedLightingParams& iblParams = element.imageBasedParams;
  873. if(supportsClusteredForward)
  874. {
  875. for (UINT32 j = 0; j < GPT_COUNT; j++)
  876. {
  877. const GpuParamBinding& binding = element.gridParamsBindings[j];
  878. if (binding.slot != (UINT32)-1)
  879. gpuParams->setParamBlockBuffer(binding.set, binding.slot, gridParams);
  880. }
  881. element.gridLightOffsetsAndSizeParam.set(gridLightOffsetsAndSize);
  882. element.gridProbeOffsetsAndSizeParam.set(gridProbeOffsetsAndSize);
  883. element.gridLightIndicesParam.set(gridLightIndices);
  884. iblParams.reflectionProbeIndicesParam.set(gridProbeIndices);
  885. element.lightsBufferParam.set(visibleLightData.getLightBuffer());
  886. iblParams.reflectionProbesParam.set(visibleReflProbeData.getProbeBuffer());
  887. }
  888. else
  889. {
  890. // Populate light & probe buffers
  891. const Bounds& bounds = sceneInfo.renderableCullInfos[i].bounds;
  892. Vector3I lightCounts;
  893. const LightData* lights[STANDARD_FORWARD_MAX_NUM_LIGHTS];
  894. visibleLightData.gatherInfluencingLights(bounds, lights, lightCounts);
  895. Vector4I lightOffsets;
  896. lightOffsets.x = lightCounts.x;
  897. lightOffsets.y = lightCounts.x;
  898. lightOffsets.z = lightOffsets.y + lightCounts.y;
  899. lightOffsets.w = lightOffsets.z + lightCounts.z;
  900. for(INT32 j = 0; j < lightOffsets.w; j++)
  901. gLightsParamDef.gLights.set(lightsParamBlock, *lights[j], j);
  902. INT32 numReflProbes = std::min(visibleReflProbeData.getNumProbes(), STANDARD_FORWARD_MAX_NUM_PROBES);
  903. for(INT32 j = 0; j < numReflProbes; j++)
  904. gReflProbesParamDef.gReflectionProbes.set(reflProbesParamBlock, visibleReflProbeData.getProbeData(j), j);
  905. gLightAndReflProbeParamsParamDef.gLightOffsets.set(lightAndReflProbeParamsParamBlock, lightOffsets);
  906. gLightAndReflProbeParamsParamDef.gReflProbeCount.set(lightAndReflProbeParamsParamBlock, numReflProbes);
  907. if(iblParams.reflProbesBinding.set != (UINT32)-1)
  908. {
  909. gpuParams->setParamBlockBuffer(
  910. iblParams.reflProbesBinding.set,
  911. iblParams.reflProbesBinding.slot,
  912. reflProbesParamBlock);
  913. }
  914. if(element.lightsParamBlockBinding.set != (UINT32)-1)
  915. {
  916. gpuParams->setParamBlockBuffer(
  917. element.lightsParamBlockBinding.set,
  918. element.lightsParamBlockBinding.slot,
  919. lightsParamBlock);
  920. }
  921. if(element.lightAndReflProbeParamsParamBlockBinding.set != (UINT32)-1)
  922. {
  923. gpuParams->setParamBlockBuffer(
  924. element.lightAndReflProbeParamsParamBlockBinding.set,
  925. element.lightAndReflProbeParamsParamBlockBinding.slot,
  926. lightAndReflProbeParamsParamBlock);
  927. }
  928. }
  929. // Image based lighting params
  930. // Note: Ideally these should be bound once (they are the same for all renderables)
  931. if (iblParams.reflProbeParamBindings.set != (UINT32)-1)
  932. {
  933. gpuParams->setParamBlockBuffer(
  934. iblParams.reflProbeParamBindings.set,
  935. iblParams.reflProbeParamBindings.slot,
  936. reflProbeParamBuffer.buffer);
  937. }
  938. iblParams.skyReflectionsTexParam.set(skyFilteredRadiance);
  939. iblParams.ambientOcclusionTexParam.set(Texture::WHITE); // Note: Add SSAO here?
  940. iblParams.ssrTexParam.set(Texture::BLACK); // Note: Add SSR here?
  941. iblParams.reflectionProbeCubemapsTexParam.set(sceneInfo.reflProbeCubemapsTex);
  942. iblParams.preintegratedEnvBRDFParam.set(RendererTextures::preintegratedEnvGF);
  943. }
  944. }
  945. // TODO: Transparent objects cannot receive shadows. In order to support this I'd have to render the light occlusion
  946. // for all lights affecting this object into a single (or a few) textures. I can likely use texture arrays for this,
  947. // or to avoid sampling many textures, perhaps just jam it all in one or few texture channels.
  948. const Vector<RenderQueueElement>& transparentElements = inputs.view.getTransparentQueue()->getSortedElements();
  949. for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
  950. {
  951. BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
  952. SPtr<Material> material = renderElem->material;
  953. if (iter->applyPass)
  954. gRendererUtility().setPass(material, iter->passIdx, renderElem->techniqueIdx);
  955. gRendererUtility().setPassParams(renderElem->params, iter->passIdx);
  956. if(renderElem->morphVertexDeclaration == nullptr)
  957. gRendererUtility().draw(renderElem->mesh, renderElem->subMesh);
  958. else
  959. gRendererUtility().drawMorph(renderElem->mesh, renderElem->subMesh, renderElem->morphShapeBuffer,
  960. renderElem->morphVertexDeclaration);
  961. }
  962. // Trigger post-lighting callbacks
  963. Camera* sceneCamera = inputs.view.getSceneCamera();
  964. if (sceneCamera != nullptr)
  965. {
  966. for(auto& extension : inputs.extPostLighting)
  967. {
  968. if (extension->check(*sceneCamera))
  969. extension->render(*sceneCamera);
  970. }
  971. }
  972. }
  973. void RCNodeClusteredForward::clear()
  974. {
  975. // Do nothing
  976. }
  977. SmallVector<StringID, 4> RCNodeClusteredForward::getDependencies(const RendererView& view)
  978. {
  979. return { RCNodeSceneColor::getNodeId(), RCNodeSkybox::getNodeId() };
  980. }
  981. void RCNodeSkybox::render(const RenderCompositorNodeInputs& inputs)
  982. {
  983. Skybox* skybox = inputs.scene.skybox;
  984. SPtr<Texture> radiance = skybox ? skybox->getTexture() : nullptr;
  985. if (radiance != nullptr)
  986. {
  987. SkyboxMat* material = SkyboxMat::getVariation(false);
  988. material->bind(inputs.view.getPerViewBuffer(), radiance, Color::White);
  989. }
  990. else
  991. {
  992. Color clearColor = inputs.view.getProperties().clearColor;
  993. SkyboxMat* material = SkyboxMat::getVariation(true);
  994. material->bind(inputs.view.getPerViewBuffer(), nullptr, clearColor);
  995. }
  996. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  997. int readOnlyFlags = FBT_DEPTH | FBT_STENCIL;
  998. RenderAPI& rapi = RenderAPI::instance();
  999. rapi.setRenderTarget(sceneColorNode->renderTarget, readOnlyFlags, RT_COLOR0 | RT_DEPTH_STENCIL);
  1000. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  1001. rapi.setViewport(area);
  1002. SPtr<Mesh> mesh = gRendererUtility().getSkyBoxMesh();
  1003. gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
  1004. }
  1005. void RCNodeSkybox::clear()
  1006. { }
  1007. SmallVector<StringID, 4> RCNodeSkybox::getDependencies(const RendererView& view)
  1008. {
  1009. SmallVector<StringID, 4> deps;
  1010. deps.push_back(RCNodeSceneColor::getNodeId());
  1011. deps.push_back(RCNodeDeferredIndirectSpecularLighting::getNodeId());
  1012. return deps;
  1013. }
  1014. void RCNodeFinalResolve::render(const RenderCompositorNodeInputs& inputs)
  1015. {
  1016. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1017. SPtr<Texture> input;
  1018. if(viewProps.runPostProcessing)
  1019. {
  1020. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[0]);
  1021. // Note: Ideally the last PP effect could write directly to the final target and we could avoid this copy
  1022. input = postProcessNode->getLastOutput();
  1023. }
  1024. else
  1025. {
  1026. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  1027. input = sceneColorNode->sceneColorTex->texture;
  1028. }
  1029. SPtr<RenderTarget> target = viewProps.target;
  1030. RenderAPI& rapi = RenderAPI::instance();
  1031. rapi.setRenderTarget(target);
  1032. rapi.setViewport(viewProps.nrmViewRect);
  1033. gRendererUtility().blit(input, Rect2I::EMPTY, viewProps.flipView);
  1034. if(viewProps.encodeDepth)
  1035. {
  1036. RCNodeResolvedSceneDepth* resolvedSceneDepthNode = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[0]);
  1037. EncodeDepthMat* encodeDepthMat = EncodeDepthMat::get();
  1038. encodeDepthMat->execute(resolvedSceneDepthNode->output->texture, viewProps.depthEncodeNear,
  1039. viewProps.depthEncodeFar, target);
  1040. }
  1041. // Trigger overlay callbacks
  1042. Camera* sceneCamera = inputs.view.getSceneCamera();
  1043. if (sceneCamera != nullptr)
  1044. {
  1045. for(auto& extension : inputs.extOverlay)
  1046. {
  1047. if (extension->check(*sceneCamera))
  1048. extension->render(*sceneCamera);
  1049. }
  1050. }
  1051. }
  1052. void RCNodeFinalResolve::clear()
  1053. { }
  1054. SmallVector<StringID, 4> RCNodeFinalResolve::getDependencies(const RendererView& view)
  1055. {
  1056. const RendererViewProperties& viewProps = view.getProperties();
  1057. SmallVector<StringID, 4> deps;
  1058. if(viewProps.runPostProcessing)
  1059. {
  1060. deps.push_back(RCNodePostProcess::getNodeId());
  1061. deps.push_back(RCNodeFXAA::getNodeId());
  1062. }
  1063. else
  1064. {
  1065. deps.push_back(RCNodeSceneColor::getNodeId());
  1066. deps.push_back(RCNodeClusteredForward::getNodeId());
  1067. }
  1068. if(viewProps.encodeDepth)
  1069. deps.push_back(RCNodeResolvedSceneDepth::getNodeId());
  1070. return deps;
  1071. }
  1072. RCNodePostProcess::RCNodePostProcess()
  1073. :mOutput(), mAllocated()
  1074. { }
  1075. void RCNodePostProcess::getAndSwitch(const RendererView& view, SPtr<RenderTexture>& output, SPtr<Texture>& lastFrame) const
  1076. {
  1077. GpuResourcePool& resPool = GpuResourcePool::instance();
  1078. const RendererViewProperties& viewProps = view.getProperties();
  1079. UINT32 width = viewProps.viewRect.width;
  1080. UINT32 height = viewProps.viewRect.height;
  1081. if(!mAllocated[mCurrentIdx])
  1082. {
  1083. mOutput[mCurrentIdx] = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA8, width, height,
  1084. TU_RENDERTARGET, 1, false));
  1085. mAllocated[mCurrentIdx] = true;
  1086. }
  1087. output = mOutput[mCurrentIdx]->renderTexture;
  1088. UINT32 otherIdx = (mCurrentIdx + 1) % 2;
  1089. if (mAllocated[otherIdx])
  1090. lastFrame = mOutput[otherIdx]->texture;
  1091. mCurrentIdx = otherIdx;
  1092. }
  1093. SPtr<Texture> RCNodePostProcess::getLastOutput() const
  1094. {
  1095. UINT32 otherIdx = (mCurrentIdx + 1) % 2;
  1096. if (mAllocated[otherIdx])
  1097. return mOutput[otherIdx]->texture;
  1098. return nullptr;
  1099. }
  1100. void RCNodePostProcess::render(const RenderCompositorNodeInputs& inputs)
  1101. {
  1102. // Do nothing, this is just a helper node
  1103. }
  1104. void RCNodePostProcess::clear()
  1105. {
  1106. GpuResourcePool& resPool = GpuResourcePool::instance();
  1107. if (mAllocated[0])
  1108. resPool.release(mOutput[0]);
  1109. if (mAllocated[1])
  1110. resPool.release(mOutput[1]);
  1111. mAllocated[0] = false;
  1112. mAllocated[1] = false;
  1113. mCurrentIdx = 0;
  1114. }
  1115. SmallVector<StringID, 4> RCNodePostProcess::getDependencies(const RendererView& view)
  1116. {
  1117. return {};
  1118. }
  1119. RCNodeTonemapping::~RCNodeTonemapping()
  1120. {
  1121. GpuResourcePool& resPool = GpuResourcePool::instance();
  1122. if (mTonemapLUT)
  1123. resPool.release(mTonemapLUT);
  1124. if (prevEyeAdaptation)
  1125. resPool.release(prevEyeAdaptation);
  1126. }
  1127. void RCNodeTonemapping::render(const RenderCompositorNodeInputs& inputs)
  1128. {
  1129. GpuResourcePool& resPool = GpuResourcePool::instance();
  1130. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1131. const RenderSettings& settings = inputs.view.getRenderSettings();
  1132. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  1133. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[2]);
  1134. SPtr<Texture> sceneColor = sceneColorNode->sceneColorTex->texture;
  1135. bool hdr = settings.enableHDR;
  1136. bool msaa = viewProps.numSamples > 1;
  1137. if(hdr && settings.enableAutoExposure)
  1138. {
  1139. // Downsample scene
  1140. DownsampleMat* downsampleMat = DownsampleMat::getVariation(1, msaa);
  1141. SPtr<PooledRenderTexture> downsampledScene = resPool.get(DownsampleMat::getOutputDesc(sceneColor));
  1142. downsampleMat->execute(sceneColor, downsampledScene->renderTexture);
  1143. if(useHistogramEyeAdapatation(inputs))
  1144. {
  1145. // Generate histogram
  1146. SPtr<PooledRenderTexture> eyeAdaptHistogram =
  1147. resPool.get(EyeAdaptHistogramMat::getOutputDesc(downsampledScene->texture));
  1148. EyeAdaptHistogramMat* eyeAdaptHistogramMat = EyeAdaptHistogramMat::get();
  1149. eyeAdaptHistogramMat->execute(downsampledScene->texture, eyeAdaptHistogram->texture, settings.autoExposure);
  1150. // Reduce histogram
  1151. SPtr<PooledRenderTexture> reducedHistogram = resPool.get(EyeAdaptHistogramReduceMat::getOutputDesc());
  1152. SPtr<Texture> prevFrameEyeAdaptation;
  1153. if (prevEyeAdaptation != nullptr)
  1154. prevFrameEyeAdaptation = prevEyeAdaptation->texture;
  1155. EyeAdaptHistogramReduceMat* eyeAdaptHistogramReduce = EyeAdaptHistogramReduceMat::get();
  1156. eyeAdaptHistogramReduce->execute(
  1157. downsampledScene->texture,
  1158. eyeAdaptHistogram->texture,
  1159. prevFrameEyeAdaptation,
  1160. reducedHistogram->renderTexture);
  1161. resPool.release(downsampledScene);
  1162. downsampledScene = nullptr;
  1163. resPool.release(eyeAdaptHistogram);
  1164. eyeAdaptHistogram = nullptr;
  1165. // Generate eye adaptation value
  1166. eyeAdaptation = resPool.get(EyeAdaptationMat::getOutputDesc());
  1167. EyeAdaptationMat* eyeAdaptationMat = EyeAdaptationMat::get();
  1168. eyeAdaptationMat->execute(
  1169. reducedHistogram->texture,
  1170. eyeAdaptation->renderTexture,
  1171. inputs.frameInfo.timeDelta,
  1172. settings.autoExposure,
  1173. settings.exposureScale);
  1174. resPool.release(reducedHistogram);
  1175. reducedHistogram = nullptr;
  1176. }
  1177. else
  1178. {
  1179. // Populate alpha values of the downsampled texture with luminance
  1180. SPtr<PooledRenderTexture> luminanceTex =
  1181. resPool.get(EyeAdaptationBasicSetupMat::getOutputDesc(downsampledScene->texture));
  1182. EyeAdaptationBasicSetupMat* setupMat = EyeAdaptationBasicSetupMat::get();
  1183. setupMat->execute(
  1184. downsampledScene->texture,
  1185. luminanceTex->renderTexture,
  1186. inputs.frameInfo.timeDelta,
  1187. settings.autoExposure,
  1188. settings.exposureScale);
  1189. SPtr<Texture> downsampleInput = luminanceTex->texture;
  1190. luminanceTex = nullptr;
  1191. // Downsample some more
  1192. for(UINT32 i = 0; i < 5; i++)
  1193. {
  1194. downsampleMat = DownsampleMat::getVariation(1, false);
  1195. SPtr<PooledRenderTexture> downsampledLuminance =
  1196. resPool.get(DownsampleMat::getOutputDesc(downsampleInput));
  1197. downsampleMat->execute(downsampleInput, downsampledLuminance->renderTexture);
  1198. downsampleInput = downsampledLuminance->texture;
  1199. }
  1200. // Generate eye adaptation value
  1201. EyeAdaptationBasicMat* eyeAdaptationMat = EyeAdaptationBasicMat::get();
  1202. SPtr<Texture> prevFrameEyeAdaptation;
  1203. if (prevEyeAdaptation != nullptr)
  1204. prevFrameEyeAdaptation = prevEyeAdaptation->texture;
  1205. eyeAdaptation = resPool.get(EyeAdaptationBasicMat::getOutputDesc());
  1206. eyeAdaptationMat->execute(
  1207. downsampleInput,
  1208. prevFrameEyeAdaptation,
  1209. eyeAdaptation->renderTexture,
  1210. inputs.frameInfo.timeDelta,
  1211. settings.autoExposure,
  1212. settings.exposureScale);
  1213. }
  1214. }
  1215. else
  1216. {
  1217. if(prevEyeAdaptation)
  1218. resPool.release(prevEyeAdaptation);
  1219. prevEyeAdaptation = nullptr;
  1220. eyeAdaptation = nullptr;
  1221. }
  1222. bool volumeLUT = inputs.featureSet == RenderBeastFeatureSet::Desktop;
  1223. bool gammaOnly;
  1224. bool autoExposure;
  1225. if (hdr)
  1226. {
  1227. if (settings.enableTonemapping)
  1228. {
  1229. UINT64 latestHash = inputs.view.getRenderSettingsHash();
  1230. bool tonemapLUTDirty = mTonemapLastUpdateHash != latestHash;
  1231. if (tonemapLUTDirty) // Rebuild LUT if PP settings changed
  1232. {
  1233. CreateTonemapLUTMat* createLUT = CreateTonemapLUTMat::getVariation(volumeLUT);
  1234. if(mTonemapLUT == nullptr)
  1235. mTonemapLUT = resPool.get(createLUT->getOutputDesc());
  1236. if(volumeLUT)
  1237. createLUT->execute3D(mTonemapLUT->texture, settings);
  1238. else
  1239. createLUT->execute2D(mTonemapLUT->renderTexture, settings);
  1240. mTonemapLastUpdateHash = latestHash;
  1241. }
  1242. gammaOnly = false;
  1243. }
  1244. else
  1245. gammaOnly = true;
  1246. autoExposure = settings.enableAutoExposure;
  1247. }
  1248. else
  1249. {
  1250. gammaOnly = true;
  1251. autoExposure = false;
  1252. }
  1253. if(gammaOnly)
  1254. {
  1255. if(mTonemapLUT)
  1256. {
  1257. resPool.release(mTonemapLUT);
  1258. mTonemapLUT = nullptr;
  1259. }
  1260. }
  1261. TonemappingMat* tonemapping = TonemappingMat::getVariation(volumeLUT, gammaOnly, autoExposure, msaa);
  1262. SPtr<RenderTexture> ppOutput;
  1263. SPtr<Texture> ppLastFrame;
  1264. postProcessNode->getAndSwitch(inputs.view, ppOutput, ppLastFrame);
  1265. SPtr<Texture> eyeAdaptationTex;
  1266. if (eyeAdaptation)
  1267. eyeAdaptationTex = eyeAdaptation->texture;
  1268. SPtr<Texture> tonemapLUTTex;
  1269. if (mTonemapLUT)
  1270. tonemapLUTTex = mTonemapLUT->texture;
  1271. tonemapping->execute(sceneColor, eyeAdaptationTex, tonemapLUTTex, ppOutput, settings);
  1272. }
  1273. void RCNodeTonemapping::clear()
  1274. {
  1275. GpuResourcePool& resPool = GpuResourcePool::instance();
  1276. // Save eye adaptation for next frame
  1277. if(prevEyeAdaptation)
  1278. resPool.release(prevEyeAdaptation);
  1279. std::swap(eyeAdaptation, prevEyeAdaptation);
  1280. }
  1281. bool RCNodeTonemapping::useHistogramEyeAdapatation(const RenderCompositorNodeInputs& inputs)
  1282. {
  1283. return inputs.featureSet == RenderBeastFeatureSet::Desktop;
  1284. }
  1285. SmallVector<StringID, 4> RCNodeTonemapping::getDependencies(const RendererView& view)
  1286. {
  1287. return{ RCNodeSceneColor::getNodeId(), RCNodeClusteredForward::getNodeId(), RCNodePostProcess::getNodeId() };
  1288. }
  1289. void RCNodeGaussianDOF::render(const RenderCompositorNodeInputs& inputs)
  1290. {
  1291. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  1292. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[2]);
  1293. const DepthOfFieldSettings& settings = inputs.view.getRenderSettings().depthOfField;
  1294. bool near = settings.nearBlurAmount > 0.0f;
  1295. bool far = settings.farBlurAmount > 0.0f;
  1296. bool enabled = settings.enabled && (near || far);
  1297. if(!enabled)
  1298. return;
  1299. GaussianDOFSeparateMat* separateMat = GaussianDOFSeparateMat::getVariation(near, far);
  1300. GaussianDOFCombineMat* combineMat = GaussianDOFCombineMat::getVariation(near, far);
  1301. GaussianBlurMat* blurMat = GaussianBlurMat::get();
  1302. SPtr<RenderTexture> ppOutput;
  1303. SPtr<Texture> ppLastFrame;
  1304. postProcessNode->getAndSwitch(inputs.view, ppOutput, ppLastFrame);
  1305. separateMat->execute(ppLastFrame, sceneDepthNode->depthTex->texture, inputs.view, settings);
  1306. SPtr<PooledRenderTexture> nearTex, farTex;
  1307. if(near && far)
  1308. {
  1309. nearTex = separateMat->getOutput(0);
  1310. farTex = separateMat->getOutput(1);
  1311. }
  1312. else
  1313. {
  1314. if (near)
  1315. nearTex = separateMat->getOutput(0);
  1316. else
  1317. farTex = separateMat->getOutput(0);
  1318. }
  1319. // Blur the out of focus pixels
  1320. // Note: Perhaps set up stencil so I can avoid performing blur on unused parts of the textures?
  1321. const TextureProperties& texProps = nearTex ? nearTex->texture->getProperties() : farTex->texture->getProperties();
  1322. POOLED_RENDER_TEXTURE_DESC tempTexDesc = POOLED_RENDER_TEXTURE_DESC::create2D(texProps.getFormat(),
  1323. texProps.getWidth(), texProps.getHeight(), TU_RENDERTARGET);
  1324. SPtr<PooledRenderTexture> tempTexture = GpuResourcePool::instance().get(tempTexDesc);
  1325. SPtr<Texture> blurredNearTex;
  1326. if(nearTex)
  1327. {
  1328. blurMat->execute(nearTex->texture, settings.nearBlurAmount, tempTexture->renderTexture);
  1329. blurredNearTex = tempTexture->texture;
  1330. }
  1331. SPtr<Texture> blurredFarTex;
  1332. if(farTex)
  1333. {
  1334. // If temporary texture is used up, re-use the original near texture for the blurred result
  1335. if(blurredNearTex)
  1336. {
  1337. blurMat->execute(farTex->texture, settings.farBlurAmount, nearTex->renderTexture);
  1338. blurredFarTex = nearTex->texture;
  1339. }
  1340. else // Otherwise just use the temporary
  1341. {
  1342. blurMat->execute(farTex->texture, settings.farBlurAmount, tempTexture->renderTexture);
  1343. blurredFarTex = tempTexture->texture;
  1344. }
  1345. }
  1346. combineMat->execute(ppLastFrame, blurredNearTex, blurredFarTex,
  1347. sceneDepthNode->depthTex->texture, ppOutput, inputs.view, settings);
  1348. separateMat->release();
  1349. GpuResourcePool::instance().release(tempTexture);
  1350. }
  1351. void RCNodeGaussianDOF::clear()
  1352. {
  1353. // Do nothing
  1354. }
  1355. SmallVector<StringID, 4> RCNodeGaussianDOF::getDependencies(const RendererView& view)
  1356. {
  1357. return { RCNodeTonemapping::getNodeId(), RCNodeSceneDepth::getNodeId(), RCNodePostProcess::getNodeId() };
  1358. }
  1359. void RCNodeFXAA::render(const RenderCompositorNodeInputs& inputs)
  1360. {
  1361. const RenderSettings& settings = inputs.view.getRenderSettings();
  1362. if (!settings.enableFXAA)
  1363. return;
  1364. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[1]);
  1365. SPtr<RenderTexture> ppOutput;
  1366. SPtr<Texture> ppLastFrame;
  1367. postProcessNode->getAndSwitch(inputs.view, ppOutput, ppLastFrame);
  1368. // Note: I could skip executing FXAA over DOF and motion blurred pixels
  1369. FXAAMat* fxaa = FXAAMat::get();
  1370. fxaa->execute(ppLastFrame, ppOutput);
  1371. }
  1372. void RCNodeFXAA::clear()
  1373. {
  1374. // Do nothing
  1375. }
  1376. SmallVector<StringID, 4> RCNodeFXAA::getDependencies(const RendererView& view)
  1377. {
  1378. return { RCNodeGaussianDOF::getNodeId(), RCNodePostProcess::getNodeId() };
  1379. }
  1380. void RCNodeResolvedSceneDepth::render(const RenderCompositorNodeInputs& inputs)
  1381. {
  1382. GpuResourcePool& resPool = GpuResourcePool::instance();
  1383. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1384. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  1385. if (viewProps.numSamples > 1)
  1386. {
  1387. UINT32 width = viewProps.viewRect.width;
  1388. UINT32 height = viewProps.viewRect.height;
  1389. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_D32_S8X24, width, height,
  1390. TU_DEPTHSTENCIL, 1, false));
  1391. RenderAPI& rapi = RenderAPI::instance();
  1392. rapi.setRenderTarget(output->renderTexture);
  1393. rapi.clearRenderTarget(FBT_STENCIL);
  1394. gRendererUtility().blit(sceneDepthNode->depthTex->texture, Rect2I::EMPTY, false, true);
  1395. mPassThrough = false;
  1396. }
  1397. else
  1398. {
  1399. output = sceneDepthNode->depthTex;
  1400. mPassThrough = true;
  1401. }
  1402. }
  1403. void RCNodeResolvedSceneDepth::clear()
  1404. {
  1405. GpuResourcePool& resPool = GpuResourcePool::instance();
  1406. if (!mPassThrough)
  1407. resPool.release(output);
  1408. else
  1409. output = nullptr;
  1410. mPassThrough = false;
  1411. }
  1412. SmallVector<StringID, 4> RCNodeResolvedSceneDepth::getDependencies(const RendererView& view)
  1413. {
  1414. // GBuffer require because it renders the base pass (populates the depth buffer)
  1415. return { RCNodeSceneDepth::getNodeId(), RCNodeGBuffer::getNodeId() };
  1416. }
  1417. void RCNodeHiZ::render(const RenderCompositorNodeInputs& inputs)
  1418. {
  1419. GpuResourcePool& resPool = GpuResourcePool::instance();
  1420. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1421. RCNodeResolvedSceneDepth* resolvedSceneDepth = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[0]);
  1422. UINT32 width = viewProps.viewRect.width;
  1423. UINT32 height = viewProps.viewRect.height;
  1424. UINT32 size = Bitwise::nextPow2(std::max(width, height));
  1425. UINT32 numMips = PixelUtil::getMaxMipmaps(size, size, 1, PF_R32F);
  1426. size = 1 << numMips;
  1427. // Note: Use the 32-bit buffer here as 16-bit causes too much banding (most of the scene gets assigned 4-5 different
  1428. // depth values).
  1429. // - When I add UNORM 16-bit format I should be able to switch to that
  1430. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R32F, size, size, TU_RENDERTARGET, 1, false, 1,
  1431. numMips));
  1432. Rect2 srcRect = viewProps.nrmViewRect;
  1433. // If viewport size is odd, adjust UV
  1434. srcRect.width += (viewProps.viewRect.width % 2) * (1.0f / viewProps.viewRect.width);
  1435. srcRect.height += (viewProps.viewRect.height % 2) * (1.0f / viewProps.viewRect.height);
  1436. // Generate first mip
  1437. RENDER_TEXTURE_DESC rtDesc;
  1438. rtDesc.colorSurfaces[0].texture = output->texture;
  1439. rtDesc.colorSurfaces[0].mipLevel = 0;
  1440. SPtr<RenderTexture> rt = RenderTexture::create(rtDesc);
  1441. Rect2 destRect;
  1442. bool downsampledFirstMip = false; // Not used currently
  1443. if (downsampledFirstMip)
  1444. {
  1445. // Make sure that 1 pixel in HiZ maps to a 2x2 block in source
  1446. destRect = Rect2(0, 0,
  1447. Math::ceilToInt(viewProps.viewRect.width / 2.0f) / (float)size,
  1448. Math::ceilToInt(viewProps.viewRect.height / 2.0f) / (float)size);
  1449. BuildHiZMat* material = BuildHiZMat::get();
  1450. material->execute(resolvedSceneDepth->output->texture, 0, srcRect, destRect, rt);
  1451. }
  1452. else // First level is just a copy of the depth buffer
  1453. {
  1454. destRect = Rect2(0, 0,
  1455. viewProps.viewRect.width / (float)size,
  1456. viewProps.viewRect.height / (float)size);
  1457. RenderAPI& rapi = RenderAPI::instance();
  1458. rapi.setRenderTarget(rt);
  1459. rapi.setViewport(destRect);
  1460. Rect2I srcAreaInt;
  1461. srcAreaInt.x = (INT32)(srcRect.x * viewProps.viewRect.width);
  1462. srcAreaInt.y = (INT32)(srcRect.y * viewProps.viewRect.height);
  1463. srcAreaInt.width = (UINT32)(srcRect.width * viewProps.viewRect.width);
  1464. srcAreaInt.height = (UINT32)(srcRect.height * viewProps.viewRect.height);
  1465. gRendererUtility().blit(resolvedSceneDepth->output->texture, srcAreaInt);
  1466. rapi.setViewport(Rect2(0, 0, 1, 1));
  1467. }
  1468. // Generate remaining mip levels
  1469. for(UINT32 i = 1; i <= numMips; i++)
  1470. {
  1471. rtDesc.colorSurfaces[0].mipLevel = i;
  1472. rt = RenderTexture::create(rtDesc);
  1473. BuildHiZMat* material = BuildHiZMat::get();
  1474. material->execute(output->texture, i - 1, destRect, destRect, rt);
  1475. }
  1476. }
  1477. void RCNodeHiZ::clear()
  1478. {
  1479. GpuResourcePool& resPool = GpuResourcePool::instance();
  1480. resPool.release(output);
  1481. }
  1482. SmallVector<StringID, 4> RCNodeHiZ::getDependencies(const RendererView& view)
  1483. {
  1484. // Note: This doesn't actually use any gbuffer textures, but node is a dependency because it renders to the depth
  1485. // buffer. In order to avoid keeping gbuffer textures alive I could separate out the base pass into its own node
  1486. // perhaps. But at the moment it doesn't matter, as anything using HiZ also needs gbuffer.
  1487. return { RCNodeResolvedSceneDepth::getNodeId(), RCNodeGBuffer::getNodeId() };
  1488. }
  1489. void RCNodeSSAO::render(const RenderCompositorNodeInputs& inputs)
  1490. {
  1491. /** Maximum valid depth range within samples in a sample set. In meters. */
  1492. static const float DEPTH_RANGE = 1.0f;
  1493. const AmbientOcclusionSettings& settings = inputs.view.getRenderSettings().ambientOcclusion;
  1494. if(!settings.enabled)
  1495. {
  1496. output = Texture::WHITE;
  1497. mPooledOutput = nullptr;
  1498. return;
  1499. }
  1500. GpuResourcePool& resPool = GpuResourcePool::instance();
  1501. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1502. RCNodeResolvedSceneDepth* resolvedDepthNode = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[0]);
  1503. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  1504. SPtr<Texture> sceneDepth = resolvedDepthNode->output->texture;
  1505. SPtr<Texture> sceneNormals = gbufferNode->normalTex->texture;
  1506. const TextureProperties& normalsProps = sceneNormals->getProperties();
  1507. SPtr<PooledRenderTexture> resolvedNormals;
  1508. RenderAPI& rapi = RenderAPI::instance();
  1509. if(sceneNormals->getProperties().getNumSamples() > 1)
  1510. {
  1511. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(normalsProps.getFormat(),
  1512. normalsProps.getWidth(), normalsProps.getHeight(), TU_RENDERTARGET);
  1513. resolvedNormals = resPool.get(desc);
  1514. rapi.setRenderTarget(resolvedNormals->renderTexture);
  1515. gRendererUtility().blit(sceneNormals);
  1516. sceneNormals = resolvedNormals->texture;
  1517. }
  1518. // Multiple downsampled AO levels are used to minimize cache trashing. Downsampled AO targets use larger radius,
  1519. // whose contents are then blended with the higher level.
  1520. UINT32 quality = settings.quality;
  1521. UINT32 numDownsampleLevels = 0;
  1522. if (quality > 1)
  1523. numDownsampleLevels = 1;
  1524. else if (quality > 2)
  1525. numDownsampleLevels = 2;
  1526. SSAODownsampleMat* downsample = SSAODownsampleMat::get();
  1527. SPtr<PooledRenderTexture> setupTex0;
  1528. if(numDownsampleLevels > 0)
  1529. {
  1530. Vector2I downsampledSize(
  1531. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 2)),
  1532. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 2))
  1533. );
  1534. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, downsampledSize.x,
  1535. downsampledSize.y, TU_RENDERTARGET);
  1536. setupTex0 = GpuResourcePool::instance().get(desc);
  1537. downsample->execute(inputs.view, sceneDepth, sceneNormals, setupTex0->renderTexture, DEPTH_RANGE);
  1538. }
  1539. SPtr<PooledRenderTexture> setupTex1;
  1540. if(numDownsampleLevels > 1)
  1541. {
  1542. Vector2I downsampledSize(
  1543. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 4)),
  1544. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 4))
  1545. );
  1546. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, downsampledSize.x,
  1547. downsampledSize.y, TU_RENDERTARGET);
  1548. setupTex1 = GpuResourcePool::instance().get(desc);
  1549. downsample->execute(inputs.view, sceneDepth, sceneNormals, setupTex1->renderTexture, DEPTH_RANGE);
  1550. }
  1551. SSAOTextureInputs textures;
  1552. textures.sceneDepth = sceneDepth;
  1553. textures.sceneNormals = sceneNormals;
  1554. textures.randomRotations = RendererTextures::ssaoRandomization4x4;
  1555. SPtr<PooledRenderTexture> downAOTex1;
  1556. if(numDownsampleLevels > 1)
  1557. {
  1558. textures.aoSetup = setupTex1->texture;
  1559. Vector2I downsampledSize(
  1560. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 4)),
  1561. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 4))
  1562. );
  1563. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, downsampledSize.x,
  1564. downsampledSize.y, TU_RENDERTARGET);
  1565. downAOTex1 = GpuResourcePool::instance().get(desc);
  1566. SSAOMat* ssaoMat = SSAOMat::getVariation(false, false, quality);
  1567. ssaoMat->execute(inputs.view, textures, downAOTex1->renderTexture, settings);
  1568. GpuResourcePool::instance().release(setupTex1);
  1569. setupTex1 = nullptr;
  1570. }
  1571. SPtr<PooledRenderTexture> downAOTex0;
  1572. if(numDownsampleLevels > 0)
  1573. {
  1574. textures.aoSetup = setupTex0->texture;
  1575. if(downAOTex1)
  1576. textures.aoDownsampled = downAOTex1->texture;
  1577. Vector2I downsampledSize(
  1578. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 2)),
  1579. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 2))
  1580. );
  1581. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, downsampledSize.x,
  1582. downsampledSize.y, TU_RENDERTARGET);
  1583. downAOTex0 = GpuResourcePool::instance().get(desc);
  1584. bool upsample = numDownsampleLevels > 1;
  1585. SSAOMat* ssaoMat = SSAOMat::getVariation(upsample, false, quality);
  1586. ssaoMat->execute(inputs.view, textures, downAOTex0->renderTexture, settings);
  1587. if(upsample)
  1588. {
  1589. GpuResourcePool::instance().release(downAOTex1);
  1590. downAOTex1 = nullptr;
  1591. }
  1592. }
  1593. UINT32 width = viewProps.viewRect.width;
  1594. UINT32 height = viewProps.viewRect.height;
  1595. mPooledOutput = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width, height, TU_RENDERTARGET));
  1596. {
  1597. if(setupTex0)
  1598. textures.aoSetup = setupTex0->texture;
  1599. if(downAOTex0)
  1600. textures.aoDownsampled = downAOTex0->texture;
  1601. bool upsample = numDownsampleLevels > 0;
  1602. SSAOMat* ssaoMat = SSAOMat::getVariation(upsample, true, quality);
  1603. ssaoMat->execute(inputs.view, textures, mPooledOutput->renderTexture, settings);
  1604. }
  1605. if(resolvedNormals)
  1606. {
  1607. GpuResourcePool::instance().release(resolvedNormals);
  1608. resolvedNormals = nullptr;
  1609. }
  1610. if(numDownsampleLevels > 0)
  1611. {
  1612. GpuResourcePool::instance().release(setupTex0);
  1613. GpuResourcePool::instance().release(downAOTex0);
  1614. }
  1615. // Blur the output
  1616. // Note: If I implement temporal AA then this can probably be avoided. I can instead jitter the sample offsets
  1617. // each frame, and averaging them out should yield blurred AO.
  1618. if(quality > 1) // On level 0 we don't blur at all, on level 1 we use the ad-hoc blur in shader
  1619. {
  1620. const RenderTargetProperties& rtProps = mPooledOutput->renderTexture->getProperties();
  1621. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, rtProps.width,
  1622. rtProps.height, TU_RENDERTARGET);
  1623. SPtr<PooledRenderTexture> blurIntermediateTex = GpuResourcePool::instance().get(desc);
  1624. SSAOBlurMat* blurHorz = SSAOBlurMat::getVariation(true);
  1625. SSAOBlurMat* blurVert = SSAOBlurMat::getVariation(false);
  1626. blurHorz->execute(inputs.view, mPooledOutput->texture, sceneDepth, blurIntermediateTex->renderTexture, DEPTH_RANGE);
  1627. blurVert->execute(inputs.view, blurIntermediateTex->texture, sceneDepth, mPooledOutput->renderTexture, DEPTH_RANGE);
  1628. GpuResourcePool::instance().release(blurIntermediateTex);
  1629. }
  1630. RenderAPI::instance().setRenderTarget(nullptr);
  1631. output = mPooledOutput->texture;
  1632. }
  1633. void RCNodeSSAO::clear()
  1634. {
  1635. if(mPooledOutput)
  1636. {
  1637. GpuResourcePool& resPool = GpuResourcePool::instance();
  1638. resPool.release(mPooledOutput);
  1639. }
  1640. output = nullptr;
  1641. }
  1642. SmallVector<StringID, 4> RCNodeSSAO::getDependencies(const RendererView& view)
  1643. {
  1644. return { RCNodeResolvedSceneDepth::getNodeId(), RCNodeGBuffer::getNodeId() };
  1645. }
  1646. RCNodeSSR::~RCNodeSSR()
  1647. {
  1648. deallocOutputs();
  1649. }
  1650. void RCNodeSSR::render(const RenderCompositorNodeInputs& inputs)
  1651. {
  1652. const ScreenSpaceReflectionsSettings& settings = inputs.view.getRenderSettings().screenSpaceReflections;
  1653. if (!settings.enabled)
  1654. {
  1655. deallocOutputs();
  1656. mPooledOutput = nullptr;
  1657. output = Texture::BLACK;
  1658. return;
  1659. }
  1660. RenderAPI& rapi = RenderAPI::instance();
  1661. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  1662. RCNodeLightAccumulation* lightAccumNode = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[1]);
  1663. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[2]);
  1664. RCNodeHiZ* hiZNode = static_cast<RCNodeHiZ*>(inputs.inputNodes[3]);
  1665. RCNodeResolvedSceneDepth* resolvedSceneDepthNode = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[4]);
  1666. GpuResourcePool& resPool = GpuResourcePool::instance();
  1667. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1668. UINT32 width = viewProps.viewRect.width;
  1669. UINT32 height = viewProps.viewRect.height;
  1670. SPtr<Texture> hiZ = hiZNode->output->texture;
  1671. // This will be executing before scene color is resolved, so get the light accum buffer instead
  1672. SPtr<Texture> sceneColor = lightAccumNode->lightAccumulationTex->texture;
  1673. // Resolve multiple samples if MSAA is used
  1674. SPtr<PooledRenderTexture> resolvedSceneColor;
  1675. if (viewProps.numSamples > 1)
  1676. {
  1677. resolvedSceneColor = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width, height,
  1678. TU_RENDERTARGET));
  1679. rapi.setRenderTarget(resolvedSceneColor->renderTexture);
  1680. gRendererUtility().blit(sceneColor);
  1681. sceneColor = resolvedSceneColor->texture;
  1682. }
  1683. GBufferTextures gbuffer;
  1684. gbuffer.albedo = gbufferNode->albedoTex->texture;
  1685. gbuffer.normals = gbufferNode->normalTex->texture;
  1686. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  1687. gbuffer.depth = sceneDepthNode->depthTex->texture;
  1688. SSRStencilMat* stencilMat = SSRStencilMat::getVariation(viewProps.numSamples > 1, true);
  1689. // Note: Making the assumption that the stencil buffer is clear at this point
  1690. rapi.setRenderTarget(resolvedSceneDepthNode->output->renderTexture, FBT_DEPTH, RT_DEPTH_STENCIL);
  1691. stencilMat->execute(inputs.view, gbuffer, settings);
  1692. SPtr<PooledRenderTexture> traceOutput = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width,
  1693. height, TU_RENDERTARGET));
  1694. RENDER_TEXTURE_DESC traceRtDesc;
  1695. traceRtDesc.colorSurfaces[0].texture = traceOutput->texture;
  1696. traceRtDesc.depthStencilSurface.texture = resolvedSceneDepthNode->output->texture;
  1697. SPtr<RenderTexture> traceRt = RenderTexture::create(traceRtDesc);
  1698. rapi.setRenderTarget(traceRt, FBT_DEPTH | FBT_STENCIL, RT_DEPTH_STENCIL);
  1699. rapi.clearRenderTarget(FBT_COLOR, Color::ZERO);
  1700. SSRTraceMat* traceMat = SSRTraceMat::getVariation(settings.quality, viewProps.numSamples > 1, true);
  1701. traceMat->execute(inputs.view, gbuffer, sceneColor, hiZ, settings, traceRt);
  1702. if (resolvedSceneColor)
  1703. {
  1704. resPool.release(resolvedSceneColor);
  1705. resolvedSceneColor = nullptr;
  1706. }
  1707. if (mPrevFrame)
  1708. {
  1709. mPooledOutput = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width, height, TU_RENDERTARGET));
  1710. rapi.setRenderTarget(mPooledOutput->renderTexture);
  1711. rapi.clearRenderTarget(FBT_COLOR);
  1712. SSRResolveMat* resolveMat = SSRResolveMat::getVariation(viewProps.numSamples > 1);
  1713. resolveMat->execute(inputs.view, mPrevFrame->texture, traceOutput->texture, sceneDepthNode->depthTex->texture,
  1714. mPooledOutput->renderTexture);
  1715. resPool.release(traceOutput);
  1716. }
  1717. else
  1718. mPooledOutput = traceOutput;
  1719. RenderAPI::instance().setRenderTarget(nullptr);
  1720. output = mPooledOutput->texture;
  1721. }
  1722. void RCNodeSSR::clear()
  1723. {
  1724. GpuResourcePool& resPool = GpuResourcePool::instance();
  1725. if(mPrevFrame)
  1726. resPool.release(mPrevFrame);
  1727. mPrevFrame = mPooledOutput;
  1728. mPooledOutput = nullptr;
  1729. output = nullptr;
  1730. }
  1731. void RCNodeSSR::deallocOutputs()
  1732. {
  1733. GpuResourcePool& resPool = GpuResourcePool::instance();
  1734. if(mPrevFrame)
  1735. {
  1736. resPool.release(mPrevFrame);
  1737. mPrevFrame = nullptr;
  1738. }
  1739. output = nullptr;
  1740. }
  1741. SmallVector<StringID, 4> RCNodeSSR::getDependencies(const RendererView& view)
  1742. {
  1743. SmallVector<StringID, 4> deps;
  1744. if (view.getRenderSettings().screenSpaceReflections.enabled)
  1745. {
  1746. deps.push_back(RCNodeSceneDepth::getNodeId());
  1747. deps.push_back(RCNodeLightAccumulation::getNodeId());
  1748. deps.push_back(RCNodeGBuffer::getNodeId());
  1749. deps.push_back(RCNodeHiZ::getNodeId());
  1750. deps.push_back(RCNodeResolvedSceneDepth::getNodeId());
  1751. deps.push_back(RCNodeIndirectDiffuseLighting::getNodeId());
  1752. }
  1753. return deps;
  1754. }
  1755. }}