- canvas стартует с opacity:0 и плавно проявляется (0.9s) при .is-ready - initPageMeshShader ставит is-ready после первого кадра - modulepreload page-mesh-shader.js для параллельной загрузки с main.js - пересборка страниц (build:pages)
111 lines
2.9 KiB
JavaScript
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
|