Browse Source

Add the GI clipmaps in reflections

Panagiotis Christopoulos Charitos 6 months ago
parent
commit
794bf8576b

+ 4 - 1
AnKi/Renderer/Reflections.cpp

@@ -30,7 +30,8 @@ Error Reflections::init()
 	const Bool bRtReflections = GrManager::getSingleton().getDeviceCapabilities().m_rayTracingEnabled && g_rtReflectionsCVar;
 	const Bool bRtReflections = GrManager::getSingleton().getDeviceCapabilities().m_rayTracingEnabled && g_rtReflectionsCVar;
 	const Bool bSsrSamplesGBuffer = bRtReflections;
 	const Bool bSsrSamplesGBuffer = bRtReflections;
 
 
-	std::initializer_list<SubMutation> mutation = {{"SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer}};
+	std::initializer_list<SubMutation> mutation = {{"SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer},
+												   {"INDIRECT_DIFFUSE_CLIPMAPS", isIndirectDiffuseClipmapsEnabled()}};
 
 
 	// Ray gen and miss
 	// Ray gen and miss
 	if(bRtReflections)
 	if(bRtReflections)
@@ -40,6 +41,7 @@ Error Reflections::init()
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_mainProg);
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_mainProg);
 		variantInitInfo.requestTechniqueAndTypes(ShaderTypeBit::kRayGen, "RtMaterialFetch");
 		variantInitInfo.requestTechniqueAndTypes(ShaderTypeBit::kRayGen, "RtMaterialFetch");
 		variantInitInfo.addMutation("SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer);
 		variantInitInfo.addMutation("SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer);
+		variantInitInfo.addMutation("INDIRECT_DIFFUSE_CLIPMAPS", isIndirectDiffuseClipmapsEnabled());
 		const ShaderProgramResourceVariant* variant;
 		const ShaderProgramResourceVariant* variant;
 		m_mainProg->getOrCreateVariant(variantInitInfo, variant);
 		m_mainProg->getOrCreateVariant(variantInitInfo, variant);
 		m_libraryGrProg.reset(&variant->getProgram());
 		m_libraryGrProg.reset(&variant->getProgram());
@@ -226,6 +228,7 @@ void Reflections::populateRenderGraph(RenderingContext& ctx)
 
 
 			cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
 			cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
 			cmdb.bindSampler(1, 0, getRenderer().getSamplers().m_trilinearClampShadow.get());
 			cmdb.bindSampler(1, 0, getRenderer().getSamplers().m_trilinearClampShadow.get());
+			cmdb.bindSampler(2, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
 
 
 			rgraphCtx.bindSrv(0, 0, getGBuffer().getColorRt(0));
 			rgraphCtx.bindSrv(0, 0, getGBuffer().getColorRt(0));
 			rgraphCtx.bindSrv(1, 0, getGBuffer().getColorRt(1));
 			rgraphCtx.bindSrv(1, 0, getGBuffer().getColorRt(1));

+ 3 - 3
AnKi/Shaders/IndirectDiffuseClipmaps.ankiprog

@@ -172,7 +172,7 @@ ANKI_FAST_CONSTANTS(Consts, g_consts)
 		rayOrigin = biasedWorldPos;
 		rayOrigin = biasedWorldPos;
 		rayDir2 = worldNormal;
 		rayDir2 = worldNormal;
 	}
 	}
-	const SampleClipmapFlag flags = kSampleClipmapFlagFullQuality & ~(kSampleClipmapFlagBiasSamplePointTowardsCamera);
+	const SampleClipmapFlag flags = kSampleClipmapFlagFullQuality & kSampleClipmapFlagBiasSamplePointSurfaceNormal;
 	const Vec3 irradiance =
 	const Vec3 irradiance =
 		sampleClipmapIrradiance(rayOrigin, rayDir2, g_globalRendererConstants.m_cameraPosition, g_globalRendererConstants.m_indirectDiffuseClipmaps,
 		sampleClipmapIrradiance(rayOrigin, rayDir2, g_globalRendererConstants.m_cameraPosition, g_globalRendererConstants.m_indirectDiffuseClipmaps,
 								g_linearAnyRepeatSampler, flags, randFactors.x);
 								g_linearAnyRepeatSampler, flags, randFactors.x);
@@ -581,13 +581,13 @@ SamplerState g_linearAnyRepeatSampler : register(s0);
 	Vec3 irradiance;
 	Vec3 irradiance;
 	if(method == 0)
 	if(method == 0)
 	{
 	{
-		const SampleClipmapFlag flags = kSampleClipmapFlagFullQuality;
+		const SampleClipmapFlag flags = kSampleClipmapFlagFullQuality | kSampleClipmapFlagBiasSamplePointTowardsCamera;
 		irradiance = sampleClipmapIrradiance(worldPos, normal, g_globalRendererConstants.m_cameraPosition,
 		irradiance = sampleClipmapIrradiance(worldPos, normal, g_globalRendererConstants.m_cameraPosition,
 											 g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags, noise);
 											 g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags, noise);
 	}
 	}
 	else
 	else
 	{
 	{
-		const SampleClipmapFlag flags = kSampleClipmapFlagFullQuality;
+		const SampleClipmapFlag flags = kSampleClipmapFlagFullQuality | kSampleClipmapFlagBiasSamplePointTowardsCamera;
 		irradiance = sampleClipmapAvgIrradiance(worldPos, normal, g_globalRendererConstants.m_cameraPosition,
 		irradiance = sampleClipmapAvgIrradiance(worldPos, normal, g_globalRendererConstants.m_cameraPosition,
 												g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags, noise);
 												g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags, noise);
 	}
 	}

+ 18 - 3
AnKi/Shaders/IndirectDiffuseClipmaps.hlsl

@@ -19,7 +19,8 @@ enum SampleClipmapFlag : U32
 	kSampleClipmapFlagBackfacingProbeRejection = 1 << 5,
 	kSampleClipmapFlagBackfacingProbeRejection = 1 << 5,
 	kSampleClipmapFlagUsePreviousFrame = 1 << 6,
 	kSampleClipmapFlagUsePreviousFrame = 1 << 6,
 
 
-	kSampleClipmapFlagFullQuality = (1 << 5) - 1,
+	kSampleClipmapFlagFullQuality = kSampleClipmapFlagAccurateClipmapSelection | kSampleClipmapFlagInvalidProbeRejection
+									| kSampleClipmapFlagChebyshevOcclusion | kSampleClipmapFlagBackfacingProbeRejection,
 	kSampleClipmapFlagNone = 0
 	kSampleClipmapFlagNone = 0
 };
 };
 
 
