Crate bevy_resvg

Crate bevy_resvg 

Source
Expand description

§Bevy Resvg

A simple library for rendering SVGs in Bevy using the amazing Resvg library.

Crates.io Documentation Bevy Version Dependency Status

§Why not bevy_svg?

I originally tried forking bevy_svg to add colour tinting support to the SVGs, as proposed by bevy_svg/#54. However, I quickly noticed that the bevy_svg had so much technical debt (no offense to Weasy666, your library has clearly worked for many, many people) due to its 5 years of existence that it was just easier to start a new library from scratch.

Funnily enough, I’m actually publishing this crate onto crates.io on bevy_svg’s 5-year anniversary (January 24th)!

Bevy Resvg takes a completely different approach to rendering SVGs compared to bevy_svg. Instead of tesselating the SVG into a mesh, it first renders the SVG as a raster image using the Resvg library. This has both advantages and (unfortunately) drawbacks over bevy_svg’s approach:

§Comparison between Bevy Resvg and bevy_svg

FeatureBevy Resvgbevy_svg
Source Lines of Code🔽2331🔼191212
Code Complexity😀111😵14512
Changing runtime colorSupportedUnsupported
GradientsSupportedUnsupported
Semi-transparencySupportedUnsupported
Positioning and sizingNative (Sprite-based)Janky and imprecise
Static SVG Spec SupportFully Supported⚠️Partial Support
Rendered quality (normal)CrispCrisp
Rendered quality (zoomed)Blurry and PixelatedCrisp
3D-RenderingUnsupportedSupported
Hot-reloading of SVGsUnsupportedUnsupported
Animated SVGsUnsupportedUnsupported
Approach🖼️Rasterisation🔺Tesselation
Output🏃‍➡️Sprite🕸Mesh2d
Licence🟰MIT OR Apache-2.0🟰MIT OR Apache-2.0

…to be expanded…

§When to use Bevy Resvg over bevy_svg

Although I am very proud of this small little crate (it’s my first ever library to be published on crates.io!, I do realise that there are situations in which bevy_svg simply makes more sense.

For starters, Bevy Resvg is a very young and immature project. If you are looking for something more mature and battle-tested, you should probably use bevy_svg.

Another feature missing from Bevy Resvg is 3D rendering, which has first-class support in bevy_svg. Unfortunately, you can’t easily render to 3D objects with Bevy Resvg, yet. Don’t worry, it’s on the Todo-list! In the meantime, check out bevy_svg if you need to render to a 3D object.

Furthermore, if your game is dependent on zooming into the SVGs, bevy_svg might fit your needs better (particularly until custom render size target support is added). Bevy Resvg only performs rasterisation once, mimicking the behaviour of e.g. the Godot Engine. This has the unfortunate side-effect of causing blurry images when zooming in. bevy_svg, however, tesselates the SVGs into a crisp Mesh2d, which results in sharper rendering when zoomed in.

However, if you are in need of rendering semi-transparent SVGs, then Bevy Resvg is your only option (to my knowledge). Perhaps you even want to change the runtime colour of your loaded SVGs. In that case, Bevy Resvg makes it super simple! Just modify the outputted Sprite’s color field and you’ve got yourself a tinted SVG! That’s not possible (again, to my knowledge) in bevy_svg. What about gradients? No problem! Resvg handles gradients naturally too.

I’m not sure why (and, like many other things in this project, I haven’t bothered to test why), but positioning and especially sizing SVGs with bevy_svg as children of sprites felt clunky and required hard-coded values back when I used bevy_svg. I have yet to encounter that issue with Bevy Resvg.

Also, although I have no data to back this up, I would assume that Bevy Resvg might be a tiny bit faster than bevy_svg. Meshes feel more expensive than simple textures to me, however I am no expert in this area.

§Usage

See the examples directory for examples of how to use the Bevy Resvg.

Currently, the only examples are:

  • simple.rs: shows the most basic usage of Bevy Resvg
  • zoom.rs: shows what happens when you zoom too far into an SVG.

More examples are planned!

If you’re too lazy to click the link, here’s the contents of simple.rs:

use bevy::prelude::*;
use bevy_resvg::prelude::*;

fn main() {
    App::new()
        .add_plugins((DefaultPlugins, SvgPlugin))
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    let svg: Handle<SvgFile> = asset_server.load("transparent.svg");
    commands.spawn(Camera2d);
    commands.spawn(Svg(svg));
}

§Migration guide from bevy_svg

If you wish to migrate from bevy_svg to Bevy Resvg, you must do the following actions:

[!IMPORTANT] 3D rendering is not yet supported in Bevy Resvg.

  1. Run cargo remove bevy_svg and cargo add bevy_resvg.
  2. If you were just using bevy_svg::prelude in your code, simply replace it with bevy_resvg::prelude.
  3. Replace all occurences of Svg with SvgFile (make sure you’re doing whole-word replacing. You don’t want an SvgFilePlugin!).
  4. Replace all occurences of Svg2d with Svg.

§Todos

  • 3D-Rendering support
  • Add more examples
  • Add tests (there are currently none…)
  • Custom rendering size targets (not dependent on viewBox value)
  • Expand comparison table
    • Particularly, add performance comparisons
  • Handle more AssetEvents
    • Added
    • Modified
    • Removed
    • Unused
    • LoadedWithDependencies
  • usvg::Options support
    • CSS support

§Minimum supported Rust version

Bevy Resvg’s MSRV is 1.89 due to Bevy’s MSRV.

§Contributing

See CONTRIBUTING.md.

§Licence

MIT OR Apache-2.0, at your option.


  1. Calculated using scc, only counting Rust code. ↩ 1 2 3 4

  2. Based on the not-yet-merged 0.18 PR by cilki↩ 1 2

Modules§

error
Error utilities for this crate.
plugin
The Plugin for initialising the Bevy logic an configuration provided by this crate.
prelude
Import this module as use bevy_resvg::prelude::* to get convenient imports.
raster
Tools and helpers for loading, rastering, and rendering SVG files.