| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #include <AnKi/Renderer/IndirectDiffuseProbes.h>
- #include <AnKi/Renderer/Renderer.h>
- #include <AnKi/Renderer/RenderQueue.h>
- #include <AnKi/Core/ConfigSet.h>
- #include <AnKi/Util/Tracer.h>
- #include <AnKi/Collision/Aabb.h>
- #include <AnKi/Collision/Functions.h>
- namespace anki {
- static NumericCVar<U32> g_indirectDiffuseProbeTileResolutionCVar(CVarSubsystem::kRenderer, "IndirectDiffuseProbeTileResolution",
- (ANKI_PLATFORM_MOBILE) ? 16 : 32, 8, 32, "GI tile resolution");
- static NumericCVar<U32> g_indirectDiffuseProbeShadowMapResolutionCVar(CVarSubsystem::kRenderer, "IndirectDiffuseProbeShadowMapResolution", 128, 4,
- 2048, "GI shadowmap resolution");
- class IndirectDiffuseProbes::InternalContext
- {
- public:
- IndirectDiffuseProbes* m_gi = nullptr;
- RenderingContext* m_ctx = nullptr;
- GlobalIlluminationProbeQueueElementForRefresh* m_probeToUpdateThisFrame = nullptr;
- Array<RenderTargetHandle, kGBufferColorRenderTargetCount> m_gbufferColorRts;
- RenderTargetHandle m_gbufferDepthRt;
- RenderTargetHandle m_shadowsRt;
- RenderTargetHandle m_lightShadingRt;
- RenderTargetHandle m_irradianceVolume;
- Array<GpuVisibilityOutput, 6> m_gbufferVisOut;
- Array<GpuVisibilityOutput, 6> m_shadowsVisOut;
- static void foo()
- {
- static_assert(std::is_trivially_destructible<InternalContext>::value, "See file");
- }
- };
- RenderTargetHandle IndirectDiffuseProbes::getCurrentlyRefreshedVolumeRt() const
- {
- ANKI_ASSERT(m_giCtx && m_giCtx->m_irradianceVolume.isValid());
- return m_giCtx->m_irradianceVolume;
- }
- Bool IndirectDiffuseProbes::hasCurrentlyRefreshedVolumeRt() const
- {
- return m_giCtx != nullptr;
- }
- Error IndirectDiffuseProbes::init()
- {
- const Error err = initInternal();
- if(err)
- {
- ANKI_R_LOGE("Failed to initialize global illumination");
- }
- return err;
- }
- Error IndirectDiffuseProbes::initInternal()
- {
- m_tileSize = g_indirectDiffuseProbeTileResolutionCVar.get();
- ANKI_CHECK(initGBuffer());
- ANKI_CHECK(initLightShading());
- ANKI_CHECK(initShadowMapping());
- ANKI_CHECK(initIrradiance());
- return Error::kNone;
- }
- Error IndirectDiffuseProbes::initGBuffer()
- {
- // Create RT descriptions
- {
- RenderTargetDescription texinit =
- getRenderer().create2DRenderTargetDescription(m_tileSize * 6, m_tileSize, kGBufferColorRenderTargetFormats[0], "GI GBuffer");
- // Create color RT descriptions
- for(U32 i = 0; i < kGBufferColorRenderTargetCount; ++i)
- {
- texinit.m_format = kGBufferColorRenderTargetFormats[i];
- m_gbuffer.m_colorRtDescrs[i] = texinit;
- m_gbuffer.m_colorRtDescrs[i].setName(RendererString().sprintf("GI GBuff Col #%u", i).toCString());
- m_gbuffer.m_colorRtDescrs[i].bake();
- }
- // Create depth RT
- texinit.m_format = getRenderer().getDepthNoStencilFormat();
- texinit.setName("GI GBuff Depth");
- m_gbuffer.m_depthRtDescr = texinit;
- m_gbuffer.m_depthRtDescr.bake();
- }
- // Create FB descr
- {
- m_gbuffer.m_fbDescr.m_colorAttachmentCount = kGBufferColorRenderTargetCount;
- for(U j = 0; j < kGBufferColorRenderTargetCount; ++j)
- {
- m_gbuffer.m_fbDescr.m_colorAttachments[j].m_loadOperation = AttachmentLoadOperation::kClear;
- }
- m_gbuffer.m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
- m_gbuffer.m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
- m_gbuffer.m_fbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0f;
- m_gbuffer.m_fbDescr.bake();
- }
- return Error::kNone;
- }
- Error IndirectDiffuseProbes::initShadowMapping()
- {
- const U32 resolution = g_indirectDiffuseProbeShadowMapResolutionCVar.get();
- ANKI_ASSERT(resolution > 8);
- // RT descr
- m_shadowMapping.m_rtDescr =
- getRenderer().create2DRenderTargetDescription(resolution * 6, resolution, getRenderer().getDepthNoStencilFormat(), "GI SM");
- m_shadowMapping.m_rtDescr.bake();
- // FB descr
- m_shadowMapping.m_fbDescr.m_colorAttachmentCount = 0;
- m_shadowMapping.m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
- m_shadowMapping.m_fbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0f;
- m_shadowMapping.m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
- m_shadowMapping.m_fbDescr.bake();
- return Error::kNone;
- }
- Error IndirectDiffuseProbes::initLightShading()
- {
- // Init RT descr
- {
- m_lightShading.m_rtDescr = getRenderer().create2DRenderTargetDescription(m_tileSize * 6, m_tileSize, getRenderer().getHdrFormat(), "GI LS");
- m_lightShading.m_rtDescr.bake();
- }
- // Create FB descr
- {
- m_lightShading.m_fbDescr.m_colorAttachmentCount = 1;
- m_lightShading.m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::kClear;
- m_lightShading.m_fbDescr.bake();
- }
- // Init deferred
- ANKI_CHECK(m_lightShading.m_deferred.init());
- return Error::kNone;
- }
- Error IndirectDiffuseProbes::initIrradiance()
- {
- ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/IrradianceDice.ankiprogbin", m_irradiance.m_prog));
- ShaderProgramResourceVariantInitInfo variantInitInfo(m_irradiance.m_prog);
- variantInitInfo.addMutation("WORKGROUP_SIZE_XY", m_tileSize);
- variantInitInfo.addMutation("LIGHT_SHADING_TEX", 0);
- variantInitInfo.addMutation("STORE_LOCATION", 0);
- variantInitInfo.addMutation("SECOND_BOUNCE", 1);
- const ShaderProgramResourceVariant* variant;
- m_irradiance.m_prog->getOrCreateVariant(variantInitInfo, variant);
- m_irradiance.m_grProg.reset(&variant->getProgram());
- return Error::kNone;
- }
- void IndirectDiffuseProbes::populateRenderGraph(RenderingContext& rctx)
- {
- ANKI_TRACE_SCOPED_EVENT(RIndirectDiffuse);
- if(rctx.m_renderQueue->m_giProbeForRefresh == nullptr) [[likely]]
- {
- m_giCtx = nullptr;
- return;
- }
- InternalContext* giCtx = newInstance<InternalContext>(*rctx.m_tempPool);
- m_giCtx = giCtx;
- giCtx->m_gi = this;
- giCtx->m_ctx = &rctx;
- giCtx->m_probeToUpdateThisFrame = rctx.m_renderQueue->m_giProbeForRefresh;
- RenderGraphDescription& rgraph = rctx.m_renderGraphDescr;
- // GBuffer visibility
- for(U32 i = 0; i < 6; ++i)
- {
- const RenderQueue& queue = *giCtx->m_probeToUpdateThisFrame->m_renderQueues[i];
- Array<F32, kMaxLodCount - 1> lodDistances = {1000.0f, 1001.0f}; // Something far to force detailed LODs
- getRenderer().getGpuVisibility().populateRenderGraph("GI GBuffer visibility", RenderingTechnique::kGBuffer, queue.m_viewProjectionMatrix,
- queue.m_cameraTransform.getTranslationPart().xyz(), lodDistances, nullptr, rgraph,
- giCtx->m_gbufferVisOut[i]);
- }
- // GBuffer
- {
- // RTs
- for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
- {
- giCtx->m_gbufferColorRts[i] = rgraph.newRenderTarget(m_gbuffer.m_colorRtDescrs[i]);
- }
- giCtx->m_gbufferDepthRt = rgraph.newRenderTarget(m_gbuffer.m_depthRtDescr);
- // Pass
- GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("GI GBuffer");
- pass.setFramebufferInfo(m_gbuffer.m_fbDescr, giCtx->m_gbufferColorRts, giCtx->m_gbufferDepthRt);
- pass.setWork(6, [this](RenderPassWorkContext& rgraphCtx) {
- runGBufferInThread(rgraphCtx);
- });
- for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
- {
- pass.newTextureDependency(giCtx->m_gbufferColorRts[i], TextureUsageBit::kFramebufferWrite);
- }
- TextureSubresourceInfo subresource(DepthStencilAspectBit::kDepth);
- pass.newTextureDependency(giCtx->m_gbufferDepthRt, TextureUsageBit::kAllFramebuffer, subresource);
- pass.newBufferDependency(getRenderer().getGpuSceneBufferHandle(),
- BufferUsageBit::kStorageGeometryRead | BufferUsageBit::kStorageFragmentRead);
- for(U32 i = 0; i < 6; ++i)
- {
- pass.newBufferDependency(giCtx->m_gbufferVisOut[i].m_mdiDrawCountsHandle, BufferUsageBit::kIndirectDraw);
- }
- }
- // Shadow visibility. Optional
- const Bool hasShadows = giCtx->m_probeToUpdateThisFrame->m_renderQueues[0]->m_directionalLight.m_uuid
- && giCtx->m_probeToUpdateThisFrame->m_renderQueues[0]->m_directionalLight.m_shadowCascadeCount > 0;
- if(hasShadows)
- {
- for(U32 i = 0; i < 6; ++i)
- {
- const RenderQueue& queue = *giCtx->m_probeToUpdateThisFrame->m_renderQueues[i]->m_directionalLight.m_shadowRenderQueues[0];
- Array<F32, kMaxLodCount - 1> lodDistances = {1000.0f, 1001.0f}; // Something far to force detailed LODs
- getRenderer().getGpuVisibility().populateRenderGraph("GI shadows visibility", RenderingTechnique::kDepth, queue.m_viewProjectionMatrix,
- queue.m_cameraTransform.getTranslationPart().xyz(), lodDistances, nullptr, rgraph,
- giCtx->m_shadowsVisOut[i]);
- }
- }
- // Shadow pass. Optional
- if(hasShadows)
- {
- // Update light matrices
- for(U i = 0; i < 6; ++i)
- {
- ANKI_ASSERT(giCtx->m_probeToUpdateThisFrame->m_renderQueues[i]->m_directionalLight.m_uuid
- && giCtx->m_probeToUpdateThisFrame->m_renderQueues[i]->m_directionalLight.m_shadowCascadeCount == 1);
- const F32 xScale = 1.0f / 6.0f;
- const F32 yScale = 1.0f;
- const F32 xOffset = F32(i) * (1.0f / 6.0f);
- const F32 yOffset = 0.0f;
- const Mat4 atlasMtx(xScale, 0.0f, 0.0f, xOffset, 0.0f, yScale, 0.0f, yOffset, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
- Mat4& lightMat = giCtx->m_probeToUpdateThisFrame->m_renderQueues[i]->m_directionalLight.m_textureMatrices[0];
- lightMat = atlasMtx * lightMat;
- }
- // RT
- giCtx->m_shadowsRt = rgraph.newRenderTarget(m_shadowMapping.m_rtDescr);
- // Pass
- GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("GI shadows");
- pass.setFramebufferInfo(m_shadowMapping.m_fbDescr, {}, giCtx->m_shadowsRt);
- pass.setWork(6, [this](RenderPassWorkContext& rgraphCtx) {
- runShadowmappingInThread(rgraphCtx);
- });
- TextureSubresourceInfo subresource(DepthStencilAspectBit::kDepth);
- pass.newTextureDependency(giCtx->m_shadowsRt, TextureUsageBit::kAllFramebuffer, subresource);
- pass.newBufferDependency(getRenderer().getGpuSceneBufferHandle(),
- BufferUsageBit::kStorageGeometryRead | BufferUsageBit::kStorageFragmentRead);
- for(U32 i = 0; i < 6; ++i)
- {
- pass.newBufferDependency(giCtx->m_shadowsVisOut[i].m_mdiDrawCountsHandle, BufferUsageBit::kIndirectDraw);
- }
- }
- else
- {
- giCtx->m_shadowsRt = {};
- }
- // Light shading pass
- {
- // RT
- giCtx->m_lightShadingRt = rgraph.newRenderTarget(m_lightShading.m_rtDescr);
- // Pass
- GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("GI light shading");
- pass.setFramebufferInfo(m_lightShading.m_fbDescr, {giCtx->m_lightShadingRt});
- pass.setWork(1, [this](RenderPassWorkContext& rgraphCtx) {
- runLightShading(rgraphCtx);
- });
- pass.newTextureDependency(giCtx->m_lightShadingRt, TextureUsageBit::kFramebufferWrite);
- for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
- {
- pass.newTextureDependency(giCtx->m_gbufferColorRts[i], TextureUsageBit::kSampledFragment);
- }
- pass.newTextureDependency(giCtx->m_gbufferDepthRt, TextureUsageBit::kSampledFragment, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
- if(giCtx->m_shadowsRt.isValid())
- {
- pass.newTextureDependency(giCtx->m_shadowsRt, TextureUsageBit::kSampledFragment);
- }
- }
- // Irradiance pass. First & 2nd bounce
- {
- m_giCtx->m_irradianceVolume = rgraph.importRenderTarget(m_giCtx->m_probeToUpdateThisFrame->m_volumeTexture, TextureUsageBit::kNone);
- ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("GI irradiance");
- pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
- runIrradiance(rgraphCtx);
- });
- pass.newTextureDependency(giCtx->m_lightShadingRt, TextureUsageBit::kSampledCompute);
- for(U32 i = 0; i < kGBufferColorRenderTargetCount - 1; ++i)
- {
- pass.newTextureDependency(giCtx->m_gbufferColorRts[i], TextureUsageBit::kSampledCompute);
- }
- pass.newTextureDependency(m_giCtx->m_irradianceVolume, TextureUsageBit::kImageComputeWrite);
- }
- }
- void IndirectDiffuseProbes::runGBufferInThread(RenderPassWorkContext& rgraphCtx) const
- {
- ANKI_ASSERT(m_giCtx->m_probeToUpdateThisFrame);
- ANKI_TRACE_SCOPED_EVENT(RIndirectDiffuse);
- CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
- const GlobalIlluminationProbeQueueElementForRefresh& probe = *m_giCtx->m_probeToUpdateThisFrame;
- const U32 faceIdx = rgraphCtx.m_currentSecondLevelCommandBufferIndex;
- const U32 viewportX = faceIdx * m_tileSize;
- cmdb.setViewport(viewportX, 0, m_tileSize, m_tileSize);
- cmdb.setScissor(viewportX, 0, m_tileSize, m_tileSize);
- const RenderQueue& rqueue = *probe.m_renderQueues[faceIdx];
- RenderableDrawerArguments args;
- args.m_viewMatrix = rqueue.m_viewMatrix;
- args.m_cameraTransform = Mat3x4::getIdentity(); // Don't care
- args.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
- args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
- args.m_renderingTechinuqe = RenderingTechnique::kGBuffer;
- args.m_sampler = getRenderer().getSamplers().m_trilinearRepeat.get();
- args.fillMdi(m_giCtx->m_gbufferVisOut[faceIdx]);
- getRenderer().getSceneDrawer().drawMdi(args, cmdb);
- // It's secondary, no need to restore the state
- }
- void IndirectDiffuseProbes::runShadowmappingInThread(RenderPassWorkContext& rgraphCtx) const
- {
- ANKI_TRACE_SCOPED_EVENT(RIndirectDiffuse);
- const InternalContext& giCtx = *m_giCtx;
- ANKI_ASSERT(giCtx.m_probeToUpdateThisFrame);
- const GlobalIlluminationProbeQueueElementForRefresh& probe = *giCtx.m_probeToUpdateThisFrame;
- CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
- cmdb.setPolygonOffset(kShadowsPolygonOffsetFactor, kShadowsPolygonOffsetUnits);
- const U32 faceIdx = rgraphCtx.m_currentSecondLevelCommandBufferIndex;
- ANKI_ASSERT(probe.m_renderQueues[faceIdx]);
- const RenderQueue& faceRenderQueue = *probe.m_renderQueues[faceIdx];
- ANKI_ASSERT(faceRenderQueue.m_directionalLight.hasShadow());
- ANKI_ASSERT(faceRenderQueue.m_directionalLight.m_shadowRenderQueues[0]);
- const RenderQueue& cascadeRenderQueue = *faceRenderQueue.m_directionalLight.m_shadowRenderQueues[0];
- const U32 rez = m_shadowMapping.m_rtDescr.m_height;
- cmdb.setViewport(rez * faceIdx, 0, rez, rez);
- cmdb.setScissor(rez * faceIdx, 0, rez, rez);
- RenderableDrawerArguments args;
- args.m_viewMatrix = cascadeRenderQueue.m_viewMatrix;
- args.m_cameraTransform = Mat3x4::getIdentity(); // Don't care
- args.m_viewProjectionMatrix = cascadeRenderQueue.m_viewProjectionMatrix;
- args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
- args.m_sampler = getRenderer().getSamplers().m_trilinearRepeatAniso.get();
- args.m_renderingTechinuqe = RenderingTechnique::kDepth;
- args.fillMdi(giCtx.m_shadowsVisOut[faceIdx]);
- getRenderer().getSceneDrawer().drawMdi(args, cmdb);
- // It's secondary, no need to restore the state
- }
- void IndirectDiffuseProbes::runLightShading(RenderPassWorkContext& rgraphCtx)
- {
- ANKI_TRACE_SCOPED_EVENT(RIndirectDiffuse);
- InternalContext& giCtx = *m_giCtx;
- ANKI_ASSERT(giCtx.m_probeToUpdateThisFrame);
- const GlobalIlluminationProbeQueueElementForRefresh& probe = *giCtx.m_probeToUpdateThisFrame;
- CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
- for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
- {
- ANKI_ASSERT(probe.m_renderQueues[faceIdx]);
- const RenderQueue& rqueue = *probe.m_renderQueues[faceIdx];
- const U32 rez = m_tileSize;
- cmdb.setScissor(rez * faceIdx, 0, rez, rez);
- cmdb.setViewport(rez * faceIdx, 0, rez, rez);
- // Draw light shading
- TraditionalDeferredLightShadingDrawInfo dsInfo;
- dsInfo.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
- dsInfo.m_invViewProjectionMatrix = rqueue.m_viewProjectionMatrix.getInverse();
- dsInfo.m_cameraPosWSpace = rqueue.m_cameraTransform.getTranslationPart().xyz1();
- dsInfo.m_viewport = UVec4(faceIdx * m_tileSize, 0, m_tileSize, m_tileSize);
- dsInfo.m_gbufferTexCoordsScale = Vec2(1.0f / F32(m_tileSize * 6), 1.0f / F32(m_tileSize));
- dsInfo.m_gbufferTexCoordsBias = Vec2(0.0f, 0.0f);
- dsInfo.m_lightbufferTexCoordsBias = Vec2(-F32(faceIdx), 0.0f);
- dsInfo.m_lightbufferTexCoordsScale = Vec2(1.0f / F32(m_tileSize), 1.0f / F32(m_tileSize));
- dsInfo.m_cameraNear = rqueue.m_cameraNear;
- dsInfo.m_cameraFar = rqueue.m_cameraFar;
- dsInfo.m_directionalLight = (rqueue.m_directionalLight.isEnabled()) ? &rqueue.m_directionalLight : nullptr;
- dsInfo.m_pointLights = rqueue.m_pointLights;
- dsInfo.m_spotLights = rqueue.m_spotLights;
- dsInfo.m_commandBuffer = &cmdb;
- dsInfo.m_gbufferRenderTargets[0] = giCtx.m_gbufferColorRts[0];
- dsInfo.m_gbufferRenderTargets[1] = giCtx.m_gbufferColorRts[1];
- dsInfo.m_gbufferRenderTargets[2] = giCtx.m_gbufferColorRts[2];
- dsInfo.m_gbufferDepthRenderTarget = giCtx.m_gbufferDepthRt;
- if(dsInfo.m_directionalLight && dsInfo.m_directionalLight->hasShadow())
- {
- dsInfo.m_directionalLightShadowmapRenderTarget = giCtx.m_shadowsRt;
- }
- dsInfo.m_renderpassContext = &rgraphCtx;
- dsInfo.m_skybox = &giCtx.m_ctx->m_renderQueue->m_skybox;
- m_lightShading.m_deferred.drawLights(dsInfo);
- }
- }
- void IndirectDiffuseProbes::runIrradiance(RenderPassWorkContext& rgraphCtx)
- {
- ANKI_TRACE_SCOPED_EVENT(RIndirectDiffuse);
- InternalContext& giCtx = *m_giCtx;
- CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
- ANKI_ASSERT(giCtx.m_probeToUpdateThisFrame);
- const GlobalIlluminationProbeQueueElementForRefresh& probe = *giCtx.m_probeToUpdateThisFrame;
- cmdb.bindShaderProgram(m_irradiance.m_grProg.get());
- // Bind resources
- cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
- rgraphCtx.bindColorTexture(0, 1, giCtx.m_lightShadingRt);
- for(U32 i = 0; i < kGBufferColorRenderTargetCount - 1; ++i)
- {
- rgraphCtx.bindColorTexture(0, 2, giCtx.m_gbufferColorRts[i], i);
- }
- rgraphCtx.bindImage(0, 3, giCtx.m_irradianceVolume, TextureSubresourceInfo());
- class
- {
- public:
- IVec3 m_volumeTexel;
- I32 m_nextTexelOffsetInU;
- } unis;
- unis.m_volumeTexel = IVec3(probe.m_cellToRefresh.x(), probe.m_cellToRefresh.y(), probe.m_cellToRefresh.z());
- unis.m_nextTexelOffsetInU = probe.m_cellCounts.x();
- cmdb.setPushConstants(&unis, sizeof(unis));
- // Dispatch
- cmdb.dispatchCompute(1, 1, 1);
- }
- } // end namespace anki
|