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.
This commit is contained in:
parent
d2c94c7873
commit
0495e689e6
|
@ -35,6 +35,7 @@
|
|||
#include "BKE_camera.h"
|
||||
#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);
|
||||
|
||||
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 */
|
||||
/* 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 */
|
||||
}
|
||||
|
||||
/* Grid matrix polygon offset (fix depth fighting) */
|
||||
/* see ED_view3d_polygon_offset */
|
||||
float offs;
|
||||
if (winmat[3][3] > 0.5f) {
|
||||
float viewdist = 1.0f / max_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
|
||||
offs = 0.00001f * viewdist;
|
||||
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;
|
||||
|
||||
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 {
|
||||
offs = winmat[3][2] * -0.0025f;
|
||||
}
|
||||
winmat[3][2] -= offs;
|
||||
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 {
|
||||
e_data.zneg_flag = e_data.zpos_flag = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
float gridA = grid(wPos.xy, fwidthUvs, scaleA);
|
||||
float gridB = grid(wPos.xy, fwidthUvs, scaleB);
|
||||
float gridC = grid(wPos.xy, fwidthUvs, scaleC);
|
||||
if ((gridFlag & GRID) > 0) {
|
||||
float blend = fract(-max(grid_res, 0.0));
|
||||
float lvl = floor(grid_res);
|
||||
|
||||
float xAxis = axis(wPos.y, fwidthUvs.y, 0.1); /* Swapped */
|
||||
float yAxis = axis(wPos.x, fwidthUvs.x, 0.1); /* Swapped */
|
||||
/* 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));
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue