You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A dynamic light / shadow casting library for Löve.
Installation
Clone the repo into your libs directory and require with
require 'path.to.lighter'
Usage
local Lighter = require 'path.to.lighter'
local lighter = Lighter()
local wall = {
100, 100,
300, 100,
300, 300,
100, 300
}
lighter:addPolygon(wall)
local lightX, lightY = 500, 500
-- addLight signature: (x,y,radius,r,g,b,a)
local light = lighter:addLight(lightX, lightY, 500, 1, 0.5, 0.5)
function love.update(dt)
lightX, lightY = love.mouse.getPosition()
lighter:updateLight(light, lightX, lightY)
end
function love.draw()
love.graphics.polygon('fill', wall)
lighter:drawLights()
end
-- Clean up
-- lighter:removeLight(light)
-- lighter:removePolygon(wall)
How to use in your game context with a darker global illumination:
(remember you can use any combination of additive & multiplicative blending to achieve a result you like)
-- Call after your light positions have been updated
function preDrawLights()
love.graphics.setCanvas({ lightCanvas, stencil = true})
love.graphics.clear(0.4, 0.4, 0.4) -- Global illumination level
self.lighter:drawLights()
love.graphics.setCanvas()
end
-- Call after you have drawn your scene (but before UI)
function drawLights()
love.graphics.setBlendMode("multiply", "premultiplied")
love.graphics.draw(lightCanvas)
love.graphics.setBlendMode("alpha")
end
For each light we cast rays towards wall polygon corners (aka map features). Checks intersections.
Builds a visibility polygon and uses it as the stencil for drawing the light.
As an optimization it uses a spatial map and calculates polygon bounding boxes on the fly so that only polygons within light radius get included in the visibility polygon calculations.