<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>
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.