Ver Fonte

Optimize tonemapping a bit. Tonemap temporal AA

Panagiotis Christopoulos Charitos há 8 anos atrás
pai
commit
ceec3ad392

+ 3 - 5
programs/FinalComposite.ankiprog

@@ -43,10 +43,8 @@ layout(std140, ANKI_UBO_BINDING(0, 0)) uniform u0_
 	vec4 u_blueNoiseLayerPad3;
 };
 
-layout(std140, ANKI_SS_BINDING(0, 0)) readonly buffer s0_
-{
-	vec4 u_averageLuminancePad3;
-};
+#define TONEMAPPING_RESOURCE readonly buffer
+#include "shaders/TonemappingResources.glsl"
 
 layout(location = 0) in vec2 in_uv;
 layout(location = 0) out vec3 out_color;
@@ -71,7 +69,7 @@ void main()
 	out_color = textureLod(u_isRt, uv, 0.0).rgb;
 #endif
 
-	out_color = tonemap(out_color, readFirstInvocationARB(u_averageLuminancePad3.x), 0.0);
+	out_color = tonemap(out_color, readFirstInvocationARB(u_exposureThreshold0));
 
 #if BLOOM_ENABLED
 	vec3 bloom = textureLod(u_ppsBloomLfRt, uv, 0.0).rgb;

+ 12 - 0
programs/TemporalAAResolve.ankiprog

@@ -18,10 +18,12 @@ http://www.anki3d.org/LICENSE
 #include "shaders/Pack.glsl"
 #include "shaders/Tonemapping.glsl"
 
+// Config
 #define VARIANCE_CLIPPING 1
 const float VARIANCE_CLIPPING_GAMMA = 1.75;
 #define YCBCR 0
 const float BLEND_FACTOR = 1.0 / 16.0; // Keep it low to have a better result
+#define TONEMAP_FIX 1
 
 layout(location = 0) in vec2 in_uv;
 
@@ -36,6 +38,11 @@ layout(ANKI_UBO_BINDING(0, 0), std140, row_major) uniform u0_
 	mat4 u_prevViewProjMatMulInvViewProjMat;
 };
 
+#if TONEMAP_FIX
+#define TONEMAPPING_RESOURCE readonly buffer
+#include "shaders/TonemappingResources.glsl"
+#endif
+
 #if YCBCR
 #define sample(s, uv) rgbToYCbCr(textureLod(s, uv, 0.0).rgb)
 #define sampleOffset(s, uv, x, y) rgbToYCbCr(textureLodOffset(s, uv, 0.0, ivec2(x, y)).rgb)
@@ -83,6 +90,11 @@ void main()
 	float lum0 = crntCol.r;
 	float lum1 = historyCol.r;
 	float maxLum = boxMax.r;
+#elif TONEMAP_FIX
+	float lum0 = computeLuminance(tonemap(crntCol, u_exposureThreshold0));
+	float lum1 = computeLuminance(tonemap(historyCol, u_exposureThreshold0));
+	//float maxLum = computeLuminance(tonemap(boxMax, u_exposureThreshold0));
+	float maxLum = 1.0;
 #else
 	float lum0 = computeLuminance(crntCol);
 	float lum1 = computeLuminance(historyCol);

+ 5 - 7
programs/TonemappingAverageLuminance.ankiprog

@@ -28,10 +28,7 @@ const uint PIXEL_READ_Y = INPUT_TEX_SIZE.y / WORKGROUP_SIZE_Y;
 
 layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_tex;
 
-layout(std140, ANKI_SS_BINDING(0, 0)) buffer ss0_
-{
-	vec4 u_averageLuminancePad3;
-};
+#include "shaders/TonemappingResources.glsl"
 
 shared float g_avgLum[WORKGROUP_SIZE];
 
@@ -84,14 +81,15 @@ void main()
 		crntLum = max(crntLum, 0.04);
 
 #if 1
-		float prevLum = u_averageLuminancePad3.x;
+		float prevLum = u_averageLuminance;
 
 		// Lerp between previous and new L value
 		const float INTERPOLATION_FACTOR = 0.05;
-		u_averageLuminancePad3.x = prevLum * (1.0 - INTERPOLATION_FACTOR) + crntLum * INTERPOLATION_FACTOR;
+		u_averageLuminance = mix(prevLum, crntLum, INTERPOLATION_FACTOR);
 #else
