2019-11-13 03:36:02 +00:00
[ package ]
name = "bevy"
2022-11-12 20:01:29 +00:00
version = "0.9.0"
2021-10-27 00:12:14 +00:00
edition = "2021"
2020-11-10 03:26:08 +00:00
categories = [ "game-engines" , "graphics" , "gui" , "rendering" ]
2020-08-10 00:24:27 +00:00
description = "A refreshingly simple data-driven game engine and app framework"
2022-06-01 23:05:30 +00:00
exclude = [ "assets/" , "tools/" , ".github/" , "crates/" , "examples/wasm/assets/" ]
2020-08-10 00:24:27 +00:00
homepage = "https://bevyengine.org"
keywords = [ "game" , "engine" , "gamedev" , "graphics" , "bevy" ]
2021-07-23 21:11:51 +00:00
license = "MIT OR Apache-2.0"
2020-11-10 18:58:51 +00:00
readme = "README.md"
2020-11-10 03:26:08 +00:00
repository = "https://github.com/bevyengine/bevy"
2023-01-27 05:26:58 +00:00
rust-version = "1.67.0"
2020-11-10 03:26:08 +00:00
[ workspace ]
2023-01-02 21:07:33 +00:00
exclude = [ "benches" , "crates/bevy_ecs_compile_fail_tests" , "crates/bevy_reflect_compile_fail_tests" ]
2022-07-15 22:37:05 +00:00
members = [
"crates/*" ,
2022-11-25 23:02:56 +00:00
"examples/android" ,
2022-07-15 22:37:05 +00:00
"examples/ios" ,
"tools/ci" ,
"tools/build-example-pages" ,
"tools/build-wasm-example" ,
"errors" ,
]
2019-11-13 03:36:02 +00:00
2020-03-11 05:20:49 +00:00
[ features ]
2020-09-02 00:02:11 +00:00
default = [
2022-04-02 22:36:02 +00:00
"animation" ,
2022-07-25 15:48:14 +00:00
"bevy_asset" ,
2020-11-10 03:26:08 +00:00
"bevy_audio" ,
"bevy_gilrs" ,
2022-07-25 15:48:14 +00:00
"bevy_scene" ,
2020-11-10 03:26:08 +00:00
"bevy_winit" ,
2022-12-11 18:46:46 +00:00
"bevy_core_pipeline" ,
"bevy_pbr" ,
"bevy_gltf" ,
"bevy_render" ,
"bevy_sprite" ,
"bevy_text" ,
"bevy_ui" ,
2020-11-10 03:26:08 +00:00
"png" ,
"hdr" ,
2021-12-23 19:19:15 +00:00
"vorbis" ,
2020-11-10 03:26:08 +00:00
"x11" ,
2021-12-18 19:38:05 +00:00
"filesystem_watcher" ,
2020-09-02 00:02:11 +00:00
]
2020-11-03 00:30:30 +00:00
2020-11-10 03:26:08 +00:00
# Force dynamic linking, which improves iterative compile times
2023-01-23 14:28:00 +00:00
dynamic_linking = [ "bevy_dylib" , "bevy_internal/dynamic_linking" ]
2020-10-01 20:04:06 +00:00
2020-11-10 03:26:08 +00:00
# Optional bevy crates
2022-04-02 22:36:02 +00:00
bevy_animation = [ "bevy_internal/bevy_animation" ]
2022-07-25 15:48:14 +00:00
bevy_asset = [ "bevy_internal/bevy_asset" ]
2020-11-10 03:26:08 +00:00
bevy_audio = [ "bevy_internal/bevy_audio" ]
2021-12-14 03:58:23 +00:00
bevy_core_pipeline = [ "bevy_internal/bevy_core_pipeline" ]
2020-11-10 03:26:08 +00:00
bevy_dynamic_plugin = [ "bevy_internal/bevy_dynamic_plugin" ]
bevy_gilrs = [ "bevy_internal/bevy_gilrs" ]
bevy_gltf = [ "bevy_internal/bevy_gltf" ]
2022-01-04 19:49:38 +00:00
bevy_pbr = [ "bevy_internal/bevy_pbr" ]
bevy_render = [ "bevy_internal/bevy_render" ]
2022-07-25 15:48:14 +00:00
bevy_scene = [ "bevy_internal/bevy_scene" ]
2022-01-04 19:49:38 +00:00
bevy_sprite = [ "bevy_internal/bevy_sprite" ]
bevy_text = [ "bevy_internal/bevy_text" ]
bevy_ui = [ "bevy_internal/bevy_ui" ]
2020-11-10 03:26:08 +00:00
bevy_winit = [ "bevy_internal/bevy_winit" ]
2022-01-04 19:49:38 +00:00
# Tracing features
2021-12-18 00:09:22 +00:00
trace_chrome = [ "trace" , "bevy_internal/trace_chrome" ]
trace_tracy = [ "trace" , "bevy_internal/trace_tracy" ]
2020-11-11 02:49:49 +00:00
trace = [ "bevy_internal/trace" ]
2020-11-10 03:26:08 +00:00
wgpu_trace = [ "bevy_internal/wgpu_trace" ]
2020-08-11 06:30:42 +00:00
# Image format support for texture loading (PNG and HDR are enabled by default)
2020-11-10 03:26:08 +00:00
hdr = [ "bevy_internal/hdr" ]
png = [ "bevy_internal/png" ]
2020-12-10 02:34:27 +00:00
tga = [ "bevy_internal/tga" ]
jpeg = [ "bevy_internal/jpeg" ]
2020-12-23 22:53:02 +00:00
bmp = [ "bevy_internal/bmp" ]
2022-03-15 22:26:46 +00:00
basis-universal = [ "bevy_internal/basis-universal" ]
dds = [ "bevy_internal/dds" ]
ktx2 = [ "bevy_internal/ktx2" ]
# For ktx2 supercompression
zlib = [ "bevy_internal/zlib" ]
zstd = [ "bevy_internal/zstd" ]
2020-08-11 06:30:42 +00:00
2022-03-08 02:11:59 +00:00
# Audio format support (vorbis is enabled by default)
2020-11-10 03:26:08 +00:00
flac = [ "bevy_internal/flac" ]
mp3 = [ "bevy_internal/mp3" ]
vorbis = [ "bevy_internal/vorbis" ]
wav = [ "bevy_internal/wav" ]
2023-01-09 19:05:30 +00:00
symphonia-aac = [ "bevy_internal/symphonia-aac" ]
symphonia-all = [ "bevy_internal/symphonia-all" ]
symphonia-flac = [ "bevy_internal/symphonia-flac" ]
symphonia-isomp4 = [ "bevy_internal/symphonia-isomp4" ]
symphonia-mp3 = [ "bevy_internal/symphonia-mp3" ]
symphonia-vorbis = [ "bevy_internal/symphonia-vorbis" ]
symphonia-wav = [ "bevy_internal/symphonia-wav" ]
2020-08-11 06:30:42 +00:00
2021-11-13 21:15:22 +00:00
# Enable watching file system for asset hot reload
filesystem_watcher = [ "bevy_internal/filesystem_watcher" ]
2020-11-10 03:26:08 +00:00
serialize = [ "bevy_internal/serialize" ]
2020-08-22 01:13:50 +00:00
2020-08-25 00:06:08 +00:00
# Display server protocol support (X11 is enabled by default)
2020-11-10 03:26:08 +00:00
wayland = [ "bevy_internal/wayland" ]
x11 = [ "bevy_internal/x11" ]
2020-05-06 01:44:32 +00:00
2022-01-04 19:49:38 +00:00
# Enable rendering of font glyphs using subpixel accuracy
2021-01-03 20:39:11 +00:00
subpixel_glyph_atlas = [ "bevy_internal/subpixel_glyph_atlas" ]
2022-01-04 19:49:38 +00:00
# Enable systems that allow for automated testing on CI
2021-04-14 21:40:36 +00:00
bevy_ci_testing = [ "bevy_internal/bevy_ci_testing" ]
2022-02-18 22:56:57 +00:00
# Enable the "debug asset server" for hot reloading internal assets
debug_asset_server = [ "bevy_internal/debug_asset_server" ]
2022-04-02 22:36:02 +00:00
# Enable animation support, and glTF animation loading
animation = [ "bevy_internal/animation" ]
2019-11-13 03:36:02 +00:00
[ dependencies ]
2022-11-12 20:01:29 +00:00
bevy_dylib = { path = "crates/bevy_dylib" , version = "0.9.0" , default-features = false , optional = true }
bevy_internal = { path = "crates/bevy_internal" , version = "0.9.0" , default-features = false }
2020-04-06 03:19:02 +00:00
2021-12-22 20:59:48 +00:00
[ target . 'cfg(target_arch = "wasm32")' . dependencies ]
2022-11-12 20:01:29 +00:00
bevy_internal = { path = "crates/bevy_internal" , version = "0.9.0" , default-features = false , features = [
Reduce power usage with configurable event loop (#3974)
# Objective
- Reduce power usage for games when not focused.
- Reduce power usage to ~0 when a desktop application is minimized (opt-in).
- Reduce power usage when focused, only updating on a `winit` event, or the user sends a redraw request. (opt-in)
https://user-images.githubusercontent.com/2632925/156904387-ec47d7de-7f06-4c6f-8aaf-1e952c1153a2.mp4
Note resource usage in the Task Manager in the above video.
## Solution
- Added a type `UpdateMode` that allows users to specify how the winit event loop is updated, without exposing winit types.
- Added two fields to `WinitConfig`, both with the `UpdateMode` type. One configures how the application updates when focused, and the other configures how the application behaves when it is not focused. Users can modify this resource manually to set the type of event loop control flow they want.
- For convenience, two functions were added to `WinitConfig`, that provide reasonable presets: `game()` (default) and `desktop_app()`.
- The `game()` preset, which is used by default, is unchanged from current behavior with one exception: when the app is out of focus the app updates at a minimum of 10fps, or every time a winit event is received. This has a huge positive impact on power use and responsiveness on my machine, which will otherwise continue running the app at many hundreds of fps when out of focus or minimized.
- The `desktop_app()` preset is fully reactive, only updating when user input (winit event) is supplied or a `RedrawRequest` event is sent. When the app is out of focus, it only updates on `Window` events - i.e. any winit event that directly interacts with the window. What this means in practice is that the app uses *zero* resources when minimized or not interacted with, but still updates fluidly when the app is out of focus and the user mouses over the application.
- Added a `RedrawRequest` event so users can force an update even if there are no events. This is useful in an application when you want to, say, run an animation even when the user isn't providing input.
- Added an example `low_power` to demonstrate these changes
## Usage
Configuring the event loop:
```rs
use bevy::winit::{WinitConfig};
// ...
.insert_resource(WinitConfig::desktop_app()) // preset
// or
.insert_resource(WinitConfig::game()) // preset
// or
.insert_resource(WinitConfig{ .. }) // manual
```
Requesting a redraw:
```rs
use bevy::window::RequestRedraw;
// ...
fn request_redraw(mut event: EventWriter<RequestRedraw>) {
event.send(RequestRedraw);
}
```
## Other details
- Because we have a single event loop for multiple windows, every time I've mentioned "focused" above, I more precisely mean, "if at least one bevy window is focused".
- Due to a platform bug in winit (https://github.com/rust-windowing/winit/issues/1619), we can't simply use `Window::request_redraw()`. As a workaround, this PR will temporarily set the window mode to `Poll` when a redraw is requested. This is then reset to the user's `WinitConfig` setting on the next frame.
2022-03-07 23:32:05 +00:00
"webgl" ,
] }
2021-12-22 20:59:48 +00:00
2020-04-06 03:19:02 +00:00
[ dev-dependencies ]
2021-07-15 21:25:49 +00:00
anyhow = "1.0.4"
2021-01-17 21:43:03 +00:00
rand = "0.8.0"
2022-09-02 14:20:49 +00:00
ron = "0.8.0"
2021-08-01 19:14:47 +00:00
serde = { version = "1" , features = [ "derive" ] }
2022-01-05 19:43:11 +00:00
bytemuck = "1.7"
2021-05-23 20:13:55 +00:00
# Needed to poll Task examples
futures-lite = "1.11.3"
2022-02-05 01:52:47 +00:00
crossbeam-channel = "0.5.0"
2019-12-24 00:13:05 +00:00
2020-05-01 20:12:47 +00:00
[ [ example ] ]
name = "hello_world"
path = "examples/hello_world.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . hello_world ]
hidden = true
2021-02-22 04:50:05 +00:00
# 2D Rendering
2022-02-02 02:44:51 +00:00
[ [ example ] ]
name = "move_sprite"
path = "examples/2d/move_sprite.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . move_sprite ]
name = "Move Sprite"
description = "Changes the transform of a sprite"
category = "2D Rendering"
wasm = true
2022-01-25 22:10:11 +00:00
[ [ example ] ]
2022-02-25 15:54:03 +00:00
name = "rotation"
2022-01-25 22:10:11 +00:00
path = "examples/2d/rotation.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . rotation ]
name = "2D Rotation"
description = "Demonstrates rotating entities in 2D with quaternions"
category = "2D Rendering"
wasm = true
Add 2d meshes and materials (#3460)
# Objective
The current 2d rendering is specialized to render sprites, we need a generic way to render 2d items, using meshes and materials like we have for 3d.
## Solution
I cloned a good part of `bevy_pbr` into `bevy_sprite/src/mesh2d`, removed lighting and pbr itself, adapted it to 2d rendering, added a `ColorMaterial`, and modified the sprite rendering to break batches around 2d meshes.
~~The PR is a bit crude; I tried to change as little as I could in both the parts copied from 3d and the current sprite rendering to make reviewing easier. In the future, I expect we could make the sprite rendering a normal 2d material, cleanly integrated with the rest.~~ _edit: see <https://github.com/bevyengine/bevy/pull/3460#issuecomment-1003605194>_
## Remaining work
- ~~don't require mesh normals~~ _out of scope_
- ~~add an example~~ _done_
- support 2d meshes & materials in the UI?
- bikeshed names (I didn't think hard about naming, please check if it's fine)
## Remaining questions
- ~~should we add a depth buffer to 2d now that there are 2d meshes?~~ _let's revisit that when we have an opaque render phase_
- ~~should we add MSAA support to the sprites, or remove it from the 2d meshes?~~ _I added MSAA to sprites since it's really needed for 2d meshes_
- ~~how to customize vertex attributes?~~ _#3120_
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-01-08 01:29:08 +00:00
[ [ example ] ]
name = "mesh2d"
path = "examples/2d/mesh2d.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . mesh2d ]
name = "Mesh 2D"
description = "Renders a 2d mesh"
category = "2D Rendering"
wasm = true
Add 2d meshes and materials (#3460)
# Objective
The current 2d rendering is specialized to render sprites, we need a generic way to render 2d items, using meshes and materials like we have for 3d.
## Solution
I cloned a good part of `bevy_pbr` into `bevy_sprite/src/mesh2d`, removed lighting and pbr itself, adapted it to 2d rendering, added a `ColorMaterial`, and modified the sprite rendering to break batches around 2d meshes.
~~The PR is a bit crude; I tried to change as little as I could in both the parts copied from 3d and the current sprite rendering to make reviewing easier. In the future, I expect we could make the sprite rendering a normal 2d material, cleanly integrated with the rest.~~ _edit: see <https://github.com/bevyengine/bevy/pull/3460#issuecomment-1003605194>_
## Remaining work
- ~~don't require mesh normals~~ _out of scope_
- ~~add an example~~ _done_
- support 2d meshes & materials in the UI?
- bikeshed names (I didn't think hard about naming, please check if it's fine)
## Remaining questions
- ~~should we add a depth buffer to 2d now that there are 2d meshes?~~ _let's revisit that when we have an opaque render phase_
- ~~should we add MSAA support to the sprites, or remove it from the 2d meshes?~~ _I added MSAA to sprites since it's really needed for 2d meshes_
- ~~how to customize vertex attributes?~~ _#3120_
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-01-08 01:29:08 +00:00
[ [ example ] ]
name = "mesh2d_manual"
path = "examples/2d/mesh2d_manual.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . mesh2d_manual ]
name = "Manual Mesh 2D"
description = "Renders a custom mesh \"manually\" with \"mid-level\" renderer apis"
category = "2D Rendering"
wasm = true
2022-05-30 16:59:45 +00:00
[ [ example ] ]
name = "mesh2d_vertex_color_texture"
path = "examples/2d/mesh2d_vertex_color_texture.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . mesh2d_vertex_color_texture ]
name = "Mesh 2D With Vertex Colors"
description = "Renders a 2d mesh with vertex color attributes"
category = "2D Rendering"
wasm = true
Add an example to draw a rectangle (#2957)
# Objective
Every time I come back to Bevy I face the same issue: how do I draw a rectangle again? How did that work? So I go to https://github.com/bevyengine/bevy/tree/main/examples in the hope of finding literally the simplest possible example that draws something on the screen without any dependency such as an image. I don't want to have to add some image first, I just quickly want to get something on the screen with `main.rs` alone so that I can continue building on from that point on. Such an example is particularly helpful for a quick start for smaller projects that don't even need any assets such as images (this is my case currently).
Currently every single example of https://github.com/bevyengine/bevy/tree/main/examples#2d-rendering (which is the first section after hello world that beginners will look for for very minimalistic and quick examples) depends on at least an asset or is too complex. This PR solves this.
It also serves as a great comparison for a beginner to realize what Bevy is really like and how different it is from what they may expect Bevy to be. For example for someone coming from [LÖVE](https://love2d.org/), they will have something like this in their head when they think of drawing a rectangle:
```lua
function love.draw()
love.graphics.setColor(0.25, 0.25, 0.75);
love.graphics.rectangle("fill", 0, 0, 50, 50);
end
```
This, of course, differs quite a lot from what you do in Bevy. I imagine there will be people that just want to see something as simple as this in comparison to have a better understanding for the amount of differences.
## Solution
Add a dead simple example drawing a blue 50x50 rectangle in the center with no more and no less than needed.
2021-12-18 00:52:37 +00:00
[ [ example ] ]
2022-09-25 00:57:07 +00:00
name = "2d_shapes"
path = "examples/2d/2d_shapes.rs"
Add an example to draw a rectangle (#2957)
# Objective
Every time I come back to Bevy I face the same issue: how do I draw a rectangle again? How did that work? So I go to https://github.com/bevyengine/bevy/tree/main/examples in the hope of finding literally the simplest possible example that draws something on the screen without any dependency such as an image. I don't want to have to add some image first, I just quickly want to get something on the screen with `main.rs` alone so that I can continue building on from that point on. Such an example is particularly helpful for a quick start for smaller projects that don't even need any assets such as images (this is my case currently).
Currently every single example of https://github.com/bevyengine/bevy/tree/main/examples#2d-rendering (which is the first section after hello world that beginners will look for for very minimalistic and quick examples) depends on at least an asset or is too complex. This PR solves this.
It also serves as a great comparison for a beginner to realize what Bevy is really like and how different it is from what they may expect Bevy to be. For example for someone coming from [LÖVE](https://love2d.org/), they will have something like this in their head when they think of drawing a rectangle:
```lua
function love.draw()
love.graphics.setColor(0.25, 0.25, 0.75);
love.graphics.rectangle("fill", 0, 0, 50, 50);
end
```
This, of course, differs quite a lot from what you do in Bevy. I imagine there will be people that just want to see something as simple as this in comparison to have a better understanding for the amount of differences.
## Solution
Add a dead simple example drawing a blue 50x50 rectangle in the center with no more and no less than needed.
2021-12-18 00:52:37 +00:00
2022-09-25 00:57:07 +00:00
[ package . metadata . example . 2 d_shapes ]
name = "2D Shapes"
2022-06-25 20:23:24 +00:00
description = "Renders a rectangle, circle, and hexagon"
category = "2D Rendering"
wasm = true
2020-05-04 08:22:25 +00:00
[ [ example ] ]
name = "sprite"
path = "examples/2d/sprite.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . sprite ]
name = "Sprite"
description = "Renders a sprite"
category = "2D Rendering"
wasm = true
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
[ [ example ] ]
name = "sprite_flipping"
path = "examples/2d/sprite_flipping.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . sprite_flipping ]
name = "Sprite Flipping"
description = "Renders a sprite flipped along an axis"
category = "2D Rendering"
wasm = true
2020-06-02 02:23:11 +00:00
[ [ example ] ]
name = "sprite_sheet"
path = "examples/2d/sprite_sheet.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . sprite_sheet ]
name = "Sprite Sheet"
description = "Renders an animated sprite"
category = "2D Rendering"
wasm = true
2020-12-27 19:19:03 +00:00
[ [ example ] ]
name = "text2d"
path = "examples/2d/text2d.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . text2d ]
name = "Text 2D"
description = "Generates text in 2D"
category = "2D Rendering"
wasm = true
2021-02-22 04:50:05 +00:00
[ [ example ] ]
name = "texture_atlas"
path = "examples/2d/texture_atlas.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . texture_atlas ]
name = "Texture Atlas"
description = "Generates a texture atlas (sprite sheet) from individual sprites"
category = "2D Rendering"
wasm = true
2022-06-06 17:52:09 +00:00
[ [ example ] ]
name = "transparency_2d"
path = "examples/2d/transparency_2d.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . transparency_2d ]
name = "Transparency in 2D"
description = "Demonstrates transparency in 2d"
category = "2D Rendering"
wasm = true
2022-11-14 22:15:46 +00:00
[ [ example ] ]
name = "pixel_perfect"
path = "examples/2d/pixel_perfect.rs"
[ package . metadata . example . pixel_perfect ]
name = "Pixel Perfect"
description = "Demonstrates pixel perfect in 2d"
category = "2D Rendering"
wasm = true
2021-02-22 04:50:05 +00:00
# 3D Rendering
2021-01-01 20:58:49 +00:00
[ [ example ] ]
name = "3d_scene"
path = "examples/3d/3d_scene.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . 3 d_scene ]
name = "3D Scene"
description = "Simple 3D scene with basic shapes and lighting"
category = "3D Rendering"
wasm = true
Camera Driven Viewports (#4898)
# Objective
Users should be able to render cameras to specific areas of a render target, which enables scenarios like split screen, minimaps, etc.
Builds on the new Camera Driven Rendering added here: #4745
Fixes: #202
Alternative to #1389 and #3626 (which are incompatible with the new Camera Driven Rendering)
## Solution
![image](https://user-images.githubusercontent.com/2694663/171560044-f0694f67-0cd9-4598-83e2-a9658c4fed57.png)
Cameras can now configure an optional "viewport", which defines a rectangle within their render target to draw to. If a `Viewport` is defined, the camera's `CameraProjection`, `View`, and visibility calculations will use the viewport configuration instead of the full render target.
```rust
// This camera will render to the first half of the primary window (on the left side).
commands.spawn_bundle(Camera3dBundle {
camera: Camera {
viewport: Some(Viewport {
physical_position: UVec2::new(0, 0),
physical_size: UVec2::new(window.physical_width() / 2, window.physical_height()),
depth: 0.0..1.0,
}),
..default()
},
..default()
});
```
To account for this, the `Camera` component has received a few adjustments:
* `Camera` now has some new getter functions:
* `logical_viewport_size`, `physical_viewport_size`, `logical_target_size`, `physical_target_size`, `projection_matrix`
* All computed camera values are now private and live on the `ComputedCameraValues` field (logical/physical width/height, the projection matrix). They are now exposed on `Camera` via getters/setters This wasn't _needed_ for viewports, but it was long overdue.
---
## Changelog
### Added
* `Camera` components now have a `viewport` field, which can be set to draw to a portion of a render target instead of the full target.
* `Camera` component has some new functions: `logical_viewport_size`, `physical_viewport_size`, `logical_target_size`, `physical_target_size`, and `projection_matrix`
* Added a new split_screen example illustrating how to render two cameras to the same scene
## Migration Guide
`Camera::projection_matrix` is no longer a public field. Use the new `Camera::projection_matrix()` method instead:
```rust
// Bevy 0.7
let projection = camera.projection_matrix;
// Bevy 0.8
let projection = camera.projection_matrix();
```
2022-06-05 00:27:49 +00:00
[ [ example ] ]
name = "3d_shapes"
2022-09-25 00:57:07 +00:00
path = "examples/3d/3d_shapes.rs"
Camera Driven Viewports (#4898)
# Objective
Users should be able to render cameras to specific areas of a render target, which enables scenarios like split screen, minimaps, etc.
Builds on the new Camera Driven Rendering added here: #4745
Fixes: #202
Alternative to #1389 and #3626 (which are incompatible with the new Camera Driven Rendering)
## Solution
![image](https://user-images.githubusercontent.com/2694663/171560044-f0694f67-0cd9-4598-83e2-a9658c4fed57.png)
Cameras can now configure an optional "viewport", which defines a rectangle within their render target to draw to. If a `Viewport` is defined, the camera's `CameraProjection`, `View`, and visibility calculations will use the viewport configuration instead of the full render target.
```rust
// This camera will render to the first half of the primary window (on the left side).
commands.spawn_bundle(Camera3dBundle {
camera: Camera {
viewport: Some(Viewport {
physical_position: UVec2::new(0, 0),
physical_size: UVec2::new(window.physical_width() / 2, window.physical_height()),
depth: 0.0..1.0,
}),
..default()
},
..default()
});
```
To account for this, the `Camera` component has received a few adjustments:
* `Camera` now has some new getter functions:
* `logical_viewport_size`, `physical_viewport_size`, `logical_target_size`, `physical_target_size`, `projection_matrix`
* All computed camera values are now private and live on the `ComputedCameraValues` field (logical/physical width/height, the projection matrix). They are now exposed on `Camera` via getters/setters This wasn't _needed_ for viewports, but it was long overdue.
---
## Changelog
### Added
* `Camera` components now have a `viewport` field, which can be set to draw to a portion of a render target instead of the full target.
* `Camera` component has some new functions: `logical_viewport_size`, `physical_viewport_size`, `logical_target_size`, `physical_target_size`, and `projection_matrix`
* Added a new split_screen example illustrating how to render two cameras to the same scene
## Migration Guide
`Camera::projection_matrix` is no longer a public field. Use the new `Camera::projection_matrix()` method instead:
```rust
// Bevy 0.7
let projection = camera.projection_matrix;
// Bevy 0.8
let projection = camera.projection_matrix();
```
2022-06-05 00:27:49 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . 3 d_shapes ]
name = "3D Shapes"
description = "A scene showcasing the built-in 3D shapes"
category = "3D Rendering"
wasm = true
Add Distance and Atmospheric Fog support (#6412)
<img width="1392" alt="image" src="https://user-images.githubusercontent.com/418473/203873533-44c029af-13b7-4740-8ea3-af96bd5867c9.png">
<img width="1392" alt="image" src="https://user-images.githubusercontent.com/418473/203873549-36be7a23-b341-42a2-8a9f-ceea8ac7a2b8.png">
# Objective
- Add support for the “classic” distance fog effect, as well as a more advanced atmospheric fog effect.
## Solution
This PR:
- Introduces a new `FogSettings` component that controls distance fog per-camera.
- Adds support for three widely used “traditional” fog falloff modes: `Linear`, `Exponential` and `ExponentialSquared`, as well as a more advanced `Atmospheric` fog;
- Adds support for directional light influence over fog color;
- Extracts fog via `ExtractComponent`, then uses a prepare system that sets up a new dynamic uniform struct (`Fog`), similar to other mesh view types;
- Renders fog in PBR material shader, as a final adjustment to the `output_color`, after PBR is computed (but before tone mapping);
- Adds a new `StandardMaterial` flag to enable fog; (`fog_enabled`)
- Adds convenience methods for easier artistic control when creating non-linear fog types;
- Adds documentation around fog.
---
## Changelog
### Added
- Added support for distance-based fog effects for PBR materials, controllable per-camera via the new `FogSettings` component;
- Added `FogFalloff` enum for selecting between three widely used “traditional” fog falloff modes: `Linear`, `Exponential` and `ExponentialSquared`, as well as a more advanced `Atmospheric` fog;
2023-01-29 15:28:56 +00:00
[ [ example ] ]
name = "atmospheric_fog"
path = "examples/3d/atmospheric_fog.rs"
[ package . metadata . example . atmospheric_fog ]
name = "Atmospheric Fog"
description = "A scene showcasing the atmospheric fog effect"
category = "3D Rendering"
wasm = true
[ [ example ] ]
name = "fog"
path = "examples/3d/fog.rs"
[ package . metadata . example . fog ]
name = "Fog"
description = "A scene showcasing the distance fog effect"
category = "3D Rendering"
wasm = true
2023-01-21 21:46:53 +00:00
[ [ example ] ]
name = "blend_modes"
path = "examples/3d/blend_modes.rs"
[ package . metadata . example . blend_modes ]
name = "Blend Modes"
description = "Showcases different blend modes"
category = "3D Rendering"
wasm = true
2021-06-02 02:59:17 +00:00
[ [ example ] ]
2021-12-14 03:58:23 +00:00
name = "lighting"
path = "examples/3d/lighting.rs"
2021-07-08 02:49:33 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . lighting ]
name = "Lighting"
description = "Illustrates various lighting options in a simple scene"
category = "3D Rendering"
wasm = true
2022-07-15 22:37:05 +00:00
[ [ example ] ]
name = "lines"
path = "examples/3d/lines.rs"
[ package . metadata . example . lines ]
name = "Lines"
description = "Create a custom material to draw 3d lines"
category = "3D Rendering"
wasm = true
2022-07-08 19:57:43 +00:00
[ [ example ] ]
name = "spotlight"
path = "examples/3d/spotlight.rs"
[ package . metadata . example . spotlight ]
name = "Spotlight"
description = "Illustrates spot lights"
category = "3D Rendering"
wasm = true
2022-11-04 01:34:12 +00:00
[ [ example ] ]
name = "bloom"
path = "examples/3d/bloom.rs"
[ package . metadata . example . bloom ]
name = "Bloom"
description = "Illustrates bloom configuration using HDR and emissive materials"
category = "3D Rendering"
wasm = false
2020-05-01 20:12:47 +00:00
[ [ example ] ]
2020-10-18 20:48:15 +00:00
name = "load_gltf"
path = "examples/3d/load_gltf.rs"
2020-05-01 20:12:47 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . load_gltf ]
name = "Load glTF"
description = "Loads and renders a glTF file as a scene"
category = "3D Rendering"
wasm = true
2022-11-02 06:51:28 +00:00
[ [ example ] ]
name = "fxaa"
path = "examples/3d/fxaa.rs"
[ package . metadata . example . fxaa ]
name = "FXAA"
description = "Compares MSAA (Multi-Sample Anti-Aliasing) and FXAA (Fast Approximate Anti-Aliasing)"
category = "3D Rendering"
wasm = true
2020-07-30 01:15:15 +00:00
[ [ example ] ]
name = "msaa"
path = "examples/3d/msaa.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . msaa ]
name = "MSAA"
description = "Configures MSAA (Multi-Sample Anti-Aliasing) for smoother edges"
category = "3D Rendering"
wasm = true
2021-02-01 00:22:06 +00:00
[ [ example ] ]
name = "orthographic"
path = "examples/3d/orthographic.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . orthographic ]
name = "Orthographic View"
description = "Shows how to create a 3D orthographic view (for isometric-look in games or CAD applications)"
category = "3D Rendering"
wasm = true
2020-05-01 20:12:47 +00:00
[ [ example ] ]
name = "parenting"
path = "examples/3d/parenting.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . parenting ]
name = "Parenting"
description = "Demonstrates parent->child relationships and relative transformations"
category = "3D Rendering"
wasm = true
2021-03-20 03:22:33 +00:00
[ [ example ] ]
name = "pbr"
path = "examples/3d/pbr.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . pbr ]
name = "Physically Based Rendering"
description = "Demonstrates use of Physically Based Rendering (PBR) properties"
category = "3D Rendering"
wasm = true
2022-05-05 00:46:32 +00:00
[ [ example ] ]
name = "render_to_texture"
path = "examples/3d/render_to_texture.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . render_to_texture ]
name = "Render to Texture"
description = "Shows how to render to a texture, useful for mirrors, UI, or exporting images"
category = "3D Rendering"
wasm = true
2021-06-27 23:10:23 +00:00
[ [ example ] ]
2021-12-14 03:58:23 +00:00
name = "shadow_biases"
path = "examples/3d/shadow_biases.rs"
2021-07-19 19:20:59 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . shadow_biases ]
name = "Shadow Biases"
description = "Demonstrates how shadow biases affect shadows in a 3d scene"
category = "3D Rendering"
wasm = true
2021-08-25 19:44:20 +00:00
[ [ example ] ]
2021-12-14 03:58:23 +00:00
name = "shadow_caster_receiver"
path = "examples/3d/shadow_caster_receiver.rs"
2020-05-01 20:12:47 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . shadow_caster_receiver ]
name = "Shadow Caster and Receiver"
description = "Demonstrates how to prevent meshes from casting/receiving shadows in a 3d scene"
category = "3D Rendering"
wasm = true
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
[ [ example ] ]
name = "skybox"
path = "examples/3d/skybox.rs"
required-features = [ "ktx2" , "zstd" ]
[ package . metadata . example . skybox ]
name = "Skybox"
description = "Load a cubemap texture onto a cube like a skybox and cycle through different compressed texture formats."
category = "3D Rendering"
wasm = false
2021-12-30 21:07:26 +00:00
[ [ example ] ]
name = "spherical_area_lights"
path = "examples/3d/spherical_area_lights.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . spherical_area_lights ]
name = "Spherical Area Lights"
description = "Demonstrates how point light radius values affect light behavior"
category = "3D Rendering"
wasm = true
Camera Driven Viewports (#4898)
# Objective
Users should be able to render cameras to specific areas of a render target, which enables scenarios like split screen, minimaps, etc.
Builds on the new Camera Driven Rendering added here: #4745
Fixes: #202
Alternative to #1389 and #3626 (which are incompatible with the new Camera Driven Rendering)
## Solution
![image](https://user-images.githubusercontent.com/2694663/171560044-f0694f67-0cd9-4598-83e2-a9658c4fed57.png)
Cameras can now configure an optional "viewport", which defines a rectangle within their render target to draw to. If a `Viewport` is defined, the camera's `CameraProjection`, `View`, and visibility calculations will use the viewport configuration instead of the full render target.
```rust
// This camera will render to the first half of the primary window (on the left side).
commands.spawn_bundle(Camera3dBundle {
camera: Camera {
viewport: Some(Viewport {
physical_position: UVec2::new(0, 0),
physical_size: UVec2::new(window.physical_width() / 2, window.physical_height()),
depth: 0.0..1.0,
}),
..default()
},
..default()
});
```
To account for this, the `Camera` component has received a few adjustments:
* `Camera` now has some new getter functions:
* `logical_viewport_size`, `physical_viewport_size`, `logical_target_size`, `physical_target_size`, `projection_matrix`
* All computed camera values are now private and live on the `ComputedCameraValues` field (logical/physical width/height, the projection matrix). They are now exposed on `Camera` via getters/setters This wasn't _needed_ for viewports, but it was long overdue.
---
## Changelog
### Added
* `Camera` components now have a `viewport` field, which can be set to draw to a portion of a render target instead of the full target.
* `Camera` component has some new functions: `logical_viewport_size`, `physical_viewport_size`, `logical_target_size`, `physical_target_size`, and `projection_matrix`
* Added a new split_screen example illustrating how to render two cameras to the same scene
## Migration Guide
`Camera::projection_matrix` is no longer a public field. Use the new `Camera::projection_matrix()` method instead:
```rust
// Bevy 0.7
let projection = camera.projection_matrix;
// Bevy 0.8
let projection = camera.projection_matrix();
```
2022-06-05 00:27:49 +00:00
[ [ example ] ]
name = "split_screen"
path = "examples/3d/split_screen.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . split_screen ]
name = "Split Screen"
description = "Demonstrates how to render two cameras to the same window to accomplish \"split screen\""
category = "3D Rendering"
wasm = true
2020-05-01 20:12:47 +00:00
[ [ example ] ]
name = "texture"
path = "examples/3d/texture.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . texture ]
name = "Texture"
description = "Shows configuration of texture materials"
category = "3D Rendering"
wasm = true
2022-06-06 17:52:09 +00:00
[ [ example ] ]
name = "transparency_3d"
path = "examples/3d/transparency_3d.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . transparency_3d ]
name = "Transparency in 3D"
description = "Demonstrates transparency in 3d"
category = "3D Rendering"
wasm = true
2022-04-12 19:27:30 +00:00
[ [ example ] ]
name = "two_passes"
path = "examples/3d/two_passes.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . two_passes ]
name = "Two Passes"
description = "Renders two 3d passes to the same window from different perspectives"
category = "3D Rendering"
wasm = true
2021-01-01 20:58:49 +00:00
[ [ example ] ]
name = "update_gltf_scene"
path = "examples/3d/update_gltf_scene.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . update_gltf_scene ]
name = "Update glTF Scene"
description = "Update a scene from a glTF file, either by spawning the scene as a child of another entity, or by accessing the entities of the scene"
category = "3D Rendering"
wasm = true
2022-05-05 00:46:32 +00:00
[ [ example ] ]
name = "vertex_colors"
path = "examples/3d/vertex_colors.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . vertex_colors ]
name = "Vertex Colors"
description = "Shows the use of vertex colors"
category = "3D Rendering"
wasm = true
2021-03-04 01:23:24 +00:00
[ [ example ] ]
name = "wireframe"
path = "examples/3d/wireframe.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . wireframe ]
name = "Wireframe"
description = "Showcases wireframe rendering"
category = "3D Rendering"
wasm = true
2022-03-29 18:31:13 +00:00
# Animation
2022-04-02 22:36:02 +00:00
[ [ example ] ]
name = "animated_fox"
path = "examples/animation/animated_fox.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . animated_fox ]
name = "Animated Fox"
description = "Plays an animation from a skinned glTF"
category = "Animation"
wasm = true
2022-04-07 23:53:43 +00:00
[ [ example ] ]
name = "animated_transform"
path = "examples/animation/animated_transform.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . animated_transform ]
name = "Animated Transform"
description = "Create and play an animation defined by code that operates on the `Transform` component"
category = "Animation"
wasm = true
2022-03-29 18:31:13 +00:00
[ [ example ] ]
name = "custom_skinned_mesh"
path = "examples/animation/custom_skinned_mesh.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . custom_skinned_mesh ]
name = "Custom Skinned Mesh"
description = "Skinned mesh example with mesh and joints data defined in code"
category = "Animation"
wasm = true
2022-03-29 18:31:13 +00:00
[ [ example ] ]
name = "gltf_skinned_mesh"
path = "examples/animation/gltf_skinned_mesh.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . gltf_skinned_mesh ]
name = "glTF Skinned Mesh"
description = "Skinned mesh example with mesh and joints data loaded from a glTF file"
category = "Animation"
wasm = true
2021-02-22 04:50:05 +00:00
# Application
2020-11-09 21:04:27 +00:00
[ [ example ] ]
name = "custom_loop"
path = "examples/app/custom_loop.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . custom_loop ]
name = "Custom Loop"
description = "Demonstrates how to create a custom runner (to update an app manually)"
category = "Application"
wasm = false
2021-01-01 21:31:22 +00:00
[ [ example ] ]
name = "drag_and_drop"
path = "examples/app/drag_and_drop.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . drag_and_drop ]
name = "Drag and Drop"
description = "An example that shows how to handle drag and drop in an app"
category = "Application"
wasm = false
2020-05-01 20:12:47 +00:00
[ [ example ] ]
name = "empty"
path = "examples/app/empty.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . empty ]
name = "Empty"
description = "An empty application (does nothing)"
category = "Application"
wasm = false
2020-11-13 01:23:57 +00:00
[ [ example ] ]
2021-02-22 04:50:05 +00:00
name = "empty_defaults"
path = "examples/app/empty_defaults.rs"
2020-11-13 01:23:57 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . empty_defaults ]
name = "Empty with Defaults"
description = "An empty application with default plugins"
category = "Application"
wasm = true
2020-05-01 20:12:47 +00:00
[ [ example ] ]
name = "headless"
path = "examples/app/headless.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . headless ]
name = "Headless"
description = "An application that runs without default plugins"
category = "Application"
wasm = false
2021-02-22 04:50:05 +00:00
[ [ example ] ]
name = "logs"
path = "examples/app/logs.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . logs ]
name = "Logs"
description = "Illustrate how to use generate log output"
category = "Application"
wasm = true
2020-05-03 08:30:10 +00:00
[ [ example ] ]
name = "plugin"
path = "examples/app/plugin.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . plugin ]
name = "Plugin"
description = "Demonstrates the creation and registration of a custom plugin"
category = "Application"
wasm = true
2020-10-29 20:04:28 +00:00
[ [ example ] ]
name = "plugin_group"
path = "examples/app/plugin_group.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . plugin_group ]
name = "Plugin Group"
description = "Demonstrates the creation and registration of a custom plugin group"
category = "Application"
wasm = true
2020-08-21 05:37:19 +00:00
[ [ example ] ]
name = "return_after_run"
path = "examples/app/return_after_run.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . return_after_run ]
name = "Return after Run"
description = "Show how to return to main after the Bevy app has exited"
category = "Application"
wasm = false
2020-08-14 17:15:29 +00:00
[ [ example ] ]
name = "thread_pool_resources"
path = "examples/app/thread_pool_resources.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . thread_pool_resources ]
name = "Thread Pool Resources"
description = "Creates and customizes the internal thread pool"
category = "Application"
wasm = false
2022-01-08 10:39:43 +00:00
[ [ example ] ]
2022-07-11 14:11:32 +00:00
name = "no_renderer"
path = "examples/app/no_renderer.rs"
2022-01-08 10:39:43 +00:00
2022-07-11 14:11:32 +00:00
[ package . metadata . example . no_renderer ]
name = "No Renderer"
description = "An application that runs with default plugins and displays an empty window, but without an actual renderer"
2022-06-25 20:23:24 +00:00
category = "Application"
wasm = false
2021-12-15 00:15:47 +00:00
[ [ example ] ]
name = "without_winit"
path = "examples/app/without_winit.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . without_winit ]
name = "Without Winit"
description = "Create an application without winit (runs single time, no event loop)"
category = "Application"
wasm = false
2021-02-22 04:50:05 +00:00
# Assets
2020-05-17 03:18:30 +00:00
[ [ example ] ]
name = "asset_loading"
path = "examples/asset/asset_loading.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . asset_loading ]
name = "Asset Loading"
description = "Demonstrates various methods to load assets"
category = "Assets"
wasm = true
2020-10-01 18:31:06 +00:00
[ [ example ] ]
2020-10-18 20:48:15 +00:00
name = "custom_asset"
path = "examples/asset/custom_asset.rs"
2020-10-01 18:31:06 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . custom_asset ]
name = "Custom Asset"
description = "Implements a custom asset loader"
category = "Assets"
wasm = true
2020-12-18 19:34:44 +00:00
[ [ example ] ]
name = "custom_asset_io"
path = "examples/asset/custom_asset_io.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . custom_asset_io ]
name = "Custom Asset IO"
description = "Implements a custom asset io loader"
category = "Assets"
wasm = true
2021-02-22 04:50:05 +00:00
[ [ example ] ]
name = "hot_asset_reloading"
path = "examples/asset/hot_asset_reloading.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . hot_asset_reloading ]
name = "Hot Reloading of Assets"
description = "Demonstrates automatic reloading of assets when modified on disk"
category = "Assets"
wasm = true
2021-05-23 20:13:55 +00:00
# Async Tasks
[ [ example ] ]
name = "async_compute"
path = "examples/async_tasks/async_compute.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . async_compute ]
name = "Async Compute"
description = "How to use `AsyncComputeTaskPool` to complete longer running tasks"
category = "Async Tasks"
wasm = false
2022-02-05 01:52:47 +00:00
[ [ example ] ]
name = "external_source_external_thread"
path = "examples/async_tasks/external_source_external_thread.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . external_source_external_thread ]
name = "External Source of Data on an External Thread"
description = "How to use an external thread to run an infinite task and communicate with a channel"
category = "Async Tasks"
wasm = false
2021-02-22 04:50:05 +00:00
# Audio
2020-07-16 20:46:51 +00:00
[ [ example ] ]
name = "audio"
path = "examples/audio/audio.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . audio ]
name = "Audio"
description = "Shows how to load and play an audio file"
category = "Audio"
wasm = true
2022-03-01 01:12:11 +00:00
[ [ example ] ]
name = "audio_control"
path = "examples/audio/audio_control.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . audio_control ]
name = "Audio Control"
description = "Shows how to load and play an audio file, and control how it's played"
category = "Audio"
wasm = true
2023-01-17 22:42:00 +00:00
[ [ example ] ]
name = "decodable"
path = "examples/audio/decodable.rs"
[ package . metadata . example . decodable ]
name = "Decodable"
description = "Shows how to create and register a custom audio source by implementing the `Decodable` type."
category = "Audio"
wasm = true
2021-02-22 04:50:05 +00:00
# Diagnostics
[ [ example ] ]
name = "log_diagnostics"
path = "examples/diagnostics/log_diagnostics.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . log_diagnostics ]
name = "Log Diagnostics"
description = "Add a plugin that logs diagnostics, like frames per second (FPS), to the console"
category = "Diagnostics"
wasm = true
2020-05-04 21:14:49 +00:00
[ [ example ] ]
name = "custom_diagnostic"
path = "examples/diagnostics/custom_diagnostic.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . custom_diagnostic ]
name = "Custom Diagnostic"
description = "Shows how to create a custom diagnostic"
category = "Diagnostics"
wasm = true
2021-02-22 04:50:05 +00:00
# ECS (Entity Component System)
2020-05-04 21:14:49 +00:00
[ [ example ] ]
2021-02-22 04:50:05 +00:00
name = "ecs_guide"
path = "examples/ecs/ecs_guide.rs"
2020-05-04 21:14:49 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . ecs_guide ]
name = "ECS Guide"
description = "Full guide to Bevy's ECS"
category = "ECS (Entity Component System)"
wasm = false
2020-12-31 22:29:08 +00:00
[ [ example ] ]
2021-07-12 20:09:43 +00:00
name = "component_change_detection"
path = "examples/ecs/component_change_detection.rs"
2020-12-31 22:29:08 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . component_change_detection ]
name = "Component Change Detection"
description = "Change detection on components"
category = "ECS (Entity Component System)"
wasm = false
Implement `WorldQuery` derive macro (#2713)
# Objective
- Closes #786
- Closes #2252
- Closes #2588
This PR implements a derive macro that allows users to define their queries as structs with named fields.
## Example
```rust
#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct NumQuery<'w, T: Component, P: Component> {
entity: Entity,
u: UNumQuery<'w>,
generic: GenericQuery<'w, T, P>,
}
#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct UNumQuery<'w> {
u_16: &'w u16,
u_32_opt: Option<&'w u32>,
}
#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct GenericQuery<'w, T: Component, P: Component> {
generic: (&'w T, &'w P),
}
#[derive(WorldQuery)]
#[world_query(filter)]
struct NumQueryFilter<T: Component, P: Component> {
_u_16: With<u16>,
_u_32: With<u32>,
_or: Or<(With<i16>, Changed<u16>, Added<u32>)>,
_generic_tuple: (With<T>, With<P>),
_without: Without<Option<u16>>,
_tp: PhantomData<(T, P)>,
}
fn print_nums_readonly(query: Query<NumQuery<u64, i64>, NumQueryFilter<u64, i64>>) {
for num in query.iter() {
println!("{:#?}", num);
}
}
#[derive(WorldQuery)]
#[world_query(mutable, derive(Debug))]
struct MutNumQuery<'w, T: Component, P: Component> {
i_16: &'w mut i16,
i_32_opt: Option<&'w mut i32>,
}
fn print_nums(mut query: Query<MutNumQuery, NumQueryFilter<u64, i64>>) {
for num in query.iter_mut() {
println!("{:#?}", num);
}
}
```
## TODOs:
- [x] Add support for `&T` and `&mut T`
- [x] Test
- [x] Add support for optional types
- [x] Test
- [x] Add support for `Entity`
- [x] Test
- [x] Add support for nested `WorldQuery`
- [x] Test
- [x] Add support for tuples
- [x] Test
- [x] Add support for generics
- [x] Test
- [x] Add support for query filters
- [x] Test
- [x] Add support for `PhantomData`
- [x] Test
- [x] Refactor `read_world_query_field_type_info`
- [x] Properly document `readonly` attribute for nested queries and the static assertions that guarantee safety
- [x] Test that we never implement `ReadOnlyFetch` for types that need mutable access
- [x] Test that we insert static assertions for nested `WorldQuery` that a user marked as readonly
2022-02-24 00:19:49 +00:00
[ [ example ] ]
name = "custom_query_param"
path = "examples/ecs/custom_query_param.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . custom_query_param ]
name = "Custom Query Parameters"
description = "Groups commonly used compound queries and query filters into a single type"
category = "ECS (Entity Component System)"
wasm = false
2020-05-01 20:12:47 +00:00
[ [ example ] ]
name = "event"
path = "examples/ecs/event.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . event ]
name = "Event"
description = "Illustrates event creation, activation, and reception"
category = "ECS (Entity Component System)"
wasm = false
2020-12-13 02:04:42 +00:00
[ [ example ] ]
name = "fixed_timestep"
path = "examples/ecs/fixed_timestep.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . fixed_timestep ]
name = "Fixed Timestep"
description = "Shows how to create systems that run every fixed timestep, rather than every tick"
category = "ECS (Entity Component System)"
wasm = false
2022-02-08 16:24:46 +00:00
[ [ example ] ]
name = "generic_system"
path = "examples/ecs/generic_system.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . generic_system ]
name = "Generic System"
description = "Shows how to create systems that can be reused with different types"
category = "ECS (Entity Component System)"
wasm = false
2021-02-22 04:50:05 +00:00
[ [ example ] ]
name = "hierarchy"
path = "examples/ecs/hierarchy.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . hierarchy ]
name = "Hierarchy"
description = "Creates a hierarchy of parents and children entities"
category = "ECS (Entity Component System)"
wasm = false
Add a method `iter_combinations` on query to iterate over combinations of query results (#1763)
Related to [discussion on discord](https://discord.com/channels/691052431525675048/742569353878437978/824731187724681289)
With const generics, it is now possible to write generic iterator over multiple entities at once.
This enables patterns of query iterations like
```rust
for [e1, e2, e3] in query.iter_combinations() {
// do something with relation of all three entities
}
```
The compiler is able to infer the correct iterator for given size of array, so either of those work
```rust
for [e1, e2] in query.iter_combinations() { ... }
for [e1, e2, e3] in query.iter_combinations() { ... }
```
This feature can be very useful for systems like collision detection.
When you ask for permutations of size K of N entities:
- if K == N, you get one result of all entities
- if K < N, you get all possible subsets of N with size K, without repetition
- if K > N, the result set is empty (no permutation of size K exist)
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-05-17 23:33:47 +00:00
[ [ example ] ]
name = "iter_combinations"
path = "examples/ecs/iter_combinations.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . iter_combinations ]
name = "Iter Combinations"
description = "Shows how to iterate over combinations of query results"
category = "ECS (Entity Component System)"
wasm = true
2021-02-22 04:50:05 +00:00
[ [ example ] ]
name = "parallel_query"
path = "examples/ecs/parallel_query.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . parallel_query ]
name = "Parallel Query"
description = "Illustrates parallel queries with `ParallelIterator`"
category = "ECS (Entity Component System)"
wasm = false
2021-02-22 04:50:05 +00:00
[ [ example ] ]
name = "removal_detection"
path = "examples/ecs/removal_detection.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . removal_detection ]
name = "Removal Detection"
description = "Query for entities that had a specific component removed in a previous stage during the current frame"
category = "ECS (Entity Component System)"
wasm = false
2020-05-01 20:12:47 +00:00
[ [ example ] ]
name = "startup_system"
path = "examples/ecs/startup_system.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . startup_system ]
name = "Startup System"
description = "Demonstrates a startup system (one that runs once when the app starts up)"
category = "ECS (Entity Component System)"
wasm = false
2020-12-13 02:04:42 +00:00
[ [ example ] ]
name = "state"
path = "examples/ecs/state.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . state ]
name = "State"
description = "Illustrates how to use States to control transitioning from a Menu state to an InGame state"
category = "ECS (Entity Component System)"
wasm = false
2020-11-17 02:18:00 +00:00
[ [ example ] ]
2022-10-11 15:21:12 +00:00
name = "system_piping"
path = "examples/ecs/system_piping.rs"
2020-11-17 02:18:00 +00:00
2022-10-11 15:21:12 +00:00
[ package . metadata . example . system_piping ]
name = "System Piping"
description = "Pipe the output of one system into a second, allowing you to handle any errors gracefully"
2022-06-25 20:23:24 +00:00
category = "ECS (Entity Component System)"
wasm = false
2022-04-27 18:02:07 +00:00
[ [ example ] ]
name = "system_closure"
path = "examples/ecs/system_closure.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . system_closure ]
name = "System Closure"
description = "Show how to use closures as systems, and how to configure `Local` variables by capturing external state"
category = "ECS (Entity Component System)"
wasm = false
2021-03-03 03:11:11 +00:00
[ [ example ] ]
name = "system_param"
path = "examples/ecs/system_param.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . system_param ]
name = "System Parameter"
description = "Illustrates creating custom system parameters with `SystemParam`"
category = "ECS (Entity Component System)"
wasm = false
2021-04-23 19:08:16 +00:00
[ [ example ] ]
name = "system_sets"
path = "examples/ecs/system_sets.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . system_sets ]
name = "System Sets"
description = "Shows `SystemSet` use along with run criterion"
category = "ECS (Entity Component System)"
wasm = false
2020-11-27 19:39:33 +00:00
[ [ example ] ]
name = "timers"
path = "examples/ecs/timers.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . timers ]
name = "Timers"
description = "Illustrates ticking `Timer` resources inside systems and handling their state"
category = "ECS (Entity Component System)"
wasm = false
2021-02-22 04:50:05 +00:00
# Games
2021-01-21 22:10:02 +00:00
[ [ example ] ]
name = "alien_cake_addict"
2022-04-10 02:05:21 +00:00
path = "examples/games/alien_cake_addict.rs"
2021-01-21 22:10:02 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . alien_cake_addict ]
name = "Alien Cake Addict"
description = "Eat the cakes. Eat them all. An example 3D game"
category = "Games"
wasm = true
2020-06-27 04:40:09 +00:00
[ [ example ] ]
name = "breakout"
2022-04-10 02:05:21 +00:00
path = "examples/games/breakout.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . breakout ]
name = "Breakout"
description = "An implementation of the classic game \"Breakout\""
category = "Games"
wasm = true
2022-04-10 02:05:21 +00:00
[ [ example ] ]
name = "contributors"
path = "examples/games/contributors.rs"
2020-06-27 04:40:09 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . contributors ]
name = "Contributors"
description = "Displays each contributor as a bouncy bevy-ball!"
category = "Games"
wasm = true
2022-01-14 19:09:42 +00:00
[ [ example ] ]
name = "game_menu"
2022-04-10 02:05:21 +00:00
path = "examples/games/game_menu.rs"
2022-01-14 19:09:42 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . game_menu ]
name = "Game Menu"
description = "A simple game menu"
category = "Games"
wasm = true
2021-02-22 04:50:05 +00:00
# Input
2020-05-01 20:12:47 +00:00
[ [ example ] ]
2021-02-22 04:50:05 +00:00
name = "char_input_events"
path = "examples/input/char_input_events.rs"
2020-05-01 20:12:47 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . char_input_events ]
name = "Char Input Events"
description = "Prints out all chars as they are inputted"
category = "Input"
wasm = false
2020-05-01 20:12:47 +00:00
[ [ example ] ]
2021-02-22 04:50:05 +00:00
name = "gamepad_input"
path = "examples/input/gamepad_input.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . gamepad_input ]
name = "Gamepad Input"
description = "Shows handling of gamepad input, connections, and disconnections"
category = "Input"
wasm = false
2021-02-22 04:50:05 +00:00
[ [ example ] ]
name = "gamepad_input_events"
path = "examples/input/gamepad_input_events.rs"
2020-06-05 06:49:36 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . gamepad_input_events ]
name = "Gamepad Input Events"
description = "Iterates and prints gamepad input and connection events"
category = "Input"
wasm = false
2020-06-05 06:49:36 +00:00
[ [ example ] ]
name = "keyboard_input"
path = "examples/input/keyboard_input.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . keyboard_input ]
name = "Keyboard Input"
description = "Demonstrates handling a key press/release"
category = "Input"
wasm = false
2021-03-14 21:00:36 +00:00
[ [ example ] ]
name = "keyboard_modifiers"
path = "examples/input/keyboard_modifiers.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . keyboard_modifiers ]
name = "Keyboard Modifiers"
description = "Demonstrates using key modifiers (ctrl, shift)"
category = "Input"
wasm = false
2020-06-05 06:49:36 +00:00
[ [ example ] ]
name = "keyboard_input_events"
path = "examples/input/keyboard_input_events.rs"
2020-05-01 20:12:47 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . keyboard_input_events ]
name = "Keyboard Input Events"
description = "Prints out all keyboard events"
category = "Input"
wasm = false
2020-11-07 01:15:56 +00:00
[ [ example ] ]
2021-02-22 04:50:05 +00:00
name = "mouse_input"
path = "examples/input/mouse_input.rs"
2020-09-18 21:43:47 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . mouse_input ]
name = "Mouse Input"
description = "Demonstrates handling a mouse button press/release"
category = "Input"
wasm = false
2020-10-21 17:27:00 +00:00
[ [ example ] ]
2021-02-22 04:50:05 +00:00
name = "mouse_input_events"
path = "examples/input/mouse_input_events.rs"
2020-10-21 17:27:00 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . mouse_input_events ]
name = "Mouse Input Events"
description = "Prints out all mouse events (buttons, movement, etc.)"
category = "Input"
wasm = false
2022-03-08 17:14:08 +00:00
[ [ example ] ]
name = "mouse_grab"
path = "examples/input/mouse_grab.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . mouse_grab ]
name = "Mouse Grab"
description = "Demonstrates how to grab the mouse, locking the cursor to the app's screen"
category = "Input"
wasm = false
2020-10-18 19:24:01 +00:00
[ [ example ] ]
name = "touch_input"
path = "examples/input/touch_input.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . touch_input ]
name = "Touch Input"
description = "Displays touch presses, releases, and cancels"
category = "Input"
wasm = false
2020-10-18 19:24:01 +00:00
[ [ example ] ]
2020-10-18 20:20:42 +00:00
name = "touch_input_events"
path = "examples/input/touch_input_events.rs"
2020-10-18 19:24:01 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . touch_input_events ]
name = "Touch Input Events"
description = "Prints out all touch inputs"
category = "Input"
wasm = false
2023-01-29 20:27:29 +00:00
[ [ example ] ]
name = "text_input"
path = "examples/input/text_input.rs"
[ package . metadata . example . text_input ]
name = "Text Input"
description = "Simple text input with IME support"
category = "Input"
wasm = false
2021-02-22 04:50:05 +00:00
# Reflection
2020-05-01 20:12:47 +00:00
[ [ example ] ]
2020-11-28 00:39:59 +00:00
name = "reflection"
path = "examples/reflection/reflection.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . reflection ]
name = "Reflection"
description = "Demonstrates how reflection in Bevy provides a way to dynamically interact with Rust types"
category = "Reflection"
wasm = false
2020-11-28 00:39:59 +00:00
[ [ example ] ]
name = "generic_reflection"
path = "examples/reflection/generic_reflection.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . generic_reflection ]
name = "Generic Reflection"
description = "Registers concrete instances of generic types that may be used with reflection"
category = "Reflection"
wasm = false
2021-02-22 04:50:05 +00:00
[ [ example ] ]
name = "reflection_types"
path = "examples/reflection/reflection_types.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . reflection_types ]
name = "Reflection Types"
description = "Illustrates the various reflection types available"
category = "Reflection"
wasm = false
2020-11-28 00:39:59 +00:00
[ [ example ] ]
name = "trait_reflection"
path = "examples/reflection/trait_reflection.rs"
2020-05-01 20:12:47 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . trait_reflection ]
name = "Trait Reflection"
description = "Allows reflection with trait objects"
category = "Reflection"
wasm = false
2021-02-22 04:50:05 +00:00
# Scene
2020-05-22 06:58:11 +00:00
[ [ example ] ]
2020-11-28 00:39:59 +00:00
name = "scene"
path = "examples/scene/scene.rs"
2020-05-22 06:58:11 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . scene ]
name = "Scene"
description = "Demonstrates loading from and saving scenes to files"
category = "Scene"
wasm = false
2021-02-22 04:50:05 +00:00
# Shaders
2022-06-25 20:23:24 +00:00
[ [ package . metadata . category ] ]
name = "Shaders"
description = "" "
These examples demonstrate how to implement different shaders in user code .
A shader in its most common usage is a small program that is run by the GPU per-vertex in a mesh ( a vertex shader ) or per-affected-screen-fragment ( a fragment shader . ) The GPU executes these programs in a highly parallel way .
There are also compute shaders which are used for more general processing leveraging the GPU ' s parallelism .
"" "
Mesh vertex buffer layouts (#3959)
This PR makes a number of changes to how meshes and vertex attributes are handled, which the goal of enabling easy and flexible custom vertex attributes:
* Reworks the `Mesh` type to use the newly added `VertexAttribute` internally
* `VertexAttribute` defines the name, a unique `VertexAttributeId`, and a `VertexFormat`
* `VertexAttributeId` is used to produce consistent sort orders for vertex buffer generation, replacing the more expensive and often surprising "name based sorting"
* Meshes can be used to generate a `MeshVertexBufferLayout`, which defines the layout of the gpu buffer produced by the mesh. `MeshVertexBufferLayouts` can then be used to generate actual `VertexBufferLayouts` according to the requirements of a specific pipeline. This decoupling of "mesh layout" vs "pipeline vertex buffer layout" is what enables custom attributes. We don't need to standardize _mesh layouts_ or contort meshes to meet the needs of a specific pipeline. As long as the mesh has what the pipeline needs, it will work transparently.
* Mesh-based pipelines now specialize on `&MeshVertexBufferLayout` via the new `SpecializedMeshPipeline` trait (which behaves like `SpecializedPipeline`, but adds `&MeshVertexBufferLayout`). The integrity of the pipeline cache is maintained because the `MeshVertexBufferLayout` is treated as part of the key (which is fully abstracted from implementers of the trait ... no need to add any additional info to the specialization key).
* Hashing `MeshVertexBufferLayout` is too expensive to do for every entity, every frame. To make this scalable, I added a generalized "pre-hashing" solution to `bevy_utils`: `Hashed<T>` keys and `PreHashMap<K, V>` (which uses `Hashed<T>` internally) . Why didn't I just do the quick and dirty in-place "pre-compute hash and use that u64 as a key in a hashmap" that we've done in the past? Because its wrong! Hashes by themselves aren't enough because two different values can produce the same hash. Re-hashing a hash is even worse! I decided to build a generalized solution because this pattern has come up in the past and we've chosen to do the wrong thing. Now we can do the right thing! This did unfortunately require pulling in `hashbrown` and using that in `bevy_utils`, because avoiding re-hashes requires the `raw_entry_mut` api, which isn't stabilized yet (and may never be ... `entry_ref` has favor now, but also isn't available yet). If std's HashMap ever provides the tools we need, we can move back to that. Note that adding `hashbrown` doesn't increase our dependency count because it was already in our tree. I will probably break these changes out into their own PR.
* Specializing on `MeshVertexBufferLayout` has one non-obvious behavior: it can produce identical pipelines for two different MeshVertexBufferLayouts. To optimize the number of active pipelines / reduce re-binds while drawing, I de-duplicate pipelines post-specialization using the final `VertexBufferLayout` as the key. For example, consider a pipeline that needs the layout `(position, normal)` and is specialized using two meshes: `(position, normal, uv)` and `(position, normal, other_vec2)`. If both of these meshes result in `(position, normal)` specializations, we can use the same pipeline! Now we do. Cool!
To briefly illustrate, this is what the relevant section of `MeshPipeline`'s specialization code looks like now:
```rust
impl SpecializedMeshPipeline for MeshPipeline {
type Key = MeshPipelineKey;
fn specialize(
&self,
key: Self::Key,
layout: &MeshVertexBufferLayout,
) -> RenderPipelineDescriptor {
let mut vertex_attributes = vec![
Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
Mesh::ATTRIBUTE_NORMAL.at_shader_location(1),
Mesh::ATTRIBUTE_UV_0.at_shader_location(2),
];
let mut shader_defs = Vec::new();
if layout.contains(Mesh::ATTRIBUTE_TANGENT) {
shader_defs.push(String::from("VERTEX_TANGENTS"));
vertex_attributes.push(Mesh::ATTRIBUTE_TANGENT.at_shader_location(3));
}
let vertex_buffer_layout = layout
.get_layout(&vertex_attributes)
.expect("Mesh is missing a vertex attribute");
```
Notice that this is _much_ simpler than it was before. And now any mesh with any layout can be used with this pipeline, provided it has vertex postions, normals, and uvs. We even got to remove `HAS_TANGENTS` from MeshPipelineKey and `has_tangents` from `GpuMesh`, because that information is redundant with `MeshVertexBufferLayout`.
This is still a draft because I still need to:
* Add more docs
* Experiment with adding error handling to mesh pipeline specialization (which would print errors at runtime when a mesh is missing a vertex attribute required by a pipeline). If it doesn't tank perf, we'll keep it.
* Consider breaking out the PreHash / hashbrown changes into a separate PR.
* Add an example illustrating this change
* Verify that the "mesh-specialized pipeline de-duplication code" works properly
Please dont yell at me for not doing these things yet :) Just trying to get this in peoples' hands asap.
Alternative to #3120
Fixes #3030
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-02-23 23:21:13 +00:00
[ [ example ] ]
name = "custom_vertex_attribute"
path = "examples/shader/custom_vertex_attribute.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . custom_vertex_attribute ]
name = "Custom Vertex Attribute"
description = "A shader that reads a mesh's custom vertex attribute"
category = "Shaders"
wasm = true
2022-06-06 00:06:49 +00:00
[ [ example ] ]
name = "post_processing"
path = "examples/shader/post_processing.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . post_processing ]
name = "Post Processing"
description = "A custom post processing effect, using two cameras, with one reusing the render texture of the first one"
category = "Shaders"
wasm = true
2020-05-01 20:12:47 +00:00
[ [ example ] ]
name = "shader_defs"
path = "examples/shader/shader_defs.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . shader_defs ]
name = "Shader Defs"
description = "A shader that uses \"shaders defs\" (a bevy tool to selectively toggle parts of a shader)"
category = "Shaders"
wasm = true
Modular Rendering (#2831)
This changes how render logic is composed to make it much more modular. Previously, all extraction logic was centralized for a given "type" of rendered thing. For example, we extracted meshes into a vector of ExtractedMesh, which contained the mesh and material asset handles, the transform, etc. We looked up bindings for "drawn things" using their index in the `Vec<ExtractedMesh>`. This worked fine for built in rendering, but made it hard to reuse logic for "custom" rendering. It also prevented us from reusing things like "extracted transforms" across contexts.
To make rendering more modular, I made a number of changes:
* Entities now drive rendering:
* We extract "render components" from "app components" and store them _on_ entities. No more centralized uber lists! We now have true "ECS-driven rendering"
* To make this perform well, I implemented #2673 in upstream Bevy for fast batch insertions into specific entities. This was merged into the `pipelined-rendering` branch here: #2815
* Reworked the `Draw` abstraction:
* Generic `PhaseItems`: each draw phase can define its own type of "rendered thing", which can define its own "sort key"
* Ported the 2d, 3d, and shadow phases to the new PhaseItem impl (currently Transparent2d, Transparent3d, and Shadow PhaseItems)
* `Draw` trait and and `DrawFunctions` are now generic on PhaseItem
* Modular / Ergonomic `DrawFunctions` via `RenderCommands`
* RenderCommand is a trait that runs an ECS query and produces one or more RenderPass calls. Types implementing this trait can be composed to create a final DrawFunction. For example the DrawPbr DrawFunction is created from the following DrawCommand tuple. Const generics are used to set specific bind group locations:
```rust
pub type DrawPbr = (
SetPbrPipeline,
SetMeshViewBindGroup<0>,
SetStandardMaterialBindGroup<1>,
SetTransformBindGroup<2>,
DrawMesh,
);
```
* The new `custom_shader_pipelined` example illustrates how the commands above can be reused to create a custom draw function:
```rust
type DrawCustom = (
SetCustomMaterialPipeline,
SetMeshViewBindGroup<0>,
SetTransformBindGroup<2>,
DrawMesh,
);
```
* ExtractComponentPlugin and UniformComponentPlugin:
* Simple, standardized ways to easily extract individual components and write them to GPU buffers
* Ported PBR and Sprite rendering to the new primitives above.
* Removed staging buffer from UniformVec in favor of direct Queue usage
* Makes UniformVec much easier to use and more ergonomic. Completely removes the need for custom render graph nodes in these contexts (see the PbrNode and view Node removals and the much simpler call patterns in the relevant Prepare systems).
* Added a many_cubes_pipelined example to benchmark baseline 3d rendering performance and ensure there were no major regressions during this port. Avoiding regressions was challenging given that the old approach of extracting into centralized vectors is basically the "optimal" approach. However thanks to a various ECS optimizations and render logic rephrasing, we pretty much break even on this benchmark!
* Lifetimeless SystemParams: this will be a bit divisive, but as we continue to embrace "trait driven systems" (ex: ExtractComponentPlugin, UniformComponentPlugin, DrawCommand), the ergonomics of `(Query<'static, 'static, (&'static A, &'static B, &'static)>, Res<'static, C>)` were getting very hard to bear. As a compromise, I added "static type aliases" for the relevant SystemParams. The previous example can now be expressed like this: `(SQuery<(Read<A>, Read<B>)>, SRes<C>)`. If anyone has better ideas / conflicting opinions, please let me know!
* RunSystem trait: a way to define Systems via a trait with a SystemParam associated type. This is used to implement the various plugins mentioned above. I also added SystemParamItem and QueryItem type aliases to make "trait stye" ecs interactions nicer on the eyes (and fingers).
* RenderAsset retrying: ensures that render assets are only created when they are "ready" and allows us to create bind groups directly inside render assets (which significantly simplified the StandardMaterial code). I think ultimately we should swap this out on "asset dependency" events to wait for dependencies to load, but this will require significant asset system changes.
* Updated some built in shaders to account for missing MeshUniform fields
2021-09-23 06:16:11 +00:00
[ [ example ] ]
2021-12-14 03:58:23 +00:00
name = "shader_material"
path = "examples/shader/shader_material.rs"
Pipeline Specialization, Shader Assets, and Shader Preprocessing (#3031)
## New Features
This adds the following to the new renderer:
* **Shader Assets**
* Shaders are assets again! Users no longer need to call `include_str!` for their shaders
* Shader hot-reloading
* **Shader Defs / Shader Preprocessing**
* Shaders now support `# ifdef NAME`, `# ifndef NAME`, and `# endif` preprocessor directives
* **Bevy RenderPipelineDescriptor and RenderPipelineCache**
* Bevy now provides its own `RenderPipelineDescriptor` and the wgpu version is now exported as `RawRenderPipelineDescriptor`. This allows users to define pipelines with `Handle<Shader>` instead of needing to manually compile and reference `ShaderModules`, enables passing in shader defs to configure the shader preprocessor, makes hot reloading possible (because the descriptor can be owned and used to create new pipelines when a shader changes), and opens the doors to pipeline specialization.
* The `RenderPipelineCache` now handles compiling and re-compiling Bevy RenderPipelineDescriptors. It has internal PipelineLayout and ShaderModule caches. Users receive a `CachedPipelineId`, which can be used to look up the actual `&RenderPipeline` during rendering.
* **Pipeline Specialization**
* This enables defining per-entity-configurable pipelines that specialize on arbitrary custom keys. In practice this will involve specializing based on things like MSAA values, Shader Defs, Bind Group existence, and Vertex Layouts.
* Adds a `SpecializedPipeline` trait and `SpecializedPipelines<MyPipeline>` resource. This is a simple layer that generates Bevy RenderPipelineDescriptors based on a custom key defined for the pipeline.
* Specialized pipelines are also hot-reloadable.
* This was the result of experimentation with two different approaches:
1. **"generic immediate mode multi-key hash pipeline specialization"**
* breaks up the pipeline into multiple "identities" (the core pipeline definition, shader defs, mesh layout, bind group layout). each of these identities has its own key. looking up / compiling a specific version of a pipeline requires composing all of these keys together
* the benefit of this approach is that it works for all pipelines / the pipeline is fully identified by the keys. the multiple keys allow pre-hashing parts of the pipeline identity where possible (ex: pre compute the mesh identity for all meshes)
* the downside is that any per-entity data that informs the values of these keys could require expensive re-hashes. computing each key for each sprite tanked bevymark performance (sprites don't actually need this level of specialization yet ... but things like pbr and future sprite scenarios might).
* this is the approach rafx used last time i checked
2. **"custom key specialization"**
* Pipelines by default are not specialized
* Pipelines that need specialization implement a SpecializedPipeline trait with a custom key associated type
* This allows specialization keys to encode exactly the amount of information required (instead of needing to be a combined hash of the entire pipeline). Generally this should fit in a small number of bytes. Per-entity specialization barely registers anymore on things like bevymark. It also makes things like "shader defs" way cheaper to hash because we can use context specific bitflags instead of strings.
* Despite the extra trait, it actually generally makes pipeline definitions + lookups simpler: managing multiple keys (and making the appropriate calls to manage these keys) was way more complicated.
* I opted for custom key specialization. It performs better generally and in my opinion is better UX. Fortunately the way this is implemented also allows for custom caches as this all builds on a common abstraction: the RenderPipelineCache. The built in custom key trait is just a simple / pre-defined way to interact with the cache
## Callouts
* The SpecializedPipeline trait makes it easy to inherit pipeline configuration in custom pipelines. The changes to `custom_shader_pipelined` and the new `shader_defs_pipelined` example illustrate how much simpler it is to define custom pipelines based on the PbrPipeline.
* The shader preprocessor is currently pretty naive (it just uses regexes to process each line). Ultimately we might want to build a more custom parser for more performance + better error handling, but for now I'm happy to optimize for "easy to implement and understand".
## Next Steps
* Port compute pipelines to the new system
* Add more preprocessor directives (else, elif, import)
* More flexible vertex attribute specialization / enable cheaply specializing on specific mesh vertex layouts
2021-10-28 19:07:47 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . shader_material ]
name = "Material"
description = "A shader and a material that uses it"
category = "Shaders"
wasm = true
2023-01-19 22:11:13 +00:00
[ [ example ] ]
name = "shader_prepass"
path = "examples/shader/shader_prepass.rs"
[ package . metadata . example . shader_prepass ]
name = "Material Prepass"
description = "A shader that uses the depth texture generated in a prepass"
category = "Shaders"
wasm = false
2022-02-28 22:55:14 +00:00
[ [ example ] ]
name = "shader_material_screenspace_texture"
path = "examples/shader/shader_material_screenspace_texture.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . shader_material_screenspace_texture ]
name = "Material - Screenspace Texture"
description = "A shader that samples a texture with view-independent UV coordinates"
category = "Shaders"
wasm = true
2022-01-05 19:43:11 +00:00
[ [ example ] ]
name = "shader_material_glsl"
path = "examples/shader/shader_material_glsl.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . shader_material_glsl ]
name = "Material - GLSL"
description = "A shader that uses the GLSL shading language"
category = "Shaders"
wasm = true
2022-01-05 19:43:11 +00:00
[ [ example ] ]
name = "shader_instancing"
path = "examples/shader/shader_instancing.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . shader_instancing ]
name = "Instancing"
description = "A shader that renders a mesh multiple times in one draw call"
category = "Shaders"
wasm = true
2022-01-05 19:43:11 +00:00
[ [ example ] ]
name = "animate_shader"
path = "examples/shader/animate_shader.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . animate_shader ]
name = "Animated"
description = "A shader that uses dynamic data like the time since startup"
category = "Shaders"
wasm = true
2022-01-05 19:43:11 +00:00
[ [ example ] ]
name = "compute_shader_game_of_life"
path = "examples/shader/compute_shader_game_of_life.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . compute_shader_game_of_life ]
name = "Compute - Game of Life"
description = "A compute shader that simulates Conway's Game of Life"
category = "Shaders"
wasm = false
2022-06-28 00:58:50 +00:00
[ [ example ] ]
name = "array_texture"
path = "examples/shader/array_texture.rs"
[ package . metadata . example . array_texture ]
name = "Array Texture"
description = "A shader that shows how to reuse the core bevy PBR shading functionality in a custom material that obtains the base color from an array texture."
category = "Shaders"
wasm = true
2023-01-26 13:18:15 +00:00
[ [ example ] ]
name = "texture_binding_array"
path = "examples/shader/texture_binding_array.rs"
[ package . metadata . example . texture_binding_array ]
name = "Texture Binding Array (Bindless Textures)"
description = "A shader that shows how to bind and sample multiple textures as a binding array (a.k.a. bindless textures)."
category = "Shaders"
wasm = false
2022-04-10 02:05:21 +00:00
# Stress tests
2022-06-25 20:23:24 +00:00
[ [ package . metadata . category ] ]
name = "Stress Tests"
description = "" "
These examples are used to test the performance and stability of various parts of the engine in an isolated way .
Due to the focus on performance it ' s recommended to run the stress tests in release mode :
` ` ` sh
cargo run --release --example < example name >
` ` `
"" "
2022-04-10 02:05:21 +00:00
2020-11-13 02:03:57 +00:00
[ [ example ] ]
name = "bevymark"
2022-04-10 02:05:21 +00:00
path = "examples/stress_tests/bevymark.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . bevymark ]
name = "Bevymark"
description = "A heavy sprite rendering workload to benchmark your system with Bevy"
category = "Stress Tests"
wasm = true
2022-07-04 13:04:15 +00:00
[ [ example ] ]
name = "many_animated_sprites"
path = "examples/stress_tests/many_animated_sprites.rs"
[ package . metadata . example . many_animated_sprites ]
name = "Many Animated Sprites"
2022-07-14 11:03:13 +00:00
description = "Displays many animated sprites in a grid arrangement with slight offsets to their animation timers. Used for performance testing."
2022-07-04 13:04:15 +00:00
category = "Stress Tests"
wasm = true
2022-07-21 14:39:03 +00:00
[ [ example ] ]
name = "many_buttons"
path = "examples/stress_tests/many_buttons.rs"
[ package . metadata . example . many_buttons ]
name = "Many Buttons"
description = "Test rendering of many UI elements"
category = "Stress Tests"
wasm = true
2022-04-10 02:05:21 +00:00
[ [ example ] ]
name = "many_cubes"
path = "examples/stress_tests/many_cubes.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . many_cubes ]
name = "Many Cubes"
description = "Simple benchmark to test per-entity draw overhead. Run with the `sphere` argument to test frustum culling"
category = "Stress Tests"
wasm = true
2022-05-08 02:57:00 +00:00
[ [ example ] ]
name = "many_foxes"
path = "examples/stress_tests/many_foxes.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . many_foxes ]
name = "Many Foxes"
description = "Loads an animated fox model and spawns lots of them. Good for testing skinned mesh performance. Takes an unsigned integer argument for the number of foxes to spawn. Defaults to 1000"
category = "Stress Tests"
wasm = true
2022-04-10 02:05:21 +00:00
[ [ example ] ]
name = "many_lights"
path = "examples/stress_tests/many_lights.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . many_lights ]
name = "Many Lights"
description = "Simple benchmark to test rendering many point lights. Run with `WGPU_SETTINGS_PRIO=webgl2` to restrict to uniform buffers and max 256 lights"
category = "Stress Tests"
wasm = true
2022-04-10 02:05:21 +00:00
[ [ example ] ]
name = "many_sprites"
path = "examples/stress_tests/many_sprites.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . many_sprites ]
name = "Many Sprites"
2022-07-14 11:03:13 +00:00
description = "Displays many sprites in a grid arrangement! Used for performance testing. Use `--colored` to enable color tinted sprites."
2022-06-25 20:23:24 +00:00
category = "Stress Tests"
wasm = true
2022-04-10 02:05:21 +00:00
[ [ example ] ]
name = "transform_hierarchy"
path = "examples/stress_tests/transform_hierarchy.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . transform_hierarchy ]
name = "Transform Hierarchy"
description = "Various test cases for hierarchy and transform propagation performance"
category = "Stress Tests"
wasm = true
2020-11-13 02:03:57 +00:00
2022-06-25 20:23:24 +00:00
# Tools
2022-03-19 19:14:13 +00:00
[ [ example ] ]
name = "scene_viewer"
2022-12-25 00:23:13 +00:00
path = "examples/tools/scene_viewer/main.rs"
2022-03-19 19:14:13 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . scene_viewer ]
name = "Scene Viewer"
description = "A simple way to view glTF models with Bevy. Just run `cargo run --release --example scene_viewer /path/to/model.gltf#Scene0`, replacing the path as appropriate. With no arguments it will load the FieldHelmet glTF model from the repository assets subdirectory"
category = "Tools"
wasm = true
2022-09-24 13:21:01 +00:00
[ [ example ] ]
name = "gamepad_viewer"
path = "examples/tools/gamepad_viewer.rs"
[ package . metadata . example . gamepad_viewer ]
name = "Gamepad Viewer"
description = "Shows a visualization of gamepad buttons, sticks, and triggers"
category = "Tools"
wasm = false
2023-01-31 01:47:00 +00:00
[ [ example ] ]
name = "nondeterministic_system_order"
path = "examples/ecs/nondeterministic_system_order.rs"
[ package . metadata . example . nondeterministic_system_order ]
name = "Nondeterministic System Order"
description = "Systems run in paralell, but their order isn't always deteriministic. Here's how to detect and fix this."
category = "ECS (Entity Component System)"
wasm = false
2022-03-15 05:49:49 +00:00
[ [ example ] ]
name = "3d_rotation"
path = "examples/transforms/3d_rotation.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . 3 d_rotation ]
name = "3D Rotation"
description = "Illustrates how to (constantly) rotate an object around an axis"
category = "Transforms"
wasm = true
2022-03-15 05:49:49 +00:00
[ [ example ] ]
name = "scale"
path = "examples/transforms/scale.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . scale ]
name = "Scale"
description = "Illustrates how to scale an object in each direction"
category = "Transforms"
wasm = true
2022-03-15 05:49:49 +00:00
[ [ example ] ]
name = "transform"
path = "examples/transforms/transform.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . transform ]
name = "Transform"
description = "Shows multiple transformations of objects"
category = "Transforms"
wasm = true
2022-03-15 05:49:49 +00:00
[ [ example ] ]
name = "translation"
path = "examples/transforms/translation.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . translation ]
name = "Translation"
description = "Illustrates how to move an object along an axis"
category = "Transforms"
wasm = true
2021-02-22 04:50:05 +00:00
# UI (User Interface)
2020-07-18 21:08:46 +00:00
[ [ example ] ]
name = "button"
path = "examples/ui/button.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . button ]
name = "Button"
description = "Illustrates creating and updating a button"
category = "UI (User Interface)"
wasm = true
2022-11-21 12:59:10 +00:00
[ [ example ] ]
name = "window_fallthrough"
path = "examples/ui/window_fallthrough.rs"
[ package . metadata . example . window_fallthrough ]
name = "Window Fallthrough"
description = "Illustrates how to access `winit::window::Window`'s `hittest` functionality."
category = "UI (User Interface)"
wasm = false
2021-02-22 04:50:05 +00:00
[ [ example ] ]
name = "font_atlas_debug"
path = "examples/ui/font_atlas_debug.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . font_atlas_debug ]
name = "Font Atlas Debug"
description = "Illustrates how FontAtlases are populated (used to optimize text rendering internally)"
category = "UI (User Interface)"
wasm = true
2023-01-16 17:17:45 +00:00
[ [ example ] ]
name = "relative_cursor_position"
path = "examples/ui/relative_cursor_position.rs"
[ package . metadata . example . relative_cursor_position ]
name = "Relative Cursor Position"
description = "Showcases the RelativeCursorPosition component"
category = "UI (User Interface)"
wasm = true
2020-05-13 20:09:32 +00:00
[ [ example ] ]
name = "text"
path = "examples/ui/text.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . text ]
name = "Text"
description = "Illustrates creating and updating text"
category = "UI (User Interface)"
wasm = true
2020-11-13 00:21:48 +00:00
[ [ example ] ]
name = "text_debug"
path = "examples/ui/text_debug.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . text_debug ]
name = "Text Debug"
description = "An example for debugging text layout"
category = "UI (User Interface)"
wasm = true
2023-01-27 19:07:48 +00:00
[ [ example ] ]
name = "text_layout"
path = "examples/ui/text_layout.rs"
[ package . metadata . example . text_layout ]
name = "Text Layout"
description = "Demonstrates how the AlignItems and JustifyContent properties can be composed to layout text"
category = "UI (User Interface)"
wasm = false
2020-05-01 20:12:47 +00:00
[ [ example ] ]
2022-06-06 17:52:09 +00:00
name = "transparency_ui"
path = "examples/ui/transparency_ui.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . transparency_ui ]
name = "Transparency UI"
description = "Demonstrates transparency for UI"
category = "UI (User Interface)"
wasm = true
Add z-index support with a predictable UI stack (#5877)
# Objective
Add consistent UI rendering and interaction where deep nodes inside two different hierarchies will never render on top of one-another by default and offer an escape hatch (z-index) for nodes to change their depth.
## The problem with current implementation
The current implementation of UI rendering is broken in that regard, mainly because [it sets the Z value of the `Transform` component based on a "global Z" space](https://github.com/bevyengine/bevy/blob/main/crates/bevy_ui/src/update.rs#L43) shared by all nodes in the UI. This doesn't account for the fact that each node's final `GlobalTransform` value will be relative to its parent. This effectively makes the depth unpredictable when two deep trees are rendered on top of one-another.
At the moment, it's also up to each part of the UI code to sort all of the UI nodes. The solution that's offered here does the full sorting of UI node entities once and offers the result through a resource so that all systems can use it.
## Solution
### New ZIndex component
This adds a new optional `ZIndex` enum component for nodes which offers two mechanism:
- `ZIndex::Local(i32)`: Overrides the depth of the node relative to its siblings.
- `ZIndex::Global(i32)`: Overrides the depth of the node relative to the UI root. This basically allows any node in the tree to "escape" the parent and be ordered relative to the entire UI.
Note that in the current implementation, omitting `ZIndex` on a node has the same result as adding `ZIndex::Local(0)`. Additionally, the "global" stacking context is essentially a way to add your node to the root stacking context, so using `ZIndex::Local(n)` on a root node (one without parent) will share that space with all nodes using `Index::Global(n)`.
### New UiStack resource
This adds a new `UiStack` resource which is calculated from both hierarchy and `ZIndex` during UI update and contains a vector of all node entities in the UI, ordered by depth (from farthest from camera to closest). This is exposed publicly by the bevy_ui crate with the hope that it can be used for consistent ordering and to reduce the amount of sorting that needs to be done by UI systems (i.e. instead of sorting everything by `global_transform.z` in every system, this array can be iterated over).
### New z_index example
This also adds a new z_index example that showcases the new `ZIndex` component. It's also a good general demo of the new UI stack system, because making this kind of UI was very broken with the old system (e.g. nodes would render on top of each other, not respecting hierarchy or insert order at all).
![image](https://user-images.githubusercontent.com/1060971/189015985-8ea8f989-0e9d-4601-a7e0-4a27a43a53f9.png)
---
## Changelog
- Added the `ZIndex` component to bevy_ui.
- Added the `UiStack` resource to bevy_ui, and added implementation in a new `stack.rs` module.
- Removed the previous Z updating system from bevy_ui, because it was replaced with the above.
- Changed bevy_ui rendering to use UiStack instead of z ordering.
- Changed bevy_ui focus/interaction system to use UiStack instead of z ordering.
- Added a new z_index example.
## ZIndex demo
Here's a demo I wrote to test these features
https://user-images.githubusercontent.com/1060971/188329295-d7beebd6-9aee-43ab-821e-d437df5dbe8a.mp4
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-11-02 22:06:04 +00:00
[ [ example ] ]
name = "z_index"
path = "examples/ui/z_index.rs"
[ package . metadata . example . z_index ]
name = "UI Z-Index"
description = "Demonstrates how to control the relative depth (z-position) of UI elements"
category = "UI (User Interface)"
wasm = true
2022-06-25 20:23:24 +00:00
2022-06-06 17:52:09 +00:00
[ [ example ] ]
2020-05-01 20:12:47 +00:00
name = "ui"
path = "examples/ui/ui.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . ui ]
name = "UI"
description = "Illustrates various features of Bevy UI"
category = "UI (User Interface)"
wasm = true
2022-08-29 23:35:53 +00:00
[ [ example ] ]
name = "ui_scaling"
2022-10-19 11:36:26 +00:00
path = "examples/ui/ui_scaling.rs"
2022-08-29 23:35:53 +00:00
[ package . metadata . example . ui_scaling ]
name = "UI Scaling"
description = "Illustrates how to scale the UI"
category = "UI (User Interface)"
wasm = true
2021-02-22 04:50:05 +00:00
# Window
2020-06-25 22:24:27 +00:00
[ [ example ] ]
name = "clear_color"
path = "examples/window/clear_color.rs"
2021-12-18 19:38:05 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . clear_color ]
name = "Clear Color"
description = "Creates a solid color window"
category = "Window"
wasm = true
Reduce power usage with configurable event loop (#3974)
# Objective
- Reduce power usage for games when not focused.
- Reduce power usage to ~0 when a desktop application is minimized (opt-in).
- Reduce power usage when focused, only updating on a `winit` event, or the user sends a redraw request. (opt-in)
https://user-images.githubusercontent.com/2632925/156904387-ec47d7de-7f06-4c6f-8aaf-1e952c1153a2.mp4
Note resource usage in the Task Manager in the above video.
## Solution
- Added a type `UpdateMode` that allows users to specify how the winit event loop is updated, without exposing winit types.
- Added two fields to `WinitConfig`, both with the `UpdateMode` type. One configures how the application updates when focused, and the other configures how the application behaves when it is not focused. Users can modify this resource manually to set the type of event loop control flow they want.
- For convenience, two functions were added to `WinitConfig`, that provide reasonable presets: `game()` (default) and `desktop_app()`.
- The `game()` preset, which is used by default, is unchanged from current behavior with one exception: when the app is out of focus the app updates at a minimum of 10fps, or every time a winit event is received. This has a huge positive impact on power use and responsiveness on my machine, which will otherwise continue running the app at many hundreds of fps when out of focus or minimized.
- The `desktop_app()` preset is fully reactive, only updating when user input (winit event) is supplied or a `RedrawRequest` event is sent. When the app is out of focus, it only updates on `Window` events - i.e. any winit event that directly interacts with the window. What this means in practice is that the app uses *zero* resources when minimized or not interacted with, but still updates fluidly when the app is out of focus and the user mouses over the application.
- Added a `RedrawRequest` event so users can force an update even if there are no events. This is useful in an application when you want to, say, run an animation even when the user isn't providing input.
- Added an example `low_power` to demonstrate these changes
## Usage
Configuring the event loop:
```rs
use bevy::winit::{WinitConfig};
// ...
.insert_resource(WinitConfig::desktop_app()) // preset
// or
.insert_resource(WinitConfig::game()) // preset
// or
.insert_resource(WinitConfig{ .. }) // manual
```
Requesting a redraw:
```rs
use bevy::window::RequestRedraw;
// ...
fn request_redraw(mut event: EventWriter<RequestRedraw>) {
event.send(RequestRedraw);
}
```
## Other details
- Because we have a single event loop for multiple windows, every time I've mentioned "focused" above, I more precisely mean, "if at least one bevy window is focused".
- Due to a platform bug in winit (https://github.com/rust-windowing/winit/issues/1619), we can't simply use `Window::request_redraw()`. As a workaround, this PR will temporarily set the window mode to `Poll` when a redraw is requested. This is then reset to the user's `WinitConfig` setting on the next frame.
2022-03-07 23:32:05 +00:00
[ [ example ] ]
name = "low_power"
path = "examples/window/low_power.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . low_power ]
name = "Low Power"
description = "Demonstrates settings to reduce power use for bevy applications"
category = "Window"
wasm = true
2021-12-18 19:38:05 +00:00
[ [ example ] ]
name = "multiple_windows"
path = "examples/window/multiple_windows.rs"
2020-06-25 22:24:27 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . multiple_windows ]
name = "Multiple Windows"
description = "Demonstrates creating multiple windows, and rendering to them"
category = "Window"
wasm = false
2020-12-28 20:26:50 +00:00
[ [ example ] ]
name = "scale_factor_override"
path = "examples/window/scale_factor_override.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . scale_factor_override ]
2022-07-05 16:59:31 +00:00
name = "Scale Factor Override"
2022-06-25 20:23:24 +00:00
description = "Illustrates how to customize the default window settings"
category = "Window"
wasm = true
2021-12-08 20:53:35 +00:00
[ [ example ] ]
name = "transparent_window"
path = "examples/window/transparent_window.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . transparent_window ]
name = "Transparent Window"
description = "Illustrates making the window transparent and hiding the window decoration"
category = "Window"
wasm = false
2020-07-20 09:05:56 +00:00
[ [ example ] ]
name = "window_settings"
2020-08-21 05:37:19 +00:00
path = "examples/window/window_settings.rs"
2020-09-16 01:05:31 +00:00
2022-06-25 20:23:24 +00:00
[ package . metadata . example . window_settings ]
name = "Window Settings"
description = "Demonstrates customizing default window settings"
category = "Window"
wasm = true
Add an example to test small window sizes (#3597)
# Objective
We keep getting issues where things break at small window sizes, e.g #3368 (caused by #3153), #3596 ('caused' by #3545)
## Solution
- Add a test that we can make small windows.
Currently, this fails on my machine with some quite scary vulkan errors:
```
2022-01-08T22:55:13.770261Z ERROR wgpu_hal::vulkan::instance: VALIDATION [VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 (0x7cd0911d)]
Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x1adbd410a60, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent = (225,60), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (225,56), minImageExtent = (225,56), maxImageExtent = (225,56). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/1.2.198.1/windows/1.2-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)
2022-01-08T22:55:13.770808Z ERROR wgpu_hal::vulkan::instance: objects: (type: DEVICE, hndl: 0x1adbd410a60, name: ?)
2022-01-08T22:55:13.787403Z ERROR wgpu_hal::vulkan::instance: VALIDATION [VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 (0x7cd0911d)]
Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x1adbd410a60, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent = (225,56), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (225,52), minImageExtent = (225,52), maxImageExtent = (225,52). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/1.2.198.1/windows/1.2-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)
```
etc.
This might be a new issue here, although I'm surprised it's vulkan giving this error; wgpu should stop it if this is illegal.
2022-04-26 22:15:24 +00:00
[ [ example ] ]
name = "resizing"
path = "tests/window/resizing.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . resizing ]
hidden = true
Add an example to test small window sizes (#3597)
# Objective
We keep getting issues where things break at small window sizes, e.g #3368 (caused by #3153), #3596 ('caused' by #3545)
## Solution
- Add a test that we can make small windows.
Currently, this fails on my machine with some quite scary vulkan errors:
```
2022-01-08T22:55:13.770261Z ERROR wgpu_hal::vulkan::instance: VALIDATION [VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 (0x7cd0911d)]
Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x1adbd410a60, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent = (225,60), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (225,56), minImageExtent = (225,56), maxImageExtent = (225,56). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/1.2.198.1/windows/1.2-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)
2022-01-08T22:55:13.770808Z ERROR wgpu_hal::vulkan::instance: objects: (type: DEVICE, hndl: 0x1adbd410a60, name: ?)
2022-01-08T22:55:13.787403Z ERROR wgpu_hal::vulkan::instance: VALIDATION [VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 (0x7cd0911d)]
Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x1adbd410a60, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent = (225,56), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (225,52), minImageExtent = (225,52), maxImageExtent = (225,52). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/1.2.198.1/windows/1.2-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)
```
etc.
This might be a new issue here, although I'm surprised it's vulkan giving this error; wgpu should stop it if this is illegal.
2022-04-26 22:15:24 +00:00
[ [ example ] ]
name = "minimising"
path = "tests/window/minimising.rs"
2022-06-25 20:23:24 +00:00
[ package . metadata . example . minimising ]
hidden = true
Add an example to test small window sizes (#3597)
# Objective
We keep getting issues where things break at small window sizes, e.g #3368 (caused by #3153), #3596 ('caused' by #3545)
## Solution
- Add a test that we can make small windows.
Currently, this fails on my machine with some quite scary vulkan errors:
```
2022-01-08T22:55:13.770261Z ERROR wgpu_hal::vulkan::instance: VALIDATION [VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 (0x7cd0911d)]
Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x1adbd410a60, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent = (225,60), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (225,56), minImageExtent = (225,56), maxImageExtent = (225,56). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/1.2.198.1/windows/1.2-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)
2022-01-08T22:55:13.770808Z ERROR wgpu_hal::vulkan::instance: objects: (type: DEVICE, hndl: 0x1adbd410a60, name: ?)
2022-01-08T22:55:13.787403Z ERROR wgpu_hal::vulkan::instance: VALIDATION [VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 (0x7cd0911d)]
Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x1adbd410a60, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent = (225,56), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (225,52), minImageExtent = (225,52), maxImageExtent = (225,52). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/1.2.198.1/windows/1.2-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)
```
etc.
This might be a new issue here, although I'm surprised it's vulkan giving this error; wgpu should stop it if this is illegal.
2022-04-26 22:15:24 +00:00
2022-08-29 23:56:43 +00:00
[ [ example ] ]
name = "window_resizing"
path = "examples/window/window_resizing.rs"
[ package . metadata . example . window_resizing ]
name = "Window Resizing"
description = "Demonstrates resizing and responding to resizing a window"
category = "Window"
wasm = true
2022-07-25 15:48:13 +00:00
[ profile . wasm-release ]
inherits = "release"
opt-level = "z"
lto = "fat"
codegen-units = 1
2022-12-20 15:59:41 +00:00
[ profile . stress-test ]
inherits = "release"
lto = "fat"
panic = "abort"