Skip to content

Latest commit

History

27 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Lighter

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

Function signatures of the public API:

 init = function(self, options)
addLight = function(self, x, y, radius, r, g, b, a, gradientImage)
updateLight = function(self, light, x, y, radius, r, g, b, a, gradientImage)
removeLight = function(self, light)
addPolygon = function(self, polygon)
removePolygon = function(self, polygon)
drawVisibilityPolygon = function(self, light)
drawLights = function(self)

Credits:

Screenshot of the library in use in a game

Screenshot of the library in use in a game

How it works under the hood

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.

About

A Löve light/shadow library

Topics

Resources

Stars

45 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages