2个版本
0.1.1 | 2023年5月25日 |
---|---|
0.1.0 | 2023年5月25日 |
#1288 in 游戏开发
26 每月下载量
30KB
594 行
bevy_sprite_instancing
Bevy插件,用于在一次绘制调用中渲染大量实例精灵。
插件是如何工作的?
插件不是逐个处理类似实体精灵,而是提供 SpriteInstancingGroup
,其中可以包含这些精灵的实体ID。然后插件收集所有这些精灵的变换,并将它们作为一个大缓冲区提交给GPU,然后用于一次性绘制所有精灵。
功能
- 动画瓦片
- 绘制大量精灵时FPS表现良好(高达100万)
我该如何使用它?
查看这个快速示例: 示例。
以下是如何绘制大量精灵的简单示例
pub const ENTITY_COUNT: usize = 100000;
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// Create a camera
commands.spawn(Camera2dBundle::default());
// Load a spritesheet
let spritesheet = InstancedSpritesheet {
image: asset_server.load("textures/my_spritesheet.png"),
// Size of this spritesheet in tiles
width_tiles: 32,
height_tiles: 32,
};
// Create an instancing group for the sprites
let mut instancing_group = SpriteInstancingGroup {
entities: HashSet::new(),
};
let group_id = commands.spawn_empty().id();
// Spawn the sprites
for _ in 0..ENTITY_COUNT {
let position = Vec3::new(..., 0.0); // some random position
let scale = Vec3::new(..., 1.0); // some random size
let transform = ...; // create a transform from these
let sprite = InstancedSprite {
group_id,
texture_index: 0
};
let entity = commands.spawn((transform, sprite)).id();
instancing_group.entities.insert(entity);
}
// Attach the instancing group and its spritesheet
commands.entity(group_id).insert((instancing_group, spritesheet));
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(InstancedSpriteRenderPlugin)
.add_startup_system(setup)
.run()
}
尚未实现的功能
还有一些高级功能我尚未实现
- 视图区域裁剪:无需提交屏幕上不存在的精灵的变换
- GPU动画:不是为每个精灵提交一个
texture_index
,也许通过单独的实例化缓冲区提交anim_start_index
和anim_len
是一个好主意
... 以及一些低级功能
- 将
SpriteInstancingGroup
标记为静态(即实体不移动),以避免每帧重新提交其实例化数据
依赖关系
~37–73MB
~1M SLoC