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>.
This commit is contained in:
Antonis Ryakiotakis 2015-03-30 14:14:32 +02:00
parent 4aeb34dc82
commit 590efaacb8
Notes: blender-bot 2023-02-14 09:19:01 +01:00
Referenced by issue #44195, Audio sync can backtrack in time
5 changed files with 41 additions and 9 deletions

View File

@ -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);

View File

@ -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");

View File

@ -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();
}

View File

@ -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

View File

@ -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 */