Skip to content

Instantly share code, notes, and snippets.

@lostintangent
Last active February 21, 2025 11:12
Show Gist options
  • Save lostintangent/5d2daaf9aa42e5795fcc3f70be959d43 to your computer and use it in GitHub Desktop.
Save lostintangent/5d2daaf9aa42e5795fcc3f70be959d43 to your computer and use it in GitHub Desktop.
GLSL: fire
<canvas id="canvas"></canvas>
<script type="glsl">
precision highp float;
uniform float time;
uniform vec2 resolution;
// taken from https://www.shadertoy.com/view/4tlSzl
vec3 firePalette(float i) {
float T = 1400. + 1300.*i;
vec3 L = vec3(7.4, 5.6, 4.4);
L = pow(L,vec3(5.0)) * (exp(1.43876719683e5/(T*L))-1.0);
return 1.0-exp(-5e8/L);
}
vec3 hash33(vec3 p) {
float n = sin(dot(p, vec3(7, 157, 113)));
return fract(vec3(2097152, 262144, 32768)*n);
}
float voronoi(vec3 p) {
vec3 b, r, g = floor(p);
p = fract(p);
float d = 1.;
for(int j = -1; j <= 1; j++) {
for(int i = -1; i <= 1; i++) {
b = vec3(i, j, -1);
r = b - p + hash33(g+b);
d = min(d, dot(r,r));
b.z = 0.0;
r = b - p + hash33(g+b);
d = min(d, dot(r,r));
b.z = 1.;
r = b - p + hash33(g+b);
d = min(d, dot(r,r));
}
}
return d;
}
float noiseLayers(in vec3 p) {
vec3 t = vec3(0., 0., p.z+time);
float tot = 0., sum = 0., amp = 1.;
for (int i = 0; i < 6; i++) {
tot += voronoi(p + t) * amp;
p *= 2.0;
t *= 1.5;
sum += amp;
amp *= 0.5;
}
return tot/sum;
}
void main(void) {
vec2 uv = (gl_FragCoord.xy - resolution.xy*0.5)/ resolution.y;
vec3 rd = normalize(vec3(uv.x, uv.y, 3.1415/8.));
float c = noiseLayers(rd*4.);
vec3 col = firePalette(c);
gl_FragColor = vec4(sqrt(col), 1.);
}
</script>
let gl = canvas.getContext('webgl');
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,3,-1,-1,3,-1]), gl.STATIC_DRAW);
let pid = gl.createProgram();
shader(`attribute vec2 v;void main(void){gl_Position=vec4(v,0.,1.);}`,gl.VERTEX_SHADER);
shader(document.querySelector(`script[type="glsl"]`).textContent,gl.FRAGMENT_SHADER);
gl.linkProgram(pid);
gl.useProgram(pid);
let v = gl.getAttribLocation(pid, "v");
gl.vertexAttribPointer(v, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(v);
let resolution = gl.getUniformLocation(pid, 'resolution');
let time = gl.getUniformLocation(pid, 'time');
let fill = gl.getUniformLocation(pid, 'fill');
requestAnimationFrame(draw);
function draw(t) {
gl.uniform1f(time, t/1000);
gl.drawArrays(gl.TRIANGLES, 0, 3);
requestAnimationFrame(draw);
}
function shader(src, type) {
let sid = gl.createShader(type);
gl.shaderSource(sid, src);
gl.compileShader(sid);
var message = gl.getShaderInfoLog(sid);
gl.attachShader(pid, sid);
if (message.length > 0) {
console.log(src.split("\n").map((str, i) =>
(""+(1+i)).padStart(4, "0")+": "+str).join("\n"));
throw message;
}
}
addEventListener('resize', function(){
if (innerWidth === canvas.width &&
innerHeight === canvas.height )
return;
canvas.width = innerWidth;
canvas.height = innerHeight;
gl.uniform2f(resolution, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
})
dispatchEvent(new Event('resize'))
body {
overflow:hidden;
margin:0;
}
{
"title": "GLSL: fire ",
"description": "GLSL: fire ",
"steps": [
{
"file": "index.html",
"line": 7,
"description": "# Heading\n\nOne"
},
{
"file": "style.css",
"line": 3,
"description": "Two"
},
{
"file": "script.js",
"line": 7,
"description": "Three"
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment