Bläddra i källkod

Optimize nearest upscale for FS

Panagiotis Christopoulos Charitos 9 år sedan
förälder
incheckning
7502e23612
4 ändrade filer med 39 tillägg och 64 borttagningar
  1. 34 52
      shaders/FsUpscale.frag.glsl
  2. 2 3
      shaders/HalfDepth.frag.glsl
  3. 1 1
      src/anki/renderer/Fs.cpp
  4. 2 8
      src/anki/renderer/FsUpscale.cpp

+ 34 - 52
shaders/FsUpscale.frag.glsl

@@ -12,11 +12,10 @@ layout(location = 0) out vec4 out_color;
 
 layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_depthFullTex;
 layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_depthHalfTex;
-layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2D u_colorTexNearest;
-layout(ANKI_TEX_BINDING(0, 3)) uniform sampler2D u_colorTexLinear;
-layout(ANKI_TEX_BINDING(0, 4)) uniform sampler2D u_volTex;
+layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2D u_fsRt;
+layout(ANKI_TEX_BINDING(0, 3)) uniform sampler2D u_volTex;
 #if SSAO_ENABLED
-layout(ANKI_TEX_BINDING(0, 5)) uniform sampler2D u_ssaoTex;
+layout(ANKI_TEX_BINDING(0, 4)) uniform sampler2D u_ssaoTex;
 #endif
 
 layout(ANKI_UBO_BINDING(0, 0)) uniform _u0
@@ -28,69 +27,52 @@ const float DEPTH_THRESHOLD = 1.0 / 1000.0;
 
 const vec2 COLOR_TEX_TEXEL_SIZE = 1.0 / vec2(TEXTURE_WIDTH, TEXTURE_HEIGHT);
 
