Commit: 76dead8603141f1f38a600701f2c6597318774a0 Author: Clément Foucault Date: Wed Jan 18 18:55:56 2017 +0100 Branches: clay-engine https://developer.blender.org/rB76dead8603141f1f38a600701f2c6597318774a0
Basic Implementation of GTAO : There is still artifacts to remove and optimisation to do. =================================================================== M source/blender/draw/engines/clay/clay.c M source/blender/draw/engines/clay/shaders/clay_frag.glsl M source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl M source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl =================================================================== diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c index 7cfe156339..32d18e8da1 100644 --- a/source/blender/draw/engines/clay/clay.c +++ b/source/blender/draw/engines/clay/clay.c @@ -111,6 +111,8 @@ typedef struct CLAY_PassList{ struct DRWPass *mode_ob_center_pass; } CLAY_PassList; +// #define GTAO + /* Functions */ static void add_icon_to_rect(PreviewImage *prv, float *final_rect, int layer) @@ -210,9 +212,14 @@ static struct GPUTexture *create_jitter_texture(void) /* TODO replace by something more evenly distributed like blue noise */ for (i = 0; i < 64 * 64; i++) { +#ifdef GTAO + jitter[i][0] = BLI_frand(); + jitter[i][1] = BLI_frand(); +#else jitter[i][0] = 2.0f * BLI_frand() - 1.0f; jitter[i][1] = 2.0f * BLI_frand() - 1.0f; normalize_v2(jitter[i]); +#endif } return DRW_texture_create_2D(64, 64, DRW_TEX_RG_16, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]); @@ -291,7 +298,11 @@ static void clay_engine_init(void) char *matcap_with_ao; BLI_dynstr_append(ds, datatoc_clay_frag_glsl); +#ifdef GTAO + BLI_dynstr_append(ds, datatoc_ssao_groundtruth_glsl); +#else BLI_dynstr_append(ds, datatoc_ssao_alchemy_glsl); +#endif matcap_with_ao = BLI_dynstr_get_cstring(ds); diff --git a/source/blender/draw/engines/clay/shaders/clay_frag.glsl b/source/blender/draw/engines/clay/shaders/clay_frag.glsl index 16178a48eb..9bc4a4ef3b 100644 --- a/source/blender/draw/engines/clay/shaders/clay_frag.glsl +++ b/source/blender/draw/engines/clay/shaders/clay_frag.glsl @@ -40,7 +40,7 @@ out vec4 fragColor; /* TODO Move this to SSAO modules */ /* 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. */ -vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 viewvec_diff, in float depth) +vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth) { if (WinMatrix[3][3] == 0.0) { /* Perspective */ @@ -48,13 +48,13 @@ vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 float zview = -WinMatrix[3][2] / (d + WinMatrix[2][2]); - return zview * (viewvec_origin + vec3(uvcoords, 0.0) * viewvec_diff); + return zview * (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz); } else { /* Orthographic */ vec3 offset = vec3(uvcoords, depth); - return vec3(viewvec_origin + offset * viewvec_diff); + return viewvecs[0].xyz + offset * viewvecs[1].xyz; } } @@ -163,7 +163,7 @@ void main() { vec2 screenco = vec2(gl_FragCoord.xy) / vec2(screenres); float depth = texture(depthtex, screenco).r; - vec3 position = get_view_space_from_depth(screenco, viewvecs[0].xyz, viewvecs[1].xyz, depth); + vec3 position = get_view_space_from_depth(screenco, depth); vec3 normal = calculate_view_space_normal(position); /* Manual Depth test */ diff --git a/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl b/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl index 0f216bf5a3..ff6728185b 100644 --- a/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl +++ b/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl @@ -38,7 +38,7 @@ void ssao_factors(in float depth, in vec3 normal, in vec3 position, in vec2 scre bool is_background = (depth_new == 1.0); /* This trick provide good edge effect even if no neighboor is found. */ - vec3 pos_new = get_view_space_from_depth(uvcoords, viewvecs[0].xyz, viewvecs[1].xyz, (is_background) ? depth : depth_new); + vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new); if (is_background) pos_new.z -= ssao_distance; diff --git a/source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl b/source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl index bfd851f5d9..291c6ab89a 100644 --- a/source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl +++ b/source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl @@ -1,9 +1,107 @@ /* Based on Practical Realtime Strategies for Accurate Indirect Occlusion - * http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf */ + * http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf + * http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx */ -void ssao_factors(in float depth, in vec3 normal, in vec3 position, in vec2 screenco, out float cavities, out float edges) +#define COSINE_WEIGHTING + +float integrate_arc(in float h1, in float h2, in float gamma, in float n_proj_len) { - cavities = 0.0; - edges = 0.0; + float a = 0.0; +#ifdef COSINE_WEIGHTING + float cos_gamma = cos(gamma); + float sin_gamma_2 = 2.0 * sin(gamma); + a += -cos(2.0 * h1 - gamma) + cos_gamma + h1 * sin_gamma_2; + a += -cos(2.0 * h2 - gamma) + cos_gamma + h2 * sin_gamma_2; + a *= 0.25; /* 1/4 */ + a *= n_proj_len; +#else + /* Uniform weighting (slide 59) */ + a += 1 - cos(h1); + a += 1 - cos(h2); +#endif + return a; } +float get_max_horizon(in vec2 co, in vec3 x, in vec3 omega_o, in float h) +{ + if (co.x < 1.0 && co.x > 0.0 && co.y < 1.0 && co.y > 0.0) { + float depth = texture2D(depthtex, co).r; + + /* Background case */ + if (depth == 1.0) + return h; + + vec3 s = get_view_space_from_depth(co, depth); /* s View coordinate */ + vec3 omega_s = s - x; + float len = length(omega_s); + + if (len < ssao_distance) { + omega_s /= len; + h = max(h, dot(omega_s, omega_o)); + } + } + return h; +} + +void ssao_factors(in float depth, in vec3 normal, in vec3 position, in vec2 screenco, out float cavities, out float edges) +{ + /* Renaming */ + vec3 omega_o = -normalize(position); /* viewvec */ + vec2 x_ = screenco; /* x^ Screen coordinate */ + vec3 x = position; /* x view space coordinate */ + + float homcco = WinMatrix[2][3] * position.z + WinMatrix[3][3]; + + vec2 jitter = texture2D(ssao_jitter, screenco.xy * jitter_tilling).rg; + + const float phi_step = 8.0; + const float theta_step = 8.0; + const float m_pi = 3.14159265358979323846; + vec2 pixel_size = vec2(float(screenres.y) / float(screenres.x), 1.0); + float n = ssao_distance / homcco; /* Search distance */ + + /* Integral over PI */ + float A = 0.0; + for (float i = 0.0; i < phi_step; i++) { + float phi = m_pi * (jitter.x + i / phi_step); + + vec2 t_phi = vec2(cos(phi), sin(phi)); /* Screen space direction */ + + /* Search maximum horizon angles Theta1 and Theta2 */ + float theta1 = -1.0, theta2 = -1.0; /* init at cos(pi) */ + for (float j = 0.0; j < theta_step; j++) { + vec2 co; + vec2 s_ = t_phi * n * ((j + 1.0 + jitter.y) / theta_step); /* s^ Screen coordinate */ + + co = x_ + s_ * pixel_size; + theta1 = get_max_horizon(co, x, omega_o, theta1); + + co = x_ - s_ * pixel_size; + theta2 = get_max_horizon(co, x, omega_o, theta2); + } + + /* (Slide 54) */ + theta1 = -acos(theta1); + theta2 = acos(theta2); + + /* Projecting Normal to Plane P defined by t_phi and omega_o */ + vec3 h = normalize(cross(vec3(t_phi, 0.0), omega_o)); /* Normal vector to Integration plane */ + vec3 t = cross(h, omega_o); /* Normal vector to plane */ + vec3 n_proj = normal - h * dot(normal, h); + float n_proj_len = length(n_proj); + vec3 n_proj_norm = normalize(n_proj); + + /* Clamping thetas (slide 58) */ + float gamma = sign(dot(n_proj_norm, t)) * acos(dot(n_proj_norm, omega_o)); /* Angle between view vec and normal */ + theta1 = gamma + max(theta1 - gamma, -m_pi * 0.5); + theta2 = gamma + min(theta2 - gamma, m_pi * 0.5); + + /* Solving inner integral */ + A += integrate_arc(theta1, theta2, gamma, n_proj_len); + } + + A /= phi_step; + + cavities = 1.0 - A; + edges = 0.0; +} \ No newline at end of file _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs