Przeglądaj źródła

Tweak SSAO. Need better filtering

Panagiotis Christopoulos Charitos 7 lat temu
rodzic
commit
0d34ab622a

+ 7 - 42
programs/GaussianBlur.ankiprog

@@ -6,7 +6,7 @@ http://www.anki3d.org/LICENSE
 -->
 -->
 <shaderProgram>
 <shaderProgram>
 	<mutators>
 	<mutators>
-		<mutator name="HORIZONTAL" values="0 1"/>
+		<mutator name="ORIENTATION" values="0 1 2"/> <!-- 0: VERTICAL, 1: HORIZONTAL, 2: BOX -->
 		<mutator name="KERNEL_SIZE" values="3 5 7 9 11 13 15"/>
 		<mutator name="KERNEL_SIZE" values="3 5 7 9 11 13 15"/>
 		<mutator name="COLOR_COMPONENTS" values="4 3 1"/>
 		<mutator name="COLOR_COMPONENTS" values="4 3 1"/>
 	</mutators>
 	</mutators>
@@ -24,50 +24,15 @@ http://www.anki3d.org/LICENSE
 			</inputs>
 			</inputs>
 
 
 			<source><![CDATA[
 			<source><![CDATA[
-#include "shaders/GaussianBlurCommon.glsl"
-
-layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_tex; ///< Input FAI
-
-layout(location = 0) in vec2 in_uv;
-
-// Determine color type
-#if COLOR_COMPONENTS == 4
-#	define COL_TYPE vec4
-#	define TEX_FETCH rgba
-#elif COLOR_COMPONENTS == 3
-#	define COL_TYPE vec3
-#	define TEX_FETCH rgb
-#elif COLOR_COMPONENTS == 1
-#	define COL_TYPE float
-#	define TEX_FETCH r
+#if ORIENTATION == 0
+#	define VERTICAL 1
+#elif ORIENTATION == 1
+#	define HORIZONTAL 1
 #else
 #else
-#	error See file
+#	define BOX 1
 #endif
 #endif
 
 
-// Output
-layout(location = 0) out COL_TYPE out_color;
-
-void main()
-{
-#if HORIZONTAL
-	const vec2 TEXEL_SIZE = vec2(1.0 / float(TEXTURE_SIZE.x), 0.0);
-#else
-	const vec2 TEXEL_SIZE = vec2(0.0, 1.0 / float(TEXTURE_SIZE.y));
-#endif
-	vec2 uv = in_uv;
-
-	out_color = texture(u_tex, uv).TEX_FETCH * WEIGHTS[0u];
-	vec2 texCoordOffset = 1.5 * TEXEL_SIZE;
-
-	for(uint i = 0u; i < STEP_COUNT; ++i)
-	{
-		COL_TYPE col =
-			texture(u_tex, uv + texCoordOffset).TEX_FETCH + texture(u_tex, uv - texCoordOffset).TEX_FETCH;
-		out_color += WEIGHTS[i + 1u] * col;
-
-		texCoordOffset += 2.0 * TEXEL_SIZE;
-	}
-}
+#include "shaders/GaussianBlur.glsl"
 			]]></source>
 			]]></source>
 		</shader>
 		</shader>
 	</shaders>
 	</shaders>

+ 35 - 0
programs/GaussianBlurCompute.ankiprog

@@ -0,0 +1,35 @@
+<!-- 
+Copyright (C) 2009-2018, Panagiotis Christopoulos Charitos and contributors.
+All rights reserved.
+Code licensed under the BSD License.
+http://www.anki3d.org/LICENSE
+-->
+<shaderProgram>
+	<mutators>
+		<mutator name="ORIENTATION" values="0 1 2"/> <!-- 0: VERTICAL, 1: HORIZONTAL, 2: BOX -->
+		<mutator name="KERNEL_SIZE" values="3 5 7 9 11 13 15"/>
+		<mutator name="COLOR_COMPONENTS" values="4 3 1"/>
+	</mutators>
+
+	<shaders>
+		<shader type="comp">
+			<inputs>
+				<input name="TEXTURE_SIZE" type="uvec2" const="1"/>
+                <input name="WORKGROUP_SIZE" type="uvec2" const="1"/>
+			</inputs>
+
+			<source><![CDATA[
+#if ORIENTATION == 0
+#	define VERTICAL 1
+#elif ORIENTATION == 1
+#	define HORIZONTAL 1
+#else
+#	define BOX 1
+#endif
+
+#include "shaders/GaussianBlur.glsl"
+			]]></source>
+		</shader>
+	</shaders>
+</shaderProgram>
+