@@ -318,7 +319,7 @@ Vec3 sampleClipmapCommon(SampleClipmapsArgs args, SamplerState linearAnyRepeatSa
 }
 }
 
 
 Vec3 sampleClipmapIrradiance(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts,
 Vec3 sampleClipmapIrradiance(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts,
-							 SamplerState linearAnyRepeatSampler, SampleClipmapFlag flags = kSampleClipmapFlagFullQuality, F32 randFactor = 0.5)
+							 SamplerState linearAnyRepeatSampler, SampleClipmapFlag flags, F32 randFactor = 0.5)
 {
 {
 	SampleClipmapsArgs args;
 	SampleClipmapsArgs args;
 	args.m_primaryVolume = 0;
 	args.m_primaryVolume = 0;
@@ -331,6 +332,20 @@ Vec3 sampleClipmapIrradiance(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, Indi
 	return sampleClipmapCommon(args, linearAnyRepeatSampler, consts);
 	return sampleClipmapCommon(args, linearAnyRepeatSampler, consts);
 }
 }
 
 
+Vec3 sampleClipmapRadiance(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts, SamplerState linearAnyRepeatSampler,
+						   SampleClipmapFlag flags, F32 randFactor = 0.5)
+{
+	SampleClipmapsArgs args;
+	args.m_primaryVolume = 1;
+	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);
+}
+
 Vec3 sampleClipmapAvgIrradianceCheap(Vec3 samplePoint, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts, F32 randFactor,
 Vec3 sampleClipmapAvgIrradianceCheap(Vec3 samplePoint, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts, F32 randFactor,
 									 SamplerState linearAnyRepeatSampler, SampleClipmapFlag flags)
 									 SamplerState linearAnyRepeatSampler, SampleClipmapFlag flags)
 {
 {
@@ -357,7 +372,7 @@ Vec3 sampleClipmapAvgIrradianceCheap(Vec3 samplePoint, Vec3 cameraPos, IndirectD
 }
 }
 
 
 Vec3 sampleClipmapAvgIrradiance(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts,
 Vec3 sampleClipmapAvgIrradiance(Vec3 samplePoint, Vec3 normal, Vec3 cameraPos, IndirectDiffuseClipmapConstants consts,
-								SamplerState linearAnyRepeatSampler, SampleClipmapFlag flags = kSampleClipmapFlagFullQuality, F32 randFactor = 0.5)
+								SamplerState linearAnyRepeatSampler, SampleClipmapFlag flags, F32 randFactor = 0.5)
 {
 {
 	const SampleClipmapFlag requireManualTrilinearFiltering =
 	const SampleClipmapFlag requireManualTrilinearFiltering =
 		kSampleClipmapFlagInvalidProbeRejection | kSampleClipmapFlagBackfacingProbeRejection | kSampleClipmapFlagChebyshevOcclusion;
 		kSampleClipmapFlagInvalidProbeRejection | kSampleClipmapFlagBackfacingProbeRejection | kSampleClipmapFlagChebyshevOcclusion;

+ 41 - 6
AnKi/Shaders/Reflections.ankiprog

@@ -6,11 +6,12 @@
 #pragma anki 16bit
 #pragma anki 16bit
 
 
 #pragma anki mutator SSR_SAMPLE_GBUFFER 0 1
 #pragma anki mutator SSR_SAMPLE_GBUFFER 0 1
+#pragma anki mutator INDIRECT_DIFFUSE_CLIPMAPS 0 1
 
 
 #pragma anki technique Classification comp mutators
 #pragma anki technique Classification comp mutators
 #pragma anki technique Ssr comp
 #pragma anki technique Ssr comp
 #pragma anki technique ReflectionProbeFallback comp mutators
 #pragma anki technique ReflectionProbeFallback comp mutators
-#pragma anki technique RtMaterialFetch rgen mutators
+#pragma anki technique RtMaterialFetch rgen mutators INDIRECT_DIFFUSE_CLIPMAPS
 #pragma anki technique SpatialDenoise comp mutators
 #pragma anki technique SpatialDenoise comp mutators
 #pragma anki technique TemporalDenoise comp mutators
 #pragma anki technique TemporalDenoise comp mutators
 #pragma anki technique BilateralDenoiseVertical comp mutators
 #pragma anki technique BilateralDenoiseVertical comp mutators
@@ -24,6 +25,7 @@
 #include <AnKi/Shaders/BilateralFilter.hlsl>
 #include <AnKi/Shaders/BilateralFilter.hlsl>
 #include <AnKi/Shaders/SsRaymarching.hlsl>
 #include <AnKi/Shaders/SsRaymarching.hlsl>
 #include <AnKi/Shaders/ClusteredShadingFunctions.hlsl>
 #include <AnKi/Shaders/ClusteredShadingFunctions.hlsl>
+#include <AnKi/Shaders/IndirectDiffuseClipmaps.hlsl>
 
 
 // Config & debug
 // Config & debug
 constexpr F32 kSpatialUpscalingPcfTexelOffset = 8.0;
 constexpr F32 kSpatialUpscalingPcfTexelOffset = 8.0;
@@ -179,6 +181,7 @@ groupshared U32 g_allSky;
 #if NOT_ZERO(ANKI_TECHNIQUE_Ssr)
 #if NOT_ZERO(ANKI_TECHNIQUE_Ssr)
 SamplerState g_trilinearClampSampler : register(s0);
 SamplerState g_trilinearClampSampler : register(s0);
 SamplerComparisonState g_shadowSampler : register(s1);
 SamplerComparisonState g_shadowSampler : register(s1);
+SamplerState g_linearAnyRepeatSampler : register(s2);
 
 
 Texture2D<Vec4> g_gbufferRt0 : register(t0);
 Texture2D<Vec4> g_gbufferRt0 : register(t0);
 Texture2D<Vec4> g_gbufferRt1 : register(t1);
 Texture2D<Vec4> g_gbufferRt1 : register(t1);
@@ -212,10 +215,18 @@ Vec3 doLightShading(Vec3 worldPos, Vec3 viewPos, UVec2 coord, F32 depth)
 	unpackGBufferNoVelocity<F32>(g_gbufferRt0[coord], g_gbufferRt1[coord], g_gbufferRt2[coord], gbuffer);
 	unpackGBufferNoVelocity<F32>(g_gbufferRt0[coord], g_gbufferRt1[coord], g_gbufferRt2[coord], gbuffer);
 
 
 	Vec3 outColor = gbuffer.m_emission;
 	Vec3 outColor = gbuffer.m_emission;
-	Cluster cluster = getClusterFragCoord(g_clusters, g_globalRendererConstants, Vec3(coord.xy + 0.5, depth));
 
 
+#	if INDIRECT_DIFFUSE_CLIPMAPS
+	const SampleClipmapFlag flags =
+		kSampleClipmapFlagFullQuality & ~(kSampleClipmapFlagChebyshevOcclusion | kSampleClipmapFlagAccurateClipmapSelection);
+	const Vec3 irradiance = sampleClipmapIrradiance(worldPos, gbuffer.m_normal, g_globalRendererConstants.m_cameraPosition,
+													g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags);
+	outColor += irradiance * gbuffer.m_diffuse;
+#	else
 	// GI
 	// GI
+	const Cluster cluster = getClusterFragCoord(g_clusters, g_globalRendererConstants, Vec3(coord.xy + 0.5, depth));
 	outColor += sampleGiProbes<F32>(cluster, g_giProbes, gbuffer.m_normal, worldPos.xyz, g_trilinearClampSampler) * gbuffer.m_diffuse;
 	outColor += sampleGiProbes<F32>(cluster, g_giProbes, gbuffer.m_normal, worldPos.xyz, g_trilinearClampSampler) * gbuffer.m_diffuse;
+#	endif
 
 
 	// Dir light
 	// Dir light
 	const DirectionalLight dirLight = g_globalRendererConstants.m_directionalLight;
 	const DirectionalLight dirLight = g_globalRendererConstants.m_directionalLight;
@@ -370,9 +381,15 @@ void bestCandidateToHallucinate(IVec2 svGroupThreadId, IVec2 offset, F32 depth,
 
 
 		const Vec3 reflDir = reflect(normalize(worldPos.xyz - g_globalRendererConstants.m_cameraPosition), worldNormal);
 		const Vec3 reflDir = reflect(normalize(worldPos.xyz - g_globalRendererConstants.m_cameraPosition), worldNormal);
 
 
+#	if INDIRECT_DIFFUSE_CLIPMAPS
+		const SampleClipmapFlag flags =
+			kSampleClipmapFlagFullQuality & ~(kSampleClipmapFlagChebyshevOcclusion | kSampleClipmapFlagAccurateClipmapSelection);
+		const Vec3 col = sampleClipmapRadiance(worldPos, reflDir, g_globalRendererConstants.m_cameraPosition,
+											   g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags);
+#	else
 		Cluster cluster = getClusterFragCoord(g_clusters, g_globalRendererConstants, Vec3(logicalCoord.xy + 0.5, depth));
 		Cluster cluster = getClusterFragCoord(g_clusters, g_globalRendererConstants, Vec3(logicalCoord.xy + 0.5, depth));
-
 		const Vec3 col = sampleGiProbes<F32>(cluster, g_giProbes, reflDir, worldPos.xyz, g_trilinearClampSampler);
 		const Vec3 col = sampleGiProbes<F32>(cluster, g_giProbes, reflDir, worldPos.xyz, g_trilinearClampSampler);
+#	endif
 
 
 		Vec3 worldHitPos = worldPos + reflDir * 1.0;
 		Vec3 worldHitPos = worldPos + reflDir * 1.0;
 		worldHitPos -= g_globalRendererConstants.m_cameraPosition;
 		worldHitPos -= g_globalRendererConstants.m_cameraPosition;
@@ -418,7 +435,14 @@ void bestCandidateToHallucinate(IVec2 svGroupThreadId, IVec2 offset, F32 depth,
 		Vec4 worldPos = mul(g_globalRendererConstants.m_matrices.m_invertedViewProjection, Vec4(uvToNdc(uv), depth, 1.0));
 		Vec4 worldPos = mul(g_globalRendererConstants.m_matrices.m_invertedViewProjection, Vec4(uvToNdc(uv), depth, 1.0));
 		worldPos.xyz /= worldPos.w;
 		worldPos.xyz /= worldPos.w;
 
 
+#	if INDIRECT_DIFFUSE_CLIPMAPS
+		const SampleClipmapFlag flags =
+			kSampleClipmapFlagFullQuality & ~(kSampleClipmapFlagChebyshevOcclusion | kSampleClipmapFlagAccurateClipmapSelection);
+		outColor = sampleClipmapRadiance(worldPos, woldReflDir, g_globalRendererConstants.m_cameraPosition,
+										 g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags);
+#	else
 		outColor = sampleGiProbes<F32>(cluster, g_giProbes, woldReflDir, worldPos.xyz, g_trilinearClampSampler);
 		outColor = sampleGiProbes<F32>(cluster, g_giProbes, woldReflDir, worldPos.xyz, g_trilinearClampSampler);
+#	endif
 
 
 		viewHitPoint = viewPos + viewReflDir * 1.0;
 		viewHitPoint = viewPos + viewReflDir * 1.0;
 		pdf = kPdfForVeryRough;
 		pdf = kPdfForVeryRough;
@@ -688,10 +712,21 @@ vector<T, 3> getDiffuseIndirect(Vec3 worldPos, Vec3 worldNormal)
 	// Do simple light shading
 	// Do simple light shading
 	HVec3 radiance = directLighting(gbuffer, hitPos, hasHitSky, kTryShadowmapFirst, g_consts.m_maxRayT);
 	HVec3 radiance = directLighting(gbuffer, hitPos, hasHitSky, kTryShadowmapFirst, g_consts.m_maxRayT);
 
 
-	if(!hasHitSky && g_consts.m_giProbeCount > 0)
+	if(!hasHitSky)
 	{
 	{
-		const HVec3 indirectDiffuse = getDiffuseIndirect<F16>(hitPos, gbuffer.m_worldNormal);
-		radiance += gbuffer.m_diffuse * indirectDiffuse;
+#	if INDIRECT_DIFFUSE_CLIPMAPS
+		const SampleClipmapFlag flags =
+			kSampleClipmapFlagFullQuality & ~(kSampleClipmapFlagChebyshevOcclusion | kSampleClipmapFlagAccurateClipmapSelection);
+		const HVec3 irradiance = sampleClipmapIrradiance(hitPos, gbuffer.m_worldNormal, g_globalRendererConstants.m_cameraPosition,
+														 g_globalRendererConstants.m_indirectDiffuseClipmaps, g_linearAnyRepeatSampler, flags);
+		radiance += gbuffer.m_diffuse * irradiance;
+#	else
+		if(g_consts.m_giProbeCount > 0)
+		{
+			const HVec3 indirectDiffuse = getDiffuseIndirect<F16>(hitPos, gbuffer.m_worldNormal);
+			radiance += gbuffer.m_diffuse * indirectDiffuse;
+		}
+#	endif
 	}
 	}
 
 
 	g_colorAndPdfTex[realCoord] = Vec4(radiance, max(0.0, pdf));
 	g_colorAndPdfTex[realCoord] = Vec4(radiance, max(0.0, pdf));