<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Holographic Circle with interference</title>

  <style>

    body, html { margin: 0; padding: 0; overflow: hidden; }

    canvas { display: block; }

  </style>

</head>

<body>

  <canvas id="shaderCanvas"></canvas>

  <script>

    const vertexShaderSource = `

      attribute vec4 position;

      varying vec2 vUv;

      void main() {

        gl_Position = position;

        vUv = position.xy * 0.5 + 0.5;

      }

    `;

    const fragmentShaderSource = `

      precision highp float;

      uniform float time;

      uniform vec2 resolution;

      varying vec2 vUv;

      #define PI 3.141592653589793

      #define TAU (2.0 * PI)

      // Circular wave interference

      vec3 holographicInterference(vec2 uv, float t) {

        // Center of the screen

        vec2 center = vec2(0.5, 0.5);

        uv -= center;

        // Distance from the center

        float dist = length(uv);

        // Circular wave pattern

        float wave = sin(dist * 2.0 - t * 0.2);

        // Color based on wave interference

        vec3 color = vec3(

          0.5 + 0.5 * sin(wave + t), // Red

          0.25 + 0.5 * cos(wave + t * 2.7), // Green

          0.5 + 0.25 * sin(wave + t * 10.3) // Blue

        );

        // Add a glow effect

        float glow = smoothstep(0.3, 0.0, dist);

        color *= glow;

        return color;

      }

      void main() {

        vec2 uv = vUv;

        
        // Dynamic holographic effect

        float t = time * 0.25;

        vec3 holoColor = holographicInterference(uv, t);

        gl_FragColor = vec4(holoColor, 1.0);

      }

    `;

    const canvas = document.getElementById('shaderCanvas');

    const gl = canvas.getContext('webgl');

    if (!gl) throw new Error('WebGL not supported');

    function compileShader(gl, source, type) {

      const shader = gl.createShader(type);

      gl.shaderSource(shader, source);

      gl.compileShader(shader);

      if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {

        console.error('Shader error:', gl.getShaderInfoLog(shader));

        return null;

      }

      return shader;

    }

    const vertexShader = compileShader(gl, vertexShaderSource, gl.VERTEX_SHADER);

    const fragmentShader = compileShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER);

    const program = gl.createProgram();

    gl.attachShader(program, vertexShader);

    gl.attachShader(program, fragmentShader);

    gl.linkProgram(program);

    gl.useProgram(program);

    const positionBuffer = gl.createBuffer();

    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);

    const positionLocation = gl.getAttribLocation(program, 'position');

    gl.enableVertexAttribArray(positionLocation);

    gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

    const timeLocation = gl.getUniformLocation(program, 'time');

    const resolutionLocation = gl.getUniformLocation(program, 'resolution');

    function render(time) {

      time *= 0.001;

      gl.uniform1f(timeLocation, time);

      gl.uniform2f(resolutionLocation, canvas.width, canvas.height);

      gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

      requestAnimationFrame(render);

    }

    function resize() {

      canvas.width = window.innerWidth;

      canvas.height = window.innerHeight;

      gl.viewport(0, 0, canvas.width, canvas.height);

    }

    window.addEventListener('resize', resize);

    resize();

    requestAnimationFrame(render);

  </script>

</body>

</html>

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.