Render wave via shader.
This commit is contained in:
parent
c8fe7b7d36
commit
f1873abed7
2
conf.lua
2
conf.lua
|
@ -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
|
||||||
|
|
18
main.lua
18
main.lua
|
@ -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,
|
||||||
|
|
72
wave.lua
72
wave.lua
|
@ -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
|
||||||
|
@ -112,7 +147,7 @@ end
|
||||||
|
|
||||||
--Apply bandlimited impulse to wave.
|
--Apply bandlimited impulse to wave.
|
||||||
local function OnImpact( impact )
|
local function OnImpact( impact )
|
||||||
|
|
||||||
local r = cur.radii
|
local r = cur.radii
|
||||||
local theta = impact.th
|
local theta = impact.th
|
||||||
local magnitude = IMPULSESIZE * impact.speed
|
local magnitude = IMPULSESIZE * impact.speed
|
||||||
|
@ -120,7 +155,7 @@ local function OnImpact( impact )
|
||||||
for i = 0, N - 1 do
|
for i = 0, N - 1 do
|
||||||
r[ i + 1 ] = r[ i + 1 ] + dt * magnitude * AliasedSinc( theta, 2.0 * math.pi * i / N )
|
r[ i + 1 ] = r[ i + 1 ] + dt * magnitude * AliasedSinc( theta, 2.0 * math.pi * i / N )
|
||||||
end
|
end
|
||||||
|
|
||||||
--We've updated the positions, now we need to take a DFT
|
--We've updated the positions, now we need to take a DFT
|
||||||
--in order to get the bandlimited second spatial derivative.
|
--in order to get the bandlimited second spatial derivative.
|
||||||
cur:DFT()
|
cur:DFT()
|
||||||
|
@ -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
|
||||||
|
@ -172,9 +213,9 @@ local function Draw()
|
||||||
love.graphics.setCanvas()
|
love.graphics.setCanvas()
|
||||||
love.graphics.setColor( 0, 0, 0, 0.5 )
|
love.graphics.setColor( 0, 0, 0, 0.5 )
|
||||||
love.graphics.circle( "fill", cx, cy, 0.02 )
|
love.graphics.circle( "fill", cx, cy, 0.02 )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for k = 0.1, 1.0, 0.1 do
|
for k = 0.1, 1.0, 0.1 do
|
||||||
--Interpolant.
|
--Interpolant.
|
||||||
love.graphics.setColor( 1.0, 0, 0, 0.7 )
|
love.graphics.setColor( 1.0, 0, 0, 0.7 )
|
||||||
|
@ -183,9 +224,9 @@ local function Draw()
|
||||||
local x, y = r * math.cos( th ), r * math.sin( th )
|
local 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 )
|
||||||
--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,15 +240,16 @@ 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
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,7 +261,7 @@ local function Update()
|
||||||
old[name][i] = t[i]
|
old[name][i] = t[i]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--Deep copy of new state to current state.
|
--Deep copy of new state to current state.
|
||||||
for name, t in pairs( new ) do
|
for name, t in pairs( new ) do
|
||||||
for i = 1, N do
|
for i = 1, N do
|
||||||
|
@ -229,16 +271,16 @@ local function Update()
|
||||||
end
|
end
|
||||||
|
|
||||||
Integrate = function( step )
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
new:DFT( )
|
new:DFT( )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue