Skip to content

speakk/lighter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 

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.

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages