{"id":23931140,"url":"https://github.com/a13X-B/bitumbra","last_synced_at":"2025-09-11T15:31:06.896Z","repository":{"id":222006944,"uuid":"732317320","full_name":"a13X-B/bitumbra","owner":"a13X-B","description":"many light 2d shadows library for love framework","archived":false,"fork":false,"pushed_at":"2024-10-28T15:04:15.000Z","size":33,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-06T00:05:22.907Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/a13X-B.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-16T09:18:47.000Z","updated_at":"2024-10-28T15:04:20.000Z","dependencies_parsed_at":"2024-02-15T18:44:00.463Z","dependency_job_id":"a864b266-5bb2-49da-a78f-cba4dfaae533","html_url":"https://github.com/a13X-B/bitumbra","commit_stats":null,"previous_names":["a13x-b/bitumbra"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/a13X-B/bitumbra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a13X-B%2Fbitumbra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a13X-B%2Fbitumbra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a13X-B%2Fbitumbra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a13X-B%2Fbitumbra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/a13X-B","download_url":"https://codeload.github.com/a13X-B/bitumbra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a13X-B%2Fbitumbra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274660055,"owners_count":25326123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-06T00:01:53.551Z","updated_at":"2025-09-11T15:31:06.604Z","avatar_url":"https://github.com/a13X-B.png","language":"Lua","funding_links":[],"categories":["Lighting"],"sub_categories":[],"readme":"# bitumbra\nmany lights 2d shadows library for love framework\n\n![image](https://github.com/a13X-B/bitumbra/assets/53251919/a5aa4456-da96-4a1f-a33a-771c421569f6)\n\nrequirements: opengl3 with array textures and instancing support(which technically should be a part of any gl3 capable system)\n\nNOTE: functionality is still being added but already existing API is very unlikely to change\n\n## bitumbra API:\n```lua\nlocal bt = require\"bitumbra\"\n```\n- `bt.newShadowMap(width, height)` - creates a new shadow map that you can render to/sample from(advanced, coming soon)\n  - `width` and `height` are shadowmap dimensions\n- `bt.newOcclusionMesh(max_edges)` - creates a new occlusion mesh that represents shadow casting geometry\n  -  `max_edges` is the maximum amount of edges the mesh can store, 10000 by default\n- `bt.newLightsArray()` - creates an array containing up to 128 lights that will cast shadows or can be drawn sampling the shadowmap\n\n## lights array API:\n```lua\nlocal lights = bt.newLightsArray()\nlights:push(x,y,radius, r,g,b)\nlights:set(i, x,y,radius, r,g,b)\nlocal x,y = lights:pop()\nlocal n = lights.count\n```\n- `push(x,y,radius, r,g,b)` - pushes new light into the array, increases lights count\n  - `x,y` - light position\n  - `radius` - length at which the light falls to zero\n  - `r,g,b` - red, green, and blue components of the light in the range of [0,1]\n- `set(i, x,y,radius, r,g,b)` - sets\n  - `i` - index of the light to set\n  - `x,y,radius, r,g,b` - see `push`\n- `pop()` - returns `x`, `y`, `radius`, and `r`,`g`,`b` of the latest light and removes it from the list\n- `get(i)` - returns `x`, `y`, `radius`, and `r`,`g`,`b` of the light at index `i`\n- `applyTransform(x, y, angle, sx, sy, ox, oy, kx, ky)` - applies the standard love transformation to every light in the array\n  - `x,y` - translation\n  - `angle` - rotation angle in radians\n  - `sx, sy` - scale\n  - `ox, oy` - origin point, useful if you want to rotate a bunch of lights around an arbitrary point\n  - `kx, ky` - shear, I honestly have no idea who uses those but they're here for consistency with love API\n  - can also accept love's very own Transform object(love.math.newTransform()) instead\n- `count` - a number of currently set lights in the array\n- `draw(shadowmap)` - draws lights with respect of shadows stored in the shadowmap\n\n## occlusion mesh API:\n```lua\nlocal geo = bt.newOcclusionMesh()\nlocal circle = bt.newOcclusionMesh()\ngeo:addEdge(ax,ay, bx,by)\ncircle:addCircle(x, y, r)\ngeo:applyTransform(x, y, angle, sx, sy, ox, oy, kx, ky)\ngeo:addOcclusionMesh(circle)\n```\n- `addEdge(ax,ay, bx,by)` - adds an edge(straight line segment from point A to point B) to occlusion mesh\n  - `ax,ay bx,by` - x and y positions of both ends of an edge segment\n- `setEdge(i, ax,ay, bx,by)` - changes the existing edge\n  - `i` - the index of the edge to change\n- `addCircle(x, y, r, seg)` - adds a few edges shaped as a circle\n  - `x, y` - center of the circle\n  - `r` - circle radius\n  - `seg` - number of segments that will form the circle(13 by default)\n- `addOcclusionMesh(mesh)` - adds an existing occlusion mesh to the current mesh\n  - `mesh` - an already existing occlusion mesh\n  - useful when you want to combine a few meshes for the final effect\n- `applyTransform(x, y, angle, sx, sy, ox, oy, kx, ky)` - applies the standard love transformation to every edge of the mesh\n  - `x,y` - translation\n  - `angle` - rotation angle in radians\n  - `sx, sy` - scale\n  - `ox, oy` - origin point, useful if you want to rotate a mesh around an arbitrary point\n  - `kx, ky` - shear\n  - can also accept love's Transform object instead\n- `edge_count` - current edge count of the mesh\n\n## shadowmap API:\n```lua\nlocal sm = bt.newShadowMap(love.graphics.getDimensions())\n```\n- `sm.render(mesh, lights)` - renders occlusion `mesh` for every one of `lights` to the shadowmap\n\n## example\n```lua\nlocal bu = require(\"bitumbra\")\nlocal g = love.graphics\nlocal w, h = g.getDimensions()\n\nlocal sm = bu.newShadowMap(g.getDimensions()) -- full-screen shadowmap\n\nlocal geo = bu.newOcclusionMesh()\n--add a bunch of edges\ngeo:addEdge(w/2-50,h/2-50, w/2+50,h/2-50) -- ax,ay, bx,by\ngeo:addEdge(w/2+50,h/2-50, w/2+50,h/2+50)\ngeo:addEdge(w/2+50,h/2+50, w/2-50,h/2+50)\ngeo:addEdge(w/2-50,h/2+50, w/2-50,h/2-50)\n\n--another new meshes\nlocal circles = bu.newOcclusionMesh()\nlocal a = 0\nfor i=1, 16 do\n\tlocal x,y = math.cos(a), math.sin(a)\n\t\tcircles:addCircle(w/2+x*180,h/2+y*180,20,24)\n\ta = a + math.pi/8\nend\n\nlocal lights = bu.newLightsArray()\n--add a bunch of lights, all 128 to be precise\nfor y=1,8 do\n\tfor x=1,16 do\n\t\tlights:push( w/16*x-w/32, h*y/8-h/16, 400, .02,.02,.02)\n\tend\nend\n\nlocal count = geo.edge_count --remember the static count\nfunction love.update(dt)\n\t--reset edge count to static\n\tgeo.edge_count = count\n\t--move dynamic meshes\n\tcircles:applyTransform(w/2,h/2,dt/10,1,1,w/2,h/2)\n\t--and add them to the geometry mesh\n\tgeo:addOcclusionMesh(circles)\n\t--move one light to the mouse position(also make it brighter)\n\tlocal mx,my = love.mouse.getPosition()\n\tlights:set(1,mx,my,500, .3,.3,.3)\nend\n\nfunction love.draw()\n\tsm:render(geo, lights)\n\tlights:draw(sm)\nend\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa13X-B%2Fbitumbra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fa13X-B%2Fbitumbra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa13X-B%2Fbitumbra/lists"}