token waste

copperpatina.tsx

Shaders

About

Webgl Background with subtle movement

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds copperpatina.tsx to your project and fits it to your theme.

Code

How copperpatina.tsx is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

/**
 * @generated 2026-01-01T19:39:25.348Z
 * @engine GlitchForge Elite v2.5
 * @compatibility React 18.x
 */

'use client';

import React, { useEffect, useRef, useMemo, useCallback, useState } from 'react';

const VERTEX_SHADER_SOURCE = `#version 300 es
in vec2 position;
void main() {
  gl_Position = vec4(position, 0.0, 1.0);
}`;
const FRAGMENT_SHADER_SOURCE = `#version 300 es
precision highp float;
uniform vec2 r;
uniform float t;
uniform vec3 u_c1, u_c2, u_c3, u_c4, u_c5;
uniform float u_zoom, u_complexity, u_speed, u_distortion;
out vec4 fragColor;

float hash(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); }
float noise(vec2 p) {
    vec2 i = floor(p), f = fract(p);
    f = f*f*(3.0-2.0*f);
    return mix(mix(hash(i), hash(i+vec2(1,0)), f.x), mix(hash(i+vec2(0,1)), hash(i+vec2(1,1)), f.x), f.y);
}
float fbm(vec2 p) {
    float v = 0.0, a = 0.5;
    for(int i=0; i<8; i++) {
        if(float(i) > u_complexity * 0.1) break;
        v += a * noise(p); p *= 2.0; a *= 0.5;
    }
    return v;
}
void main() {
    vec2 uv = gl_FragCoord.xy / r;
    float time = t * u_speed;
    vec2 p = (uv * 2.0 - 1.0) * u_zoom;
    
    // Triple Nested Domain Warping
    vec2 q = vec2(fbm(p + time * 0.1), fbm(p + vec2(1.0)));
    vec2 b = vec2(fbm(p + 4.0*q + vec2(1.7, 9.2) + 0.15*time), fbm(p + 4.0*q + vec2(8.3, 2.8) + 0.126*time));
    float f = fbm(p + 4.0*b);
    
    vec3 col = mix(u_c1, u_c2, clamp((f*f)*4.0, 0.0, 1.0));
    col = mix(col, u_c3, clamp(length(q), 0.0, 1.0));
    col = mix(col, u_c4, clamp(length(b.x), 0.0, 1.0));
    
    fragColor = vec4(col * f * (1.0 + u_distortion * 0.1), 1.0);
}`;
const PALETTE_RGB = [{"r":0.01568627450980392,"g":0.3333333333333333,"b":0.9647058823529412},{"r":0,"g":0.9333333333333333,"b":1},{"r":0.00392156862745098,"g":0.9764705882352941,"b":0.8627450980392157},{"r":1,"g":0.30196078431372547,"b":0},{"r":0.17254901960784313,"g":0.01568627450980392,"b":0.9647058823529412}] as const;

