Browse Source

Add roughness cutoff in SSR

Panagiotis Christopoulos Charitos 3 years ago
parent
commit
272bb1d413

+ 2 - 0
AnKi/Renderer/ConfigVars.defs.h

@@ -31,6 +31,8 @@ ANKI_CONFIG_VAR_U32(RSsrFirstStepPixels, 32, 1, 256, "The 1st step in ray marchi
 ANKI_CONFIG_VAR_U32(RSsrDepthLod, 2, 0, 1000, "Texture LOD of the depth texture that will be raymarched")
 ANKI_CONFIG_VAR_U32(RSsrMaxSteps, 64, 1, 256, "Max SSR raymarching steps")
 ANKI_CONFIG_VAR_BOOL(RSsrStochastic, false, "Stochastic reflections")
+ANKI_CONFIG_VAR_F32(RSsrRoughnessCutoff, (ANKI_PLATFORM_MOBILE) ? 0.7f : 0.9f, 0.0f, 1.0f,
+					"Materials with roughness higher that this value will fallback to probe reflections")
 
 // GI probes
 ANKI_CONFIG_VAR_U32(RIndirectDiffuseProbeTileResolution, (ANKI_PLATFORM_MOBILE) ? 16 : 32, 8, 32, "GI tile resolution")

+ 1 - 0
AnKi/Renderer/IndirectSpecular.cpp

@@ -126,6 +126,7 @@ void IndirectSpecular::run(const RenderingContext& ctx, RenderPassWorkContext& r
 	unis->m_projMat = ctx.m_matrices.m_projectionJitter;
 	unis->m_invProjMat = ctx.m_matrices.m_projectionJitter.getInverse();
 	unis->m_normalMat = Mat3x4(Vec3(0.0f), ctx.m_matrices.m_view.getRotationPart());
+	unis->m_roughnessCutoff = getConfig().getRSsrRoughnessCutoff();
 
 	// Bind all
 	cmdb->bindSampler(0, 1, m_r->getSamplers().m_trilinearClamp);

+ 2 - 1
AnKi/Shaders/Include/MiscRendererTypes.h

@@ -116,7 +116,8 @@ struct SsrUniforms
 	U32 m_maxSteps;
 	U32 m_lightBufferMipCount;
 
-	UVec3 m_padding0;
+	UVec2 m_padding0;
+	F32 m_roughnessCutoff;
 	U32 m_firstStepPixels;
 
 	Mat4 m_prevViewProjMatMulInvViewProjMat;

+ 19 - 7
AnKi/Shaders/IndirectSpecular.glsl

@@ -80,16 +80,28 @@ void main()
 	const Vec3 reflDir = reflect(-viewDir, viewNormal);
 #endif
 
+	// Is rough enough to deserve SSR?
+	const F32 ssrFactor = saturate(1.0f - pow(roughness / u_unis.m_roughnessCutoff, 16.0f));
+
 	// Do the heavy work
 	Vec3 hitPoint;
 	F32 hitAttenuation;
-	const U32 lod = 8u; // Use the max LOD for ray marching
-	const U32 step = u_unis.m_firstStepPixels;
-	const F32 stepf = F32(step);
-	const F32 minStepf = stepf / 4.0;
-	raymarchGroundTruth(viewPos, reflDir, uv, depth, u_unis.m_projMat, u_unis.m_maxSteps, u_depthRt,
-						u_trilinearClampSampler, F32(lod), u_unis.m_depthBufferSize, step,
-						U32((stepf - minStepf) * noise.x + minStepf), hitPoint, hitAttenuation);
+	if(ssrFactor > EPSILON)
+	{
+		const U32 lod = 8u; // Use the max LOD for ray marching
+		const U32 step = u_unis.m_firstStepPixels;
+		const F32 stepf = F32(step);
+		const F32 minStepf = stepf / 4.0;
+		raymarchGroundTruth(viewPos, reflDir, uv, depth, u_unis.m_projMat, u_unis.m_maxSteps, u_depthRt,
+							u_trilinearClampSampler, F32(lod), u_unis.m_depthBufferSize, step,
+							U32((stepf - minStepf) * noise.x + minStepf), hitPoint, hitAttenuation);
+
+		hitAttenuation *= ssrFactor;
+	}
+	else
+	{
+		hitAttenuation = 0.0f;
+	}
 
 #if EXTRA_REJECTION
 	// Reject backfacing