[Bf-blender-cvs] [4137f30928] blender2.8: Object Mode: Add stencil test to remove object outlines inside the silouhette.

Clément Foucault noreply at git.blender.org
Sat Mar 18 02:07:44 CET 2017


Commit: 4137f30928dcfda4539d3d80df2c3e079eed12ec
Author: Clément Foucault
Date:   Sat Mar 18 01:55:41 2017 +0100
Branches: blender2.8
https://developer.blender.org/rB4137f30928dcfda4539d3d80df2c3e079eed12ec

Object Mode: Add stencil test to remove object outlines inside the silouhette.

It also adds nice occluded silouhette information for selected objects that are behind visible objects.
This methods is really heavy because it needs to render the wires twices.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/clay/clay.c
M	source/blender/draw/engines/eevee/eevee.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/draw/intern/draw_view.c
M	source/blender/draw/modes/edit_mesh_mode.c
M	source/blender/draw/modes/object_mode.c
A	source/blender/draw/modes/shaders/object_occluded_outline_frag.glsl

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 74e772958f..ec34e710c1 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -115,6 +115,7 @@ data_to_c_simple(modes/shaders/edit_overlay_facefill_vert.glsl SRC)
 data_to_c_simple(modes/shaders/edit_overlay_facefill_frag.glsl SRC)
 data_to_c_simple(modes/shaders/edit_normals_vert.glsl SRC)
 data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC)
+data_to_c_simple(modes/shaders/object_occluded_outline_frag.glsl SRC)
 
 list(APPEND INC
 )
diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c
index a91027cb31..a40805a50c 100644
--- a/source/blender/draw/engines/clay/clay.c
+++ b/source/blender/draw/engines/clay/clay.c
@@ -597,7 +597,11 @@ static DRWShadingGroup *CLAY_object_shgrp_get(Object *ob, CLAY_StorageList *stl,
 }
 
 static DRWShadingGroup *depth_shgrp;
+static DRWShadingGroup *depth_shgrp_select;
+static DRWShadingGroup *depth_shgrp_active;
 static DRWShadingGroup *depth_shgrp_cull;
+static DRWShadingGroup *depth_shgrp_cull_select;
+static DRWShadingGroup *depth_shgrp_cull_active;
 
 static void CLAY_cache_init(void)
 {
@@ -607,11 +611,23 @@ static void CLAY_cache_init(void)
 
 	/* Depth Pass */
 	{
-		psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
 		psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+		depth_shgrp = DRW_shgroup_create(data.depth_sh, psl->depth_pass);
+
+		depth_shgrp_select = DRW_shgroup_create(data.depth_sh, psl->depth_pass);
+		DRW_shgroup_state_set(depth_shgrp_select, DRW_STATE_WRITE_STENCIL_SELECT);
+
+		depth_shgrp_active = DRW_shgroup_create(data.depth_sh, psl->depth_pass);
+		DRW_shgroup_state_set(depth_shgrp_active, DRW_STATE_WRITE_STENCIL_ACTIVE);
 
+		psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
 		depth_shgrp_cull = DRW_shgroup_create(data.depth_sh, psl->depth_pass_cull);
-		depth_shgrp = DRW_shgroup_create(data.depth_sh, psl->depth_pass);
+
+		depth_shgrp_cull_select = DRW_shgroup_create(data.depth_sh, psl->depth_pass_cull);
+		DRW_shgroup_state_set(depth_shgrp_cull_select, DRW_STATE_WRITE_STENCIL_SELECT);
+
+		depth_shgrp_cull_active = DRW_shgroup_create(data.depth_sh, psl->depth_pass_cull);
+		DRW_shgroup_state_set(depth_shgrp_cull_active, DRW_STATE_WRITE_STENCIL_ACTIVE);
 	}
 
 	/* Clay Pass */
@@ -642,7 +658,13 @@ static void CLAY_cache_populate(Object *ob)
 		geom = DRW_cache_surface_get(ob);
 
 		/* Depth Prepass */
-		DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull : depth_shgrp, geom, ob->obmat);
+		/* waiting for proper flag */
+		// if ((ob->base_flag & BASE_ACTIVE) != 0)
+			// DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull_active : depth_shgrp_active, geom, ob->obmat);
+		if ((ob->base_flag & BASE_SELECTED) != 0)
+			DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull_select : depth_shgrp_select, geom, ob->obmat);
+		else
+			DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull : depth_shgrp, geom, ob->obmat);
 
 		/* Shading */
 		clay_shgrp = CLAY_object_shgrp_get(ob, stl, psl);
diff --git a/source/blender/draw/engines/eevee/eevee.c b/source/blender/draw/engines/eevee/eevee.c
index b4b461f583..c85e35c904 100644
--- a/source/blender/draw/engines/eevee/eevee.c
+++ b/source/blender/draw/engines/eevee/eevee.c
@@ -33,11 +33,18 @@
 /* *********** STATIC *********** */
 static struct {
 	struct GPUShader *default_lit;
+	struct GPUShader *depth_sh;
 	struct GPUShader *tonemap;
 } e_data = {NULL}; /* Engine data */
 
 static struct {
 	DRWShadingGroup *default_lit_grp;
+	DRWShadingGroup *depth_shgrp;
+	DRWShadingGroup *depth_shgrp_select;
+	DRWShadingGroup *depth_shgrp_active;
+	DRWShadingGroup *depth_shgrp_cull;
+	DRWShadingGroup *depth_shgrp_cull_select;
+	DRWShadingGroup *depth_shgrp_cull_active;
 	EEVEE_Data *vedata;
 } g_data = {NULL}; /* Transient data */
 
@@ -62,6 +69,10 @@ static void EEVEE_engine_init(void)
 	                    &tex, 1);
 
 	if (!e_data.default_lit) {
+		e_data.depth_sh = DRW_shader_create_3D_depth_only();
+	}
+
+	if (!e_data.default_lit) {
 		e_data.default_lit = DRW_shader_create(datatoc_lit_surface_vert_glsl, NULL, datatoc_lit_surface_frag_glsl, "#define MAX_LIGHT 128\n");
 	}
 
