#3d #sprite #gamedev #bevy

bevy_sprite3d

Bevy Plugin to allow using 2d sprites in a 3d scene

18 stable releases (8 major)

8.0.0 Jan 15, 2026
7.0.0 Oct 7, 2025
7.0.0-rc Sep 15, 2025
6.0.0 Aug 18, 2025
0.1.0 Jul 29, 2022

#96 in Game dev

Download history 45/week @ 2026-01-22 135/week @ 2026-01-29 135/week @ 2026-02-05 182/week @ 2026-02-12 106/week @ 2026-02-19 131/week @ 2026-02-26 105/week @ 2026-03-05 161/week @ 2026-03-12 105/week @ 2026-03-19 109/week @ 2026-03-26 83/week @ 2026-04-02 142/week @ 2026-04-09 41/week @ 2026-04-16 86/week @ 2026-04-23 61/week @ 2026-04-30 24/week @ 2026-05-07

228 downloads per month
Used in 3 crates

MIT license

2.5MB
341 lines

bevy_sprite3d

Crates.io MIT

Use 2d sprites in a 3d bevy scene.

This is a pretty common setup in other engines (unity, godot, etc). Useful for:

  • 2d games using bevy's lighting (orthographic camera, 3d sprites)
  • 2d games with easier parallax and scale (perspective camera, 3d sprites)
  • 2d games in a 3d world (perspective camera, both 3d sprites and meshes)
  • 3d games with billboard sprites (a la Delver)

Both meshes and materials are internally cached, so this crate can be used for things like tilemaps without issue.

Examples

Example using bevy_sprite3d:

chaos

A more complicated scene: examples/dungeon.rs. Try this one with cargo run --example dungeon.

https://github.com/FraserLee/bevy_sprite3d/assets/30442265/1821b13c-9770-4f4e-a889-f67e06a3cda6

Some more examples. These don't use bevy, but demonstrate the effect style:

the last night

the last night

hollow knight

Usage

Check out the examples for details. Tl;dr initialize the plugin with

app.add_plugin(Sprite3dPlugin)

and spawn sprites with

fn setup(
    mut commands: Commands,
    images: Res<ImageAssets>, // this is your custom resource populated with asset handles
) {

    // ----------------------- Single Static Sprite ----------------------------

    commands.spawn((
        Sprite {
            image: images.sprite.clone(),
            ..default()
        },
        Sprite3d {
            pixels_per_metre: 400.,

            partial_alpha: true,

            unlit: true,

            ..default()

            // pivot: Some(Vec2::new(0.5, 0.5)),
            // double_sided: true,
        }
    ));

    // ------------------- Texture Atlas (Sprite Sheet) ------------------------

    let texture_atlas = TextureAtlas {
        layout: images.layout.clone(),
        index: 3,
    };

    commands.spawn((
        Sprite {
            image: images.sprite_sheet.clone(),
            texture_atlas: Some(texture_atlas),
            ..default()
        },
        Sprite3d {
            pixels_per_metre: 32.,
            partial_alpha: true,
            unlit: true,

            ..default()

            // pivot: Some(Vec2::new(0.5, 0.5)),
            // double_sided: true,
        }
    ));
}

One small complication: your image assets should be loaded prior to spawning, as bevy_sprite3d uses some properties of the image (such as size and aspect ratio) in constructing the 3d mesh. Examples show how to do this with Bevy's States.

Versioning

bevy_sprite3d version bevy version
8.0 0.18
7.0 0.17
7.0.0-rc 0.17.0-rc
5.0 - 6.0 0.16
5.0.0-rc 0.16.0-rc
4.0 0.15
3.0 0.14
2.8 0.13
2.7 0.12
2.5 - 2.6 0.11
2.4 0.10
2.1 - 2.3 0.9
1.1 - 2.0 0.8
1.0 0.7

Dependencies

~63–105MB
~2M SLoC