2023-08-24 10:54:59 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2017-2023 Blender Authors
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
|
|
2025-09-25 10:57:02 +02:00
|
|
|
#include "infos/overlay_grid_infos.hh"
|
2025-02-24 16:17:18 +01:00
|
|
|
|
|
|
|
|
FRAGMENT_SHADER_CREATE_INFO(overlay_grid_next)
|
|
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
/**
|
|
|
|
|
* Infinite grid:
|
2023-08-19 23:44:20 +10:00
|
|
|
* Draw anti-aliased grid and axes of different sizes with smooth blending between levels of
|
|
|
|
|
* detail. We draw multiple triangles to avoid float precision issues due to perspective
|
|
|
|
|
* interpolation.
|
2023-08-19 17:13:05 +10:00
|
|
|
*/
|
2017-03-22 21:28:59 +01:00
|
|
|
|
2025-01-23 18:06:22 +01:00
|
|
|
#include "draw_view_lib.glsl"
|
2025-02-10 18:14:50 +01:00
|
|
|
#include "gpu_shader_utildefines_lib.glsl"
|
2023-08-19 17:56:48 +10:00
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float get_grid(float2 co, float2 fwidthCos, float2 grid_scale)
|
2017-03-22 21:28:59 +01:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
float2 half_size = grid_scale / 2.0f;
|
2022-04-28 21:13:04 +02:00
|
|
|
/* Triangular wave pattern, amplitude is [0, half_size]. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float2 grid_domain = abs(mod(co + half_size, grid_scale) - half_size);
|
2022-04-28 21:13:04 +02:00
|
|
|
/* Modulate by the absolute rate of change of the coordinates
|
|
|
|
|
* (make line have the same width under perspective). */
|
2017-03-25 02:46:23 +01:00
|
|
|
grid_domain /= fwidthCos;
|
2022-04-28 21:13:04 +02:00
|
|
|
/* Collapse waves. */
|
2018-10-30 16:20:48 +01:00
|
|
|
float line_dist = min(grid_domain.x, grid_domain.y);
|
2025-04-24 15:20:25 +02:00
|
|
|
return 1.0 - LINE_STEP(line_dist - grid_buf.line_size);
|
2017-03-22 21:28:59 +01:00
|
|
|
}
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 get_axes(float3 co, float3 fwidthCos, float line_size)
|
2017-03-22 21:28:59 +01:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 axes_domain = abs(co);
|
2022-04-28 21:13:04 +02:00
|
|
|
/* Modulate by the absolute rate of change of the coordinates
|
|
|
|
|
* (make line have the same width under perspective). */
|
2017-05-27 21:35:03 +02:00
|
|
|
axes_domain /= fwidthCos;
|
2025-04-24 15:20:25 +02:00
|
|
|
return 1.0 - LINE_STEP(axes_domain - (line_size + grid_buf.line_size));
|
2017-03-22 21:28:59 +01:00
|
|
|
}
|
|
|
|
|
|
2025-04-11 18:28:45 +02:00
|
|
|
#define linearstep(p0, p1, v) (clamp(((v) - (p0)) / abs((p1) - (p0)), 0.0f, 1.0f))
|
2019-08-19 11:49:07 -03:00
|
|
|
|
2017-03-22 21:28:59 +01:00
|
|
|
void main()
|
|
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 P = local_pos * grid_buf.size.xyz;
|
2025-05-05 09:59:00 +02:00
|
|
|
float3 dFdxPos = gpu_dfdx(P);
|
|
|
|
|
float3 dFdyPos = gpu_dfdy(P);
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 fwidthPos = abs(dFdxPos) + abs(dFdyPos);
|
2025-01-23 18:06:22 +01:00
|
|
|
P += drw_view_position() * plane_axes;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-03-27 14:01:25 +02:00
|
|
|
float dist, fade;
|
2025-04-11 18:28:45 +02:00
|
|
|
bool is_persp = drw_view().winmat[3][3] == 0.0f;
|
2022-04-28 21:13:04 +02:00
|
|
|
if (is_persp) {
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 V = drw_view_position() - P;
|
2022-04-28 21:13:04 +02:00
|
|
|
dist = length(V);
|
|
|
|
|
V /= dist;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-04-03 21:37:40 +02:00
|
|
|
float angle;
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, PLANE_XZ)) {
|
|
|
|
|
angle = V.y;
|
2018-07-05 22:56:18 +02:00
|
|
|
}
|
2022-04-28 21:13:04 +02:00
|
|
|
else if (flag_test(grid_flag, PLANE_YZ)) {
|
|
|
|
|
angle = V.x;
|
2018-07-05 22:56:18 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2022-04-28 21:13:04 +02:00
|
|
|
angle = V.z;
|
2018-07-05 22:56:18 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-04-11 18:28:45 +02:00
|
|
|
angle = 1.0f - abs(angle);
|
2017-10-12 04:03:42 +02:00
|
|
|
angle *= angle;
|
2025-04-11 18:28:45 +02:00
|
|
|
fade = 1.0f - angle * angle;
|
|
|
|
|
fade *= 1.0f - smoothstep(0.0f, grid_buf.distance, dist - grid_buf.distance);
|
2017-03-22 21:28:59 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2025-04-11 18:28:45 +02:00
|
|
|
dist = gl_FragCoord.z * 2.0f - 1.0f;
|
2023-02-12 14:37:16 +11:00
|
|
|
/* Avoid fading in +Z direction in camera view (see #70193). */
|
2025-04-11 18:28:45 +02:00
|
|
|
dist = flag_test(grid_flag, GRID_CAMERA) ? clamp(dist, 0.0f, 1.0f) : abs(dist);
|
|
|
|
|
fade = 1.0f - smoothstep(0.0f, 0.5f, dist - 0.5f);
|
|
|
|
|
dist = 1.0f; /* Avoid branch after. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, PLANE_XY)) {
|
2025-04-11 18:28:45 +02:00
|
|
|
float angle = 1.0f - abs(drw_view().viewinv[2].z);
|
|
|
|
|
dist = 1.0f + angle * 2.0f;
|
2017-10-12 04:03:42 +02:00
|
|
|
angle *= angle;
|
2025-04-11 18:28:45 +02:00
|
|
|
fade *= 1.0f - angle * angle;
|
2017-04-03 21:37:40 +02:00
|
|
|
}
|
2017-03-25 02:46:23 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, SHOW_GRID)) {
|
2025-03-04 12:30:59 +01:00
|
|
|
/* Using `max(dot(dFdxPos, drw_view().viewinv[0]), dot(dFdyPos, drw_view().viewinv[1]))`
|
2019-08-19 11:49:07 -03:00
|
|
|
* would be more accurate, but not really necessary. */
|
2025-03-04 12:30:59 +01:00
|
|
|
float grid_res = dot(dFdxPos, drw_view().viewinv[0].xyz);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
/* The grid begins to appear when it comprises 4 pixels. */
|
2019-08-19 11:49:07 -03:00
|
|
|
grid_res *= 4;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
/* For UV/Image editor use grid_buf.zoom_factor. */
|
|
|
|
|
if (flag_test(grid_flag, PLANE_IMAGE) &&
|
2021-09-29 17:47:32 +10:00
|
|
|
/* Grid begins to appear when the length of one grid unit is at least
|
|
|
|
|
* (256/grid_size) pixels Value of grid_size defined in `overlay_grid.c`. */
|
2022-04-28 21:13:04 +02:00
|
|
|
!flag_test(grid_flag, CUSTOM_GRID))
|
|
|
|
|
{
|
|
|
|
|
grid_res = grid_buf.zoom_factor;
|
2021-09-29 17:47:32 +10:00
|
|
|
}
|
|
|
|
|
|
2022-09-18 17:03:40 +12:00
|
|
|
/** Keep in sync with `SI_GRID_STEPS_LEN` in `DNA_space_types.h`. */
|
|
|
|
|
#define STEPS_LEN 8
|
|
|
|
|
int step_id_x = STEPS_LEN - 1;
|
|
|
|
|
int step_id_y = STEPS_LEN - 1;
|
|
|
|
|
|
|
|
|
|
/* Loop backwards a compile-time-constant number of steps. */
|
|
|
|
|
for (int i = STEPS_LEN - 2; i >= 0; --i) {
|
|
|
|
|
step_id_x = (grid_res < grid_buf.steps[i].x) ? i : step_id_x; /* Branchless. */
|
|
|
|
|
step_id_y = (grid_res < grid_buf.steps[i].y) ? i : step_id_y;
|
2019-08-19 11:49:07 -03:00
|
|
|
}
|
2022-04-28 21:13:04 +02:00
|
|
|
|
2022-09-18 17:03:40 +12:00
|
|
|
/* From biggest to smallest. */
|
2025-04-11 18:28:45 +02:00
|
|
|
float scale0x = step_id_x > 0 ? grid_buf.steps[step_id_x - 1].x : 0.0f;
|
2022-09-18 17:03:40 +12:00
|
|
|
float scaleAx = grid_buf.steps[step_id_x].x;
|
|
|
|
|
float scaleBx = grid_buf.steps[min(step_id_x + 1, STEPS_LEN - 1)].x;
|
|
|
|
|
float scaleCx = grid_buf.steps[min(step_id_x + 2, STEPS_LEN - 1)].x;
|
|
|
|
|
|
2025-04-11 18:28:45 +02:00
|
|
|
float scale0y = step_id_y > 0 ? grid_buf.steps[step_id_y - 1].y : 0.0f;
|
2022-09-18 17:03:40 +12:00
|
|
|
float scaleAy = grid_buf.steps[step_id_y].y;
|
|
|
|
|
float scaleBy = grid_buf.steps[min(step_id_y + 1, STEPS_LEN - 1)].y;
|
|
|
|
|
float scaleCy = grid_buf.steps[min(step_id_y + 2, STEPS_LEN - 1)].y;
|
|
|
|
|
|
|
|
|
|
/* Subtract from 1.0 to fix blending when `scale0x == scaleAx`. */
|
2025-04-11 18:28:45 +02:00
|
|
|
float blend = 1.0f - linearstep(scale0x + scale0y, scaleAx + scaleAy, grid_res + grid_res);
|
2019-08-19 11:49:07 -03:00
|
|
|
blend = blend * blend * blend;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float2 grid_pos, grid_fwidth;
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, PLANE_XZ)) {
|
|
|
|
|
grid_pos = P.xz;
|
2018-05-27 10:50:39 +02:00
|
|
|
grid_fwidth = fwidthPos.xz;
|
|
|
|
|
}
|
2022-04-28 21:13:04 +02:00
|
|
|
else if (flag_test(grid_flag, PLANE_YZ)) {
|
|
|
|
|
grid_pos = P.yz;
|
2018-05-27 10:50:39 +02:00
|
|
|
grid_fwidth = fwidthPos.yz;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2022-04-28 21:13:04 +02:00
|
|
|
grid_pos = P.xy;
|
2018-05-27 10:50:39 +02:00
|
|
|
grid_fwidth = fwidthPos.xy;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float gridA = get_grid(grid_pos, grid_fwidth, float2(scaleAx, scaleAy));
|
|
|
|
|
float gridB = get_grid(grid_pos, grid_fwidth, float2(scaleBx, scaleBy));
|
|
|
|
|
float gridC = get_grid(grid_pos, grid_fwidth, float2(scaleCx, scaleCy));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-04-26 11:28:24 +02:00
|
|
|
out_color = theme.colors.grid;
|
2022-04-28 21:13:04 +02:00
|
|
|
out_color.a *= gridA * blend;
|
2025-04-26 11:28:24 +02:00
|
|
|
out_color = mix(out_color, mix(theme.colors.grid, theme.colors.grid_emphasis, blend), gridB);
|
|
|
|
|
out_color = mix(out_color, theme.colors.grid_emphasis, gridC);
|
2017-03-25 02:46:23 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2025-04-26 11:28:24 +02:00
|
|
|
out_color = float4(theme.colors.grid.rgb, 0.0f);
|
2017-03-25 02:46:23 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, (SHOW_AXIS_X | SHOW_AXIS_Y | SHOW_AXIS_Z))) {
|
2017-05-27 21:35:03 +02:00
|
|
|
/* Setup axes 'domains' */
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 axes_dist, axes_fwidth;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, SHOW_AXIS_X)) {
|
|
|
|
|
axes_dist.x = dot(P.yz, plane_axes.yz);
|
|
|
|
|
axes_fwidth.x = dot(fwidthPos.yz, plane_axes.yz);
|
2017-03-25 02:46:23 +01:00
|
|
|
}
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, SHOW_AXIS_Y)) {
|
|
|
|
|
axes_dist.y = dot(P.xz, plane_axes.xz);
|
|
|
|
|
axes_fwidth.y = dot(fwidthPos.xz, plane_axes.xz);
|
2017-03-25 02:46:23 +01:00
|
|
|
}
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, SHOW_AXIS_Z)) {
|
|
|
|
|
axes_dist.z = dot(P.xy, plane_axes.xy);
|
|
|
|
|
axes_fwidth.z = dot(fwidthPos.xy, plane_axes.xy);
|
2017-03-25 02:46:23 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
/* Computing all axes at once using float3 */
|
|
|
|
|
float3 axes = get_axes(axes_dist, axes_fwidth, 0.1f);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, SHOW_AXIS_X)) {
|
|
|
|
|
out_color.a = max(out_color.a, axes.x);
|
2025-04-26 11:28:24 +02:00
|
|
|
out_color.rgb = (axes.x < 1e-8f) ? out_color.rgb : theme.colors.grid_axis_x.rgb;
|
2017-03-25 02:46:23 +01:00
|
|
|
}
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, SHOW_AXIS_Y)) {
|
|
|
|
|
out_color.a = max(out_color.a, axes.y);
|
2025-04-26 11:28:24 +02:00
|
|
|
out_color.rgb = (axes.y < 1e-8f) ? out_color.rgb : theme.colors.grid_axis_y.rgb;
|
2017-03-25 02:46:23 +01:00
|
|
|
}
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, SHOW_AXIS_Z)) {
|
|
|
|
|
out_color.a = max(out_color.a, axes.z);
|
2025-04-26 11:28:24 +02:00
|
|
|
out_color.rgb = (axes.z < 1e-8f) ? out_color.rgb : theme.colors.grid_axis_z.rgb;
|
2017-03-25 02:46:23 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float2 uv = gl_FragCoord.xy / float2(textureSize(depth_tx, 0));
|
2024-11-21 18:02:36 +01:00
|
|
|
float scene_depth = texture(depth_tx, uv, 0).r;
|
|
|
|
|
|
|
|
|
|
float scene_depth_infront = texture(depth_infront_tx, uv, 0).r;
|
2025-04-11 18:28:45 +02:00
|
|
|
if (scene_depth_infront != 1.0f) {
|
2024-11-21 18:02:36 +01:00
|
|
|
/* Treat in front objects as if they were on the near plane to occlude the grid. */
|
2025-04-11 18:28:45 +02:00
|
|
|
scene_depth = 0.0f;
|
2024-11-21 18:02:36 +01:00
|
|
|
}
|
|
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
if (flag_test(grid_flag, GRID_BACK)) {
|
2025-04-11 18:28:45 +02:00
|
|
|
fade *= (scene_depth == 1.0f) ? 1.0f : 0.0f;
|
2018-05-27 11:25:29 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2020-04-23 22:21:22 +02:00
|
|
|
/* Add a small bias so the grid will always be below of a mesh with the same depth. */
|
2025-04-11 18:28:45 +02:00
|
|
|
float grid_depth = gl_FragCoord.z + 4.8e-7f;
|
2018-05-27 11:25:29 +02:00
|
|
|
/* Manual, non hard, depth test:
|
|
|
|
|
* Progressively fade the grid below occluders
|
2018-09-19 18:19:49 +02:00
|
|
|
* (avoids popping visuals due to depth buffer precision) */
|
2018-05-27 11:25:29 +02:00
|
|
|
/* Harder settings tend to flicker more,
|
|
|
|
|
* but have less "see through" appearance. */
|
2025-05-05 09:59:00 +02:00
|
|
|
float bias = max(gpu_fwidth(gl_FragCoord.z), 2.4e-7f);
|
2020-04-23 22:21:22 +02:00
|
|
|
fade *= linearstep(grid_depth, grid_depth + bias, scene_depth);
|
2018-05-27 11:25:29 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-28 21:13:04 +02:00
|
|
|
out_color.a *= fade;
|
2018-04-22 08:44:23 +02:00
|
|
|
}
|