[Bf-blender-cvs] [f17e7a34744] blender2.8-workbench: Workbench: Shadows

Jeroen Bakker noreply at git.blender.org
Wed May 2 15:13:41 CEST 2018


Commit: f17e7a3474483315edb186d753deb1d7d6216ab7
Author: Jeroen Bakker
Date:   Wed May 2 15:12:42 2018 +0200
Branches: blender2.8-workbench
https://developer.blender.org/rBf17e7a3474483315edb186d753deb1d7d6216ab7

Workbench: Shadows

Use a depth fail shadow volume algoritmh. TODO: optimize for speed. Fix
fireflies

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

M	release/scripts/startup/bl_ui/properties_render.py
M	source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
M	source/blender/draw/engines/workbench/workbench_engine.c
M	source/blender/draw/engines/workbench/workbench_materials.c
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager_exec.c
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/makesrna/intern/rna_layer.c

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

diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 5e5a55a3dab..3de97789691 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -768,6 +768,7 @@ class RENDER_PT_workbench_environment_light(RenderButtonsPanel, Panel):
         col.prop(props, "diffuse_light_z_neg", text="")
 
         layout.prop(props, "light_direction", text="")
+        layout.prop(props, "ambient_light_intensity")
 
 
 classes = (
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 9d6da35c314..15834cd4d45 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
@@ -1,37 +1,64 @@
 #define EPSILON 0.0000001
-#define INFINITE 1000.0
-layout(lines) in;
-layout(triangle_strip, max_vertices=4) out;
+#define INFINITE 100.0
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices=14) out;
 
 uniform mat4 ModelMatrix;
 uniform mat4 ModelViewProjectionMatrix;
 
 uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
-flat in vec3 faceNormal1[]; 
-flat in vec3 faceNormal2[];
-
-void emit_quad(vec4 start_vertex, vec4 end_vertex, vec4 light_direction) {
-	gl_Position = ModelViewProjectionMatrix * (start_vertex + light_direction * EPSILON);
+vec3 face_normal(vec3 v1, vec3 v2, vec3 v3) {
+	return normalize(cross(v2 - v1, v3 - v1));
+}
+void emit_side_quad(vec4 v1, vec4 v2, vec4 light_direction) {
+	gl_Position = ModelViewProjectionMatrix * (v1 + light_direction * EPSILON);
 	EmitVertex();
-	gl_Position = ModelViewProjectionMatrix * (start_vertex + light_direction * INFINITE);
+	gl_Position = ModelViewProjectionMatrix * (v1 + light_direction * INFINITE);
 	EmitVertex();
-	gl_Position = ModelViewProjectionMatrix * (end_vertex + light_direction * EPSILON);
+	gl_Position = ModelViewProjectionMatrix * (v2 + light_direction * EPSILON);
 	EmitVertex();
-	gl_Position = ModelViewProjectionMatrix * (end_vertex + light_direction * INFINITE);
+	gl_Position = ModelViewProjectionMatrix * (v2 + light_direction * INFINITE);
 	EmitVertex();
 	EndPrimitive();
 }
+void emit_front_cap(vec4 v1, vec4 v2, vec4 v3, vec4 light_direction) {
+	gl_Position = ModelViewProjectionMatrix * (v1 + light_direction * EPSILON);
+	EmitVertex();
+	gl_Position = ModelViewProjectionMatrix * (v2 + light_direction * EPSILON);
+	EmitVertex();
+	gl_Position = ModelViewProjectionMatrix * (v3 + light_direction * EPSILON);
+	EmitVertex();
+	EndPrimitive();
+}
+
+void emit_back_cap(vec4 v1, vec4 v2, vec4 v3, vec4 light_direction) {
+	gl_Position = ModelViewProjectionMatrix * (v3 + light_direction * INFINITE);
+	EmitVertex();
+	gl_Position = ModelViewProjectionMatrix * (v2 + light_direction * INFINITE);
+	EmitVertex();
+	gl_Position = ModelViewProjectionMatrix * (v1 + light_direction * INFINITE);
+	EmitVertex();
+	EndPrimitive();
+}
+
 void main()
 {
-	/* light_direction: Light direction in object space TODO: Move to CPU */
+	/* light_direction: Light direction in object space TODO: Move to world space */
 	vec3 light_direction = normalize((vec4(lightDirection, 0.0) * ModelMatrix).xyz);
-	bool front1 = dot(faceNormal1[0], light_direction) >= 0;
-	bool front2 = dot(faceNormal2[0], light_direction) >= 0;
+	vec4 v1 = gl_in[0].gl_Position;
+	vec4 v2 = gl_in[1].gl_Position;
+	vec4 v3 = gl_in[2].gl_Position;
+	bool backface = dot(face_normal(v1.xyz, v2.xyz, v3.xyz), light_direction) > 0.0;
 
-	if (!front1 && front2) {
-		emit_quad(gl_in[0].gl_Position, gl_in[1].gl_Position, vec4(light_direction, 0.0));
+	if (backface) {
+		vec4 light_direction4 = vec4(light_direction, 0.0);
+		/* emit side faces */
+		emit_side_quad(v2, v1, light_direction4);
+		emit_side_quad(v3, v2, light_direction4);
+		emit_side_quad(v1, v3, light_direction4);
+		/* emit front and back cap */
+		emit_front_cap(v3, v2, v1, light_direction4);
+		emit_back_cap(v3, v2, v1, light_direction4);
 	}
-	else if (front1 && !front2) {
-		emit_quad(gl_in[1].gl_Position, gl_in[0].gl_Position, vec4(light_direction, 0.0));
-	}
-}
\ No newline at end of file
+}
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 32c8479393e..844513372c9 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -74,7 +74,9 @@ static void workbench_view_layer_settings_create(RenderEngine *UNUSED(engine), I
 	BKE_collection_engine_property_add_float_array(props, "diffuse_light_z_neg", diffuse_z_neg, 3);
 
 	const float light_direction[3] = {0.577350269, 0.577350269, 0.577350269};
+	const float ambient_light_intensity = 0.8;
 	BKE_collection_engine_property_add_float_array(props, "light_direction", light_direction, 3);
+	BKE_collection_engine_property_add_float(props, "ambient_light_intensity", ambient_light_intensity);
 }
 
 /* Note: currently unused, we may want to register so we can see this when debugging the view. */
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 0187f3d1581..98397403edb 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -38,8 +38,9 @@
 
 /* *********** STATIC *********** */
 
-// #define SHOW_SHADOW_VOLUME
+//#define DEBUG_SHADOW_VOLUME
 #define MAX_SHADERS 255
+
 static struct {
 	struct GPUShader *prepass_sh_cache[MAX_SHADERS];
 	struct GPUShader *composite_sh_cache[MAX_SHADERS];
@@ -74,7 +75,6 @@ extern DrawEngineType draw_engine_workbench_solid;
 #define OBJECT_ID_PASS_ENABLED(wpd) (wpd->drawtype_options & V3D_DRAWOPTION_OBJECT_OVERLAP)
 #define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (wpd->drawtype_lighting & V3D_LIGHTING_STUDIO)
 #define SHADOW_ENABLED(wpd) (wpd->drawtype_options & V3D_DRAWOPTION_SHADOW)
-
 static char *workbench_build_defines(WORKBENCH_PrivateData *wpd)
 {
 	char *str = NULL;
@@ -220,8 +220,6 @@ 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.light_multiplier = 1.0;
-		e_data.shadow_multiplier = 0.8;
 		e_data.shadow_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl, datatoc_workbench_shadow_geom_glsl, NULL, NULL);
 	}
 
@@ -320,6 +318,8 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
 		wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), NULL);
 		DRW_uniformbuffer_update(wpd->world_ubo, &wpd->world_data);
 
