Really short FastLED Perlin Fire by @Johnny5canuck
Similarly short by ldirko
https://www.reddit.com/r/FastLED/comments/hgu16i/my_fire_effect_implementation_based_on_perlin/
Code is linked in each…
Both use a fire palette and inoise. We have neither, so this is quite a bit longer. Lots of tunable sliders, and it’s not done by any means. Suggestions and improvements welcome. There are lots of ways to build a fire…
It’s bit too orange-y I think, but it has a really nice roar, like a big bonfire or a fireplace, as opposed to a steady burn. Adjust by adding wood, or maybe sliding the sliders, till it’s at a comfy level for you.
Perlin Fire - an early attempt on PB
// Perlin Fire - an early attempt on PB
export var reset = 1
export function sliderNewGrid(v){
var rereset = reset
reset = v
if (reset == 0 && rereset != reset){
buildTable()
}
}
export var noisescaleX = 1
export function sliderScaleX(v){
noisescaleX = v*10
}
export var noisescaleY = 1
export function sliderScaleY(v){
noisescaleY = v*10
}
export var noisescaleZ = 1
export function sliderScaleZTime(v){
noisescaleZ = v*10
}
export var fireheight = 1
export function sliderFireHeight(v){
fireheight = 10 - v*10
}
function lerp(a, b, t) {
return (1 - t) * a + t * b;
}
export var time
export function beforeRender(delta) {
time += delta/5000 * noisescaleZ
}
export function render2D(index, x, y) {
h = lerp(-.05,.25,abs(noise(x*noisescaleX, y*noisescaleY, time)))
s = 1
if (h < 0) {
h = abs(h)
s = 1-h
}
v = 1-(x+h*fireheight)
hsv(h,s,v)
}
//
// Written by Thom Chiovoloni, dedicated into the public domain
// per http://creativecommons.org/publicdomain/zero/1.0
// https://github.com/thomcc/quick-noise.js
//
// adapted by ScruffyNerf into Pixelblaze's JSish language
// you could replace the use of random() with a different RNG if you wish
var arraySize = 256
var permSize = arraySize
var gradSize = permSize
var perm = array(permSize)
var grad1 = array(gradSize)
var grad2 = array(gradSize)
var grad3 = array(gradSize)
var gradBasis = array(36)
var gradIndex = 0
var gradIdx = 0
function gradinit(){
grad(1,1,0); grad(-1,1,0); grad(1,-1,0); grad(-1,-1,0)
grad(1,0,1); grad(-1,0,1); grad(1,0,-1); grad(-1,0,-1)
grad(0,1,1); grad(0,-1,1); grad(0,1,-1); grad(0,-1,-1)
}
function buildTable() {
perm.mutate(arrayFill)
perm.mutate(arrayShuffle)
perm.mutate(arrayShuffle) // for good measure, shuffle twice
gradIdx = 0
perm.forEach(gradPop)
}
function arrayFill(v,i,a){
return i
}
function arrayShuffle(v,i,a){
r = floor(random(a.length))
t = a[r]
a[r] = v
return t
}
function grad(x, y, z) {
gradBasis[gradIndex] = x
gradIndex++
gradBasis[gradIndex] = y
gradIndex++
gradBasis[gradIndex] = z
gradIndex++
}
function gradPop(v,i,a){
g = v%12 * 3
grad1[gradIdx] = gradBasis[g]
grad2[gradIdx] = gradBasis[g+1]
grad3[gradIdx] = gradBasis[g+2]
gradIdx++
}
function fade(t) {
return t * t * t * (t * (t * 6 - 15) + 10)
}
function noise(x, y, z, xWrap, yWrap, zWrap) {
// x, y, z are numbers.
// xWrap, yWrap, and zWrap are integer powers of two between 0 and 256.
// (0 and 256 are equivalent). If these aren't provided, they default to 0.
xMask = ((xWrap-1) & 255) >> 0
yMask = ((yWrap-1) & 255) >> 0
zMask = ((zWrap-1) & 255) >> 0
px = floor(x)
py = floor(y)
pz = floor(z)
x0 = (px+0) & xMask
x1 = (px+1) & xMask
y0 = (py+0) & yMask
y1 = (py+1) & yMask
z0 = (pz+0) & zMask
z1 = (pz+1) & zMask
x -= px
y -= py
z -= pz
u = fade(x)
v = fade(y)
w = fade(z)
r0 = perm[x0%256]
r1 = perm[x1%256]
r00 = perm[(r0+y0)%256]
r01 = perm[(r0+y1)%256]
r10 = perm[(r1+y0)%256]
r11 = perm[(r1+y1)%256]
h000 = perm[(r00+z0)%256]%256
h001 = perm[(r00+z1)%256]%256
h010 = perm[(r01+z0)%256]%256
h011 = perm[(r01+z1)%256]%256
h100 = perm[(r10+z0)%256]%256
h101 = perm[(r10+z1)%256]%256
h110 = perm[(r11+z0)%256]%256
h111 = perm[(r11+z1)%256]%256
n000 = grad1[h000]*(x+0) + grad2[h000]*(y+0) + grad3[h000]*(z+0)
n001 = grad1[h001]*(x+0) + grad2[h001]*(y+0) + grad3[h001]*(z-1)
n010 = grad1[h010]*(x+0) + grad2[h010]*(y-1) + grad3[h010]*(z+0)
n011 = grad1[h011]*(x+0) + grad2[h011]*(y-1) + grad3[h011]*(z-1)
n100 = grad1[h100]*(x-1) + grad2[h100]*(y+0) + grad3[h100]*(z+0)
n101 = grad1[h101]*(x-1) + grad2[h101]*(y+0) + grad3[h101]*(z-1)
n110 = grad1[h110]*(x-1) + grad2[h110]*(y-1) + grad3[h110]*(z+0)
n111 = grad1[h111]*(x-1) + grad2[h111]*(y-1) + grad3[h111]*(z-1)
n00 = n000 + (n001-n000) * w
n01 = n010 + (n011-n010) * w
n10 = n100 + (n101-n100) * w
n11 = n110 + (n111-n110) * w
n0 = n00 + (n01-n00) * v
n1 = n10 + (n11-n10) * v
return n0 + (n1-n0) * u
}
function fractal3d(x, y, z, octaves) {
val = 0;
for (i = 0; i < octaves; i++) {
val += noise(x, y, z) / pow(2, 0.5 + i - 0.5 * i);
x -= i * 7;
y += i * 13;
z -= i * 23;
x *= 1.57;
y *= 1.57;
z *= 1.57;
}
return val;
}
gradinit()
buildTable()