[Bf-blender-cvs] [76dead8603] clay-engine: Basic Implementation of GTAO : There is still artifacts to remove and optimisation to do.

Clément Foucault noreply at git.blender.org
Wed Jan 18 18:57:38 CET 2017


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




More information about the Bf-blender-cvs mailing list