[Bf-blender-cvs] [306711c7ab] clay-engine: Separate SSAO code & add orthographic support

Clément Foucault noreply at git.blender.org
Thu Jan 12 12:30:42 CET 2017


Commit: 306711c7ab79bc1cbe6e197926d7b74370884ab4
Author: Clément Foucault
Date:   Thu Jan 12 01:15:16 2017 +0100
Branches: clay-engine
https://developer.blender.org/rB306711c7ab79bc1cbe6e197926d7b74370884ab4

Separate SSAO code & add orthographic support

===================================================================

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/clay/clay.c
M	source/blender/draw/engines/clay/shaders/clay_frag.glsl
A	source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl
A	source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 8348ef4810..3aef11dfcb 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -61,6 +61,8 @@ set(SRC
 
 data_to_c_simple(engines/clay/shaders/clay_frag.glsl SRC)
 data_to_c_simple(engines/clay/shaders/clay_vert.glsl SRC)
+data_to_c_simple(engines/clay/shaders/ssao_alchemy.glsl SRC)
+data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
 
 list(APPEND INC
 )
diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c
index 7180c6b30e..c0468211ab 100644
--- a/source/blender/draw/engines/clay/clay.c
+++ b/source/blender/draw/engines/clay/clay.c
@@ -23,6 +23,7 @@
 
 #include "BKE_icons.h"
 
+#include "BLI_dynstr.h"
 #include "BLI_rand.h"
 
 #include "IMB_imbuf.h"
@@ -37,6 +38,8 @@
 
 extern char datatoc_clay_frag_glsl[];
 extern char datatoc_clay_vert_glsl[];
+extern char datatoc_ssao_alchemy_glsl[];
+extern char datatoc_ssao_groundtruth_glsl[];
 
 /* Storage */
 
@@ -268,6 +271,7 @@ static void clay_engine_init(void)
 
 	/* Shading pass */
 	if (!data.clay_sh[0]) {
+		DynStr *ds = BLI_dynstr_new();
 		const char *with_all =
 		        "#define USE_AO;\n"
 		        "#define USE_HSV;\n"
@@ -284,15 +288,24 @@ static void clay_engine_init(void)
 		const char *with_ao ="#define USE_AO;\n";
 		const char *with_rot ="#define USE_ROTATION;\n";
 		const char *with_hsv ="#define USE_HSV;\n";
+		char *matcap_with_ao;
 
-		data.clay_sh[WITH_ALL] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, datatoc_clay_frag_glsl, with_all);
-		data.clay_sh[WITH_HSV_ROT] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, datatoc_clay_frag_glsl, with_hsv_rot);
-		data.clay_sh[WITH_AO_ROT] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, datatoc_clay_frag_glsl, with_ao_rot);
-		data.clay_sh[WITH_AO_HSV] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, datatoc_clay_frag_glsl, with_ao_hsv);
-		data.clay_sh[WITH_AO] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, datatoc_clay_frag_glsl, with_ao);
-		data.clay_sh[WITH_ROT] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, datatoc_clay_frag_glsl, with_rot);
-		data.clay_sh[WITH_HSV] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, datatoc_clay_frag_glsl, with_hsv);
-		data.clay_sh[WITH_NONE] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, datatoc_clay_frag_glsl, NULL);
+		BLI_dynstr_append(ds, datatoc_clay_frag_glsl);
+		BLI_dynstr_append(ds, datatoc_ssao_alchemy_glsl);
+
+		matcap_with_ao = BLI_dynstr_get_cstring(ds);
+
+		data.clay_sh[WITH_ALL] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, matcap_with_ao, with_all);
+		data.clay_sh[WITH_HSV_ROT] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, matcap_with_ao, with_hsv_rot);
+		data.clay_sh[WITH_AO_ROT] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, matcap_with_ao, with_ao_rot);
+		data.clay_sh[WITH_AO_HSV] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, matcap_with_ao, with_ao_hsv);
+		data.clay_sh[WITH_AO] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, matcap_with_ao, with_ao);
+		data.clay_sh[WITH_ROT] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, matcap_with_ao, with_rot);
+		data.clay_sh[WITH_HSV] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, matcap_with_ao, with_hsv);
+		data.clay_sh[WITH_NONE] = DRW_shader_create(datatoc_clay_vert_glsl, NULL, matcap_with_ao, NULL);
+
+		BLI_dynstr_free(ds);
+		MEM_freeN(matcap_with_ao);
 	}
 }
 
diff --git a/source/blender/draw/engines/clay/shaders/clay_frag.glsl b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
index 4db8b56ab6..56b26acf0d 100644
--- a/source/blender/draw/engines/clay/shaders/clay_frag.glsl
+++ b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
@@ -37,6 +37,33 @@ in vec3 normal;
 out vec4 fragColor;
 #endif
 
+/* 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)
+{
+	if (WinMatrix[3][3] == 0.0) {
+		/* Perspective */
+		float d = 2.0 * depth - 1.0;
+
+		float zview = -WinMatrix[3][2] / (d + WinMatrix[2][2]);
+
+		return zview * (viewvec_origin + vec3(uvcoords, 0.0) * viewvec_diff);
+	}
+	else {
+		/* Orthographic */
+		vec3 offset = vec3(uvcoords, depth);
+
+		return vec3(viewvec_origin + offset * viewvec_diff);
+	}
+}
+
+/* TODO remove this when switching to geometric normals */
+vec3 calculate_view_space_normal(in vec3 viewposition)
+{
+	vec3 normal = cross(normalize(dFdx(viewposition)), dfdy_sign * normalize(dFdy(viewposition)));
+	return normalize(normal);
+}
+
 #ifdef USE_HSV
 void rgb_to_hsv(vec3 rgb, out vec3 outcol)
 {
@@ -126,96 +153,16 @@ void hue_sat(float hue, float sat, float value, inout vec3 col)
 }
 #endif
 
-/* 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 OpenGL model.  */
-
-/* perspective camera code */
-
-vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 viewvec_diff, in float depth)
-{
-	float d = 2.0 * depth - 1.0;
-
-	float zview = -WinMatrix[3][2] / (d + WinMatrix[2][2]);
-
-	return zview * (viewvec_origin + vec3(uvcoords, 0.0) * viewvec_diff);
-}
-
-/* TODO remove this when switching to geometric normals */
-vec3 calculate_view_space_normal(in vec3 viewposition)
-{
-	vec3 normal = cross(normalize(dFdx(viewposition)), dfdy_sign * normalize(dFdy(viewposition)));
-
-	return normalize(normal);
-}
-
 #ifdef USE_AO
-void calculate_ssao_factor(in float depth, in vec3 normal, in vec3 position, out float cavities, out float edges)
-{
-	vec2 uvs = vec2(gl_FragCoord.xy) / vec2(screenres);
-
-	/* take the normalized ray direction here */
-	vec2 rotX = texture2D(ssao_jitter, uvs.xy * jitter_tilling).rg;
-	vec2 rotY = vec2(-rotX.y, rotX.x);
-
-	/* find the offset in screen space by multiplying a point
-	 * in camera space at the depth of the point by the projection matrix. */
-	vec2 offset;
-	float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3];
-	offset.x = WinMatrix[0][0] * ssao_distance / homcoord;
-	offset.y = WinMatrix[1][1] * ssao_distance / homcoord;
-	/* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
-	offset *= 0.5;
-
-	cavities = edges = 0.0;
-	int x;
-	int num_samples = int(ssao_samples_num);
-
-	for (x = 0; x < num_samples; x++) {
-		vec2 dir_sample = texture1D(ssao_samples, (float(x) + 0.5) / ssao_samples_num).rg;
-
-		/* rotate with random direction to get jittered result */
-		vec2 dir_jittered = vec2(dot(dir_sample, rotX), dot(dir_sample, rotY));
-
-		vec2 uvcoords = uvs.xy + dir_jittered * offset;
-
-		if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0)
-			continue;
-
-		float depth_new = texture2D(depthtex, uvcoords).r;
-		/* Handle Background case */
-		if (depth_new != 1.0) {
-			vec3 pos_new = get_view_space_from_depth(uvcoords, viewvecs[0].xyz, viewvecs[1].xyz, depth_new);
-			vec3 dir = pos_new - position;
-			float len = length(dir);
-			float f_cavities = dot(dir, normal);
-			float f_edge = dot(dir, -normal);
-			float f_bias = 0.05 * len + 0.0001;
-
-			float attenuation = 1.0 / (len * (1.0 + len * len * ssao_attenuation));
-
-			/* use minor bias here to avoid self shadowing */
-			if (f_cavities > f_bias)
-				cavities += f_cavities * attenuation;
-
-			if (f_edge > f_bias)
-				edges += f_edge * attenuation;
-		}
-	}
-
-	cavities /= ssao_samples_num;
-	edges /= ssao_samples_num;
-
-	/* don't let cavity wash out the surface appearance */
-	cavities = clamp(cavities * ssao_factor_cavity, 0.0, 0.85);
-	edges = edges * ssao_factor_edge;
-}
+/* Prototype */
+void ssao_factors(in float depth, in vec3 normal, in vec3 position, in vec2 screenco, out float cavities, out float edges);
 #endif
 
 void main() {
-	vec2 uvs = vec2(gl_FragCoord.xy) / vec2(screenres);
-	float depth = texture(depthtex, uvs).r;
+	vec2 screenco = vec2(gl_FragCoord.xy) / vec2(screenres);
+	float depth = texture(depthtex, screenco).r;
 
-	vec3 position = get_view_space_from_depth(uvs, viewvecs[0].xyz, viewvecs[1].xyz, depth);
+	vec3 position = get_view_space_from_depth(screenco, viewvecs[0].xyz, viewvecs[1].xyz, depth);
 	vec3 normal = calculate_view_space_normal(position);
 
 	/* Manual Depth test */
@@ -235,7 +182,7 @@ void main() {
 
 #ifdef USE_AO
 	float cavity, edges;
-	calculate_ssao_factor(depth, normal, position, cavity, edges);
+	ssao_factors(depth, normal, position, screenco, cavity, edges);
 
 	col = mix(col, matcaps_color[int(matcap_index)], cavity);
 	col *= edges + 1.0;
diff --git a/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl b/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl
new file mode 100644
index 0000000000..f1ca611428
--- /dev/null
+++ b/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl
@@ -0,0 +1,61 @@
+/*  from The Alchemy screen-space ambient obscurance algorithm
+ * http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */
+
+void ssao_factors(in float depth, in vec3 normal, in vec3 position, in vec2 screenco, out float cavities, out float edges)
+{
+	/* take the normalized ray direction here */
+	vec2 rotX = texture2D(ssao_jitter, screenco.xy * jitter_tilling).rg;
+	vec2 rotY = vec2(-rotX.y, rotX.x);
+
+	/* find the offset in screen space by multiplying a point
+	 * in camera space at the depth of the point by the projection matrix. */
+	vec2 offset;
+	float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3];
+	offset.x = WinMatrix[0][0] * ssao_distance / homcoord;
+	offset.y = WinMatrix[1][1] * ssao_distance / homcoord;
+	/* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
+	offset *= 0.5;
+
+	cavities = edges = 0.0;
+	int x;
+	int num_samples = int(ssao_samples_num);
+
+	for (x = 0; x < num_samples; x++) {
+		vec2 dir_sample = texture1D(ssao_samples, (float(x) + 0.5) / ssao_samples_num).rg;
+
+		/* rotate with random direction to get jittered result */
+		vec2 dir_jittered = vec2(dot(dir_sample, rotX), dot(dir

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list