Created
January 7, 2023 17:18
-
-
Save jmiskovic/9708c104dbcd626e19b756db8658f867 to your computer and use it in GitHub Desktop.
Reaction-diffusion model with hands erasing the growth (for lovr framework)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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