-		u_averageLuminancePad3.x = crntLum;
+		u_averageLuminance = crntLum;
 #endif
+		u_exposureThreshold0 = computeExposure(u_averageLuminance, 0.0);
 	}
 }
 			]]></source>

+ 15 - 7
shaders/Tonemapping.glsl

@@ -19,14 +19,19 @@ float computeLuminance(in vec3 color)
 	return max(dot(vec3(0.30, 0.59, 0.11), color), EPSILON);
 }
 
-vec3 computeExposedColor(in vec3 color, in float avgLum, in float threshold)
+float computeExposure(float avgLum, float threshold)
 {
 	float keyValue = 1.03 - (2.0 / (2.0 + log10(avgLum + 1.0)));
 	float linearExposure = (keyValue / avgLum);
 	float exposure = log2(linearExposure);
 
 	exposure -= threshold;
-	return exp2(exposure) * color;
+	return exp2(exposure);
+}
+
+vec3 computeExposedColor(in vec3 color, in float avgLum, in float threshold)
+{
+	return computeExposure(avgLum, threshold) * color;
 }
 
 // Reinhard operator
@@ -50,13 +55,16 @@ vec3 tonemapUncharted2(in vec3 color)
 	return ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F;
 }
 
-vec3 tonemap(in vec3 color, in float avgLum, in float threshold)
+vec3 tonemap(vec3 color, float exposure)
 {
-	vec3 c = computeExposedColor(color, avgLum, threshold);
-	// float saturation = clamp(avgLum, 0.0, 1.0);
+	color *= exposure;
 	float saturation = 1.0;
-	return tonemapReinhard(c, saturation);
-	// return tonemapUncharted2(c);
+	return tonemapReinhard(color, saturation);
 }
 
+vec3 tonemap(vec3 color, float avgLum, float threshold)
+{
+	float exposure = computeExposure(avgLum, threshold);
+	return tonemap(color, exposure);
+}
 #endif

+ 33 - 0
shaders/TonemappingResources.glsl

@@ -0,0 +1,33 @@
+// Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+// Tonemapping resources
+
+#ifndef ANKI_SHADERS_TONEMAPPING_RESOURCES_GLSL
+#define ANKI_SHADERS_TONEMAPPING_RESOURCES_GLSL
+
+#include "shaders/Common.glsl"
+
+#ifndef TONEMAPPING_SET
+#define TONEMAPPING_SET 0
+#endif
+
+#ifndef TONEMAPPING_LOCATION
+#define TONEMAPPING_LOCATION 0
+#endif
+
+#ifndef TONEMAPPING_RESOURCE
+#define TONEMAPPING_RESOURCE buffer
+#endif
+
+layout(std140, ANKI_SS_BINDING(TONEMAPPING_SET, TONEMAPPING_LOCATION)) TONEMAPPING_RESOURCE tmrss0_
+{
+	vec4 u_averageLuminanceExposurePad2;
+};
+
+#define u_averageLuminance u_averageLuminanceExposurePad2.x
+#define u_exposureThreshold0 u_averageLuminanceExposurePad2.y
+
+#endif

+ 2 - 0
src/anki/renderer/TemporalAA.cpp

@@ -7,6 +7,7 @@
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/GBuffer.h>
 #include <anki/renderer/LightShading.h>
+#include <anki/renderer/Tonemapping.h>
 
 namespace anki
 {
@@ -80,6 +81,7 @@ void TemporalAA::run(RenderingContext& ctx)
 	cmdb->bindTextureAndSampler(0, 1, m_r->getLightShading().getRt(), m_r->getLinearSampler());
 	cmdb->informTextureCurrentUsage(m_rts[(m_r->getFrameCount() + 1) & 1], TextureUsageBit::SAMPLED_FRAGMENT);
 	cmdb->bindTextureAndSampler(0, 2, m_rts[(m_r->getFrameCount() + 1) & 1], m_r->getLinearSampler());
+	cmdb->bindStorageBuffer(0, 0, m_r->getTonemapping().m_luminanceBuff, 0, MAX_PTR_SIZE);
 
 	Mat4* unis = allocateAndBindUniforms<Mat4*>(sizeof(Mat4), cmdb, 0, 0);
 	*unis = ctx.m_jitterMat * ctx.m_prevViewProjMat * ctx.m_viewProjMatJitter.getInverse();