BsRenderCompositor.cpp 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910
  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 == -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 == -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. if (element.perCameraBindingIdx != -1)
  224. element.params->setParamBlockBuffer(element.perCameraBindingIdx, inputs.view.getPerViewBuffer(), true);
  225. }
  226. }
  227. Camera* sceneCamera = inputs.view.getSceneCamera();
  228. // Trigger pre-base-pass callbacks
  229. if (sceneCamera != nullptr)
  230. {
  231. for(auto& extension : inputs.extPreBasePass)
  232. {
  233. if (extension->check(*sceneCamera))
  234. extension->render(*sceneCamera);
  235. }
  236. }
  237. // Render base pass
  238. RenderAPI& rapi = RenderAPI::instance();
  239. rapi.setRenderTarget(renderTarget);
  240. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  241. rapi.setViewport(area);
  242. // Clear all targets
  243. rapi.clearViewport(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::ZERO, 1.0f, 0);
  244. // Render all visible opaque elements
  245. const Vector<RenderQueueElement>& opaqueElements = inputs.view.getOpaqueQueue()->getSortedElements();
  246. for (auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
  247. {
  248. BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
  249. SPtr<Material> material = renderElem->material;
  250. if (iter->applyPass)
  251. gRendererUtility().setPass(material, iter->passIdx, renderElem->techniqueIdx);
  252. gRendererUtility().setPassParams(renderElem->params, iter->passIdx);
  253. if(renderElem->morphVertexDeclaration == nullptr)
  254. gRendererUtility().draw(renderElem->mesh, renderElem->subMesh);
  255. else
  256. gRendererUtility().drawMorph(renderElem->mesh, renderElem->subMesh, renderElem->morphShapeBuffer,
  257. renderElem->morphVertexDeclaration);
  258. }
  259. // Trigger post-base-pass callbacks
  260. if (sceneCamera != nullptr)
  261. {
  262. for(auto& extension : inputs.extPostBasePass)
  263. {
  264. if (extension->check(*sceneCamera))
  265. extension->render(*sceneCamera);
  266. }
  267. }
  268. }
  269. void RCNodeGBuffer::clear()
  270. {
  271. GpuResourcePool& resPool = GpuResourcePool::instance();
  272. resPool.release(albedoTex);
  273. resPool.release(normalTex);
  274. resPool.release(roughMetalTex);
  275. }
  276. SmallVector<StringID, 4> RCNodeGBuffer::getDependencies(const RendererView& view)
  277. {
  278. return { RCNodeSceneDepth::getNodeId() };
  279. }
  280. void RCNodeSceneColor::render(const RenderCompositorNodeInputs& inputs)
  281. {
  282. GpuResourcePool& resPool = GpuResourcePool::instance();
  283. const RendererViewProperties& viewProps = inputs.view.getProperties();
  284. UINT32 width = viewProps.viewRect.width;
  285. UINT32 height = viewProps.viewRect.height;
  286. UINT32 numSamples = viewProps.numSamples;
  287. // Note: Consider customizable HDR format via options? e.g. smaller PF_FLOAT_R11G11B10 or larger 32-bit format
  288. sceneColorTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width, height, TU_RENDERTARGET |
  289. TU_LOADSTORE, numSamples, false));
  290. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  291. SPtr<PooledRenderTexture> sceneDepthTex = sceneDepthNode->depthTex;
  292. if (viewProps.numSamples > 1)
  293. {
  294. UINT32 bufferNumElements = width * height * viewProps.numSamples;
  295. flattenedSceneColorBuffer = resPool.get(POOLED_STORAGE_BUFFER_DESC::createStandard(BF_16X4F, bufferNumElements));
  296. }
  297. else
  298. flattenedSceneColorBuffer = nullptr;
  299. bool rebuildRT = false;
  300. if (renderTarget != nullptr)
  301. {
  302. rebuildRT |= renderTarget->getColorTexture(0) != sceneColorTex->texture;
  303. rebuildRT |= renderTarget->getDepthStencilTexture() != sceneDepthTex->texture;
  304. }
  305. else
  306. rebuildRT = true;
  307. if (rebuildRT)
  308. {
  309. RENDER_TEXTURE_DESC sceneColorDesc;
  310. sceneColorDesc.colorSurfaces[0].texture = sceneColorTex->texture;
  311. sceneColorDesc.colorSurfaces[0].face = 0;
  312. sceneColorDesc.colorSurfaces[0].numFaces = 1;
  313. sceneColorDesc.colorSurfaces[0].mipLevel = 0;
  314. sceneColorDesc.depthStencilSurface.texture = sceneDepthTex->texture;
  315. sceneColorDesc.depthStencilSurface.face = 0;
  316. sceneColorDesc.depthStencilSurface.numFaces = 1;
  317. sceneColorDesc.depthStencilSurface.mipLevel = 0;
  318. renderTarget = RenderTexture::create(sceneColorDesc);
  319. }
  320. }
  321. void RCNodeSceneColor::clear()
  322. {
  323. GpuResourcePool& resPool = GpuResourcePool::instance();
  324. resPool.release(sceneColorTex);
  325. if (flattenedSceneColorBuffer != nullptr)
  326. resPool.release(flattenedSceneColorBuffer);
  327. }
  328. SmallVector<StringID, 4> RCNodeSceneColor::getDependencies(const RendererView& view)
  329. {
  330. return { RCNodeSceneDepth::getNodeId() };
  331. }
  332. void RCNodeMSAACoverage::render(const RenderCompositorNodeInputs& inputs)
  333. {
  334. GpuResourcePool& resPool = GpuResourcePool::instance();
  335. const RendererViewProperties& viewProps = inputs.view.getProperties();
  336. UINT32 width = viewProps.viewRect.width;
  337. UINT32 height = viewProps.viewRect.height;
  338. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width, height, TU_RENDERTARGET));
  339. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[0]);
  340. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  341. GBufferTextures gbuffer;
  342. gbuffer.albedo = gbufferNode->albedoTex->texture;
  343. gbuffer.normals = gbufferNode->normalTex->texture;
  344. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  345. gbuffer.depth = sceneDepthNode->depthTex->texture;
  346. MSAACoverageMat* mat = MSAACoverageMat::getVariation(viewProps.numSamples);
  347. RenderAPI::instance().setRenderTarget(output->renderTexture);
  348. mat->execute(inputs.view, gbuffer);
  349. }
  350. void RCNodeMSAACoverage::clear()
  351. {
  352. GpuResourcePool& resPool = GpuResourcePool::instance();
  353. resPool.release(output);
  354. }
  355. SmallVector<StringID, 4> RCNodeMSAACoverage::getDependencies(const RendererView& view)
  356. {
  357. return { RCNodeGBuffer::getNodeId(), RCNodeSceneDepth::getNodeId() };
  358. }
  359. void RCNodeLightAccumulation::render(const RenderCompositorNodeInputs& inputs)
  360. {
  361. GpuResourcePool& resPool = GpuResourcePool::instance();
  362. const RendererViewProperties& viewProps = inputs.view.getProperties();
  363. UINT32 width = viewProps.viewRect.width;
  364. UINT32 height = viewProps.viewRect.height;
  365. UINT32 numSamples = viewProps.numSamples;
  366. if (numSamples > 1)
  367. {
  368. UINT32 bufferNumElements = width * height * numSamples;
  369. flattenedLightAccumBuffer =
  370. resPool.get(POOLED_STORAGE_BUFFER_DESC::createStandard(BF_16X4F, bufferNumElements));
  371. SPtr<GpuBuffer> buffer = flattenedLightAccumBuffer->buffer;
  372. auto& bufferProps = buffer->getProperties();
  373. UINT32 bufferSize = bufferProps.getElementSize() * bufferProps.getElementCount();
  374. UINT16* data = (UINT16*)buffer->lock(0, bufferSize, GBL_WRITE_ONLY_DISCARD);
  375. {
  376. memset(data, 0, bufferSize);
  377. }
  378. buffer->unlock();
  379. }
  380. else
  381. flattenedLightAccumBuffer = nullptr;
  382. lightAccumulationTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width,
  383. height, TU_LOADSTORE | TU_RENDERTARGET, numSamples, false));
  384. bool rebuildRT;
  385. if (renderTarget != nullptr)
  386. rebuildRT = renderTarget->getColorTexture(0) != lightAccumulationTex->texture;
  387. else
  388. rebuildRT = true;
  389. if (rebuildRT)
  390. {
  391. RENDER_TEXTURE_DESC lightAccumulationRTDesc;
  392. lightAccumulationRTDesc.colorSurfaces[0].texture = lightAccumulationTex->texture;
  393. lightAccumulationRTDesc.colorSurfaces[0].face = 0;
  394. lightAccumulationRTDesc.colorSurfaces[0].numFaces = 1;
  395. lightAccumulationRTDesc.colorSurfaces[0].mipLevel = 0;
  396. renderTarget = RenderTexture::create(lightAccumulationRTDesc);
  397. }
  398. }
  399. void RCNodeLightAccumulation::clear()
  400. {
  401. GpuResourcePool& resPool = GpuResourcePool::instance();
  402. resPool.release(lightAccumulationTex);
  403. if (flattenedLightAccumBuffer)
  404. resPool.release(flattenedLightAccumBuffer);
  405. }
  406. SmallVector<StringID, 4> RCNodeLightAccumulation::getDependencies(const RendererView& view)
  407. {
  408. return {};
  409. }
  410. void RCNodeTiledDeferredLighting::render(const RenderCompositorNodeInputs& inputs)
  411. {
  412. output = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[0]);
  413. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  414. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[2]);
  415. const RendererViewProperties& viewProps = inputs.view.getProperties();
  416. SPtr<Texture> msaaCoverage;
  417. if(viewProps.numSamples > 1)
  418. {
  419. RCNodeMSAACoverage* coverageNode = static_cast<RCNodeMSAACoverage*>(inputs.inputNodes[3]);
  420. msaaCoverage = coverageNode->output->texture;
  421. }
  422. TiledDeferredLightingMat* tiledDeferredMat = TiledDeferredLightingMat::getVariation(viewProps.numSamples);
  423. GBufferTextures gbuffer;
  424. gbuffer.albedo = gbufferNode->albedoTex->texture;
  425. gbuffer.normals = gbufferNode->normalTex->texture;
  426. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  427. gbuffer.depth = sceneDepthNode->depthTex->texture;
  428. RenderAPI& rapi = RenderAPI::instance();
  429. rapi.setRenderTarget(output->renderTarget, FBT_DEPTH | FBT_STENCIL, RT_COLOR0 | RT_DEPTH_STENCIL);
  430. const VisibleLightData& lightData = inputs.viewGroup.getVisibleLightData();
  431. SPtr<GpuBuffer> flattenedLightAccumBuffer;
  432. if (output->flattenedLightAccumBuffer)
  433. flattenedLightAccumBuffer = output->flattenedLightAccumBuffer->buffer;
  434. tiledDeferredMat->execute(inputs.view, lightData, gbuffer, output->lightAccumulationTex->texture,
  435. flattenedLightAccumBuffer, msaaCoverage);
  436. }
  437. void RCNodeTiledDeferredLighting::clear()
  438. {
  439. output = nullptr;
  440. }
  441. SmallVector<StringID, 4> RCNodeTiledDeferredLighting::getDependencies(const RendererView& view)
  442. {
  443. SmallVector<StringID, 4> deps;
  444. deps.push_back(RCNodeLightAccumulation::getNodeId());
  445. deps.push_back(RCNodeGBuffer::getNodeId());
  446. deps.push_back(RCNodeSceneDepth::getNodeId());
  447. if(view.getProperties().numSamples > 1)
  448. deps.push_back(RCNodeMSAACoverage::getNodeId());
  449. return deps;
  450. }
  451. void RCNodeStandardDeferredLighting::render(const RenderCompositorNodeInputs& inputs)
  452. {
  453. RCNodeTiledDeferredLighting* tileDeferredNode = static_cast<RCNodeTiledDeferredLighting*>(inputs.inputNodes[0]);
  454. output = tileDeferredNode->output;
  455. // If shadows are disabled we handle all lights through tiled deferred
  456. if (!inputs.view.getRenderSettings().enableShadows)
  457. return;
  458. GpuResourcePool& resPool = GpuResourcePool::instance();
  459. const RendererViewProperties& viewProps = inputs.view.getProperties();
  460. UINT32 width = viewProps.viewRect.width;
  461. UINT32 height = viewProps.viewRect.height;
  462. UINT32 numSamples = viewProps.numSamples;
  463. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  464. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[2]);
  465. // Allocate light occlusion
  466. SPtr<PooledRenderTexture> lightOcclusionTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width,
  467. height, TU_RENDERTARGET, numSamples, false));
  468. bool rebuildRT = false;
  469. if (mRenderTarget != nullptr)
  470. {
  471. rebuildRT |= mRenderTarget->getColorTexture(0) != lightOcclusionTex->texture;
  472. rebuildRT |= mRenderTarget->getDepthStencilTexture() != sceneDepthNode->depthTex->texture;
  473. }
  474. else
  475. rebuildRT = true;
  476. if (rebuildRT)
  477. {
  478. RENDER_TEXTURE_DESC lightOcclusionRTDesc;
  479. lightOcclusionRTDesc.colorSurfaces[0].texture = lightOcclusionTex->texture;
  480. lightOcclusionRTDesc.colorSurfaces[0].face = 0;
  481. lightOcclusionRTDesc.colorSurfaces[0].numFaces = 1;
  482. lightOcclusionRTDesc.colorSurfaces[0].mipLevel = 0;
  483. lightOcclusionRTDesc.depthStencilSurface.texture = sceneDepthNode->depthTex->texture;
  484. lightOcclusionRTDesc.depthStencilSurface.face = 0;
  485. lightOcclusionRTDesc.depthStencilSurface.numFaces = 1;
  486. lightOcclusionRTDesc.depthStencilSurface.mipLevel = 0;
  487. mRenderTarget = RenderTexture::create(lightOcclusionRTDesc);
  488. }
  489. GBufferTextures gbuffer;
  490. gbuffer.albedo = gbufferNode->albedoTex->texture;
  491. gbuffer.normals = gbufferNode->normalTex->texture;
  492. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  493. gbuffer.depth = sceneDepthNode->depthTex->texture;
  494. const VisibleLightData& lightData = inputs.viewGroup.getVisibleLightData();
  495. const ShadowRendering& shadowRenderer = inputs.viewGroup.getShadowRenderer();
  496. RenderAPI& rapi = RenderAPI::instance();
  497. for (UINT32 i = 0; i < (UINT32)LightType::Count; i++)
  498. {
  499. LightType lightType = (LightType)i;
  500. auto& lights = lightData.getLights(lightType);
  501. UINT32 count = lightData.getNumShadowedLights(lightType);
  502. UINT32 offset = lightData.getNumUnshadowedLights(lightType);
  503. for (UINT32 j = 0; j < count; j++)
  504. {
  505. rapi.setRenderTarget(mRenderTarget, FBT_DEPTH, RT_DEPTH_STENCIL);
  506. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  507. rapi.setViewport(area);
  508. rapi.clearViewport(FBT_COLOR, Color::ZERO);
  509. UINT32 lightIdx = offset + j;
  510. const RendererLight& light = *lights[lightIdx];
  511. shadowRenderer.renderShadowOcclusion(inputs.view, inputs.options.shadowFilteringQuality, light, gbuffer);
  512. rapi.setRenderTarget(output->renderTarget, FBT_DEPTH | FBT_STENCIL, RT_COLOR0 | RT_DEPTH_STENCIL);
  513. StandardDeferred::instance().renderLight(lightType, light, inputs.view, gbuffer,
  514. lightOcclusionTex->texture);
  515. }
  516. }
  517. // Makes sure light accumulation can be read by following passes
  518. rapi.setRenderTarget(nullptr);
  519. resPool.release(lightOcclusionTex);
  520. }
  521. void RCNodeStandardDeferredLighting::clear()
  522. {
  523. output = nullptr;
  524. }
  525. SmallVector<StringID, 4> RCNodeStandardDeferredLighting::getDependencies(const RendererView& view)
  526. {
  527. SmallVector<StringID, 4> deps;
  528. deps.push_back(RCNodeTiledDeferredLighting::getNodeId());
  529. deps.push_back(RCNodeGBuffer::getNodeId());
  530. deps.push_back(RCNodeSceneDepth::getNodeId());
  531. if (view.getProperties().numSamples > 1)
  532. deps.push_back(RCNodeUnflattenLightAccum::getNodeId());
  533. return deps;
  534. }
  535. void RCNodeUnflattenLightAccum::render(const RenderCompositorNodeInputs& inputs)
  536. {
  537. RCNodeLightAccumulation* lightAccumNode = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[0]);
  538. FlatFramebufferToTextureMat* material = FlatFramebufferToTextureMat::get();
  539. RenderAPI& rapi = RenderAPI::instance();
  540. rapi.setRenderTarget(lightAccumNode->renderTarget, FBT_DEPTH | FBT_STENCIL, RT_COLOR0 | RT_DEPTH_STENCIL);
  541. material->execute(lightAccumNode->flattenedLightAccumBuffer->buffer, lightAccumNode->lightAccumulationTex->texture);
  542. }
  543. void RCNodeUnflattenLightAccum::clear()
  544. {
  545. output = nullptr;
  546. }
  547. SmallVector<StringID, 4> RCNodeUnflattenLightAccum::getDependencies(const RendererView& view)
  548. {
  549. return { RCNodeLightAccumulation::getNodeId() };
  550. }
  551. void RCNodeIndirectLighting::render(const RenderCompositorNodeInputs& inputs)
  552. {
  553. if (!inputs.view.getRenderSettings().enableIndirectLighting)
  554. return;
  555. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[0]);
  556. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  557. RCNodeLightAccumulation* lightAccumNode = static_cast <RCNodeLightAccumulation*>(inputs.inputNodes[2]);
  558. SPtr<Texture> ssao;
  559. if (inputs.view.getRenderSettings().ambientOcclusion.enabled)
  560. {
  561. RCNodeSSAO* ssaoNode = static_cast<RCNodeSSAO*>(inputs.inputNodes[4]);
  562. ssao = ssaoNode->output->texture;
  563. }
  564. else
  565. ssao = Texture::WHITE;
  566. GpuResourcePool& resPool = GpuResourcePool::instance();
  567. const RendererViewProperties& viewProps = inputs.view.getProperties();
  568. const LightProbes& lightProbes = inputs.scene.lightProbes;
  569. LightProbesInfo lpInfo = lightProbes.getInfo();
  570. IrradianceEvaluateMat* evaluateMat;
  571. SPtr<PooledRenderTexture> volumeIndices;
  572. if(lightProbes.hasAnyProbes())
  573. {
  574. POOLED_RENDER_TEXTURE_DESC volumeIndicesDesc;
  575. POOLED_RENDER_TEXTURE_DESC depthDesc;
  576. TetrahedraRenderMat::getOutputDesc(inputs.view, volumeIndicesDesc, depthDesc);
  577. volumeIndices = resPool.get(volumeIndicesDesc);
  578. SPtr<PooledRenderTexture> depthTex = resPool.get(depthDesc);
  579. RENDER_TEXTURE_DESC rtDesc;
  580. rtDesc.colorSurfaces[0].texture = volumeIndices->texture;
  581. rtDesc.depthStencilSurface.texture = depthTex->texture;
  582. SPtr<RenderTexture> rt = RenderTexture::create(rtDesc);
  583. RenderAPI& rapi = RenderAPI::instance();
  584. rapi.setRenderTarget(rt);
  585. rapi.clearRenderTarget(FBT_DEPTH);
  586. gRendererUtility().clear(-1);
  587. TetrahedraRenderMat* renderTetrahedra = TetrahedraRenderMat::getVariation(viewProps.numSamples > 1);
  588. renderTetrahedra->execute(inputs.view, sceneDepthNode->depthTex->texture, lpInfo.tetrahedraVolume, rt);
  589. rt = nullptr;
  590. resPool.release(depthTex);
  591. evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples, false);
  592. }
  593. else // Sky only
  594. {
  595. evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples, true);
  596. }
  597. GBufferTextures gbuffer;
  598. gbuffer.albedo = gbufferNode->albedoTex->texture;
  599. gbuffer.normals = gbufferNode->normalTex->texture;
  600. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  601. gbuffer.depth = sceneDepthNode->depthTex->texture;
  602. SPtr<Texture> volumeIndicesTex;
  603. if (volumeIndices)
  604. volumeIndicesTex = volumeIndices->texture;
  605. evaluateMat->execute(inputs.view, gbuffer, volumeIndicesTex, lpInfo, inputs.scene.skybox, ssao,
  606. lightAccumNode->renderTarget);
  607. if(volumeIndices)
  608. resPool.release(volumeIndices);
  609. }
  610. void RCNodeIndirectLighting::clear()
  611. {
  612. // Do nothing
  613. }
  614. SmallVector<StringID, 4> RCNodeIndirectLighting::getDependencies(const RendererView& view)
  615. {
  616. SmallVector<StringID, 4> deps;
  617. deps.push_back(RCNodeGBuffer::getNodeId());
  618. deps.push_back(RCNodeSceneDepth::getNodeId());
  619. deps.push_back(RCNodeLightAccumulation::getNodeId());
  620. deps.push_back(RCNodeStandardDeferredLighting::getNodeId());
  621. if(view.getRenderSettings().ambientOcclusion.enabled)
  622. deps.push_back(RCNodeSSAO::getNodeId());
  623. if (view.getProperties().numSamples > 1)
  624. deps.push_back(RCNodeUnflattenLightAccum::getNodeId());
  625. return deps;
  626. }
  627. void RCNodeTiledDeferredIBL::render(const RenderCompositorNodeInputs& inputs)
  628. {
  629. const RenderSettings& rs = inputs.view.getRenderSettings();
  630. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  631. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  632. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[2]);
  633. RCNodeLightAccumulation* lightAccumNode = static_cast <RCNodeLightAccumulation*>(inputs.inputNodes[3]);
  634. SPtr<Texture> ssr;
  635. if (rs.screenSpaceReflections.enabled)
  636. {
  637. RCNodeSSR* ssrNode = static_cast<RCNodeSSR*>(inputs.inputNodes[5]);
  638. ssr = ssrNode->output->texture;
  639. }
  640. else
  641. ssr = Texture::BLACK;
  642. UINT32 nodeIdx = 6;
  643. SPtr<Texture> ssao;
  644. if (rs.ambientOcclusion.enabled)
  645. {
  646. RCNodeSSAO* ssaoNode = static_cast<RCNodeSSAO*>(inputs.inputNodes[nodeIdx++]);
  647. ssao = ssaoNode->output->texture;
  648. }
  649. else
  650. ssao = Texture::WHITE;
  651. const RendererViewProperties& viewProps = inputs.view.getProperties();
  652. SPtr<Texture> msaaCoverage;
  653. if(viewProps.numSamples > 1)
  654. {
  655. RCNodeMSAACoverage* coverageNode = static_cast<RCNodeMSAACoverage*>(inputs.inputNodes[nodeIdx++]);
  656. msaaCoverage = coverageNode->output->texture;
  657. }
  658. TiledDeferredImageBasedLightingMat* material = TiledDeferredImageBasedLightingMat::getVariation(viewProps.numSamples);
  659. TiledDeferredImageBasedLightingMat::Inputs iblInputs;
  660. iblInputs.gbuffer.albedo = gbufferNode->albedoTex->texture;
  661. iblInputs.gbuffer.normals = gbufferNode->normalTex->texture;
  662. iblInputs.gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  663. iblInputs.gbuffer.depth = sceneDepthNode->depthTex->texture;
  664. iblInputs.sceneColorTex = sceneColorNode->sceneColorTex->texture;
  665. iblInputs.lightAccumulation = lightAccumNode->lightAccumulationTex->texture;
  666. iblInputs.preIntegratedGF = RendererTextures::preintegratedEnvGF;
  667. iblInputs.ambientOcclusion = ssao;
  668. iblInputs.ssr = ssr;
  669. iblInputs.msaaCoverage = msaaCoverage;
  670. if(sceneColorNode->flattenedSceneColorBuffer)
  671. iblInputs.sceneColorBuffer = sceneColorNode->flattenedSceneColorBuffer->buffer;
  672. material->execute(inputs.view, inputs.scene, inputs.viewGroup.getVisibleReflProbeData(), iblInputs);
  673. }
  674. void RCNodeTiledDeferredIBL::clear()
  675. {
  676. output = nullptr;
  677. }
  678. SmallVector<StringID, 4> RCNodeTiledDeferredIBL::getDependencies(const RendererView& view)
  679. {
  680. SmallVector<StringID, 4> deps;
  681. deps.push_back(RCNodeSceneColor::getNodeId());
  682. deps.push_back(RCNodeGBuffer::getNodeId());
  683. deps.push_back(RCNodeSceneDepth::getNodeId());
  684. deps.push_back(RCNodeLightAccumulation::getNodeId());
  685. deps.push_back(RCNodeIndirectLighting::getNodeId());
  686. deps.push_back(RCNodeSSR::getNodeId());
  687. if(view.getRenderSettings().ambientOcclusion.enabled)
  688. deps.push_back(RCNodeSSAO::getNodeId());
  689. if(view.getProperties().numSamples > 1)
  690. deps.push_back(RCNodeMSAACoverage::getNodeId());
  691. return deps;
  692. }
  693. void RCNodeUnflattenSceneColor::render(const RenderCompositorNodeInputs& inputs)
  694. {
  695. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  696. FlatFramebufferToTextureMat* material = FlatFramebufferToTextureMat::get();
  697. int readOnlyFlags = FBT_DEPTH | FBT_STENCIL;
  698. RenderAPI& rapi = RenderAPI::instance();
  699. rapi.setRenderTarget(sceneColorNode->renderTarget, readOnlyFlags, RT_COLOR0 | RT_DEPTH_STENCIL);
  700. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  701. rapi.setViewport(area);
  702. material->execute(sceneColorNode->flattenedSceneColorBuffer->buffer, sceneColorNode->sceneColorTex->texture);
  703. }
  704. void RCNodeUnflattenSceneColor::clear()
  705. {
  706. output = nullptr;
  707. }
  708. SmallVector<StringID, 4> RCNodeUnflattenSceneColor::getDependencies(const RendererView& view)
  709. {
  710. return { RCNodeSceneColor::getNodeId() };
  711. }
  712. void RCNodeClusteredForward::render(const RenderCompositorNodeInputs& inputs)
  713. {
  714. const SceneInfo& sceneInfo = inputs.scene;
  715. const RendererViewProperties& viewProps = inputs.view.getProperties();
  716. const VisibleLightData& visibleLightData = inputs.viewGroup.getVisibleLightData();
  717. const VisibleReflProbeData& visibleReflProbeData = inputs.viewGroup.getVisibleReflProbeData();
  718. const LightGrid& lightGrid = inputs.view.getLightGrid();
  719. SPtr<GpuParamBlockBuffer> gridParams;
  720. SPtr<GpuBuffer> gridLightOffsetsAndSize, gridLightIndices;
  721. SPtr<GpuBuffer> gridProbeOffsetsAndSize, gridProbeIndices;
  722. lightGrid.getOutputs(gridLightOffsetsAndSize, gridLightIndices, gridProbeOffsetsAndSize, gridProbeIndices,
  723. gridParams);
  724. // Prepare refl. probe param buffer
  725. ReflProbeParamBuffer reflProbeParamBuffer;
  726. reflProbeParamBuffer.populate(sceneInfo.skybox, visibleReflProbeData, sceneInfo.reflProbeCubemapsTex,
  727. viewProps.renderingReflections);
  728. SPtr<Texture> skyFilteredRadiance;
  729. if(sceneInfo.skybox)
  730. skyFilteredRadiance = sceneInfo.skybox->getFilteredRadiance();
  731. // Prepare objects for rendering
  732. const VisibilityInfo& visibility = inputs.view.getVisibilityMasks();
  733. UINT32 numRenderables = (UINT32)sceneInfo.renderables.size();
  734. for (UINT32 i = 0; i < numRenderables; i++)
  735. {
  736. if (!visibility.renderables[i])
  737. continue;
  738. for (auto& element : sceneInfo.renderables[i]->elements)
  739. {
  740. bool isTransparent = (element.material->getShader()->getFlags() & (UINT32)ShaderFlags::Transparent) != 0;
  741. if (!isTransparent)
  742. continue;
  743. // Note: It would be nice to be able to set this once and keep it, only updating if the buffers actually
  744. // change (e.g. when growing). Although technically the internal systems should be smart enough to
  745. // avoid updates unless objects actually changed.
  746. if (element.gridParamsBindingIdx != -1)
  747. element.params->setParamBlockBuffer(element.gridParamsBindingIdx, gridParams, true);
  748. element.gridLightOffsetsAndSizeParam.set(gridLightOffsetsAndSize);
  749. element.gridLightIndicesParam.set(gridLightIndices);
  750. element.lightsBufferParam.set(visibleLightData.getLightBuffer());
  751. // Image based lighting params
  752. ImageBasedLightingParams& iblParams = element.imageBasedParams;
  753. if (iblParams.reflProbeParamsBindingIdx != -1)
  754. element.params->setParamBlockBuffer(iblParams.reflProbeParamsBindingIdx, reflProbeParamBuffer.buffer);
  755. element.gridProbeOffsetsAndSizeParam.set(gridProbeOffsetsAndSize);
  756. iblParams.reflectionProbeIndicesParam.set(gridProbeIndices);
  757. iblParams.reflectionProbesParam.set(visibleReflProbeData.getProbeBuffer());
  758. iblParams.skyReflectionsTexParam.set(skyFilteredRadiance);
  759. iblParams.ambientOcclusionTexParam.set(Texture::WHITE); // Note: Add SSAO here?
  760. iblParams.ssrTexParam.set(Texture::BLACK); // Note: Add SSR here?
  761. iblParams.reflectionProbeCubemapsTexParam.set(sceneInfo.reflProbeCubemapsTex);
  762. iblParams.preintegratedEnvBRDFParam.set(RendererTextures::preintegratedEnvGF);
  763. }
  764. }
  765. // TODO: Transparent objects cannot receive shadows. In order to support this I'd have to render the light occlusion
  766. // for all lights affecting this object into a single (or a few) textures. I can likely use texture arrays for this,
  767. // or to avoid sampling many textures, perhaps just jam it all in one or few texture channels.
  768. const Vector<RenderQueueElement>& transparentElements = inputs.view.getTransparentQueue()->getSortedElements();
  769. for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
  770. {
  771. BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
  772. SPtr<Material> material = renderElem->material;
  773. if (iter->applyPass)
  774. gRendererUtility().setPass(material, iter->passIdx, renderElem->techniqueIdx);
  775. gRendererUtility().setPassParams(renderElem->params, iter->passIdx);
  776. if(renderElem->morphVertexDeclaration == nullptr)
  777. gRendererUtility().draw(renderElem->mesh, renderElem->subMesh);
  778. else
  779. gRendererUtility().drawMorph(renderElem->mesh, renderElem->subMesh, renderElem->morphShapeBuffer,
  780. renderElem->morphVertexDeclaration);
  781. }
  782. // Trigger post-lighting callbacks
  783. Camera* sceneCamera = inputs.view.getSceneCamera();
  784. if (sceneCamera != nullptr)
  785. {
  786. for(auto& extension : inputs.extPostLighting)
  787. {
  788. if (extension->check(*sceneCamera))
  789. extension->render(*sceneCamera);
  790. }
  791. }
  792. }
  793. void RCNodeClusteredForward::clear()
  794. {
  795. // Do nothing
  796. }
  797. SmallVector<StringID, 4> RCNodeClusteredForward::getDependencies(const RendererView& view)
  798. {
  799. return { RCNodeSceneColor::getNodeId(), RCNodeSkybox::getNodeId() };
  800. }
  801. void RCNodeSkybox::render(const RenderCompositorNodeInputs& inputs)
  802. {
  803. Skybox* skybox = inputs.scene.skybox;
  804. SPtr<Texture> radiance = skybox ? skybox->getTexture() : nullptr;
  805. if (radiance != nullptr)
  806. {
  807. SkyboxMat* material = SkyboxMat::getVariation(false);
  808. material->bind(inputs.view.getPerViewBuffer());
  809. material->setParams(radiance, Color::White);
  810. }
  811. else
  812. {
  813. Color clearColor = inputs.view.getProperties().clearColor;
  814. SkyboxMat* material = SkyboxMat::getVariation(true);
  815. material->bind(inputs.view.getPerViewBuffer());
  816. material->setParams(nullptr, clearColor);
  817. }
  818. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[1]);
  819. int readOnlyFlags = FBT_DEPTH | FBT_STENCIL;
  820. RenderAPI& rapi = RenderAPI::instance();
  821. rapi.setRenderTarget(sceneColorNode->renderTarget, readOnlyFlags, RT_COLOR0 | RT_DEPTH_STENCIL);
  822. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  823. rapi.setViewport(area);
  824. SPtr<Mesh> mesh = gRendererUtility().getSkyBoxMesh();
  825. gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
  826. }
  827. void RCNodeSkybox::clear()
  828. { }
  829. SmallVector<StringID, 4> RCNodeSkybox::getDependencies(const RendererView& view)
  830. {
  831. SmallVector<StringID, 4> deps;
  832. deps.push_back(RCNodeTiledDeferredIBL::getNodeId());
  833. deps.push_back(RCNodeSceneColor::getNodeId());
  834. if (view.getProperties().numSamples > 1)
  835. deps.push_back(RCNodeUnflattenSceneColor::getNodeId());
  836. return deps;
  837. }
  838. void RCNodeFinalResolve::render(const RenderCompositorNodeInputs& inputs)
  839. {
  840. const RendererViewProperties& viewProps = inputs.view.getProperties();
  841. SPtr<Texture> input;
  842. if(viewProps.runPostProcessing)
  843. {
  844. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[0]);
  845. // Note: Ideally the last PP effect could write directly to the final target and we could avoid this copy
  846. input = postProcessNode->getLastOutput();
  847. }
  848. else
  849. {
  850. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  851. input = sceneColorNode->sceneColorTex->texture;
  852. }
  853. SPtr<RenderTarget> target = viewProps.target;
  854. RenderAPI& rapi = RenderAPI::instance();
  855. rapi.setRenderTarget(target);
  856. rapi.setViewport(viewProps.nrmViewRect);
  857. gRendererUtility().blit(input, Rect2I::EMPTY, viewProps.flipView);
  858. if(viewProps.encodeDepth)
  859. {
  860. RCNodeResolvedSceneDepth* resolvedSceneDepthNode = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[0]);
  861. EncodeDepthMat* encodeDepthMat = EncodeDepthMat::get();
  862. encodeDepthMat->execute(resolvedSceneDepthNode->output->texture, viewProps.depthEncodeNear,
  863. viewProps.depthEncodeFar, target);
  864. }
  865. // Trigger overlay callbacks
  866. Camera* sceneCamera = inputs.view.getSceneCamera();
  867. if (sceneCamera != nullptr)
  868. {
  869. for(auto& extension : inputs.extOverlay)
  870. {
  871. if (extension->check(*sceneCamera))
  872. extension->render(*sceneCamera);
  873. }
  874. }
  875. }
  876. void RCNodeFinalResolve::clear()
  877. { }
  878. SmallVector<StringID, 4> RCNodeFinalResolve::getDependencies(const RendererView& view)
  879. {
  880. const RendererViewProperties& viewProps = view.getProperties();
  881. SmallVector<StringID, 4> deps;
  882. if(viewProps.runPostProcessing)
  883. {
  884. deps.push_back(RCNodePostProcess::getNodeId());
  885. deps.push_back(RCNodeFXAA::getNodeId());
  886. }
  887. else
  888. {
  889. deps.push_back(RCNodeSceneColor::getNodeId());
  890. deps.push_back(RCNodeClusteredForward::getNodeId());
  891. }
  892. if(viewProps.encodeDepth)
  893. deps.push_back(RCNodeResolvedSceneDepth::getNodeId());
  894. return deps;
  895. }
  896. RCNodePostProcess::RCNodePostProcess()
  897. :mOutput(), mAllocated()
  898. { }
  899. void RCNodePostProcess::getAndSwitch(const RendererView& view, SPtr<RenderTexture>& output, SPtr<Texture>& lastFrame) const
  900. {
  901. GpuResourcePool& resPool = GpuResourcePool::instance();
  902. const RendererViewProperties& viewProps = view.getProperties();
  903. UINT32 width = viewProps.viewRect.width;
  904. UINT32 height = viewProps.viewRect.height;
  905. if(!mAllocated[mCurrentIdx])
  906. {
  907. mOutput[mCurrentIdx] = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA8, width, height,
  908. TU_RENDERTARGET, 1, false));
  909. mAllocated[mCurrentIdx] = true;
  910. }
  911. output = mOutput[mCurrentIdx]->renderTexture;
  912. UINT32 otherIdx = (mCurrentIdx + 1) % 2;
  913. if (mAllocated[otherIdx])
  914. lastFrame = mOutput[otherIdx]->texture;
  915. mCurrentIdx = otherIdx;
  916. }
  917. SPtr<Texture> RCNodePostProcess::getLastOutput() const
  918. {
  919. UINT32 otherIdx = (mCurrentIdx + 1) % 2;
  920. if (mAllocated[otherIdx])
  921. return mOutput[otherIdx]->texture;
  922. return nullptr;
  923. }
  924. void RCNodePostProcess::render(const RenderCompositorNodeInputs& inputs)
  925. {
  926. // Do nothing, this is just a helper node
  927. }
  928. void RCNodePostProcess::clear()
  929. {
  930. GpuResourcePool& resPool = GpuResourcePool::instance();
  931. if (mAllocated[0])
  932. resPool.release(mOutput[0]);
  933. if (mAllocated[1])
  934. resPool.release(mOutput[1]);
  935. mAllocated[0] = false;
  936. mAllocated[1] = false;
  937. mCurrentIdx = 0;
  938. }
  939. SmallVector<StringID, 4> RCNodePostProcess::getDependencies(const RendererView& view)
  940. {
  941. return {};
  942. }
  943. RCNodeTonemapping::~RCNodeTonemapping()
  944. {
  945. GpuResourcePool& resPool = GpuResourcePool::instance();
  946. if (mTonemapLUT)
  947. resPool.release(mTonemapLUT);
  948. if (prevEyeAdaptation)
  949. resPool.release(prevEyeAdaptation);
  950. }
  951. void RCNodeTonemapping::render(const RenderCompositorNodeInputs& inputs)
  952. {
  953. GpuResourcePool& resPool = GpuResourcePool::instance();
  954. const RendererViewProperties& viewProps = inputs.view.getProperties();
  955. const RenderSettings& settings = inputs.view.getRenderSettings();
  956. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  957. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[2]);
  958. SPtr<Texture> sceneColor = sceneColorNode->sceneColorTex->texture;
  959. bool hdr = settings.enableHDR;
  960. bool msaa = viewProps.numSamples > 1;
  961. if(hdr && settings.enableAutoExposure)
  962. {
  963. // Downsample scene
  964. DownsampleMat* downsampleMat = DownsampleMat::getVariation(1, msaa);
  965. SPtr<PooledRenderTexture> downsampledScene = resPool.get(DownsampleMat::getOutputDesc(sceneColor));
  966. downsampleMat->execute(sceneColor, downsampledScene->renderTexture);
  967. // Generate histogram
  968. SPtr<PooledRenderTexture> eyeAdaptHistogram = resPool.get(
  969. EyeAdaptHistogramMat::getOutputDesc(downsampledScene->texture));
  970. EyeAdaptHistogramMat* eyeAdaptHistogramMat = EyeAdaptHistogramMat::get();
  971. eyeAdaptHistogramMat->execute(downsampledScene->texture, eyeAdaptHistogram->texture, settings.autoExposure);
  972. // Reduce histogram
  973. SPtr<PooledRenderTexture> reducedHistogram = resPool.get(EyeAdaptHistogramReduceMat::getOutputDesc());
  974. SPtr<Texture> prevFrameEyeAdaptation;
  975. if (prevEyeAdaptation != nullptr)
  976. prevFrameEyeAdaptation = prevEyeAdaptation->texture;
  977. EyeAdaptHistogramReduceMat* eyeAdaptHistogramReduce = EyeAdaptHistogramReduceMat::get();
  978. eyeAdaptHistogramReduce->execute(downsampledScene->texture, eyeAdaptHistogram->texture,
  979. prevFrameEyeAdaptation, reducedHistogram->renderTexture);
  980. resPool.release(downsampledScene);
  981. downsampledScene = nullptr;
  982. resPool.release(eyeAdaptHistogram);
  983. eyeAdaptHistogram = nullptr;
  984. // Generate eye adaptation value
  985. eyeAdaptation = resPool.get(EyeAdaptationMat::getOutputDesc());
  986. EyeAdaptationMat* eyeAdaptationMat = EyeAdaptationMat::get();
  987. eyeAdaptationMat->execute(reducedHistogram->texture, eyeAdaptation->renderTexture, inputs.frameInfo.timeDelta,
  988. settings.autoExposure, settings.exposureScale);
  989. resPool.release(reducedHistogram);
  990. reducedHistogram = nullptr;
  991. }
  992. else
  993. {
  994. if(prevEyeAdaptation)
  995. resPool.release(prevEyeAdaptation);
  996. prevEyeAdaptation = nullptr;
  997. eyeAdaptation = nullptr;
  998. }
  999. bool gammaOnly;
  1000. bool autoExposure;
  1001. if (hdr)
  1002. {
  1003. if (settings.enableTonemapping)
  1004. {
  1005. UINT64 latestHash = inputs.view.getRenderSettingsHash();
  1006. bool tonemapLUTDirty = mTonemapLastUpdateHash != latestHash;
  1007. if (tonemapLUTDirty) // Rebuild LUT if PP settings changed
  1008. {
  1009. if(mTonemapLUT == nullptr)
  1010. mTonemapLUT = resPool.get(CreateTonemapLUTMat::getOutputDesc());
  1011. CreateTonemapLUTMat* createLUT = CreateTonemapLUTMat::get();
  1012. createLUT->execute(mTonemapLUT->texture, settings);
  1013. mTonemapLastUpdateHash = latestHash;
  1014. }
  1015. gammaOnly = false;
  1016. }
  1017. else
  1018. gammaOnly = true;
  1019. autoExposure = settings.enableAutoExposure;
  1020. }
  1021. else
  1022. {
  1023. gammaOnly = true;
  1024. autoExposure = false;
  1025. }
  1026. if(gammaOnly)
  1027. {
  1028. if(mTonemapLUT)
  1029. {
  1030. resPool.release(mTonemapLUT);
  1031. mTonemapLUT = nullptr;
  1032. }
  1033. }
  1034. TonemappingMat* tonemapping = TonemappingMat::getVariation(gammaOnly, autoExposure, msaa);
  1035. SPtr<RenderTexture> ppOutput;
  1036. SPtr<Texture> ppLastFrame;
  1037. postProcessNode->getAndSwitch(inputs.view, ppOutput, ppLastFrame);
  1038. SPtr<Texture> eyeAdaptationTex;
  1039. if (eyeAdaptation)
  1040. eyeAdaptationTex = eyeAdaptation->texture;
  1041. SPtr<Texture> tonemapLUTTex;
  1042. if (mTonemapLUT)
  1043. tonemapLUTTex = mTonemapLUT->texture;
  1044. tonemapping->execute(sceneColor, eyeAdaptationTex, tonemapLUTTex, ppOutput, settings);
  1045. }
  1046. void RCNodeTonemapping::clear()
  1047. {
  1048. GpuResourcePool& resPool = GpuResourcePool::instance();
  1049. // Save eye adaptation for next frame
  1050. if(prevEyeAdaptation)
  1051. resPool.release(prevEyeAdaptation);
  1052. std::swap(eyeAdaptation, prevEyeAdaptation);
  1053. }
  1054. SmallVector<StringID, 4> RCNodeTonemapping::getDependencies(const RendererView& view)
  1055. {
  1056. return{ RCNodeSceneColor::getNodeId(), RCNodeClusteredForward::getNodeId(), RCNodePostProcess::getNodeId() };
  1057. }
  1058. void RCNodeGaussianDOF::render(const RenderCompositorNodeInputs& inputs)
  1059. {
  1060. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  1061. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[2]);
  1062. const DepthOfFieldSettings& settings = inputs.view.getRenderSettings().depthOfField;
  1063. bool near = settings.nearBlurAmount > 0.0f;
  1064. bool far = settings.farBlurAmount > 0.0f;
  1065. bool enabled = settings.enabled && (near || far);
  1066. if(!enabled)
  1067. return;
  1068. GaussianDOFSeparateMat* separateMat = GaussianDOFSeparateMat::getVariation(near, far);
  1069. GaussianDOFCombineMat* combineMat = GaussianDOFCombineMat::getVariation(near, far);
  1070. GaussianBlurMat* blurMat = GaussianBlurMat::get();
  1071. SPtr<RenderTexture> ppOutput;
  1072. SPtr<Texture> ppLastFrame;
  1073. postProcessNode->getAndSwitch(inputs.view, ppOutput, ppLastFrame);
  1074. separateMat->execute(ppLastFrame, sceneDepthNode->depthTex->texture, inputs.view, settings);
  1075. SPtr<PooledRenderTexture> nearTex, farTex;
  1076. if(near && far)
  1077. {
  1078. nearTex = separateMat->getOutput(0);
  1079. farTex = separateMat->getOutput(1);
  1080. }
  1081. else
  1082. {
  1083. if (near)
  1084. nearTex = separateMat->getOutput(0);
  1085. else
  1086. farTex = separateMat->getOutput(0);
  1087. }
  1088. // Blur the out of focus pixels
  1089. // Note: Perhaps set up stencil so I can avoid performing blur on unused parts of the textures?
  1090. const TextureProperties& texProps = nearTex ? nearTex->texture->getProperties() : farTex->texture->getProperties();
  1091. POOLED_RENDER_TEXTURE_DESC tempTexDesc = POOLED_RENDER_TEXTURE_DESC::create2D(texProps.getFormat(),
  1092. texProps.getWidth(), texProps.getHeight(), TU_RENDERTARGET);
  1093. SPtr<PooledRenderTexture> tempTexture = GpuResourcePool::instance().get(tempTexDesc);
  1094. SPtr<Texture> blurredNearTex;
  1095. if(nearTex)
  1096. {
  1097. blurMat->execute(nearTex->texture, settings.nearBlurAmount, tempTexture->renderTexture);
  1098. blurredNearTex = tempTexture->texture;
  1099. }
  1100. SPtr<Texture> blurredFarTex;
  1101. if(farTex)
  1102. {
  1103. // If temporary texture is used up, re-use the original near texture for the blurred result
  1104. if(blurredNearTex)
  1105. {
  1106. blurMat->execute(farTex->texture, settings.farBlurAmount, nearTex->renderTexture);
  1107. blurredFarTex = nearTex->texture;
  1108. }
  1109. else // Otherwise just use the temporary
  1110. {
  1111. blurMat->execute(farTex->texture, settings.farBlurAmount, tempTexture->renderTexture);
  1112. blurredFarTex = tempTexture->texture;
  1113. }
  1114. }
  1115. combineMat->execute(ppLastFrame, blurredNearTex, blurredFarTex,
  1116. sceneDepthNode->depthTex->texture, ppOutput, inputs.view, settings);
  1117. separateMat->release();
  1118. GpuResourcePool::instance().release(tempTexture);
  1119. }
  1120. void RCNodeGaussianDOF::clear()
  1121. {
  1122. // Do nothing
  1123. }
  1124. SmallVector<StringID, 4> RCNodeGaussianDOF::getDependencies(const RendererView& view)
  1125. {
  1126. return { RCNodeTonemapping::getNodeId(), RCNodeSceneDepth::getNodeId(), RCNodePostProcess::getNodeId() };
  1127. }
  1128. void RCNodeFXAA::render(const RenderCompositorNodeInputs& inputs)
  1129. {
  1130. const RenderSettings& settings = inputs.view.getRenderSettings();
  1131. if (!settings.enableFXAA)
  1132. return;
  1133. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[1]);
  1134. SPtr<RenderTexture> ppOutput;
  1135. SPtr<Texture> ppLastFrame;
  1136. postProcessNode->getAndSwitch(inputs.view, ppOutput, ppLastFrame);
  1137. // Note: I could skip executing FXAA over DOF and motion blurred pixels
  1138. FXAAMat* fxaa = FXAAMat::get();
  1139. fxaa->execute(ppLastFrame, ppOutput);
  1140. }
  1141. void RCNodeFXAA::clear()
  1142. {
  1143. // Do nothing
  1144. }
  1145. SmallVector<StringID, 4> RCNodeFXAA::getDependencies(const RendererView& view)
  1146. {
  1147. return { RCNodeGaussianDOF::getNodeId(), RCNodePostProcess::getNodeId() };
  1148. }
  1149. void RCNodeResolvedSceneDepth::render(const RenderCompositorNodeInputs& inputs)
  1150. {
  1151. GpuResourcePool& resPool = GpuResourcePool::instance();
  1152. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1153. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  1154. if (viewProps.numSamples > 1)
  1155. {
  1156. UINT32 width = viewProps.viewRect.width;
  1157. UINT32 height = viewProps.viewRect.height;
  1158. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_D32_S8X24, width, height,
  1159. TU_DEPTHSTENCIL, 1, false));
  1160. RenderAPI& rapi = RenderAPI::instance();
  1161. rapi.setRenderTarget(output->renderTexture);
  1162. rapi.clearRenderTarget(FBT_STENCIL);
  1163. gRendererUtility().blit(sceneDepthNode->depthTex->texture, Rect2I::EMPTY, false, true);
  1164. mPassThrough = false;
  1165. }
  1166. else
  1167. {
  1168. output = sceneDepthNode->depthTex;
  1169. mPassThrough = true;
  1170. }
  1171. }
  1172. void RCNodeResolvedSceneDepth::clear()
  1173. {
  1174. GpuResourcePool& resPool = GpuResourcePool::instance();
  1175. if (!mPassThrough)
  1176. resPool.release(output);
  1177. else
  1178. output = nullptr;
  1179. mPassThrough = false;
  1180. }
  1181. SmallVector<StringID, 4> RCNodeResolvedSceneDepth::getDependencies(const RendererView& view)
  1182. {
  1183. // GBuffer require because it renders the base pass (populates the depth buffer)
  1184. return { RCNodeSceneDepth::getNodeId(), RCNodeGBuffer::getNodeId() };
  1185. }
  1186. void RCNodeHiZ::render(const RenderCompositorNodeInputs& inputs)
  1187. {
  1188. GpuResourcePool& resPool = GpuResourcePool::instance();
  1189. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1190. RCNodeResolvedSceneDepth* resolvedSceneDepth = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[0]);
  1191. UINT32 width = viewProps.viewRect.width;
  1192. UINT32 height = viewProps.viewRect.height;
  1193. UINT32 size = Bitwise::nextPow2(std::max(width, height));
  1194. UINT32 numMips = PixelUtil::getMaxMipmaps(size, size, 1, PF_R32F);
  1195. size = 1 << numMips;
  1196. // Note: Use the 32-bit buffer here as 16-bit causes too much banding (most of the scene gets assigned 4-5 different
  1197. // depth values).
  1198. // - When I add UNORM 16-bit format I should be able to switch to that
  1199. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R32F, size, size, TU_RENDERTARGET, 1, false, 1,
  1200. numMips));
  1201. Rect2 srcRect = viewProps.nrmViewRect;
  1202. // If viewport size is odd, adjust UV
  1203. srcRect.width += (viewProps.viewRect.width % 2) * (1.0f / viewProps.viewRect.width);
  1204. srcRect.height += (viewProps.viewRect.height % 2) * (1.0f / viewProps.viewRect.height);
  1205. // Generate first mip
  1206. RENDER_TEXTURE_DESC rtDesc;
  1207. rtDesc.colorSurfaces[0].texture = output->texture;
  1208. rtDesc.colorSurfaces[0].mipLevel = 0;
  1209. SPtr<RenderTexture> rt = RenderTexture::create(rtDesc);
  1210. Rect2 destRect;
  1211. bool downsampledFirstMip = false; // Not used currently
  1212. if (downsampledFirstMip)
  1213. {
  1214. // Make sure that 1 pixel in HiZ maps to a 2x2 block in source
  1215. destRect = Rect2(0, 0,
  1216. Math::ceilToInt(viewProps.viewRect.width / 2.0f) / (float)size,
  1217. Math::ceilToInt(viewProps.viewRect.height / 2.0f) / (float)size);
  1218. BuildHiZMat* material = BuildHiZMat::get();
  1219. material->execute(resolvedSceneDepth->output->texture, 0, srcRect, destRect, rt);
  1220. }
  1221. else // First level is just a copy of the depth buffer
  1222. {
  1223. destRect = Rect2(0, 0,
  1224. viewProps.viewRect.width / (float)size,
  1225. viewProps.viewRect.height / (float)size);
  1226. RenderAPI& rapi = RenderAPI::instance();
  1227. rapi.setRenderTarget(rt);
  1228. rapi.setViewport(destRect);
  1229. Rect2I srcAreaInt;
  1230. srcAreaInt.x = (INT32)(srcRect.x * viewProps.viewRect.width);
  1231. srcAreaInt.y = (INT32)(srcRect.y * viewProps.viewRect.height);
  1232. srcAreaInt.width = (UINT32)(srcRect.width * viewProps.viewRect.width);
  1233. srcAreaInt.height = (UINT32)(srcRect.height * viewProps.viewRect.height);
  1234. gRendererUtility().blit(resolvedSceneDepth->output->texture, srcAreaInt);
  1235. rapi.setViewport(Rect2(0, 0, 1, 1));
  1236. }
  1237. // Generate remaining mip levels
  1238. for(UINT32 i = 1; i <= numMips; i++)
  1239. {
  1240. rtDesc.colorSurfaces[0].mipLevel = i;
  1241. rt = RenderTexture::create(rtDesc);
  1242. BuildHiZMat* material = BuildHiZMat::get();
  1243. material->execute(output->texture, i - 1, destRect, destRect, rt);
  1244. }
  1245. }
  1246. void RCNodeHiZ::clear()
  1247. {
  1248. GpuResourcePool& resPool = GpuResourcePool::instance();
  1249. resPool.release(output);
  1250. }
  1251. SmallVector<StringID, 4> RCNodeHiZ::getDependencies(const RendererView& view)
  1252. {
  1253. // Note: This doesn't actually use any gbuffer textures, but node is a dependency because it renders to the depth
  1254. // buffer. In order to avoid keeping gbuffer textures alive I could separate out the base pass into its own node
  1255. // perhaps. But at the moment it doesn't matter, as anything using HiZ also needs gbuffer.
  1256. return { RCNodeResolvedSceneDepth::getNodeId(), RCNodeGBuffer::getNodeId() };
  1257. }
  1258. void RCNodeSSAO::render(const RenderCompositorNodeInputs& inputs)
  1259. {
  1260. /** Maximum valid depth range within samples in a sample set. In meters. */
  1261. static const float DEPTH_RANGE = 1.0f;
  1262. GpuResourcePool& resPool = GpuResourcePool::instance();
  1263. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1264. const AmbientOcclusionSettings& settings = inputs.view.getRenderSettings().ambientOcclusion;
  1265. RCNodeResolvedSceneDepth* resolvedDepthNode = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[0]);
  1266. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  1267. SPtr<Texture> sceneDepth = resolvedDepthNode->output->texture;
  1268. SPtr<Texture> sceneNormals = gbufferNode->normalTex->texture;
  1269. const TextureProperties& normalsProps = sceneNormals->getProperties();
  1270. SPtr<PooledRenderTexture> resolvedNormals;
  1271. RenderAPI& rapi = RenderAPI::instance();
  1272. if(sceneNormals->getProperties().getNumSamples() > 1)
  1273. {
  1274. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(normalsProps.getFormat(),
  1275. normalsProps.getWidth(), normalsProps.getHeight(), TU_RENDERTARGET);
  1276. resolvedNormals = resPool.get(desc);
  1277. rapi.setRenderTarget(resolvedNormals->renderTexture);
  1278. gRendererUtility().blit(sceneNormals);
  1279. sceneNormals = resolvedNormals->texture;
  1280. }
  1281. // Multiple downsampled AO levels are used to minimize cache trashing. Downsampled AO targets use larger radius,
  1282. // whose contents are then blended with the higher level.
  1283. UINT32 quality = settings.quality;
  1284. UINT32 numDownsampleLevels = 0;
  1285. if (quality > 1)
  1286. numDownsampleLevels = 1;
  1287. else if (quality > 2)
  1288. numDownsampleLevels = 2;
  1289. SSAODownsampleMat* downsample = SSAODownsampleMat::get();
  1290. SPtr<PooledRenderTexture> setupTex0;
  1291. if(numDownsampleLevels > 0)
  1292. {
  1293. Vector2I downsampledSize(
  1294. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 2)),
  1295. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 2))
  1296. );
  1297. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, downsampledSize.x,
  1298. downsampledSize.y, TU_RENDERTARGET);
  1299. setupTex0 = GpuResourcePool::instance().get(desc);
  1300. downsample->execute(inputs.view, sceneDepth, sceneNormals, setupTex0->renderTexture, DEPTH_RANGE);
  1301. }
  1302. SPtr<PooledRenderTexture> setupTex1;
  1303. if(numDownsampleLevels > 1)
  1304. {
  1305. Vector2I downsampledSize(
  1306. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 4)),
  1307. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 4))
  1308. );
  1309. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, downsampledSize.x,
  1310. downsampledSize.y, TU_RENDERTARGET);
  1311. setupTex1 = GpuResourcePool::instance().get(desc);
  1312. downsample->execute(inputs.view, sceneDepth, sceneNormals, setupTex1->renderTexture, DEPTH_RANGE);
  1313. }
  1314. SSAOTextureInputs textures;
  1315. textures.sceneDepth = sceneDepth;
  1316. textures.sceneNormals = sceneNormals;
  1317. textures.randomRotations = RendererTextures::ssaoRandomization4x4;
  1318. SPtr<PooledRenderTexture> downAOTex1;
  1319. if(numDownsampleLevels > 1)
  1320. {
  1321. textures.aoSetup = setupTex1->texture;
  1322. Vector2I downsampledSize(
  1323. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 4)),
  1324. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 4))
  1325. );
  1326. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, downsampledSize.x,
  1327. downsampledSize.y, TU_RENDERTARGET);
  1328. downAOTex1 = GpuResourcePool::instance().get(desc);
  1329. SSAOMat* ssaoMat = SSAOMat::getVariation(false, false, quality);
  1330. ssaoMat->execute(inputs.view, textures, downAOTex1->renderTexture, settings);
  1331. GpuResourcePool::instance().release(setupTex1);
  1332. setupTex1 = nullptr;
  1333. }
  1334. SPtr<PooledRenderTexture> downAOTex0;
  1335. if(numDownsampleLevels > 0)
  1336. {
  1337. textures.aoSetup = setupTex0->texture;
  1338. if(downAOTex1)
  1339. textures.aoDownsampled = downAOTex1->texture;
  1340. Vector2I downsampledSize(
  1341. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 2)),
  1342. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 2))
  1343. );
  1344. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, downsampledSize.x,
  1345. downsampledSize.y, TU_RENDERTARGET);
  1346. downAOTex0 = GpuResourcePool::instance().get(desc);
  1347. bool upsample = numDownsampleLevels > 1;
  1348. SSAOMat* ssaoMat = SSAOMat::getVariation(upsample, false, quality);
  1349. ssaoMat->execute(inputs.view, textures, downAOTex0->renderTexture, settings);
  1350. if(upsample)
  1351. {
  1352. GpuResourcePool::instance().release(downAOTex1);
  1353. downAOTex1 = nullptr;
  1354. }
  1355. }
  1356. UINT32 width = viewProps.viewRect.width;
  1357. UINT32 height = viewProps.viewRect.height;
  1358. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width, height, TU_RENDERTARGET));
  1359. {
  1360. if(setupTex0)
  1361. textures.aoSetup = setupTex0->texture;
  1362. if(downAOTex0)
  1363. textures.aoDownsampled = downAOTex0->texture;
  1364. bool upsample = numDownsampleLevels > 0;
  1365. SSAOMat* ssaoMat = SSAOMat::getVariation(upsample, true, quality);
  1366. ssaoMat->execute(inputs.view, textures, output->renderTexture, settings);
  1367. }
  1368. if(resolvedNormals)
  1369. {
  1370. GpuResourcePool::instance().release(resolvedNormals);
  1371. resolvedNormals = nullptr;
  1372. }
  1373. if(numDownsampleLevels > 0)
  1374. {
  1375. GpuResourcePool::instance().release(setupTex0);
  1376. GpuResourcePool::instance().release(downAOTex0);
  1377. }
  1378. // Blur the output
  1379. // Note: If I implement temporal AA then this can probably be avoided. I can instead jitter the sample offsets
  1380. // each frame, and averaging them out should yield blurred AO.
  1381. if(quality > 1) // On level 0 we don't blur at all, on level 1 we use the ad-hoc blur in shader
  1382. {
  1383. const RenderTargetProperties& rtProps = output->renderTexture->getProperties();
  1384. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, rtProps.getWidth(),
  1385. rtProps.getHeight(), TU_RENDERTARGET);
  1386. SPtr<PooledRenderTexture> blurIntermediateTex = GpuResourcePool::instance().get(desc);
  1387. SSAOBlurMat* blurHorz = SSAOBlurMat::getVariation(true);
  1388. SSAOBlurMat* blurVert = SSAOBlurMat::getVariation(false);
  1389. blurHorz->execute(inputs.view, output->texture, sceneDepth, blurIntermediateTex->renderTexture, DEPTH_RANGE);
  1390. blurVert->execute(inputs.view, blurIntermediateTex->texture, sceneDepth, output->renderTexture, DEPTH_RANGE);
  1391. GpuResourcePool::instance().release(blurIntermediateTex);
  1392. }
  1393. }
  1394. void RCNodeSSAO::clear()
  1395. {
  1396. GpuResourcePool& resPool = GpuResourcePool::instance();
  1397. resPool.release(output);
  1398. }
  1399. SmallVector<StringID, 4> RCNodeSSAO::getDependencies(const RendererView& view)
  1400. {
  1401. return { RCNodeResolvedSceneDepth::getNodeId(), RCNodeGBuffer::getNodeId() };
  1402. }
  1403. RCNodeSSR::~RCNodeSSR()
  1404. {
  1405. deallocOutputs();
  1406. }
  1407. void RCNodeSSR::render(const RenderCompositorNodeInputs& inputs)
  1408. {
  1409. const ScreenSpaceReflectionsSettings& settings = inputs.view.getRenderSettings().screenSpaceReflections;
  1410. if (settings.enabled)
  1411. {
  1412. RenderAPI& rapi = RenderAPI::instance();
  1413. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  1414. RCNodeLightAccumulation* lightAccumNode = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[1]);
  1415. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[2]);
  1416. RCNodeHiZ* hiZNode = static_cast<RCNodeHiZ*>(inputs.inputNodes[3]);
  1417. RCNodeResolvedSceneDepth* resolvedSceneDepthNode = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[4]);
  1418. GpuResourcePool& resPool = GpuResourcePool::instance();
  1419. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1420. UINT32 width = viewProps.viewRect.width;
  1421. UINT32 height = viewProps.viewRect.height;
  1422. SPtr<Texture> hiZ = hiZNode->output->texture;
  1423. // This will be executing before scene color is resolved, so get the light accum buffer instead
  1424. SPtr<Texture> sceneColor = lightAccumNode->lightAccumulationTex->texture;
  1425. // Resolve multiple samples if MSAA is used
  1426. SPtr<PooledRenderTexture> resolvedSceneColor;
  1427. if(viewProps.numSamples > 1)
  1428. {
  1429. resolvedSceneColor = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width, height,
  1430. TU_RENDERTARGET));
  1431. rapi.setRenderTarget(resolvedSceneColor->renderTexture);
  1432. gRendererUtility().blit(sceneColor);
  1433. sceneColor = resolvedSceneColor->texture;
  1434. }
  1435. GBufferTextures gbuffer;
  1436. gbuffer.albedo = gbufferNode->albedoTex->texture;
  1437. gbuffer.normals = gbufferNode->normalTex->texture;
  1438. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  1439. gbuffer.depth = sceneDepthNode->depthTex->texture;
  1440. SSRStencilMat* stencilMat = SSRStencilMat::getVariation(viewProps.numSamples > 1);
  1441. // Note: Making the assumption that the stencil buffer is clear at this point
  1442. rapi.setRenderTarget(resolvedSceneDepthNode->output->renderTexture);
  1443. stencilMat->execute(inputs.view, gbuffer, settings);
  1444. SPtr<PooledRenderTexture> traceOutput = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width,
  1445. height, TU_RENDERTARGET));
  1446. RENDER_TEXTURE_DESC traceRtDesc;
  1447. traceRtDesc.colorSurfaces[0].texture = traceOutput->texture;
  1448. traceRtDesc.depthStencilSurface.texture = resolvedSceneDepthNode->output->texture;
  1449. SPtr<RenderTexture> traceRt = RenderTexture::create(traceRtDesc);
  1450. rapi.setRenderTarget(traceRt);
  1451. rapi.clearRenderTarget(FBT_COLOR);
  1452. SSRTraceMat* traceMat = SSRTraceMat::getVariation(settings.quality, viewProps.numSamples > 1);
  1453. traceMat->execute(inputs.view, gbuffer, sceneColor, hiZ, settings, traceRt);
  1454. if (resolvedSceneColor)
  1455. {
  1456. resPool.release(resolvedSceneColor);
  1457. resolvedSceneColor = nullptr;
  1458. }
  1459. if (mPrevFrame)
  1460. {
  1461. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width, height, TU_RENDERTARGET));
  1462. rapi.setRenderTarget(output->renderTexture);
  1463. rapi.clearRenderTarget(FBT_COLOR);
  1464. SSRResolveMat* resolveMat = SSRResolveMat::getVariation(viewProps.numSamples > 1);
  1465. resolveMat->execute(inputs.view, mPrevFrame->texture, traceOutput->texture, sceneDepthNode->depthTex->texture,
  1466. output->renderTexture);
  1467. resPool.release(traceOutput);
  1468. }
  1469. else
  1470. output = traceOutput;
  1471. RenderAPI::instance().setRenderTarget(nullptr);
  1472. }
  1473. else
  1474. deallocOutputs();
  1475. }
  1476. void RCNodeSSR::clear()
  1477. {
  1478. GpuResourcePool& resPool = GpuResourcePool::instance();
  1479. if(mPrevFrame)
  1480. resPool.release(mPrevFrame);
  1481. mPrevFrame = output;
  1482. output = nullptr;
  1483. }
  1484. void RCNodeSSR::deallocOutputs()
  1485. {
  1486. GpuResourcePool& resPool = GpuResourcePool::instance();
  1487. if(mPrevFrame)
  1488. {
  1489. resPool.release(mPrevFrame);
  1490. mPrevFrame = nullptr;
  1491. }
  1492. }
  1493. SmallVector<StringID, 4> RCNodeSSR::getDependencies(const RendererView& view)
  1494. {
  1495. SmallVector<StringID, 4> deps;
  1496. if (view.getRenderSettings().screenSpaceReflections.enabled)
  1497. {
  1498. deps.push_back(RCNodeSceneDepth::getNodeId());
  1499. deps.push_back(RCNodeLightAccumulation::getNodeId());
  1500. deps.push_back(RCNodeGBuffer::getNodeId());
  1501. deps.push_back(RCNodeHiZ::getNodeId());
  1502. deps.push_back(RCNodeResolvedSceneDepth::getNodeId());
  1503. if (view.getProperties().numSamples > 1)
  1504. deps.push_back(RCNodeUnflattenLightAccum::getNodeId());
  1505. }
  1506. return deps;
  1507. }
  1508. }}