Advertisement
Snusmumriken

love2d postprocessing and using one shader multiple times

Oct 25th, 2016
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.07 KB | None | 0 0
  1. --[[
  2. Reference:
  3. local Effect = requre'effect'
  4. local shader = love.graphics.newShader[[ -- yet another shader (wawe-effect)
  5. extern float time = 0;
  6. extern vec2 point = vec2(0, 0);
  7. extern float size = 100;
  8. extern float speed = 1;
  9. extern float radius = 2;
  10. float t = time;
  11. float distance(vec2 x){
  12. return pow(x.x*x.x + x.y*x.y, 0.5);
  13. };
  14. vec4 effect( vec4 color, Image texture, vec2 tc, vec2 sc ){
  15. vec2 d = point - tc;
  16. float dist = distance(d*vec2(1.0, 0.65));
  17. if (dist < radius){
  18. float delta = (cos(dist/time*speed*10)/2+0.5)/(dist*size);
  19. vec2 s = vec2(0.8, 0.6)*delta;
  20. return Texel(texture, tc + d*s)*color;
  21. }
  22. else return Texel(texture, tc)*color;
  23. }
  24. ]]
  25.  
  26.  
  27. effect = Effect(shader) -- initialisation new shader-effect
  28. image = love.graphics.newImage('image.png') -- add image
  29. framebuffer = love.graphics.newCanvas() -- framebuffer
  30. time = 0
  31.  
  32. function love.update(dt)
  33. love.window.setTitle(love.timer.getFPS())
  34. eff:update(dt) -- update all shader-instances
  35. time = time + dt
  36. end
  37.  
  38. function love.mousepressed(x, y, key)
  39. local x, y = love.mouse.getPosition(0)
  40. local ix, iy = love.graphics:getDimensions()
  41. eff:add(x/ix, y/iy, 5) -- add new instance on 0-1 screen position by x/y and 5 seconds lifetime
  42. end
  43.  
  44. function love.draw()
  45. love.graphics.setCanvas(canvas) -- draw image on canvas
  46. love.graphics.draw(image)
  47. eff:draw(canvas) -- apply all shader-instances on canvas
  48. love.graphics.setCanvas()
  49. love.graphics.draw(canvas) -- draw it
  50. love.graphics.circle('line', love.mouse.getX(), love.mouse.getY(), 100)
  51. end
  52. ]]
  53.  
  54.  
  55.  
  56. local function postprocessing()
  57. local graphics = love.graphics
  58. local buffer = graphics.newCanvas()
  59. local resX, resY = graphics.getDimensions()
  60. return function(canvas, shader, clear)
  61. assert(canvas:type() == 'Canvas', 'Argument #1 error: love2d-canvas expected. Use post processing only with canvases.')
  62. assert(shader:type() == 'Shader', 'Argument #2 error: love2d-shader expected.')
  63. local x, y = graphics.getDimensions()
  64. if x ~= resX or y ~= resY then buffer = graphics.newCanvas(); resX, resY = x, y end
  65. graphics.push('all')
  66. graphics.setCanvas(buffer)
  67. if clear then graphics.clear(0.0, 0.0, 0.0, 0.0) end
  68. graphics.setShader(shader) graphics.draw(canvas) graphics.setShader()
  69. graphics.setCanvas(canvas) graphics.draw(buffer)
  70. graphics.pop()
  71. end
  72. end
  73.  
  74. local effect = {}
  75. setmetatable(effect, {__call =
  76. function(self, shader)
  77. local o = {}
  78. o.post = postprocessing()
  79. o.list = {}
  80. o.shader = shader
  81. self.__index = self
  82. return setmetatable(o, self)
  83. end
  84. })
  85.  
  86. function effect:add(x, y, t)
  87. table.insert(self.list, {x = x, y = y, limit = t, t = 0})
  88. end
  89.  
  90. function effect:update(dt)
  91. for i, v in ipairs(self.list) do
  92. v.t = v.t + dt
  93. if v.t > v.limit then table.remove(self.list, i) end
  94. end
  95. end
  96.  
  97. function effect:draw(canvas)
  98. for i, v in ipairs(self.list) do
  99. self.shader:send('point', {v.x, v.y})
  100. self.shader:send('time', v.t)
  101. self.shader:send('size', (v.t+0.5)*200)
  102. self.post(canvas, self.shader)
  103. end
  104. end
  105.  
  106. return effect
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement