[Bf-blender-cvs] [9b6778271e5] blender2.8-workbench: Workbench: Shadows (WIP)

Jeroen Bakker noreply at git.blender.org
Mon Apr 30 17:03:02 CEST 2018


Commit: 9b6778271e54029b6081cfe54cef5fb299772118
Author: Jeroen Bakker
Date:   Mon Apr 30 17:02:34 2018 +0200
Branches: blender2.8-workbench
https://developer.blender.org/rB9b6778271e54029b6081cfe54cef5fb299772118

Workbench: Shadows (WIP)

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

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/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager_exec.c

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

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 6312ca20bcf..00caed91285 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
@@ -1,25 +1,43 @@
+#define EPSILON 0.0000001
+
 layout(lines) in;
 layout(triangle_strip, max_vertices=4) out;
 
-uniform vec4 lightDirection = vec4(-4.0, -25.0, 0.0, 0.0);
-uniform vec3 lightDirection2 = vec3(0.57, 0.57, 0.57);
+uniform mat4 ViewProjectionMatrix;
+
+uniform vec3 lightDirection = vec3(0.57, -0.57, -0.57);
 in vec3 faceNormal1[]; 
 in vec3 faceNormal2[];
+in vec3 localPos[];
 
+void emit_quad(vec3 start_vertex, vec3 end_vertex, vec3 light_direction) {
+	gl_Position = ViewProjectionMatrix * vec4((start_vertex + light_direction * EPSILON), 1.0);
+	EmitVertex();
+	gl_Position = ViewProjectionMatrix * vec4((start_vertex + light_direction * 25.0), 1.0);
+	EmitVertex();
+	gl_Position = ViewProjectionMatrix * vec4((end_vertex + light_direction * EPSILON), 1.0);
+	EmitVertex();
+	gl_Position = ViewProjectionMatrix * vec4((end_vertex + light_direction * 25.0), 1.0);
+	EmitVertex();
+	EndPrimitive();
+}
 void main()
 {
-	bool front1 = dot(faceNormal1[0], lightDirection2) >= 0;
-	bool front2 = dot(faceNormal2[1], lightDirection2) >= 0;
+	/* 
+		TODO: light is currently connected to the object.
+		multiply with inverse object matrix to get to counteracti this.
+		or fo not use the modelviewprojectionmatrix (but the ViewProjectionMatrix)
+		
+		Should the faceNormal and local pos not be done in the vertex shader (conversion to world coordinates...)
+	*/
+	vec3 light_direction = lightDirection;
+	bool front1 = dot(faceNormal1[0], normalize(light_direction)) >= 0;
+	bool front2 = dot(faceNormal2[1], normalize(light_direction)) >= 0;
 
-	if (front1 != front2) {
-		gl_Position = gl_in[0].gl_Position;
-		EmitVertex();
-		gl_Position = gl_in[1].gl_Position;
-		EmitVertex();
-		gl_Position = gl_in[0].gl_Position + lightDirection;
-		EmitVertex();
-		gl_Position = gl_in[1].gl_Position + lightDirection;
-		EmitVertex();
-		EndPrimitive();
+	if (!front1 && front2) {
+		emit_quad(gl_in[0].gl_Position.xyz, gl_in[1].gl_Position.xyz, light_direction);
+	}
+	else if (front1 && !front2) {
+		emit_quad(gl_in[1].gl_Position.xyz, gl_in[0].gl_Position.xyz, light_direction);
 	}
 }
\ No newline at end of file
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 3e8812a4431..74ed0265690 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
@@ -1,5 +1,3 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat3 NormalMatrix;
 in vec3 pos;
 in vec3 N1;
 in vec3 N2;
@@ -7,7 +5,7 @@ out vec3 faceNormal1;
 out vec3 faceNormal2;
 void main()
 {
-	gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
-	faceNormal1 = NormalMatrix * N1;
-	faceNormal2 = NormalMatrix * N2;
+	faceNormal1 = N1;
+	faceNormal2 = N2;
+	gl_Position = vec4(pos, 1.0);
 }
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 714421ff529..8aa2d3fe914 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -316,14 +316,14 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
 
 		if (SHADOW_ENABLED(wpd)) {
 			psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL);
+			// DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_INCR_DECR_WRAP
 			grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
 			DRW_shgroup_stencil_mask(grp, 0x01);
 			wpd->shadow_shgrp = grp;
-			// DRW_shgroup_call_add(grp, DRW_cache_quad_get(), NULL);
 
-			psl->composite_shadow_pass = DRW_pass_create("Composite Shadow", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
+			psl->composite_shadow_pass = DRW_pass_create("Composite Shadow", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL);
 			grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_shadow_pass);
-			DRW_shgroup_stencil_mask(grp, 0x01);
+			DRW_shgroup_stencil_mask(grp, 0x00);
 			workbench_composite_uniforms(wpd, grp);
 			DRW_shgroup_uniform_float(grp, "lightMultiplier", &e_data.shadow_multiplier, 1);
 			DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
@@ -443,7 +443,7 @@ void workbench_materials_draw_background(WORKBENCH_Data *vedata)
 	WORKBENCH_PrivateData *wpd = stl->g_data;
 	const float clear_depth = 1.0f;
 	const float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-	unsigned int clear_stencil = 0x01;
+	unsigned int clear_stencil = 0xFF;
 
 	GPU_framebuffer_bind(fbl->prepass_fb);
 	int clear_bits = GPU_DEPTH_BIT;
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index e287bcc99df..6386cccd4d0 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -295,8 +295,10 @@ typedef enum {
 	DRW_STATE_CLIP_PLANES   = (1 << 18),
 	DRW_STATE_ADDITIVE_FULL = (1 << 19), /* Same as DRW_STATE_ADDITIVE but let alpha accumulate without premult. */
 
-	DRW_STATE_WRITE_STENCIL    = (1 << 27),
-	DRW_STATE_STENCIL_EQUAL    = (1 << 28),
+	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),
 } 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 9aa5efc837d..62826b9289c 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -275,7 +275,9 @@ void drw_state_set(DRWState state)
 		DRWState test;
 		if (CHANGED_ANY_STORE_VAR(
 		        DRW_STATE_WRITE_STENCIL |
-		        DRW_STATE_STENCIL_EQUAL,
+		        DRW_STATE_STENCIL_INCR_DECR_WRAP |
+		        DRW_STATE_STENCIL_EQUAL |
+		        DRW_STATE_STENCIL_NEQUAL,
 		        test))
 		{
 			if (test) {
@@ -283,14 +285,25 @@ void drw_state_set(DRWState state)
 
 				/* Stencil Write */
 				if ((state & DRW_STATE_WRITE_STENCIL) != 0) {
-					glStencilMask(0xFF);
-					glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+					if ((state & DRW_STATE_STENCIL_INCR_DECR_WRAP) != 0) {
+						glStencilMask(0xFF);
+						glStencilOpSeparate(GL_BACK,  GL_KEEP, GL_INCR_WRAP, GL_KEEP);
+						glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
+					}
+					else {
+						glStencilMask(0xFF);
+						glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+					}
 				}
 				/* Stencil Test */
 				else if ((state & DRW_STATE_STENCIL_EQUAL) != 0) {
 					glStencilMask(0x00); /* disable write */
 					DST.stencil_mask = 0;
 				}
+				else if ((state & DRW_STATE_STENCIL_NEQUAL) != 0) {
+					glStencilMask(0x00); /* disable write */
+					DST.stencil_mask = 0;
+				}
 				else {
 					BLI_assert(0);
 				}
@@ -314,7 +327,10 @@ void drw_state_set(DRWState state)
 
 static void drw_stencil_set(unsigned int mask)
 {
-	if (DST.stencil_mask != mask) {
+	/* NOTE: need to ask to hypersomniac: Why check for difference? when mask is set to 0 it will not work.? 
+	  Should we remove the test?
+	*/
+	if (DST.stencil_mask != mask || (DST.state & DRW_STATE_STENCIL_NEQUAL) != 0) {
 		/* Stencil Write */
 		if ((DST.state & DRW_STATE_WRITE_STENCIL) != 0) {
 			glStencilFunc(GL_ALWAYS, mask, 0xFF);
@@ -325,6 +341,10 @@ static void drw_stencil_set(unsigned int mask)
 			glStencilFunc(GL_EQUAL, mask, 0xFF);
 			DST.stencil_mask = mask;
 		}
+		else if ((DST.state & DRW_STATE_STENCIL_NEQUAL) != 0) {
+			glStencilFunc(GL_NOTEQUAL, mask, 0xFF);
+			DST.stencil_mask = mask;
+		}
 	}
 }



More information about the Bf-blender-cvs mailing list