{"id":15017990,"url":"https://github.com/johanhelsing/bevy_smud","last_synced_at":"2026-01-22T18:06:50.755Z","repository":{"id":39933382,"uuid":"452354192","full_name":"johanhelsing/bevy_smud","owner":"johanhelsing","description":"Sdf 2d shape renderer for Bevy","archived":false,"fork":false,"pushed_at":"2025-10-16T18:51:52.000Z","size":446,"stargazers_count":165,"open_issues_count":4,"forks_count":12,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-17T00:27:14.777Z","etag":null,"topics":["2d","bevy","bevy-plugin","game-development","sdf","shaders","shapes","signed-distance-field"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johanhelsing.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-01-26T16:33:55.000Z","updated_at":"2025-10-14T18:30:38.000Z","dependencies_parsed_at":"2023-11-21T09:27:15.822Z","dependency_job_id":"90903e84-a14e-442c-a0fa-c254af8f86f9","html_url":"https://github.com/johanhelsing/bevy_smud","commit_stats":{"total_commits":212,"total_committers":5,"mean_commits":42.4,"dds":0.06603773584905659,"last_synced_commit":"b5a88223185caa2b24d7c7f85a953a2c99d03aa4"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/johanhelsing/bevy_smud","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanhelsing%2Fbevy_smud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanhelsing%2Fbevy_smud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanhelsing%2Fbevy_smud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanhelsing%2Fbevy_smud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johanhelsing","download_url":"https://codeload.github.com/johanhelsing/bevy_smud/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanhelsing%2Fbevy_smud/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28667881,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T17:07:18.858Z","status":"ssl_error","status_checked_at":"2026-01-22T17:05:02.040Z","response_time":144,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["2d","bevy","bevy-plugin","game-development","sdf","shaders","shapes","signed-distance-field"],"created_at":"2024-09-24T19:51:17.591Z","updated_at":"2026-01-22T18:06:50.740Z","avatar_url":"https://github.com/johanhelsing.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bevy_smud\n\n[![crates.io](https://img.shields.io/crates/v/bevy_smud.svg)](https://crates.io/crates/bevy_smud)\n![MIT/Apache 2.0](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)\n[![crates.io](https://img.shields.io/crates/d/bevy_smud.svg)](https://crates.io/crates/bevy_smud)\n[![docs.rs](https://img.shields.io/docsrs/bevy_smud)](https://docs.rs/bevy_smud)\n\n[Signed_Distance_Field/Function][SDF] (SDF) 2D shape rendering for [Bevy](https://bevyengine.org).\n\n![screenshot of a bird drawn with bevy_smud](https://johanhelsing.studio/assets/bevy_smud_banner.png)\n\nBevy smud is a way to conveniently construct and render sdf shapes with Bevy.\n\nGiven a shape function/expression, and a fill type, it generates shaders at run-time.\n\nIf you keep the number of different sdf and fill combinations relatively low it's pretty performant. My machine easily handles 100k shapes at 60 fps, with 40 different shape/fill combinations in randomized order (see [gallery](https://github.com/johanhelsing/bevy_smud/blob/main/examples/gallery.rs) example).\n\n## Usage\n\nAn SDF is a way to map points in space to distances to a surface. If a point maps to a positive value, it's outside the shape, if it's negative, it's inside the shape. These \"mappings\" can be described by functions, which takes a point as input and returns a distance to a surface. For instance, if you wanted to make a circle, it could be described as `length(position - center) - radius`. That way, all the points that are `radius` away from `center` would be 0 and would define the edge of the shape.\n\nMany such functions describing geometric primitives are included in this library, they are imported automatically when using the single-expression or body shorthand for adding sdfs. For instance, the circle above could also be described as:\n\n```wgsl\nsmud::sd_circle(p - center, 50.)\n```\n\nSimilarly there are a bunch of other shapes (`sd_ellipse`, `sd_box`, `sd_rounded_box`, `sd_egg` etc. etc.)\n\nMost of the built-in shapes are direct ports of the ones on [this page](https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm), which includes screenshots of the various shapes. So that page might act as a good reference. The ports here use snake_case instead of camelCase.\n\nTo put together a shape, you can do:\n\n```rust no_run\nuse bevy::prelude::*;\nuse bevy_smud::prelude::*;\n\nfn main() {\n    App::new()\n        .add_plugins((DefaultPlugins, SmudPlugin))\n        .add_systems(Startup, setup)\n        .run();\n}\n\nfn setup(\n    mut commands: Commands,\n    mut shaders: ResMut\u003cAssets\u003cShader\u003e\u003e,\n) {\n    commands.spawn(Camera2d);\n\n    let circle = shaders.add_sdf_expr(\"smud::sd_circle(p, 50.)\");\n\n    commands.spawn(SmudShape {\n        color: Color::WHITE,\n        sdf: circle,\n        bounds: Rectangle::from_length(110.),\n        ..default()\n    });\n}\n```\n\nMake sure you reuse the shaders, i.e. don't call `add_sdf_expr` every frame.\n\nYou can also define shapes in .wgsl files. Note that in order to use the built-in shapes, you have to import [`smud`](https://github.com/johanhelsing/bevy_smud/blob/main/assets/smud.wgsl), and you must create a function named `sdf` that takes a `smud::SdfInput` and returns `f32`.\n\nOther than that, make sure you understand how to combine shapes, use symmetries and change domains. For instance, the [bevy](https://github.com/johanhelsing/bevy_smud/blob/main/assets/bevy.wgsl) in the screenshot above is built up of several circles, ellipses, and a vesica for the beak.\n\nAlso, check out the [examples](https://github.com/johanhelsing/bevy_smud/blob/main/examples). In particular, the [basic](https://github.com/johanhelsing/bevy_smud/blob/main/examples/basic.rs) example should be a good place to start.\n\n## Picking\n\nBevy_smud includes a picking backend that allows SDF shapes to respond to mouse/touch input. Add the `SmudPickingPlugin` to enable picking support:\n\n```rust no_run\nuse bevy::prelude::*;\nuse bevy_smud::prelude::*;\n\nfn main() {\n    App::new()\n        .add_plugins((DefaultPlugins, SmudPlugin, SmudPickingPlugin));\n        // ...\n}\n```\n\nThe picking backend supports both bounds-based picking (fast, uses shape bounds) and precise SDF-based picking (accurate, uses Rust distance functions that match the shape geometry). See the [picking example](https://github.com/johanhelsing/bevy_smud/blob/main/examples/picking.rs) for details.\n\n## Bevy Primitives\n\nFor convenience, bevy_smud provides `From` implementations for some of Bevy's built-in 2D primitive shapes (`Circle`, `Rectangle`, `Ellipse`, etc.), allowing you to quickly create SDF shapes without writing shader code. See the [bevy_primitives example](https://github.com/johanhelsing/bevy_smud/blob/main/examples/bevy_primitives.rs) for usage.\n\n## Showcase\n\nSend me a PR if you want your project featured here.\n\n### Bevy Smud Demo\n\n[@jakoschiko](https://github.com/jakoschiko/) made an interactive editor for `bevy_smud` shapes.\n\n[![bevy_smud_demo screenshot](https://raw.githubusercontent.com/jakoschiko/bevy_smud_demo/refs/heads/main/screenshot.png)](https://jakoschiko.github.io/bevy_smud_demo)\n\nIt lets you code sdf shaders and fills and tweak parameters while seeing a live preview on the side.\n\nIt contains a set of templates and is a good way to try out and get familiar with the tech.\n\n- [source code](https://github.com/jakoschiko/bevy_smud_demo)\n- [live demo](https://jakoschiko.github.io/bevy_smud_demo)\n\n### Dis order\n\n[![dis order screenshot](https://johanhelsing.studio/assets/dis-order.png)](https://jhelsing.itch.io/dis-order)\n\nA downloadable game I made for MiniJam. It uses sdfs to draw into an offscreen buffer which in turn is used in a compute shader to influence particle movement.\n\n## Bevy version support\n\nThe `main` branch targets the latest bevy release.\n\n|bevy|bevy_smud|\n|----|---------|\n|0.18|0.13, main|\n|0.17|0.12     |\n|0.16|0.11     |\n|0.15|no support|\n|0.14|0.9      |\n|0.12|0.7      |\n|0.11|0.6      |\n|0.10|0.5      |\n|0.9 |0.4      |\n|0.8 |0.3      |\n|0.7 |0.2      |\n|0.6 |0.1      |\n\n## Thanks!\n\nLittle of this crate is original work. It's mostly a mishmash of [`bevy_sprite`](https://github.com/bevyengine/bevy/tree/main/crates/bevy_sprite) and [Inigo Quilez sdf rendering primitives](https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm) ported to wgsl. I just put the two together in a way I found convenient.\n\n[SDF]: https://en.wikipedia.org/wiki/Signed_distance_function\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohanhelsing%2Fbevy_smud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohanhelsing%2Fbevy_smud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohanhelsing%2Fbevy_smud/lists"}