diff options
Diffstat (limited to 'source/blender/draw/modes/shaders/object_grid_frag.glsl')
-rw-r--r-- | source/blender/draw/modes/shaders/object_grid_frag.glsl | 316 |
1 files changed, 159 insertions, 157 deletions
diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl index 7d89676fd47..841b4a95b21 100644 --- a/source/blender/draw/modes/shaders/object_grid_frag.glsl +++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl @@ -18,23 +18,23 @@ uniform float lineKernel = 0.0; uniform float gridOneOverLogSubdiv; uniform sampler2D depthBuffer; -#define gridDistance gridSettings.x -#define gridResolution gridSettings.y -#define gridScale gridSettings.z -#define gridSubdiv gridSettings.w +#define gridDistance gridSettings.x +#define gridResolution gridSettings.y +#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 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_BACK (1 << 9) /* grid is behind objects */ -#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */ +#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */ /** * We want to know how much a pixel is covered by a line. @@ -49,159 +49,161 @@ uniform int gridFlag; float get_grid(vec2 co, vec2 fwidthCos, float grid_size) { - float half_size = grid_size / 2.0; - /* triangular wave pattern, amplitude is [0, half_size] */ - vec2 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; + float half_size = grid_size / 2.0; + /* triangular wave pattern, amplitude is [0, half_size] */ + vec2 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; - /* collapse waves */ - float line_dist = min(grid_domain.x, grid_domain.y); + /* collapse waves */ + float line_dist = min(grid_domain.x, grid_domain.y); - return 1.0 - smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, line_dist - lineKernel); + return 1.0 - smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, line_dist - lineKernel); } vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size) { - vec3 axes_domain = abs(co); - /* modulate by the absolute rate of change of the coordinates - * (make line have the same width under perspective) */ - axes_domain /= fwidthCos; - - return 1.0 - smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, axes_domain - (line_size + lineKernel)); + vec3 axes_domain = abs(co); + /* modulate by the absolute rate of change of the coordinates + * (make line have the same width under perspective) */ + axes_domain /= fwidthCos; + + return 1.0 - smoothstep(GRID_LINE_SMOOTH_START, + GRID_LINE_SMOOTH_END, + axes_domain - (line_size + lineKernel)); } void main() { - vec3 wPos = local_pos * meshSize; - vec3 fwidthPos = fwidth(wPos); - wPos += cameraPos * planeAxes; - - float dist, fade; - /* if persp */ - if (ProjectionMatrix[3][3] == 0.0) { - vec3 viewvec = cameraPos - wPos; - dist = length(viewvec); - viewvec /= dist; - - float angle; - if ((gridFlag & PLANE_XZ) != 0) { - angle = viewvec.y; - } - else if ((gridFlag & PLANE_YZ) != 0) { - angle = viewvec.x; - } - else { - angle = viewvec.z; - } - - angle = 1.0 - abs(angle); - angle *= angle; - fade = 1.0 - angle * angle; - fade *= 1.0 - smoothstep(0.0, gridDistance, dist - gridDistance); - } - else { - dist = abs(gl_FragCoord.z * 2.0 - 1.0); - fade = 1.0 - smoothstep(0.0, 0.5, dist - 0.5); - dist = 1.0; /* avoid branch after */ - - if ((gridFlag & PLANE_XY) != 0) { - float angle = 1.0 - abs(eye.z); - dist = 1.0 + angle * 2.0; - angle *= angle; - fade *= 1.0 - angle * angle; - } - } - - if ((gridFlag & GRID) != 0) { - float grid_res = log(dist * gridResolution) * gridOneOverLogSubdiv; - - float blend = fract(-max(grid_res, 0.0)); - float lvl = floor(grid_res); - - /* 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)); - - vec2 grid_pos, grid_fwidth; - if ((gridFlag & PLANE_XZ) != 0) { - grid_pos = wPos.xz; - grid_fwidth = fwidthPos.xz; - } - else if ((gridFlag & PLANE_YZ) != 0) { - grid_pos = wPos.yz; - grid_fwidth = fwidthPos.yz; - } - else { - grid_pos = wPos.xy; - grid_fwidth = fwidthPos.xy; - } - - float gridA = get_grid(grid_pos, grid_fwidth, scaleA); - float gridB = get_grid(grid_pos, grid_fwidth, scaleB); - float gridC = get_grid(grid_pos, grid_fwidth, scaleC); - - FragColor = colorGrid; - FragColor.a *= gridA * blend; - FragColor = mix(FragColor, mix(colorGrid, colorGridEmphasise, blend), gridB); - FragColor = mix(FragColor, colorGridEmphasise, gridC); - } - else { - FragColor = vec4(colorGrid.rgb, 0.0); - } - - 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); - } - if ((gridFlag & AXIS_Y) != 0) { - axes_dist.y = dot(wPos.xz, planeAxes.xz); - axes_fwidth.y = dot(fwidthPos.xz, planeAxes.xz); - } - if ((gridFlag & AXIS_Z) != 0) { - axes_dist.z = dot(wPos.xy, planeAxes.xy); - axes_fwidth.z = dot(fwidthPos.xy, planeAxes.xy); - } - - /* Computing all axes at once using vec3 */ - vec3 axes = get_axes(axes_dist, axes_fwidth, 0.1); - - if ((gridFlag & AXIS_X) != 0) { - FragColor.a = max(FragColor.a, axes.x); - FragColor.rgb = (axes.x < 1e-8) ? FragColor.rgb : colorGridAxisX.rgb; - } - if ((gridFlag & AXIS_Y) != 0) { - FragColor.a = max(FragColor.a, axes.y); - FragColor.rgb = (axes.y < 1e-8) ? FragColor.rgb : colorGridAxisY.rgb; - } - if ((gridFlag & AXIS_Z) != 0) { - FragColor.a = max(FragColor.a, axes.z); - FragColor.rgb = (axes.z < 1e-8) ? FragColor.rgb : colorGridAxisZ.rgb; - } - } - - /* Add a small bias so the grid will always - * be on top of a mesh with the same depth. */ - float grid_depth = gl_FragCoord.z - 6e-8 - fwidth(gl_FragCoord.z); - float scene_depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; - if ((gridFlag & GRID_BACK) != 0) { - fade *= (scene_depth == 1.0) ? 1.0 : 0.0; - } - else { - /* Manual, non hard, depth test: - * Progressively fade the grid below occluders - * (avoids popping visuals due to depth buffer precision) */ - /* Harder settings tend to flicker more, - * but have less "see through" appearance. */ - const float test_hardness = 1e7; - fade *= 1.0 - clamp((grid_depth - scene_depth) * test_hardness, 0.0, 1.0); - } - - FragColor.a *= fade; + vec3 wPos = local_pos * meshSize; + vec3 fwidthPos = fwidth(wPos); + wPos += cameraPos * planeAxes; + + float dist, fade; + /* if persp */ + if (ProjectionMatrix[3][3] == 0.0) { + vec3 viewvec = cameraPos - wPos; + dist = length(viewvec); + viewvec /= dist; + + float angle; + if ((gridFlag & PLANE_XZ) != 0) { + angle = viewvec.y; + } + else if ((gridFlag & PLANE_YZ) != 0) { + angle = viewvec.x; + } + else { + angle = viewvec.z; + } + + angle = 1.0 - abs(angle); + angle *= angle; + fade = 1.0 - angle * angle; + fade *= 1.0 - smoothstep(0.0, gridDistance, dist - gridDistance); + } + else { + dist = abs(gl_FragCoord.z * 2.0 - 1.0); + fade = 1.0 - smoothstep(0.0, 0.5, dist - 0.5); + dist = 1.0; /* avoid branch after */ + + if ((gridFlag & PLANE_XY) != 0) { + float angle = 1.0 - abs(eye.z); + dist = 1.0 + angle * 2.0; + angle *= angle; + fade *= 1.0 - angle * angle; + } + } + + if ((gridFlag & GRID) != 0) { + float grid_res = log(dist * gridResolution) * gridOneOverLogSubdiv; + + float blend = fract(-max(grid_res, 0.0)); + float lvl = floor(grid_res); + + /* 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)); + + vec2 grid_pos, grid_fwidth; + if ((gridFlag & PLANE_XZ) != 0) { + grid_pos = wPos.xz; + grid_fwidth = fwidthPos.xz; + } + else if ((gridFlag & PLANE_YZ) != 0) { + grid_pos = wPos.yz; + grid_fwidth = fwidthPos.yz; + } + else { + grid_pos = wPos.xy; + grid_fwidth = fwidthPos.xy; + } + + float gridA = get_grid(grid_pos, grid_fwidth, scaleA); + float gridB = get_grid(grid_pos, grid_fwidth, scaleB); + float gridC = get_grid(grid_pos, grid_fwidth, scaleC); + + FragColor = colorGrid; + FragColor.a *= gridA * blend; + FragColor = mix(FragColor, mix(colorGrid, colorGridEmphasise, blend), gridB); + FragColor = mix(FragColor, colorGridEmphasise, gridC); + } + else { + FragColor = vec4(colorGrid.rgb, 0.0); + } + + 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); + } + if ((gridFlag & AXIS_Y) != 0) { + axes_dist.y = dot(wPos.xz, planeAxes.xz); + axes_fwidth.y = dot(fwidthPos.xz, planeAxes.xz); + } + if ((gridFlag & AXIS_Z) != 0) { + axes_dist.z = dot(wPos.xy, planeAxes.xy); + axes_fwidth.z = dot(fwidthPos.xy, planeAxes.xy); + } + + /* Computing all axes at once using vec3 */ + vec3 axes = get_axes(axes_dist, axes_fwidth, 0.1); + + if ((gridFlag & AXIS_X) != 0) { + FragColor.a = max(FragColor.a, axes.x); + FragColor.rgb = (axes.x < 1e-8) ? FragColor.rgb : colorGridAxisX.rgb; + } + if ((gridFlag & AXIS_Y) != 0) { + FragColor.a = max(FragColor.a, axes.y); + FragColor.rgb = (axes.y < 1e-8) ? FragColor.rgb : colorGridAxisY.rgb; + } + if ((gridFlag & AXIS_Z) != 0) { + FragColor.a = max(FragColor.a, axes.z); + FragColor.rgb = (axes.z < 1e-8) ? FragColor.rgb : colorGridAxisZ.rgb; + } + } + + /* Add a small bias so the grid will always + * be on top of a mesh with the same depth. */ + float grid_depth = gl_FragCoord.z - 6e-8 - fwidth(gl_FragCoord.z); + float scene_depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; + if ((gridFlag & GRID_BACK) != 0) { + fade *= (scene_depth == 1.0) ? 1.0 : 0.0; + } + else { + /* Manual, non hard, depth test: + * Progressively fade the grid below occluders + * (avoids popping visuals due to depth buffer precision) */ + /* Harder settings tend to flicker more, + * but have less "see through" appearance. */ + const float test_hardness = 1e7; + fade *= 1.0 - clamp((grid_depth - scene_depth) * test_hardness, 0.0, 1.0); + } + + FragColor.a *= fade; } |