BsRenderCompositor.cpp 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353
  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. SmallVector<StringID, 4> RCNodeSceneColor::getDependencies(const RendererView& view)
  349. {
  350. return { RCNodeSceneDepth::getNodeId() };
  351. }
  352. void RCNodeMSAACoverage::render(const RenderCompositorNodeInputs& inputs)
  353. {
  354. GpuResourcePool& resPool = GpuResourcePool::instance();
  355. const RendererViewProperties& viewProps = inputs.view.getProperties();
  356. UINT32 width = viewProps.viewRect.width;
  357. UINT32 height = viewProps.viewRect.height;
  358. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width, height, TU_RENDERTARGET));
  359. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[0]);
  360. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  361. GBufferTextures gbuffer;
  362. gbuffer.albedo = gbufferNode->albedoTex->texture;
  363. gbuffer.normals = gbufferNode->normalTex->texture;
  364. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  365. gbuffer.depth = sceneDepthNode->depthTex->texture;
  366. MSAACoverageMat* mat = MSAACoverageMat::getVariation(viewProps.numSamples);
  367. RenderAPI& rapi = RenderAPI::instance();
  368. rapi.setRenderTarget(output->renderTexture);
  369. mat->execute(inputs.view, gbuffer);
  370. MSAACoverageStencilMat* stencilMat = MSAACoverageStencilMat::get();
  371. rapi.setRenderTarget(sceneDepthNode->depthTex->renderTexture);
  372. stencilMat->execute(inputs.view, output->texture);
  373. rapi.setRenderTarget(nullptr);
  374. }
  375. void RCNodeMSAACoverage::clear()
  376. {
  377. GpuResourcePool& resPool = GpuResourcePool::instance();
  378. resPool.release(output);
  379. }
  380. SmallVector<StringID, 4> RCNodeMSAACoverage::getDependencies(const RendererView& view)
  381. {
  382. return { RCNodeGBuffer::getNodeId(), RCNodeSceneDepth::getNodeId() };
  383. }
  384. void RCNodeLightAccumulation::render(const RenderCompositorNodeInputs& inputs)
  385. {
  386. bool supportsTiledDeferred = gRenderBeast()->getFeatureSet() != RenderBeastFeatureSet::DesktopMacOS;
  387. if(!supportsTiledDeferred)
  388. {
  389. // If tiled deferred is not supported, we don't need a separate texture for light accumulation, instead we
  390. // use scene color directly
  391. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  392. lightAccumulationTex = sceneColorNode->sceneColorTex;
  393. renderTarget = sceneColorNode->renderTarget;
  394. mOwnsTexture = false;
  395. return;
  396. }
  397. GpuResourcePool& resPool = GpuResourcePool::instance();
  398. const RendererViewProperties& viewProps = inputs.view.getProperties();
  399. RCNodeSceneDepth* depthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  400. UINT32 width = viewProps.viewRect.width;
  401. UINT32 height = viewProps.viewRect.height;
  402. UINT32 numSamples = viewProps.numSamples;
  403. if (numSamples > 1)
  404. {
  405. UINT32 bufferNumElements = width * height * numSamples;
  406. flattenedLightAccumBuffer =
  407. resPool.get(POOLED_STORAGE_BUFFER_DESC::createStandard(BF_16X4F, bufferNumElements));
  408. SPtr<GpuBuffer> buffer = flattenedLightAccumBuffer->buffer;
  409. auto& bufferProps = buffer->getProperties();
  410. UINT32 bufferSize = bufferProps.getElementSize() * bufferProps.getElementCount();
  411. UINT16* data = (UINT16*)buffer->lock(0, bufferSize, GBL_WRITE_ONLY_DISCARD);
  412. {
  413. memset(data, 0, bufferSize);
  414. }
  415. buffer->unlock();
  416. }
  417. else
  418. flattenedLightAccumBuffer = nullptr;
  419. lightAccumulationTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width,
  420. height, TU_LOADSTORE | TU_RENDERTARGET, numSamples, false));
  421. bool rebuildRT;
  422. if (renderTarget != nullptr)
  423. {
  424. rebuildRT = renderTarget->getColorTexture(0) != lightAccumulationTex->texture;
  425. rebuildRT |= renderTarget->getDepthStencilTexture() != depthNode->depthTex->texture;
  426. }
  427. else
  428. rebuildRT = true;
  429. if (rebuildRT)
  430. {
  431. RENDER_TEXTURE_DESC lightAccumulationRTDesc;
  432. lightAccumulationRTDesc.colorSurfaces[0].texture = lightAccumulationTex->texture;
  433. lightAccumulationRTDesc.colorSurfaces[0].face = 0;
  434. lightAccumulationRTDesc.colorSurfaces[0].numFaces = 1;
  435. lightAccumulationRTDesc.colorSurfaces[0].mipLevel = 0;
  436. lightAccumulationRTDesc.depthStencilSurface.texture = depthNode->depthTex->texture;
  437. lightAccumulationRTDesc.depthStencilSurface.face = 0;
  438. lightAccumulationRTDesc.depthStencilSurface.numFaces = 1;
  439. lightAccumulationRTDesc.depthStencilSurface.mipLevel = 0;
  440. renderTarget = RenderTexture::create(lightAccumulationRTDesc);
  441. }
  442. mOwnsTexture = true;
  443. }
  444. void RCNodeLightAccumulation::clear()
  445. {
  446. GpuResourcePool& resPool = GpuResourcePool::instance();
  447. if(mOwnsTexture)
  448. resPool.release(lightAccumulationTex);
  449. else
  450. {
  451. lightAccumulationTex = nullptr;
  452. renderTarget = nullptr;
  453. }
  454. if (flattenedLightAccumBuffer)
  455. resPool.release(flattenedLightAccumBuffer);
  456. }
  457. SmallVector<StringID, 4> RCNodeLightAccumulation::getDependencies(const RendererView& view)
  458. {
  459. SmallVector<StringID, 4> deps;
  460. bool supportsTiledDeferred = gRenderBeast()->getFeatureSet() != RenderBeastFeatureSet::DesktopMacOS;
  461. if(!supportsTiledDeferred)
  462. deps.push_back(RCNodeSceneColor::getNodeId());
  463. else
  464. deps.push_back(RCNodeSceneDepth::getNodeId());
  465. return deps;
  466. }
  467. void RCNodeTiledDeferredLighting::render(const RenderCompositorNodeInputs& inputs)
  468. {
  469. output = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[0]);
  470. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  471. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[2]);
  472. const RendererViewProperties& viewProps = inputs.view.getProperties();
  473. SPtr<Texture> msaaCoverage;
  474. if(viewProps.numSamples > 1)
  475. {
  476. RCNodeMSAACoverage* coverageNode = static_cast<RCNodeMSAACoverage*>(inputs.inputNodes[3]);
  477. msaaCoverage = coverageNode->output->texture;
  478. }
  479. TiledDeferredLightingMat* tiledDeferredMat = TiledDeferredLightingMat::getVariation(viewProps.numSamples);
  480. GBufferTextures gbuffer;
  481. gbuffer.albedo = gbufferNode->albedoTex->texture;
  482. gbuffer.normals = gbufferNode->normalTex->texture;
  483. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  484. gbuffer.depth = sceneDepthNode->depthTex->texture;
  485. const VisibleLightData& lightData = inputs.viewGroup.getVisibleLightData();
  486. SPtr<GpuBuffer> flattenedLightAccumBuffer;
  487. if (output->flattenedLightAccumBuffer)
  488. flattenedLightAccumBuffer = output->flattenedLightAccumBuffer->buffer;
  489. tiledDeferredMat->execute(inputs.view, lightData, gbuffer, output->lightAccumulationTex->texture,
  490. flattenedLightAccumBuffer, msaaCoverage);
  491. }
  492. void RCNodeTiledDeferredLighting::clear()
  493. {
  494. output = nullptr;
  495. }
  496. SmallVector<StringID, 4> RCNodeTiledDeferredLighting::getDependencies(const RendererView& view)
  497. {
  498. SmallVector<StringID, 4> deps;
  499. deps.push_back(RCNodeLightAccumulation::getNodeId());
  500. deps.push_back(RCNodeGBuffer::getNodeId());
  501. deps.push_back(RCNodeSceneDepth::getNodeId());
  502. if(view.getProperties().numSamples > 1)
  503. deps.push_back(RCNodeMSAACoverage::getNodeId());
  504. return deps;
  505. }
  506. void RCNodeStandardDeferredLighting::render(const RenderCompositorNodeInputs& inputs)
  507. {
  508. SPtr<RenderTexture> outputRT;
  509. bool tiledDeferredSupported = inputs.featureSet != RenderBeastFeatureSet::DesktopMacOS;
  510. if(tiledDeferredSupported)
  511. {
  512. RCNodeTiledDeferredLighting* tileDeferredNode = static_cast<RCNodeTiledDeferredLighting*>(inputs.inputNodes[2]);
  513. outputRT = tileDeferredNode->output->renderTarget;
  514. // If shadows are disabled we handle all lights through tiled deferred, except when tiled deferred isn't available
  515. if (!inputs.view.getRenderSettings().enableShadows)
  516. {
  517. mLightOcclusionRT = nullptr;
  518. return;
  519. }
  520. }
  521. else
  522. {
  523. RCNodeLightAccumulation* lightAccumNode = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[2]);
  524. outputRT = lightAccumNode->renderTarget;
  525. mLightOcclusionRT = nullptr;
  526. }
  527. GpuResourcePool& resPool = GpuResourcePool::instance();
  528. const RendererViewProperties& viewProps = inputs.view.getProperties();
  529. UINT32 width = viewProps.viewRect.width;
  530. UINT32 height = viewProps.viewRect.height;
  531. UINT32 numSamples = viewProps.numSamples;
  532. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[0]);
  533. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  534. GBufferTextures gbuffer;
  535. gbuffer.albedo = gbufferNode->albedoTex->texture;
  536. gbuffer.normals = gbufferNode->normalTex->texture;
  537. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  538. gbuffer.depth = sceneDepthNode->depthTex->texture;
  539. const VisibleLightData& lightData = inputs.viewGroup.getVisibleLightData();
  540. RenderAPI& rapi = RenderAPI::instance();
  541. // Render unshadowed lights
  542. if(!tiledDeferredSupported)
  543. {
  544. rapi.setRenderTarget(outputRT, FBT_DEPTH | FBT_STENCIL, RT_DEPTH_STENCIL);
  545. rapi.clearRenderTarget(FBT_COLOR, Color::ZERO);
  546. for (UINT32 i = 0; i < (UINT32)LightType::Count; i++)
  547. {
  548. LightType lightType = (LightType)i;
  549. auto& lights = lightData.getLights(lightType);
  550. UINT32 count = lightData.getNumUnshadowedLights(lightType);
  551. for (UINT32 j = 0; j < count; j++)
  552. {
  553. UINT32 lightIdx = j;
  554. const RendererLight& light = *lights[lightIdx];
  555. StandardDeferred::instance().renderLight(lightType, light, inputs.view, gbuffer, Texture::BLACK);
  556. }
  557. }
  558. }
  559. // Allocate light occlusion
  560. SPtr<PooledRenderTexture> lightOcclusionTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width,
  561. height, TU_RENDERTARGET, numSamples, false));
  562. bool rebuildRT = false;
  563. if (mLightOcclusionRT != nullptr)
  564. {
  565. rebuildRT |= mLightOcclusionRT->getColorTexture(0) != lightOcclusionTex->texture;
  566. rebuildRT |= mLightOcclusionRT->getDepthStencilTexture() != sceneDepthNode->depthTex->texture;
  567. }
  568. else
  569. rebuildRT = true;
  570. if (rebuildRT)
  571. {
  572. RENDER_TEXTURE_DESC lightOcclusionRTDesc;
  573. lightOcclusionRTDesc.colorSurfaces[0].texture = lightOcclusionTex->texture;
  574. lightOcclusionRTDesc.colorSurfaces[0].face = 0;
  575. lightOcclusionRTDesc.colorSurfaces[0].numFaces = 1;
  576. lightOcclusionRTDesc.colorSurfaces[0].mipLevel = 0;
  577. lightOcclusionRTDesc.depthStencilSurface.texture = sceneDepthNode->depthTex->texture;
  578. lightOcclusionRTDesc.depthStencilSurface.face = 0;
  579. lightOcclusionRTDesc.depthStencilSurface.numFaces = 1;
  580. lightOcclusionRTDesc.depthStencilSurface.mipLevel = 0;
  581. mLightOcclusionRT = RenderTexture::create(lightOcclusionRTDesc);
  582. }
  583. // Render shadowed lights
  584. const ShadowRendering& shadowRenderer = inputs.viewGroup.getShadowRenderer();
  585. for (UINT32 i = 0; i < (UINT32)LightType::Count; i++)
  586. {
  587. LightType lightType = (LightType)i;
  588. auto& lights = lightData.getLights(lightType);
  589. UINT32 count = lightData.getNumShadowedLights(lightType);
  590. UINT32 offset = lightData.getNumUnshadowedLights(lightType);
  591. for (UINT32 j = 0; j < count; j++)
  592. {
  593. rapi.setRenderTarget(mLightOcclusionRT, FBT_DEPTH, RT_DEPTH_STENCIL);
  594. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  595. rapi.setViewport(area);
  596. rapi.clearViewport(FBT_COLOR, Color::ZERO);
  597. UINT32 lightIdx = offset + j;
  598. const RendererLight& light = *lights[lightIdx];
  599. shadowRenderer.renderShadowOcclusion(inputs.view, light, gbuffer);
  600. rapi.setRenderTarget(outputRT, FBT_DEPTH | FBT_STENCIL, RT_COLOR0 | RT_DEPTH_STENCIL);
  601. StandardDeferred::instance().renderLight(lightType, light, inputs.view, gbuffer,
  602. lightOcclusionTex->texture);
  603. }
  604. }
  605. // Makes sure light accumulation can be read by following passes
  606. rapi.setRenderTarget(nullptr);
  607. resPool.release(lightOcclusionTex);
  608. }
  609. void RCNodeStandardDeferredLighting::clear()
  610. {
  611. // Do nothing
  612. }
  613. SmallVector<StringID, 4> RCNodeStandardDeferredLighting::getDependencies(const RendererView& view)
  614. {
  615. SmallVector<StringID, 4> deps;
  616. deps.push_back(RCNodeGBuffer::getNodeId());
  617. deps.push_back(RCNodeSceneDepth::getNodeId());
  618. bool tiledDeferredSupported = gRenderBeast()->getFeatureSet() != RenderBeastFeatureSet::DesktopMacOS;
  619. if(!tiledDeferredSupported)
  620. {
  621. deps.push_back(RCNodeLightAccumulation::getNodeId());
  622. }
  623. else
  624. {
  625. deps.push_back(RCNodeTiledDeferredLighting::getNodeId());
  626. if (view.getProperties().numSamples > 1)
  627. deps.push_back(RCNodeUnflattenLightAccum::getNodeId());
  628. }
  629. return deps;
  630. }
  631. void RCNodeStandardDeferredIBL::render(const RenderCompositorNodeInputs& inputs)
  632. {
  633. RCNodeLightAccumulation* lightAccumNode = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[2]);
  634. SPtr<RenderTexture> outputRT = lightAccumNode->renderTarget;
  635. GpuResourcePool& resPool = GpuResourcePool::instance();
  636. const RendererViewProperties& viewProps = inputs.view.getProperties();
  637. UINT32 width = viewProps.viewRect.width;
  638. UINT32 height = viewProps.viewRect.height;
  639. UINT32 numSamples = viewProps.numSamples;
  640. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[0]);
  641. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  642. GBufferTextures gbuffer;
  643. gbuffer.albedo = gbufferNode->albedoTex->texture;
  644. gbuffer.normals = gbufferNode->normalTex->texture;
  645. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  646. gbuffer.depth = sceneDepthNode->depthTex->texture;
  647. RenderAPI& rapi = RenderAPI::instance();
  648. const RenderSettings& rs = inputs.view.getRenderSettings();
  649. bool isMSAA = viewProps.numSamples > 1;
  650. SPtr<PooledRenderTexture> iblRadianceTex = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width,
  651. height, TU_RENDERTARGET, numSamples, false));
  652. RENDER_TEXTURE_DESC rtDesc;
  653. rtDesc.colorSurfaces[0].texture = iblRadianceTex->texture;
  654. rtDesc.depthStencilSurface.texture = sceneDepthNode->depthTex->texture;
  655. SPtr<GpuParamBlockBuffer> perViewBuffer = inputs.view.getPerViewBuffer();
  656. SPtr<RenderTexture> iblRadianceRT = RenderTexture::create(rtDesc);
  657. rapi.setRenderTarget(iblRadianceRT, FBT_DEPTH | FBT_STENCIL, RT_DEPTH_STENCIL);
  658. const VisibleReflProbeData& probeData = inputs.viewGroup.getVisibleReflProbeData();
  659. ReflProbeParamBuffer reflProbeParams;
  660. reflProbeParams.populate(inputs.scene.skybox, probeData.getNumProbes(), inputs.scene.reflProbeCubemapsTex,
  661. viewProps.capturingReflections);
  662. // Prepare the texture for refl. probe and skybox rendering
  663. {
  664. SPtr<Texture> ssr;
  665. if (rs.screenSpaceReflections.enabled)
  666. {
  667. RCNodeSSR* ssrNode = static_cast<RCNodeSSR*>(inputs.inputNodes[3]);
  668. ssr = ssrNode->output->texture;
  669. }
  670. else
  671. ssr = Texture::BLACK;
  672. UINT32 nodeIdx = 4;
  673. SPtr<Texture> ssao;
  674. if (rs.ambientOcclusion.enabled)
  675. {
  676. RCNodeSSAO* ssaoNode = static_cast<RCNodeSSAO*>(inputs.inputNodes[nodeIdx++]);
  677. ssao = ssaoNode->output->texture;
  678. }
  679. else
  680. ssao = Texture::WHITE;
  681. DeferredIBLSetupMat* mat = DeferredIBLSetupMat::getVariation(isMSAA, true);
  682. mat->bind(gbuffer, perViewBuffer, ssr, ssao, reflProbeParams.buffer);
  683. gRendererUtility().drawScreenQuad();
  684. // Draw pixels requiring per-sample evaluation
  685. if (isMSAA)
  686. {
  687. DeferredIBLSetupMat* msaaMat = DeferredIBLSetupMat::getVariation(true, false);
  688. msaaMat->bind(gbuffer, perViewBuffer, ssr, ssao, reflProbeParams.buffer);
  689. gRendererUtility().drawScreenQuad();
  690. }
  691. }
  692. if (!viewProps.capturingReflections)
  693. {
  694. // Render refl. probes
  695. UINT32 numProbes = probeData.getNumProbes();
  696. for (UINT32 i = 0; i < numProbes; i++)
  697. {
  698. const ReflProbeData& probe = probeData.getProbeData(i);
  699. StandardDeferred::instance().renderReflProbe(probe, inputs.view, gbuffer, inputs.scene,
  700. reflProbeParams.buffer);
  701. }
  702. // Render sky
  703. SPtr<Texture> skyFilteredRadiance;
  704. if (inputs.scene.skybox)
  705. skyFilteredRadiance = inputs.scene.skybox->getFilteredRadiance();
  706. if (skyFilteredRadiance)
  707. {
  708. DeferredIBLSkyMat* skymat = DeferredIBLSkyMat::getVariation(isMSAA, true);
  709. skymat->bind(gbuffer, perViewBuffer, inputs.scene.skybox, reflProbeParams.buffer);
  710. gRendererUtility().drawScreenQuad();
  711. // Draw pixels requiring per-sample evaluation
  712. if (isMSAA)
  713. {
  714. DeferredIBLSkyMat* msaaMat = DeferredIBLSkyMat::getVariation(true, false);
  715. msaaMat->bind(gbuffer, perViewBuffer, inputs.scene.skybox, reflProbeParams.buffer);
  716. gRendererUtility().drawScreenQuad();
  717. }
  718. }
  719. }
  720. // Finalize rendered reflections and output them to main render target
  721. {
  722. rapi.setRenderTarget(outputRT, FBT_DEPTH | FBT_STENCIL, RT_COLOR0 | RT_DEPTH_STENCIL);
  723. DeferredIBLFinalizeMat* mat = DeferredIBLFinalizeMat::getVariation(isMSAA, true);
  724. mat->bind(gbuffer, perViewBuffer, iblRadianceTex->texture, RendererTextures::preintegratedEnvGF,
  725. reflProbeParams.buffer);
  726. gRendererUtility().drawScreenQuad();
  727. // Draw pixels requiring per-sample evaluation
  728. if (isMSAA)
  729. {
  730. DeferredIBLFinalizeMat* msaaMat = DeferredIBLFinalizeMat::getVariation(true, false);
  731. msaaMat->bind(gbuffer, perViewBuffer, iblRadianceTex->texture, RendererTextures::preintegratedEnvGF,
  732. reflProbeParams.buffer);
  733. gRendererUtility().drawScreenQuad();
  734. }
  735. }
  736. // Makes sure light accumulation can be read by following passes
  737. rapi.setRenderTarget(nullptr);
  738. }
  739. void RCNodeStandardDeferredIBL::clear()
  740. {
  741. // Do nothing
  742. }
  743. SmallVector<StringID, 4> RCNodeStandardDeferredIBL::getDependencies(const RendererView& view)
  744. {
  745. SmallVector<StringID, 4> deps;
  746. deps.push_back(RCNodeGBuffer::getNodeId());
  747. deps.push_back(RCNodeSceneDepth::getNodeId());
  748. deps.push_back(RCNodeLightAccumulation::getNodeId());
  749. deps.push_back(RCNodeSSR::getNodeId());
  750. if (view.getRenderSettings().ambientOcclusion.enabled)
  751. deps.push_back(RCNodeSSAO::getNodeId());
  752. deps.push_back(RCNodeStandardDeferredLighting::getNodeId());
  753. return deps;
  754. }
  755. void RCNodeUnflattenLightAccum::render(const RenderCompositorNodeInputs& inputs)
  756. {
  757. RCNodeLightAccumulation* lightAccumNode = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[0]);
  758. FlatFramebufferToTextureMat* material = FlatFramebufferToTextureMat::get();
  759. RenderAPI& rapi = RenderAPI::instance();
  760. rapi.setRenderTarget(lightAccumNode->renderTarget, FBT_DEPTH | FBT_STENCIL, RT_DEPTH_STENCIL);
  761. material->execute(lightAccumNode->flattenedLightAccumBuffer->buffer, lightAccumNode->lightAccumulationTex->texture);
  762. }
  763. void RCNodeUnflattenLightAccum::clear()
  764. {
  765. output = nullptr;
  766. }
  767. SmallVector<StringID, 4> RCNodeUnflattenLightAccum::getDependencies(const RendererView& view)
  768. {
  769. return { RCNodeLightAccumulation::getNodeId() };
  770. }
  771. void RCNodeIndirectLighting::render(const RenderCompositorNodeInputs& inputs)
  772. {
  773. if (!inputs.view.getRenderSettings().enableIndirectLighting)
  774. return;
  775. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[0]);
  776. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  777. RCNodeLightAccumulation* lightAccumNode = static_cast <RCNodeLightAccumulation*>(inputs.inputNodes[2]);
  778. SPtr<Texture> ssao;
  779. if (inputs.view.getRenderSettings().ambientOcclusion.enabled)
  780. {
  781. RCNodeSSAO* ssaoNode = static_cast<RCNodeSSAO*>(inputs.inputNodes[4]);
  782. ssao = ssaoNode->output->texture;
  783. }
  784. else
  785. ssao = Texture::WHITE;
  786. GpuResourcePool& resPool = GpuResourcePool::instance();
  787. const RendererViewProperties& viewProps = inputs.view.getProperties();
  788. const LightProbes& lightProbes = inputs.scene.lightProbes;
  789. LightProbesInfo lpInfo = lightProbes.getInfo();
  790. IrradianceEvaluateMat* evaluateMat;
  791. SPtr<PooledRenderTexture> volumeIndices;
  792. if(lightProbes.hasAnyProbes())
  793. {
  794. POOLED_RENDER_TEXTURE_DESC volumeIndicesDesc;
  795. POOLED_RENDER_TEXTURE_DESC depthDesc;
  796. TetrahedraRenderMat::getOutputDesc(inputs.view, volumeIndicesDesc, depthDesc);
  797. volumeIndices = resPool.get(volumeIndicesDesc);
  798. SPtr<PooledRenderTexture> depthTex = resPool.get(depthDesc);
  799. RENDER_TEXTURE_DESC rtDesc;
  800. rtDesc.colorSurfaces[0].texture = volumeIndices->texture;
  801. rtDesc.depthStencilSurface.texture = depthTex->texture;
  802. SPtr<RenderTexture> rt = RenderTexture::create(rtDesc);
  803. RenderAPI& rapi = RenderAPI::instance();
  804. rapi.setRenderTarget(rt);
  805. rapi.clearRenderTarget(FBT_DEPTH);
  806. gRendererUtility().clear(-1);
  807. TetrahedraRenderMat* renderTetrahedra = TetrahedraRenderMat::getVariation(viewProps.numSamples > 1, true);
  808. renderTetrahedra->execute(inputs.view, sceneDepthNode->depthTex->texture, lpInfo.tetrahedraVolume, rt);
  809. rt = nullptr;
  810. resPool.release(depthTex);
  811. evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples > 1, true, false);
  812. }
  813. else // Sky only
  814. {
  815. evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples > 1, true, true);
  816. }
  817. GBufferTextures gbuffer;
  818. gbuffer.albedo = gbufferNode->albedoTex->texture;
  819. gbuffer.normals = gbufferNode->normalTex->texture;
  820. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  821. gbuffer.depth = sceneDepthNode->depthTex->texture;
  822. SPtr<Texture> volumeIndicesTex;
  823. if (volumeIndices)
  824. volumeIndicesTex = volumeIndices->texture;
  825. evaluateMat->execute(inputs.view, gbuffer, volumeIndicesTex, lpInfo, inputs.scene.skybox, ssao,
  826. lightAccumNode->renderTarget);
  827. if(volumeIndices)
  828. resPool.release(volumeIndices);
  829. }
  830. void RCNodeIndirectLighting::clear()
  831. {
  832. // Do nothing
  833. }
  834. SmallVector<StringID, 4> RCNodeIndirectLighting::getDependencies(const RendererView& view)
  835. {
  836. SmallVector<StringID, 4> deps;
  837. deps.push_back(RCNodeGBuffer::getNodeId());
  838. deps.push_back(RCNodeSceneDepth::getNodeId());
  839. deps.push_back(RCNodeLightAccumulation::getNodeId());
  840. bool supportsTiledDeferred = gRenderBeast()->getFeatureSet() != RenderBeastFeatureSet::DesktopMacOS;
  841. if(supportsTiledDeferred)
  842. deps.push_back(RCNodeStandardDeferredLighting::getNodeId());
  843. else
  844. deps.push_back(RCNodeStandardDeferredIBL::getNodeId());
  845. if(view.getRenderSettings().ambientOcclusion.enabled)
  846. deps.push_back(RCNodeSSAO::getNodeId());
  847. if(supportsTiledDeferred)
  848. {
  849. if (view.getProperties().numSamples > 1)
  850. deps.push_back(RCNodeUnflattenLightAccum::getNodeId());
  851. }
  852. return deps;
  853. }
  854. void RCNodeTiledDeferredIBL::render(const RenderCompositorNodeInputs& inputs)
  855. {
  856. const RenderSettings& rs = inputs.view.getRenderSettings();
  857. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  858. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  859. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[2]);
  860. RCNodeLightAccumulation* lightAccumNode = static_cast <RCNodeLightAccumulation*>(inputs.inputNodes[3]);
  861. SPtr<Texture> ssr;
  862. if (rs.screenSpaceReflections.enabled)
  863. {
  864. RCNodeSSR* ssrNode = static_cast<RCNodeSSR*>(inputs.inputNodes[5]);
  865. ssr = ssrNode->output->texture;
  866. }
  867. else
  868. ssr = Texture::BLACK;
  869. UINT32 nodeIdx = 6;
  870. SPtr<Texture> ssao;
  871. if (rs.ambientOcclusion.enabled)
  872. {
  873. RCNodeSSAO* ssaoNode = static_cast<RCNodeSSAO*>(inputs.inputNodes[nodeIdx++]);
  874. ssao = ssaoNode->output->texture;
  875. }
  876. else
  877. ssao = Texture::WHITE;
  878. const RendererViewProperties& viewProps = inputs.view.getProperties();
  879. SPtr<Texture> msaaCoverage;
  880. if(viewProps.numSamples > 1)
  881. {
  882. RCNodeMSAACoverage* coverageNode = static_cast<RCNodeMSAACoverage*>(inputs.inputNodes[nodeIdx++]);
  883. msaaCoverage = coverageNode->output->texture;
  884. }
  885. TiledDeferredImageBasedLightingMat* material = TiledDeferredImageBasedLightingMat::getVariation(viewProps.numSamples);
  886. TiledDeferredImageBasedLightingMat::Inputs iblInputs;
  887. iblInputs.gbuffer.albedo = gbufferNode->albedoTex->texture;
  888. iblInputs.gbuffer.normals = gbufferNode->normalTex->texture;
  889. iblInputs.gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  890. iblInputs.gbuffer.depth = sceneDepthNode->depthTex->texture;
  891. iblInputs.sceneColorTex = sceneColorNode->sceneColorTex->texture;
  892. iblInputs.lightAccumulation = lightAccumNode->lightAccumulationTex->texture;
  893. iblInputs.preIntegratedGF = RendererTextures::preintegratedEnvGF;
  894. iblInputs.ambientOcclusion = ssao;
  895. iblInputs.ssr = ssr;
  896. iblInputs.msaaCoverage = msaaCoverage;
  897. if(sceneColorNode->flattenedSceneColorBuffer)
  898. iblInputs.sceneColorBuffer = sceneColorNode->flattenedSceneColorBuffer->buffer;
  899. material->execute(inputs.view, inputs.scene, inputs.viewGroup.getVisibleReflProbeData(), iblInputs);
  900. }
  901. void RCNodeTiledDeferredIBL::clear()
  902. {
  903. output = nullptr;
  904. }
  905. SmallVector<StringID, 4> RCNodeTiledDeferredIBL::getDependencies(const RendererView& view)
  906. {
  907. SmallVector<StringID, 4> deps;
  908. deps.push_back(RCNodeSceneColor::getNodeId());
  909. deps.push_back(RCNodeGBuffer::getNodeId());
  910. deps.push_back(RCNodeSceneDepth::getNodeId());
  911. deps.push_back(RCNodeLightAccumulation::getNodeId());
  912. deps.push_back(RCNodeIndirectLighting::getNodeId());
  913. deps.push_back(RCNodeSSR::getNodeId());
  914. if(view.getRenderSettings().ambientOcclusion.enabled)
  915. deps.push_back(RCNodeSSAO::getNodeId());
  916. if(view.getProperties().numSamples > 1)
  917. deps.push_back(RCNodeMSAACoverage::getNodeId());
  918. return deps;
  919. }
  920. void RCNodeUnflattenSceneColor::render(const RenderCompositorNodeInputs& inputs)
  921. {
  922. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  923. FlatFramebufferToTextureMat* material = FlatFramebufferToTextureMat::get();
  924. int readOnlyFlags = FBT_DEPTH | FBT_STENCIL;
  925. RenderAPI& rapi = RenderAPI::instance();
  926. rapi.setRenderTarget(sceneColorNode->renderTarget, readOnlyFlags, RT_DEPTH_STENCIL);
  927. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  928. rapi.setViewport(area);
  929. material->execute(sceneColorNode->flattenedSceneColorBuffer->buffer, sceneColorNode->sceneColorTex->texture);
  930. }
  931. void RCNodeUnflattenSceneColor::clear()
  932. {
  933. output = nullptr;
  934. }
  935. SmallVector<StringID, 4> RCNodeUnflattenSceneColor::getDependencies(const RendererView& view)
  936. {
  937. return { RCNodeSceneColor::getNodeId() };
  938. }
  939. RCNodeClusteredForward::RCNodeClusteredForward()
  940. { }
  941. void RCNodeClusteredForward::render(const RenderCompositorNodeInputs& inputs)
  942. {
  943. const SceneInfo& sceneInfo = inputs.scene;
  944. const RendererViewProperties& viewProps = inputs.view.getProperties();
  945. const VisibleLightData& visibleLightData = inputs.viewGroup.getVisibleLightData();
  946. const VisibleReflProbeData& visibleReflProbeData = inputs.viewGroup.getVisibleReflProbeData();
  947. // Buffers used when clustered forward is available
  948. SPtr<GpuParamBlockBuffer> gridParams;
  949. SPtr<GpuBuffer> gridLightOffsetsAndSize, gridLightIndices;
  950. SPtr<GpuBuffer> gridProbeOffsetsAndSize, gridProbeIndices;
  951. // Buffers used when clustered forward is unavailable
  952. SPtr<GpuParamBlockBuffer> lightsParamBlock;
  953. SPtr<GpuParamBlockBuffer> reflProbesParamBlock;
  954. SPtr<GpuParamBlockBuffer> lightAndReflProbeParamsParamBlock;
  955. bool supportsClusteredForward = gRenderBeast()->getFeatureSet() == RenderBeastFeatureSet::Desktop;
  956. if(supportsClusteredForward)
  957. {
  958. const LightGrid& lightGrid = inputs.view.getLightGrid();
  959. lightGrid.getOutputs(gridLightOffsetsAndSize, gridLightIndices, gridProbeOffsetsAndSize, gridProbeIndices,
  960. gridParams);
  961. }
  962. else
  963. {
  964. // Note: Store these instead of creating them every time?
  965. lightsParamBlock = gLightsParamDef.createBuffer();
  966. reflProbesParamBlock = gReflProbesParamDef.createBuffer();
  967. lightAndReflProbeParamsParamBlock = gLightAndReflProbeParamsParamDef.createBuffer();
  968. }
  969. // Prepare refl. probe param buffer
  970. ReflProbeParamBuffer reflProbeParamBuffer;
  971. reflProbeParamBuffer.populate(sceneInfo.skybox, visibleReflProbeData.getNumProbes(), sceneInfo.reflProbeCubemapsTex,
  972. viewProps.capturingReflections);
  973. SPtr<Texture> skyFilteredRadiance;
  974. if(sceneInfo.skybox)
  975. skyFilteredRadiance = sceneInfo.skybox->getFilteredRadiance();
  976. // Prepare objects for rendering
  977. const VisibilityInfo& visibility = inputs.view.getVisibilityMasks();
  978. UINT32 numRenderables = (UINT32)sceneInfo.renderables.size();
  979. for (UINT32 i = 0; i < numRenderables; i++)
  980. {
  981. if (!visibility.renderables[i])
  982. continue;
  983. for (auto& element : sceneInfo.renderables[i]->elements)
  984. {
  985. bool isTransparent = (element.material->getShader()->getFlags() & (UINT32)ShaderFlags::Transparent) != 0;
  986. if (!isTransparent)
  987. continue;
  988. // Note: It would be nice to be able to set this once and keep it, only updating if the buffers actually
  989. // change (e.g. when growing).
  990. SPtr<GpuParams> gpuParams = element.params->getGpuParams();
  991. ImageBasedLightingParams& iblParams = element.imageBasedParams;
  992. if(supportsClusteredForward)
  993. {
  994. for (UINT32 j = 0; j < GPT_COUNT; j++)
  995. {
  996. const GpuParamBinding& binding = element.gridParamsBindings[j];
  997. if (binding.slot != (UINT32)-1)
  998. gpuParams->setParamBlockBuffer(binding.set, binding.slot, gridParams);
  999. }
  1000. element.gridLightOffsetsAndSizeParam.set(gridLightOffsetsAndSize);
  1001. element.gridProbeOffsetsAndSizeParam.set(gridProbeOffsetsAndSize);
  1002. element.gridLightIndicesParam.set(gridLightIndices);
  1003. iblParams.reflectionProbeIndicesParam.set(gridProbeIndices);
  1004. element.lightsBufferParam.set(visibleLightData.getLightBuffer());
  1005. iblParams.reflectionProbesParam.set(visibleReflProbeData.getProbeBuffer());
  1006. }
  1007. else
  1008. {
  1009. // Populate light & probe buffers
  1010. const Bounds& bounds = sceneInfo.renderableCullInfos[i].bounds;
  1011. Vector3I lightCounts;
  1012. const LightData* lights[STANDARD_FORWARD_MAX_NUM_LIGHTS];
  1013. visibleLightData.gatherInfluencingLights(bounds, lights, lightCounts);
  1014. Vector4I lightOffsets;
  1015. lightOffsets.x = lightCounts.x;
  1016. lightOffsets.y = lightCounts.x;
  1017. lightOffsets.z = lightOffsets.y + lightCounts.y;
  1018. lightOffsets.w = lightOffsets.z + lightCounts.z;
  1019. for(INT32 j = 0; j < lightOffsets.w; j++)
  1020. gLightsParamDef.gLights.set(lightsParamBlock, *lights[j], j);
  1021. INT32 numReflProbes = std::min(visibleReflProbeData.getNumProbes(), STANDARD_FORWARD_MAX_NUM_PROBES);
  1022. for(INT32 j = 0; j < numReflProbes; j++)
  1023. gReflProbesParamDef.gReflectionProbes.set(reflProbesParamBlock, visibleReflProbeData.getProbeData(j), j);
  1024. gLightAndReflProbeParamsParamDef.gLightOffsets.set(lightAndReflProbeParamsParamBlock, lightOffsets);
  1025. gLightAndReflProbeParamsParamDef.gReflProbeCount.set(lightAndReflProbeParamsParamBlock, numReflProbes);
  1026. if(iblParams.reflProbesBinding.set != (UINT32)-1)
  1027. {
  1028. gpuParams->setParamBlockBuffer(
  1029. iblParams.reflProbesBinding.set,
  1030. iblParams.reflProbesBinding.slot,
  1031. reflProbesParamBlock);
  1032. }
  1033. if(element.lightsParamBlockBinding.set != (UINT32)-1)
  1034. {
  1035. gpuParams->setParamBlockBuffer(
  1036. element.lightsParamBlockBinding.set,
  1037. element.lightsParamBlockBinding.slot,
  1038. lightsParamBlock);
  1039. }
  1040. if(element.lightAndReflProbeParamsParamBlockBinding.set != (UINT32)-1)
  1041. {
  1042. gpuParams->setParamBlockBuffer(
  1043. element.lightAndReflProbeParamsParamBlockBinding.set,
  1044. element.lightAndReflProbeParamsParamBlockBinding.slot,
  1045. lightAndReflProbeParamsParamBlock);
  1046. }
  1047. }
  1048. // Image based lighting params
  1049. // Note: Ideally these should be bound once (they are the same for all renderables)
  1050. if (iblParams.reflProbeParamBindings.set != (UINT32)-1)
  1051. {
  1052. gpuParams->setParamBlockBuffer(
  1053. iblParams.reflProbeParamBindings.set,
  1054. iblParams.reflProbeParamBindings.slot,
  1055. reflProbeParamBuffer.buffer);
  1056. }
  1057. iblParams.skyReflectionsTexParam.set(skyFilteredRadiance);
  1058. iblParams.ambientOcclusionTexParam.set(Texture::WHITE); // Note: Add SSAO here?
  1059. iblParams.ssrTexParam.set(Texture::BLACK); // Note: Add SSR here?
  1060. iblParams.reflectionProbeCubemapsTexParam.set(sceneInfo.reflProbeCubemapsTex);
  1061. iblParams.preintegratedEnvBRDFParam.set(RendererTextures::preintegratedEnvGF);
  1062. }
  1063. }
  1064. // TODO: Transparent objects cannot receive shadows. In order to support this I'd have to render the light occlusion
  1065. // for all lights affecting this object into a single (or a few) textures. I can likely use texture arrays for this,
  1066. // or to avoid sampling many textures, perhaps just jam it all in one or few texture channels.
  1067. const Vector<RenderQueueElement>& transparentElements = inputs.view.getTransparentQueue()->getSortedElements();
  1068. for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
  1069. {
  1070. BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
  1071. SPtr<Material> material = renderElem->material;
  1072. if (iter->applyPass)
  1073. gRendererUtility().setPass(material, iter->passIdx, renderElem->techniqueIdx);
  1074. gRendererUtility().setPassParams(renderElem->params, iter->passIdx);
  1075. if(renderElem->morphVertexDeclaration == nullptr)
  1076. gRendererUtility().draw(renderElem->mesh, renderElem->subMesh);
  1077. else
  1078. gRendererUtility().drawMorph(renderElem->mesh, renderElem->subMesh, renderElem->morphShapeBuffer,
  1079. renderElem->morphVertexDeclaration);
  1080. }
  1081. // Trigger post-lighting callbacks
  1082. Camera* sceneCamera = inputs.view.getSceneCamera();
  1083. if (sceneCamera != nullptr)
  1084. {
  1085. for(auto& extension : inputs.extPostLighting)
  1086. {
  1087. if (extension->check(*sceneCamera))
  1088. extension->render(*sceneCamera);
  1089. }
  1090. }
  1091. }
  1092. void RCNodeClusteredForward::clear()
  1093. {
  1094. // Do nothing
  1095. }
  1096. SmallVector<StringID, 4> RCNodeClusteredForward::getDependencies(const RendererView& view)
  1097. {
  1098. return { RCNodeSceneColor::getNodeId(), RCNodeSkybox::getNodeId() };
  1099. }
  1100. void RCNodeSkybox::render(const RenderCompositorNodeInputs& inputs)
  1101. {
  1102. Skybox* skybox = inputs.scene.skybox;
  1103. SPtr<Texture> radiance = skybox ? skybox->getTexture() : nullptr;
  1104. if (radiance != nullptr)
  1105. {
  1106. SkyboxMat* material = SkyboxMat::getVariation(false);
  1107. material->bind(inputs.view.getPerViewBuffer(), radiance, Color::White);
  1108. }
  1109. else
  1110. {
  1111. Color clearColor = inputs.view.getProperties().clearColor;
  1112. SkyboxMat* material = SkyboxMat::getVariation(true);
  1113. material->bind(inputs.view.getPerViewBuffer(), nullptr, clearColor);
  1114. }
  1115. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  1116. int readOnlyFlags = FBT_DEPTH | FBT_STENCIL;
  1117. RenderAPI& rapi = RenderAPI::instance();
  1118. rapi.setRenderTarget(sceneColorNode->renderTarget, readOnlyFlags, RT_COLOR0 | RT_DEPTH_STENCIL);
  1119. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  1120. rapi.setViewport(area);
  1121. SPtr<Mesh> mesh = gRendererUtility().getSkyBoxMesh();
  1122. gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
  1123. }
  1124. void RCNodeSkybox::clear()
  1125. { }
  1126. SmallVector<StringID, 4> RCNodeSkybox::getDependencies(const RendererView& view)
  1127. {
  1128. bool supportsTiledDeferred = gRenderBeast()->getFeatureSet() != RenderBeastFeatureSet::DesktopMacOS;
  1129. SmallVector<StringID, 4> deps;
  1130. deps.push_back(RCNodeSceneColor::getNodeId());
  1131. if(supportsTiledDeferred)
  1132. {
  1133. deps.push_back(RCNodeTiledDeferredIBL::getNodeId());
  1134. if (view.getProperties().numSamples > 1)
  1135. deps.push_back(RCNodeUnflattenSceneColor::getNodeId());
  1136. }
  1137. else
  1138. deps.push_back(RCNodeIndirectLighting::getNodeId());
  1139. return deps;
  1140. }
  1141. void RCNodeFinalResolve::render(const RenderCompositorNodeInputs& inputs)
  1142. {
  1143. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1144. SPtr<Texture> input;
  1145. if(viewProps.runPostProcessing)
  1146. {
  1147. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[0]);
  1148. // Note: Ideally the last PP effect could write directly to the final target and we could avoid this copy
  1149. input = postProcessNode->getLastOutput();
  1150. }
  1151. else
  1152. {
  1153. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  1154. input = sceneColorNode->sceneColorTex->texture;
  1155. }
  1156. SPtr<RenderTarget> target = viewProps.target;
  1157. RenderAPI& rapi = RenderAPI::instance();
  1158. rapi.setRenderTarget(target);
  1159. rapi.setViewport(viewProps.nrmViewRect);
  1160. gRendererUtility().blit(input, Rect2I::EMPTY, viewProps.flipView);
  1161. if(viewProps.encodeDepth)
  1162. {
  1163. RCNodeResolvedSceneDepth* resolvedSceneDepthNode = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[0]);
  1164. EncodeDepthMat* encodeDepthMat = EncodeDepthMat::get();
  1165. encodeDepthMat->execute(resolvedSceneDepthNode->output->texture, viewProps.depthEncodeNear,
  1166. viewProps.depthEncodeFar, target);
  1167. }
  1168. // Trigger overlay callbacks
  1169. Camera* sceneCamera = inputs.view.getSceneCamera();
  1170. if (sceneCamera != nullptr)
  1171. {
  1172. for(auto& extension : inputs.extOverlay)
  1173. {
  1174. if (extension->check(*sceneCamera))
  1175. extension->render(*sceneCamera);
  1176. }
  1177. }
  1178. }
  1179. void RCNodeFinalResolve::clear()
  1180. { }
  1181. SmallVector<StringID, 4> RCNodeFinalResolve::getDependencies(const RendererView& view)
  1182. {
  1183. const RendererViewProperties& viewProps = view.getProperties();
  1184. SmallVector<StringID, 4> deps;
  1185. if(viewProps.runPostProcessing)
  1186. {
  1187. deps.push_back(RCNodePostProcess::getNodeId());
  1188. deps.push_back(RCNodeFXAA::getNodeId());
  1189. }
  1190. else
  1191. {
  1192. deps.push_back(RCNodeSceneColor::getNodeId());
  1193. deps.push_back(RCNodeClusteredForward::getNodeId());
  1194. }
  1195. if(viewProps.encodeDepth)
  1196. deps.push_back(RCNodeResolvedSceneDepth::getNodeId());
  1197. return deps;
  1198. }
  1199. RCNodePostProcess::RCNodePostProcess()
  1200. :mOutput(), mAllocated()
  1201. { }
  1202. void RCNodePostProcess::getAndSwitch(const RendererView& view, SPtr<RenderTexture>& output, SPtr<Texture>& lastFrame) const
  1203. {
  1204. GpuResourcePool& resPool = GpuResourcePool::instance();
  1205. const RendererViewProperties& viewProps = view.getProperties();
  1206. UINT32 width = viewProps.viewRect.width;
  1207. UINT32 height = viewProps.viewRect.height;
  1208. if(!mAllocated[mCurrentIdx])
  1209. {
  1210. mOutput[mCurrentIdx] = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA8, width, height,
  1211. TU_RENDERTARGET, 1, false));
  1212. mAllocated[mCurrentIdx] = true;
  1213. }
  1214. output = mOutput[mCurrentIdx]->renderTexture;
  1215. UINT32 otherIdx = (mCurrentIdx + 1) % 2;
  1216. if (mAllocated[otherIdx])
  1217. lastFrame = mOutput[otherIdx]->texture;
  1218. mCurrentIdx = otherIdx;
  1219. }
  1220. SPtr<Texture> RCNodePostProcess::getLastOutput() const
  1221. {
  1222. UINT32 otherIdx = (mCurrentIdx + 1) % 2;
  1223. if (mAllocated[otherIdx])
  1224. return mOutput[otherIdx]->texture;
  1225. return nullptr;
  1226. }
  1227. void RCNodePostProcess::render(const RenderCompositorNodeInputs& inputs)
  1228. {
  1229. // Do nothing, this is just a helper node
  1230. }
  1231. void RCNodePostProcess::clear()
  1232. {
  1233. GpuResourcePool& resPool = GpuResourcePool::instance();
  1234. if (mAllocated[0])
  1235. resPool.release(mOutput[0]);
  1236. if (mAllocated[1])
  1237. resPool.release(mOutput[1]);
  1238. mAllocated[0] = false;
  1239. mAllocated[1] = false;
  1240. mCurrentIdx = 0;
  1241. }
  1242. SmallVector<StringID, 4> RCNodePostProcess::getDependencies(const RendererView& view)
  1243. {
  1244. return {};
  1245. }
  1246. RCNodeTonemapping::~RCNodeTonemapping()
  1247. {
  1248. GpuResourcePool& resPool = GpuResourcePool::instance();
  1249. if (mTonemapLUT)
  1250. resPool.release(mTonemapLUT);
  1251. if (prevEyeAdaptation)
  1252. resPool.release(prevEyeAdaptation);
  1253. }
  1254. void RCNodeTonemapping::render(const RenderCompositorNodeInputs& inputs)
  1255. {
  1256. GpuResourcePool& resPool = GpuResourcePool::instance();
  1257. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1258. const RenderSettings& settings = inputs.view.getRenderSettings();
  1259. RCNodeSceneColor* sceneColorNode = static_cast<RCNodeSceneColor*>(inputs.inputNodes[0]);
  1260. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[2]);
  1261. SPtr<Texture> sceneColor = sceneColorNode->sceneColorTex->texture;
  1262. bool hdr = settings.enableHDR;
  1263. bool msaa = viewProps.numSamples > 1;
  1264. if(hdr && settings.enableAutoExposure)
  1265. {
  1266. // Downsample scene
  1267. DownsampleMat* downsampleMat = DownsampleMat::getVariation(1, msaa);
  1268. SPtr<PooledRenderTexture> downsampledScene = resPool.get(DownsampleMat::getOutputDesc(sceneColor));
  1269. downsampleMat->execute(sceneColor, downsampledScene->renderTexture);
  1270. if(useHistogramEyeAdapatation(inputs))
  1271. {
  1272. // Generate histogram
  1273. SPtr<PooledRenderTexture> eyeAdaptHistogram =
  1274. resPool.get(EyeAdaptHistogramMat::getOutputDesc(downsampledScene->texture));
  1275. EyeAdaptHistogramMat* eyeAdaptHistogramMat = EyeAdaptHistogramMat::get();
  1276. eyeAdaptHistogramMat->execute(downsampledScene->texture, eyeAdaptHistogram->texture, settings.autoExposure);
  1277. // Reduce histogram
  1278. SPtr<PooledRenderTexture> reducedHistogram = resPool.get(EyeAdaptHistogramReduceMat::getOutputDesc());
  1279. SPtr<Texture> prevFrameEyeAdaptation;
  1280. if (prevEyeAdaptation != nullptr)
  1281. prevFrameEyeAdaptation = prevEyeAdaptation->texture;
  1282. EyeAdaptHistogramReduceMat* eyeAdaptHistogramReduce = EyeAdaptHistogramReduceMat::get();
  1283. eyeAdaptHistogramReduce->execute(
  1284. downsampledScene->texture,
  1285. eyeAdaptHistogram->texture,
  1286. prevFrameEyeAdaptation,
  1287. reducedHistogram->renderTexture);
  1288. resPool.release(downsampledScene);
  1289. downsampledScene = nullptr;
  1290. resPool.release(eyeAdaptHistogram);
  1291. eyeAdaptHistogram = nullptr;
  1292. // Generate eye adaptation value
  1293. eyeAdaptation = resPool.get(EyeAdaptationMat::getOutputDesc());
  1294. EyeAdaptationMat* eyeAdaptationMat = EyeAdaptationMat::get();
  1295. eyeAdaptationMat->execute(
  1296. reducedHistogram->texture,
  1297. eyeAdaptation->renderTexture,
  1298. inputs.frameInfo.timeDelta,
  1299. settings.autoExposure,
  1300. settings.exposureScale);
  1301. resPool.release(reducedHistogram);
  1302. reducedHistogram = nullptr;
  1303. }
  1304. else
  1305. {
  1306. // Populate alpha values of the downsampled texture with luminance
  1307. SPtr<PooledRenderTexture> luminanceTex =
  1308. resPool.get(EyeAdaptationBasicSetupMat::getOutputDesc(downsampledScene->texture));
  1309. EyeAdaptationBasicSetupMat* setupMat = EyeAdaptationBasicSetupMat::get();
  1310. setupMat->execute(
  1311. downsampledScene->texture,
  1312. luminanceTex->renderTexture,
  1313. inputs.frameInfo.timeDelta,
  1314. settings.autoExposure,
  1315. settings.exposureScale);
  1316. SPtr<Texture> downsampleInput = luminanceTex->texture;
  1317. luminanceTex = nullptr;
  1318. // Downsample some more
  1319. for(UINT32 i = 0; i < 5; i++)
  1320. {
  1321. downsampleMat = DownsampleMat::getVariation(1, false);
  1322. SPtr<PooledRenderTexture> downsampledLuminance =
  1323. resPool.get(DownsampleMat::getOutputDesc(downsampleInput));
  1324. downsampleMat->execute(downsampleInput, downsampledLuminance->renderTexture);
  1325. downsampleInput = downsampledLuminance->texture;
  1326. }
  1327. // Generate eye adaptation value
  1328. EyeAdaptationBasicMat* eyeAdaptationMat = EyeAdaptationBasicMat::get();
  1329. SPtr<Texture> prevFrameEyeAdaptation;
  1330. if (prevEyeAdaptation != nullptr)
  1331. prevFrameEyeAdaptation = prevEyeAdaptation->texture;
  1332. eyeAdaptation = resPool.get(EyeAdaptationBasicMat::getOutputDesc());
  1333. eyeAdaptationMat->execute(
  1334. downsampleInput,
  1335. prevFrameEyeAdaptation,
  1336. eyeAdaptation->renderTexture,
  1337. inputs.frameInfo.timeDelta,
  1338. settings.autoExposure,
  1339. settings.exposureScale);
  1340. }
  1341. }
  1342. else
  1343. {
  1344. if(prevEyeAdaptation)
  1345. resPool.release(prevEyeAdaptation);
  1346. prevEyeAdaptation = nullptr;
  1347. eyeAdaptation = nullptr;
  1348. }
  1349. bool volumeLUT = inputs.featureSet == RenderBeastFeatureSet::Desktop;
  1350. bool gammaOnly;
  1351. bool autoExposure;
  1352. if (hdr)
  1353. {
  1354. if (settings.enableTonemapping)
  1355. {
  1356. UINT64 latestHash = inputs.view.getRenderSettingsHash();
  1357. bool tonemapLUTDirty = mTonemapLastUpdateHash != latestHash;
  1358. if (tonemapLUTDirty) // Rebuild LUT if PP settings changed
  1359. {
  1360. CreateTonemapLUTMat* createLUT = CreateTonemapLUTMat::getVariation(volumeLUT);
  1361. if(mTonemapLUT == nullptr)
  1362. mTonemapLUT = resPool.get(createLUT->getOutputDesc());
  1363. if(volumeLUT)
  1364. createLUT->execute3D(mTonemapLUT->texture, settings);
  1365. else
  1366. createLUT->execute2D(mTonemapLUT->renderTexture, settings);
  1367. mTonemapLastUpdateHash = latestHash;
  1368. }
  1369. gammaOnly = false;
  1370. }
  1371. else
  1372. gammaOnly = true;
  1373. autoExposure = settings.enableAutoExposure;
  1374. }
  1375. else
  1376. {
  1377. gammaOnly = true;
  1378. autoExposure = false;
  1379. }
  1380. if(gammaOnly)
  1381. {
  1382. if(mTonemapLUT)
  1383. {
  1384. resPool.release(mTonemapLUT);
  1385. mTonemapLUT = nullptr;
  1386. }
  1387. }
  1388. TonemappingMat* tonemapping = TonemappingMat::getVariation(volumeLUT, gammaOnly, autoExposure, msaa);
  1389. SPtr<RenderTexture> ppOutput;
  1390. SPtr<Texture> ppLastFrame;
  1391. postProcessNode->getAndSwitch(inputs.view, ppOutput, ppLastFrame);
  1392. SPtr<Texture> eyeAdaptationTex;
  1393. if (eyeAdaptation)
  1394. eyeAdaptationTex = eyeAdaptation->texture;
  1395. SPtr<Texture> tonemapLUTTex;
  1396. if (mTonemapLUT)
  1397. tonemapLUTTex = mTonemapLUT->texture;
  1398. tonemapping->execute(sceneColor, eyeAdaptationTex, tonemapLUTTex, ppOutput, settings);
  1399. }
  1400. void RCNodeTonemapping::clear()
  1401. {
  1402. GpuResourcePool& resPool = GpuResourcePool::instance();
  1403. // Save eye adaptation for next frame
  1404. if(prevEyeAdaptation)
  1405. resPool.release(prevEyeAdaptation);
  1406. std::swap(eyeAdaptation, prevEyeAdaptation);
  1407. }
  1408. bool RCNodeTonemapping::useHistogramEyeAdapatation(const RenderCompositorNodeInputs& inputs)
  1409. {
  1410. return inputs.featureSet == RenderBeastFeatureSet::Desktop;
  1411. }
  1412. SmallVector<StringID, 4> RCNodeTonemapping::getDependencies(const RendererView& view)
  1413. {
  1414. return{ RCNodeSceneColor::getNodeId(), RCNodeClusteredForward::getNodeId(), RCNodePostProcess::getNodeId() };
  1415. }
  1416. void RCNodeGaussianDOF::render(const RenderCompositorNodeInputs& inputs)
  1417. {
  1418. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
  1419. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[2]);
  1420. const DepthOfFieldSettings& settings = inputs.view.getRenderSettings().depthOfField;
  1421. bool near = settings.nearBlurAmount > 0.0f;
  1422. bool far = settings.farBlurAmount > 0.0f;
  1423. bool enabled = settings.enabled && (near || far);
  1424. if(!enabled)
  1425. return;
  1426. GaussianDOFSeparateMat* separateMat = GaussianDOFSeparateMat::getVariation(near, far);
  1427. GaussianDOFCombineMat* combineMat = GaussianDOFCombineMat::getVariation(near, far);
  1428. GaussianBlurMat* blurMat = GaussianBlurMat::get();
  1429. SPtr<RenderTexture> ppOutput;
  1430. SPtr<Texture> ppLastFrame;
  1431. postProcessNode->getAndSwitch(inputs.view, ppOutput, ppLastFrame);
  1432. separateMat->execute(ppLastFrame, sceneDepthNode->depthTex->texture, inputs.view, settings);
  1433. SPtr<PooledRenderTexture> nearTex, farTex;
  1434. if(near && far)
  1435. {
  1436. nearTex = separateMat->getOutput(0);
  1437. farTex = separateMat->getOutput(1);
  1438. }
  1439. else
  1440. {
  1441. if (near)
  1442. nearTex = separateMat->getOutput(0);
  1443. else
  1444. farTex = separateMat->getOutput(0);
  1445. }
  1446. // Blur the out of focus pixels
  1447. // Note: Perhaps set up stencil so I can avoid performing blur on unused parts of the textures?
  1448. const TextureProperties& texProps = nearTex ? nearTex->texture->getProperties() : farTex->texture->getProperties();
  1449. POOLED_RENDER_TEXTURE_DESC tempTexDesc = POOLED_RENDER_TEXTURE_DESC::create2D(texProps.getFormat(),
  1450. texProps.getWidth(), texProps.getHeight(), TU_RENDERTARGET);
  1451. SPtr<PooledRenderTexture> tempTexture = GpuResourcePool::instance().get(tempTexDesc);
  1452. SPtr<Texture> blurredNearTex;
  1453. if(nearTex)
  1454. {
  1455. blurMat->execute(nearTex->texture, settings.nearBlurAmount, tempTexture->renderTexture);
  1456. blurredNearTex = tempTexture->texture;
  1457. }
  1458. SPtr<Texture> blurredFarTex;
  1459. if(farTex)
  1460. {
  1461. // If temporary texture is used up, re-use the original near texture for the blurred result
  1462. if(blurredNearTex)
  1463. {
  1464. blurMat->execute(farTex->texture, settings.farBlurAmount, nearTex->renderTexture);
  1465. blurredFarTex = nearTex->texture;
  1466. }
  1467. else // Otherwise just use the temporary
  1468. {
  1469. blurMat->execute(farTex->texture, settings.farBlurAmount, tempTexture->renderTexture);
  1470. blurredFarTex = tempTexture->texture;
  1471. }
  1472. }
  1473. combineMat->execute(ppLastFrame, blurredNearTex, blurredFarTex,
  1474. sceneDepthNode->depthTex->texture, ppOutput, inputs.view, settings);
  1475. separateMat->release();
  1476. GpuResourcePool::instance().release(tempTexture);
  1477. }
  1478. void RCNodeGaussianDOF::clear()
  1479. {
  1480. // Do nothing
  1481. }
  1482. SmallVector<StringID, 4> RCNodeGaussianDOF::getDependencies(const RendererView& view)
  1483. {
  1484. return { RCNodeTonemapping::getNodeId(), RCNodeSceneDepth::getNodeId(), RCNodePostProcess::getNodeId() };
  1485. }
  1486. void RCNodeFXAA::render(const RenderCompositorNodeInputs& inputs)
  1487. {
  1488. const RenderSettings& settings = inputs.view.getRenderSettings();
  1489. if (!settings.enableFXAA)
  1490. return;
  1491. RCNodePostProcess* postProcessNode = static_cast<RCNodePostProcess*>(inputs.inputNodes[1]);
  1492. SPtr<RenderTexture> ppOutput;
  1493. SPtr<Texture> ppLastFrame;
  1494. postProcessNode->getAndSwitch(inputs.view, ppOutput, ppLastFrame);
  1495. // Note: I could skip executing FXAA over DOF and motion blurred pixels
  1496. FXAAMat* fxaa = FXAAMat::get();
  1497. fxaa->execute(ppLastFrame, ppOutput);
  1498. }
  1499. void RCNodeFXAA::clear()
  1500. {
  1501. // Do nothing
  1502. }
  1503. SmallVector<StringID, 4> RCNodeFXAA::getDependencies(const RendererView& view)
  1504. {
  1505. return { RCNodeGaussianDOF::getNodeId(), RCNodePostProcess::getNodeId() };
  1506. }
  1507. void RCNodeResolvedSceneDepth::render(const RenderCompositorNodeInputs& inputs)
  1508. {
  1509. GpuResourcePool& resPool = GpuResourcePool::instance();
  1510. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1511. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  1512. if (viewProps.numSamples > 1)
  1513. {
  1514. UINT32 width = viewProps.viewRect.width;
  1515. UINT32 height = viewProps.viewRect.height;
  1516. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_D32_S8X24, width, height,
  1517. TU_DEPTHSTENCIL, 1, false));
  1518. RenderAPI& rapi = RenderAPI::instance();
  1519. rapi.setRenderTarget(output->renderTexture);
  1520. rapi.clearRenderTarget(FBT_STENCIL);
  1521. gRendererUtility().blit(sceneDepthNode->depthTex->texture, Rect2I::EMPTY, false, true);
  1522. mPassThrough = false;
  1523. }
  1524. else
  1525. {
  1526. output = sceneDepthNode->depthTex;
  1527. mPassThrough = true;
  1528. }
  1529. }
  1530. void RCNodeResolvedSceneDepth::clear()
  1531. {
  1532. GpuResourcePool& resPool = GpuResourcePool::instance();
  1533. if (!mPassThrough)
  1534. resPool.release(output);
  1535. else
  1536. output = nullptr;
  1537. mPassThrough = false;
  1538. }
  1539. SmallVector<StringID, 4> RCNodeResolvedSceneDepth::getDependencies(const RendererView& view)
  1540. {
  1541. // GBuffer require because it renders the base pass (populates the depth buffer)
  1542. return { RCNodeSceneDepth::getNodeId(), RCNodeGBuffer::getNodeId() };
  1543. }
  1544. void RCNodeHiZ::render(const RenderCompositorNodeInputs& inputs)
  1545. {
  1546. GpuResourcePool& resPool = GpuResourcePool::instance();
  1547. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1548. RCNodeResolvedSceneDepth* resolvedSceneDepth = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[0]);
  1549. UINT32 width = viewProps.viewRect.width;
  1550. UINT32 height = viewProps.viewRect.height;
  1551. UINT32 size = Bitwise::nextPow2(std::max(width, height));
  1552. UINT32 numMips = PixelUtil::getMaxMipmaps(size, size, 1, PF_R32F);
  1553. size = 1 << numMips;
  1554. // Note: Use the 32-bit buffer here as 16-bit causes too much banding (most of the scene gets assigned 4-5 different
  1555. // depth values).
  1556. // - When I add UNORM 16-bit format I should be able to switch to that
  1557. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R32F, size, size, TU_RENDERTARGET, 1, false, 1,
  1558. numMips));
  1559. Rect2 srcRect = viewProps.nrmViewRect;
  1560. // If viewport size is odd, adjust UV
  1561. srcRect.width += (viewProps.viewRect.width % 2) * (1.0f / viewProps.viewRect.width);
  1562. srcRect.height += (viewProps.viewRect.height % 2) * (1.0f / viewProps.viewRect.height);
  1563. // Generate first mip
  1564. RENDER_TEXTURE_DESC rtDesc;
  1565. rtDesc.colorSurfaces[0].texture = output->texture;
  1566. rtDesc.colorSurfaces[0].mipLevel = 0;
  1567. SPtr<RenderTexture> rt = RenderTexture::create(rtDesc);
  1568. Rect2 destRect;
  1569. bool downsampledFirstMip = false; // Not used currently
  1570. if (downsampledFirstMip)
  1571. {
  1572. // Make sure that 1 pixel in HiZ maps to a 2x2 block in source
  1573. destRect = Rect2(0, 0,
  1574. Math::ceilToInt(viewProps.viewRect.width / 2.0f) / (float)size,
  1575. Math::ceilToInt(viewProps.viewRect.height / 2.0f) / (float)size);
  1576. BuildHiZMat* material = BuildHiZMat::get();
  1577. material->execute(resolvedSceneDepth->output->texture, 0, srcRect, destRect, rt);
  1578. }
  1579. else // First level is just a copy of the depth buffer
  1580. {
  1581. destRect = Rect2(0, 0,
  1582. viewProps.viewRect.width / (float)size,
  1583. viewProps.viewRect.height / (float)size);
  1584. RenderAPI& rapi = RenderAPI::instance();
  1585. rapi.setRenderTarget(rt);
  1586. rapi.setViewport(destRect);
  1587. Rect2I srcAreaInt;
  1588. srcAreaInt.x = (INT32)(srcRect.x * viewProps.viewRect.width);
  1589. srcAreaInt.y = (INT32)(srcRect.y * viewProps.viewRect.height);
  1590. srcAreaInt.width = (UINT32)(srcRect.width * viewProps.viewRect.width);
  1591. srcAreaInt.height = (UINT32)(srcRect.height * viewProps.viewRect.height);
  1592. gRendererUtility().blit(resolvedSceneDepth->output->texture, srcAreaInt);
  1593. rapi.setViewport(Rect2(0, 0, 1, 1));
  1594. }
  1595. // Generate remaining mip levels
  1596. for(UINT32 i = 1; i <= numMips; i++)
  1597. {
  1598. rtDesc.colorSurfaces[0].mipLevel = i;
  1599. rt = RenderTexture::create(rtDesc);
  1600. BuildHiZMat* material = BuildHiZMat::get();
  1601. material->execute(output->texture, i - 1, destRect, destRect, rt);
  1602. }
  1603. }
  1604. void RCNodeHiZ::clear()
  1605. {
  1606. GpuResourcePool& resPool = GpuResourcePool::instance();
  1607. resPool.release(output);
  1608. }
  1609. SmallVector<StringID, 4> RCNodeHiZ::getDependencies(const RendererView& view)
  1610. {
  1611. // Note: This doesn't actually use any gbuffer textures, but node is a dependency because it renders to the depth
  1612. // buffer. In order to avoid keeping gbuffer textures alive I could separate out the base pass into its own node
  1613. // perhaps. But at the moment it doesn't matter, as anything using HiZ also needs gbuffer.
  1614. return { RCNodeResolvedSceneDepth::getNodeId(), RCNodeGBuffer::getNodeId() };
  1615. }
  1616. void RCNodeSSAO::render(const RenderCompositorNodeInputs& inputs)
  1617. {
  1618. /** Maximum valid depth range within samples in a sample set. In meters. */
  1619. static const float DEPTH_RANGE = 1.0f;
  1620. GpuResourcePool& resPool = GpuResourcePool::instance();
  1621. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1622. const AmbientOcclusionSettings& settings = inputs.view.getRenderSettings().ambientOcclusion;
  1623. RCNodeResolvedSceneDepth* resolvedDepthNode = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[0]);
  1624. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[1]);
  1625. SPtr<Texture> sceneDepth = resolvedDepthNode->output->texture;
  1626. SPtr<Texture> sceneNormals = gbufferNode->normalTex->texture;
  1627. const TextureProperties& normalsProps = sceneNormals->getProperties();
  1628. SPtr<PooledRenderTexture> resolvedNormals;
  1629. RenderAPI& rapi = RenderAPI::instance();
  1630. if(sceneNormals->getProperties().getNumSamples() > 1)
  1631. {
  1632. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(normalsProps.getFormat(),
  1633. normalsProps.getWidth(), normalsProps.getHeight(), TU_RENDERTARGET);
  1634. resolvedNormals = resPool.get(desc);
  1635. rapi.setRenderTarget(resolvedNormals->renderTexture);
  1636. gRendererUtility().blit(sceneNormals);
  1637. sceneNormals = resolvedNormals->texture;
  1638. }
  1639. // Multiple downsampled AO levels are used to minimize cache trashing. Downsampled AO targets use larger radius,
  1640. // whose contents are then blended with the higher level.
  1641. UINT32 quality = settings.quality;
  1642. UINT32 numDownsampleLevels = 0;
  1643. if (quality > 1)
  1644. numDownsampleLevels = 1;
  1645. else if (quality > 2)
  1646. numDownsampleLevels = 2;
  1647. SSAODownsampleMat* downsample = SSAODownsampleMat::get();
  1648. SPtr<PooledRenderTexture> setupTex0;
  1649. if(numDownsampleLevels > 0)
  1650. {
  1651. Vector2I downsampledSize(
  1652. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 2)),
  1653. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 2))
  1654. );
  1655. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, downsampledSize.x,
  1656. downsampledSize.y, TU_RENDERTARGET);
  1657. setupTex0 = GpuResourcePool::instance().get(desc);
  1658. downsample->execute(inputs.view, sceneDepth, sceneNormals, setupTex0->renderTexture, DEPTH_RANGE);
  1659. }
  1660. SPtr<PooledRenderTexture> setupTex1;
  1661. if(numDownsampleLevels > 1)
  1662. {
  1663. Vector2I downsampledSize(
  1664. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 4)),
  1665. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 4))
  1666. );
  1667. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, downsampledSize.x,
  1668. downsampledSize.y, TU_RENDERTARGET);
  1669. setupTex1 = GpuResourcePool::instance().get(desc);
  1670. downsample->execute(inputs.view, sceneDepth, sceneNormals, setupTex1->renderTexture, DEPTH_RANGE);
  1671. }
  1672. SSAOTextureInputs textures;
  1673. textures.sceneDepth = sceneDepth;
  1674. textures.sceneNormals = sceneNormals;
  1675. textures.randomRotations = RendererTextures::ssaoRandomization4x4;
  1676. SPtr<PooledRenderTexture> downAOTex1;
  1677. if(numDownsampleLevels > 1)
  1678. {
  1679. textures.aoSetup = setupTex1->texture;
  1680. Vector2I downsampledSize(
  1681. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 4)),
  1682. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 4))
  1683. );
  1684. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, downsampledSize.x,
  1685. downsampledSize.y, TU_RENDERTARGET);
  1686. downAOTex1 = GpuResourcePool::instance().get(desc);
  1687. SSAOMat* ssaoMat = SSAOMat::getVariation(false, false, quality);
  1688. ssaoMat->execute(inputs.view, textures, downAOTex1->renderTexture, settings);
  1689. GpuResourcePool::instance().release(setupTex1);
  1690. setupTex1 = nullptr;
  1691. }
  1692. SPtr<PooledRenderTexture> downAOTex0;
  1693. if(numDownsampleLevels > 0)
  1694. {
  1695. textures.aoSetup = setupTex0->texture;
  1696. if(downAOTex1)
  1697. textures.aoDownsampled = downAOTex1->texture;
  1698. Vector2I downsampledSize(
  1699. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.width, 2)),
  1700. std::max(1, Math::divideAndRoundUp((INT32)viewProps.viewRect.height, 2))
  1701. );
  1702. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, downsampledSize.x,
  1703. downsampledSize.y, TU_RENDERTARGET);
  1704. downAOTex0 = GpuResourcePool::instance().get(desc);
  1705. bool upsample = numDownsampleLevels > 1;
  1706. SSAOMat* ssaoMat = SSAOMat::getVariation(upsample, false, quality);
  1707. ssaoMat->execute(inputs.view, textures, downAOTex0->renderTexture, settings);
  1708. if(upsample)
  1709. {
  1710. GpuResourcePool::instance().release(downAOTex1);
  1711. downAOTex1 = nullptr;
  1712. }
  1713. }
  1714. UINT32 width = viewProps.viewRect.width;
  1715. UINT32 height = viewProps.viewRect.height;
  1716. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width, height, TU_RENDERTARGET));
  1717. {
  1718. if(setupTex0)
  1719. textures.aoSetup = setupTex0->texture;
  1720. if(downAOTex0)
  1721. textures.aoDownsampled = downAOTex0->texture;
  1722. bool upsample = numDownsampleLevels > 0;
  1723. SSAOMat* ssaoMat = SSAOMat::getVariation(upsample, true, quality);
  1724. ssaoMat->execute(inputs.view, textures, output->renderTexture, settings);
  1725. }
  1726. if(resolvedNormals)
  1727. {
  1728. GpuResourcePool::instance().release(resolvedNormals);
  1729. resolvedNormals = nullptr;
  1730. }
  1731. if(numDownsampleLevels > 0)
  1732. {
  1733. GpuResourcePool::instance().release(setupTex0);
  1734. GpuResourcePool::instance().release(downAOTex0);
  1735. }
  1736. // Blur the output
  1737. // Note: If I implement temporal AA then this can probably be avoided. I can instead jitter the sample offsets
  1738. // each frame, and averaging them out should yield blurred AO.
  1739. if(quality > 1) // On level 0 we don't blur at all, on level 1 we use the ad-hoc blur in shader
  1740. {
  1741. const RenderTargetProperties& rtProps = output->renderTexture->getProperties();
  1742. POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, rtProps.width,
  1743. rtProps.height, TU_RENDERTARGET);
  1744. SPtr<PooledRenderTexture> blurIntermediateTex = GpuResourcePool::instance().get(desc);
  1745. SSAOBlurMat* blurHorz = SSAOBlurMat::getVariation(true);
  1746. SSAOBlurMat* blurVert = SSAOBlurMat::getVariation(false);
  1747. blurHorz->execute(inputs.view, output->texture, sceneDepth, blurIntermediateTex->renderTexture, DEPTH_RANGE);
  1748. blurVert->execute(inputs.view, blurIntermediateTex->texture, sceneDepth, output->renderTexture, DEPTH_RANGE);
  1749. GpuResourcePool::instance().release(blurIntermediateTex);
  1750. }
  1751. RenderAPI::instance().setRenderTarget(nullptr);
  1752. }
  1753. void RCNodeSSAO::clear()
  1754. {
  1755. GpuResourcePool& resPool = GpuResourcePool::instance();
  1756. resPool.release(output);
  1757. }
  1758. SmallVector<StringID, 4> RCNodeSSAO::getDependencies(const RendererView& view)
  1759. {
  1760. return { RCNodeResolvedSceneDepth::getNodeId(), RCNodeGBuffer::getNodeId() };
  1761. }
  1762. RCNodeSSR::~RCNodeSSR()
  1763. {
  1764. deallocOutputs();
  1765. }
  1766. void RCNodeSSR::render(const RenderCompositorNodeInputs& inputs)
  1767. {
  1768. const ScreenSpaceReflectionsSettings& settings = inputs.view.getRenderSettings().screenSpaceReflections;
  1769. if (settings.enabled)
  1770. {
  1771. RenderAPI& rapi = RenderAPI::instance();
  1772. RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[0]);
  1773. RCNodeLightAccumulation* lightAccumNode = static_cast<RCNodeLightAccumulation*>(inputs.inputNodes[1]);
  1774. RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[2]);
  1775. RCNodeHiZ* hiZNode = static_cast<RCNodeHiZ*>(inputs.inputNodes[3]);
  1776. RCNodeResolvedSceneDepth* resolvedSceneDepthNode = static_cast<RCNodeResolvedSceneDepth*>(inputs.inputNodes[4]);
  1777. GpuResourcePool& resPool = GpuResourcePool::instance();
  1778. const RendererViewProperties& viewProps = inputs.view.getProperties();
  1779. UINT32 width = viewProps.viewRect.width;
  1780. UINT32 height = viewProps.viewRect.height;
  1781. SPtr<Texture> hiZ = hiZNode->output->texture;
  1782. // This will be executing before scene color is resolved, so get the light accum buffer instead
  1783. SPtr<Texture> sceneColor = lightAccumNode->lightAccumulationTex->texture;
  1784. // Resolve multiple samples if MSAA is used
  1785. SPtr<PooledRenderTexture> resolvedSceneColor;
  1786. if(viewProps.numSamples > 1)
  1787. {
  1788. resolvedSceneColor = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width, height,
  1789. TU_RENDERTARGET));
  1790. rapi.setRenderTarget(resolvedSceneColor->renderTexture);
  1791. gRendererUtility().blit(sceneColor);
  1792. sceneColor = resolvedSceneColor->texture;
  1793. }
  1794. GBufferTextures gbuffer;
  1795. gbuffer.albedo = gbufferNode->albedoTex->texture;
  1796. gbuffer.normals = gbufferNode->normalTex->texture;
  1797. gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
  1798. gbuffer.depth = sceneDepthNode->depthTex->texture;
  1799. SSRStencilMat* stencilMat = SSRStencilMat::getVariation(viewProps.numSamples > 1, true);
  1800. // Note: Making the assumption that the stencil buffer is clear at this point
  1801. rapi.setRenderTarget(resolvedSceneDepthNode->output->renderTexture, FBT_DEPTH, RT_DEPTH_STENCIL);
  1802. stencilMat->execute(inputs.view, gbuffer, settings);
  1803. SPtr<PooledRenderTexture> traceOutput = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width,
  1804. height, TU_RENDERTARGET));
  1805. RENDER_TEXTURE_DESC traceRtDesc;
  1806. traceRtDesc.colorSurfaces[0].texture = traceOutput->texture;
  1807. traceRtDesc.depthStencilSurface.texture = resolvedSceneDepthNode->output->texture;
  1808. SPtr<RenderTexture> traceRt = RenderTexture::create(traceRtDesc);
  1809. rapi.setRenderTarget(traceRt, FBT_DEPTH | FBT_STENCIL, RT_DEPTH_STENCIL);
  1810. rapi.clearRenderTarget(FBT_COLOR, Color::ZERO);
  1811. SSRTraceMat* traceMat = SSRTraceMat::getVariation(settings.quality, viewProps.numSamples > 1, true);
  1812. traceMat->execute(inputs.view, gbuffer, sceneColor, hiZ, settings, traceRt);
  1813. if (resolvedSceneColor)
  1814. {
  1815. resPool.release(resolvedSceneColor);
  1816. resolvedSceneColor = nullptr;
  1817. }
  1818. if (mPrevFrame)
  1819. {
  1820. output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_RGBA16F, width, height, TU_RENDERTARGET));
  1821. rapi.setRenderTarget(output->renderTexture);
  1822. rapi.clearRenderTarget(FBT_COLOR);
  1823. SSRResolveMat* resolveMat = SSRResolveMat::getVariation(viewProps.numSamples > 1);
  1824. resolveMat->execute(inputs.view, mPrevFrame->texture, traceOutput->texture, sceneDepthNode->depthTex->texture,
  1825. output->renderTexture);
  1826. resPool.release(traceOutput);
  1827. }
  1828. else
  1829. output = traceOutput;
  1830. RenderAPI::instance().setRenderTarget(nullptr);
  1831. }
  1832. else
  1833. deallocOutputs();
  1834. }
  1835. void RCNodeSSR::clear()
  1836. {
  1837. GpuResourcePool& resPool = GpuResourcePool::instance();
  1838. if(mPrevFrame)
  1839. resPool.release(mPrevFrame);
  1840. mPrevFrame = output;
  1841. output = nullptr;
  1842. }
  1843. void RCNodeSSR::deallocOutputs()
  1844. {
  1845. GpuResourcePool& resPool = GpuResourcePool::instance();
  1846. if(mPrevFrame)
  1847. {
  1848. resPool.release(mPrevFrame);
  1849. mPrevFrame = nullptr;
  1850. }
  1851. }
  1852. SmallVector<StringID, 4> RCNodeSSR::getDependencies(const RendererView& view)
  1853. {
  1854. SmallVector<StringID, 4> deps;
  1855. if (view.getRenderSettings().screenSpaceReflections.enabled)
  1856. {
  1857. deps.push_back(RCNodeSceneDepth::getNodeId());
  1858. deps.push_back(RCNodeLightAccumulation::getNodeId());
  1859. deps.push_back(RCNodeGBuffer::getNodeId());
  1860. deps.push_back(RCNodeHiZ::getNodeId());
  1861. deps.push_back(RCNodeResolvedSceneDepth::getNodeId());
  1862. bool supportsTiledDeferred = gRenderBeast()->getFeatureSet() != RenderBeastFeatureSet::DesktopMacOS;
  1863. if(supportsTiledDeferred)
  1864. {
  1865. if (view.getProperties().numSamples > 1)
  1866. deps.push_back(RCNodeUnflattenLightAccum::getNodeId());
  1867. }
  1868. }
  1869. return deps;
  1870. }
  1871. }}