diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-08-23 14:35:10 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-08-23 14:56:39 +0300 |
commit | 55f122264c7faeedb4cdb1b3d1038ac3af28f6f2 (patch) | |
tree | f87c7fdfed0e599dc7130e1cae8f19b21a2e42f3 /source/blender/draw | |
parent | 0cbbcac23e47a686519b89c9cac7b2df2e4a4458 (diff) |
3D Grid: Fix grid passing through objects too much
For this we need to add a bias depending on the viewing angle.
But increasing the hardness of the test make float precision issues in
the mesh transformation more prominent (actual geometry is far below the
surface). So to solve this issue we use a more subdivided grid mesh
8x8 quads instead of 1 triangle.
Diffstat (limited to 'source/blender/draw')
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 43 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 1 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 8 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/object_grid_frag.glsl | 10 |
4 files changed, 53 insertions, 9 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 412ad72207e..03c3e1ff16e 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -53,6 +53,7 @@ static struct DRWShapeCache { GPUBatch *drw_fullscreen_quad; GPUBatch *drw_fullscreen_quad_texcoord; GPUBatch *drw_quad; + GPUBatch *drw_grid; GPUBatch *drw_sphere; GPUBatch *drw_screenspace_circle; GPUBatch *drw_plain_axes; @@ -322,6 +323,48 @@ GPUBatch *DRW_cache_quad_get(void) return SHC.drw_quad; } +/* Grid */ +GPUBatch *DRW_cache_grid_get(void) +{ + if (!SHC.drw_grid) { + /* Position Only 2D format */ + static GPUVertFormat format = { 0 }; + static struct { uint pos; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 8 * 8 * 2 * 3); + + uint v_idx = 0; + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + float pos0[2] = {(float)i / 8.0f, (float)j / 8.0f}; + float pos1[2] = {(float)(i+1) / 8.0f, (float)j / 8.0f}; + float pos2[2] = {(float)i / 8.0f, (float)(j+1) / 8.0f}; + float pos3[2] = {(float)(i+1) / 8.0f, (float)(j+1) / 8.0f}; + + madd_v2_v2v2fl(pos0, (float[2]){-1.0f, -1.0f}, pos0, 2.0f); + madd_v2_v2v2fl(pos1, (float[2]){-1.0f, -1.0f}, pos1, 2.0f); + madd_v2_v2v2fl(pos2, (float[2]){-1.0f, -1.0f}, pos2, 2.0f); + madd_v2_v2v2fl(pos3, (float[2]){-1.0f, -1.0f}, pos3, 2.0f); + + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos0); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos2); + + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos3); + } + } + + SHC.drw_grid = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); + } + return SHC.drw_grid; +} + /* Sphere */ GPUBatch *DRW_cache_sphere_get(void) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index eb75c685ec0..08c93010700 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -39,6 +39,7 @@ void DRW_shape_cache_reset(void); struct GPUBatch *DRW_cache_cursor_get(bool crosshair_lines); /* Common Shapes */ +struct GPUBatch *DRW_cache_grid_get(void); struct GPUBatch *DRW_cache_fullscreen_quad_get(void); struct GPUBatch *DRW_cache_quad_get(void); struct GPUBatch *DRW_cache_cube_get(void); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 934b9ada99f..3ae0bec77b2 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -1042,7 +1042,7 @@ static void OBJECT_cache_init(void *vedata) DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND; psl->grid = DRW_pass_create("Infinite Grid Pass", state); - struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *geom = DRW_cache_grid_get(); static float mat[4][4]; unit_m4(mat); @@ -1058,7 +1058,7 @@ static void OBJECT_cache_init(void *vedata) DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo); DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); - DRW_shgroup_call_add(grp, quad, mat); + DRW_shgroup_call_add(grp, geom, mat); grp = DRW_shgroup_create(e_data.grid_sh, psl->grid); DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.grid_flag, 1); @@ -1066,7 +1066,7 @@ static void OBJECT_cache_init(void *vedata) DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.grid_axes, 1); DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); - DRW_shgroup_call_add(grp, quad, mat); + DRW_shgroup_call_add(grp, geom, mat); grp = DRW_shgroup_create(e_data.grid_sh, psl->grid); DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zpos_flag, 1); @@ -1074,7 +1074,7 @@ static void OBJECT_cache_init(void *vedata) DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1); DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); - DRW_shgroup_call_add(grp, quad, mat); + DRW_shgroup_call_add(grp, geom, mat); } for (int i = 0; i < 2; ++i) { diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl index 82780e0cddc..06369e80c8d 100644 --- a/source/blender/draw/modes/shaders/object_grid_frag.glsl +++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl @@ -1,6 +1,6 @@ /* Infinite grid - * Clément Foucault */ + * Author: Clément Foucault */ out vec4 FragColor; @@ -209,6 +209,9 @@ void main() } } + /* Add a small bias so the grid will always + * be on top of a mesh with the same depth. */ + float grid_depth = gl_FragCoord.z - 6e-8 - fwidth(gl_FragCoord.z); float scene_depth = texture(depthBuffer, sPos).r; if ((gridFlag & GRID_BACK) != 0) { fade *= (scene_depth == 1.0) ? 1.0 : 0.0; @@ -217,12 +220,9 @@ void main() /* Manual, non hard, depth test: * Progressively fade the grid below occluders * (avoids poping visuals due to depth buffer precision) */ - /* Add a small bias so the grid will always - * be on top of a mesh with the same depth. */ - float grid_depth = gl_FragCoord.z - 1e-8; /* Harder settings tend to flicker more, * but have less "see through" appearance. */ - const float test_hardness = 1e4; + const float test_hardness = 1e7; fade *= 1.0 - clamp((grid_depth - scene_depth) * test_hardness, 0.0, 1.0); } |