[Bf-blender-cvs] [7a28dea1e17] blender2.8: Workbench: Shadow: Add Depth Fail method

Clément Foucault noreply at git.blender.org
Sun May 20 19:20:17 CEST 2018


Commit: 7a28dea1e173aefd08ef2130a9efc401d049e150
Author: Clément Foucault
Date:   Sun May 20 15:15:22 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB7a28dea1e173aefd08ef2130a9efc401d049e150

Workbench: Shadow: Add Depth Fail method

Also add new debug visualisation.

Depth fail method is not used for the moment but has nice benefits. It will
be used efficiently in the future.

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

M	source/blender/draw/CMakeLists.txt
A	source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl
A	source/blender/draw/engines/workbench/shaders/workbench_shadow_debug_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
M	source/blender/draw/engines/workbench/workbench_materials.c
M	source/blender/draw/engines/workbench/workbench_private.h
M	source/blender/draw/intern/draw_manager_exec.c

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index d3079c337ea..9478d41f6db 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -213,6 +213,8 @@ data_to_c_simple(engines/workbench/shaders/workbench_prepass_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_composite_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_shadow_vert.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_shadow_geom.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_shadow_caps_geom.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_shadow_debug_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_background_lib.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_common_lib.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_data_lib.glsl SRC)
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl
new file mode 100644
index 00000000000..5d286bd1090
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl
@@ -0,0 +1,82 @@
+#extension GL_ARB_gpu_shader5 : enable
+
+#ifdef GL_ARB_gpu_shader5
+#define USE_INVOC_EXT
+#endif
+
+#define DOUBLE_MANIFOLD
+
+#ifdef DOUBLE_MANIFOLD
+#  ifdef USE_INVOC_EXT
+#    define invoc_ct 4
+#  else
+#    define vert_ct 12
+#  endif
+#else
+#  ifdef USE_INVOC_EXT
+#    define invoc_ct 2
+#  else
+#    define vert_ct 6
+#  endif
+#endif
+
+#ifdef USE_INVOC_EXT
+layout(triangles, invocations = invoc_ct) in;
+layout(triangle_strip, max_vertices = 3) out;
+#else
+layout(triangles) in;
+layout(triangle_strip, max_vertices = vert_ct) out;
+#endif
+
+uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
+
+in VertexData {
+	vec3 pos;           /* local position */
+	vec4 frontPosition; /* final ndc position */
+	vec4 backPosition;
+} vData[];
+
+vec4 get_pos(int v, bool backface)
+{
+	return (backface) ? vData[v].backPosition : vData[v].frontPosition;
+}
+
+void emit_cap(const bool front)
+{
+	if (front) {
+		gl_Position = vData[0].frontPosition; EmitVertex();
+		gl_Position = vData[1].frontPosition; EmitVertex();
+		gl_Position = vData[2].frontPosition; EmitVertex();
+	}
+	else {
+		gl_Position = vData[0].backPosition; EmitVertex();
+		gl_Position = vData[2].backPosition; EmitVertex();
+		gl_Position = vData[1].backPosition; EmitVertex();
+	}
+	EndPrimitive();
+}
+
+void main()
+{
+	vec3 v10 = vData[0].pos - vData[1].pos;
+	vec3 v12 = vData[2].pos - vData[1].pos;
+
+	vec3 n = cross(v12, v10);
+	float facing = dot(n, lightDirection);
+
+	bool backface = facing > 0.0;
+
+	if (!backface) {
+#ifdef USE_INVOC_EXT
+		bool do_front = (gl_InvocationID & 1) == 0;
+		emit_cap(do_front);
+#else
+		emit_cap(true);
+		emit_cap(false);
+#  ifdef DOUBLE_MANIFOLD
+		emit_cap(true);
+		emit_cap(false);
+#  endif
+#endif
+	}
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_debug_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_debug_frag.glsl
new file mode 100644
index 00000000000..ceb33e77f2b
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_debug_frag.glsl
@@ -0,0 +1,14 @@
+
+out vec4 fragColor;
+
+void main()
+{
+	const float intensity = 0.25;
+#ifdef SHADOW_PASS
+	fragColor = vec4((gl_FrontFacing) ? vec3(intensity, -intensity, 0.0)
+	                                  : vec3(-intensity, intensity, 0.0), 1.0);
+#else
+	fragColor = vec4((gl_FrontFacing) ? vec3(intensity, intensity, -intensity)
+	                                  : vec3(-intensity, -intensity, intensity), 1.0);
+#endif
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
index 881cc901ffb..7352623b74c 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
@@ -1,11 +1,31 @@
 #extension GL_ARB_gpu_shader5 : enable
 
 #ifdef GL_ARB_gpu_shader5
-layout(lines_adjacency, invocations = 2) in;
+#define USE_INVOC_EXT
+#endif
+
+#define DOUBLE_MANIFOLD
+
+#ifdef DOUBLE_MANIFOLD
+#  ifdef USE_INVOC_EXT
+#    define invoc_ct 2
+#  else
+#    define vert_ct 8
+#  endif
+#else
+#  ifdef USE_INVOC_EXT
+#    define invoc_ct 1
+#  else
+#    define vert_ct 4
+#  endif
+#endif
+
+#ifdef USE_INVOC_EXT
+layout(lines_adjacency, invocations = invoc_ct) in;
 layout(triangle_strip, max_vertices = 4) out;
 #else
 layout(lines_adjacency) in;
-layout(triangle_strip, max_vertices = 8) out;
+layout(triangle_strip, max_vertices = vert_ct) out;
 #endif
 
 uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
@@ -22,7 +42,8 @@ in VertexData {
 
 void extrude_edge(bool invert)
 {
-	ivec2 idx = (invert) ? ivec2(2, 1) : ivec2(1, 2);
+	/* Reverse order if backfacing the light. */
+	ivec2 idx = (invert) ? ivec2(1, 2) : ivec2(2, 1);
 	gl_Position = vData[idx.x].frontPosition; EmitVertex();
 	gl_Position = vData[idx.y].frontPosition; EmitVertex();
 	gl_Position = vData[idx.x].backPosition; EmitVertex();
@@ -69,23 +90,23 @@ void main()
 	if (backface.x == backface.y)
 		return;
 
-	/* Reverse order if backfacing the light. */
-	ivec2 idx = ivec2(1, 2);
-	idx = (backface.x) ? idx.yx : idx.xy;
-
-#ifdef GL_ARB_gpu_shader5
+#ifdef USE_INVOC_EXT
 	if (gl_InvocationID == 0) {
 		extrude_edge(backface.x);
 	}
 	else if (is_manifold) {
+#  ifdef DOUBLE_MANIFOLD
 		/* Increment/Decrement twice for manifold edges. */
 		extrude_edge(backface.x);
+#  endif
 	}
 #else
 	extrude_edge(backface.x);
-	/* Increment/Decrement twice for manifold edges. */
 	if (is_manifold) {
+#  ifdef DOUBLE_MANIFOLD
+		/* Increment/Decrement twice for manifold edges. */
 		extrude_edge(backface.x);
+#  endif
 	}
 #endif
 }
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
index 4a06d325db6..3a61bf0a286 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
@@ -1,8 +1,7 @@
-#define EPSILON 0.0001
-#define INFINITE 1000000.0
+#define INFINITE 1000.0
 
 uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ViewProjectionMatrix;
+
 uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
 
 in vec3 pos;
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 959186cd1d2..72a9431efbe 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -54,7 +54,9 @@
 static struct {
 	struct GPUShader *prepass_sh_cache[MAX_SHADERS];
 	struct GPUShader *composite_sh_cache[MAX_SHADERS];
-	struct GPUShader *shadow_sh;
+	struct GPUShader *shadow_fail_sh;
+	struct GPUShader *shadow_pass_sh;
+	struct GPUShader *shadow_caps_sh;
 
 	struct GPUTexture *object_id_tx; /* ref only, not alloced */
 	struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
@@ -74,6 +76,8 @@ extern char datatoc_workbench_composite_frag_glsl[];
 
 extern char datatoc_workbench_shadow_vert_glsl[];
 extern char datatoc_workbench_shadow_geom_glsl[];
+extern char datatoc_workbench_shadow_caps_geom_glsl[];
+extern char datatoc_workbench_shadow_debug_frag_glsl[];
 
 extern char datatoc_workbench_background_lib_glsl[];
 extern char datatoc_workbench_common_lib_glsl[];
@@ -320,7 +324,26 @@ void workbench_materials_engine_init(WORKBENCH_Data *vedata)
 		memset(e_data.prepass_sh_cache,   0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
 		memset(e_data.composite_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
 		e_data.next_object_id = 1;
-		e_data.shadow_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl, datatoc_workbench_shadow_geom_glsl, NULL, NULL);
+#ifdef DEBUG_SHADOW_VOLUME
+		const char *shadow_frag = datatoc_workbench_shadow_debug_frag_glsl;
+#else
+		const char *shadow_frag = NULL;
+#endif
+		e_data.shadow_pass_sh = DRW_shader_create(
+		        datatoc_workbench_shadow_vert_glsl,
+		        datatoc_workbench_shadow_geom_glsl,
+		        shadow_frag,
+		        "#define SHADOW_PASS\n");
+		e_data.shadow_fail_sh = DRW_shader_create(
+		        datatoc_workbench_shadow_vert_glsl,
+		        datatoc_workbench_shadow_geom_glsl,
+		        shadow_frag,
+		        "#define SHADOW_FAIL\n");
+		e_data.shadow_caps_sh = DRW_shader_create(
+		        datatoc_workbench_shadow_vert_glsl,
+		        datatoc_workbench_shadow_caps_geom_glsl,
+		        shadow_frag,
+		        NULL);
 	}
 
 	if (!stl->g_data) {
@@ -369,7 +392,9 @@ void workbench_materials_engine_free()
 		DRW_SHADER_FREE_SAFE(e_data.prepass_sh_cache[index]);
 		DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
 	}
-	DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
+	DRW_SHADER_FREE_SAFE(e_data.shadow_pass_sh);
+	DRW_SHADER_FREE_SAFE(e_data.shadow_fail_sh);
+	DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh);
 }
 
 static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
@@ -442,13 +467,22 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
 			DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 
 #ifdef DEBUG_SHADOW_VOLUME
-			psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK | DRW_STATE_WRITE_COLOR);
-			grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
-			DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.display.light_direction, 1);
-			DRW_shgroup_stencil_mask(grp, 0xFF);
-			wpd->shadow_shgrp = grp;
+			psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Debug Pass", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
+			grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
+			psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Debug Fail", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
+			grp = DRW_shgroup_create(e_data.shadow_fail_s

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list