[Bf-blender-cvs] [0495e689e6] blender2.8: New Grid : Feature parity with old grid.
Clément Foucault
noreply at git.blender.org
Sat Mar 25 19:56:55 CET 2017
Commit: 0495e689e60c313e039b09468307dcbab2a7ae1c
Author: Clément Foucault
Date: Sat Mar 25 02:46:23 2017 +0100
Branches: blender2.8
https://developer.blender.org/rB0495e689e60c313e039b09468307dcbab2a7ae1c
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.
===================================================================
M source/blender/draw/modes/object_mode.c
M source/blender/draw/modes/shaders/object_grid_frag.glsl
M source/blender/draw/modes/shaders/object_grid_vert.glsl
===================================================================
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index bf431a6172..b7bb489ca2 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 0f7be9fea3..8b890ea869 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
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list