WebGL Background #2

If you don't known how to prepare your page for using WebGL, I recommend you to read this article about how to manage all necessary infrastructure.

For that background I use a combination of simple noise and hexagonal pattern from here. Here is my noise code (I use a random from position function, but add a scale):

float rand(vec2 pos) {
    return fract(sin(dot(pos,
                         vec2(12.9898, 78.233))) *
                 43758.5453123);
}

float white_noise(vec2 pos, vec2 steps) {
    vec2 scaled_pos = floor(pos * steps);
    return rand(scaled_pos);
}
                

Then we need a hexagonal pattern generator:

float hex(vec2 pos, vec2 steps) {
    vec2 p = (pos * steps);
    p.x *= 0.57735 * 2.0;
    p.y += mod(floor(p.x), 2.0) * 0.5;
    p = abs((mod(p, 1.0) - 0.5));
    return pow(abs(max(p.x * 1.5 + p.y, p.y * 2.0) - 1.0), 0.25);
}
                

I use steps to set a number of bricks for horizontal and vertical dimensions. To create variative number we use two values, but it's possible to use only single one.

Now we have prepared everything we need. So let's combine it in the main function. Firstly we need to generate random bricks and animate them:

float lum = white_noise(uv, uResolution * 0.02 * vec2(5.0, 3.0));
lum = sin(lum * uTime * 3.0) * 0.5 + 0.5;
lum = 0.25 + 0.75 * lum;
                
  • uv - a current position in viewport (in range [0; 1]).
  • uResolution - a resolutoin of viewport in pixels.
  • uResolution * 0.02 - until using a ratio we have side_length / 50 bricks along each side, so we have constant size of patterns independent on window size.
  • vec2(5.0, 3.0) - a ratio of bricks' sides.
  • lum = sin(lum * uTime * 3.0) * 0.5 + 0.5; - changing of value during a time in the range [0; 1]. You can increase the speed of the animation changing 3.0 to a greater value.
  • lum = 0.25 + 0.75 * lum; - change the range of final values to [0.25; 1.0].

The second step is combining with hexagonal pattern and colorisation:

lum *= hex(uv, uResolution * 0.15);

vec3 clr = vec3(0.2, 0.381, 0.541); 

gl_FragColor = vec4(lum * clr, 1.0);
                

And, of course, you can just look at the page code to see the whole implementation of the effect. So below is whole fragment shader code:

#ifdef GL_ES
    precision highp float;
#endif

uniform vec2 uResolution;
uniform float uTime;

varying vec2 tPos;

float rand(vec2 pos) {
    return fract(sin(dot(pos,
                         vec2(12.9898, 78.233))) *
                 43758.5453123);
}

float white_noise(vec2 pos, vec2 steps) {
    vec2 scaled_pos = floor(pos * steps);
    return rand(scaled_pos);
}

float hex(vec2 pos, vec2 steps) {
    vec2 p = (pos * steps);
    p.x *= 0.57735 * 2.0;
    p.y += mod(floor(p.x), 2.0) * 0.5;
    p = abs((mod(p, 1.0) - 0.5));
    return pow(abs(max(p.x * 1.5 + p.y, p.y * 2.0) - 1.0), 0.25);
}

void main(void)
{
    vec2 uv = tPos;
    
    float lum = white_noise(uv, uResolution * 0.02 * vec2(5.0, 3.0));
    lum = sin(lum * uTime * 3.0) * 0.5 + 0.5;
    lum = 0.25 + 0.75 * lum;
    
    lum *= hex(uv, uResolution * 0.15);
    
    vec3 clr = vec3(0.2, 0.381, 0.541); 
    gl_FragColor = vec4(lum * clr, 1.0);
}