Files
nodarium/app/src/lib/graph-interface/background/Background.frag

113 lines
3.2 KiB
GLSL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
precision highp float;
// For WebGL1 make sure this extension is enabled in your material:
// #extension GL_OES_standard_derivatives : enable
varying vec2 vUv;
const float PI = 3.14159265359;
uniform vec2 dimensions;
uniform vec3 camPos;
uniform vec2 zoomLimits;
uniform vec3 backgroundColor;
uniform vec3 lineColor;
// Anti-aliased step: threshold in the same units as `value`
float aaStep(float threshold, float value, float deriv) {
float w = deriv * 0.5; // ~one pixel
return smoothstep(threshold - w, threshold + w, value);
}
float grid(float x, float y, float divisions, float thickness) {
// Continuous grid coordinates
float gx = x * divisions;
float gy = y * divisions;
// Distance to nearest grid line (0 at the line)
float fx = fract(gx);
fx = min(fx, 1.0 - fx);
float fy = fract(gy);
fy = min(fy, 1.0 - fy);
// Derivatives in screen space use the continuous coords here
float dx = fwidth(gx);
float dy = fwidth(gy);
// Keep the original semantics: thickness is the threshold in the [0, 0.5] distance domain
float lineX = 1.0 - aaStep(thickness, fx, dx);
float lineY = 1.0 - aaStep(thickness, fy, dy);
return clamp(lineX + lineY, 0.0, 1.0);
}
float circle_grid(float x, float y, float divisions, float circleRadius) {
float gridX = mod(x + divisions * 0.5, divisions) - divisions * 0.5;
float gridY = mod(y + divisions * 0.5, divisions) - divisions * 0.5;
vec2 g = vec2(gridX, gridY);
float d = length(g);
// Screen-space derivative for AA on the circle edge
float w = fwidth(d);
float circle = 1.0 - smoothstep(circleRadius - w, circleRadius + w, d);
return circle;
}
float lerp(float a, float b,float t) {
return a * (1.0 - t) + b * t;
}
void main(void) {
float cx = camPos.x;
float cy = camPos.y;
float cz = camPos.z;
float width = dimensions.x;
float height = dimensions.y;
float minZ = zoomLimits.x;
float maxZ = zoomLimits.y;
float divisions = 0.1 / cz;
float thickness = 0.05 / cz;
float nz = (cz - minZ) / (maxZ - minZ);
float ux = (vUv.x - 0.5) * width + cx * cz;
float uy = (vUv.y - 0.5) * height - cy * cz;
// extra small grid
float m1 = grid(ux, uy, divisions * 4.0, thickness * 4.0) * 0.9;
float m2 = grid(ux, uy, divisions * 16.0, thickness * 16.0) * 0.5;
float xsmall = max(m1, m2);
float s3 = circle_grid(ux, uy, cz / 1.6, 1.0) * 0.5;
xsmall = max(xsmall, s3);
// small grid
float c1 = grid(ux, uy, divisions, thickness) * 0.6;
float c2 = grid(ux, uy, divisions * 2.0, thickness * 2.0) * 0.5;
float small = max(c1, c2);
float s1 = circle_grid(ux, uy, cz * 10.0, 2.0) * 0.5;
small = max(small, s1);
// large grid
float c3 = grid(ux, uy, divisions / 8.0, thickness / 8.0) * 0.5;
float c4 = grid(ux, uy, divisions / 2.0, thickness / 4.0) * 0.4;
float large = max(c3, c4);
float s2 = circle_grid(ux, uy, cz * 20.0, 1.0) * 0.4;
large = max(large, s2);
float c = mix(large, small, min(nz * 2.0 + 0.05, 1.0));
c = mix(c, xsmall, clamp((nz - 0.3) / 0.7, 0.0, 1.0));
vec3 color = mix(backgroundColor, lineColor, c);
gl_FragColor = vec4(color, 1.0);
}