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
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-03-25 04:46:23 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-03-25 21:11:01 +0300
commit0495e689e60c313e039b09468307dcbab2a7ae1c (patch)
tree6fbac1eb94633bd3e76aca6c4bb78845161f362c /source
parentd2c94c78736e84c1318859c8e902b3ee622fd6f0 (diff)
New Grid : Feature parity with old grid.
Removed infinite details and went for decreasing details with the distance instead (like the axis aligned ortho view auto sized grid). Separate drawing of the Z axis into 2 pass (using shading group) to render ordered transparency with the main grid pass.
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/modes/object_mode.c154
-rw-r--r--source/blender/draw/modes/shaders/object_grid_frag.glsl103
-rw-r--r--source/blender/draw/modes/shaders/object_grid_vert.glsl52
3 files changed, 264 insertions, 45 deletions
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index bf431a61728..b7bb489ca2b 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -36,6 +36,7 @@
#include "BKE_global.h"
#include "ED_view3d.h"
+#include "ED_view3d.h"
#include "GPU_shader.h"
@@ -164,8 +165,24 @@ static struct {
float camera_pos[3];
float grid_settings[4];
float grid_mat[4][4];
+ int grid_flag;
+ int zpos_flag;
+ int zneg_flag;
} e_data = {NULL}; /* Engine data */
+
+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),
+};
+
/* *********** FUNCTIONS *********** */
static void OBJECT_engine_init(void)
@@ -206,7 +223,20 @@ static void OBJECT_engine_init(void)
}
{
- float viewinvmat[4][4], winmat[4][4], viewmat[4][4];
+ /* Grid precompute */
+ float viewinvmat[4][4], winmat[4][4], invwinmat[4][4], viewmat[4][4];
+ const bContext *C = DRW_get_context();
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ float grid_scale = ED_view3d_grid_scale(scene, v3d, NULL);
+ float grid_res, offs;
+
+ const bool show_axis_x = v3d->gridflag & V3D_SHOW_X;
+ const bool show_axis_y = v3d->gridflag & V3D_SHOW_Y;
+ const bool show_axis_z = v3d->gridflag & V3D_SHOW_Z;
+ const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR);
+
DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
DRW_viewport_matrix_get(viewinvmat, DRW_MAT_VIEWINV);
@@ -214,29 +244,113 @@ static void OBJECT_engine_init(void)
/* Setup camera pos */
copy_v3_v3(e_data.camera_pos, viewinvmat[3]);
- /* grid settings */
- const bContext *C = DRW_get_context();
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
+ /* 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}
+ };
+ /* invert the proj matrix */
+ invert_m4_m4(invwinmat, winmat);
+
+ /* convert the view vectors to view space */
+ for (int i = 0; i < 2; i++) {
+ mul_m4_v4(invwinmat, viewvecs[i]);
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]); /* normalize */
+ }
- e_data.grid_settings[0] = 100.0f; /* gridDistance */
- e_data.grid_settings[1] = 2.0f; /* gridResolution */
- e_data.grid_settings[2] = ED_view3d_grid_scale(scene, v3d, NULL); /* gridScale */
- e_data.grid_settings[3] = v3d->gridsubdiv; /* gridSubdiv */
+ fov = angle_v3v3(viewvecs[0], viewvecs[1]) / 2.0f;
+ grid_res = fabsf(tanf(fov)) / grid_scale;
+
+ /* Grid matrix polygon offset (fix depth fighting) */
+ /* see ED_view3d_polygon_offset */
+ offs = winmat[3][2] * -0.0025f;
- /* Grid matrix polygon offset (fix depth fighting) */
- /* see ED_view3d_polygon_offset */
- float offs;
- if (winmat[3][3] > 0.5f) {
+ e_data.grid_flag = (1 << 4); /* XY plane */
+ if (show_axis_x)
+ e_data.grid_flag |= SHOW_AXIS_X;
+ if (show_axis_y)
+ e_data.grid_flag |= SHOW_AXIS_Y;
+ if (show_floor)
+ e_data.grid_flag |= SHOW_GRID;
+ }
+ else {
float viewdist = 1.0f / max_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
+ grid_res = viewdist / grid_scale;
+
+ /* Grid matrix polygon offset (fix depth fighting) */
+ /* see ED_view3d_polygon_offset */
offs = 0.00001f * viewdist;
+ if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) {
+ e_data.grid_flag = PLANE_YZ;
+ e_data.grid_flag |= SHOW_AXIS_Y;
+ e_data.grid_flag |= SHOW_AXIS_Z;
+ e_data.grid_flag |= SHOW_GRID;
+ }
+ else if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
+ e_data.grid_flag = PLANE_XY;
+ e_data.grid_flag |= SHOW_AXIS_X;
+ e_data.grid_flag |= SHOW_AXIS_Y;
+ e_data.grid_flag |= SHOW_GRID;
+ }
+ else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
+ e_data.grid_flag = PLANE_XZ;
+ e_data.grid_flag |= SHOW_AXIS_X;
+ e_data.grid_flag |= SHOW_AXIS_Z;
+ e_data.grid_flag |= SHOW_GRID;
+ }
+ else { /* RV3D_VIEW_USER */
+ e_data.grid_flag = PLANE_XY;
+ if (show_axis_x)
+ e_data.grid_flag |= SHOW_AXIS_X;
+ if (show_axis_y)
+ e_data.grid_flag |= SHOW_AXIS_Y;
+ if (show_floor)
+ e_data.grid_flag |= SHOW_GRID;
+ }
+ }
+
+ /* Z axis if needed */
+ if ((rv3d->view == RV3D_VIEW_USER) && show_axis_z) {
+ e_data.zpos_flag = SHOW_AXIS_Z;
+
+ float zvec[4] = {0.0f, 0.0f, -1.0f, 0.0f};
+ mul_m4_v4(viewinvmat, zvec);
+
+ /* z axis : chose the most facing plane */
+ if (fabsf(zvec[0]) > fabsf(zvec[1])) {
+ e_data.zpos_flag |= (PLANE_XZ | SHOW_AXIS_X);
+ }
+ else {
+ e_data.zpos_flag |= (PLANE_YZ | SHOW_AXIS_Y);
+ }
+
+ e_data.zneg_flag = e_data.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) && (e_data.camera_pos[2] > 0.0f)) ||
+ ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) {
+ e_data.zpos_flag |= CLIP_ZPOS;
+ e_data.zneg_flag |= CLIP_ZNEG;
+ }
+ else {
+ e_data.zpos_flag |= CLIP_ZNEG;
+ e_data.zneg_flag |= CLIP_ZPOS;
+ }
}
else {
- offs = winmat[3][2] * -0.0025f;
+ e_data.zneg_flag = e_data.zpos_flag = 0;
}
- winmat[3][2] -= offs;
+ winmat[3][2] -= offs;
mul_m4_m4m4(e_data.grid_mat, winmat, viewmat);
+
+ e_data.grid_settings[0] = v3d->far / 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 */
}
}
@@ -382,12 +496,22 @@ static void OBJECT_cache_init(void)
struct Batch *quad = DRW_cache_fullscreen_quad_get();
+ /* Create 3 quads to render ordered transparency Z axis */
DRWShadingGroup *grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
+ DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zneg_flag, 1);
DRW_shgroup_uniform_mat4(grp, "ViewProjectionOffsetMatrix", (float *)e_data.grid_mat);
DRW_shgroup_uniform_vec3(grp, "cameraPos", e_data.camera_pos, 1);
DRW_shgroup_uniform_vec4(grp, "gridSettings", e_data.grid_settings, 1);
DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo, 0);
DRW_shgroup_call_add(grp, quad, NULL);
+
+ grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
+ DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.grid_flag, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+
+ grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
+ DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zpos_flag, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
}
{
diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl
index 0f7be9fea3e..8b890ea8692 100644
--- a/source/blender/draw/modes/shaders/object_grid_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl
@@ -15,19 +15,29 @@ uniform vec4 gridSettings;
#define gridScale gridSettings.z
#define gridSubdiv gridSettings.w
+uniform int gridFlag;
+
+#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_LINE_SMOOTH 1.15
-float grid(vec2 uv, vec2 fwidthUvs, float grid_size)
+float grid(vec3 uv, vec3 fwidthCos, float grid_size)
{
float half_size = grid_size / 2.0;
/* triangular wave pattern, amplitude is [0, grid_size] */
- vec2 grid_domain = abs(mod(uv + half_size, grid_size) - half_size);
+ vec3 grid_domain = abs(mod(uv + half_size, grid_size) - half_size);
/* modulate by the absolute rate of change of the uvs
* (make lines have the same width under perspective) */
- grid_domain /= fwidthUvs;
+ grid_domain /= fwidthCos;
/* collapse waves and normalize */
- grid_domain.x = min(grid_domain.x, grid_domain.y) / grid_size;
+ grid_domain.x = min(grid_domain.x, min(grid_domain.y, grid_domain.z)) / grid_size;
return 1.0 - smoothstep(0.0, GRID_LINE_SMOOTH / grid_size, grid_domain.x);
}
@@ -44,43 +54,78 @@ float axis(float u, float fwidthU, float line_size)
void main()
{
- vec2 fwidthUvs = fwidth(wPos.xy);
-
- float blend, lvl, fade;
+ vec3 fwidthCos = fwidth(wPos);
+ float fade, grid_res;
/* if persp */
if (ProjectionMatrix[3][3] == 0.0) {
float dist = distance(cameraPos, wPos);
- float log2dist = -log2(dist / (2.0 * gridDistance));
-
- blend = fract(log2dist / gridResolution);
- lvl = floor(log2dist / gridResolution);
+ float dist_norm = dist / (2.0 * gridDistance);
+ grid_res = log(dist * gridResolution) / log(gridSubdiv);
fade = 1.0 - smoothstep(0.0, gridDistance, dist - gridDistance);
}
else {
- /* todo find a better way */
- blend = 0.0;
- lvl = 0.0;
- fade = 1.0;
+ float dist = abs(gl_FragCoord.z * 2.0 - 1.0);
+ grid_res = log(gridResolution) / log(gridSubdiv);
+ fade = 1.0 - smoothstep(0.0, 0.5, dist - 0.5);
}
- /* from smallest to biggest */
- float scaleA = gridScale * pow(gridSubdiv, min(-lvl + 1.0, 1.0));
- float scaleB = gridScale * pow(gridSubdiv, min(-lvl + 2.0, 1.0));
- float scaleC = gridScale * pow(gridSubdiv, min(-lvl + 3.0, 1.0));
+ /* fix division by 0 (log(1) = 0) */
+ if (gridSubdiv == 1.0) {
+ grid_res = 0.0;
+ }
+
+ if ((gridFlag & GRID) > 0) {
+ float blend = fract(-max(grid_res, 0.0));
+ float lvl = floor(grid_res);
- float gridA = grid(wPos.xy, fwidthUvs, scaleA);
- float gridB = grid(wPos.xy, fwidthUvs, scaleB);
- float gridC = grid(wPos.xy, fwidthUvs, scaleC);
+ /* from smallest to biggest */
+ 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));
- float xAxis = axis(wPos.y, fwidthUvs.y, 0.1); /* Swapped */
- float yAxis = axis(wPos.x, fwidthUvs.x, 0.1); /* Swapped */
+ float gridA = grid(wPos, fwidthCos, scaleA);
+ float gridB = grid(wPos, fwidthCos, scaleB);
+ float gridC = grid(wPos, fwidthCos, scaleC);
- FragColor = vec4(colorGrid.rgb, gridA * blend);
- FragColor = mix(FragColor, vec4(mix(colorGrid.rgb, colorGridEmphasise.rgb, blend), 1.0), gridB);
- FragColor = mix(FragColor, vec4(colorGridEmphasise.rgb, 1.0), gridC);
+ FragColor = vec4(colorGrid.rgb, gridA * blend);
+ FragColor = mix(FragColor, vec4(mix(colorGrid.rgb, colorGridEmphasise.rgb, blend), 1.0), gridB);
+ FragColor = mix(FragColor, vec4(colorGridEmphasise.rgb, 1.0), gridC);
+ }
+ else {
+ FragColor = vec4(colorGrid.rgb, 0.0);
+ }
+
+ if ((gridFlag & AXIS_X) > 0) {
+ float xAxis;
+ if ((gridFlag & AXIS_Y) > 0) {
+ xAxis = axis(wPos.y, fwidthCos.y, 0.1);
+ }
+ else {
+ xAxis = axis(wPos.z, fwidthCos.z, 0.1);
+ }
+ FragColor = mix(FragColor, colorGridAxisX, xAxis);
+ }
+ if ((gridFlag & AXIS_Y) > 0) {
+ float yAxis;
+ if ((gridFlag & AXIS_X) > 0) {
+ yAxis = axis(wPos.x, fwidthCos.x, 0.1);
+ }
+ else {
+ yAxis = axis(wPos.z, fwidthCos.z, 0.1);
+ }
+ FragColor = mix(FragColor, colorGridAxisY, yAxis);
+ }
+ if ((gridFlag & AXIS_Z) > 0) {
+ float zAxis;
+ if ((gridFlag & AXIS_Y) > 0) {
+ zAxis = axis(wPos.y, fwidthCos.y, 0.1);
+ }
+ else {
+ zAxis = axis(wPos.x, fwidthCos.x, 0.1);
+ }
+ FragColor = mix(FragColor, colorGridAxisZ, zAxis);
+ }
- FragColor = mix(FragColor, colorGridAxisX, xAxis);
- FragColor = mix(FragColor, colorGridAxisY, yAxis);
FragColor.a *= fade;
} \ No newline at end of file
diff --git a/source/blender/draw/modes/shaders/object_grid_vert.glsl b/source/blender/draw/modes/shaders/object_grid_vert.glsl
index 3c6f0a3bd25..5127bd81474 100644
--- a/source/blender/draw/modes/shaders/object_grid_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_grid_vert.glsl
@@ -3,6 +3,22 @@
* Clément Foucault */
uniform mat4 ViewProjectionOffsetMatrix;
+uniform mat4 ProjectionMatrix;
+uniform vec3 cameraPos;
+uniform vec4 gridSettings;
+
+#define gridDistance gridSettings.x
+#define gridResolution gridSettings.y
+#define gridScale gridSettings.z
+#define gridSubdiv gridSettings.w
+
+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)
in vec3 pos;
@@ -10,7 +26,41 @@ out vec3 wPos;
void main()
{
- vec3 realPos = pos * 1e3;
+ vec3 vert_pos, proj_camera_pos;
+
+ /* Project camera pos to the needed plane */
+ if ((gridFlag & PLANE_XY) > 0) {
+ vert_pos = vec3(pos.x, pos.y, 0.0);
+ proj_camera_pos = vec3(cameraPos.x, cameraPos.y, 0.0);
+ }
+ else if ((gridFlag & PLANE_XZ) > 0) {
+ vert_pos = vec3(pos.x, 0.0, pos.y);
+ proj_camera_pos = vec3(cameraPos.x, 0.0, cameraPos.z);
+ }
+ else {
+ vert_pos = vec3(0.0, pos.x, pos.y);
+ proj_camera_pos = vec3(0.0, cameraPos.y, cameraPos.z);
+ }
+
+ /* if persp */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ vert_pos *= gridDistance * 2.0;
+ }
+ else {
+ float viewdist = 1.0f / min(abs(ProjectionMatrix[0][0]), abs(ProjectionMatrix[1][1]));
+ vert_pos *= viewdist * gridDistance * 2.0;
+ }
+
+ vec3 realPos = proj_camera_pos + vert_pos;
+
+ /* Used for additional Z axis */
+ if ((gridFlag & CLIP_Z_POS) > 0) {
+ realPos.z = max(realPos.z, 0.0);
+ }
+ else if ((gridFlag & CLIP_Z_NEG) > 0) {
+ realPos.z = min(realPos.z, 0.0);
+ }
+
gl_Position = ViewProjectionOffsetMatrix * vec4(realPos, 1.0);
wPos = realPos;
}