+		e_data.light_multiplier = 1.0;
+		e_data.shadow_multiplier = BKE_collection_engine_property_value_get_float(props, "ambient_light_intensity");
 		copy_v3_v3(e_data.light_direction, BKE_collection_engine_property_value_get_float_array(props, "light_direction"));
 		negate_v3(e_data.light_direction);
 
@@ -331,14 +331,14 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
 		DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 
 		if (SHADOW_ENABLED(wpd)) {
-#ifdef SHOW_SHADOW_VOLUME
-			psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR );
+#ifdef DEBUG_SHADOW_VOLUME
+			psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR);
 			grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
 			DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction, 1);
 			DRW_shgroup_stencil_mask(grp, 0xFF);
 			wpd->shadow_shgrp = grp;
 #else
-			psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_INCR_DECR_WRAP);
+			psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_DEPTH_FAIL_INCR_DECR_WRAP);
 			grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
 			DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction, 1);
 			DRW_shgroup_stencil_mask(grp, 0xFF);
@@ -468,7 +468,7 @@ void workbench_materials_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob
 		}
 
 		if (SHADOW_ENABLED(wpd)) {
-			struct Gwn_Batch *geom_shadow = DRW_cache_mesh_wire_outline_get(ob);
+			struct Gwn_Batch *geom_shadow = DRW_cache_object_surface_get(ob);
 			if (geom_shadow) {
 				DRW_shgroup_call_object_add(wpd->shadow_shgrp, geom_shadow, ob);
 			}
@@ -508,7 +508,7 @@ void workbench_materials_draw_scene(WORKBENCH_Data *vedata)
 	GPU_framebuffer_bind(fbl->prepass_fb);
 	DRW_draw_pass(psl->prepass_pass);
 	if (SHADOW_ENABLED(wpd)) {
-#ifdef SHOW_SHADOW_VOLUME
+#ifdef DEBUG_SHADOW_VOLUME
 		GPU_framebuffer_bind(dfbl->default_fb);
 		DRW_draw_pass(psl->composite_pass);
 		DRW_draw_pass(psl->shadow_pass);
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index ba7a5f3e75a..7fd9030bc25 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -272,7 +272,7 @@ typedef enum {
 	DRW_STATE_WRITE_STENCIL          = (1 << 27),
 	DRW_STATE_STENCIL_EQUAL          = (1 << 28),
 	DRW_STATE_STENCIL_NEQUAL         = (1 << 29),
-	DRW_STATE_STENCIL_INCR_DECR_WRAP = (1 << 30),
+	DRW_STATE_STENCIL_DEPTH_FAIL_INCR_DECR_WRAP = (1 << 30),
 } DRWState;
 
 #define DRW_STATE_DEFAULT (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS)
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 4d063aedf7e..77b83ab4e99 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -275,7 +275,7 @@ void drw_state_set(DRWState state)
 		DRWState test;
 		if (CHANGED_ANY_STORE_VAR(
 		        DRW_STATE_WRITE_STENCIL |
-		        DRW_STATE_STENCIL_INCR_DECR_WRAP |
+		        DRW_STATE_STENCIL_DEPTH_FAIL_INCR_DECR_WRAP |
 		        DRW_STATE_STENCIL_EQUAL |
 		        DRW_STATE_STENCIL_NEQUAL,
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list