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:
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/modes/object_mode.c32
-rw-r--r--source/blender/draw/modes/shaders/object_grid_frag.glsl121
2 files changed, 95 insertions, 58 deletions
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 133995269a4..f557315305d 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -212,8 +212,12 @@ static struct {
float grid_settings[5];
float grid_mat[4][4];
int grid_flag;
+ float grid_normal[3];
+ float grid_axes[3];
int zpos_flag;
int zneg_flag;
+ float zplane_normal[3];
+ float zplane_axes[3];
bool draw_grid;
/* Temp buffer textures */
struct GPUTexture *outlines_depth_tx;
@@ -397,7 +401,17 @@ static void OBJECT_engine_init(void *vedata)
}
}
+ e_data.grid_normal[0] = (float)((e_data.grid_flag & PLANE_YZ) != 0);
+ e_data.grid_normal[1] = (float)((e_data.grid_flag & PLANE_XZ) != 0);
+ e_data.grid_normal[2] = (float)((e_data.grid_flag & PLANE_XY) != 0);
+
+ e_data.grid_axes[0] = (float)((e_data.grid_flag & (PLANE_XZ | PLANE_XY)) != 0);
+ e_data.grid_axes[1] = (float)((e_data.grid_flag & (PLANE_YZ | PLANE_XY)) != 0);
+ e_data.grid_axes[2] = (float)((e_data.grid_flag & (PLANE_YZ | PLANE_XZ)) != 0);
+
/* Vectors to recover pixel world position. Fix grid precision issue. */
+ /* Using pixel at z = 0.0f in ndc space : gives average precision between
+ * near and far plane. Note that it might not be the best choice. */
copy_v4_fl4(e_data.screenvecs[0], 1.0f, -1.0f, 0.0f, 1.0f);
copy_v4_fl4(e_data.screenvecs[1], -1.0f, 1.0f, 0.0f, 1.0f);
copy_v4_fl4(e_data.screenvecs[2], -1.0f, -1.0f, 0.0f, 1.0f);
@@ -410,6 +424,9 @@ static void OBJECT_engine_init(void *vedata)
e_data.screenvecs[i][1] /= e_data.screenvecs[i][3]; /* perspective divide */
e_data.screenvecs[i][2] /= e_data.screenvecs[i][3]; /* perspective divide */
e_data.screenvecs[i][3] = 1.0f;
+ /* main instability come from this one */
+ /* TODO : to make things even more stable, don't use
+ * invviewmat and derive vectors from camera properties */
mul_m4_v4(invviewmat, e_data.screenvecs[i]);
}
@@ -444,6 +461,15 @@ static void OBJECT_engine_init(void *vedata)
e_data.zpos_flag |= CLIP_ZNEG;
e_data.zneg_flag |= CLIP_ZPOS;
}
+
+ e_data.zplane_normal[0] = (float)((e_data.zpos_flag & PLANE_YZ) != 0);
+ e_data.zplane_normal[1] = (float)((e_data.zpos_flag & PLANE_XZ) != 0);
+ e_data.zplane_normal[2] = (float)((e_data.zpos_flag & PLANE_XY) != 0);
+
+ e_data.zplane_axes[0] = (float)((e_data.zpos_flag & (PLANE_XZ | PLANE_XY)) != 0);
+ e_data.zplane_axes[1] = (float)((e_data.zpos_flag & (PLANE_YZ | PLANE_XY)) != 0);
+ e_data.zplane_axes[2] = (float)((e_data.zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0);
+
}
else {
e_data.zneg_flag = e_data.zpos_flag = CLIP_ZNEG | CLIP_ZPOS;
@@ -775,6 +801,8 @@ static void OBJECT_cache_init(void *vedata)
/* 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_vec3(grp, "planeNormal", e_data.zplane_normal, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 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, "screenvecs[0]", e_data.screenvecs[0], 3);
@@ -786,10 +814,14 @@ static void OBJECT_cache_init(void *vedata)
grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.grid_flag, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.grid_normal, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.grid_axes, 1);
DRW_shgroup_call_add(grp, quad, mat);
grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zpos_flag, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.zplane_normal, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1);
DRW_shgroup_call_add(grp, quad, mat);
}
diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl
index 2db5100e1b3..0196b1a6f98 100644
--- a/source/blender/draw/modes/shaders/object_grid_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl
@@ -2,10 +2,13 @@
/* Infinite grid
* Clément Foucault */
+
out vec4 FragColor;
uniform mat4 ProjectionMatrix;
uniform vec3 cameraPos;
+uniform vec3 planeNormal;
+uniform vec3 planeAxes;
uniform vec3 eye;
uniform vec4 gridSettings;
uniform vec2 viewportSize;
@@ -29,12 +32,12 @@ uniform int gridFlag;
#define GRID_LINE_SMOOTH 1.15
-float grid(vec3 uv, vec3 fwidthCos, float grid_size)
+float get_grid(vec3 co, vec3 fwidthCos, float grid_size)
{
float half_size = grid_size / 2.0;
/* triangular wave pattern, amplitude is [0, grid_size] */
- vec3 grid_domain = abs(mod(uv + half_size, grid_size) - half_size);
- /* modulate by the absolute rate of change of the uvs
+ vec3 grid_domain = abs(mod(co + half_size, grid_size) - half_size);
+ /* modulate by the absolute rate of change of the coordinates
* (make lines have the same width under perspective) */
grid_domain /= fwidthCos;
@@ -44,56 +47,58 @@ float grid(vec3 uv, vec3 fwidthCos, float grid_size)
return 1.0 - smoothstep(0.0, GRID_LINE_SMOOTH / grid_size, grid_domain.x);
}
-float axis(float u, float fwidthU, float line_size)
+vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size)
{
- float axis_domain = abs(u);
- /* modulate by the absolute rate of change of the uvs
+ vec3 axes_domain = abs(co);
+ /* modulate by the absolute rate of change of the coordinates
* (make line have the same width under perspective) */
- axis_domain /= fwidthU;
+ axes_domain /= fwidthCos;
- return 1.0 - smoothstep(0.0, GRID_LINE_SMOOTH, axis_domain - line_size);
+ return 1.0 - smoothstep(0.0, GRID_LINE_SMOOTH, axes_domain - line_size);
}
-vec3 get_floor_pos(vec2 uv)
+vec3 get_floor_pos(vec2 uv, out vec3 wPos)
{
- /* if perspective */
- vec3 camera_vec, camera_pos;
- vec3 pixel_pos = screenvecs[2].xyz + uv.x * screenvecs[0].xyz + uv.y * screenvecs[1].xyz;
+ vec3 camera_vec, camera_pos, corner_pos;
+ vec3 floored_pos = planeAxes * floor(screenvecs[2].xyz);
+ corner_pos = screenvecs[2].xyz - floored_pos;
+
+ vec3 pixel_pos = corner_pos + uv.x * screenvecs[0].xyz + uv.y * screenvecs[1].xyz;
+ /* if perspective */
if (ProjectionMatrix[3][3] == 0.0) {
- camera_vec = normalize(pixel_pos - cameraPos);
- camera_pos = cameraPos;
+ camera_pos = cameraPos - floored_pos;
+ camera_vec = normalize(pixel_pos - camera_pos);
}
else {
- camera_vec = normalize(eye);
camera_pos = pixel_pos;
+ camera_vec = normalize(eye);
}
- vec3 plane_normal;
- if ((gridFlag & PLANE_XZ) > 0) {
- plane_normal = vec3(0.0, 1.0, 0.0);
- }
- else if ((gridFlag & PLANE_YZ) > 0) {
- plane_normal = vec3(1.0, 0.0, 0.0);
- }
- else {
- plane_normal = vec3(0.0, 0.0, 1.0);
- }
-
- float p = -dot(plane_normal, camera_pos) / dot(plane_normal, camera_vec);
+ float p = -dot(planeNormal, camera_pos) / dot(planeNormal, camera_vec);
vec3 plane = camera_pos + camera_vec * p;
/* fix residual imprecision */
- vec3 mask = vec3(1.0) - plane_normal;
- return plane * mask;
+ plane *= planeAxes;
+
+ /* Recover non-offseted world position */
+ wPos = plane + floored_pos;
+
+ return plane;
}
void main()
{
vec2 sPos = gl_FragCoord.xy / viewportSize; /* Screen [0,1] position */
- vec3 wPos = get_floor_pos(sPos);
- vec3 fwidthCos = fwidth(wPos);
+ /* To reduce artifacts, use a local version of the positions
+ * to compute derivatives since they are not position dependant.
+ * This gets rid of the blocky artifacts. Unfortunately we still
+ * need the world position for the grid to scale properly from the origin. */
+ vec3 gPos, wPos; /* Grid pos., World pos. */
+ gPos = get_floor_pos(sPos, wPos);
+
+ vec3 fwidthPos = fwidth(gPos);
float dist, fade;
/* if persp */
@@ -132,14 +137,14 @@ void main()
float blend = fract(-max(grid_res, 0.0));
float lvl = floor(grid_res);
- /* from smallest to biggest */
+ /* 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));
- float gridA = grid(wPos, fwidthCos, scaleA);
- float gridB = grid(wPos, fwidthCos, scaleB);
- float gridC = grid(wPos, fwidthCos, scaleC);
+ float gridA = get_grid(wPos, fwidthPos, scaleA);
+ float gridB = get_grid(wPos, fwidthPos, scaleB);
+ float gridC = get_grid(wPos, fwidthPos, scaleC);
FragColor = vec4(colorGrid.rgb, gridA * blend);
FragColor = mix(FragColor, vec4(mix(colorGrid.rgb, colorGridEmphasise.rgb, blend), 1.0), gridB);
@@ -149,35 +154,35 @@ void main()
FragColor = vec4(colorGrid.rgb, 0.0);
}
- if ((gridFlag & AXIS_X) > 0) {
- float xAxis;
- if ((gridFlag & PLANE_XZ) > 0) {
- xAxis = axis(wPos.z, fwidthCos.z, 0.1);
+ if ((gridFlag & (AXIS_X | AXIS_Y | AXIS_Z)) > 0) {
+ /* 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);
}
- else {
- xAxis = axis(wPos.y, fwidthCos.y, 0.1);
+ if ((gridFlag & AXIS_Y) > 0) {
+ axes_dist.y = dot(wPos.xz, planeAxes.xz);
+ axes_fwidth.y = dot(fwidthPos.xz, planeAxes.xz);
}
- FragColor = mix(FragColor, colorGridAxisX, xAxis);
- }
- if ((gridFlag & AXIS_Y) > 0) {
- float yAxis;
- if ((gridFlag & PLANE_YZ) > 0) {
- yAxis = axis(wPos.z, fwidthCos.z, 0.1);
+ if ((gridFlag & AXIS_Z) > 0) {
+ axes_dist.z = dot(wPos.xy, planeAxes.xy);
+ axes_fwidth.z = dot(fwidthPos.xy, planeAxes.xy);
}
- else {
- yAxis = axis(wPos.x, fwidthCos.x, 0.1);
+
+ /* Computing all axes at once using vec3 */
+ vec3 axes = get_axes(axes_dist, axes_fwidth, 0.1);
+
+ if ((gridFlag & AXIS_X) > 0) {
+ FragColor = mix(FragColor, colorGridAxisX, axes.x);
}
- FragColor = mix(FragColor, colorGridAxisY, yAxis);
- }
- if ((gridFlag & AXIS_Z) > 0) {
- float zAxis;
- if ((gridFlag & PLANE_YZ) > 0) {
- zAxis = axis(wPos.y, fwidthCos.y, 0.1);
+ if ((gridFlag & AXIS_Y) > 0) {
+ FragColor = mix(FragColor, colorGridAxisY, axes.y);
}
- else {
- zAxis = axis(wPos.x, fwidthCos.x, 0.1);
+ if ((gridFlag & AXIS_Z) > 0) {
+ FragColor = mix(FragColor, colorGridAxisZ, axes.z);
}
- FragColor = mix(FragColor, colorGridAxisZ, zAxis);
}
FragColor.a *= fade;