@@ -84,7 +95,27 @@ static void EEVEE_cache_init(void)
 	EEVEE_StorageList *stl = g_data.vedata->stl;
 
 	{
-		DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
+		psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+		g_data.depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
+
+		g_data.depth_shgrp_select = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
+		DRW_shgroup_state_set(g_data.depth_shgrp_select, DRW_STATE_WRITE_STENCIL_SELECT);
+
+		g_data.depth_shgrp_active = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
+		DRW_shgroup_state_set(g_data.depth_shgrp_active, DRW_STATE_WRITE_STENCIL_ACTIVE);
+
+		psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
+		g_data.depth_shgrp_cull = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull);
+
+		g_data.depth_shgrp_cull_select = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull);
+		DRW_shgroup_state_set(g_data.depth_shgrp_cull_select, DRW_STATE_WRITE_STENCIL_SELECT);
+
+		g_data.depth_shgrp_cull_active = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull);
+		DRW_shgroup_state_set(g_data.depth_shgrp_cull_active, DRW_STATE_WRITE_STENCIL_ACTIVE);
+	}
+
+	{
+		DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_EQUAL;
 		psl->pass = DRW_pass_create("Default Light Pass", state);
 
 		g_data.default_lit_grp = DRW_shgroup_create(e_data.default_lit, psl->pass);
@@ -112,8 +143,19 @@ static void EEVEE_cache_populate(Object *ob)
 	EEVEE_StorageList *stl = g_data.vedata->stl;
 
 	if (ob->type == OB_MESH) {
+		CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
+		bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
 		struct Batch *geom = DRW_cache_surface_get(ob);
 
+		/* Depth Prepass */
+		/* waiting for proper flag */
+		// if ((ob->base_flag & BASE_ACTIVE) != 0)
+			// DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull_active : depth_shgrp_active, geom, ob->obmat);
+		if ((ob->base_flag & BASE_SELECTED) != 0)
+			DRW_shgroup_call_add((do_cull) ? g_data.depth_shgrp_cull_select : g_data.depth_shgrp_select, geom, ob->obmat);
+		else
+			DRW_shgroup_call_add((do_cull) ? g_data.depth_shgrp_cull : g_data.depth_shgrp, geom, ob->obmat);
+
 		DRW_shgroup_call_add(g_data.default_lit_grp, geom, ob->obmat);
 	}
 	else if (ob->type == OB_LAMP) {
@@ -146,8 +188,10 @@ static void EEVEE_draw_scene(void)
 	/* Clear Depth */
 	/* TODO do background */
 	float clearcol[4] = {0.0f, 0.0f, 0.0f, 1.0f};
-	DRW_framebuffer_clear(true, true, clearcol, 1.0f);
+	DRW_framebuffer_clear(true, true, true, clearcol, 1.0f);
 
+	DRW_draw_pass(psl->depth_pass);
+	DRW_draw_pass(psl->depth_pass_cull);
 	DRW_draw_pass(psl->pass);
 
 	/* Restore default framebuffer */
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 4e96675771..4d8f697cc6 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -27,6 +27,8 @@ struct Object;
 
 /* keep it under MAX_PASSES */
 typedef struct EEVEE_PassList {
+	struct DRWPass *depth_pass;
+	struct DRWPass *depth_pass_cull;
 	struct DRWPass *pass;
 	struct DRWPass *tonemap;
 } EEVEE_PassList;
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 470f061ebe..0fcfa50f48 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -161,7 +161,7 @@ typedef struct DRWFboTexture {
 
 void DRW_framebuffer_init(struct GPUFrameBuffer **fb, int width, int height, DRWFboTexture textures[MAX_FBO_TEX], int texnbr);
 void DRW_framebuffer_bind(struct GPUFrameBuffer *fb);
-void DRW_framebuffer_clear(bool color, bool depth, float clear_col[4], float clear_depth);
+void DRW_framebuffer_clear(bool color, bool depth, bool stencil, float clear_col[4], float clear_depth);
 void DRW_framebuffer_texture_attach(struct GPUFrameBuffer *fb, struct GPUTexture *tex, int slot);
 void DRW_framebuffer_texture_detach(struct GPUTexture *tex);
 void DRW_framebuffer_blit(struct GPUFrameBuffer *fb_read, struct GPUFrameBuffer *fb_write, bool depth);
@@ -190,6 +190,11 @@ typedef enum {
 	DRW_STATE_STIPPLE_3     = (1 << 11),
 	DRW_STATE_STIPPLE_4     = (1 << 12),
 	DRW_STATE_BLEND         = (1 << 13),
+
+	DRW_STATE_WRITE_STENCIL_SELECT = (1 << 14),
+	DRW_STATE_WRITE_STENCIL_ACTIVE = (1 << 15),
+	DRW_STATE_TEST_STENCIL_SELECT  = (1 << 16),
+	DRW_STATE_TEST_STENCIL_ACTIVE  = (1 << 17),
 } DRWState;
 
 DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
@@ -230,7 +235,6 @@ typedef enum {
 
 void DRW_viewport_init(const bContext *C);
 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type);
-void DRW_viewport_engine_data_set(const char *engine_name, void *fbl, void *txl, void *psl,	void *stl);
 void *DRW_viewport_engine_data_get(const char *engine_name);
 float *DRW_viewport_size_get(void);
 float *DRW_viewport_screenvecs_get(void);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 26ab09fe48..6b7fe00dba 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -148,7 +148,7 @@ struct DRWShadingGroup {
 	struct GPUShader *shader;        /* Shader to bind */
 	struct DRWInterface *interface;  /* Uniforms pointers */
 	ListBase calls;                  /* DRWCall or DRWDynamicCall depending of type*/
-	int state;                       /* State changes for this batch only */
+	DRWState state;                  /* State changes for this batch only */
 	int 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list