Skip to content

Instantly share code, notes, and snippets.

@jmiskovic
Created January 7, 2023 17:18
Show Gist options
  • Save jmiskovic/9708c104dbcd626e19b756db8658f867 to your computer and use it in GitHub Desktop.
Save jmiskovic/9708c104dbcd626e19b756db8658f867 to your computer and use it in GitHub Desktop.
Reaction-diffusion model with hands erasing the growth (for lovr framework)
local resolution = 1024
local group_size = 16
local tex1 = lovr.graphics.newTexture(resolution, resolution, {mipmaps = false, usage = {'render', 'sample', 'storage', 'transfer'}, linear = true})
local tex2 = lovr.graphics.newTexture(resolution, resolution, {mipmaps = false, usage = {'render', 'sample', 'storage', 'transfer'}, linear = true})
local tex = lovr.graphics.newTexture(resolution, resolution, {mipmaps = false, usage = {'render', 'sample', 'storage', 'transfer'}, linear = true})
local projection = lovr.math.newMat4():perspective(math.rad(110), 1, .1, 0)
local palette = {0xded4c8, 0xbeaa9c, 0x94837a, 0x645c59, 0x181e28, 0xdbaf88, 0xb8926f, 0x987052, 0x624a30, 0x2f2114, 0xdf8b79, 0xe26560, 0xb0454c, 0x5b3636, 0xe5be3e, 0xbe8e03, 0x916803, 0x644507, 0xf18b49, 0xd46b2b, 0xba5113, 0x7a3412, 0xeb8281, 0xd95b5b, 0xbf2f37, 0x64272c, 0xb58fb6, 0x7e638e, 0x594a66, 0x3c3145, 0x30bab3, 0x1390ac, 0x0b5472, 0x233552, 0xabcf5f, 0x789949, 0x39681d, 0x084739}
local computeShader = lovr.graphics.newShader([[
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
layout(set = 0, binding = 0, rgba8) uniform image2D pTex;
layout(set = 0, binding = 1, rgba8) uniform image2D nTex;
layout(set = 0, binding = 2, rgba8) uniform image2D Tex;
vec3 laplacian(ivec2 coords) {
vec3 rg = vec3(0.0, 0.0, 0.0);
rg += imageLoad(pTex, coords + ivec2(-1, -1)).rgb * 0.05;
rg += imageLoad(pTex, coords + ivec2( 0, -1)).rgb * 0.2;
rg += imageLoad(pTex, coords + ivec2( 1, -1)).rgb * 0.05;
rg += imageLoad(pTex, coords + ivec2(-1, 0)).rgb * 0.2;
rg += imageLoad(pTex, coords + ivec2( 0, 0)).rgb * -1.0;
rg += imageLoad(pTex, coords + ivec2( 1, 0)).rgb * 0.2;
rg += imageLoad(pTex, coords + ivec2(-1, 1)).rgb * 0.05;
rg += imageLoad(pTex, coords + ivec2( 0, 1)).rgb * 0.2;
rg += imageLoad(pTex, coords + ivec2( 1, 1)).rgb * 0.05;
return rg;
}
void lovrmain() {
const float dt = 1.0;
const float diffusion_rate_a = 0.804f;
const float diffusion_rate_b = 0.282f;
const float feed_rate = 0.06718f;
const float kill_rate = 0.0648f;
ivec2 size = imageSize(pTex);
ivec2 coords = ivec2(GlobalThreadID.xy);
vec4 color = imageLoad(pTex, coords);
float a = color.r;
float b = color.g;
vec3 lp = laplacian(coords);
float n_a = a + (diffusion_rate_a * lp.x - a*b*b + feed_rate*(1.0 - a)) * dt;
float n_b = b + (diffusion_rate_b * lp.y + a*b*b - (kill_rate + feed_rate)*b) * dt;
imageStore(nTex, coords, vec4(n_a, n_b, color.b, 1.0));
const float amp = 3.5;
imageStore(Tex, coords, vec4(n_b * amp, n_b * amp, n_b * amp, n_b * amp));
}
]])
local function draw(pass)
local t = lovr.timer.getTime()
pass:setColor(1, 1, 0)
for _, hand in ipairs({ 'left', 'right' }) do
local skeleton = lovr.headset.getSkeleton(hand)
if skeleton then
for _, joint in ipairs(skeleton or {}) do
local x, y, z, r, angle, ax, ay, az = unpack(joint)
pass:capsule(mat4(x, y, z, r, r, r, angle, ax, ay, az))
end
else
pass:box(mat4(lovr.headset.getPose(hand)):scale(0.03, 0.08, 0.10))
end
end
end
function lovr.update(dt)
local pass = lovr.graphics.getPass('render', {tex1, clear = false, samples = 1, mipmap = false})
pass:setViewPose(1, mat4(lovr.headset.getPose()))
pass:setProjection(1, projection)
draw(pass)
lovr.graphics.submit(pass)
local computer = lovr.graphics.getPass('compute')
computer:setShader(computeShader)
local steps_per_frame = 20
local odd = true
for i=1, steps_per_frame do
if odd then
computer:send('pTex', tex1)
computer:send('nTex', tex2)
else
computer:send('pTex', tex2)
computer:send('nTex', tex1)
end
computer:send('Tex', tex)
odd = not odd
computer:compute(resolution / group_size, resolution / group_size)
end
lovr.graphics.submit(computer)
end
function lovr.draw(pass)
local t = lovr.timer.getTime() * 5
pass:setDepthWrite(false)
pass:setColor(1,0,0)
pass:setMaterial(tex)
local d = -2
local s = 4
local off = 0.02
pass:setColor(0xe20074)
pass:plane(0, 1.2, d, s, s)
pass:setColor(0x1390ac)
pass:plane(0.03 + off*math.sin(t), 1.2 + off*math.cos(t), d - 0.1, s, s)
pass:setColor(0xe5be3e)
pass:plane(0.02, 1.202 - off*math.cos(t), d - 0.2 + off*math.sin(t), s, s)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment