Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/speakk/lighter
A Löve light/shadow library
https://github.com/speakk/lighter
dynamic-lighting lighting love2d love2d-framework
Last synced: about 2 months ago
JSON representation
A Löve light/shadow library
- Host: GitHub
- URL: https://github.com/speakk/lighter
- Owner: speakk
- Created: 2020-11-12T22:22:13.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2023-09-02T05:42:17.000Z (over 1 year ago)
- Last Synced: 2024-10-01T08:03:18.398Z (2 months ago)
- Topics: dynamic-lighting, lighting, love2d, love2d-framework
- Language: Lua
- Homepage:
- Size: 177 KB
- Stars: 35
- Watchers: 3
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-love2d - lighter - A performant dynamic light implementation with a simple API. (Lighting)
README
# Lighter
A dynamic light / shadow casting library for Löve.
## Installation
Clone the repo into your libs directory and require withrequire '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)
endfunction 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:
* Helped me understand the premise and their code provided me with tons of helpful tips for getting this implemented: [https://github.com/OneLoneCoder](https://github.com/OneLoneCoder)
* The actual page I ended up following to really get the idea: [https://ncase.me/sight-and-light/](https://ncase.me/sight-and-light/)### Screenshot of the library in use in a game
![Screenshot of the library in use in a game](./screenshot.jpg)## 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.