many lights 2d shadows library for love framework
requirements: opengl3 with array textures and instancing support(which technically should be a part of any gl3 capable system)
NOTE: functionality is still being added but already existing API is very unlikely to change
local bt = require"bitumbra"
bt.newShadowMap(width, height)
- creates a new shadow map that you can render to/sample from(advanced, coming soon)width
andheight
are shadowmap dimensions
bt.newOcclusionMesh(max_edges)
- creates a new occlusion mesh that represents shadow casting geometrymax_edges
is the maximum amount of edges the mesh can store, 10000 by default
bt.newLightsArray()
- creates an array containing up to 128 lights that will cast shadows or can be drawn sampling the shadowmap
local lights = bt.newLightsArray()
lights:push(x,y,radius, r,g,b)
lights:set(i, x,y,radius, r,g,b)
local x,y = lights:pop()
local n = lights.count
push(x,y,radius, r,g,b)
- pushes new light into the array, increases lights countx,y
- light positionradius
- length at which the light falls to zeror,g,b
- red, green, and blue components of the light in the range of [0,1]
set(i, x,y,radius, r,g,b)
- setsi
- index of the light to setx,y,radius, r,g,b
- seepush
pop()
- returnsx
,y
,radius
, andr
,g
,b
of the latest light and removes it from the listget(i)
- returnsx
,y
,radius
, andr
,g
,b
of the light at indexi
applyTransform(x, y, angle, sx, sy, ox, oy, kx, ky)
- applies the standard love transformation to every light in the arrayx,y
- translationangle
- rotation angle in radianssx, sy
- scaleox, oy
- origin point, useful if you want to rotate a bunch of lights around an arbitrary pointkx, ky
- shear, I honestly have no idea who uses those but they're here for consistency with love API- can also accept love's very own Transform object(love.math.newTransform()) instead
count
- a number of currently set lights in the arraydraw(shadowmap)
- draws lights with respect of shadows stored in the shadowmap
local geo = bt.newOcclusionMesh()
local circle = bt.newOcclusionMesh()
geo:addEdge(ax,ay, bx,by)
circle:addCircle(x, y, r)
geo:applyTransform(x, y, angle, sx, sy, ox, oy, kx, ky)
geo:addOcclusionMesh(circle)
addEdge(ax,ay, bx,by)
- adds an edge(straight line segment from point A to point B) to occlusion meshax,ay bx,by
- x and y positions of both ends of an edge segment
setEdge(i, ax,ay, bx,by)
- changes the existing edgei
- the index of the edge to change
addCircle(x, y, r, seg)
- adds a few edges shaped as a circlex, y
- center of the circler
- circle radiusseg
- number of segments that will form the circle(13 by default)
addOcclusionMesh(mesh)
- adds an existing occlusion mesh to the current meshmesh
- an already existing occlusion mesh- useful when you want to combine a few meshes for the final effect
applyTransform(x, y, angle, sx, sy, ox, oy, kx, ky)
- applies the standard love transformation to every edge of the meshx,y
- translationangle
- rotation angle in radianssx, sy
- scaleox, oy
- origin point, useful if you want to rotate a mesh around an arbitrary pointkx, ky
- shear- can also accept love's Transform object instead
edge_count
- current edge count of the mesh
local sm = bt.newShadowMap(love.graphics.getDimensions())
sm.render(mesh, lights)
- renders occlusionmesh
for every one oflights
to the shadowmap
local bu = require("bitumbra")
local g = love.graphics
local w, h = g.getDimensions()
local sm = bu.newShadowMap(g.getDimensions()) -- full-screen shadowmap
local geo = bu.newOcclusionMesh()
--add a bunch of edges
geo:addEdge(w/2-50,h/2-50, w/2+50,h/2-50) -- ax,ay, bx,by
geo:addEdge(w/2+50,h/2-50, w/2+50,h/2+50)
geo:addEdge(w/2+50,h/2+50, w/2-50,h/2+50)
geo:addEdge(w/2-50,h/2+50, w/2-50,h/2-50)
--another new meshes
local circles = bu.newOcclusionMesh()
local a = 0
for i=1, 16 do
local x,y = math.cos(a), math.sin(a)
circles:addCircle(w/2+x*180,h/2+y*180,20,24)
a = a + math.pi/8
end
local lights = bu.newLightsArray()
--add a bunch of lights, all 128 to be precise
for y=1,8 do
for x=1,16 do
lights:push( w/16*x-w/32, h*y/8-h/16, 400, .02,.02,.02)
end
end
local count = geo.edge_count --remember the static count
function love.update(dt)
--reset edge count to static
geo.edge_count = count
--move dynamic meshes
circles:applyTransform(w/2,h/2,dt/10,1,1,w/2,h/2)
--and add them to the geometry mesh
geo:addOcclusionMesh(circles)
--move one light to the mouse position(also make it brighter)
local mx,my = love.mouse.getPosition()
lights:set(1,mx,my,500, .3,.3,.3)
end
function love.draw()
sm:render(geo, lights)
lights:draw(sm)
end