{"id":18022928,"url":"https://github.com/gingerbeardman/openscad-spritesheet","last_synced_at":"2025-03-26T23:30:55.694Z","repository":{"id":198252353,"uuid":"700404085","full_name":"gingerbeardman/openscad-spritesheet","owner":"gingerbeardman","description":"Workflow to generate sprite sheets from rotations of an OpenSCAD model.","archived":false,"fork":false,"pushed_at":"2023-10-04T15:50:16.000Z","size":269,"stargazers_count":13,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-20T02:58:43.674Z","etag":null,"topics":["animation","openscad","shell-scripts","spritesheet"],"latest_commit_sha":null,"homepage":"https://blog.gingerbeardman.com/2023/10/04/openscad-to-sprite-sheet/","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gingerbeardman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-10-04T14:31:27.000Z","updated_at":"2025-03-18T22:20:28.000Z","dependencies_parsed_at":"2023-10-05T02:17:17.688Z","dependency_job_id":"fc1bc679-60fa-4c14-89b1-ef1c1a4dc00e","html_url":"https://github.com/gingerbeardman/openscad-spritesheet","commit_stats":null,"previous_names":["gingerbeardman/openscad-spritesheet"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gingerbeardman%2Fopenscad-spritesheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gingerbeardman%2Fopenscad-spritesheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gingerbeardman%2Fopenscad-spritesheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gingerbeardman%2Fopenscad-spritesheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gingerbeardman","download_url":"https://codeload.github.com/gingerbeardman/openscad-spritesheet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245753858,"owners_count":20666823,"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","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":["animation","openscad","shell-scripts","spritesheet"],"created_at":"2024-10-30T07:06:22.451Z","updated_at":"2025-03-26T23:30:55.299Z","avatar_url":"https://github.com/gingerbeardman.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenSCAD to Sprite Sheet\n\nThis takes a [OpenSCAD](https://github.com/openscad/openscad) model and exports `$ROTS` rotations as individual frames. \n\nThe model is rendered in different poses such as wheels turned, body tilted, car or shadow. These are controlled by shell script variables that are either passed to the model in the call to OpenSCAD.\n\nThe process is clever enough to only render models that have changed since last build, those whose modified date is newer than the existing generated sprite sheet for that model.\n\n## Post Processing\n\nAfter exporting all frames there is some `image magick` work to process the files as follows:\n1. stitch frames together into a single sprite sheet\n2. split sprite sheet into RGBA channels\n3. process channels to recolour and dither as required\n4. recombine processed channels into new sprite sheet image\n\nYou can [read about that in an old blog post of mine](https://blog.gingerbeardman.com/2021/06/05/channelling-rgb-into-1bit/).\n\n## Notes\n\nThis workflow was made for my game [Daily Driver](https://gingerbeardman.itch.io/daily-driver) so a lot of the values are set to produce tiny, 1-bit, dithered sprites across several different poses, resulting in sprite sheet with 990 frames each for car and shadow totalling 1980 frames per model.\n\n## Optimisations\n\nAs many things are done in parallel as possible using shell script backgrounding, but there is still room for improvement. \n\nIt would be great if OpenSCAD could produce a sprite sheet which would remove the overhead of having to render many frames, write them to disk, then have another process read them back in and stitch them together.\n\n## Benchmarks\n\nA full build of 36 cars is as follows:\n\n- 3GHz 6-core Intel Mac mini 32GB\n  - 100% CPU for ~26 minutes\n- M1 Pro 10-core MacBook Pro 16GB\n  - 70% CPU for ~9 mins\n  - about 3x speedup\n  - approx 16 seconds per car\n\nThat's parallel 3D rendering, PNG writing \u0026 compositing \u0026 processing, and copying of ~140K files (which takes up ~0.5GB of disk space).\n\n----\n\n## Example Model\n\nNot to scale! Sizes of features are exagerated to allow for them to appear correct when rendered at a very small size.\n\n![](_car.png)\n\n## Example Output\n\n990 frames each for car and shadow, total of 1980 frames per sprite sheet. Each sprite sheet takes up about ~400KB of RAM on Playdate, and only one is loaded at a time.\n\n![](car-table-38-38.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgingerbeardman%2Fopenscad-spritesheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgingerbeardman%2Fopenscad-spritesheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgingerbeardman%2Fopenscad-spritesheet/lists"}