-const vec2 OFFSETS[8] = vec2[](vec2(-COLOR_TEX_TEXEL_SIZE.x, -COLOR_TEX_TEXEL_SIZE.y),
-	vec2(0.0, -COLOR_TEX_TEXEL_SIZE.y),
-	vec2(COLOR_TEX_TEXEL_SIZE.x, -COLOR_TEX_TEXEL_SIZE.y),
-	vec2(COLOR_TEX_TEXEL_SIZE.x, 0.0),
-	vec2(COLOR_TEX_TEXEL_SIZE.x, COLOR_TEX_TEXEL_SIZE.y),
-	vec2(0.0, COLOR_TEX_TEXEL_SIZE.y),
-	vec2(-COLOR_TEX_TEXEL_SIZE.x, COLOR_TEX_TEXEL_SIZE.y),
-	vec2(-COLOR_TEX_TEXEL_SIZE.x, 0.0));
-
 void main()
 {
 	// Get the depth of the current fragment
 	float depth = texture(u_depthFullTex, in_uv).r;
+	vec3 color = textureLod(u_volTex, in_uv, 0.0).rgb;
 
-	// Gather the depths around the current fragment and:
-	// - Get the min difference compared to crnt depth
-	// - Get the new UV that is closer to the crnt depth
-	float lowDepth = texture(u_depthHalfTex, in_uv).r;
-	float minDiff = abs(depth - lowDepth);
-	float maxDiff = minDiff;
-	vec2 newUv = in_uv;
-	for(uint i = 0u; i < 8u; ++i)
-	{
-		// Read the low depth
-		vec2 uv = in_uv + OFFSETS[i];
-		float lowDepth = texture(u_depthHalfTex, uv).r;
-
-		// Update the max difference compared to the current fragment
-		float diff = abs(depth - lowDepth);
-		maxDiff = max(maxDiff, diff);
+	vec4 lowDepths = textureGather(u_depthHalfTex, in_uv, 0);
+	vec4 diffs = abs(vec4(depth) - lowDepths);
 
-		// Update the new UV
-		if(diff < minDiff)
-		{
-			minDiff = diff;
-			newUv = uv;
-		}
-	}
-
-// Check for depth discontinuites. Use textureLod because it's undefined if you are sampling mipmaped in a conditional
-// branch. See http://teknicool.tumblr.com/post/77263472964/glsl-dynamic-branching-and-texture-samplers
-#if 0
-	float a = u_linearizePad2.x;
-	float b = u_linearizePad2.y;
-	float maxDiffLinear = abs(linearizeDepthOptimal(depth + maxDiff, a, b)
-		- linearizeDepthOptimal(depth, a, b));
-#else
-	float maxDiffLinear = abs(maxDiff);
-#endif
-	vec3 color = textureLod(u_volTex, in_uv, 0.0).rgb;
-	if(maxDiffLinear < DEPTH_THRESHOLD)
+	if(all(lessThan(diffs, vec4(DEPTH_THRESHOLD))))
 	{
 		// No major discontinuites, sample with bilinear
-		color += textureLod(u_colorTexLinear, in_uv, 0.0).rgb;
+		color += textureLod(u_fsRt, in_uv, 0.0).rgb;
 	}
 	else
 	{
 		// Some discontinuites, need to use the newUv
-		color += textureLod(u_colorTexNearest, newUv, 0.0).rgb;
+		vec4 r = textureGather(u_fsRt, in_uv, 0);
+		vec4 g = textureGather(u_fsRt, in_uv, 1);
+		vec4 b = textureGather(u_fsRt, in_uv, 2);
+
+		float minDiff = diffs.x;
+		uint comp = 0;
+
+		if(diffs.y < minDiff)
+		{
+			comp = 1;
+			minDiff = diffs.y;
+		}
+
+		if(diffs.z < minDiff)
+		{
+			comp = 2;
+			minDiff = diffs.z;
+		}
+
+		if(diffs.w < minDiff)
+		{
+			comp = 3;
+		}
+
+		color += vec3(r[comp], g[comp], b[comp]);
 	}
 
 #if SSAO_ENABLED
-	float ssao = texture(u_ssaoTex, in_uv).r;
+	float ssao = textureLod(u_ssaoTex, in_uv, 0.0).r;
 	out_color = vec4(color, ssao);
 #else
 	out_color = vec4(color, 1.0);

+ 2 - 3
shaders/HalfDepth.frag.glsl

@@ -13,9 +13,8 @@ void main()
 {
 	vec4 depths = textureGather(u_depthRt, in_uv, 0);
 
-	float mind = min(depths.x, depths.y);
-	mind = min(mind, depths.z);
-	mind = min(mind, depths.w);
+	vec2 mind2 = min(depths.xy, depths.zw);
+	float mind = min(mind2.x, mind2.y);
 
 	gl_FragDepth = mind;
 }

+ 1 - 1
src/anki/renderer/Fs.cpp

@@ -33,7 +33,7 @@ Error Fs::init(const ConfigSet&)
 		m_height,
 		IS_COLOR_ATTACHMENT_PIXEL_FORMAT,
 		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
-		SamplingFilter::NEAREST,
+		SamplingFilter::LINEAR,
 		1,
 		m_rt);
 

+ 2 - 8
src/anki/renderer/FsUpscale.cpp

@@ -33,17 +33,11 @@ Error FsUpscale::init(const ConfigSet& config)
 	rcInit.m_textures[1].m_sampler = gr.newInstance<Sampler>(sinit);
 	rcInit.m_textures[1].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 
-	sinit.m_minLod = 0.0;
 	rcInit.m_textures[2].m_texture = m_r->getFs().getRt();
-	rcInit.m_textures[2].m_sampler = gr.newInstance<Sampler>(sinit);
 
-	sinit.m_minMagFilter = SamplingFilter::LINEAR;
-	rcInit.m_textures[3].m_texture = m_r->getFs().getRt();
-	rcInit.m_textures[3].m_sampler = gr.newInstance<Sampler>(sinit);
+	rcInit.m_textures[3].m_texture = m_r->getVolumetric().m_rt;
 
-	rcInit.m_textures[4].m_texture = m_r->getVolumetric().m_rt;
-
-	rcInit.m_textures[5].m_texture = m_r->getSsao().getRt();
+	rcInit.m_textures[4].m_texture = m_r->getSsao().getRt();
 
 	rcInit.m_uniformBuffers[0].m_uploadedMemory = true;
 	rcInit.m_uniformBuffers[0].m_usage = BufferUsageBit::UNIFORM_FRAGMENT;