[Bf-blender-cvs] [590efaa] master: Potential fix for T43987, ambient occlusion different between offscreen and on screen rendering.

Antony Riakiotakis noreply at git.blender.org
Mon Mar 30 14:15:01 CEST 2015


Commit: 590efaacb862aa4352b11e77d37805df5445a90f
Author: Antony Riakiotakis
Date:   Mon Mar 30 14:14:32 2015 +0200
Branches: master
https://developer.blender.org/rB590efaacb862aa4352b11e77d37805df5445a90f

Potential fix for T43987, ambient occlusion different between offscreen
and on screen rendering.

Aaaaah, the beauty of driver implementations of OpenGL!

Turns out the problem here is that drivers calculate df/dy differently
in some cases (probably because OpenGL counts y reverse to how the
window system does, so drivers can get confused).

Fixed this for the ATI case based on info we have so far, there's also
the Intel case which will be handled separately (missing info on Intel's
renderer string etc).

Unfortunately we can't really fix this for the general case so we'll
have to haldle cases as they come in our tracker and by adding silly
string comparisons in our GPU initialization module <sigh>.

===================================================================

M	source/blender/gpu/GPU_extensions.h
M	source/blender/gpu/intern/gpu_compositing.c
M	source/blender/gpu/intern/gpu_extensions.c
M	source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
M	source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl

===================================================================

diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index c006540..de0af81 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -66,6 +66,7 @@ bool GPU_instanced_drawing_support(void);
 
 int GPU_max_texture_size(void);
 int GPU_color_depth(void);
+void GPU_get_dfdy_factors(float fac[2]);
 
 void GPU_code_generate_glsl_lib(void);
 
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index f850b6f..ab47265 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -645,6 +645,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str
 	int numslots = 0;
 	float invproj[4][4];
 	int i;
+	float dfdyfac[2];
 	/* number of passes left. when there are no more passes, the result is passed to the frambuffer */
 	int passes_left = fx->num_passes;
 	/* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */
@@ -657,6 +658,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str
 	if (fx->effects == 0)
 		return false;
 
+	GPU_get_dfdy_factors(dfdyfac);
 	/* first, unbind the render-to-texture framebuffer */
 	GPU_framebuffer_texture_detach(fx->color_buffer);
 	GPU_framebuffer_texture_detach(fx->depth_buffer);
@@ -722,6 +724,8 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str
 			sample_params[2] = fx->gbuffer_dim[0] / 64.0;
 			sample_params[3] = fx->gbuffer_dim[1] / 64.0;
 
+			ssao_params[3] = (passes_left == 1) ? dfdyfac[0] : dfdyfac[1];
+
 			ssao_uniform = GPU_shader_get_uniform(ssao_shader, "ssao_params");
 			ssao_color_uniform = GPU_shader_get_uniform(ssao_shader, "ssao_color");
 			color_uniform = GPU_shader_get_uniform(ssao_shader, "colorbuffer");
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index bc6e24f..c602fda 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -40,6 +40,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
 #include "BLI_math_base.h"
+#include "BLI_math_vector.h"
 
 #include "BKE_global.h"
 
@@ -113,6 +114,9 @@ static struct GPUGlobal {
 	GPUTexture *invalid_tex_1D; /* texture used in place of invalid textures (not loaded correctly, missing) */
 	GPUTexture *invalid_tex_2D;
 	GPUTexture *invalid_tex_3D;
+	float dfdyfactors[2]; /* workaround for different calculation of dfdy factors on GPUs. Some GPUs/drivers
+	                         calculate dfdy in shader differently when drawing to an offscreen buffer. First
+	                         number is factor on screen and second is off-screen */
 } GG = {1, 0};
 
 /* Number of maximum output slots. We support 4 outputs for now (usually we wouldn't need more to preserve fill rate) */
@@ -144,10 +148,15 @@ int GPU_max_texture_size(void)
 	return GG.maxtexsize;
 }
 
+void GPU_get_dfdy_factors(float fac[2])
+{
+	copy_v2_v2(fac, GG.dfdyfactors);
+}
+
 void gpu_extensions_init(void)
 {
 	GLint r, g, b;
-	const char *vendor, *renderer;
+	const char *vendor, *renderer, *version;
 
 	/* glewIsSupported("GL_VERSION_2_0") */
 
@@ -168,6 +177,7 @@ void gpu_extensions_init(void)
 
 	vendor = (const char *)glGetString(GL_VENDOR);
 	renderer = (const char *)glGetString(GL_RENDERER);
+	version = (const char *)glGetString(GL_VERSION);
 
 	if (strstr(vendor, "ATI")) {
 		GG.device = GPU_DEVICE_ATI;
@@ -244,6 +254,23 @@ void gpu_extensions_init(void)
 #endif
 
 
+	/* df/dy calculation factors, those are dependent on driver */
+	if ((strstr(vendor, "ATI") && strstr(version, "3.3.10750"))) {
+		GG.dfdyfactors[0] = 1.0;
+		GG.dfdyfactors[1] = -1.0;
+	}
+	/*
+	if ((strstr(vendor, "Intel"))) {
+		GG.dfdyfactors[0] = -1.0;
+		GG.dfdyfactors[1] = 1.0;
+	}
+	*/
+	else {
+		GG.dfdyfactors[0] = 1.0;
+		GG.dfdyfactors[1] = 1.0;
+	}
+
+
 	GPU_invalid_tex_init();
 	GPU_simple_shaders_init();
 }
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
index 6c4bf3b..1dc49b5 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
@@ -1,11 +1,3 @@
-vec3 calculate_view_space_normal(in vec3 viewposition)
-{
-	vec3 normal = cross(normalize(dFdx(viewposition)),
-	                    normalize(dFdy(viewposition)));
-	normalize(normal);
-	return normal;
-}
-
 /* simple depth reconstruction, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer
  * we change the factors from the article to fit the OpennGL model.  */
 #ifdef PERSP_MATRIX
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
index 5e2512b..783bce7 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
@@ -23,6 +23,14 @@ uniform vec4 ssao_color;
  * see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
 uniform vec4 viewvecs[3];
 
+vec3 calculate_view_space_normal(in vec3 viewposition)
+{
+	vec3 normal = cross(normalize(dFdx(viewposition)),
+	                    ssao_params.w * normalize(dFdy(viewposition)));
+	normalize(normal);
+	return normal;
+}
+
 float calculate_ssao_factor(float depth)
 {
 	/* take the normalized ray direction here */




More information about the Bf-blender-cvs mailing list