diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-04-28 22:13:04 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-04-28 22:13:04 +0300 |
commit | 308a12ac647d6f9b4ef2b6c403903e0aeb65a571 (patch) | |
tree | d327529eb93340033a3adddd95d28c92f75b1b69 /source/blender | |
parent | 3d9f0280ff1bc308aa31e95af6b1726f1b497111 (diff) |
Overlay: Port Grid shader to shaderCreateInfo and other code cleanup
Along with the port to createInfo this also:
- Packs constant uniforms in a UBO.
- Share enum declaration and unify names
- Makes codeflow easier to undestand.
- Split grid data to its own struct.
# Conflicts:
# source/blender/draw/engines/overlay/overlay_grid.c
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/overlay_engine.c | 14 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/overlay_grid.c | 356 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/overlay_private.h | 26 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/overlay_shader.c | 11 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/overlay_shader_shared.h | 47 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/shaders/grid_frag.glsl | 227 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/shaders/grid_vert.glsl | 36 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/shaders/infos/grid_info.hh | 20 | ||||
-rw-r--r-- | source/blender/gpu/CMakeLists.txt | 1 |
10 files changed, 386 insertions, 354 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 8c54c923476..beae1c92d6e 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -521,6 +521,8 @@ set(GLSL_SRC engines/overlay/shaders/wireframe_frag.glsl engines/overlay/shaders/xray_fade_frag.glsl + engines/overlay/overlay_shader_shared.h + engines/image/shaders/image_engine_color_frag.glsl engines/image/shaders/image_engine_color_vert.glsl engines/image/shaders/image_engine_depth_frag.glsl diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c index 64bd34c2a23..16f69adc813 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.c +++ b/source/blender/draw/engines/overlay/overlay_engine.c @@ -45,6 +45,11 @@ static void OVERLAY_engine_init(void *vedata) stl->pd = MEM_callocN(sizeof(*stl->pd), __func__); } + /* Allocate instance. */ + if (data->instance == NULL) { + data->instance = MEM_callocN(sizeof(*data->instance), __func__); + } + OVERLAY_PrivateData *pd = stl->pd; pd->space_type = v3d != NULL ? SPACE_VIEW3D : draw_ctx->space_data->spacetype; @@ -695,6 +700,13 @@ static void OVERLAY_engine_free(void) OVERLAY_shader_free(); } +static void OVERLAY_instance_free(void *instance_) +{ + OVERLAY_Instance *instance = (OVERLAY_Instance *)instance_; + DRW_UBO_FREE_SAFE(instance->grid_ubo); + MEM_freeN(instance); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -710,7 +722,7 @@ DrawEngineType draw_engine_overlay_type = { &overlay_data_size, &OVERLAY_engine_init, &OVERLAY_engine_free, - NULL, /* instance_free */ + &OVERLAY_instance_free, &OVERLAY_cache_init, &OVERLAY_cache_populate, &OVERLAY_cache_finish, diff --git a/source/blender/draw/engines/overlay/overlay_grid.c b/source/blender/draw/engines/overlay/overlay_grid.c index 3d42765a5e5..55013d0429b 100644 --- a/source/blender/draw/engines/overlay/overlay_grid.c +++ b/source/blender/draw/engines/overlay/overlay_grid.c @@ -19,32 +19,22 @@ #include "overlay_private.h" -enum { - SHOW_AXIS_X = (1 << 0), - SHOW_AXIS_Y = (1 << 1), - SHOW_AXIS_Z = (1 << 2), - SHOW_GRID = (1 << 3), - PLANE_XY = (1 << 4), - PLANE_XZ = (1 << 5), - PLANE_YZ = (1 << 6), - CLIP_ZPOS = (1 << 7), - CLIP_ZNEG = (1 << 8), - GRID_BACK = (1 << 9), - GRID_CAMERA = (1 << 10), - PLANE_IMAGE = (1 << 11), - CUSTOM_GRID = (1 << 12), -}; +BLI_STATIC_ASSERT(SI_GRID_STEPS_LEN == OVERLAY_GRID_STEPS_LEN, "") void OVERLAY_grid_init(OVERLAY_Data *vedata) { OVERLAY_PrivateData *pd = vedata->stl->pd; - OVERLAY_ShadingData *shd = &pd->shdata; + OVERLAY_GridData *grid = &pd->grid_data; const DRWContextState *draw_ctx = DRW_context_state_get(); - shd->grid_flag = 0; - shd->zneg_flag = 0; - shd->zpos_flag = 0; - shd->grid_line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f; + float *grid_axes = pd->grid.grid_axes; + float *zplane_axes = pd->grid.zplane_axes; + float grid_steps[SI_GRID_STEPS_LEN] = { + 0.001f, 0.01f, 0.1f, 1.0f, 10.0f, 100.0f, 1000.0f, 10000.0f}; + OVERLAY_GridBits grid_flag = 0, zneg_flag = 0, zpos_flag = 0; + grid->line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f; + /* Default, nothing is drawn. */ + pd->grid.grid_flag = pd->grid.zneg_flag = pd->grid.zpos_flag = 0; if (pd->space_type == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; @@ -58,231 +48,233 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata) SI_OVERLAY_SHOW_GRID_BACKGROUND) != 0) : true; if (background_enabled) { - shd->grid_flag = GRID_BACK | PLANE_IMAGE; + grid_flag = GRID_BACK | PLANE_IMAGE; } const bool draw_grid = is_uv_edit || !ED_space_image_has_buffer(sima); if (background_enabled && draw_grid) { - shd->grid_flag |= SHOW_GRID; + grid_flag |= SHOW_GRID; if (is_uv_edit && (sima->flag & SI_CUSTOM_GRID) != 0) { - shd->grid_flag |= CUSTOM_GRID; + grid_flag |= CUSTOM_GRID; } } - shd->grid_distance = 1.0f; - copy_v3_fl3(shd->grid_size, 1.0f, 1.0f, 1.0f); + grid->distance = 1.0f; + copy_v3_fl3(grid->size, 1.0f, 1.0f, 1.0f); if (is_uv_edit) { - shd->grid_size[0] = (float)sima->tile_grid_shape[0]; - shd->grid_size[1] = (float)sima->tile_grid_shape[1]; + grid->size[0] = (float)sima->tile_grid_shape[0]; + grid->size[1] = (float)sima->tile_grid_shape[1]; } - const int grid_size = SI_GRID_STEPS_LEN; - shd->zoom_factor = ED_space_image_zoom_level(v2d, grid_size); - ED_space_image_grid_steps(sima, shd->grid_steps, grid_size); - - return; - } - - View3D *v3d = draw_ctx->v3d; - Scene *scene = draw_ctx->scene; - RegionView3D *rv3d = draw_ctx->rv3d; - - const bool show_axis_x = (pd->v3d_gridflag & V3D_SHOW_X) != 0; - const bool show_axis_y = (pd->v3d_gridflag & V3D_SHOW_Y) != 0; - const bool show_axis_z = (pd->v3d_gridflag & V3D_SHOW_Z) != 0; - const bool show_floor = (pd->v3d_gridflag & V3D_SHOW_FLOOR) != 0; - const bool show_ortho_grid = (pd->v3d_gridflag & V3D_SHOW_ORTHO_GRID) != 0; - - if (pd->hide_overlays || !(pd->v3d_gridflag & (V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z | - V3D_SHOW_FLOOR | V3D_SHOW_ORTHO_GRID))) { - return; - } - - float viewinv[4][4], wininv[4][4]; - float viewmat[4][4], winmat[4][4]; - DRW_view_winmat_get(NULL, winmat, false); - DRW_view_winmat_get(NULL, wininv, true); - DRW_view_viewmat_get(NULL, viewmat, false); - DRW_view_viewmat_get(NULL, viewinv, true); - - /* If perspective view or non-axis aligned view. */ - if (winmat[3][3] == 0.0f || rv3d->view == RV3D_VIEW_USER) { - if (show_axis_x) { - shd->grid_flag |= PLANE_XY | SHOW_AXIS_X; - } - if (show_axis_y) { - shd->grid_flag |= PLANE_XY | SHOW_AXIS_Y; - } - if (show_floor) { - shd->grid_flag |= PLANE_XY | SHOW_GRID; - } + grid->zoom_factor = ED_space_image_zoom_level(v2d, SI_GRID_STEPS_LEN); + ED_space_image_grid_steps(sima, grid_steps, SI_GRID_STEPS_LEN); } else { - if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) { - shd->grid_flag = PLANE_YZ | SHOW_AXIS_Y | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK; + /* SPACE_VIEW3D */ + View3D *v3d = draw_ctx->v3d; + Scene *scene = draw_ctx->scene; + RegionView3D *rv3d = draw_ctx->rv3d; + + const bool show_axis_x = (pd->v3d_gridflag & V3D_SHOW_X) != 0; + const bool show_axis_y = (pd->v3d_gridflag & V3D_SHOW_Y) != 0; + const bool show_axis_z = (pd->v3d_gridflag & V3D_SHOW_Z) != 0; + const bool show_floor = (pd->v3d_gridflag & V3D_SHOW_FLOOR) != 0; + const bool show_ortho_grid = (pd->v3d_gridflag & V3D_SHOW_ORTHO_GRID) != 0; + + if (pd->hide_overlays || !(pd->v3d_gridflag & (V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z | + V3D_SHOW_FLOOR | V3D_SHOW_ORTHO_GRID))) { + return; } - else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) { - shd->grid_flag = PLANE_XY | SHOW_AXIS_X | SHOW_AXIS_Y | SHOW_GRID | GRID_BACK; + + float viewinv[4][4], wininv[4][4]; + float viewmat[4][4], winmat[4][4]; + DRW_view_winmat_get(NULL, winmat, false); + DRW_view_winmat_get(NULL, wininv, true); + DRW_view_viewmat_get(NULL, viewmat, false); + DRW_view_viewmat_get(NULL, viewinv, true); + + /* If perspective view or non-axis aligned view. */ + if (winmat[3][3] == 0.0f || rv3d->view == RV3D_VIEW_USER) { + if (show_axis_x) { + grid_flag |= PLANE_XY | SHOW_AXIS_X; + } + if (show_axis_y) { + grid_flag |= PLANE_XY | SHOW_AXIS_Y; + } + if (show_floor) { + grid_flag |= PLANE_XY | SHOW_GRID; + } } - else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) { - shd->grid_flag = PLANE_XZ | SHOW_AXIS_X | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK; + else { + if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) { + grid_flag = PLANE_YZ | SHOW_AXIS_Y | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK; + } + else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) { + grid_flag = PLANE_XY | SHOW_AXIS_X | SHOW_AXIS_Y | SHOW_GRID | GRID_BACK; + } + else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) { + grid_flag = PLANE_XZ | SHOW_AXIS_X | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK; + } } - } - shd->grid_axes[0] = (float)((shd->grid_flag & (PLANE_XZ | PLANE_XY)) != 0); - shd->grid_axes[1] = (float)((shd->grid_flag & (PLANE_YZ | PLANE_XY)) != 0); - shd->grid_axes[2] = (float)((shd->grid_flag & (PLANE_YZ | PLANE_XZ)) != 0); + grid_axes[0] = (float)((grid_flag & (PLANE_XZ | PLANE_XY)) != 0); + grid_axes[1] = (float)((grid_flag & (PLANE_YZ | PLANE_XY)) != 0); + grid_axes[2] = (float)((grid_flag & (PLANE_YZ | PLANE_XZ)) != 0); - /* Z axis if needed */ - if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) { - shd->zpos_flag = SHOW_AXIS_Z; + /* Z axis if needed */ + if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) { + zpos_flag = SHOW_AXIS_Z; - float zvec[3], campos[3]; - negate_v3_v3(zvec, viewinv[2]); - copy_v3_v3(campos, viewinv[3]); + float zvec[3], campos[3]; + negate_v3_v3(zvec, viewinv[2]); + copy_v3_v3(campos, viewinv[3]); + + /* z axis : chose the most facing plane */ + if (fabsf(zvec[0]) < fabsf(zvec[1])) { + zpos_flag |= PLANE_XZ; + } + else { + zpos_flag |= PLANE_YZ; + } + + zneg_flag = zpos_flag; + + /* Persp : If camera is below floor plane, we switch clipping + * Ortho : If eye vector is looking up, we switch clipping */ + if (((winmat[3][3] == 0.0f) && (campos[2] > 0.0f)) || + ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) { + zpos_flag |= CLIP_ZPOS; + zneg_flag |= CLIP_ZNEG; + } + else { + zpos_flag |= CLIP_ZNEG; + zneg_flag |= CLIP_ZPOS; + } - /* z axis : chose the most facing plane */ - if (fabsf(zvec[0]) < fabsf(zvec[1])) { - shd->zpos_flag |= PLANE_XZ; + zplane_axes[0] = (float)((zpos_flag & (PLANE_XZ | PLANE_XY)) != 0); + zplane_axes[1] = (float)((zpos_flag & (PLANE_YZ | PLANE_XY)) != 0); + zplane_axes[2] = (float)((zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0); } else { - shd->zpos_flag |= PLANE_YZ; + zneg_flag = zpos_flag = CLIP_ZNEG | CLIP_ZPOS; } - shd->zneg_flag = shd->zpos_flag; + float dist; + if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) { + Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera); + dist = ((Camera *)(camera_object->data))->clip_end; + grid_flag |= GRID_CAMERA; + zneg_flag |= GRID_CAMERA; + zpos_flag |= GRID_CAMERA; + } + else { + dist = v3d->clip_end; + } - /* Persp : If camera is below floor plane, we switch clipping - * Ortho : If eye vector is looking up, we switch clipping */ - if (((winmat[3][3] == 0.0f) && (campos[2] > 0.0f)) || - ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) { - shd->zpos_flag |= CLIP_ZPOS; - shd->zneg_flag |= CLIP_ZNEG; + if (winmat[3][3] == 0.0f) { + copy_v3_fl(grid->size, dist); } else { - shd->zpos_flag |= CLIP_ZNEG; - shd->zneg_flag |= CLIP_ZPOS; + float viewdist = 1.0f / min_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1])); + copy_v3_fl(grid->size, viewdist * dist); } - shd->zplane_axes[0] = (float)((shd->zpos_flag & (PLANE_XZ | PLANE_XY)) != 0); - shd->zplane_axes[1] = (float)((shd->zpos_flag & (PLANE_YZ | PLANE_XY)) != 0); - shd->zplane_axes[2] = (float)((shd->zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0); - } - else { - shd->zneg_flag = shd->zpos_flag = CLIP_ZNEG | CLIP_ZPOS; - } + grid->distance = dist / 2.0f; - float dist; - if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) { - Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera); - dist = ((Camera *)(camera_object->data))->clip_end; - shd->grid_flag |= GRID_CAMERA; - shd->zneg_flag |= GRID_CAMERA; - shd->zpos_flag |= GRID_CAMERA; - } - else { - dist = v3d->clip_end; - } + ED_view3d_grid_steps(scene, v3d, rv3d, grid_steps); - if (winmat[3][3] == 0.0f) { - copy_v3_fl(shd->grid_size, dist); - } - else { - float viewdist = 1.0f / min_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1])); - copy_v3_fl(shd->grid_size, viewdist * dist); + if ((v3d->flag & (V3D_XR_SESSION_SURFACE | V3D_XR_SESSION_MIRROR)) != 0) { + /* The calculations for the grid parameters assume that the view matrix has no scale + * component, which may not be correct if the user is "shrunk" or "enlarged" by zooming in or + * out. Therefore, we need to compensate the values here. */ + /* Assumption is uniform scaling (all column vectors are of same length). */ + float viewinvscale = len_v3(viewinv[0]); + grid->distance *= viewinvscale; + } } - shd->grid_distance = dist / 2.0f; - - ED_view3d_grid_steps(scene, v3d, rv3d, shd->grid_steps); - - if ((v3d->flag & (V3D_XR_SESSION_SURFACE | V3D_XR_SESSION_MIRROR)) != 0) { - /* The calculations for the grid parameters assume that the view matrix has no scale component, - * which may not be correct if the user is "shrunk" or "enlarged" by zooming in or out. - * Therefore, we need to compensate the values here. */ - float viewinvscale = len_v3( - viewinv[0]); /* Assumption is uniform scaling (all column vectors are of same length). */ - shd->grid_distance *= viewinvscale; + /* Convert to UBO alignment. */ + for (int i = 0; i < SI_GRID_STEPS_LEN; i++) { + grid->steps[i][0] = grid_steps[i]; } + pd->grid.grid_flag = grid_flag; + pd->grid.zneg_flag = zneg_flag; + pd->grid.zpos_flag = zpos_flag; } -void OVERLAY_grid_cache_init(OVERLAY_Data *vedata) +void OVERLAY_grid_cache_init(OVERLAY_Data *ved) { - OVERLAY_StorageList *stl = vedata->stl; + OVERLAY_StorageList *stl = ved->stl; OVERLAY_PrivateData *pd = stl->pd; - OVERLAY_ShadingData *shd = &pd->shdata; + OVERLAY_GridData *grid = &pd->grid_data; - OVERLAY_PassList *psl = vedata->psl; + OVERLAY_PassList *psl = ved->psl; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); psl->grid_ps = NULL; - if ((shd->grid_flag == 0 && shd->zpos_flag == 0) || !DRW_state_is_fbo()) { + if ((pd->grid.grid_flag == 0 && pd->grid.zpos_flag == 0) || !DRW_state_is_fbo()) { return; } + if (ved->instance->grid_ubo == NULL) { + ved->instance->grid_ubo = GPU_uniformbuf_create(sizeof(OVERLAY_GridData)); + } + GPU_uniformbuf_update(ved->instance->grid_ubo, &pd->grid_data); + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA; DRW_PASS_CREATE(psl->grid_ps, state); DRWShadingGroup *grp; GPUShader *sh; struct GPUBatch *geom = DRW_cache_grid_get(); - const float line_zero = 0; - static const float grid_steps_default[8] = {0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0, 10000.0}; - if (pd->space_type == SPACE_IMAGE) { float mat[4][4]; - /* add quad background */ + /* Add quad background. */ sh = OVERLAY_shader_grid_background(); - grp = DRW_shgroup_create(sh, psl->grid_ps); + DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->grid_ps); float color_back[4]; interp_v4_v4v4(color_back, G_draw.block.color_background, G_draw.block.color_grid, 0.5); DRW_shgroup_uniform_vec4_copy(grp, "color", color_back); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); unit_m4(mat); - mat[0][0] = shd->grid_size[0]; - mat[1][1] = shd->grid_size[1]; - mat[2][2] = shd->grid_size[2]; + mat[0][0] = grid->size[0]; + mat[1][1] = grid->size[1]; + mat[2][2] = grid->size[2]; DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat); } - sh = OVERLAY_shader_grid(); - - /* Create 3 quads to render ordered transparency Z axis */ - grp = DRW_shgroup_create(sh, psl->grid_ps); - DRW_shgroup_uniform_int(grp, "gridFlag", &shd->zneg_flag, 1); - DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->zplane_axes, 1); - DRW_shgroup_uniform_float(grp, "gridDistance", &shd->grid_distance, 1); - DRW_shgroup_uniform_float_copy(grp, "lineKernel", shd->grid_line_size); - DRW_shgroup_uniform_vec3(grp, "gridSize", shd->grid_size, 1); - DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); - DRW_shgroup_uniform_float(grp, "gridSteps", grid_steps_default, 8); - if (shd->zneg_flag & SHOW_AXIS_Z) { - DRW_shgroup_call(grp, geom, NULL); - } + { + DRWShadingGroup *grp; - grp = DRW_shgroup_create(sh, psl->grid_ps); - DRW_shgroup_uniform_int(grp, "gridFlag", &shd->grid_flag, 1); - DRW_shgroup_uniform_float_copy(grp, "zoomFactor", shd->zoom_factor); - DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->grid_axes, 1); - DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); - DRW_shgroup_uniform_float_copy(grp, "lineKernel", line_zero); - DRW_shgroup_uniform_float(grp, "gridSteps", shd->grid_steps, ARRAY_SIZE(shd->grid_steps)); - if (shd->grid_flag) { - DRW_shgroup_call(grp, geom, NULL); - } + sh = OVERLAY_shader_grid(); - grp = DRW_shgroup_create(sh, psl->grid_ps); - DRW_shgroup_uniform_int(grp, "gridFlag", &shd->zpos_flag, 1); - DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->zplane_axes, 1); - DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); - DRW_shgroup_uniform_float_copy(grp, "lineKernel", line_zero); - DRW_shgroup_uniform_float(grp, "gridSteps", grid_steps_default, 8); - if (shd->zpos_flag & SHOW_AXIS_Z) { - DRW_shgroup_call(grp, geom, NULL); + /* Create 3 quads to render ordered transparency Z axis */ + grp = DRW_shgroup_create(sh, psl->grid_ps); + DRW_shgroup_uniform_block(grp, "grid_buf", ved->instance->grid_ubo); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); + DRW_shgroup_uniform_texture_ref(grp, "depth_tx", &dtxl->depth); + + DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.zneg_flag); + DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.zplane_axes); + if (pd->grid.zneg_flag & SHOW_AXIS_Z) { + DRW_shgroup_call(grp, geom, NULL); + } + + grp = DRW_shgroup_create_sub(grp); + DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.grid_flag); + DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.grid_axes); + if (pd->grid.grid_flag) { + DRW_shgroup_call(grp, geom, NULL); + } + + grp = DRW_shgroup_create_sub(grp); + DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.zpos_flag); + DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.zplane_axes); + if (pd->grid.zpos_flag & SHOW_AXIS_Z) { + DRW_shgroup_call(grp, geom, NULL); + } } if (pd->space_type == SPACE_IMAGE) { @@ -293,12 +285,12 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *vedata) float mat[4][4]; /* add wire border */ sh = OVERLAY_shader_grid_image(); - grp = DRW_shgroup_create(sh, psl->grid_ps); + DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->grid_ps); DRW_shgroup_uniform_vec4_copy(grp, "color", theme_color); unit_m4(mat); - for (int x = 0; x < shd->grid_size[0]; x++) { + for (int x = 0; x < grid->size[0]; x++) { mat[3][0] = x; - for (int y = 0; y < shd->grid_size[1]; y++) { + for (int y = 0; y < grid->size[1]; y++) { mat[3][1] = y; DRW_shgroup_call_obmat(grp, DRW_cache_quad_wires_get(), mat); } diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h index 4c933e08a57..9c8d5c600df 100644 --- a/source/blender/draw/engines/overlay/overlay_private.h +++ b/source/blender/draw/engines/overlay/overlay_private.h @@ -9,6 +9,8 @@ #include "DRW_render.h" +#include "overlay_shader_shared.h" + #ifdef __cplusplus extern "C" { #endif @@ -120,18 +122,8 @@ typedef struct OVERLAY_PassList { DRWPass *xray_fade_ps; } OVERLAY_PassList; -/* Data used by GLSL shader. To be used as UBO. */ +/* Data used by GLSL shader. */ typedef struct OVERLAY_ShadingData { - /** Grid */ - float grid_axes[3], grid_distance; - float zplane_axes[3], grid_size[3]; - float grid_steps[SI_GRID_STEPS_LEN]; - float inv_viewport_size[2]; - float grid_line_size; - float zoom_factor; /* Only for UV editor */ - int grid_flag; - int zpos_flag; - int zneg_flag; /** Wireframe */ float wire_step_param; float wire_opacity; @@ -326,8 +318,14 @@ typedef struct OVERLAY_PrivateData { int cfra; DRWState clipping_state; OVERLAY_ShadingData shdata; + OVERLAY_GridData grid_data; struct { + float grid_axes[3]; + float zplane_axes[3]; + OVERLAY_GridBits zneg_flag, zpos_flag, grid_flag; + } grid; + struct { bool enabled; bool do_depth_copy; bool do_depth_infront_copy; @@ -418,12 +416,18 @@ typedef struct OVERLAY_StorageList { struct OVERLAY_PrivateData *pd; } OVERLAY_StorageList; +typedef struct OVERLAY_Instance { + GPUUniformBuf *grid_ubo; +} OVERLAY_Instance; + typedef struct OVERLAY_Data { void *engine_type; OVERLAY_FramebufferList *fbl; OVERLAY_TextureList *txl; OVERLAY_PassList *psl; OVERLAY_StorageList *stl; + + OVERLAY_Instance *instance; } OVERLAY_Data; typedef struct OVERLAY_DupliData { diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c index 278aefb8fec..651fb0f2494 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.c +++ b/source/blender/draw/engines/overlay/overlay_shader.c @@ -849,16 +849,7 @@ GPUShader *OVERLAY_shader_grid(void) { OVERLAY_Shaders *sh_data = &e_data.sh_data[0]; if (!sh_data->grid) { - sh_data->grid = GPU_shader_create_from_arrays({ - .vert = (const char *[]){datatoc_common_globals_lib_glsl, - datatoc_common_view_lib_glsl, - datatoc_grid_vert_glsl, - NULL}, - .frag = (const char *[]){datatoc_common_globals_lib_glsl, - datatoc_common_view_lib_glsl, - datatoc_grid_frag_glsl, - NULL}, - }); + sh_data->grid = GPU_shader_create_from_info_name("overlay_grid"); } return sh_data->grid; } diff --git a/source/blender/draw/engines/overlay/overlay_shader_shared.h b/source/blender/draw/engines/overlay/overlay_shader_shared.h new file mode 100644 index 00000000000..4b1d4eea69a --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_shader_shared.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef GPU_SHADER +# include "GPU_shader_shared_utils.h" + +# ifdef __cplusplus +extern "C" { +# else +typedef enum OVERLAY_GridBits OVERLAY_GridBits; +# endif +typedef struct OVERLAY_GridData OVERLAY_GridData; +#endif + +enum OVERLAY_GridBits { + SHOW_AXIS_X = (1 << 0), + SHOW_AXIS_Y = (1 << 1), + SHOW_AXIS_Z = (1 << 2), + SHOW_GRID = (1 << 3), + PLANE_XY = (1 << 4), + PLANE_XZ = (1 << 5), + PLANE_YZ = (1 << 6), + CLIP_ZPOS = (1 << 7), + CLIP_ZNEG = (1 << 8), + GRID_BACK = (1 << 9), + GRID_CAMERA = (1 << 10), + PLANE_IMAGE = (1 << 11), + CUSTOM_GRID = (1 << 12), +}; + +/* Match: #SI_GRID_STEPS_LEN */ +#define OVERLAY_GRID_STEPS_LEN 8 + +struct OVERLAY_GridData { + float4 steps[OVERLAY_GRID_STEPS_LEN]; /* float arrays are padded to float4 in std130. */ + float4 size; /* float3 padded to float4. */ + float distance; + float line_size; + float zoom_factor; /* Only for UV editor */ + float _pad0; +}; +BLI_STATIC_ASSERT_ALIGN(OVERLAY_GridData, 16) + +#ifndef GPU_SHADER +# ifdef __cplusplus +} +# endif +#endif diff --git a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl index f1fcc3ad8fa..25f4984f119 100644 --- a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl @@ -1,38 +1,11 @@ +/** + * Infinite grid: + * Draw antialiazed grid and axes of different sizes with smooth blending between Level of details. + * We draw multiple triangles to avoid float precision issues due to perspective interpolation. + **/ -/* Infinite grid - * Author: Clément Foucault */ - -/* We use the normalized local position to avoid precision - * loss during interpolation. */ -in vec3 local_pos; - -out vec4 FragColor; - -uniform vec3 planeAxes; -uniform float gridDistance; -uniform vec3 gridSize; -uniform float lineKernel = 0.0; -uniform depth2D depthBuffer; - -uniform int gridFlag; -uniform float zoomFactor; - -#define STEPS_LEN 8 /* Match: #SI_GRID_STEPS_LEN */ -uniform float gridSteps[STEPS_LEN]; - -#define AXIS_X (1 << 0) -#define AXIS_Y (1 << 1) -#define AXIS_Z (1 << 2) -#define GRID (1 << 3) -#define PLANE_XY (1 << 4) -#define PLANE_XZ (1 << 5) -#define PLANE_YZ (1 << 6) -#define GRID_BACK (1 << 9) /* grid is behind objects */ -#define GRID_CAMERA (1 << 10) /* In camera view */ -#define PLANE_IMAGE (1 << 11) /* UV/Image Image editor */ -#define CUSTOM_GRID (1 << 12) /* UV Editor only */ - -#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) /** * We want to know how much a pixel is covered by a line. @@ -41,78 +14,75 @@ uniform float gridSteps[STEPS_LEN]; * The formula for the area uses inverse trig function and is quite complexe. Instead, * we approximate it by using the smoothstep function and a 1.05 factor to the disc radius. */ +#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */ #define DISC_RADIUS (M_1_SQRTPI * 1.05) #define GRID_LINE_SMOOTH_START (0.5 - DISC_RADIUS) #define GRID_LINE_SMOOTH_END (0.5 + DISC_RADIUS) +#define GRID_LINE_STEP(dist) smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, dist) -float get_grid(vec2 co, vec2 fwidthCos, float grid_size) +float get_grid(vec2 co, vec2 fwidthCos, float grid_scale) { - float half_size = grid_size / 2.0; - /* triangular wave pattern, amplitude is [0, half_size] */ - vec2 grid_domain = abs(mod(co + half_size, vec2(grid_size)) - half_size); - /* modulate by the absolute rate of change of the coordinates - * (make lines have the same width under perspective) */ + float half_size = grid_scale / 2.0; + /* Triangular wave pattern, amplitude is [0, half_size]. */ + vec2 grid_domain = abs(mod(co + half_size, vec2(grid_scale)) - half_size); + /* Modulate by the absolute rate of change of the coordinates + * (make line have the same width under perspective). */ grid_domain /= fwidthCos; - - /* collapse waves */ + /* Collapse waves. */ float line_dist = min(grid_domain.x, grid_domain.y); - - return 1.0 - smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, line_dist - lineKernel); + return 1.0 - GRID_LINE_STEP(line_dist - grid_buf.line_size); } vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size) { vec3 axes_domain = abs(co); - /* modulate by the absolute rate of change of the coordinates - * (make line have the same width under perspective) */ + /* Modulate by the absolute rate of change of the coordinates + * (make line have the same width under perspective). */ axes_domain /= fwidthCos; - - return 1.0 - smoothstep(GRID_LINE_SMOOTH_START, - GRID_LINE_SMOOTH_END, - axes_domain - (line_size + lineKernel)); + return 1.0 - GRID_LINE_STEP(axes_domain - (line_size + grid_buf.line_size)); } #define linearstep(p0, p1, v) (clamp(((v) - (p0)) / abs((p1) - (p0)), 0.0, 1.0)) void main() { - vec3 wPos = local_pos * gridSize; - vec3 dFdxPos = dFdx(wPos); - vec3 dFdyPos = dFdy(wPos); + vec3 P = local_pos * grid_buf.size.xyz; + vec3 dFdxPos = dFdx(P); + vec3 dFdyPos = dFdy(P); vec3 fwidthPos = abs(dFdxPos) + abs(dFdyPos); - wPos += cameraPos * planeAxes; + P += cameraPos * plane_axes; float dist, fade; - /* if persp */ - if (ProjectionMatrix[3][3] == 0.0) { - vec3 viewvec = cameraPos - wPos; - dist = length(viewvec); - viewvec /= dist; + bool is_persp = ProjectionMatrix[3][3] == 0.0; + if (is_persp) { + vec3 V = cameraPos - P; + dist = length(V); + V /= dist; float angle; - if ((gridFlag & PLANE_XZ) != 0) { - angle = viewvec.y; + if (flag_test(grid_flag, PLANE_XZ)) { + angle = V.y; } - else if ((gridFlag & PLANE_YZ) != 0) { - angle = viewvec.x; + else if (flag_test(grid_flag, PLANE_YZ)) { + angle = V.x; } else { - angle = viewvec.z; + angle = V.z; } angle = 1.0 - abs(angle); angle *= angle; fade = 1.0 - angle * angle; - fade *= 1.0 - smoothstep(0.0, gridDistance, dist - gridDistance); + fade *= 1.0 - smoothstep(0.0, grid_buf.distance, dist - grid_buf.distance); } else { dist = gl_FragCoord.z * 2.0 - 1.0; /* Avoid fading in +Z direction in camera view (see T70193). */ - dist = ((gridFlag & GRID_CAMERA) != 0) ? clamp(dist, 0.0, 1.0) : abs(dist); + dist = flag_test(grid_flag, GRID_CAMERA) ? clamp(dist, 0.0, 1.0) : abs(dist); fade = 1.0 - smoothstep(0.0, 0.5, dist - 0.5); - dist = 1.0; /* avoid branch after */ + dist = 1.0; /* Avoid branch after. */ - if ((gridFlag & PLANE_XY) != 0) { + if (flag_test(grid_flag, PLANE_XY)) { float angle = 1.0 - abs(ViewMatrixInverse[2].z); dist = 1.0 + angle * 2.0; angle *= angle; @@ -120,75 +90,78 @@ void main() } } - if ((gridFlag & GRID) != 0) { + if (flag_test(grid_flag, SHOW_GRID)) { /* Using `max(dot(dFdxPos, screenVecs[0]), dot(dFdyPos, screenVecs[1]))` * would be more accurate, but not really necessary. */ float grid_res = dot(dFdxPos, screenVecs[0].xyz); - /* The grid begins to appear when it comprises 4 pixels */ + /* The grid begins to appear when it comprises 4 pixels. */ grid_res *= 4; - /* For UV/Image editor use zoomFactor */ - if ((gridFlag & PLANE_IMAGE) != 0 && + /* For UV/Image editor use grid_buf.zoom_factor. */ + if (flag_test(grid_flag, PLANE_IMAGE) && /* Grid begins to appear when the length of one grid unit is at least * (256/grid_size) pixels Value of grid_size defined in `overlay_grid.c`. */ - (gridFlag & CUSTOM_GRID) == 0) { - grid_res = zoomFactor; + !flag_test(grid_flag, CUSTOM_GRID)) { + grid_res = grid_buf.zoom_factor; } - /* from biggest to smallest */ + /* From biggest to smallest. */ vec4 scale; -#if 0 +#define grid_step(a) grid_buf.steps[a].x +#if 0 /* Inefficient. */ int step_id = 0; scale[0] = 0.0; - scale[1] = gridSteps[0]; + scale[1] = grid_step(0); while (scale[1] < grid_res && step_id != STEPS_LEN - 1) { scale[0] = scale[1]; - scale[1] = gridSteps[++step_id]; + scale[1] = grid_step(++step_id); } - scale[2] = gridSteps[min(step_id + 1, STEPS_LEN - 1)]; - scale[3] = gridSteps[min(step_id + 2, STEPS_LEN - 1)]; + scale[2] = grid_step(min(step_id + 1, STEPS_LEN - 1)); + scale[3] = grid_step(min(step_id + 2, STEPS_LEN - 1)); #else /* For more efficiency, unroll the loop above. */ - if (gridSteps[0] > grid_res) { - scale = vec4(0.0, gridSteps[0], gridSteps[1], gridSteps[2]); + if (grid_step(0) > grid_res) { + scale = vec4(0.0, grid_step(0), grid_step(1), grid_step(2)); } - else if (gridSteps[1] > grid_res) { - scale = vec4(gridSteps[0], gridSteps[1], gridSteps[2], gridSteps[3]); + else if (grid_step(1) > grid_res) { + scale = vec4(grid_step(0), grid_step(1), grid_step(2), grid_step(3)); } - else if (gridSteps[2] > grid_res) { - scale = vec4(gridSteps[1], gridSteps[2], gridSteps[3], gridSteps[4]); + else if (grid_step(2) > grid_res) { + scale = vec4(grid_step(1), grid_step(2), grid_step(3), grid_step(4)); } - else if (gridSteps[3] > grid_res) { - scale = vec4(gridSteps[2], gridSteps[3], gridSteps[4], gridSteps[5]); + else if (grid_step(3) > grid_res) { + scale = vec4(grid_step(2), grid_step(3), grid_step(4), grid_step(5)); } - else if (gridSteps[4] > grid_res) { - scale = vec4(gridSteps[3], gridSteps[4], gridSteps[5], gridSteps[6]); + else if (grid_step(4) > grid_res) { + scale = vec4(grid_step(3), grid_step(4), grid_step(5), grid_step(6)); } - else if (gridSteps[5] > grid_res) { - scale = vec4(gridSteps[4], gridSteps[5], gridSteps[6], gridSteps[7]); + else if (grid_step(5) > grid_res) { + scale = vec4(grid_step(4), grid_step(5), grid_step(6), grid_step(7)); } - else if (gridSteps[6] > grid_res) { - scale = vec4(gridSteps[5], gridSteps[6], gridSteps[7], gridSteps[7]); + else if (grid_step(6) > grid_res) { + scale = vec4(grid_step(5), grid_step(6), grid_step(7), grid_step(7)); } else { - scale = vec4(gridSteps[6], gridSteps[7], gridSteps[7], gridSteps[7]); + scale = vec4(grid_step(6), grid_step(7), grid_step(7), grid_step(7)); } #endif +#undef grid_step + float blend = 1.0 - linearstep(scale[0], scale[1], grid_res); blend = blend * blend * blend; vec2 grid_pos, grid_fwidth; - if ((gridFlag & PLANE_XZ) != 0) { - grid_pos = wPos.xz; + if (flag_test(grid_flag, PLANE_XZ)) { + grid_pos = P.xz; grid_fwidth = fwidthPos.xz; } - else if ((gridFlag & PLANE_YZ) != 0) { - grid_pos = wPos.yz; + else if (flag_test(grid_flag, PLANE_YZ)) { + grid_pos = P.yz; grid_fwidth = fwidthPos.yz; } else { - grid_pos = wPos.xy; + grid_pos = P.xy; grid_fwidth = fwidthPos.xy; } @@ -196,51 +169,51 @@ void main() float gridB = get_grid(grid_pos, grid_fwidth, scale[2]); float gridC = get_grid(grid_pos, grid_fwidth, scale[3]); - FragColor = colorGrid; - FragColor.a *= gridA * blend; - FragColor = mix(FragColor, mix(colorGrid, colorGridEmphasis, blend), gridB); - FragColor = mix(FragColor, colorGridEmphasis, gridC); + out_color = colorGrid; + out_color.a *= gridA * blend; + out_color = mix(out_color, mix(colorGrid, colorGridEmphasis, blend), gridB); + out_color = mix(out_color, colorGridEmphasis, gridC); } else { - FragColor = vec4(colorGrid.rgb, 0.0); + out_color = vec4(colorGrid.rgb, 0.0); } - if ((gridFlag & (AXIS_X | AXIS_Y | AXIS_Z)) != 0) { + if (flag_test(grid_flag, (SHOW_AXIS_X | SHOW_AXIS_Y | SHOW_AXIS_Z))) { /* Setup axes 'domains' */ vec3 axes_dist, axes_fwidth; - if ((gridFlag & AXIS_X) != 0) { - axes_dist.x = dot(wPos.yz, planeAxes.yz); - axes_fwidth.x = dot(fwidthPos.yz, planeAxes.yz); + if (flag_test(grid_flag, SHOW_AXIS_X)) { + axes_dist.x = dot(P.yz, plane_axes.yz); + axes_fwidth.x = dot(fwidthPos.yz, plane_axes.yz); } - if ((gridFlag & AXIS_Y) != 0) { - axes_dist.y = dot(wPos.xz, planeAxes.xz); - axes_fwidth.y = dot(fwidthPos.xz, planeAxes.xz); + if (flag_test(grid_flag, SHOW_AXIS_Y)) { + axes_dist.y = dot(P.xz, plane_axes.xz); + axes_fwidth.y = dot(fwidthPos.xz, plane_axes.xz); } - if ((gridFlag & AXIS_Z) != 0) { - axes_dist.z = dot(wPos.xy, planeAxes.xy); - axes_fwidth.z = dot(fwidthPos.xy, planeAxes.xy); + if (flag_test(grid_flag, SHOW_AXIS_Z)) { + axes_dist.z = dot(P.xy, plane_axes.xy); + axes_fwidth.z = dot(fwidthPos.xy, plane_axes.xy); } /* Computing all axes at once using vec3 */ vec3 axes = get_axes(axes_dist, axes_fwidth, 0.1); - if ((gridFlag & AXIS_X) != 0) { - FragColor.a = max(FragColor.a, axes.x); - FragColor.rgb = (axes.x < 1e-8) ? FragColor.rgb : colorGridAxisX.rgb; + if (flag_test(grid_flag, SHOW_AXIS_X)) { + out_color.a = max(out_color.a, axes.x); + out_color.rgb = (axes.x < 1e-8) ? out_color.rgb : colorGridAxisX.rgb; } - if ((gridFlag & AXIS_Y) != 0) { - FragColor.a = max(FragColor.a, axes.y); - FragColor.rgb = (axes.y < 1e-8) ? FragColor.rgb : colorGridAxisY.rgb; + if (flag_test(grid_flag, SHOW_AXIS_Y)) { + out_color.a = max(out_color.a, axes.y); + out_color.rgb = (axes.y < 1e-8) ? out_color.rgb : colorGridAxisY.rgb; } - if ((gridFlag & AXIS_Z) != 0) { - FragColor.a = max(FragColor.a, axes.z); - FragColor.rgb = (axes.z < 1e-8) ? FragColor.rgb : colorGridAxisZ.rgb; + if (flag_test(grid_flag, SHOW_AXIS_Z)) { + out_color.a = max(out_color.a, axes.z); + out_color.rgb = (axes.z < 1e-8) ? out_color.rgb : colorGridAxisZ.rgb; } } - float scene_depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; - if ((gridFlag & GRID_BACK) != 0) { + float scene_depth = texelFetch(depth_tx, ivec2(gl_FragCoord.xy), 0).r; + if (flag_test(grid_flag, GRID_BACK)) { fade *= (scene_depth == 1.0) ? 1.0 : 0.0; } else { @@ -255,5 +228,5 @@ void main() fade *= linearstep(grid_depth, grid_depth + bias, scene_depth); } - FragColor.a *= fade; + out_color.a *= fade; } diff --git a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl index d77d6012e06..b81f1a24358 100644 --- a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl @@ -1,34 +1,24 @@ +/** + * Infinite grid: + * Draw antialiazed grid and axes of different sizes with smooth blending between Level of details. + * We draw multiple triangles to avoid float precision issues due to perspective interpolation. + **/ -/* Infinite grid - * Clément Foucault */ - -uniform vec3 planeAxes; -uniform vec3 gridSize; - -uniform int gridFlag; - -#define PLANE_XY (1 << 4) -#define PLANE_XZ (1 << 5) -#define PLANE_YZ (1 << 6) -#define CLIP_Z_POS (1 << 7) -#define CLIP_Z_NEG (1 << 8) -#define PLANE_IMAGE (1 << 11) -in vec3 pos; - -out vec3 local_pos; +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) void main() { vec3 vert_pos; /* Project camera pos to the needed plane */ - if ((gridFlag & PLANE_XY) != 0) { + if (flag_test(grid_flag, PLANE_XY)) { vert_pos = vec3(pos.x, pos.y, 0.0); } - else if ((gridFlag & PLANE_XZ) != 0) { + else if (flag_test(grid_flag, PLANE_XZ)) { vert_pos = vec3(pos.x, 0.0, pos.y); } - else if ((gridFlag & PLANE_YZ) != 0) { + else if (flag_test(grid_flag, PLANE_YZ)) { vert_pos = vec3(0.0, pos.x, pos.y); } else /* PLANE_IMAGE */ { @@ -37,14 +27,14 @@ void main() local_pos = vert_pos; - vec3 real_pos = cameraPos * planeAxes + vert_pos * gridSize; + vec3 real_pos = cameraPos * plane_axes + vert_pos * grid_buf.size.xyz; /* Used for additional Z axis */ - if ((gridFlag & CLIP_Z_POS) != 0) { + if (flag_test(grid_flag, CLIP_ZPOS)) { real_pos.z = clamp(real_pos.z, 0.0, 1e30); local_pos.z = clamp(local_pos.z, 0.0, 1.0); } - if ((gridFlag & CLIP_Z_NEG) != 0) { + if (flag_test(grid_flag, CLIP_ZNEG)) { real_pos.z = clamp(real_pos.z, -1e30, 0.0); local_pos.z = clamp(local_pos.z, -1.0, 0.0); } diff --git a/source/blender/draw/engines/overlay/shaders/infos/grid_info.hh b/source/blender/draw/engines/overlay/shaders/infos/grid_info.hh new file mode 100644 index 00000000000..be36aa67735 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/infos/grid_info.hh @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +/* We use the normalized local position to avoid precision loss during interpolation. */ +GPU_SHADER_INTERFACE_INFO(overlay_grid_iface, "").smooth(Type::VEC3, "local_pos"); + +GPU_SHADER_CREATE_INFO(overlay_grid) + .do_static_compilation(true) + .typedef_source("overlay_shader_shared.h") + .vertex_in(0, Type::VEC3, "pos") + .vertex_out(overlay_grid_iface) + .fragment_out(0, Type::VEC4, "out_color") + .sampler(0, ImageType::DEPTH_2D, "depth_tx") + .uniform_buf(3, "OVERLAY_GridData", "grid_buf") + .push_constant(Type::VEC3, "plane_axes") + .push_constant(Type::INT, "grid_flag") + .vertex_source("grid_vert.glsl") + .fragment_source("grid_frag.glsl") + .additional_info("draw_view", "draw_globals"); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 042b79565ef..a675b503f75 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -444,6 +444,7 @@ set(SRC_SHADER_CREATE_INFOS ../draw/engines/gpencil/shaders/infos/gpencil_info.hh ../draw/engines/gpencil/shaders/infos/gpencil_vfx_info.hh ../draw/engines/overlay/shaders/infos/armature_info.hh + ../draw/engines/overlay/shaders/infos/grid_info.hh ../draw/engines/overlay/shaders/infos/edit_mode_info.hh ../draw/engines/workbench/shaders/infos/workbench_composite_info.hh ../draw/engines/workbench/shaders/infos/workbench_effect_antialiasing_info.hh |