Browse Source

Add blue noise in SSR

Panagiotis Christopoulos Charitos 5 years ago
parent
commit
cb577e27b9

+ 1 - 0
.gitignore

@@ -14,5 +14,6 @@
 !*.anki*
 !*.blend
 !*.lua
+!*.png
 !CMakeLists.txt
 build*/*

BIN
engine_data/BlueNoiseRgb816x16.png


+ 21 - 14
shaders/Ssr.ankiprog

@@ -21,20 +21,23 @@
 const UVec2 WORKGROUP_SIZE = UVec2(16, 16);
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
 
-layout(set = 0, binding = 0) uniform sampler u_trilinearClampSampler;
-layout(set = 0, binding = 1) uniform sampler u_nearestNearestClampSampler;
-layout(set = 0, binding = 2) uniform texture2D u_gbufferRt1;
-layout(set = 0, binding = 3) uniform texture2D u_gbufferRt2;
-layout(set = 0, binding = 4) uniform texture2D u_depthRt;
-layout(set = 0, binding = 5) uniform texture2D u_lightBufferRt;
+layout(set = 0, binding = 0, rgba16f) uniform image2D out_img;
 
-layout(set = 0, binding = 6, rgba16f) uniform image2D out_img;
-
-layout(set = 0, binding = 7, row_major) uniform u_
+layout(set = 0, binding = 1, row_major) uniform u_
 {
 	SsrUniforms u_unis;
 };
 
+layout(set = 0, binding = 2) uniform sampler u_trilinearClampSampler;
+layout(set = 0, binding = 3) uniform texture2D u_gbufferRt1;
+layout(set = 0, binding = 4) uniform texture2D u_gbufferRt2;
+layout(set = 0, binding = 5) uniform texture2D u_depthRt;
+layout(set = 0, binding = 6) uniform texture2D u_lightBufferRt;
+
+layout(set = 0, binding = 7) uniform sampler u_trilinearRepeatSampler;
+layout(set = 0, binding = 8) uniform texture2D u_noiseTex;
+const Vec2 NOISE_TEX_SIZE = Vec2(16.0);
+
 void main()
 {
 	// Compute a global invocation ID that takes the checkerboard pattern into account
@@ -71,25 +74,29 @@ void main()
 	const Vec3 reflVec = reflect(viewDir, viewNormal);
 
 	// Rand idx
-	U32 randIdx = (fixedInvocationId.x & 1) * 2 + (fixedInvocationId.y & 1);
-	randIdx = (randIdx + u_unis.m_frameCount & 3) & 3;
+	const Vec2 noiseUv = Vec2(u_unis.m_framebufferSize) / NOISE_TEX_SIZE * uv;
+	const Vec2 noiseShift = 1.0 / NOISE_TEX_SIZE * (u_unis.m_frameCount % 4u);
+	const F32 noise = textureLod(u_noiseTex, u_trilinearRepeatSampler, noiseUv + noiseShift, 0.0).r;
 
 	// Do the heavy work
 	Vec3 hitPoint;
 	F32 hitAttenuation;
 	const U32 lod = 1;
+	const U32 step = 16u;
+	const F32 stepf = step;
+	const F32 minStepf = 4.0;
 	raymarchGroundTruth(viewPos,
 		reflVec,
 		uv,
 		depth,
 		u_unis.m_projMat,
-		randIdx,
 		u_unis.m_maxSteps,
 		u_depthRt,
-		u_nearestNearestClampSampler,
+		u_trilinearClampSampler,
 		F32(lod),
 		u_unis.m_depthBufferSize >> lod,
-		16u,
+		step,
+		U32((stepf - minStepf) * noise + minStepf),
 		hitPoint,
 		hitAttenuation);
 

+ 19 - 15
src/anki/renderer/Ssr.cpp

@@ -36,6 +36,8 @@ Error Ssr::initInternal(const ConfigSet& cfg)
 	ANKI_R_LOGI("Initializing SSR pass (%ux%u)", width, height);
 	m_maxSteps = cfg.getNumberU32("r_ssrMaxSteps");
 
+	ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseRgb816x16.png", m_noiseTex));
+
 	// Create RTs
 	TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(width,
 		height,
@@ -94,23 +96,10 @@ void Ssr::run(RenderPassWorkContext& rgraphCtx)
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	cmdb->bindShaderProgram(m_grProg[m_r->getFrameCount() & 1u]);
 
-	// Bind all
-	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
-	cmdb->bindSampler(0, 1, m_r->getSamplers().m_nearestNearestClamp);
-
-	rgraphCtx.bindColorTexture(0, 2, m_r->getGBuffer().getColorRt(1));
-	rgraphCtx.bindColorTexture(0, 3, m_r->getGBuffer().getColorRt(2));
-
-	TextureSubresourceInfo hizSubresource;
-	hizSubresource.m_mipmapCount = m_r->getDepthDownscale().getMipmapCount();
-	rgraphCtx.bindTexture(0, 4, m_r->getDepthDownscale().getHiZRt(), hizSubresource);
-
-	rgraphCtx.bindColorTexture(0, 5, m_r->getDownscaleBlur().getRt());
-
-	rgraphCtx.bindImage(0, 6, m_runCtx.m_rt, TextureSubresourceInfo());
+	rgraphCtx.bindImage(0, 0, m_runCtx.m_rt, TextureSubresourceInfo());
 
 	// Bind uniforms
-	SsrUniforms* unis = allocateAndBindUniforms<SsrUniforms*>(sizeof(SsrUniforms), cmdb, 0, 7);
+	SsrUniforms* unis = allocateAndBindUniforms<SsrUniforms*>(sizeof(SsrUniforms), cmdb, 0, 1);
 	unis->m_depthBufferSize = UVec2(m_r->getWidth(), m_r->getHeight()) >> 2u;
 	unis->m_framebufferSize = UVec2(m_r->getWidth(), m_r->getHeight());
 	unis->m_frameCount = m_r->getFrameCount() & MAX_U32;
@@ -123,6 +112,21 @@ void Ssr::run(RenderPassWorkContext& rgraphCtx)
 	unis->m_invProjMat = ctx.m_matrices.m_projectionJitter.getInverse();
 	unis->m_normalMat = Mat3x4(ctx.m_matrices.m_view.getRotationPart());
 
+	// Bind all
+	cmdb->bindSampler(0, 2, m_r->getSamplers().m_trilinearClamp);
+
+	rgraphCtx.bindColorTexture(0, 3, m_r->getGBuffer().getColorRt(1));
+	rgraphCtx.bindColorTexture(0, 4, m_r->getGBuffer().getColorRt(2));
+
+	TextureSubresourceInfo hizSubresource;
+	hizSubresource.m_mipmapCount = m_r->getDepthDownscale().getMipmapCount();
+	rgraphCtx.bindTexture(0, 5, m_r->getDepthDownscale().getHiZRt(), hizSubresource);
+
+	rgraphCtx.bindColorTexture(0, 6, m_r->getDownscaleBlur().getRt());
+
+	cmdb->bindSampler(0, 7, m_r->getSamplers().m_trilinearRepeat);
+	cmdb->bindTexture(0, 8, m_noiseTex->getGrTextureView(), TextureUsageBit::SAMPLED_ALL);
+
 	// Dispatch
 	dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], m_r->getWidth() / 2, m_r->getHeight());
 }

+ 1 - 0
src/anki/renderer/Ssr.h

@@ -39,6 +39,7 @@ private:
 	Array<ShaderProgramPtr, 2> m_grProg;
 
 	TexturePtr m_rt;
+	TextureResourcePtr m_noiseTex;
 
 	Array<U32, 2> m_workgroupSize = {};
 	U32 m_maxSteps = 32;

+ 5 - 0
src/anki/resource/ImageLoader.cpp

@@ -178,6 +178,11 @@ public:
 	{
 		return m_rfile->seek(offset, origin);
 	}
+
+	PtrSize getSize() const final
+	{
+		return m_rfile->getSize();
+	}
 };
 
 class ImageLoader::SystemFile : public FileInterface

+ 1 - 1
tests/util/ThreadHive.cpp

@@ -60,7 +60,7 @@ static void taskToWait(void* arg, U32 threadId, ThreadHive& hive, ThreadHiveSema
 
 ANKI_TEST(Util, ThreadHive)
 {
-	const U32 threadCount = 4;
+	const U32 threadCount = 32;
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
 	ThreadHive hive(threadCount, alloc);