Browse Source

Make some things bindless

Panagiotis Christopoulos Charitos 6 months ago
parent
commit
1f8f48dc1e

+ 55 - 106
AnKi/Renderer/IndirectDiffuseClipmaps.cpp

@@ -16,17 +16,17 @@
 
 
 namespace anki {
 namespace anki {
 
 
-static void computeClipmapBounds(Vec3 cameraPos, Vec3 lookDir, Clipmap& clipmap)
+static void computeClipmapBounds(Vec3 cameraPos, Vec3 lookDir, U32 clipmapIdx, IndirectDiffuseClipmapConstants& consts)
 {
 {
-	const Vec3 offset = lookDir * kIndirectDiffuseClipmapForwardBias * F32(clipmap.m_index + 1);
+	const Vec3 offset = lookDir * kIndirectDiffuseClipmapForwardBias * F32(clipmapIdx + 1);
 	cameraPos += offset;
 	cameraPos += offset;
 
 
-	const Vec3 halfSize = clipmap.m_size * 0.5;
-	const Vec3 probeSize = clipmap.m_size / Vec3(clipmap.m_probeCounts);
+	const Vec3 halfSize = consts.m_sizes[clipmapIdx].xyz() * 0.5;
+	const Vec3 probeSize = consts.m_sizes[clipmapIdx].xyz() / Vec3(consts.m_probeCounts);
 	const Vec3 roundedPos = (cameraPos / probeSize).round() * probeSize;
 	const Vec3 roundedPos = (cameraPos / probeSize).round() * probeSize;
-	clipmap.m_aabbMin = roundedPos - halfSize;
+	consts.m_aabbMins[clipmapIdx] = (roundedPos - halfSize).xyz0();
 	[[maybe_unused]] const Vec3 aabbMax = roundedPos + halfSize;
 	[[maybe_unused]] const Vec3 aabbMax = roundedPos + halfSize;
-	ANKI_ASSERT(aabbMax - clipmap.m_aabbMin == clipmap.m_size);
+	ANKI_ASSERT(aabbMax - consts.m_aabbMins[clipmapIdx].xyz() == consts.m_sizes[clipmapIdx].xyz());
 }
 }
 
 
 Error IndirectDiffuseClipmaps::init()
 Error IndirectDiffuseClipmaps::init()
@@ -38,55 +38,38 @@ Error IndirectDiffuseClipmaps::init()
 													  getRenderer().getHdrFormat(), "IndirectDiffuseClipmap: Final");
 													  getRenderer().getHdrFormat(), "IndirectDiffuseClipmap: Final");
 	m_appliedGiRtDesc.bake();
 	m_appliedGiRtDesc.bake();
 
 
-	m_clipmapInfo[0].m_probeCounts =
-		UVec3(g_indirectDiffuseClipmapProbesXZCVar, g_indirectDiffuseClipmapProbesYCVar, g_indirectDiffuseClipmapProbesXZCVar);
-	m_clipmapInfo[1].m_probeCounts = m_clipmapInfo[0].m_probeCounts;
-	m_clipmapInfo[2].m_probeCounts = m_clipmapInfo[0].m_probeCounts;
-	m_clipmapInfo[0].m_size = Vec3(g_indirectDiffuseClipmap0XZSizeCVar, g_indirectDiffuseClipmap0YSizeCVar, g_indirectDiffuseClipmap0XZSizeCVar);
-	m_clipmapInfo[1].m_size = Vec3(g_indirectDiffuseClipmap1XZSizeCVar, g_indirectDiffuseClipmap1YSizeCVar, g_indirectDiffuseClipmap1XZSizeCVar);
-	m_clipmapInfo[2].m_size = Vec3(g_indirectDiffuseClipmap2XZSizeCVar, g_indirectDiffuseClipmap2YSizeCVar, g_indirectDiffuseClipmap2XZSizeCVar);
+	m_consts.m_probeCounts = UVec3(g_indirectDiffuseClipmapProbesXZCVar, g_indirectDiffuseClipmapProbesYCVar, g_indirectDiffuseClipmapProbesXZCVar);
+	m_consts.m_totalProbeCount = m_consts.m_probeCounts.x() * m_consts.m_probeCounts.y() * m_consts.m_probeCounts.z();
 
 
-	U32 probesPerClipmap = 0;
-	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-	{
-		const U32 count = m_clipmapInfo[i].m_probeCounts.x() * m_clipmapInfo[i].m_probeCounts.y() * m_clipmapInfo[i].m_probeCounts.z();
-		m_clipmapInfo[i].m_probeCountTotal = count;
-		m_clipmapInfo[i].m_index = i;
-		if(i == 0)
-		{
-			probesPerClipmap = count;
-		}
-		else
-		{
-			ANKI_ASSERT(probesPerClipmap == count);
-		}
-	}
+	m_consts.m_sizes[0] = Vec3(g_indirectDiffuseClipmap0XZSizeCVar, g_indirectDiffuseClipmap0YSizeCVar, g_indirectDiffuseClipmap0XZSizeCVar).xyz0();
+	m_consts.m_sizes[1] = Vec3(g_indirectDiffuseClipmap1XZSizeCVar, g_indirectDiffuseClipmap1YSizeCVar, g_indirectDiffuseClipmap1XZSizeCVar).xyz0();
+	m_consts.m_sizes[2] = Vec3(g_indirectDiffuseClipmap2XZSizeCVar, g_indirectDiffuseClipmap2YSizeCVar, g_indirectDiffuseClipmap2XZSizeCVar).xyz0();
 
 
 	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
 	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
 	{
 	{
-		TextureInitInfo init = getRenderer().create2DRenderTargetInitInfo(m_clipmapInfo[i].m_probeCounts.x(), m_clipmapInfo[i].m_probeCounts.z(),
-																		  Format::kR8_Unorm, TextureUsageBit::kUavCompute | TextureUsageBit::kAllSrv,
+		TextureInitInfo init = getRenderer().create2DRenderTargetInitInfo(m_consts.m_probeCounts.x(), m_consts.m_probeCounts.z(), Format::kR8_Unorm,
+																		  TextureUsageBit::kUavCompute | TextureUsageBit::kAllSrv,
 																		  generateTempPassName("IndirectDiffuseClipmap: Probe validity #%u", i));
 																		  generateTempPassName("IndirectDiffuseClipmap: Probe validity #%u", i));
 
 
-		init.m_depth = m_clipmapInfo[i].m_probeCounts.y();
+		init.m_depth = m_consts.m_probeCounts.y();
 		init.m_type = TextureType::k3D;
 		init.m_type = TextureType::k3D;
 
 
 		m_probeValidityVolumes[i] = getRenderer().createAndClearRenderTarget(init, TextureUsageBit::kSrvCompute);
 		m_probeValidityVolumes[i] = getRenderer().createAndClearRenderTarget(init, TextureUsageBit::kSrvCompute);
 	}
 	}
 
 
-	// Create the lighting result texture
+	// Create the RT result texture
 	const U32 raysPerProbePerFrame = square(g_indirectDiffuseClipmapRadianceOctMapSize / 2);
 	const U32 raysPerProbePerFrame = square(g_indirectDiffuseClipmapRadianceOctMapSize / 2);
-	m_rtResultRtDesc = getRenderer().create2DRenderTargetDescription(probesPerClipmap, raysPerProbePerFrame * kIndirectDiffuseClipmapCount,
+	m_rtResultRtDesc = getRenderer().create2DRenderTargetDescription(m_consts.m_totalProbeCount, raysPerProbePerFrame * kIndirectDiffuseClipmapCount,
 																	 Format::kR16G16B16A16_Sfloat, "IndirectDiffuseClipmap: RT result");
 																	 Format::kR16G16B16A16_Sfloat, "IndirectDiffuseClipmap: RT result");
 	m_rtResultRtDesc.bake();
 	m_rtResultRtDesc.bake();
 
 
 	for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
 	for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
 	{
 	{
 		TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
 		TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
-			m_clipmapInfo[clipmap].m_probeCounts.x() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2),
-			m_clipmapInfo[clipmap].m_probeCounts.z() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2), Format::kB10G11R11_Ufloat_Pack32,
+			m_consts.m_probeCounts.x() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2),
+			m_consts.m_probeCounts.z() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2), Format::kB10G11R11_Ufloat_Pack32,
 			TextureUsageBit::kAllShaderResource, generateTempPassName("IndirectDiffuseClipmap: Radiance #%u", clipmap));
 			TextureUsageBit::kAllShaderResource, generateTempPassName("IndirectDiffuseClipmap: Radiance #%u", clipmap));
-		volumeInit.m_depth = m_clipmapInfo[clipmap].m_probeCounts.y();
+		volumeInit.m_depth = m_consts.m_probeCounts.y();
 		volumeInit.m_type = TextureType::k3D;
 		volumeInit.m_type = TextureType::k3D;
 
 
 		m_radianceVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
 		m_radianceVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
@@ -95,10 +78,10 @@ Error IndirectDiffuseClipmaps::init()
 	for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
 	for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
 	{
 	{
 		TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
 		TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
-			m_clipmapInfo[clipmap].m_probeCounts.x() * (g_indirectDiffuseClipmapIrradianceOctMapSize + 2),
-			m_clipmapInfo[clipmap].m_probeCounts.z() * (g_indirectDiffuseClipmapIrradianceOctMapSize + 2), Format::kB10G11R11_Ufloat_Pack32,
+			m_consts.m_probeCounts.x() * (g_indirectDiffuseClipmapIrradianceOctMapSize + 2),
+			m_consts.m_probeCounts.z() * (g_indirectDiffuseClipmapIrradianceOctMapSize + 2), Format::kB10G11R11_Ufloat_Pack32,
 			TextureUsageBit::kAllShaderResource, generateTempPassName("IndirectDiffuseClipmap: Irradiance #%u", clipmap));
 			TextureUsageBit::kAllShaderResource, generateTempPassName("IndirectDiffuseClipmap: Irradiance #%u", clipmap));
-		volumeInit.m_depth = m_clipmapInfo[clipmap].m_probeCounts.y();
+		volumeInit.m_depth = m_consts.m_probeCounts.y();
 		volumeInit.m_type = TextureType::k3D;
 		volumeInit.m_type = TextureType::k3D;
 
 
 		m_irradianceVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
 		m_irradianceVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
@@ -107,10 +90,10 @@ Error IndirectDiffuseClipmaps::init()
 	for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
 	for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
 	{
 	{
 		TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
 		TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
-			m_clipmapInfo[clipmap].m_probeCounts.x() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2),
-			m_clipmapInfo[clipmap].m_probeCounts.z() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2), Format::kR16G16_Sfloat,
+			m_consts.m_probeCounts.x() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2),
+			m_consts.m_probeCounts.z() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2), Format::kR16G16_Sfloat,
 			TextureUsageBit::kAllShaderResource, generateTempPassName("IndirectDiffuseClipmap: Dist moments #%u", clipmap));
 			TextureUsageBit::kAllShaderResource, generateTempPassName("IndirectDiffuseClipmap: Dist moments #%u", clipmap));
-		volumeInit.m_depth = m_clipmapInfo[clipmap].m_probeCounts.y();
+		volumeInit.m_depth = m_consts.m_probeCounts.y();
 		volumeInit.m_type = TextureType::k3D;
 		volumeInit.m_type = TextureType::k3D;
 
 
 		m_distanceMomentsVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
 		m_distanceMomentsVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
@@ -118,12 +101,13 @@ Error IndirectDiffuseClipmaps::init()
 
 
 	for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
 	for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
 	{
 	{
-		m_avgLightColorRtDescs[clipmap] = getRenderer().create2DRenderTargetDescription(
-			m_clipmapInfo[0].m_probeCounts.x(), m_clipmapInfo[0].m_probeCounts.z(), Format::kB10G11R11_Ufloat_Pack32,
+		TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
+			m_consts.m_probeCounts.x(), m_consts.m_probeCounts.z(), Format::kB10G11R11_Ufloat_Pack32, TextureUsageBit::kAllShaderResource,
 			generateTempPassName("IndirectDiffuseClipmap: Avg light #%u", clipmap));
 			generateTempPassName("IndirectDiffuseClipmap: Avg light #%u", clipmap));
-		m_avgLightColorRtDescs[clipmap].m_depth = m_clipmapInfo[0].m_probeCounts.y();
-		m_avgLightColorRtDescs[clipmap].m_type = TextureType::k3D;
-		m_avgLightColorRtDescs[clipmap].bake();
+		volumeInit.m_depth = m_consts.m_probeCounts.y();
+		volumeInit.m_type = TextureType::k3D;
+
+		m_avgIrradianceVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
 	}
 	}
 
 
 	const Array<SubMutation, 4> mutation = {{{"GPU_WAVE_SIZE", MutatorValue(GrManager::getSingleton().getDeviceCapabilities().m_maxWaveSize)},
 	const Array<SubMutation, 4> mutation = {{{"GPU_WAVE_SIZE", MutatorValue(GrManager::getSingleton().getDeviceCapabilities().m_maxWaveSize)},
@@ -173,6 +157,19 @@ Error IndirectDiffuseClipmaps::init()
 
 
 	ANKI_CHECK(ResourceManager::getSingleton().loadResource("EngineAssets/BlueNoise_Rgba8_64x64.png", m_blueNoiseImg));
 	ANKI_CHECK(ResourceManager::getSingleton().loadResource("EngineAssets/BlueNoise_Rgba8_64x64.png", m_blueNoiseImg));
 
 
+	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
+	{
+		m_consts.m_textures[i].m_radianceTexture = m_radianceVolumes[i]->getOrCreateBindlessTextureIndex(TextureSubresourceDesc::all());
+		m_consts.m_textures[i].m_irradianceTexture = m_irradianceVolumes[i]->getOrCreateBindlessTextureIndex(TextureSubresourceDesc::all());
+		m_consts.m_textures[i].m_distanceMomentsTexture = m_distanceMomentsVolumes[i]->getOrCreateBindlessTextureIndex(TextureSubresourceDesc::all());
+		m_consts.m_textures[i].m_probeValidityTexture = m_probeValidityVolumes[i]->getOrCreateBindlessTextureIndex(TextureSubresourceDesc::all());
+		m_consts.m_textures[i].m_averageIrradianceTexture = m_avgIrradianceVolumes[i]->getOrCreateBindlessTextureIndex(TextureSubresourceDesc::all());
+
+		m_consts.m_textures[i].m_distanceMomentsOctMapSize = (m_distanceMomentsVolumes[i]->getWidth() / m_consts.m_probeCounts.x()) - 2;
+		m_consts.m_textures[i].m_irradianceOctMapSize = (m_irradianceVolumes[i]->getWidth() / m_consts.m_probeCounts.x()) - 2;
+		m_consts.m_textures[i].m_radianceOctMapSize = (m_radianceVolumes[i]->getWidth() / m_consts.m_probeCounts.x()) - 2;
+	}
+
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -182,10 +179,10 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 
 
 	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
 	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
 	{
 	{
-		m_clipmapInfo[i].m_prevFrameAabbMin = m_clipmapInfo[i].m_aabbMin;
+		m_consts.m_previousFrameAabbMins[i] = m_consts.m_aabbMins[i];
 
 
 		computeClipmapBounds(ctx.m_matrices.m_cameraTransform.getTranslationPart(),
 		computeClipmapBounds(ctx.m_matrices.m_cameraTransform.getTranslationPart(),
-							 -ctx.m_matrices.m_cameraTransform.getRotationPart().getZAxis().normalize(), m_clipmapInfo[i]);
+							 -ctx.m_matrices.m_cameraTransform.getRotationPart().getZAxis().normalize(), i, m_consts);
 	}
 	}
 
 
 	RenderGraphBuilder& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphBuilder& rgraph = ctx.m_renderGraphDescr;
@@ -207,6 +204,7 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 			irradianceVolumes[i] = rgraph.importRenderTarget(m_irradianceVolumes[i].get());
 			irradianceVolumes[i] = rgraph.importRenderTarget(m_irradianceVolumes[i].get());
 			distanceMomentsVolumes[i] = rgraph.importRenderTarget(m_distanceMomentsVolumes[i].get());
 			distanceMomentsVolumes[i] = rgraph.importRenderTarget(m_distanceMomentsVolumes[i].get());
 			probeValidityVolumes[i] = rgraph.importRenderTarget(m_probeValidityVolumes[i].get());
 			probeValidityVolumes[i] = rgraph.importRenderTarget(m_probeValidityVolumes[i].get());
+			avgIrradianceVolumes[i] = rgraph.importRenderTarget(m_avgIrradianceVolumes[i].get());
 		}
 		}
 		else
 		else
 		{
 		{
@@ -214,11 +212,12 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 			irradianceVolumes[i] = rgraph.importRenderTarget(m_irradianceVolumes[i].get(), TextureUsageBit::kSrvCompute);
 			irradianceVolumes[i] = rgraph.importRenderTarget(m_irradianceVolumes[i].get(), TextureUsageBit::kSrvCompute);
 			distanceMomentsVolumes[i] = rgraph.importRenderTarget(m_distanceMomentsVolumes[i].get(), TextureUsageBit::kSrvCompute);
 			distanceMomentsVolumes[i] = rgraph.importRenderTarget(m_distanceMomentsVolumes[i].get(), TextureUsageBit::kSrvCompute);
 			probeValidityVolumes[i] = rgraph.importRenderTarget(m_probeValidityVolumes[i].get(), TextureUsageBit::kSrvCompute);
 			probeValidityVolumes[i] = rgraph.importRenderTarget(m_probeValidityVolumes[i].get(), TextureUsageBit::kSrvCompute);
+			avgIrradianceVolumes[i] = rgraph.importRenderTarget(m_avgIrradianceVolumes[i].get(), TextureUsageBit::kSrvCompute);
 		}
 		}
-
-		avgIrradianceVolumes[i] = rgraph.newRenderTarget(m_avgLightColorRtDescs[i]);
 	}
 	}
 
 
+	m_texturesImportedOnce = true;
+
 	// SBT build
 	// SBT build
 	BufferHandle sbtHandle;
 	BufferHandle sbtHandle;
 	BufferView sbtBuffer;
 	BufferView sbtBuffer;
@@ -291,19 +290,6 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 			cmdb.bindSrv(srv++, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
 			cmdb.bindSrv(srv++, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
 			cmdb.bindSrv(srv++, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
 			cmdb.bindSrv(srv++, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
 
 
-			for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
-			{
-				rgraphCtx.bindSrv(srv++, 2, irradianceVolumes[clipmap]);
-			}
-			for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
-			{
-				rgraphCtx.bindSrv(srv++, 2, probeValidityVolumes[clipmap]);
-			}
-			for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
-			{
-				rgraphCtx.bindSrv(srv++, 2, distanceMomentsVolumes[clipmap]);
-			}
-
 			for(U32 i = 0; i < 3; ++i)
 			for(U32 i = 0; i < 3; ++i)
 			{
 			{
 				cmdb.bindSrv(srv++, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
 				cmdb.bindSrv(srv++, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
@@ -324,9 +310,8 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 				const UVec4 consts(clipmap, g_indirectDiffuseClipmapRadianceOctMapSize, 0, 0);
 				const UVec4 consts(clipmap, g_indirectDiffuseClipmapRadianceOctMapSize, 0, 0);
 				cmdb.setFastConstants(&consts, sizeof(consts));
 				cmdb.setFastConstants(&consts, sizeof(consts));
 
 
-				const U32 probeCount = m_clipmapInfo[0].m_probeCountTotal;
 				cmdb.traceRays(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,
 				cmdb.traceRays(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,
-							   probeCount * raysPerProbePerFrame, 1, 1);
+							   m_consts.m_totalProbeCount * raysPerProbePerFrame, 1, 1);
 			}
 			}
 		});
 		});
 	}
 	}
@@ -363,7 +348,7 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 
 
 				const U32 raysPerProbePerFrame = square(g_indirectDiffuseClipmapRadianceOctMapSize / 2);
 				const U32 raysPerProbePerFrame = square(g_indirectDiffuseClipmapRadianceOctMapSize / 2);
 				const U32 threadCount = 64;
 				const U32 threadCount = 64;
-				cmdb.dispatchCompute((raysPerProbePerFrame * m_clipmapInfo[clipmap].m_probeCountTotal + threadCount - 1) / threadCount, 1, 1);
+				cmdb.dispatchCompute((raysPerProbePerFrame * m_consts.m_totalProbeCount + threadCount - 1) / threadCount, 1, 1);
 			}
 			}
 		});
 		});
 	}
 	}
@@ -400,8 +385,7 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 				rgraphCtx.bindUav(uav++, 0, avgIrradianceVolumes[clipmap]);
 				rgraphCtx.bindUav(uav++, 0, avgIrradianceVolumes[clipmap]);
 			}
 			}
 
 
-			cmdb.dispatchCompute(m_clipmapInfo[0].m_probeCounts[0] * kIndirectDiffuseClipmapCount, m_clipmapInfo[0].m_probeCounts[1],
-								 m_clipmapInfo[0].m_probeCounts[2]);
+			cmdb.dispatchCompute(m_consts.m_probeCounts[0] * kIndirectDiffuseClipmapCount, m_consts.m_probeCounts[1], m_consts.m_probeCounts[2]);
 		});
 		});
 	}
 	}
 
 
@@ -479,19 +463,6 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 			cmdb.bindSrv(srv++, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
 			cmdb.bindSrv(srv++, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
 			cmdb.bindSrv(srv++, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
 			cmdb.bindSrv(srv++, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
 
 
-			for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
-			{
-				rgraphCtx.bindSrv(srv++, 2, irradianceVolumes[clipmap]);
-			}
-			for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
-			{
-				rgraphCtx.bindSrv(srv++, 2, probeValidityVolumes[clipmap]);
-			}
-			for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
-			{
-				rgraphCtx.bindSrv(srv++, 2, distanceMomentsVolumes[clipmap]);
-			}
-
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getDepthRt());
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getDepthRt());
 			cmdb.bindSrv(srv++, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
 			cmdb.bindSrv(srv++, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getColorRt(2));
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getColorRt(2));
@@ -503,8 +474,7 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 			rgraphCtx.bindUav(0, 2, m_runCtx.m_handles.m_appliedIrradiance);
 			rgraphCtx.bindUav(0, 2, m_runCtx.m_handles.m_appliedIrradiance);
 			cmdb.bindUav(1, 2, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
 			cmdb.bindUav(1, 2, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
 
 
-			const Vec3 probeSizes = m_clipmapInfo[0].m_size / Vec3(m_clipmapInfo[0].m_probeCounts);
-			const F32 rayTMax = max(probeSizes.x(), max(probeSizes.y(), probeSizes.z())) * 10.0f;
+			const F32 rayTMax = 10.0f; // TODO
 			const Vec4 consts(rayTMax);
 			const Vec4 consts(rayTMax);
 			cmdb.setFastConstants(&consts, sizeof(consts));
 			cmdb.setFastConstants(&consts, sizeof(consts));
 
 
@@ -537,27 +507,6 @@ void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
 				rgraphCtx.bindSrv(1, 0, getGBuffer().getColorRt(2));
 				rgraphCtx.bindSrv(1, 0, getGBuffer().getColorRt(2));
 				cmdb.bindSrv(2, 0, TextureView(&m_blueNoiseImg->getTexture(), TextureSubresourceDesc::firstSurface()));
 				cmdb.bindSrv(2, 0, TextureView(&m_blueNoiseImg->getTexture(), TextureSubresourceDesc::firstSurface()));
 
 
-				U32 srvReg = 3;
-				for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-				{
-					rgraphCtx.bindSrv(srvReg++, 0, irradianceVolumes[i]);
-				}
-
-				for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-				{
-					rgraphCtx.bindSrv(srvReg++, 0, probeValidityVolumes[i]);
-				}
-
-				for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-				{
-					rgraphCtx.bindSrv(srvReg++, 0, distanceMomentsVolumes[i]);
-				}
-
-				for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-				{
-					rgraphCtx.bindSrv(srvReg++, 0, avgIrradianceVolumes[i]);
-				}
-
 				rgraphCtx.bindUav(0, 0, m_runCtx.m_handles.m_appliedIrradiance);
 				rgraphCtx.bindUav(0, 0, m_runCtx.m_handles.m_appliedIrradiance);
 
 
 				cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
 				cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
@@ -587,7 +536,7 @@ void IndirectDiffuseClipmaps::drawDebugProbes(const RenderingContext& ctx, Rende
 	rgraphCtx.bindSrv(1, 0, m_runCtx.m_handles.m_probeValidityVolumes[clipmap]);
 	rgraphCtx.bindSrv(1, 0, m_runCtx.m_handles.m_probeValidityVolumes[clipmap]);
 	cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
 	cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
 
 
-	cmdb.draw(PrimitiveTopology::kTriangles, 36, m_clipmapInfo[clipmap].m_probeCountTotal);
+	cmdb.draw(PrimitiveTopology::kTriangles, 36, m_consts.m_totalProbeCount);
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 4 - 4
AnKi/Renderer/IndirectDiffuseClipmaps.h

@@ -88,9 +88,9 @@ public:
 		handles[0] = m_runCtx.m_handles.m_appliedIrradiance;
 		handles[0] = m_runCtx.m_handles.m_appliedIrradiance;
 	}
 	}
 
 
-	const Array<Clipmap, kIndirectDiffuseClipmapCount>& getClipmapsInfo() const
+	const IndirectDiffuseClipmapConstants& getClipmapConsts() const
 	{
 	{
-		return m_clipmapInfo;
+		return m_consts;
 	}
 	}
 
 
 	void drawDebugProbes(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx) const;
 	void drawDebugProbes(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx) const;
@@ -105,12 +105,12 @@ private:
 	Array<TexturePtr, kIndirectDiffuseClipmapCount> m_irradianceVolumes;
 	Array<TexturePtr, kIndirectDiffuseClipmapCount> m_irradianceVolumes;
 	Array<TexturePtr, kIndirectDiffuseClipmapCount> m_distanceMomentsVolumes;
 	Array<TexturePtr, kIndirectDiffuseClipmapCount> m_distanceMomentsVolumes;
 	Array<TexturePtr, kIndirectDiffuseClipmapCount> m_probeValidityVolumes;
 	Array<TexturePtr, kIndirectDiffuseClipmapCount> m_probeValidityVolumes;
+	Array<TexturePtr, kIndirectDiffuseClipmapCount> m_avgIrradianceVolumes;
 
 
 	RenderTargetDesc m_rtResultRtDesc;
 	RenderTargetDesc m_rtResultRtDesc;
 	RenderTargetDesc m_appliedGiRtDesc;
 	RenderTargetDesc m_appliedGiRtDesc;
-	Array<RenderTargetDesc, kIndirectDiffuseClipmapCount> m_avgLightColorRtDescs;
 
 
-	Array<Clipmap, kIndirectDiffuseClipmapCount> m_clipmapInfo;
+	IndirectDiffuseClipmapConstants m_consts;
 
 
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramResourcePtr m_missProg;
 	ShaderProgramResourcePtr m_missProg;

+ 0 - 5
AnKi/Renderer/Reflections.cpp

@@ -329,11 +329,6 @@ void Reflections::populateRenderGraph(RenderingContext& ctx)
 						 (arr.getElementCount()) ? arr.getBufferView() : BufferView(getDummyGpuResources().m_buffer.get(), 0, arr.getElementSize()));
 						 (arr.getElementCount()) ? arr.getBufferView() : BufferView(getDummyGpuResources().m_buffer.get(), 0, arr.getElementSize()));
 			cmdb.bindSrv(srv++, 2, pixelsFailedSsrBuff);
 			cmdb.bindSrv(srv++, 2, pixelsFailedSsrBuff);
 
 
-			for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount * 3; ++clipmap)
-			{
-				cmdb.bindSrv(srv++, 2, TextureView(getDummyGpuResources().m_texture3DSrv.get(), TextureSubresourceDesc::all()));
-			}
-
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getDepthRt());
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getDepthRt());
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getColorRt(1));
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getColorRt(1));
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getColorRt(2));
 			rgraphCtx.bindSrv(srv++, 2, getGBuffer().getColorRt(2));

+ 1 - 4
AnKi/Renderer/Renderer.cpp

@@ -438,10 +438,7 @@ void Renderer::writeGlobalRendererConstants(RenderingContext& ctx, GlobalRendere
 
 
 	if(m_indirectDiffuseClipmaps)
 	if(m_indirectDiffuseClipmaps)
 	{
 	{
-		for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-		{
-			consts.m_indirectDiffuseClipmaps[i] = m_indirectDiffuseClipmaps->getClipmapsInfo()[i];
-		}
+		memcpy(&consts.m_indirectDiffuseClipmaps, &m_indirectDiffuseClipmaps->getClipmapConsts(), sizeof(consts.m_indirectDiffuseClipmaps));
 	}
 	}
 
 
 	outConsts = consts;
 	outConsts = consts;

+ 0 - 17
AnKi/Renderer/VolumetricLightingAccumulation.cpp

@@ -114,23 +114,6 @@ void VolumetricLightingAccumulation::populateRenderGraph(RenderingContext& ctx)
 		{
 		{
 			cmdb.bindSrv(srv++, 0, getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kGlobalIlluminationProbe));
 			cmdb.bindSrv(srv++, 0, getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kGlobalIlluminationProbe));
 		}
 		}
-		else
-		{
-			for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-			{
-				rgraphCtx.bindSrv(srv++, 0, getIndirectDiffuseClipmaps().getRts().m_avgIrradianceVolumes[i]);
-			}
-
-			for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-			{
-				rgraphCtx.bindSrv(srv++, 0, getIndirectDiffuseClipmaps().getRts().m_distanceMomentsVolumes[i]);
-			}
-
-			for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-			{
-				rgraphCtx.bindSrv(srv++, 0, getIndirectDiffuseClipmaps().getRts().m_probeValidityVolumes[i]);
-			}
-		}
 
 
 		const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
 		const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
 
 

+ 23 - 9
AnKi/Shaders/Include/MiscRendererTypes.h

@@ -71,19 +71,33 @@ struct Sky
 	U32 m_type;
 	U32 m_type;
 };
 };
 
 
-struct Clipmap
+struct IndirectDiffuseClipmapTextures
+{
+	U32 m_irradianceTexture : 16;
+	U32 m_irradianceOctMapSize : 16;
+
+	U32 m_radianceTexture : 16;
+	U32 m_radianceOctMapSize : 16;
+
+	U32 m_distanceMomentsTexture : 16;
+	U32 m_distanceMomentsOctMapSize : 16;
+
+	U32 m_averageIrradianceTexture : 16;
+	U32 m_probeValidityTexture : 16;
+};
+
+struct IndirectDiffuseClipmapConstants
 {
 {
 	UVec3 m_probeCounts;
 	UVec3 m_probeCounts;
-	U32 m_probeCountTotal;
+	U32 m_totalProbeCount;
+
+	Vec4 m_sizes[kIndirectDiffuseClipmapCount];
 
 
-	Vec3 m_size;
-	U32 m_index;
+	Vec4 m_aabbMins[kIndirectDiffuseClipmapCount];
 
 
-	Vec3 m_aabbMin;
-	F32 m_padding1;
+	Vec4 m_previousFrameAabbMins[kIndirectDiffuseClipmapCount];
 
 
-	Vec3 m_prevFrameAabbMin;
-	F32 m_padding3;
+	IndirectDiffuseClipmapTextures m_textures[kIndirectDiffuseClipmapCount];
 };
 };
 
 
 /// Common constants for all passes.
 /// Common constants for all passes.
@@ -113,7 +127,7 @@ struct GlobalRendererConstants
 
 
 	Sky m_sky;
 	Sky m_sky;
 
 
-	Clipmap m_indirectDiffuseClipmaps[kIndirectDiffuseClipmapCount];
+	IndirectDiffuseClipmapConstants m_indirectDiffuseClipmaps;
 };
 };
 
 
 // RT shadows
 // RT shadows

+ 72 - 93
AnKi/Shaders/IndirectDiffuseClipmaps.ankiprog

@@ -31,17 +31,6 @@
 #endif
 #endif
 #include <AnKi/Shaders/RtMaterialFetch.hlsl>
 #include <AnKi/Shaders/RtMaterialFetch.hlsl>
 
 
-Vec2 generateRandomUv(U32 sampleIdx, U32 sampleCount, U32 frame)
-{
-	const UVec3 r = rand3DPCG16(UVec3(frame % 8u, frame % 4u, frame % 16u));
-	return hammersleyRandom16(sampleIdx, sampleCount, r);
-}
-
-HVec3 generateRandomPointInSphere(U32 sampleIdx, U32 sampleCount, U32 frame)
-{
-	return octahedronDecode(generateRandomUv(sampleIdx, sampleCount, frame));
-}
-
 // ===========================================================================
 // ===========================================================================
 // RtMaterialFetch                                                           =
 // RtMaterialFetch                                                           =
 // ===========================================================================
 // ===========================================================================
