summaryrefslogtreecommitdiff
path: root/themes/src/_shaders/snowflake.frag
blob: d887cf540b76f7c94b87332e90a6086c6e93a606 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Procedural star fragment shader
varying lowp vec2 vUV;
varying lowp float vSeed;
varying lowp float vScale;

const lowp float PI = 3.14159265359;

// Simple hash function for deterministic randomness
lowp float hash(lowp float n) {
    return fract(sin(n) * 43758.5453123);
}

// Generate star pattern procedurally
lowp float starPattern(lowp vec2 uv) {
    lowp float dist = length(uv);
    lowp float angle = atan(uv.y, uv.x);

    // Number of star points (4 or 5)
    lowp float numPoints = 4.0 + floor(hash(vSeed) * 2.0);

    // Create sharp star with triangular points
    lowp float angleStep = 2.0 * PI / numPoints;
    lowp float currentAngle = mod(angle + PI / numPoints, angleStep) - angleStep * 0.5;

    // Create triangular points - distance from center to edge varies linearly with angle
    lowp float normalizedAngle = abs(currentAngle) / (angleStep * 0.5);

    // Outer tip radius and inner valley radius
    lowp float tipRadius = 0.5;
    lowp float valleyRadius = 0.15;

    // Linear interpolation creates sharp triangular points
    lowp float rayEdge = mix(tipRadius, valleyRadius, normalizedAngle);

    // Hard cutoff for sharp edges
    lowp float star = step(dist, rayEdge);

    return star;
}

void main() {
    lowp float pattern = starPattern(vUV);

    // Color variation based on seed - white and blue tints
    lowp float colorVar = hash(vSeed * 3.0);
    lowp vec3 starColor;

    if (colorVar < 0.5) {
        // Pure white
        starColor = vec3(1.0, 1.0, 1.0);
    } else if (colorVar < 0.75) {
        // Light blue tint
        starColor = vec3(0.9, 0.95, 1.0);
    } else {
        // Stronger blue tint
        starColor = vec3(0.85, 0.92, 1.0);
    }

    // Scale alpha based on size - smaller stars are more transparent
    // Normalize scale from range [16, 48] to [0, 1]
    lowp float sizeRatio = (vScale - 16.0) / (48.0 - 16.0);
    // Map to alpha range [0.3, 1.0] - smaller stars at 30% opacity, larger at 100%
    lowp float alpha = mix(0.3, 1.0, sizeRatio);

    lowp vec4 color = vec4(starColor, pattern * alpha);

    // Discard fully transparent pixels for performance
    if (color.a < 0.01) {
        discard;
    }

    gl_FragColor = color;
}