Files
site-portfolio/public/vendor/paper-shaders/shaders/dot-grid.js
T
root daa623fe73 feat(mesh-bg): fade-in шейдера фона + modulepreload графа
- canvas стартует с opacity:0 и плавно проявляется (0.9s) при .is-ready
- initPageMeshShader ставит is-ready после первого кадра
- modulepreload page-mesh-shader.js для параллельной загрузки с main.js
- пересборка страниц (build:pages)
2026-09-24 21:37:40 +02:00

111 lines
2.9 KiB
JavaScript

/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Paper Shaders *
* https://github.com/paper-design/shaders *
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
import {} from "../shader-sizing.js";
import { declarePI, simplexNoise } from "../shader-utils.js";
const dotGridFragmentShader = `#version 300 es
precision mediump float;
uniform vec4 u_colorBack;
uniform vec4 u_colorFill;
uniform vec4 u_colorStroke;
uniform float u_dotSize;
uniform float u_gapX;
uniform float u_gapY;
uniform float u_strokeWidth;
uniform float u_sizeRange;
uniform float u_opacityRange;
uniform float u_shape;
in vec2 v_patternUV;
out vec4 fragColor;
${declarePI}
${simplexNoise}
float polygon(vec2 p, float N, float rot) {
float a = atan(p.x, p.y) + rot;
float r = TWO_PI / float(N);
return cos(floor(.5 + a / r) * r - a) * length(p);
}
void main() {
// x100 is a default multiplier between vertex and fragmant shaders
// we use it to avoid UV presision issues
vec2 shape_uv = 100. * v_patternUV;
vec2 gap = max(abs(vec2(u_gapX, u_gapY)), vec2(1e-6));
vec2 grid = fract(shape_uv / gap) + 1e-4;
vec2 grid_idx = floor(shape_uv / gap);
float sizeRandomizer = .5 + .8 * snoise(2. * vec2(grid_idx.x * 100., grid_idx.y));
float opacity_randomizer = .5 + .7 * snoise(2. * vec2(grid_idx.y, grid_idx.x));
vec2 center = vec2(0.5) - 1e-3;
vec2 p = (grid - center) * vec2(u_gapX, u_gapY);
float baseSize = u_dotSize * (1. - sizeRandomizer * u_sizeRange);
float strokeWidth = u_strokeWidth * (1. - sizeRandomizer * u_sizeRange);
float dist;
if (u_shape < 0.5) {
// Circle
dist = length(p);
} else if (u_shape < 1.5) {
// Diamond
strokeWidth *= 1.5;
dist = polygon(1.5 * p, 4., .25 * PI);
} else if (u_shape < 2.5) {
// Square
dist = polygon(1.03 * p, 4., 1e-3);
} else {
// Triangle
strokeWidth *= 1.5;
p = p * 2. - 1.;
p *= .9;
p.y = 1. - p.y;
p.y -= .75 * baseSize;
dist = polygon(p, 3., 1e-3);
}
float edgeWidth = fwidth(dist);
float shapeOuter = 1. - smoothstep(baseSize - edgeWidth, baseSize + edgeWidth, dist - strokeWidth);
float shapeInner = 1. - smoothstep(baseSize - edgeWidth, baseSize + edgeWidth, dist);
float stroke = shapeOuter - shapeInner;
float dotOpacity = max(0., 1. - opacity_randomizer * u_opacityRange);
stroke *= dotOpacity;
shapeInner *= dotOpacity;
stroke *= u_colorStroke.a;
shapeInner *= u_colorFill.a;
vec3 color = vec3(0.);
color += stroke * u_colorStroke.rgb;
color += shapeInner * u_colorFill.rgb;
color += (1. - shapeInner - stroke) * u_colorBack.rgb * u_colorBack.a;
float opacity = 0.;
opacity += stroke;
opacity += shapeInner;
opacity += (1. - opacity) * u_colorBack.a;
fragColor = vec4(color, opacity);
}
`;
const DotGridShapes = {
circle: 0,
diamond: 1,
square: 2,
triangle: 3
};
export {
DotGridShapes,
dotGridFragmentShader
};
//# sourceMappingURL=dot-grid.js.map