Clay Engine: Replace Manual depth test by depth copy.
This avoid glitches due to float comparison precision.
This commit is contained in:
parent
bdd3fd64e9
commit
f9e4d8e93a
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue