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:
parent
4aeb34dc82
commit
590efaacb8
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user