@@ -59,18 +48,21 @@ ANKI_FAST_CONSTANTS(Consts, g_consts)
 
 
 [Shader("raygeneration")] void main()
 [Shader("raygeneration")] void main()
 {
 {
-	const Clipmap clipmap = g_globalRendererConstants.m_indirectDiffuseClipmaps[g_consts.m_clipmapIdx];
+	const IndirectDiffuseClipmapConstants idConsts = g_globalRendererConstants.m_indirectDiffuseClipmaps;
+	const UVec3 probeCounts = idConsts.m_probeCounts;
+	const U32 probeCountTotal = idConsts.m_totalProbeCount;
+	const Vec3 clipmapSize = idConsts.m_sizes[g_consts.m_clipmapIdx];
+	const Vec3 clipmapAabbMin = idConsts.m_aabbMins[g_consts.m_clipmapIdx];
 
 
 	// Compute probe info. Make sure you shoot coherent rays as much as possible by using the same direction on a specific wave
 	// Compute probe info. Make sure you shoot coherent rays as much as possible by using the same direction on a specific wave
-	const U32 outPixelIdx = DispatchRaysIndex().x / clipmap.m_probeCountTotal;
-	const U32 probeIdx = DispatchRaysIndex().x % clipmap.m_probeCountTotal;
+	const U32 outPixelIdx = DispatchRaysIndex().x / probeCountTotal;
+	const U32 probeIdx = DispatchRaysIndex().x % probeCountTotal;
 
 
 	UVec3 probe3dIdx;
 	UVec3 probe3dIdx;
-	unflatten3dArrayIndex(clipmap.m_probeCounts.z, clipmap.m_probeCounts.y, clipmap.m_probeCounts.x, probeIdx, probe3dIdx.z, probe3dIdx.y,
-						  probe3dIdx.x);
+	unflatten3dArrayIndex(probeCounts.z, probeCounts.y, probeCounts.x, probeIdx, probe3dIdx.z, probe3dIdx.y, probe3dIdx.x);
 
 
-	const Vec3 probeSize = clipmap.m_size / clipmap.m_probeCounts;
-	const Vec3 probeWorldPos = probe3dIdx * probeSize + probeSize * 0.5 + clipmap.m_aabbMin;
+	const Vec3 probeSize = clipmapSize / probeCounts;
+	const Vec3 probeWorldPos = probe3dIdx * probeSize + probeSize * 0.5 + clipmapAabbMin;
 
 
 	// Generate direction
 	// Generate direction
 	const U32 checkerboardIdx = g_globalRendererConstants.m_frame % 4;
 	const U32 checkerboardIdx = g_globalRendererConstants.m_frame % 4;
@@ -103,21 +95,10 @@ ANKI_FAST_CONSTANTS(Consts, g_consts)
 		radiance = directLighting<F16>(gbuffer, hitPos, !hit, true, tMax, traceFlags | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH);
 		radiance = directLighting<F16>(gbuffer, hitPos, !hit, true, tMax, traceFlags | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH);
 
 
 		// Apply indirect
 		// Apply indirect
-#		if 0
-		const Mat3x4 cameraTrf = g_globalRendererConstants.m_matrices.m_cameraTransform;
-		const Vec3 lookDir = -Vec3(cameraTrf.m_row0[2], cameraTrf.m_row1[2], cameraTrf.m_row2[2]);
-		const Vec3 irradiance = sampleClipmapIrradianceAccurate(hitPos, gbuffer.m_worldNormal, g_globalRendererConstants.m_cameraPosition, lookDir,
-																g_globalRendererConstants.m_indirectDiffuseClipmaps, g_irradianceVolumes,
-																g_distanceMomentsVolumes, g_probeValidityVolumes, g_linearAnyRepeatSampler, noise);
-#		else
-		Clipmap clipmaps[kIndirectDiffuseClipmapCount];
-		for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
-		{
-			clipmaps[i] = g_globalRendererConstants.m_indirectDiffuseClipmaps[i];
-			clipmaps[i].m_aabbMin = clipmaps[i].m_prevFrameAabbMin;
-		}
-		const Vec3 irradiance = sampleClipmapIrradianceCheap(hitPos, gbuffer.m_worldNormal, clipmaps, g_irradianceVolumes, g_linearAnyRepeatSampler);
-#		endif
+		constexpr SampleClipmapFlag flags =
+			kSampleClipmapFlagBackfacingProbeRejection | kSampleClipmapFlagBiasSamplePointSurfaceNormal | kSampleClipmapFlagUsePreviousFrame;
+		const Vec3 irradiance = sampleClipmapIrradiance(hitPos, gbuffer.m_worldNormal, g_globalRendererConstants.m_cameraPosition, idConsts,
+														g_linearAnyRepeatSampler, flags);
 
 
 		radiance += irradiance * gbuffer.m_diffuse / kPi;
 		radiance += irradiance * gbuffer.m_diffuse / kPi;
 	}
 	}
@@ -127,7 +108,9 @@ ANKI_FAST_CONSTANTS(Consts, g_consts)
 	const F32 kMaxDist = 1000.0; // Chose something small and make sure its square doesn't overflow F16
 	const F32 kMaxDist = 1000.0; // Chose something small and make sure its square doesn't overflow F16
 	TEX(g_lightResultTex, UVec2(probeIdx, outPixelIdx + raysPerProbePerFrame * g_consts.m_clipmapIdx)) = HVec4(radiance, min(rayT, kMaxDist));
 	TEX(g_lightResultTex, UVec2(probeIdx, outPixelIdx + raysPerProbePerFrame * g_consts.m_clipmapIdx)) = HVec4(radiance, min(rayT, kMaxDist));
 }
 }
-#	else
+#	else // RT_MATERIAL_FETCH_CLIPMAP
+
+// RT based apply of indirect
 
 
 struct Consts
 struct Consts
 {
 {
@@ -176,15 +159,23 @@ ANKI_FAST_CONSTANTS(Consts, g_consts)
 		radiance = directLighting<F16>(gbuffer, hitPos, !hit, true, 1000.0, traceFlags | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH);
 		radiance = directLighting<F16>(gbuffer, hitPos, !hit, true, 1000.0, traceFlags | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH);
 	}
 	}
 
 
-	const Mat3x4 cameraTrf = g_globalRendererConstants.m_matrices.m_cameraTransform;
-	const Vec3 lookDir = -Vec3(cameraTrf.m_row0[2], cameraTrf.m_row1[2], cameraTrf.m_row2[2]);
-
-	const Vec3 rayOrigin = (hit) ? hitPos : biasedWorldPos;
-	const Vec3 rayDir2 = (hit) ? gbuffer.m_worldNormal : worldNormal;
-	const Bool biasSamplePoint = !hit; // Bias the sample point if it's not for the 2nd bounce
-	const Vec3 irradiance = sampleClipmapIrradianceAccurate(
-		rayOrigin, rayDir2, g_globalRendererConstants.m_cameraPosition, lookDir, g_globalRendererConstants.m_indirectDiffuseClipmaps,
-		g_irradianceVolumes, g_distanceMomentsVolumes, g_probeValidityVolumes, g_linearAnyRepeatSampler, randFactors.x, biasSamplePoint);
+	Vec3 rayOrigin;
+	Vec3 rayDir2;
+	if(hit)
+	{
+		// 2nd bounce
+		rayOrigin = hitPos;
+		rayDir2 = gbuffer.m_worldNormal;
+	}
+	else
+	{
+		rayOrigin = biasedWorldPos;
+		rayDir2 = worldNormal;
+	}
+	const SampleClipmapFlag flags = kSampleClipmapFlagFullQuality & ~(kSampleClipmapFlagBiasSamplePointTowardsCamera);
+	const Vec3 irradiance =
+		sampleClipmapIrradiance(rayOrigin, rayDir2, g_globalRendererConstants.m_cameraPosition, g_globalRendererConstants.m_indirectDiffuseClipmaps,
+								g_linearAnyRepeatSampler, flags, randFactors.x);
 
 
 	Vec3 final;
 	Vec3 final;
 	if(hit)
 	if(hit)
@@ -224,27 +215,31 @@ ANKI_FAST_CONSTANTS(Consts, g_consts)
 
 
 [NumThreads(64, 1, 1)] void main(COMPUTE_ARGS)
 [NumThreads(64, 1, 1)] void main(COMPUTE_ARGS)
 {
 {
-	const Clipmap clipmap = g_globalRendererConstants.m_indirectDiffuseClipmaps[g_consts.m_clipmapIdx];
+	const IndirectDiffuseClipmapConstants idConsts = g_globalRendererConstants.m_indirectDiffuseClipmaps;
+	const U32 clipmapIdx = g_consts.m_clipmapIdx;
+	const Vec3 clipmapSize = idConsts.m_sizes[clipmapIdx].xyz;
+	const UVec3 probeCounts = idConsts.m_probeCounts;
+	const Vec3 clipmapAabbMin = idConsts.m_aabbMins[clipmapIdx].xyz;
+	const Vec3 prevClipmapAabbMin = idConsts.m_previousFrameAabbMins[clipmapIdx].xyz;
 
 
 	const U32 halfRadianceOctMapSize = RADIANCE_OCTAHEDRON_MAP_SIZE / 2;
 	const U32 halfRadianceOctMapSize = RADIANCE_OCTAHEDRON_MAP_SIZE / 2;
 	const U32 raysPerProbePerFrame = square(halfRadianceOctMapSize);
 	const U32 raysPerProbePerFrame = square(halfRadianceOctMapSize);
 
 
 	const U32 rtPixelIdx = svDispatchThreadId.x % raysPerProbePerFrame;
 	const U32 rtPixelIdx = svDispatchThreadId.x % raysPerProbePerFrame;
 	const U32 probeIdx = svDispatchThreadId.x / raysPerProbePerFrame;
 	const U32 probeIdx = svDispatchThreadId.x / raysPerProbePerFrame;
-	if(probeIdx >= clipmap.m_probeCountTotal)
+	if(probeIdx >= idConsts.m_totalProbeCount)
 	{
 	{
 		return;
 		return;
 	}
 	}
 
 
-	const Vec3 probeSize = clipmap.m_size / clipmap.m_probeCounts;
+	const Vec3 probeSize = clipmapSize / probeCounts;
 	UVec3 probe3dIdx;
 	UVec3 probe3dIdx;
-	unflatten3dArrayIndex(clipmap.m_probeCounts.z, clipmap.m_probeCounts.y, clipmap.m_probeCounts.x, probeIdx, probe3dIdx.z, probe3dIdx.y,
-						  probe3dIdx.x);
-	const Vec3 probeWorldPos = probe3dIdx * probeSize + probeSize * 0.5 + clipmap.m_aabbMin;
-	const Bool blendWithHistory = all(probeWorldPos > clipmap.m_prevFrameAabbMin) && all(probeWorldPos < clipmap.m_prevFrameAabbMin + clipmap.m_size);
+	unflatten3dArrayIndex(probeCounts.z, probeCounts.y, probeCounts.x, probeIdx, probe3dIdx.z, probe3dIdx.y, probe3dIdx.x);
+	const Vec3 probeWorldPos = probe3dIdx * probeSize + probeSize * 0.5 + clipmapAabbMin;
+	const Bool blendWithHistory = all(probeWorldPos > prevClipmapAabbMin) && all(probeWorldPos < prevClipmapAabbMin + clipmapSize);
 
 
-	UVec3 noOctTexCoord = frac(probeWorldPos / clipmap.m_size) * clipmap.m_probeCounts;
-	noOctTexCoord = min(noOctTexCoord, clipmap.m_probeCounts - 1u);
+	UVec3 noOctTexCoord = frac(probeWorldPos / clipmapSize) * probeCounts;
+	noOctTexCoord = min(noOctTexCoord, probeCounts - 1u);
 	noOctTexCoord = noOctTexCoord.xzy;
 	noOctTexCoord = noOctTexCoord.xzy;
 
 
 	// Read the result from RT
 	// Read the result from RT
@@ -418,9 +413,9 @@ Vec3 decodeAtomicColor(U32 x, U32 y)
 // The group services a single probe. Every thread reads a radiance value and bins it to the appropreate irradiance pixel
 // The group services a single probe. Every thread reads a radiance value and bins it to the appropreate irradiance pixel
 [NumThreads(kThreadCount, 1, 1)] void main(COMPUTE_ARGS)
 [NumThreads(kThreadCount, 1, 1)] void main(COMPUTE_ARGS)
 {
 {
-	const U32 clipmapIdx = svGroupId.x / g_globalRendererConstants.m_indirectDiffuseClipmaps[0].m_probeCounts[0];
-	const UVec3 probeId = UVec3(svGroupId.x % g_globalRendererConstants.m_indirectDiffuseClipmaps[0].m_probeCounts[0], svGroupId.y, svGroupId.z);
-	const Clipmap clipmap = g_globalRendererConstants.m_indirectDiffuseClipmaps[clipmapIdx];
+	const IndirectDiffuseClipmapConstants idConsts = g_globalRendererConstants.m_indirectDiffuseClipmaps;
+	const U32 clipmapIdx = svGroupId.x / idConsts.m_probeCounts.x;
+	const UVec3 probeId = UVec3(svGroupId.x % idConsts.m_probeCounts.x, svGroupId.y, svGroupId.z);
 
 
 	// Zero shared memory
 	// Zero shared memory
 	const U32 irradianceTexelCount = IRRADIANCE_OCTAHEDRON_MAP_SIZE * IRRADIANCE_OCTAHEDRON_MAP_SIZE;
 	const U32 irradianceTexelCount = IRRADIANCE_OCTAHEDRON_MAP_SIZE * IRRADIANCE_OCTAHEDRON_MAP_SIZE;
@@ -440,7 +435,7 @@ Vec3 decodeAtomicColor(U32 x, U32 y)
 	UVec3 radianceTexelCoordStart = probeId.xzy;
 	UVec3 radianceTexelCoordStart = probeId.xzy;
 	radianceTexelCoordStart.xy *= RADIANCE_OCTAHEDRON_MAP_SIZE + 2;
 	radianceTexelCoordStart.xy *= RADIANCE_OCTAHEDRON_MAP_SIZE + 2;
 	radianceTexelCoordStart.xy += 1;
 	radianceTexelCoordStart.xy += 1;
-	const Vec3 radianceVolumeSize = clipmap.m_probeCounts.xzy * Vec3(RADIANCE_OCTAHEDRON_MAP_SIZE + 2, RADIANCE_OCTAHEDRON_MAP_SIZE + 2, 1.0);
+	const Vec3 radianceVolumeSize = idConsts.m_probeCounts.xzy * Vec3(RADIANCE_OCTAHEDRON_MAP_SIZE + 2, RADIANCE_OCTAHEDRON_MAP_SIZE + 2, 1.0);
 	const Vec3 radianceTexelStartUv = (Vec3(radianceTexelCoordStart) + Vec3(0.0, 0.0, 0.5)) / radianceVolumeSize;
 	const Vec3 radianceTexelStartUv = (Vec3(radianceTexelCoordStart) + Vec3(0.0, 0.0, 0.5)) / radianceVolumeSize;
 
 
 	const U32 halfRadianceOctMapSize = RADIANCE_OCTAHEDRON_MAP_SIZE / 2;
 	const U32 halfRadianceOctMapSize = RADIANCE_OCTAHEDRON_MAP_SIZE / 2;
@@ -551,11 +546,6 @@ Texture2D<Vec4> g_gbufferRt2 : register(t1);
 
 
 Texture2D<Vec4> g_blueNoiseTex : register(t2);
 Texture2D<Vec4> g_blueNoiseTex : register(t2);
 
 
-Texture3D<Vec4> g_clipmapVolumes[kIndirectDiffuseClipmapCount] : register(t3);
-Texture3D<Vec4> g_probeValidityVolumes[kIndirectDiffuseClipmapCount] : register(t6); // WARNING: Adjust if kIndirectDiffuseClipmapCount changed
-Texture3D<Vec4> g_distanceMomentsVolumes[kIndirectDiffuseClipmapCount] : register(t9);
-Texture3D<Vec4> g_avgIrradianceVolumes[kIndirectDiffuseClipmapCount] : register(t12);
-
 RWTexture2D<Vec4> g_outTex : register(u0);
 RWTexture2D<Vec4> g_outTex : register(u0);
 
 
 ConstantBuffer<GlobalRendererConstants> g_globalRendererConstants : register(b0);
 ConstantBuffer<GlobalRendererConstants> g_globalRendererConstants : register(b0);
@@ -587,33 +577,19 @@ SamplerState g_linearAnyRepeatSampler : register(s0);
 	noise3 = animateBlueNoise(noise3, g_globalRendererConstants.m_frame);
 	noise3 = animateBlueNoise(noise3, g_globalRendererConstants.m_frame);
 	const F32 noise = noise3.x;
 	const F32 noise = noise3.x;
 
 
-	const Mat3x4 cameraTrf = g_globalRendererConstants.m_matrices.m_cameraTransform;
-	const Vec3 lookDir = -Vec3(cameraTrf.m_row0[2], cameraTrf.m_row1[2], cameraTrf.m_row2[2]);
-
 	const U32 method = 0;
 	const U32 method = 0;
 	Vec3 irradiance;
 	Vec3 irradiance;
 	if(method == 0)
 	if(method == 0)
 	{
 	{
-		irradiance = sampleClipmapIrradianceAccurate(worldPos, normal, g_globalRendererConstants.m_cameraPosition, lookDir,
-													 g_globalRendererConstants.m_indirectDiffuseClipmaps, g_clipmapVolumes, g_distanceMomentsVolumes,
-													 g_probeValidityVolumes, g_linearAnyRepeatSampler, noise);
-	}
-	else if(method == 1)
-	{
-		irradiance = sampleClipmapIrradianceCheap(worldPos, normal, g_globalRendererConstants.m_indirectDiffuseClipmaps, g_clipmapVolumes,
-												  g_linearAnyRepeatSampler);
-	}
-	else if(method == 2)
-	{
-		irradiance = sampleClipmapAvgIrradianceAccurate(worldPos, normal, g_globalRendererConstants.m_cameraPosition, lookDir,
-														g_globalRendererConstants.m_indirectDiffuseClipmaps, g_avgIrradianceVolumes,
-														g_distanceMomentsVolumes, g_probeValidityVolumes, g_linearAnyRepeatSampler, noise);
+		const SampleClipmapFlag flags = kSampleClipmapFlagFullQuality;
+		irradiance = sampleClipmapIrradiance(worldPos, normal, g_globalRendererConstants.m_cameraPosition,
+											 g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags, noise);
 	}
 	}
 	else
 	else
 	{
 	{
-		irradiance = sampleClipmapAvgIrradianceCheap(worldPos, g_globalRendererConstants.m_cameraPosition, lookDir,
-													 g_globalRendererConstants.m_indirectDiffuseClipmaps, g_avgIrradianceVolumes, noise,
-													 g_linearAnyRepeatSampler, true);
+		const SampleClipmapFlag flags = kSampleClipmapFlagFullQuality;
+		irradiance = sampleClipmapAvgIrradiance(worldPos, normal, g_globalRendererConstants.m_cameraPosition,
+												g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags, noise);
 	}
 	}
 
 
 	TEX(g_outTex, svDispatchThreadId.xy).xyz = irradiance;
 	TEX(g_outTex, svDispatchThreadId.xy).xyz = irradiance;
@@ -672,15 +648,16 @@ constexpr U32 cubeIndices[36] = {0, 1, 2, 2, 3, 0, 1, 5, 6, 6, 2, 1, 5, 4, 7, 7,
 
 
 VertOut main(VertIn input)
 VertOut main(VertIn input)
 {
 {
-	const Clipmap clipmap = g_globalRendererConstants.m_indirectDiffuseClipmaps[g_consts.m_clipmapIdx];
 	const Vec3 camPos = g_globalRendererConstants.m_cameraPosition;
 	const Vec3 camPos = g_globalRendererConstants.m_cameraPosition;
+	const IndirectDiffuseClipmapConstants idConsts = g_globalRendererConstants.m_indirectDiffuseClipmaps;
+	const UVec3 probeCounts = idConsts.m_probeCounts;
+	const U32 clipmapIdx = g_consts.m_clipmapIdx;
 
 
 	UVec3 probeCoord;
 	UVec3 probeCoord;
-	unflatten3dArrayIndex(clipmap.m_probeCounts.z, clipmap.m_probeCounts.y, clipmap.m_probeCounts.x, input.m_svInstanceId, probeCoord.z, probeCoord.y,
-						  probeCoord.x);
+	unflatten3dArrayIndex(probeCounts.z, probeCounts.y, probeCounts.x, input.m_svInstanceId, probeCoord.z, probeCoord.y, probeCoord.x);
 
 
-	const Vec3 probeSize = clipmap.m_size / clipmap.m_probeCounts;
-	const Vec3 probeWorldPos = probeCoord * probeSize + probeSize * 0.5 + clipmap.m_aabbMin;
+	const Vec3 probeSize = idConsts.m_sizes[clipmapIdx] / probeCounts;
+	const Vec3 probeWorldPos = probeCoord * probeSize + probeSize * 0.5 + idConsts.m_aabbMins[clipmapIdx];
 
 
 	// Vert pos
 	// Vert pos
 	const U32 index = cubeIndices[input.m_svVertexId];
 	const U32 index = cubeIndices[input.m_svVertexId];
@@ -699,7 +676,9 @@ VertOut main(VertIn input)
 #	if ANKI_PIXEL_SHADER
 #	if ANKI_PIXEL_SHADER
 FragOut main(VertOut input)
 FragOut main(VertOut input)
 {
 {
-	const Clipmap clipmap = g_globalRendererConstants.m_indirectDiffuseClipmaps[g_consts.m_clipmapIdx];
+	const IndirectDiffuseClipmapConstants idConsts = g_globalRendererConstants.m_indirectDiffuseClipmaps;
+	const UVec3 probeCounts = idConsts.m_probeCounts;
+	const U32 clipmapIdx = g_consts.m_clipmapIdx;
 
 
 	FragOut output;
 	FragOut output;
 
 
@@ -727,22 +706,22 @@ FragOut main(VertOut input)
 	UVec3 texSize;
 	UVec3 texSize;
 	g_volume.GetDimensions(texSize.x, texSize.y, texSize.z);
 	g_volume.GetDimensions(texSize.x, texSize.y, texSize.z);
 
 
-	const Bool hasOctMap = texSize.x != clipmap.m_probeCounts.x;
+	const Bool hasOctMap = texSize.x != probeCounts.x;
 
 
-	Vec3 uvw = frac(input.m_probeCenter.xzy / clipmap.m_size.xzy);
-	const UVec3 texelCoord = uvw * clipmap.m_probeCounts.xzy;
+	Vec3 uvw = frac(input.m_probeCenter.xzy / idConsts.m_sizes[clipmapIdx].xzy);
+	const UVec3 texelCoord = uvw * probeCounts.xzy;
 
 
 	if(hasOctMap)
 	if(hasOctMap)
 	{
 	{
-		const U32 octProbeSize = texSize.x / clipmap.m_probeCounts.x - 2;
+		const U32 octProbeSize = texSize.x / probeCounts.x - 2;
 
 
 		const Vec3 normal = normalize(collisionPoint - input.m_probeCenter);
 		const Vec3 normal = normalize(collisionPoint - input.m_probeCenter);
 
 
 		uvw.xy = texelCoord.xy * (octProbeSize + 2);
 		uvw.xy = texelCoord.xy * (octProbeSize + 2);
 		uvw.xy += octahedronEncode(normal) * octProbeSize + 1.0;
 		uvw.xy += octahedronEncode(normal) * octProbeSize + 1.0;
-		uvw.xy /= clipmap.m_probeCounts.xz * (octProbeSize + 2);
+		uvw.xy /= probeCounts.xz * (octProbeSize + 2);
 
 
-		uvw.z = (texelCoord.z + 0.5) / clipmap.m_probeCounts.y;
+		uvw.z = (texelCoord.z + 0.5) / probeCounts.y;
 	}
 	}
 	else
 	else
 	{
 	{

+ 166 - 142
AnKi/Shaders/IndirectDiffuseClipmaps.hlsl

@@ -8,15 +8,35 @@
 #include <AnKi/Shaders/Common.hlsl>
 #include <AnKi/Shaders/Common.hlsl>
 #include <AnKi/Shaders/Include/MiscRendererTypes.h>
 #include <AnKi/Shaders/Include/MiscRendererTypes.h>
 
 
-F32 computeClipmapFade(Clipmap clipmap, Vec3 cameraPos, Vec3 lookDir, Vec3 worldPos)
+/// Flags to fine tune the probe selection in sampleClipmapCommon
+enum SampleClipmapFlag : U32
 {
 {
-	const Vec3 offset = normalize(lookDir) * kIndirectDiffuseClipmapForwardBias * (clipmap.m_index + 1);
-	const Vec3 biasedCameraPos = cameraPos + offset;
+	kSampleClipmapFlagAccurateClipmapSelection = 1 << 0,
+	kSampleClipmapFlagBiasSamplePointTowardsCamera = 1 << 1,
+	kSampleClipmapFlagBiasSamplePointSurfaceNormal = 1 << 2,
+	kSampleClipmapFlagInvalidProbeRejection = 1 << 3,
+	kSampleClipmapFlagChebyshevOcclusion = 1 << 4,
+	kSampleClipmapFlagBackfacingProbeRejection = 1 << 5,
+	kSampleClipmapFlagUsePreviousFrame = 1 << 6,
+
+	kSampleClipmapFlagFullQuality = (1 << 5) - 1,
+	kSampleClipmapFlagNone = 0
+};
 
 
-	const Vec3 probeSize = clipmap.m_size / clipmap.m_probeCounts;
-	const Vec3 halfSize = clipmap.m_size * 0.5;
-	const Vec3 aabbMin = biasedCameraPos - halfSize + probeSize;
-	const Vec3 aabbMax = biasedCameraPos + halfSize - probeSize;
+F32 computeClipmapFade(IndirectDiffuseClipmapConstants consts, U32 clipmapIdx, Vec3 cameraPos, Vec3 worldPos, SampleClipmapFlag flags)
+{
+	Vec3 aabbMin;
+	Vec3 aabbMax;
+	if(flags & kSampleClipmapFlagUsePreviousFrame)
+	{
+		aabbMin = consts.m_previousFrameAabbMins[clipmapIdx].xyz;
+		aabbMax = consts.m_previousFrameAabbMins[clipmapIdx].xyz + consts.m_sizes[clipmapIdx].xyz;
+	}
+	else
+	{
+		aabbMin = consts.m_aabbMins[clipmapIdx].xyz;
+		aabbMax = consts.m_aabbMins[clipmapIdx].xyz + consts.m_sizes[clipmapIdx].xyz;
+	}
 
 
 	const Vec3 distances = select(worldPos > cameraPos, aabbMax - cameraPos, cameraPos - aabbMin);
 	const Vec3 distances = select(worldPos > cameraPos, aabbMax - cameraPos, cameraPos - aabbMin);
 
 
@@ -30,16 +50,29 @@ F32 computeClipmapFade(Clipmap clipmap, Vec3 cameraPos, Vec3 lookDir, Vec3 world
 	return fade;
 	return fade;
 }
 }
 
 
-Bool insideClipmap(Clipmap clipmap, Vec3 worldPos)
+Bool insideClipmap(IndirectDiffuseClipmapConstants consts, U32 clipmapIdx, Vec3 worldPos, SampleClipmapFlag flags)
 {
 {
-	return (all(worldPos < clipmap.m_aabbMin + clipmap.m_size) && all(worldPos > clipmap.m_aabbMin));
+	Vec3 aabbMin;
+	Vec3 aabbMax;
+	if(flags & kSampleClipmapFlagUsePreviousFrame)
+	{
+		aabbMin = consts.m_previousFrameAabbMins[clipmapIdx].xyz;
+		aabbMax = consts.m_previousFrameAabbMins[clipmapIdx].xyz + consts.m_sizes[clipmapIdx].xyz;
+	}
+	else
+	{
+		aabbMin = consts.m_aabbMins[clipmapIdx].xyz;
+		aabbMax = consts.m_aabbMins[clipmapIdx].xyz + consts.m_sizes[clipmapIdx].xyz;
+	}
+
+	return (all(worldPos < aabbMax) && all(worldPos > aabbMin));
 }
 }
 
 
-U16 findClipmapOnPosition(Clipmap clipmaps[kIndirectDiffuseClipmapCount], Vec3 cameraPos, Vec3 lookDir, Vec3 worldPos, F32 randFactor)
+U16 findClipmapOnPosition(IndirectDiffuseClipmapConstants consts, Vec3 cameraPos, Vec3 worldPos, F32 randFactor, SampleClipmapFlag flags)
 {
 {
 	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
 	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
 	{
 	{
-		const F32 fade = computeClipmapFade(clipmaps[i], cameraPos, lookDir, worldPos);
+		const F32 fade = computeClipmapFade(consts, i, cameraPos, worldPos, flags);
 		if(fade > randFactor)
 		if(fade > randFactor)
 		{
 		{
 			return i;
 			return i;
@@ -49,11 +82,11 @@ U16 findClipmapOnPosition(Clipmap clipmaps[kIndirectDiffuseClipmapCount], Vec3 c
 	return kIndirectDiffuseClipmapCount;
 	return kIndirectDiffuseClipmapCount;
 }
 }
 
 
-U16 findClipmapOnPositionCheap(Clipmap clipmaps[kIndirectDiffuseClipmapCount], Vec3 worldPos)
+U16 findClipmapOnPositionCheap(IndirectDiffuseClipmapConstants consts, Vec3 worldPos, SampleClipmapFlag flags)
 {
 {
 	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
 	for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
 	{
 	{
-		if(insideClipmap(clipmaps[i], worldPos))
+		if(insideClipmap(consts, i, worldPos, flags))
 		{
 		{
 			return i;
 			return i;
 		}
 		}
@@ -62,38 +95,60 @@ U16 findClipmapOnPositionCheap(Clipmap clipmaps[kIndirectDiffuseClipmapCount], V
 	return kIndirectDiffuseClipmapCount;
 	return kIndirectDiffuseClipmapCount;
 }
 }
 
 
-struct SampleClipmapsConfig
-{
-	Bool m_fastClipmapSelection;
-	Bool m_biasSamplePoint;
-	Bool m_doInvalidProbeRejection;
-	Bool m_doChebyshevOcclusion;
-	Bool m_primaryVolumesHaveOctMap;
-	Bool m_normalRejection;
-};
-
 struct SampleClipmapsArgs
 struct SampleClipmapsArgs
 {
 {
+	SampleClipmapFlag m_flags;
+	U32 m_primaryVolume; // 0: Irradiance, 1: radiance, 2: avgIrradiance
+
 	F32 m_clipmapSelectionRandFactor;
 	F32 m_clipmapSelectionRandFactor;
 	Vec3 m_samplePoint;
 	Vec3 m_samplePoint;
 	Vec3 m_normal;
 	Vec3 m_normal;
 	Vec3 m_cameraPos;
 	Vec3 m_cameraPos;
-	Vec3 m_lookDir; // Only used when SampleClipmapsConfig::m_fastClipmapSelection is false
 };
 };
 
 
+Vec3 computeBiasedSamplePoint(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, SampleClipmapFlag flags, F32 bias)
+{
+	constexpr SampleClipmapFlag bothBiases = kSampleClipmapFlagBiasSamplePointTowardsCamera | kSampleClipmapFlagBiasSamplePointSurfaceNormal;
+
+	if(flags & bothBiases)
+	{
+		Vec3 biasDir = 0.0;
+		if(flags & kSampleClipmapFlagBiasSamplePointTowardsCamera)
+		{
+			biasDir = normalize(cameraPos - samplePoint);
+		}
+
+		if(flags & kSampleClipmapFlagBiasSamplePointSurfaceNormal)
+		{
+			biasDir += normal;
+		}
+
+		if((flags & bothBiases) == bothBiases)
+		{
+			// Normalize if both biases have been applied
+			biasDir = normalize(biasDir);
+		}
+
+		return samplePoint + biasDir * bias;
+	}
+	else
+	{
+		return samplePoint;
+	}
+}
+
 /// Find out the clipmap for a given sample point and sample the probes in the volumes.
 /// Find out the clipmap for a given sample point and sample the probes in the volumes.
-Vec3 sampleClipmapIrradianceCommon(SampleClipmapsConfig cfg, SampleClipmapsArgs args, Texture3D<Vec4> primaryVolumes[kIndirectDiffuseClipmapCount],
-								   Texture3D<Vec4> distanceMomentsVolumes[kIndirectDiffuseClipmapCount],
-								   Texture3D<Vec4> probeValidityVolumes[kIndirectDiffuseClipmapCount], SamplerState linearAnyRepeatSampler,
-								   Clipmap clipmaps[kIndirectDiffuseClipmapCount])
+Vec3 sampleClipmapCommon(SampleClipmapsArgs args, SamplerState linearAnyRepeatSampler, IndirectDiffuseClipmapConstants consts)
 {
 {
+	const SampleClipmapFlag flags = args.m_flags;
+
 #if 1
 #if 1
-	const U16 clipmapIdx = (cfg.m_fastClipmapSelection) ? findClipmapOnPositionCheap(clipmaps, args.m_samplePoint)
-														: findClipmapOnPosition(clipmaps, args.m_cameraPos, args.m_lookDir, args.m_samplePoint,
-																				args.m_clipmapSelectionRandFactor);
+	const U16 clipmapIdx = (flags & kSampleClipmapFlagAccurateClipmapSelection)
+							   ? findClipmapOnPosition(consts, args.m_cameraPos, args.m_samplePoint, args.m_clipmapSelectionRandFactor, flags)
+							   : findClipmapOnPositionCheap(consts, args.m_samplePoint, flags);
 #else
 #else
 	U16 clipmapIdx = 0;
 	U16 clipmapIdx = 0;
-	if(!insideClipmap(clipmaps[clipmapIdx], args.m_samplePoint))
+	if(!insideClipmap(consts, clipmapIdx, args.m_samplePoint))
 	{
 	{
 		clipmapIdx = 10;
 		clipmapIdx = 10;
 	}
 	}
@@ -123,36 +178,24 @@ Vec3 sampleClipmapIrradianceCommon(SampleClipmapsConfig cfg, SampleClipmapsArgs
 		return 0.0;
 		return 0.0;
 	}
 	}
 
 
-	const Clipmap clipmap = clipmaps[clipmapIdx];
-	const Vec3 probeSize = clipmap.m_size / clipmap.m_probeCounts;
-	const Vec3 fakeVolumeSize = clipmap.m_probeCounts; // Volume size without the octahedron
+	const Vec3 clipmapSize = consts.m_sizes[clipmapIdx].xyz;
+	const Vec3 probeCountsf = consts.m_probeCounts;
+	const IndirectDiffuseClipmapTextures textures = consts.m_textures[clipmapIdx];
 
 
-	const Vec3 biasDir = normalize(args.m_cameraPos - args.m_samplePoint);
-	const Vec3 biasedWorldPos = (cfg.m_biasSamplePoint) ? args.m_samplePoint + biasDir * probeSize * 0.2 : args.m_samplePoint;
+	const Vec3 probeSize = clipmapSize / probeCountsf;
+	const Vec3 fakeVolumeSize = probeCountsf; // Volume size without the octahedron
 
 
-	F32 octahedronSize = 0.0;
-	Vec3 realVolumeSize = 0.0;
-	{
-		primaryVolumes[0].GetDimensions(realVolumeSize.x, realVolumeSize.y, realVolumeSize.z);
+	const Vec3 biasedWorldPos = computeBiasedSamplePoint(args.m_samplePoint, args.m_normal, args.m_cameraPos, flags, min3(probeSize) * 0.2);
 
 
-		if(cfg.m_primaryVolumesHaveOctMap)
-		{
-			octahedronSize = realVolumeSize.x / clipmap.m_probeCounts.x;
-			octahedronSize -= 2.0; // The border
-		}
-	};
+	const Bool primaryVolumesHaveOctMap = args.m_primaryVolume != 2;
+	const F32 octahedronSize =
+		(primaryVolumesHaveOctMap) ? ((args.m_primaryVolume == 0) ? textures.m_irradianceOctMapSize : textures.m_radianceOctMapSize) : 1.0;
+	const Vec3 realVolumeSize = probeCountsf.xzy * Vec3(octahedronSize + 2.0, octahedronSize + 2.0, 1.0);
 
 
-	F32 distMomentsOctSize = 0.0;
-	Vec3 distMomentsRealVolumeSize = 0.0;
-	if(cfg.m_doChebyshevOcclusion)
-	{
-		distanceMomentsVolumes[0].GetDimensions(distMomentsRealVolumeSize.x, distMomentsRealVolumeSize.y, distMomentsRealVolumeSize.z);
-
-		distMomentsOctSize = distMomentsRealVolumeSize.x / clipmap.m_probeCounts.x;
-		distMomentsOctSize -= 2.0; // The border
-	}
+	const F32 distMomentsOctSize = textures.m_distanceMomentsOctMapSize;
+	const Vec3 distMomentsRealVolumeSize = probeCountsf.xzy * Vec3(distMomentsOctSize + 2.0, distMomentsOctSize + 2.0, 1.0);
 
 
-	const Vec3 samplePointUvw = frac(biasedWorldPos / clipmap.m_size);
+	const Vec3 samplePointUvw = frac(biasedWorldPos / clipmapSize);
 	const Vec3 icoord = floor(samplePointUvw * fakeVolumeSize - 0.5);
 	const Vec3 icoord = floor(samplePointUvw * fakeVolumeSize - 0.5);
 	const Vec3 fcoord = frac(samplePointUvw * fakeVolumeSize - 0.5);
 	const Vec3 fcoord = frac(samplePointUvw * fakeVolumeSize - 0.5);
 
 
@@ -169,23 +212,20 @@ Vec3 sampleClipmapIrradianceCommon(SampleClipmapsConfig cfg, SampleClipmapsArgs
 		coords = select(coords >= 0.0, coords, fakeVolumeSize + coords);
 		coords = select(coords >= 0.0, coords, fakeVolumeSize + coords);
 		coords = select(coords < fakeVolumeSize, coords, coords - fakeVolumeSize);
 		coords = select(coords < fakeVolumeSize, coords, coords - fakeVolumeSize);
 
 
-		if(cfg.m_doInvalidProbeRejection)
+		if(flags & kSampleClipmapFlagInvalidProbeRejection)
 		{
 		{
-			const Bool valid = TEX(probeValidityVolumes[NonUniformResourceIndex(clipmapIdx)], coords.xzy).x > 0.8;
+			const Bool valid = TEX(getBindlessTextureNonUniformIndex3DVec4(textures.m_probeValidityTexture), coords.xzy).x > 0.8;
 			if(!valid)
 			if(!valid)
 			{
 			{
 				continue;
 				continue;
 			}
 			}
 		}
 		}
 
 
-		// Reject probes outside the current clipmap. The accurate version doesn't need that because it fades between clipmaps.
+		// Reject probes outside the current clipmap
 		const Vec3 probePosition = firstProbePosition + xyz * probeSize;
 		const Vec3 probePosition = firstProbePosition + xyz * probeSize;
-		if(cfg.m_fastClipmapSelection)
+		if(!insideClipmap(consts, clipmapIdx, probePosition, flags))
 		{
 		{
-			if(!insideClipmap(clipmap, probePosition))
-			{
-				continue;
-			}
+			continue;
 		}
 		}
 
 
 		// Filtering weight
 		// Filtering weight
@@ -193,7 +233,7 @@ Vec3 sampleClipmapIrradianceCommon(SampleClipmapsConfig cfg, SampleClipmapsArgs
 		F32 w = w3.x * w3.y * w3.z;
 		F32 w = w3.x * w3.y * w3.z;
 
 
 		// Normal weight
 		// Normal weight
-		if(cfg.m_normalRejection)
+		if(flags & kSampleClipmapFlagBackfacingProbeRejection)
 		{
 		{
 			const Vec3 dir = normalize(probePosition - args.m_samplePoint);
 			const Vec3 dir = normalize(probePosition - args.m_samplePoint);
 			const F32 wNormal = (dot(dir, args.m_normal) + 1.0) * 0.5;
 			const F32 wNormal = (dot(dir, args.m_normal) + 1.0) * 0.5;
@@ -201,7 +241,7 @@ Vec3 sampleClipmapIrradianceCommon(SampleClipmapsConfig cfg, SampleClipmapsArgs
 		}
 		}
 
 
 		// Chebyshev occlusion
 		// Chebyshev occlusion
-		if(cfg.m_doChebyshevOcclusion)
+		if(flags & kSampleClipmapFlagChebyshevOcclusion)
 		{
 		{
 			Vec3 uvw = coords.xzy;
 			Vec3 uvw = coords.xzy;
 			uvw.xy *= distMomentsOctSize + 2.0;
 			uvw.xy *= distMomentsOctSize + 2.0;
@@ -209,7 +249,8 @@ Vec3 sampleClipmapIrradianceCommon(SampleClipmapsConfig cfg, SampleClipmapsArgs
 			uvw.xy += octahedronEncode(normalize(biasedWorldPos - probePosition)) * distMomentsOctSize;
 			uvw.xy += octahedronEncode(normalize(biasedWorldPos - probePosition)) * distMomentsOctSize;
 			uvw.z += 0.5;
 			uvw.z += 0.5;
 			uvw /= distMomentsRealVolumeSize;
 			uvw /= distMomentsRealVolumeSize;
-			const Vec2 distMoments = distanceMomentsVolumes[NonUniformResourceIndex(clipmapIdx)].SampleLevel(linearAnyRepeatSampler, uvw, 0.0);
+			const Vec2 distMoments =
+				getBindlessTextureNonUniformIndex3DVec4(textures.m_distanceMomentsTexture).SampleLevel(linearAnyRepeatSampler, uvw, 0.0);
 
 
 			const F32 variance = abs(distMoments.x * distMoments.x - distMoments.y);
 			const F32 variance = abs(distMoments.x * distMoments.x - distMoments.y);
 
 
@@ -229,9 +270,22 @@ Vec3 sampleClipmapIrradianceCommon(SampleClipmapsConfig cfg, SampleClipmapsArgs
 			w *= chebyshevWeight;
 			w *= chebyshevWeight;
 		}
 		}
 
 
-		// Compute the actual coords
+		// Compute the actual coords and sample
+		U32 bindlessIndex;
+		switch(args.m_primaryVolume)
+		{
+		case 0:
+			bindlessIndex = textures.m_irradianceTexture;
+			break;
+		case 1:
+			bindlessIndex = textures.m_radianceTexture;
+			break;
+		default:
+			bindlessIndex = textures.m_averageIrradianceTexture;
+		}
+
 		Vec3 v;
 		Vec3 v;
-		if(cfg.m_primaryVolumesHaveOctMap)
+		if(primaryVolumesHaveOctMap)
 		{
 		{
 			Vec3 uvw = coords.xzy;
 			Vec3 uvw = coords.xzy;
 			uvw.xy *= octahedronSize + 2.0;
 			uvw.xy *= octahedronSize + 2.0;
@@ -240,11 +294,11 @@ Vec3 sampleClipmapIrradianceCommon(SampleClipmapsConfig cfg, SampleClipmapsArgs
 			uvw.z += 0.5;
 			uvw.z += 0.5;
 			uvw /= realVolumeSize;
 			uvw /= realVolumeSize;
 
 
-			v = primaryVolumes[NonUniformResourceIndex(clipmapIdx)].SampleLevel(linearAnyRepeatSampler, uvw, 0.0);
+			v = getBindlessTextureNonUniformIndex3DVec4(bindlessIndex).SampleLevel(linearAnyRepeatSampler, uvw, 0.0);
 		}
 		}
 		else
 		else
 		{
 		{
-			v = TEX(primaryVolumes[NonUniformResourceIndex(clipmapIdx)], coords.xzy);
+			v = TEX(getBindlessTextureNonUniformIndex3DVec4(bindlessIndex), coords.xzy);
 		}
 		}
 
 
 		value += v * w;
 		value += v * w;
@@ -263,94 +317,64 @@ Vec3 sampleClipmapIrradianceCommon(SampleClipmapsConfig cfg, SampleClipmapsArgs
 	return value;
 	return value;
 }
 }
 
 
-Vec3 sampleClipmapIrradianceAccurate(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, Vec3 lookDir, Clipmap clipmaps[kIndirectDiffuseClipmapCount],
-									 Texture3D<Vec4> primaryVolumes[kIndirectDiffuseClipmapCount],
-									 Texture3D<Vec4> distanceMomentsVolumes[kIndirectDiffuseClipmapCount],
-									 Texture3D<Vec4> probeValidityVolumes[kIndirectDiffuseClipmapCount], SamplerState linearAnyRepeatSampler,
-									 F32 randFactor, Bool biasSamplePoint = true)
+Vec3 sampleClipmapIrradiance(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts,
+							 SamplerState linearAnyRepeatSampler, SampleClipmapFlag flags = kSampleClipmapFlagFullQuality, F32 randFactor = 0.5)
 {
 {
-	SampleClipmapsConfig cfg;
-	cfg.m_biasSamplePoint = biasSamplePoint;
-	cfg.m_doChebyshevOcclusion = true;
-	cfg.m_doInvalidProbeRejection = true;
-	cfg.m_fastClipmapSelection = false;
-	cfg.m_primaryVolumesHaveOctMap = true;
-	cfg.m_normalRejection = true;
-
 	SampleClipmapsArgs args;
 	SampleClipmapsArgs args;
+	args.m_primaryVolume = 0;
+	args.m_flags = flags;
 	args.m_cameraPos = cameraPos;
 	args.m_cameraPos = cameraPos;
 	args.m_clipmapSelectionRandFactor = randFactor;
 	args.m_clipmapSelectionRandFactor = randFactor;
-	args.m_lookDir = lookDir;
 	args.m_normal = normal;
 	args.m_normal = normal;
 	args.m_samplePoint = samplePoint;
 	args.m_samplePoint = samplePoint;
 
 
-	return sampleClipmapIrradianceCommon(cfg, args, primaryVolumes, distanceMomentsVolumes, probeValidityVolumes, linearAnyRepeatSampler, clipmaps);
+	return sampleClipmapCommon(args, linearAnyRepeatSampler, consts);
 }
 }
 
 
-Vec3 sampleClipmapIrradianceCheap(Vec3 samplePoint, Vec3 normal, Clipmap clipmaps[kIndirectDiffuseClipmapCount],
-								  Texture3D<Vec4> primaryVolumes[kIndirectDiffuseClipmapCount], SamplerState linearAnyRepeatSampler,
-								  Bool biasSamplePoint = true)
+Vec3 sampleClipmapAvgIrradianceCheap(Vec3 samplePoint, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts, F32 randFactor,
+									 SamplerState linearAnyRepeatSampler, SampleClipmapFlag flags)
 {
 {
-	SampleClipmapsConfig cfg;
-	cfg.m_biasSamplePoint = biasSamplePoint;
-	cfg.m_doChebyshevOcclusion = false;
-	cfg.m_doInvalidProbeRejection = false;
-	cfg.m_fastClipmapSelection = true;
-	cfg.m_primaryVolumesHaveOctMap = true;
-	cfg.m_normalRejection = true;
+	const U16 clipmapIdx = (flags & kSampleClipmapFlagAccurateClipmapSelection)
+							   ? findClipmapOnPosition(consts, cameraPos, samplePoint, randFactor, flags)
+							   : findClipmapOnPositionCheap(consts, samplePoint, flags);
 
 
-	SampleClipmapsArgs args;
-	args.m_cameraPos = 0.0;
-	args.m_clipmapSelectionRandFactor = 0.0;
-	args.m_lookDir = 0.0;
-	args.m_normal = normal;
-	args.m_samplePoint = samplePoint;
+	if(clipmapIdx >= kIndirectDiffuseClipmapCount)
+	{
+		return 0.0;
+	}
 
 
-	return sampleClipmapIrradianceCommon(cfg, args, primaryVolumes, primaryVolumes, primaryVolumes, linearAnyRepeatSampler, clipmaps);
-}
+	const Vec3 clipmapSize = consts.m_sizes[clipmapIdx].xyz;
+	const Vec3 probeCountsf = consts.m_probeCounts;
 
 
-Vec3 sampleClipmapAvgIrradianceAccurate(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, Vec3 lookDir, Clipmap clipmaps[kIndirectDiffuseClipmapCount],
-										Texture3D<Vec4> primaryVolumes[kIndirectDiffuseClipmapCount],
-										Texture3D<Vec4> distanceMomentsVolumes[kIndirectDiffuseClipmapCount],
-										Texture3D<Vec4> probeValidityVolumes[kIndirectDiffuseClipmapCount], SamplerState linearAnyRepeatSampler,
-										F32 randFactor, Bool biasSamplePoint = true, Bool normalRejection = true)
-{
-	SampleClipmapsConfig cfg;
-	cfg.m_biasSamplePoint = biasSamplePoint;
-	cfg.m_doChebyshevOcclusion = true;
-	cfg.m_doInvalidProbeRejection = true;
-	cfg.m_fastClipmapSelection = false;
-	cfg.m_primaryVolumesHaveOctMap = false;
-	cfg.m_normalRejection = normalRejection;
+	const Vec3 probeSize = clipmapSize / probeCountsf;
+	const Vec3 biasedWorldPos = computeBiasedSamplePoint(samplePoint, 0.0, cameraPos, flags, min3(probeSize) * 0.2);
 
 
-	SampleClipmapsArgs args;
-	args.m_cameraPos = cameraPos;
-	args.m_clipmapSelectionRandFactor = randFactor;
-	args.m_lookDir = lookDir;
-	args.m_normal = normal;
-	args.m_samplePoint = samplePoint;
+	const Vec3 samplePointUvw = (biasedWorldPos / clipmapSize).xzy;
 
 
-	return sampleClipmapIrradianceCommon(cfg, args, primaryVolumes, distanceMomentsVolumes, probeValidityVolumes, linearAnyRepeatSampler, clipmaps);
+	return getBindlessTextureNonUniformIndex3DVec4(consts.m_textures[clipmapIdx].m_averageIrradianceTexture)
+		.SampleLevel(linearAnyRepeatSampler, samplePointUvw, 0.0)
+		.xyz;
 }
 }
 
 
-Vec3 sampleClipmapAvgIrradianceCheap(Vec3 samplePoint, Vec3 cameraPos, Vec3 lookDir, Clipmap clipmaps[kIndirectDiffuseClipmapCount],
-									 Texture3D<Vec4> primaryVolumes[kIndirectDiffuseClipmapCount], F32 randFactor,
-									 SamplerState linearAnyRepeatSampler, Bool biasSamplePoint = true)
+Vec3 sampleClipmapAvgIrradiance(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts,
+								SamplerState linearAnyRepeatSampler, SampleClipmapFlag flags = kSampleClipmapFlagFullQuality, F32 randFactor = 0.5)
 {
 {
-	const U16 clipmapIdx = findClipmapOnPosition(clipmaps, cameraPos, lookDir, samplePoint, randFactor);
-
-	if(clipmapIdx >= kIndirectDiffuseClipmapCount)
+	const SampleClipmapFlag requireManualTrilinearFiltering =
+		kSampleClipmapFlagInvalidProbeRejection | kSampleClipmapFlagBackfacingProbeRejection | kSampleClipmapFlagChebyshevOcclusion;
+	if(flags & requireManualTrilinearFiltering)
 	{
 	{
-		return 0.0;
+		SampleClipmapsArgs args;
+		args.m_primaryVolume = 2;
+		args.m_flags = flags;
+		args.m_cameraPos = cameraPos;
+		args.m_clipmapSelectionRandFactor = randFactor;
+		args.m_normal = normal;
+		args.m_samplePoint = samplePoint;
+
+		return sampleClipmapCommon(args, linearAnyRepeatSampler, consts);
+	}
+	else
+	{
+		return sampleClipmapAvgIrradianceCheap(samplePoint, cameraPos, consts, randFactor, linearAnyRepeatSampler, flags);
 	}
 	}
-
-	const Clipmap clipmap = clipmaps[clipmapIdx];
-	const Vec3 probeSize = clipmap.m_size / clipmap.m_probeCounts;
-
-	const Vec3 biasDir = normalize(cameraPos - samplePoint);
-	const Vec3 biasedWorldPos = (biasSamplePoint) ? samplePoint + biasDir * probeSize * 0.2 : samplePoint;
-
-	const Vec3 samplePointUvw = (biasedWorldPos / clipmap.m_size).xzy;
-
-	return primaryVolumes[NonUniformResourceIndex(clipmapIdx)].SampleLevel(linearAnyRepeatSampler, samplePointUvw, 0.0).xyz;
 }
 }

+ 4 - 8
AnKi/Shaders/RtMaterialFetch.hlsl

@@ -39,16 +39,12 @@ StructuredBuffer<GpuSceneGlobalIlluminationProbe> g_giProbes : register(t3, SPAC
 StructuredBuffer<PixelFailedSsr> g_pixelsFailedSsr : register(t4, SPACE);
 StructuredBuffer<PixelFailedSsr> g_pixelsFailedSsr : register(t4, SPACE);
 #	endif
 #	endif
 
 
-Texture3D<Vec4> g_irradianceVolumes[kIndirectDiffuseClipmapCount] : register(t5, SPACE);
-Texture3D<Vec4> g_probeValidityVolumes[kIndirectDiffuseClipmapCount] : register(t8, SPACE); // WARNING: Adjust if kIndirectDiffuseClipmapCount changed
-Texture3D<Vec4> g_distanceMomentsVolumes[kIndirectDiffuseClipmapCount] : register(t11, SPACE);
-
 #	if defined(CLIPMAP_VOLUME)
 #	if defined(CLIPMAP_VOLUME)
-Texture2D<Vec4> g_dummyTex[3] : register(t14, SPACE);
+Texture2D<Vec4> g_dummyTex[3] : register(t5, SPACE);
 #	else
 #	else
-Texture2D<Vec4> g_depthTex : register(t14, SPACE);
-Texture2D<Vec4> g_gbufferRt1 : register(t15, SPACE);
-Texture2D<Vec4> g_gbufferRt2 : register(t16, SPACE);
+Texture2D<Vec4> g_depthTex : register(t5, SPACE);
+Texture2D<Vec4> g_gbufferRt1 : register(t6, SPACE);
+Texture2D<Vec4> g_gbufferRt2 : register(t7, SPACE);
 #	endif
 #	endif
 
 
 // UAVs
 // UAVs

+ 4 - 21
AnKi/Shaders/VolumetricLightingAccumulation.ankiprog

@@ -32,11 +32,7 @@ StructuredBuffer<SpotLight> g_spotLights : register(t3);
 Texture2D<Vec4> g_shadowAtlasTex : register(t4);
 Texture2D<Vec4> g_shadowAtlasTex : register(t4);
 StructuredBuffer<FogDensityVolume> g_fogDensityVolumes : register(t5);
 StructuredBuffer<FogDensityVolume> g_fogDensityVolumes : register(t5);
 StructuredBuffer<Cluster> g_clusters : register(t6);
 StructuredBuffer<Cluster> g_clusters : register(t6);
-#if CLIPMAP_DIFFUSE_INDIRECT
-Texture3D<Vec4> g_avgIrradianceVolumes[kIndirectDiffuseClipmapCount] : register(t7);
-Texture3D<Vec4> g_probeValidityVolumes[kIndirectDiffuseClipmapCount] : register(t10);
-Texture3D<Vec4> g_distanceMomentsVolumes[kIndirectDiffuseClipmapCount] : register(t13);
-#else
+#if !CLIPMAP_DIFFUSE_INDIRECT
 StructuredBuffer<GlobalIlluminationProbe> g_giProbes : register(t7);
 StructuredBuffer<GlobalIlluminationProbe> g_giProbes : register(t7);
 #endif
 #endif
 
 
@@ -164,22 +160,9 @@ Vec4 accumulateLightsAndFog(Cluster cluster, Vec3 worldPos, F32 negativeZViewSpa
 	// Indirect diffuse GI
 	// Indirect diffuse GI
 #if CLIPMAP_DIFFUSE_INDIRECT
 #if CLIPMAP_DIFFUSE_INDIRECT
 	{
 	{
-		const Mat3x4 cameraTrf = g_globalConstants.m_matrices.m_cameraTransform;
-		const Vec3 lookDir = -Vec3(cameraTrf.m_row0[2], cameraTrf.m_row1[2], cameraTrf.m_row2[2]);
-
-		Vec3 irradiance;
-		if(1)
-		{
-			irradiance =
-				sampleClipmapAvgIrradianceCheap(worldPos, g_globalConstants.m_cameraPosition, lookDir, g_globalConstants.m_indirectDiffuseClipmaps,
-												g_avgIrradianceVolumes, noise, g_linearAnyRepeatSampler, false);
-		}
-		else
-		{
-			irradiance = sampleClipmapAvgIrradianceAccurate(
-				worldPos, 0.0, g_globalConstants.m_cameraPosition, lookDir, g_globalConstants.m_indirectDiffuseClipmaps, g_avgIrradianceVolumes,
-				g_distanceMomentsVolumes, g_probeValidityVolumes, g_linearAnyRepeatSampler, noise, false, false);
-		}
+		const SampleClipmapFlag flags = kSampleClipmapFlagNone;
+		const Vec3 irradiance = sampleClipmapAvgIrradiance(worldPos, 0.0, g_globalConstants.m_cameraPosition,
+														   g_globalConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags, noise);
 
 
 		color += irradiance * kPi; // Not sure why the multiplication with Pi but it looks more correct
 		color += irradiance * kPi; // Not sure why the multiplication with Pi but it looks more correct
 	}
 	}