Skip to content

Instantly share code, notes, and snippets.

@astellon
Created March 24, 2022 13:04
Show Gist options
  • Save astellon/393195a11433c793126121e4b87d7293 to your computer and use it in GitHub Desktop.
Save astellon/393195a11433c793126121e4b87d7293 to your computer and use it in GitHub Desktop.
# generate fractional Brownian motion (fBM)
# reference: https://thebookofshaders.com/13 by Patricio Gonzalez Vivo
using LinearAlgebra
using Images, FileIO
function fract(x)
x - floor(x)
end
function random(vec)
return fract(sin(dot(vec, [12.9898,78.233])) * 43758.5453123);
end
function mix(x, y, a)
x * (1 - a) + y * a
end
function noise(vec)
i = floor.(vec)
f = fract.(vec)
# Four corners in 2D of a tile
a = random(i)
b = random(i .+ [1.0, 0.0])
c = random(i .+ [0.0, 1.0])
d = random(i .+ [1.0, 1.0])
u = f .* f .* (3.0 .- 2.0 * f)
mix(a, b, u[1]) + (c - a) * u[2] * (1.0 - u[1]) + (d - b) * u[1] * u[2]
end
function fbm(vec, octaves=6)
# Initial values
value = 0.0
amplitude = 0.5
frequency = 0.0
# Loop of octaves
for i in 1:octaves
value = value + amplitude * noise(vec)
vec = vec .* 2
amplitude = amplitude * 0.5
end
value
end
function main()
width = 320
height = 320
xy = collect.(Iterators.product(collect(0:width - 1) ./ width, collect(0:height - 1) ./ height))
pix = zeros(RGB{Normed{UInt8,8}}, width, height, 30)
for i in 1:30
pix[:, :, i] = RGB.(fbm.(xy .* 3.0))
end
save("fbm.gif", permutedims(pix, (2, 1)))
end
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment