Render wave via shader.

This commit is contained in:
yaw-man 2023-01-14 16:03:57 -04:00
parent c8fe7b7d36
commit f1873abed7
3 changed files with 58 additions and 34 deletions

View File

@ -4,7 +4,7 @@ function love.conf( t )
t.modules.touch = false t.modules.touch = false
t.modules.video = false t.modules.video = false
t.window.title = "By Your Own Beat" t.window.title = "Your Own Drum"
t.window.width = 600 t.window.width = 600
t.window.height = 600 t.window.height = 600
t.window.resizable = true t.window.resizable = true

View File

@ -29,24 +29,6 @@ state = {
currentBeat = 1, currentBeat = 1,
startTime = 0.0, startTime = 0.0,
wave = {
x = { 1.0, 0.0, -0.5, 0.2, 0.4, 0.8, 0.3, 0.9, -0.4, 0.8, 0.5, 0.1, -0.9 },
dx = { 1.0, 0.0, -0.5, 0.2, 0.4, 0.8, 0.3, 0.9, -0.4, 0.8, 0.5, 0.1, -0.9 },
ddx = { 1.0, 0.0, -0.5, 0.2, 0.4, 0.8, 0.3, 0.9, -0.4, 0.8, 0.5, 0.1, -0.9 },
X = function(th) end,
DX = function(th) end,
DDX = function(th) end,
Draw = function() end,
AddImpulse = function( th, size ) end,
ImpactPoint = function( xi, yi, xf, yf )
local impact = { r = 0, th = 0, t = 0, x = 0, y = 0, dx = 0, dy = 0 }
return impact
end,
Update = function( dt ) end,
},
beat = { beat = {
t = nil, t = nil,
mu = nil, mu = nil,

View File

@ -1,6 +1,6 @@
--Render and simulate 1D wave equation. --Render and simulate 1D wave equation.
local love = love local love = love
local N = 15 local N = 33
local SOUNDSPEED = 0.5 local SOUNDSPEED = 0.5
local IMPULSESIZE = 20 local IMPULSESIZE = 20
local DAMPING = 0.01 local DAMPING = 0.01
@ -16,6 +16,41 @@ local Derivative
local SecondDerivative local SecondDerivative
local DFT local DFT
local shader = love.graphics.newShader([[
uniform float re[33];
uniform float im[33];
//Slow IDFT
float r( float x )
{
float r = re[0];
for( int k = 1; k < 17; k++ )
{
float c = cos( x * float( k ) );
float s = sin( x * float( k ) );
r +=
+ c * re[k]
- s * im[k]
+ c * re[33 - k]
+ s * im[33 - k];
}
return r;
}
vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords)
{
vec2 p = (3.0 * screen_coords - 1.5 * love_ScreenSize.xy ) / love_ScreenSize.y;
p.y = -p.y;
float r = r( atan(p.y, p.x) ) - length( p );
return vec4(color.x, color.y, color.z, (r > -0.01)) ;
}
]])
--Calculate discrete fourier transform of radius function. --Calculate discrete fourier transform of radius function.
do do
@ -161,10 +196,16 @@ local function Draw()
-- Blue circle. -- Blue circle.
love.graphics.setColor( 91 / 255, 206 / 255, 250 / 255 ) love.graphics.setColor( 91 / 255, 206 / 255, 250 / 255 )
love.graphics.circle("fill", 0, 0, 1)
shader:send( "re", unpack( cur.dftre ) )
shader:send( "im", unpack( cur.dftim ) )
love.graphics.setShader( shader )
love.graphics.circle("fill", 0, 0, 1.5)
local t = love.timer.getTime() local t = love.timer.getTime()
love.graphics.setShader( )
-- Debug dots. -- Debug dots.
--[[
for i = 1, N do for i = 1, N do
local th = ( i - 1 ) * 2.0 * math.pi / N local th = ( i - 1 ) * 2.0 * math.pi / N
@ -185,7 +226,7 @@ local function Draw()
--love.graphics.circle( "fill", th / math.pi - 1.0 , r, 0.01) --love.graphics.circle( "fill", th / math.pi - 1.0 , r, 0.01)
--First derivative. --First derivative.
--[[love.graphics.setColor( 0, 1.0, 0, 0.7 ) --love.graphics.setColor( 0, 1.0, 0, 0.7 )
r = cur:Derivative( th ) r = cur:Derivative( th )
x, y = r * math.cos( th ), r * math.sin( th ) x, y = r * math.cos( th ), r * math.sin( th )
--love.graphics.circle( "fill", x, y, 0.01 ) --love.graphics.circle( "fill", x, y, 0.01 )
@ -199,7 +240,7 @@ local function Draw()
love.graphics.circle( "fill", th / math.pi - 1.0, r, 0.01) love.graphics.circle( "fill", th / math.pi - 1.0, r, 0.01)
love.graphics.setColor( 1.0, 1.0, 1.0, 0.2 ) love.graphics.setColor( 1.0, 1.0, 1.0, 0.2 )
love.graphics.circle( "fill", 2.0 * ( i + k ) / N - 1.2, 0, 0.02 )]] love.graphics.circle( "fill", 2.0 * ( i + k ) / N - 1.2, 0, 0.02 )
end end
end end
@ -207,7 +248,8 @@ local function Draw()
love.graphics.setColor( 1, 1, 1, 0.5 ) love.graphics.setColor( 1, 1, 1, 0.5 )
local r = cur:Interpolate( t ) local r = cur:Interpolate( t )
local x, y = r * math.cos( t ), r * math.sin( t ) local x, y = r * math.cos( t ), r * math.sin( t )
love.graphics.circle( "fill", x, y, 0.02 ) love.graphics.circle( "fill", x, y, 0.02 )]]
end end
@ -233,7 +275,7 @@ Integrate = function( step )
for i = 1, N do for i = 1, N do
local rxx = cur:SecondDerivative( math.pi * 2.0 * ( i - 1 ) / N ) local rxx = cur:SecondDerivative( math.pi * 2.0 * ( i - 1 ) / N )
local r = ( 1.0 - DAMPING ) * ( 2.0 * cur.radii[i] - old.radii[i] + step * step * SOUNDSPEED * rxx ) --Verlet local r = ( 1.0 - DAMPING ) * ( 2.0 * cur.radii[i] - old.radii[i] + step * step * SOUNDSPEED * rxx ) --Verlet
+ DAMPING --Damping: oscillate toward 1. + DAMPING --Damping: oscillate toward 1.
if r > 1.5 then r = 1.5 end if r > 1.5 then r = 1.5 end
if r < 0.5 then r = 0.5 end if r < 0.5 then r = 0.5 end
new.radii[i] = r new.radii[i] = r