Browse Source

Feed the jittered HDR light shading to VRS SRI generation. Also fix the seam in the skybox

Panagiotis Christopoulos Charitos 3 years ago
parent
commit
d1752d16de

+ 1 - 1
AnKi/Renderer/ConfigVars.defs.h

@@ -30,7 +30,7 @@ ANKI_CONFIG_VAR_BOOL(RDbgEnabled, false, "Enable or not debugging")
 // VRS
 ANKI_CONFIG_VAR_BOOL(RVrs, true, "Enable VRS in multiple passes")
 ANKI_CONFIG_VAR_BOOL(RGBufferVrs, false, "Enable VRS in GBuffer")
-ANKI_CONFIG_VAR_F32(RVrsThreshold, 0.05f, 0.0f, 1.0f, "Threshold under which a lower shading rate will be applied")
+ANKI_CONFIG_VAR_F32(RVrsThreshold, 0.1f, 0.0f, 1.0f, "Threshold under which a lower shading rate will be applied")
 ANKI_CONFIG_VAR_BOOL(RVrsLimitTo2x2, false, "If true the max rate will be 2x2")
 
 // SSR

+ 15 - 0
AnKi/Renderer/LightShading.cpp

@@ -24,6 +24,7 @@ namespace anki {
 LightShading::LightShading(Renderer* r)
 	: RendererObject(r)
 {
+	registerDebugRenderTarget("LightShading");
 }
 
 LightShading::~LightShading()
@@ -97,6 +98,12 @@ Error LightShading::initLightShading()
 
 	m_lightShading.m_fbDescr.bake();
 
+	// Debug visualization
+	ANKI_CHECK(
+		getResourceManager().loadResource("ShaderBinaries/VisualizeHdrRenderTarget.ankiprogbin", m_visualizeRtProg));
+	m_visualizeRtProg->getOrCreateVariant(variant);
+	m_visualizeRtGrProg = variant->getProgram();
+
 	return Error::NONE;
 }
 
@@ -402,4 +409,12 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	m_r->getForwardShading().setDependencies(ctx, pass);
 }
 
+void LightShading::getDebugRenderTarget([[maybe_unused]] CString rtName, RenderTargetHandle& handle,
+										ShaderProgramPtr& optionalShaderProgram) const
+{
+	ANKI_ASSERT(rtName == "LightShading");
+	handle = m_runCtx.m_rt;
+	optionalShaderProgram = m_visualizeRtGrProg;
+}
+
 } // end namespace anki

+ 6 - 0
AnKi/Renderer/LightShading.h

@@ -69,12 +69,18 @@ private:
 		RenderTargetHandle m_rt;
 	} m_runCtx; ///< Run context.
 
+	ShaderProgramResourcePtr m_visualizeRtProg;
+	ShaderProgramPtr m_visualizeRtGrProg;
+
 	Error initLightShading();
 	Error initSkybox();
 	Error initApplyFog();
 	Error initApplyIndirect();
 
 	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
+
+	void getDebugRenderTarget(CString rtName, RenderTargetHandle& handle,
+							  ShaderProgramPtr& optionalShaderProgram) const override;
 };
 /// @}
 

+ 3 - 4
AnKi/Renderer/VrsSriGeneration.cpp

@@ -5,7 +5,7 @@
 
 #include <AnKi/Renderer/VrsSriGeneration.h>
 #include <AnKi/Renderer/Renderer.h>
-#include <AnKi/Renderer/TemporalAA.h>
+#include <AnKi/Renderer/LightShading.h>
 #include <AnKi/Core/ConfigSet.h>
 
 namespace anki {
@@ -149,15 +149,14 @@ void VrsSriGeneration::populateRenderGraph(RenderingContext& ctx)
 		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("VRS SRI generation");
 
 		pass.newDependency(RenderPassDependency(m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
-		pass.newDependency(
-			RenderPassDependency(m_r->getTemporalAA().getTonemappedRt(), TextureUsageBit::SAMPLED_COMPUTE));
+		pass.newDependency(RenderPassDependency(m_r->getLightShading().getRt(), TextureUsageBit::SAMPLED_COMPUTE));
 
 		pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 			CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
 			cmdb->bindShaderProgram(m_grProg);
 
-			rgraphCtx.bindColorTexture(0, 0, m_r->getTemporalAA().getTonemappedRt());
+			rgraphCtx.bindColorTexture(0, 0, m_r->getLightShading().getRt());
 			cmdb->bindSampler(0, 1, m_r->getSamplers().m_nearestNearestClamp);
 			rgraphCtx.bindImage(0, 2, m_runCtx.m_rt);
 			const Vec4 pc(1.0f / Vec2(m_r->getInternalResolution()), getConfig().getRVrsThreshold(), 0.0f);

+ 10 - 1
AnKi/Shaders/LightShadingSkybox.ankiprog

@@ -57,7 +57,16 @@ void main()
 	const Vec3 eyeToFrag = normalize(worldPos - u_cameraPos);
 
 	const Vec2 uv = equirectangularMapping(eyeToFrag);
-	out_color = texture(u_envMapTex, u_trilinearAnySampler, uv).rgb;
+
+	// When uv is close to the edge of the texture the other quads might be in the oposit coordinate. Then the
+	// derivatives will be huge causing the texture to use the highest mip and thus create a visible seam. To fix this
+	// find when the derivatives are large and do some manual work to fix it
+	const Vec2 dx = abs(dFdx(uv));
+	const F32 maxD = max(dx.x, dx.y);
+
+	const F32 bias = (maxD > 0.9) ? -100.0f : 0.0f;
+
+	out_color = texture(u_envMapTex, u_trilinearAnySampler, uv, bias).rgb;
 #endif
 }
 

+ 23 - 0
AnKi/Shaders/VisualizeHdrRenderTarget.ankiprog

@@ -0,0 +1,23 @@
+// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma anki start vert
+#include <AnKi/Shaders/QuadVert.glsl>
+#pragma anki end
+
+#pragma anki start frag
+#include <AnKi/Shaders/TonemappingFunctions.glsl>
+
+layout(set = 0, binding = 0) uniform texture2D u_inTex;
+layout(set = 0, binding = 1) uniform sampler u_nearestAnyClampSampler;
+
+layout(location = 0) in Vec2 in_uv;
+layout(location = 0) out Vec3 out_color;
+
+void main()
+{
+	out_color = invertibleTonemap(textureLod(u_inTex, u_nearestAnyClampSampler, in_uv, 0.0).rgb);
+}
+#pragma anki end

+ 14 - 9
AnKi/Shaders/VrsSriGenerationCompute.ankiprog

@@ -45,9 +45,14 @@ shared F32 s_averageLuma[SHARED_MEMORY_ENTRIES];
 shared Vec2 s_maxDerivative[SHARED_MEMORY_ENTRIES];
 #endif
 
+F32 computeLuma(Vec3 color)
+{
+	const F32 l = computeLuminance(color);
+	return l / (1.0f + l);
+}
+
 #define sampleLuma(offsetX, offsetY) \
-	computeLuminance( \
-		textureLodOffset(sampler2D(u_inputTex, u_nearestClampSampler), uv, 0.0, IVec2(offsetX, offsetY)).xyz)
+	computeLuma(textureLodOffset(sampler2D(u_inputTex, u_nearestClampSampler), uv, 0.0, IVec2(offsetX, offsetY)).xyz)
 
 void main()
 {
@@ -84,11 +89,11 @@ void main()
 	F32 averageLuma = (l0.x + l0.y + l0.z + l0.w) / 4.0;
 #else
 	// Get luminance.
-	//       l2.z
-	// l1.z  l1.w  l2.y
-	// l1.x  l1.y
-	// l0.z  l0.w  l2.x
-	// l0.x  l0.y
+	//             l2.z
+	// l2.y  l1.z  l1.w
+	//       l1.x  l1.y
+	//       l0.z  l0.w  l2.x
+	//       l0.x  l0.y
 	Vec4 l0;
 	l0.x = sampleLuma(0, 0);
 	l0.y = sampleLuma(1, 0);
@@ -103,12 +108,12 @@ void main()
 
 	Vec3 l2;
 	l2.x = sampleLuma(2, 1);
-	l2.y = sampleLuma(2, 3);
+	l2.y = sampleLuma(-1, 3);
 	l2.z = sampleLuma(1, 4);
 
 	// Calculate derivatives.
 	Vec4 a = Vec4(l0.y, l2.x, l1.y, l2.y);
-	Vec4 b = Vec4(l0.x, l0.w, l1.x, l1.w);
+	Vec4 b = Vec4(l0.x, l0.w, l1.x, l1.z);
 	const Vec4 dx = abs(a - b);
 
 	a = Vec4(l0.z, l0.w, l1.z, l2.z);

+ 2 - 3
Samples/Common/SampleApp.cpp

@@ -109,9 +109,8 @@ Error SampleApp::userMainLoop(Bool& quit, Second elapsedTime)
 
 	if(in.getKey(KeyCode::L) == 1)
 	{
-		renderer.setCurrentDebugRenderTarget((renderer.getCurrentDebugRenderTarget() == "MotionVectorsHistoryLength")
-												 ? ""
-												 : "MotionVectorsHistoryLength");
+		renderer.setCurrentDebugRenderTarget(
+			(renderer.getCurrentDebugRenderTarget() == "LightShading") ? "" : "LightShading");
 	}
 
 	if(in.getKey(KeyCode::H) == 1)

+ 30 - 2
Samples/PhysicsPlayground/Main.cpp

@@ -224,10 +224,38 @@ Error MyApp::userMainLoop(Bool& quit, [[maybe_unused]] Second elapsedTime)
 																									 : "RtShadows");
 	}
 
-	if(getInput().getKey(KeyCode::U) == 1)
+	if(getInput().getKey(KeyCode::P) == 1)
+	{
+		static U32 idx = 3;
+		++idx;
+		idx %= 4;
+		if(idx == 0)
+		{
+			renderer.setCurrentDebugRenderTarget("IndirectDiffuseVrsSri");
+		}
+		else if(idx == 1)
+		{
+			renderer.setCurrentDebugRenderTarget("VrsSriDownscaled");
+		}
+		else if(idx == 2)
+		{
+			renderer.setCurrentDebugRenderTarget("VrsSri");
+		}
+		else
+		{
+			renderer.setCurrentDebugRenderTarget("");
+		}
+	}
+
+	if(getInput().getKey(KeyCode::L) == 1)
 	{
 		renderer.setCurrentDebugRenderTarget(
-			(renderer.getCurrentDebugRenderTarget() == "GBufferNormals") ? "" : "GBufferNormals");
+			(renderer.getCurrentDebugRenderTarget() == "LightShading") ? "" : "LightShading");
+	}
+
+	if(getInput().getKey(KeyCode::J) == 1)
+	{
+		m_config.setRVrs(!m_config.getRVrs());
 	}
 
 	if(getInput().getKey(KeyCode::F1) == 1)