diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-02-15 17:15:42 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-02-15 17:16:06 +0300 |
commit | f9e4d8e93a0c2706c69f2656fa673daa74bdb165 (patch) | |
tree | f02cb6e9bdf8fe2bc6a6596a1ffe68417e644b0a | |
parent | bdd3fd64e94460ad76c88e68d2c9c50778ef90b2 (diff) |
Clay Engine: Replace Manual depth test by depth copy.
This avoid glitches due to float comparison precision.
-rw-r--r-- | source/blender/draw/engines/clay/clay.c | 39 | ||||
-rw-r--r-- | source/blender/draw/engines/clay/shaders/clay_frag.glsl | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 5 | ||||
-rw-r--r-- | source/blender/gpu/GPU_framebuffer.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_framebuffer.c | 34 |
6 files changed, 67 insertions, 20 deletions
diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c index efaec22c77c..8c0dce78b80 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 c1fe2df5318..35d803dc9ef 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 775ae1c6e30..ae278b612fc 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 18bd26daf8b..c265f57297f 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 9611a6f0577..15617832c9b 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 1efc451f4a8..3b44abb479c 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 { |