+ 1 - 1
sandbox/Main.cpp

@@ -214,7 +214,7 @@ Error MyApp::userMainLoop(Bool& quit)
 		quit = true;
 		quit = true;
 	}
 	}
 
 
-	if(m_profile && getGlobalTimestamp() == 500)
+	if(m_profile && getGlobalTimestamp() == 1000)
 	{
 	{
 		quit = true;
 		quit = true;
 		return Error::NONE;
 		return Error::NONE;

+ 14 - 12
shaders/DepthAwareBlur.glsl

@@ -75,13 +75,6 @@ void sampleTex(vec2 uv, float refDepth, inout COL_TYPE col, inout float weight)
 
 
 void main()
 void main()
 {
 {
-	// Compute texel size
-#if defined(HORIZONTAL)
-	const vec2 TEXEL_SIZE = vec2(1.0 / float(TEXTURE_SIZE.x), 0.0);
-#elif defined(VERTICAL)
-	const vec2 TEXEL_SIZE = vec2(0.0, 1.0 / float(TEXTURE_SIZE.y));
-#endif
-
 	// Set UVs
 	// Set UVs
 #if USE_COMPUTE
 #if USE_COMPUTE
 	ANKI_BRANCH if(gl_GlobalInvocationID.x >= TEXTURE_SIZE.x || gl_GlobalInvocationID.y >= TEXTURE_SIZE.y)
 	ANKI_BRANCH if(gl_GlobalInvocationID.x >= TEXTURE_SIZE.x || gl_GlobalInvocationID.y >= TEXTURE_SIZE.y)
@@ -95,6 +88,8 @@ void main()
 	vec2 uv = in_uv;
 	vec2 uv = in_uv;
 #endif
 #endif
 
 
+	const vec2 TEXEL_SIZE = 1.0 / vec2(TEXTURE_SIZE);
+
 	// Sample
 	// Sample
 	COL_TYPE color = textureLod(u_inTex, uv, 0.0).TEX_FETCH;
 	COL_TYPE color = textureLod(u_inTex, uv, 0.0).TEX_FETCH;
 	float refDepth = readDepth(uv);
 	float refDepth = readDepth(uv);
@@ -103,19 +98,26 @@ void main()
 #if !defined(BOX)
 #if !defined(BOX)
 	// Do seperable
 	// Do seperable
 
 
-	vec2 texCoordOffset = 1.5 * TEXEL_SIZE;
+#	if defined(HORIZONTAL)
+#		define X_OR_Y x
+#	else
+#		define X_OR_Y y
+#	endif
+
+	vec2 uvOffset = vec2(0.0);
+	uvOffset.X_OR_Y = 1.5 * TEXEL_SIZE.X_OR_Y;
 
 
 	ANKI_UNROLL for(uint i = 0u; i < (SAMPLE_COUNT - 1u) / 2u; ++i)
 	ANKI_UNROLL for(uint i = 0u; i < (SAMPLE_COUNT - 1u) / 2u; ++i)
 	{
 	{
-		sampleTex(uv + texCoordOffset, refDepth, color, weight);
-		sampleTex(uv - texCoordOffset, refDepth, color, weight);
+		sampleTex(uv + uvOffset, refDepth, color, weight);
+		sampleTex(uv - uvOffset, refDepth, color, weight);
 
 
-		texCoordOffset += 2.0 * TEXEL_SIZE;
+		uvOffset.X_OR_Y += 2.0 * TEXEL_SIZE.X_OR_Y;
 	}
 	}
 #else
 #else
 	// Do box
 	// Do box
 
 
-	const vec2 OFFSET = 1.5 * (1.0 / vec2(TEXTURE_SIZE));
+	const vec2 OFFSET = 1.5 * TEXEL_SIZE;
 
 
 	sampleTex(uv + vec2(+OFFSET.x, +OFFSET.y), refDepth, color, weight);
 	sampleTex(uv + vec2(+OFFSET.x, +OFFSET.y), refDepth, color, weight);
 	sampleTex(uv + vec2(+OFFSET.x, -OFFSET.y), refDepth, color, weight);
 	sampleTex(uv + vec2(+OFFSET.x, -OFFSET.y), refDepth, color, weight);

+ 120 - 0
shaders/GaussianBlur.glsl

@@ -0,0 +1,120 @@
+// Copyright (C) 2009-2018, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+// Defines it needs:
+// HORIZONTAL | VERTICAL | BOX
+// COLOR_COMPONENTS
+// WORKGROUP_SIZE (only for compute)
+// TEXTURE_SIZE
+// KERNEL_SIZE (must be odd number)
+
+#ifndef ANKI_SHADERS_GAUSSIAN_BLUR_GLSL
+#define ANKI_SHADERS_GAUSSIAN_BLUR_GLSL
+
+#include "shaders/GaussianBlurCommon.glsl"
+
+#if defined(ANKI_COMPUTE_SHADER)
+#	define USE_COMPUTE 1
+#else
+#	define USE_COMPUTE 0
+#endif
+
+// Determine color type
+#if COLOR_COMPONENTS == 4
+#	define COL_TYPE vec4
+#	define TEX_FETCH rgba
+#	define TO_VEC4(x_) x_
+#elif COLOR_COMPONENTS == 3
+#	define COL_TYPE vec3
+#	define TEX_FETCH rgb
+#	define TO_VEC4(x_) vec4(x_, 0.0)
+#elif COLOR_COMPONENTS == 1
+#	define COL_TYPE float
+#	define TEX_FETCH r
+#	define TO_VEC4(x_) vec4(x_, 0.0, 0.0, 0.0)
+#else
+#	error See file
+#endif
+
+layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_tex; ///< Input texture
+
+#if USE_COMPUTE
+layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
+layout(ANKI_IMAGE_BINDING(0, 0)) writeonly uniform image2D u_outImg;
+#else
+layout(location = 0) in vec2 in_uv;
+layout(location = 0) out COL_TYPE out_color;
+#endif
+
+void main()
+{
+	// Set UVs
+#if USE_COMPUTE
+	ANKI_BRANCH if(gl_GlobalInvocationID.x >= TEXTURE_SIZE.x || gl_GlobalInvocationID.y >= TEXTURE_SIZE.y)
+	{
+		// Out of bounds
+		return;
+	}
+
+	vec2 uv = (vec2(gl_GlobalInvocationID.xy) + 0.5) / vec2(TEXTURE_SIZE);
+#else
+	vec2 uv = in_uv;
+#endif
+
+	const vec2 TEXEL_SIZE = 1.0 / vec2(TEXTURE_SIZE);
+
+#if !defined(BOX)
+	// Do seperable
+
+#	if defined(HORIZONTAL)
+#		define X_OR_Y x
+#	else
+#		define X_OR_Y y
+#	endif
+
+	COL_TYPE color = textureLod(u_tex, uv, 0.0).TEX_FETCH * WEIGHTS[0u];
+
+	vec2 uvOffset = vec2(0.0);
+	uvOffset.X_OR_Y = 1.5 * TEXEL_SIZE.X_OR_Y;
+
+	ANKI_UNROLL for(uint i = 0u; i < STEP_COUNT; ++i)
+	{
+		COL_TYPE col =
+			textureLod(u_tex, uv + uvOffset, 0.0).TEX_FETCH + textureLod(u_tex, uv - uvOffset, 0.0).TEX_FETCH;
+		color += WEIGHTS[i + 1u] * col;
+
+		uvOffset.X_OR_Y += 2.0 * TEXEL_SIZE.X_OR_Y;
+	}
+#else
+	// Do box
+
+	const vec2 OFFSET = 1.5 * TEXEL_SIZE;
+
+	COL_TYPE color = textureLod(u_tex, uv, 0.0).TEX_FETCH;
+	/*COL_TYPE color = textureLod(u_tex, uv, 0.0).TEX_FETCH * BOX_WEIGHTS[0u];
+
+	COL_TYPE col;
+	col = textureLod(u_tex, uv + vec2(OFFSET.x, 0.0), 0.0).TEX_FETCH;
+	col += textureLod(u_tex, uv + vec2(0.0, OFFSET.y), 0.0).TEX_FETCH;
+	col += textureLod(u_tex, uv + vec2(-OFFSET.x, 0.0), 0.0).TEX_FETCH;
+	col += textureLod(u_tex, uv + vec2(0.0, -OFFSET.y), 0.0).TEX_FETCH;
+	color += col * BOX_WEIGHTS[1u];
+
+	col = textureLod(u_tex, uv + vec2(+OFFSET.x, +OFFSET.y), 0.0).TEX_FETCH;
+	col += textureLod(u_tex, uv + vec2(+OFFSET.x, -OFFSET.y), 0.0).TEX_FETCH;
+	col += textureLod(u_tex, uv + vec2(-OFFSET.x, +OFFSET.y), 0.0).TEX_FETCH;
+	col += textureLod(u_tex, uv + vec2(-OFFSET.x, -OFFSET.y), 0.0).TEX_FETCH;
+	color += col * BOX_WEIGHTS[2u];*/
+#endif
+
+	// Write value
+#if USE_COMPUTE
+	imageStore(u_outImg, ivec2(gl_GlobalInvocationID.xy), TO_VEC4(color));
+#else
+	out_color = color;
+#endif
+}
+
+#endif

+ 11 - 16
shaders/Ssao.glsl

@@ -108,14 +108,14 @@ vec3 computeNormal(vec2 uv, vec3 origin)
 	barrier();
 	barrier();
 
 
 	// Have one thread every quad to compute the normal
 	// Have one thread every quad to compute the normal
-	if((gl_LocalInvocationID.x & 1u) + (gl_LocalInvocationID.y & 1u) == 0u)
+	if(((gl_LocalInvocationID.x & 1u) + (gl_LocalInvocationID.y & 1u)) == 0u)
 	{
 	{
 		// It's the bottom left pixel of the quad
 		// It's the bottom left pixel of the quad
 
 
 		vec3 center, right, top;
 		vec3 center, right, top;
 		center = origin;
 		center = origin;
 		right = s_scratch[gl_LocalInvocationID.y][gl_LocalInvocationID.x + 1u];
 		right = s_scratch[gl_LocalInvocationID.y][gl_LocalInvocationID.x + 1u];
-		top = s_scratch[gl_LocalInvocationID.y + 1u][gl_LocalInvocationID.x + 1u];
+		top = s_scratch[gl_LocalInvocationID.y + 1u][gl_LocalInvocationID.x];
 
 
 		vec3 normal = normalize(cross(right - center, top - center));
 		vec3 normal = normalize(cross(right - center, top - center));
 
 
@@ -205,22 +205,17 @@ void main(void)
 	barrier();
 	barrier();
 
 
 	// Sample neighbours
 	// Sample neighbours
-	ssao *= BOX_WEIGHTS[0];
+	ssao += s_scratch[gl_LocalInvocationID.y][left].x;
+	ssao += s_scratch[gl_LocalInvocationID.y][right].x;
+	ssao += s_scratch[bottom][gl_LocalInvocationID.x].x;
+	ssao += s_scratch[top][gl_LocalInvocationID.x].x;
 
 
-	float cross;
-	cross = s_scratch[gl_LocalInvocationID.y][left].x;
-	cross += s_scratch[gl_LocalInvocationID.y][right].x;
-	cross += s_scratch[bottom][gl_LocalInvocationID.x].x;
-	cross += s_scratch[top][gl_LocalInvocationID.x].x;
+	ssao += s_scratch[bottom][left].x;
+	ssao += s_scratch[bottom][right].x;
+	ssao += s_scratch[top][left].x;
+	ssao += s_scratch[top][right].x;
 
 
-	ssao += cross * BOX_WEIGHTS[1];
-
-	cross = s_scratch[bottom][left].x;
-	cross += s_scratch[bottom][right].x;
-	cross += s_scratch[top][left].x;
-	cross += s_scratch[top][right].x;
-
-	ssao += cross * BOX_WEIGHTS[2];
+	ssao *= (1.0 / 9.0);
 #endif
 #endif
 
 
 	// Store the result
 	// Store the result

+ 2 - 2
src/anki/renderer/Renderer.cpp

@@ -211,7 +211,7 @@ void Renderer::initJitteredMats()
 		subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
 		subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
 
 
 		m_jitteredMats16x[i] = Mat4::getIdentity();
 		m_jitteredMats16x[i] = Mat4::getIdentity();
-		m_jitteredMats16x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
+		// m_jitteredMats16x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
 	}
 	}
 
 
 	static const Array<Vec2, 8> SAMPLE_LOCS_8 = {{Vec2(-7.0, 1.0),
 	static const Array<Vec2, 8> SAMPLE_LOCS_8 = {{Vec2(-7.0, 1.0),
@@ -234,7 +234,7 @@ void Renderer::initJitteredMats()
 		subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
 		subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
 
 
 		m_jitteredMats8x[i] = Mat4::getIdentity();
 		m_jitteredMats8x[i] = Mat4::getIdentity();
-		m_jitteredMats8x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
+		// m_jitteredMats8x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
 	}
 	}
 }
 }
 
 

+ 4 - 10
src/anki/renderer/Ssao.cpp

@@ -56,10 +56,10 @@ Error Ssao::initBlur(const ConfigSet& config)
 	// shader
 	// shader
 	if(m_blurUseCompute)
 	if(m_blurUseCompute)
 	{
 	{
-		ANKI_CHECK(m_r->getResourceManager().loadResource("programs/DepthAwareBlurCompute.ankiprog", m_blur.m_prog));
+		ANKI_CHECK(m_r->getResourceManager().loadResource("programs/GaussianBlurCompute.ankiprog", m_blur.m_prog));
 
 
 		ShaderProgramResourceMutationInitList<3> mutators(m_blur.m_prog);
 		ShaderProgramResourceMutationInitList<3> mutators(m_blur.m_prog);
-		mutators.add("ORIENTATION", 2).add("SAMPLE_COUNT", 3).add("COLOR_COMPONENTS", 1);
+		mutators.add("ORIENTATION", 2).add("KERNEL_SIZE", 3).add("COLOR_COMPONENTS", 1);
 		ShaderProgramResourceConstantValueInitList<2> consts(m_blur.m_prog);
 		ShaderProgramResourceConstantValueInitList<2> consts(m_blur.m_prog);
 		consts.add("TEXTURE_SIZE", UVec2(m_width, m_height))
 		consts.add("TEXTURE_SIZE", UVec2(m_width, m_height))
 			.add("WORKGROUP_SIZE", UVec2(m_workgroupSize[0], m_workgroupSize[1]));
 			.add("WORKGROUP_SIZE", UVec2(m_workgroupSize[0], m_workgroupSize[1]));
@@ -71,10 +71,10 @@ Error Ssao::initBlur(const ConfigSet& config)
 	}
 	}
 	else
 	else
 	{
 	{
-		ANKI_CHECK(m_r->getResourceManager().loadResource("programs/DepthAwareBlur.ankiprog", m_blur.m_prog));
+		ANKI_CHECK(m_r->getResourceManager().loadResource("programs/GaussianBlur.ankiprog", m_blur.m_prog));
 
 
 		ShaderProgramResourceMutationInitList<3> mutators(m_blur.m_prog);
 		ShaderProgramResourceMutationInitList<3> mutators(m_blur.m_prog);
-		mutators.add("ORIENTATION", 2).add("SAMPLE_COUNT", 3).add("COLOR_COMPONENTS", 1);
+		mutators.add("ORIENTATION", 2).add("KERNEL_SIZE", 3).add("COLOR_COMPONENTS", 1);
 		ShaderProgramResourceConstantValueInitList<1> consts(m_blur.m_prog);
 		ShaderProgramResourceConstantValueInitList<1> consts(m_blur.m_prog);
 		consts.add("TEXTURE_SIZE", UVec2(m_width, m_height));
 		consts.add("TEXTURE_SIZE", UVec2(m_width, m_height));
 
 
@@ -184,8 +184,6 @@ void Ssao::runBlur(RenderPassWorkContext& rgraphCtx)
 
 
 	cmdb->bindShaderProgram(m_blur.m_grProg);
 	cmdb->bindShaderProgram(m_blur.m_grProg);
 	rgraphCtx.bindColorTextureAndSampler(0, 0, m_runCtx.m_rts[0], m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 0, m_runCtx.m_rts[0], m_r->getLinearSampler());
-	rgraphCtx.bindTextureAndSampler(
-		0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_QUARTER_DEPTH, m_r->getLinearSampler());
 
 
 	if(m_blurUseCompute)
 	if(m_blurUseCompute)
 	{
 	{
@@ -257,8 +255,6 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 
 
 			pass.setWork(runBlurCallback, this, 0);
 			pass.setWork(runBlurCallback, this, 0);
 
 
-			pass.newConsumer(
-				{m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, HIZ_QUARTER_DEPTH});
 			pass.newConsumer({m_runCtx.m_rts[1], TextureUsageBit::IMAGE_COMPUTE_WRITE});
 			pass.newConsumer({m_runCtx.m_rts[1], TextureUsageBit::IMAGE_COMPUTE_WRITE});
 			pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_COMPUTE});
 			pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_COMPUTE});
 			pass.newProducer({m_runCtx.m_rts[1], TextureUsageBit::IMAGE_COMPUTE_WRITE});
 			pass.newProducer({m_runCtx.m_rts[1], TextureUsageBit::IMAGE_COMPUTE_WRITE});
@@ -272,8 +268,6 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 
 
 			pass.newConsumer({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 			pass.newConsumer({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 			pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_FRAGMENT});
 			pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_FRAGMENT});
-			pass.newConsumer(
-				{m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
 			pass.newProducer({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 			pass.newProducer({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 		}
 		}
 	}
 	}