export const Forge_Dominionwarp: React.FC = () => {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const requestRef = useRef<number>();
  const startTimeRef = useRef<number>(Date.now());
  const [webglSupported, setWebglSupported] = useState(true);

  const handleResize = useCallback(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const gl = canvas.getContext('webgl2');
    if (!gl) return;
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    gl.viewport(0, 0, canvas.width, canvas.height);
  }, []);

  useEffect(() => {
    

    const canvas = canvasRef.current;
    if (!canvas) return;
    const gl = canvas.getContext('webgl2', { antialias: true, alpha: false, powerPreference: 'high-performance' });
    if (!gl) { setWebglSupported(false); return; }

    let program: WebGLProgram | null = null, vs: WebGLShader | null = null, fs: WebGLShader | null = null;
    let vao: WebGLVertexArrayObject | null = null, vbo: WebGLBuffer | null = null, locs: any = {};

    const setup = () => {
      vs = gl.createShader(gl.VERTEX_SHADER)!; gl.shaderSource(vs, VERTEX_SHADER_SOURCE); gl.compileShader(vs);
      fs = gl.createShader(gl.FRAGMENT_SHADER)!; gl.shaderSource(fs, FRAGMENT_SHADER_SOURCE); gl.compileShader(fs);
      program = gl.createProgram()!; gl.attachShader(program, vs); gl.attachShader(program, fs); gl.linkProgram(program);
      gl.useProgram(program);

      const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
      vao = gl.createVertexArray(); vbo = gl.createBuffer();
      gl.bindVertexArray(vao); gl.bindBuffer(gl.ARRAY_BUFFER, vbo); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
      const posLoc = gl.getAttribLocation(program, 'position');
      gl.enableVertexAttribArray(posLoc); gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);

      locs = {
        r: gl.getUniformLocation(program, 'r'),
        t: gl.getUniformLocation(program, 't'),
        zoom: gl.getUniformLocation(program, 'u_zoom'),
        comp: gl.getUniformLocation(program, 'u_complexity'),
        speed: gl.getUniformLocation(program, 'u_speed'),
        dist: gl.getUniformLocation(program, 'u_distortion'),
        colors: PALETTE_RGB.map((_, i) => gl.getUniformLocation(program!, `u_c${i + 1}`))
      };
    };

    setup();
    const onLost = (e: Event) => e.preventDefault();
    const onRestored = () => { setup(); render(); };
    canvas.addEventListener('webglcontextlost', onLost);
    canvas.addEventListener('webglcontextrestored', onRestored);
    window.addEventListener('resize', handleResize); handleResize();

    const render = () => {
      if (!gl || !program) return;
      gl.useProgram(program);
      const t = (Date.now() - startTimeRef.current) / 1000;
      gl.uniform2f(locs.r, canvas.width, canvas.height); gl.uniform1f(locs.t, t);
      gl.uniform1f(locs.zoom, 1.5); gl.uniform1f(locs.comp, 150);
      gl.uniform1f(locs.speed, 0.1); gl.uniform1f(locs.dist, 5);
      PALETTE_RGB.forEach((rgb, i) => { if (locs.colors[i]) gl.uniform3f(locs.colors[i], rgb.r, rgb.g, rgb.b); });
      gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
      requestRef.current = requestAnimationFrame(render);
    };
    render();

    return () => {
      window.removeEventListener('resize', handleResize);
      if (requestRef.current) cancelAnimationFrame(requestRef.current);
      gl.deleteProgram(program);
      gl.deleteShader(vs);
      gl.deleteShader(fs);
      gl.deleteBuffer(vbo);
      gl.deleteVertexArray(vao);
    };
  }, [handleResize]);

  const layers = useMemo(() => [], []);

  if (!webglSupported) return <div style={{background:'#000', color:'#fff', padding:'20px', textAlign: 'center'}}>WebGL2 Not Supported</div>;

  return (
    <div style={{ position: 'fixed', inset: 0, background: '#000', overflow: 'hidden' }}>
      <canvas ref={canvasRef} style={{ display: 'block', width: '100%', height: '100%' }} />
      <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
        {layers.map(l => (
          <div key={l.id} style={{ position: 'fixed', left: `${l.x}%`, top: `${l.y}%`, transform: `translate(-50%, -50%) rotate(${l.rotation}deg)`, opacity: l.opacity, color: l.color, fontSize: `${l.size}px`, fontFamily: l.font, fontWeight: 700, whiteSpace: 'pre' }}>{l.text}</div>
        ))}
      </div>
    </div>
  );
};

export default Forge_Dominionwarp;

More by token waste

View all
  • shadergen.tsx

    shadergen.tsx

More in Shaders

View all
  • Glass Fold

    Glass Fold

    193
  • Paper design shader Background

    Paper design shader Background

    672
  • Wave

    Wave

    683
  • LightSpeed

    LightSpeed

    206
  • Neural Noise

    Neural Noise

    711
  • DitheredShaderBackground

    DitheredShaderBackground

    43
  • Gigabit

    Gigabit

    55
  • Shader Lines

    Shader Lines

    2.3K