[Bf-blender-cvs] [f9e4d8e93a] blender2.8: Clay Engine: Replace Manual depth test by depth copy.

Clément Foucault noreply at git.blender.org
Wed Feb 15 15:17:52 CET 2017


Commit: f9e4d8e93a0c2706c69f2656fa673daa74bdb165
Author: Clément Foucault
Date:   Wed Feb 15 15:15:42 2017 +0100
Branches: blender2.8
https://developer.blender.org/rBf9e4d8e93a0c2706c69f2656fa673daa74bdb165

Clay Engine: Replace Manual depth test by depth copy.

This avoid glitches due to float comparison precision.

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

M	source/blender/draw/engines/clay/clay.c
M	source/blender/draw/engines/clay/shaders/clay_frag.glsl
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/gpu/GPU_framebuffer.h
M	source/blender/gpu/intern/gpu_framebuffer.c

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

diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c
index efaec22c77..8c0dce78b8 100644
--- a/source/blender/draw/engines/clay/clay.c
+++ b/source/blender/draw/engines/clay/clay.c
@@ -105,7 +105,7 @@ typedef struct CLAY_FramebufferList{
 	/* default */
 	struct GPUFrameBuffer *default_fb;
 	/* engine specific */
-	struct GPUFrameBuffer *downsample_depth;
+	struct GPUFrameBuffer *dupli_depth;
 } CLAY_FramebufferList;
 
 /* keep it under MAX_TEXTURES */
@@ -114,14 +114,14 @@ typedef struct CLAY_TextureList{
 	struct GPUTexture *color;
 	struct GPUTexture *depth;
 	/* engine specific */
-	struct GPUTexture *depth_low;
+	struct GPUTexture *depth_dup;
 } CLAY_TextureList;
 
 /* for clarity follow the same layout as CLAY_TextureList */
 enum {
 	SCENE_COLOR,
 	SCENE_DEPTH,
-	SCENE_DEPTH_LOW,
+	SCENE_DEPTH_DUP,
 };
 
 /* keep it under MAX_PASSES */
@@ -283,7 +283,7 @@ MaterialEngineSettings *CLAY_material_settings_create(void)
 	return (MaterialEngineSettings *)settings;
 }
 
-static void CLAY_engine_init(CLAY_StorageList *stl)
+static void CLAY_engine_init(CLAY_StorageList *stl, CLAY_TextureList *txl, CLAY_FramebufferList *fbl)
 {
 	/* Create Texture Array */
 	if (!data.matcap_array) {
@@ -373,6 +373,14 @@ static void CLAY_engine_init(CLAY_StorageList *stl)
 			ubo_mat_idxs[i] = i;
 		}
 	}
+
+	{
+		float *viewport_size = DRW_viewport_size_get();
+		DRWFboTexture tex = {&txl->depth_dup, DRW_BUF_DEPTH_24};
+		DRW_framebuffer_init(&fbl->dupli_depth,
+		                     (int)viewport_size[0], (int)viewport_size[1],
+		                     &tex, 1);
+	}
 }
 
 static void CLAY_ssao_setup(void)
@@ -434,7 +442,7 @@ static DRWShadingGroup *CLAY_shgroup_create(DRWPass *pass, int *material_id)
 	DRWShadingGroup *grp = DRW_shgroup_create(data.clay_sh, pass);
 
 	DRW_shgroup_uniform_vec2(grp, "screenres", DRW_viewport_size_get(), 1);
-	DRW_shgroup_uniform_buffer(grp, "depthtex", SCENE_DEPTH, depthloc);
+	DRW_shgroup_uniform_buffer(grp, "depthtex", SCENE_DEPTH_DUP, depthloc);
 	DRW_shgroup_uniform_texture(grp, "matcaps", data.matcap_array, matcaploc);
 	DRW_shgroup_uniform_mat4(grp, "WinMatrix", (float *)data.winmat);
 	DRW_shgroup_uniform_vec4(grp, "viewvecs", (float *)data.viewvecs, 3);
@@ -609,7 +617,7 @@ static void CLAY_create_cache(CLAY_PassList *passes, CLAY_StorageList *stl, cons
 
 	/* Clay Pass */
 	{
-		passes->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR);
+		passes->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
 		stl->storage->ubo_current_id = 0;
 	}
 
@@ -629,7 +637,7 @@ static void CLAY_create_cache(CLAY_PassList *passes, CLAY_StorageList *stl, cons
 		}
 
 		struct Batch *geom;
-		//bool do_outlines;
+		bool do_outlines;
 
 		switch (ob->type) {
 			case OB_MESH:
@@ -644,8 +652,8 @@ static void CLAY_create_cache(CLAY_PassList *passes, CLAY_StorageList *stl, cons
 
 				//DRW_shgroup_wire_overlay(passes->wire_overlay_pass, ob);
 
-				//do_outlines  = ((ob->base_flag & BASE_SELECTED) != 0);
-				//DRW_shgroup_wire_outline(passes->wire_outline_pass, ob, false, false, do_outlines);
+				do_outlines  = ((ob->base_flag & BASE_SELECTED) != 0);
+				DRW_shgroup_wire_outline(passes->wire_outline_pass, ob, false, false, do_outlines);
 
 				/* When encountering a new material :
 				 * - Create new Batch
@@ -683,7 +691,8 @@ static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context
 
 	DRW_viewport_init(context, (void **)&buffers, (void **)&textures, (void **)&passes, (void **)&storage);
 
-	CLAY_engine_init(storage);
+	CLAY_engine_init(storage, textures, buffers);
+
 
 	/* TODO : tag to refresh by the deps graph */
 	/* ideally only refresh when objects are added/removed */
@@ -708,20 +717,18 @@ static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context
 	/* Pass 1 : Depth pre-pass */
 	DRW_draw_pass(passes->depth_pass);
 
-	/* Pass 2 (Optionnal) : Separated Downsampled AO */
-	DRW_framebuffer_texture_detach(textures->depth);
-	/* TODO */
+	/* Pass 2 : Duplicate depth */
+	/* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */
+	DRW_framebuffer_blit(buffers->default_fb, buffers->dupli_depth, true);
 
 	/* Pass 3 : Shading */
 	CLAY_ssao_setup();
 	DRW_draw_pass(passes->clay_pass);
 
 	/* Pass 4 : Overlays */
-	DRW_framebuffer_texture_attach(buffers->default_fb, textures->depth, 0);
-
 	DRW_draw_grid();
 	//DRW_draw_pass(passes->wire_overlay_pass);
-	//DRW_draw_pass(passes->wire_outline_pass);
+	DRW_draw_pass(passes->wire_outline_pass);
 	DRW_draw_pass(passes->non_meshes_pass);
 	DRW_draw_pass(passes->ob_center_pass);
 
diff --git a/source/blender/draw/engines/clay/shaders/clay_frag.glsl b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
index c1fe2df531..35d803dc9e 100644
--- a/source/blender/draw/engines/clay/shaders/clay_frag.glsl
+++ b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
@@ -160,10 +160,6 @@ void main() {
 	vec2 screenco = vec2(gl_FragCoord.xy) / screenres;
 	float depth = texture(depthtex, screenco).r;
 
-	/* Manual Depth test */
-	if (gl_FragCoord.z > depth + 1e-5)
-		discard;
-
 	vec3 position = get_view_space_from_depth(screenco, depth);
 
 #ifdef USE_ROTATION
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 775ae1c6e3..ae278b612f 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -135,6 +135,7 @@ void DRW_framebuffer_init(struct GPUFrameBuffer **fb, int width, int height, DRW
 void DRW_framebuffer_bind(struct GPUFrameBuffer *fb);
 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);
 /* Shaders */
 struct GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, const char *defines);
 struct GPUShader *DRW_shader_create_2D(const char *frag, const char *defines);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 18bd26daf8..c265f57297 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1133,6 +1133,11 @@ void DRW_framebuffer_texture_detach(GPUTexture *tex)
 	GPU_framebuffer_texture_detach(tex);
 }
 
+void DRW_framebuffer_blit(struct GPUFrameBuffer *fb_read, struct GPUFrameBuffer *fb_write, bool depth)
+{
+	GPU_framebuffer_blit(fb_read, 0, fb_write, 0, depth);
+}
+
 /* ****************************************** Viewport ******************************************/
 
 float *DRW_viewport_size_get(void)
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index 9611a6f057..15617832c9 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -67,6 +67,10 @@ void GPU_framebuffer_blur(
         GPUFrameBuffer *fb, struct GPUTexture *tex,
         GPUFrameBuffer *blurfb, struct GPUTexture *blurtex);
 
+void GPU_framebuffer_blit(
+        GPUFrameBuffer *fb_read, int read_slot,
+        GPUFrameBuffer *fb_write, int write_slot, bool use_depth);
+
 /* GPU OffScreen
  * - wrapper around framebuffer and texture for simple offscreen drawing
  * - changes size if graphics card can't support it */
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 1efc451f4a..3b44abb479 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -448,6 +448,40 @@ void GPU_framebuffer_blur(
 	GPU_shader_unbind();
 }
 
+void GPU_framebuffer_blit(GPUFrameBuffer *fb_read, int read_slot, GPUFrameBuffer *fb_write, int write_slot, bool use_depth)
+{
+	GPUTexture *read_tex = (use_depth) ? fb_read->depthtex : fb_read->colortex[read_slot];
+	GPUTexture *write_tex = (use_depth) ? fb_write->depthtex : fb_write->colortex[write_slot];
+	int read_attach = (use_depth) ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0 + GPU_texture_framebuffer_attachment(read_tex);
+	int write_attach = (use_depth) ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0 + GPU_texture_framebuffer_attachment(write_tex);
+	int read_bind = GPU_texture_opengl_bindcode(read_tex);
+	int write_bind = GPU_texture_opengl_bindcode(write_tex);
+	const int read_w = GPU_texture_width(read_tex);
+	const int read_h = GPU_texture_height(read_tex);
+	const int write_w = GPU_texture_width(write_tex);
+	const int write_h = GPU_texture_height(write_tex);
+
+	/* read from multi-sample buffer */
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, fb_read->object);
+	glFramebufferTexture2D(
+	        GL_READ_FRAMEBUFFER, read_attach,
+	        GL_TEXTURE_2D, read_bind, 0);
+	BLI_assert(glCheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+
+	/* write into new single-sample buffer */
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_write->object);
+	glFramebufferTexture2D(
+	        GL_DRAW_FRAMEBUFFER, write_attach,
+	        GL_TEXTURE_2D, write_bind, 0);
+	BLI_assert(glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+
+	glBlitFramebuffer(0, 0, read_w, read_h, 0, 0, write_w, write_h, (use_depth) ? GL_DEPTH_BUFFER_BIT : GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+	/* Restore previous framebuffer */
+	glBindFramebuffer(GL_FRAMEBUFFER, GG.currentfb);
+	glDrawBuffer(GL_COLOR_ATTACHMENT0);
+}
+
 /* GPUOffScreen */
 
 struct GPUOffScreen {




More information about the Bf-blender-cvs mailing list