Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-04-28 22:13:04 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-04-28 22:13:04 +0300
commit308a12ac647d6f9b4ef2b6c403903e0aeb65a571 (patch)
treed327529eb93340033a3adddd95d28c92f75b1b69 /source/blender/draw
parent3d9f0280ff1bc308aa31e95af6b1726f1b497111 (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/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c14
-rw-r--r--source/blender/draw/engines/overlay/overlay_grid.c356
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h26
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.c11
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader_shared.h47
-rw-r--r--source/blender/draw/engines/overlay/shaders/grid_frag.glsl227
-rw-r--r--source/blender/draw/engines/overlay/shaders/grid_vert.glsl36
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/grid_info.hh20
9 files changed, 385 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");