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

Reply via email to