Back to Components
A fully animated WebGL shader effect that renders fiery tendril‑like energy on a full‑screen canvas.
Component

A fully animated WebGL shader effect that renders fiery tendril‑like energy on a full‑screen canvas.

CodewithLord
November 29, 2025

This component produces Tendril Fire Energy, inspired by a Fire Titan aura.

🔥 Description

This component produces Tendril Fire Energy, inspired by a Fire Titan aura. It twists, rotates, and animates fractal‑like tendrils using pure WebGL fragment shaders.

🧠 How the Effect Works (Explanation)

1️⃣ Canvas + WebGL Setup

  • A full‑screen <canvas> is used.

  • JavaScript initializes WebGL, loads shaders, creates buffers, and renders every frame.


2️⃣ Vertex Shader

  • Passes full‑screen quad coordinates directly to the fragment shader.

  • Does not modify shapes — all visuals are in the fragment shader.


3️⃣ Fragment Shader (Main Magic)

  • Normalizes pixel coordinates.

  • Rotates them using time‑based rotation matrices.

  • Computes radial + angular distortions.

  • Uses a custom color function palette3() to generate flowing, fiery gradients.

  • Layers 5 tendrils using a loop.

  • Creates glowing intensity using pow() and sin().


4️⃣ JavaScript Rendering

  • Sends u_time and u_resolution every frame.
  • Uses requestAnimationFrame() for smooth animation.

📄 HTML Code

1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <title>tendrils</title> 6 <link rel="stylesheet" href="./style.css" /> 7 </head> 8 <body> 9 <canvas id="glcanvas"></canvas> 10 11 <script id="vertex-shader" type="x-shader/x-vertex"> 12 attribute vec2 a_position; 13 void main() { 14 gl_Position = vec4(a_position, 0.0, 1.0); 15 } 16 </script> 17 18 <script id="fragment-shader" type="x-shader/x-fragment"> 19#ifdef GL_ES 20precision highp float; 21#endif 22 23uniform vec2 u_resolution; 24uniform vec2 u_mouse; 25uniform float u_time; 26 27vec3 palette3(float t, float factor) { 28 vec3 a = vec3(0.5) + 0.3 * sin(vec3(0.1, 0.3, 0.5) * factor); 29 vec3 b = vec3(0.5) + 0.3 * cos(vec3(0.2, 0.4, 0.6) * factor); 30 vec3 c = vec3(1.0) + 0.5 * sin(vec3(0.3, 0.7, 0.9) * factor); 31 vec3 d = vec3(0.25, 0.4, 0.55) + 0.2 * cos(vec3(0.5, 0.6, 0.7) * factor); 32 return a + b * cos(6.28318 * (c * t + d)); 33} 34 35void main() { 36 vec2 st = (gl_FragCoord.xy / u_resolution.xy) * 2.0 - 1.0; 37 st.x *= u_resolution.x/u_resolution.y; 38 vec3 color = vec3(0.0); 39 40 for (float i = 1.0; i < 6.0; i++) { 41 vec2 st0 = st; 42 float sgn = 1.0 - 2.0 * mod(i, 2.0); 43 float t = u_time * 0.02 - float(i); 44 st0 *= mat2(cos(t), sin(t), -sin(t), cos(t)); 45 46 float R = length(st0); 47 float d = R * i; 48 float angle = atan(st0.y, st0.x) * 3.0; 49 50 vec3 pal = palette3(-exp((length(d) * -0.9)), abs(d) * 0.4); 51 52 float radial = exp(-R); 53 radial *= smoothstep(1.2, 0.5, R); 54 pal *= radial; 55 56 float phase = -(d + sgn * angle) + u_time * 0.3; 57 float v = sin(phase); 58 v = max(abs(v), 0.02); 59 float w = pow(0.02 / v, 0.8); 60 61 color += pal * w; 62 } 63 64 gl_FragColor = vec4(color, 1.0); 65} 66 </script> 67 68 <script src="./script.js"></script> 69 </body> 70</html>



🎨 CSS Code

1body { 2 height: 100vh; 3 margin: 0; 4} 5body, 6html { 7 overflow: hidden; 8}



🧠 JavaScript Code

1const canvas = document.getElementById('glcanvas'); 2const gl = canvas.getContext('webgl'); 3 4canvas.width = window.innerWidth; 5canvas.height = window.innerHeight; 6 7function getShaderSource(id) { 8 return document.getElementById(id).textContent; 9} 10 11const vertexShaderSource = getShaderSource('vertex-shader'); 12const fragmentShaderSource = getShaderSource('fragment-shader'); 13 14function createShader(gl, type, source) { 15 const shader = gl.createShader(type); 16 gl.shaderSource(shader, source); 17 gl.compileShader(shader); 18 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 19 console.error('Shader compile error:', gl.getShaderInfoLog(shader)); 20 gl.deleteShader(shader); 21 return null; 22 } 23 return shader; 24} 25 26function createProgram(gl, vertexShader, fragmentShader) { 27 const program = gl.createProgram(); 28 gl.attachShader(program, vertexShader); 29 gl.attachShader(program, fragmentShader); 30 gl.linkProgram(program); 31 if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 32 console.error('Program link error:', gl.getProgramInfoLog(program)); 33 return null; 34 } 35 return program; 36} 37 38const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource); 39const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource); 40const program = createProgram(gl, vertexShader, fragmentShader); 41 42const positionBuffer = gl.createBuffer(); 43gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); 44const positions = [-1, -1, 1, -1, -1, 1, 1, 1]; 45gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); 46 47const positionLocation = gl.getAttribLocation(program, 'a_position'); 48gl.enableVertexAttribArray(positionLocation); 49gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); 50 51gl.useProgram(program); 52 53const resolutionLocation = gl.getUniformLocation(program, 'u_resolution'); 54const timeLocation = gl.getUniformLocation(program, 'u_time'); 55 56function render(time) { 57 gl.uniform2f(resolutionLocation, canvas.width, canvas.height); 58 gl.uniform1f(timeLocation, time * 0.001); 59 60 gl.clear(gl.COLOR_BUFFER_BIT); 61 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 62 requestAnimationFrame(render); 63} 64 65function resize() { 66 const ratio = Math.min(window.devicePixelRatio || 1, 2); 67 canvas.width = window.innerWidth * ratio; 68 canvas.height = window.innerHeight * ratio; 69 gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 70 canvas.style.width = window.innerWidth + 'px'; 71 canvas.style.height = window.innerHeight + 'px'; 72} 73 74window.addEventListener('resize', resize); 75resize(); 76requestAnimationFrame(render);



✅ Usage

  • Put all files (index.html, style.css, script.js) in one folder.
  • Open index.html in a browser.
  • You will see glowing tendril energy representing Fire Titan Aura.

📌 Notes

  • This effect is tendril-based, not a full fire titan body.
  • Uses pure WebGL shaders.
  • Works best on desktops.

Love this component?

Explore more components and build amazing UIs.

View All Components