diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d.py | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.h | 1 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 42 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/common_globals_lib.glsl | 5 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/object_grid_frag.glsl | 75 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/object_grid_vert.glsl | 6 | ||||
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 73 |
8 files changed, 133 insertions, 77 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 8bb211052da..9b9623eaa60 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -5354,6 +5354,8 @@ class VIEW3D_PT_overlay_guides(Panel): layout = self.layout view = context.space_data + scene = context.scene + overlay = view.overlay shading = view.shading display_all = overlay.show_overlays @@ -5381,6 +5383,8 @@ class VIEW3D_PT_overlay_guides(Panel): (overlay.show_ortho_grid and grid_active) ) sub.prop(overlay, "grid_scale", text="Scale") + sub = sub.row(align=True) + sub.active = scene.unit_settings.system == 'NONE' sub.prop(overlay, "grid_subdivisions", text="Subdivisions") sub = split.column() diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 05d7bafa00d..52b94689679 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -113,7 +113,6 @@ typedef struct GlobalsUboStorage { /* Pack individual float at the end of the buffer to avoid alignment errors */ float sizeLightCenter, sizeLightCircle, sizeLightCircleShadow; float sizeVertex, sizeEdge, sizeEdgeFix, sizeFaceDot; - float gridDistance, gridResolution, gridSubdivisions, gridScale; float pad_globalsBlock; } GlobalsUboStorage; diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 87fc74f1f72..06e5b521514 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -332,7 +332,7 @@ static struct { OBJECT_Shaders sh_data[GPU_SHADER_CFG_LEN]; - float grid_settings[5]; + float grid_distance; float grid_mesh_size; int grid_flag; float grid_axes[3]; @@ -340,6 +340,7 @@ static struct { int zneg_flag; float zplane_axes[3]; float inv_viewport_size[2]; + float grid_steps[8]; bool draw_grid; /* Temp buffer textures */ struct GPUTexture *outlines_depth_tx; @@ -559,8 +560,6 @@ static void OBJECT_engine_init(void *vedata) View3D *v3d = draw_ctx->v3d; Scene *scene = draw_ctx->scene; RegionView3D *rv3d = draw_ctx->rv3d; - float grid_scale = ED_view3d_grid_scale(scene, v3d, NULL); - float grid_res; const bool show_axis_x = (v3d->gridflag & V3D_SHOW_X) != 0; const bool show_axis_y = (v3d->gridflag & V3D_SHOW_Y) != 0; @@ -576,21 +575,6 @@ static void OBJECT_engine_init(void *vedata) /* if perps */ if (winmat[3][3] == 0.0f) { - float fov; - float viewvecs[2][4] = { - {1.0f, -1.0f, -1.0f, 1.0f}, - {-1.0f, 1.0f, -1.0f, 1.0f}, - }; - - /* convert the view vectors to view space */ - for (int i = 0; i < 2; i++) { - mul_m4_v4(wininv, viewvecs[i]); - mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]); /* perspective divide */ - } - - fov = angle_v3v3(viewvecs[0], viewvecs[1]) / 2.0f; - grid_res = fabsf(tanf(fov)) / grid_scale; - e_data.grid_flag = (1 << 4); /* XY plane */ if (show_axis_x) { e_data.grid_flag |= SHOW_AXIS_X; @@ -603,14 +587,6 @@ static void OBJECT_engine_init(void *vedata) } } else { - if (rv3d->view != RV3D_VIEW_USER) { - /* Allow 3 more subdivisions. */ - grid_scale /= powf(v3d->gridsubdiv, 3); - } - - float viewdist = 1.0f / max_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1])); - grid_res = viewdist / grid_scale; - if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) { e_data.draw_grid = show_ortho_grid; e_data.grid_flag = PLANE_YZ | SHOW_AXIS_Y | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK; @@ -688,12 +664,7 @@ static void OBJECT_engine_init(void *vedata) dist = v3d->clip_end; } - e_data.grid_settings[0] = dist / 2.0f; /* gridDistance */ - e_data.grid_settings[1] = grid_res; /* gridResolution */ - e_data.grid_settings[2] = grid_scale; /* gridScale */ - e_data.grid_settings[3] = v3d->gridsubdiv; /* gridSubdiv */ - e_data.grid_settings[4] = (v3d->gridsubdiv > 1) ? 1.0f / logf(v3d->gridsubdiv) : - 0.0f; /* 1/log(gridSubdiv) */ + e_data.grid_distance = dist / 2.0f; /* gridDistance */ if (winmat[3][3] == 0.0f) { e_data.grid_mesh_size = dist; @@ -702,6 +673,8 @@ static void OBJECT_engine_init(void *vedata) float viewdist = 1.0f / min_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1])); e_data.grid_mesh_size = viewdist * dist; } + + ED_view3d_grid_steps(scene, v3d, rv3d, e_data.grid_steps); } copy_v2_v2(e_data.inv_viewport_size, DRW_viewport_size_get()); @@ -1512,10 +1485,10 @@ static void OBJECT_cache_init(void *vedata) DRWShadingGroup *grp = DRW_shgroup_create(sh_data->grid, psl->grid); DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zneg_flag, 1); DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1); - DRW_shgroup_uniform_vec4(grp, "gridSettings", e_data.grid_settings, 1); + DRW_shgroup_uniform_vec3(grp, "screenVecs[0]", DRW_viewport_screenvecs_get(), 2); + DRW_shgroup_uniform_float(grp, "gridDistance", &e_data.grid_distance, 1); DRW_shgroup_uniform_float_copy(grp, "lineKernel", grid_line_size); DRW_shgroup_uniform_float_copy(grp, "meshSize", e_data.grid_mesh_size); - DRW_shgroup_uniform_float(grp, "gridOneOverLogSubdiv", &e_data.grid_settings[4], 1); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); DRW_shgroup_call(grp, geom, NULL); @@ -1525,6 +1498,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", G_draw.block_ubo); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_float(grp, "gridSteps", e_data.grid_steps, ARRAY_SIZE(e_data.grid_steps)); DRW_shgroup_call(grp, geom, NULL); grp = DRW_shgroup_create(sh_data->grid, psl->grid); diff --git a/source/blender/draw/modes/shaders/common_globals_lib.glsl b/source/blender/draw/modes/shaders/common_globals_lib.glsl index f75ef06b6d9..e559224eb9e 100644 --- a/source/blender/draw/modes/shaders/common_globals_lib.glsl +++ b/source/blender/draw/modes/shaders/common_globals_lib.glsl @@ -75,11 +75,6 @@ layout(std140) uniform globalsBlock float sizeEdgeFix; float sizeFaceDot; - float gridDistance; - float gridResolution; - float gridSubdivisions; - float gridScale; - float pad_globalsBlock; }; diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl index a20f12efd93..751d839eb79 100644 --- a/source/blender/draw/modes/shaders/object_grid_frag.glsl +++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl @@ -9,21 +9,19 @@ in vec3 local_pos; out vec4 FragColor; uniform vec3 planeAxes; -uniform vec4 gridSettings; +uniform vec3 screenVecs[2]; +uniform float gridDistance; uniform float meshSize; uniform float lineKernel = 0.0; -uniform float gridOneOverLogSubdiv; uniform sampler2D depthBuffer; -#define gridDistance gridSettings.x -#define gridResolution gridSettings.y -#define gridScale gridSettings.z -#define gridSubdiv gridSettings.w - #define cameraPos (ViewMatrixInverse[3].xyz) uniform int gridFlag; +#define STEPS_LEN 8 +uniform float gridSteps[STEPS_LEN] = float[](0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0, 10000.0); + #define AXIS_X (1 << 0) #define AXIS_Y (1 << 1) #define AXIS_Z (1 << 2) @@ -73,10 +71,14 @@ vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size) axes_domain - (line_size + lineKernel)); } +#define linearstep(p0, p1, v) (clamp(((v) - (p0)) / abs((p1) - (p0)), 0.0, 1.0)) + void main() { vec3 wPos = local_pos * meshSize; - vec3 fwidthPos = fwidth(wPos); + vec3 dFdxPos = dFdx(wPos); + vec3 dFdyPos = dFdy(wPos); + vec3 fwidthPos = abs(dFdxPos) + abs(dFdyPos); wPos += cameraPos * planeAxes; float dist, fade; @@ -116,15 +118,54 @@ void main() } if ((gridFlag & GRID) != 0) { - float grid_res = log(dist * gridResolution) * gridOneOverLogSubdiv; + /* 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]); - float blend = fract(-max(grid_res, 0.0)); - float lvl = floor(grid_res); + /* The gride begins to appear when it comprises 4 pixels */ + grid_res *= 4; /* from biggest to smallest */ - float scaleA = gridScale * pow(gridSubdiv, max(lvl - 1.0, 0.0)); - float scaleB = gridScale * pow(gridSubdiv, max(lvl + 0.0, 0.0)); - float scaleC = gridScale * pow(gridSubdiv, max(lvl + 1.0, 1.0)); + vec4 scale; +#if 0 + int step_id = 0; + scale[0] = 0.0; + scale[1] = gridSteps[0]; + while (scale[1] < grid_res && step_id != STEPS_LEN - 1) { + scale[0] = scale[1]; + scale[1] = gridSteps[++step_id]; + } + scale[2] = gridSteps[min(step_id + 1, STEPS_LEN - 1)]; + scale[3] = gridSteps[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]); + } + else if (gridSteps[1] > grid_res) { + scale = vec4(gridSteps[0], gridSteps[1], gridSteps[2], gridSteps[3]); + } + else if (gridSteps[2] > grid_res) { + scale = vec4(gridSteps[1], gridSteps[2], gridSteps[3], gridSteps[4]); + } + else if (gridSteps[3] > grid_res) { + scale = vec4(gridSteps[2], gridSteps[3], gridSteps[4], gridSteps[5]); + } + else if (gridSteps[4] > grid_res) { + scale = vec4(gridSteps[3], gridSteps[4], gridSteps[5], gridSteps[6]); + } + else if (gridSteps[5] > grid_res) { + scale = vec4(gridSteps[4], gridSteps[5], gridSteps[6], gridSteps[7]); + } + else if (gridSteps[6] > grid_res) { + scale = vec4(gridSteps[5], gridSteps[6], gridSteps[7], gridSteps[7]); + } + else { + scale = vec4(gridSteps[6], gridSteps[7], gridSteps[7], gridSteps[7]); + } +#endif + 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) { @@ -140,9 +181,9 @@ void main() grid_fwidth = fwidthPos.xy; } - float gridA = get_grid(grid_pos, grid_fwidth, scaleA); - float gridB = get_grid(grid_pos, grid_fwidth, scaleB); - float gridC = get_grid(grid_pos, grid_fwidth, scaleC); + float gridA = get_grid(grid_pos, grid_fwidth, scale[1]); + 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; diff --git a/source/blender/draw/modes/shaders/object_grid_vert.glsl b/source/blender/draw/modes/shaders/object_grid_vert.glsl index d247967b03a..496bb011c74 100644 --- a/source/blender/draw/modes/shaders/object_grid_vert.glsl +++ b/source/blender/draw/modes/shaders/object_grid_vert.glsl @@ -3,14 +3,8 @@ * Clément Foucault */ uniform vec3 planeAxes; -uniform vec4 gridSettings; uniform float meshSize; -#define gridDistance gridSettings.x -#define gridResolution gridSettings.y -#define gridScale gridSettings.z -#define gridSubdiv gridSettings.w - uniform int gridFlag; #define cameraPos (ViewMatrixInverse[3].xyz) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 67dfb184d19..56661b992c4 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -690,6 +690,10 @@ bool ED_view3d_distance_set_from_location(struct RegionView3D *rv3d, float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit); float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit); +void ED_view3d_grid_steps(struct Scene *scene, + struct View3D *v3d, + struct RegionView3D *rv3d, + float *r_grid_steps); float ED_view3d_grid_view_scale(struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d, diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 6c534ee1b98..038d32c4d20 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -859,6 +859,51 @@ float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit) return v3d->grid * ED_scene_grid_scale(scene, grid_unit); } +#define STEPS_LEN 8 +void ED_view3d_grid_steps(Scene *scene, + View3D *v3d, + RegionView3D *rv3d, + float r_grid_steps[STEPS_LEN]) +{ + const void *usys; + int i, len; + bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len); + float grid_scale = v3d->grid; + + if (usys) { + if (rv3d->view == RV3D_VIEW_USER) { + /* Skip steps */ + len = bUnit_GetBaseUnit(usys) + 1; + } + + grid_scale /= scene->unit.scale_length; + + for (i = 0; i < len; i++) { + r_grid_steps[i] = (float)bUnit_GetScaler(usys, len - 1 - i) * grid_scale; + } + for (; i < STEPS_LEN; i++) { + /* Fill last slots */ + r_grid_steps[i] = 10.0f * r_grid_steps[i - 1]; + } + } + else { + if (rv3d->view != RV3D_VIEW_USER) { + /* Allow 3 more subdivisions. */ + grid_scale /= powf(v3d->gridsubdiv, 3); + } + int subdiv = 1; + for (i = 0;; i++) { + r_grid_steps[i] = grid_scale * subdiv; + + if (i == STEPS_LEN - 1) { + break; + } + subdiv *= v3d->gridsubdiv; + } + } +} +#undef STEPS_LEN + /* Simulates the grid scale that is actually viewed. * The actual code is seen in `object_grid_frag.glsl` (see `grid_res`). * Currently the simulation is only done when RV3D_VIEW_IS_AXIS. */ @@ -867,24 +912,24 @@ float ED_view3d_grid_view_scale(Scene *scene, RegionView3D *rv3d, const char **grid_unit) { - float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit); + float grid_scale; if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) { /* Decrease the distance between grid snap points depending on zoom. */ - float grid_subdiv = v3d->gridsubdiv; - if (grid_subdiv > 1) { - /* Allow 3 more subdivisions (see OBJECT_engine_init). */ - grid_scale /= powf(grid_subdiv, 3); - - /* `3.0` was a value obtained by trial and error in order to get - * a nice snap distance.*/ - float grid_res = 3.0 * (rv3d->dist / v3d->lens); - float lvl = (logf(grid_res / grid_scale) / logf(grid_subdiv)); - - CLAMP_MIN(lvl, 0.0f); - - grid_scale *= pow(grid_subdiv, (int)lvl); + /* `0.38` was a value visually obtained in order to get a snap distance + * that matches previous versions Blender.*/ + float min_dist = 0.38f * (rv3d->dist / v3d->lens); + float grid_steps[8]; + ED_view3d_grid_steps(scene, v3d, rv3d, grid_steps); + for (int i = 0; i < ARRAY_SIZE(grid_steps); i++) { + grid_scale = grid_steps[i]; + if (grid_scale > min_dist) { + break; + } } } + else { + grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit); + } return grid_scale; } |