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.video = false
|
||||
|
||||
t.window.title = "By Your Own Beat"
|
||||
t.window.title = "Your Own Drum"
|
||||
t.window.width = 600
|
||||
t.window.height = 600
|
||||
t.window.resizable = true
|
||||
|
|
18
main.lua
18
main.lua
|
@ -29,24 +29,6 @@ state = {
|
|||
currentBeat = 1,
|
||||
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 = {
|
||||
t = nil,
|
||||
mu = nil,
|
||||
|
|
72
wave.lua
72
wave.lua
|
@ -1,6 +1,6 @@
|
|||
--Render and simulate 1D wave equation.
|
||||
local love = love
|
||||
local N = 15
|
||||
local N = 33
|
||||
local SOUNDSPEED = 0.5
|
||||
local IMPULSESIZE = 20
|
||||
local DAMPING = 0.01
|
||||
|
@ -16,6 +16,41 @@ local Derivative
|
|||
local SecondDerivative
|
||||
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.
|
||||
do
|
||||
|
@ -112,7 +147,7 @@ end
|
|||
|
||||
--Apply bandlimited impulse to wave.
|
||||
local function OnImpact( impact )
|
||||
|
||||
|
||||
local r = cur.radii
|
||||
local theta = impact.th
|
||||
local magnitude = IMPULSESIZE * impact.speed
|
||||
|
@ -120,7 +155,7 @@ local function OnImpact( impact )
|
|||
for i = 0, N - 1 do
|
||||
r[ i + 1 ] = r[ i + 1 ] + dt * magnitude * AliasedSinc( theta, 2.0 * math.pi * i / N )
|
||||
end
|
||||
|
||||
|
||||
--We've updated the positions, now we need to take a DFT
|
||||
--in order to get the bandlimited second spatial derivative.
|
||||
cur:DFT()
|
||||
|
@ -161,10 +196,16 @@ local function Draw()
|
|||
|
||||
-- Blue circle.
|
||||
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()
|
||||
love.graphics.setShader( )
|
||||
|
||||
-- Debug dots.
|
||||
--[[
|
||||
for i = 1, N do
|
||||
|
||||
local th = ( i - 1 ) * 2.0 * math.pi / N
|
||||
|
@ -172,9 +213,9 @@ local function Draw()
|
|||
love.graphics.setCanvas()
|
||||
love.graphics.setColor( 0, 0, 0, 0.5 )
|
||||
love.graphics.circle( "fill", cx, cy, 0.02 )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for k = 0.1, 1.0, 0.1 do
|
||||
--Interpolant.
|
||||
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 )
|
||||
love.graphics.circle( "fill", x, y, 0.01 )
|
||||
--love.graphics.circle( "fill", th / math.pi - 1.0 , r, 0.01)
|
||||
|
||||
|
||||
--First derivative.
|
||||
--[[love.graphics.setColor( 0, 1.0, 0, 0.7 )
|
||||
--love.graphics.setColor( 0, 1.0, 0, 0.7 )
|
||||
r = cur:Derivative( th )
|
||||
x, y = r * math.cos( th ), r * math.sin( th )
|
||||
--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.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
|
||||
|
||||
love.graphics.setColor( 1, 1, 1, 0.5 )
|
||||
local r = cur:Interpolate( 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
|
||||
|
||||
|
||||
|
@ -219,7 +261,7 @@ local function Update()
|
|||
old[name][i] = t[i]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--Deep copy of new state to current state.
|
||||
for name, t in pairs( new ) do
|
||||
for i = 1, N do
|
||||
|
@ -229,16 +271,16 @@ local function Update()
|
|||
end
|
||||
|
||||
Integrate = function( step )
|
||||
|
||||
|
||||
for i = 1, N do
|
||||
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
|
||||
+ DAMPING --Damping: oscillate toward 1.
|
||||
+ DAMPING --Damping: oscillate toward 1.
|
||||
if r > 1.5 then r = 1.5 end
|
||||
if r < 0.5 then r = 0.5 end
|
||||
new.radii[i] = r
|
||||
end
|
||||
|
||||
|
||||
new:DFT( )
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue