# Objective
As was pointed out in #13183, `bevy_mikktspace` is missing it's msrv
from it `Cargo.toml`. This promted me to check the msrv of every
`bevy_*` crate. Closes#13183.
## Solution
- Call `cargo check` with different rust versions on every bevy crate
until it doesn't complain.
- Write down the rust version `cargo check` started working.
## Testing
- Install `cargo-msrv`.
- Run `cargo msrv verify`.
- Rejoice.
---
## Changelog
Every published bevy crate now specifies a MSRV. If your rust toolchain
isn't at least version `1.77.0` You'll likely not be able to compile
most of bevy.
## Migration Guide
If your rust toolchain is bellow version`1.77.0, update.
This commit implements the [depth of field] effect, simulating the blur
of objects out of focus of the virtual lens. Either the [hexagonal
bokeh] effect or a faster Gaussian blur may be used. In both cases, the
implementation is a simple separable two-pass convolution. This is not
the most physically-accurate real-time bokeh technique that exists;
Unreal Engine has [a more accurate implementation] of "cinematic depth
of field" from 2018. However, it's simple, and most engines provide
something similar as a fast option, often called "mobile" depth of
field.
The general approach is outlined in [a blog post from 2017]. We take
advantage of the fact that both Gaussian blurs and hexagonal bokeh blurs
are *separable*. This means that their 2D kernels can be reduced to a
small number of 1D kernels applied one after another, asymptotically
reducing the amount of work that has to be done. Gaussian blurs can be
accomplished by blurring horizontally and then vertically, while
hexagonal bokeh blurs can be done with a vertical blur plus a diagonal
blur, plus two diagonal blurs. In both cases, only two passes are
needed. Bokeh requires the first pass to have a second render target and
requires two subpasses in the second pass, which decreases its
performance relative to the Gaussian blur.
The bokeh blur is generally more aesthetically pleasing than the
Gaussian blur, as it simulates the effect of a camera more accurately.
The shape of the bokeh circles are determined by the number of blades of
the aperture. In our case, we use a hexagon, which is usually considered
specific to lower-quality cameras. (This is a downside of the fast
hexagon approach compared to the higher-quality approaches.) The blur
amount is generally specified by the [f-number], which we use to compute
the focal length from the film size and FOV. By default, we simulate
standard cinematic cameras of f/1 and [Super 35]. The developer can
customize these values as desired.
A new example has been added to demonstrate depth of field. It allows
customization of the mode (Gaussian vs. bokeh), focal distance and
f-numbers. The test scene is inspired by a [blog post on depth of field
in Unity]; however, the effect is implemented in a completely different
way from that blog post, and all the assets (textures, etc.) are
original.
Bokeh depth of field:
![Screenshot 2024-04-17
152535](https://github.com/bevyengine/bevy/assets/157897/702f0008-1c8a-4cf3-b077-4110f8c46584)
Gaussian depth of field:
![Screenshot 2024-04-17
152542](https://github.com/bevyengine/bevy/assets/157897/f4ece47a-520e-4483-a92d-f4fa760795d3)
No depth of field:
![Screenshot 2024-04-17
152547](https://github.com/bevyengine/bevy/assets/157897/9444e6aa-fcae-446c-b66b-89469f1a1325)
[depth of field]: https://en.wikipedia.org/wiki/Depth_of_field
[hexagonal bokeh]:
https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited/
[a more accurate implementation]:
https://epicgames.ent.box.com/s/s86j70iamxvsuu6j35pilypficznec04
[a blog post from 2017]:
https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited/
[f-number]: https://en.wikipedia.org/wiki/F-number
[Super 35]: https://en.wikipedia.org/wiki/Super_35
[blog post on depth of field in Unity]:
https://catlikecoding.com/unity/tutorials/advanced-rendering/depth-of-field/
## Changelog
### Added
* A depth of field postprocessing effect is now available, to simulate
objects being out of focus of the camera. To use it, add
`DepthOfFieldSettings` to an entity containing a `Camera3d` component.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Bram Buurlage <brambuurlage@gmail.com>
# Objective
The `Cone` primitive should support meshing.
## Solution
Implement meshing for the `Cone` primitive. The default cone has a
height of 1 and a base radius of 0.5, and is centered at the origin.
An issue with cone meshes is that the tip does not really have a normal
that works, even with duplicated vertices. This PR uses only a single
vertex for the tip, with a normal of zero; this results in an "invalid"
normal that gets ignored by the fragment shader. This seems to be the
only approach we have for perfectly smooth cones. For discussion on the
topic, see #10298 and #5891.
Another thing to note is that the cone uses polar coordinates for the
UVs:
<img
src="https://github.com/bevyengine/bevy/assets/57632562/e101ded9-110a-4ac4-a98d-f1e4d740a24a"
alt="cone" width="400" />
This way, textures are applied as if looking at the cone from above:
<img
src="https://github.com/bevyengine/bevy/assets/57632562/8dea00f1-a283-4bc4-9676-91e8d4adb07a"
alt="texture" width="200" />
<img
src="https://github.com/bevyengine/bevy/assets/57632562/d9d1b5e6-a8ba-4690-b599-904dd85777a1"
alt="cone" width="200" />
# Objective
adopted from #10716
adds example for updating state
---------
Co-authored-by: Stepan Koltsov <stepan.koltsov@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit fixes two issues in auto_exposure.wgsl:
* A `storageBarrier()` was incorrectly used where a `workgroupBarrier()`
should be used instead;
* Resetting the `histogram_shared` array would write beyond the 64th
index, which is out of bounds.
## Solution
The first issue is fixed by using the appropriate workgroupBarrier
instead;
The second issue is fixed by adding a range check before setting
`histogram_shared[local_invocation_index] = 0u`.
## Testing
These changes were tested using the Xcode metal profiler, and I could
not find any noticable change in compute shader performance.
# Objective
- When building for release, there are "unused" warnings:
```
warning: unused import: `bevy_utils::warn_once`
--> crates/bevy_pbr/src/render/mesh_view_bindings.rs:32:5
|
32 | use bevy_utils::warn_once;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused variable: `texture_count`
--> crates/bevy_pbr/src/render/mesh_view_bindings.rs:371:17
|
371 | let texture_count: usize = entries
| ^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_texture_count`
|
= note: `#[warn(unused_variables)]` on by default
```
## Solution
- Gate the import and definition by the same cfg as their uses
# Objective
Add an explanation of the differences between `alignment` and `Anchor`
to the `Text2dBundle` docs.
---------
Co-authored-by: Rob Parrett <robparrett@gmail.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/12597
The current tracing customization option (the `update_subscriber` field)
was basically unusable because it provides a `dyn Subscriber` and most
layers require a `Subscriber` that also implements `for<'a>
LookupSpan<'a, Data=Data<'a>>`, so it was impossible to add a layer on
top of the `dyn Subscriber`.
This PR provides an alternative way of adding additional tracing layers
to the LogPlugin by instead creating an `Option<Layer>`.
This is enough for most situations because `Option<Layer>` and
`Vec<Layer>` both implement `Layer`.
## Solution
- Replace the `update_subscriber` field of `LogPlugin` with a
`custom_layer` field which is function pointer returning an
`Option<BoxedLayer>`
- Update the examples to showcase that this works:
- with multiple additional layers
- with Layers that were previously problematic, such as
`bevy::log::tracing_subscriber::fmt::layer().with_file(true)` (mentioned
in the issue)
Note that in the example this results in duplicate logs, since we have
our own layer on top of the default `fmt_layer` added in the LogPlugin;
maybe in the future we might want to provide a single one? Or to let the
user customize the default `fmt_layer` ? I still think this change is an
improvement upon the previous solution, which was basically broken.
---
## Changelog
> This section is optional. If this was a trivial fix, or has no
externally-visible impact, you can delete this section.
- The `LogPlugin`'s `update_subscriber` field has been replaced with
`custom_layer` to allow the user to flexibly add a `tracing::Layer` to
the layer stack
## Migration Guide
- The `LogPlugin`'s `update_subscriber` field has been replaced with
`custom_layer`
---------
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
# Objective
Fixes#13097 and other issues preventing the motion blur example from
working on wasm
## Solution
- Use a vec2 for padding
- Fix error initializing the `MotionBlur` struct on wasm+webgl2
- Disable MSAA on wasm+webgl2
- Fix `GlobalsUniform` padding getting added on the shader side for
webgpu builds
## Notes
The motion blur example now runs, but with artifacts. In addition to the
obvious black artifacts, the motion blur or dithering seem to just look
worse in a way I can't really describe. That may be expected.
```
AdapterInfo { name: "ANGLE (Apple, ANGLE Metal Renderer: Apple M1 Max, Unspecified Version)", vendor: 4203, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Gl }
```
<img width="1276" alt="Screenshot 2024-04-25 at 6 51 21 AM"
src="https://github.com/bevyengine/bevy/assets/200550/65401d4f-92fe-454b-9dbc-a2d89d3ad963">
# Objective
- **Describe the objective or issue this PR addresses.**
`bevy_asset` includes code
[here](4350ad0bd1/crates/bevy_asset/src/io/wasm.rs (L61))
that references `web_sys::WorkerGlobalScope`. However, `bevy_asset` does
not enable this feature, see
[here](4350ad0bd1/crates/bevy_asset/Cargo.toml (L50)).
Running examples does not catch this problem because the feature is
implicitly included by `wgpu` when `bevy_render` is also a dependency,
see
[bevy_render](4350ad0bd1/crates/bevy_render/Cargo.toml (L73-L80))
and
[wgpu](3b6112d45d/wgpu/Cargo.toml (L201)).
This results in compile errors for environments that are not using
`bevy_render`.
To reproduce the problem, try to build the crate individually for wasm
targets by running `cargo build -p bevy_asset --target
wasm32-unknown-unknown`.
Running `cargo tree -e features --target wasm32-unknown-unknown` helped
diagnose the issue.
## Solution
- **Describe the solution used to achieve the objective above.**
This PR adds the `WorkerGlobalScope` feature to the `web-sys` portion of
`bevy_asset`'s `Cargo.toml`.
It also seems to be the case that `bevy_asset` no longer needs the
`Request` feature, since no code for `Request` is present anymore. I
confirmed that building the crate individually for wasm succeeds without
the feature, so that change is also included here.
This is a little off-topic, but the repository would probably benefit
from some automation around these types of changes, but I'm not sure
what would work there. For example, building each crate individually for
some key targets would work, but is...well, a lot. Happy to follow up if
there is agreement on a good direction.
## Testing
- **Did you test these changes? If so, how?**
- **How can other people (reviewers) test your changes? Is there
anything specific they need to know?**
Building the crate individually for wasm by running `cargo build -p
bevy_asset --target wasm32-unknown-unknown`.
- **Are there any parts that need more testing?**
I don't believe so.
# Objective
Fixes two issues related to #13208.
First, we ensure render resources for a window are always dropped first
to ensure that the `winit::Window` always drops on the main thread when
it is removed from `WinitWindows`. Previously, changes in #12978 caused
the window to drop in the render world, causing issues.
We accomplish this by delaying despawning the window by a frame by
inserting a marker component `ClosingWindow` that indicates the window
has been requested to close and is in the process of closing. The render
world now responds to the equivalent `WindowClosing` event rather than
`WindowCloseed` which now fires after the render resources are
guarunteed to be cleaned up.
Secondly, fixing the above caused (revealed?) that additional events
were being delivered to the the event loop handler after exit had
already been requested: in my testing `RedrawRequested` and
`LoopExiting`. This caused errors to be reported try to send an exit
event on the close channel. There are two options here:
- Guard the handler so no additional events are delivered once the app
is exiting. I ~considered this but worried it might be confusing or bug
prone if in the future someone wants to handle `LoopExiting` or some
other event to clean-up while exiting.~ We are now taking this approach.
- Only send an exit signal if we are not already exiting. ~It doesn't
appear to cause any problems to handle the extra events so this seems
safer.~
Fixing this also appears to have fixed#13231.
Fixes#10260.
## Testing
Tested on mac only.
---
## Changelog
### Added
- A `WindowClosing` event has been added that indicates the window will
be despawned on the next frame.
### Changed
- Windows now close a frame after their exit has been requested.
## Migration Guide
- Ensure custom exit logic does not rely on the app exiting the same
frame as a window is closed.
# Objective
Fixes #13230
## Solution
Uses solution described in #13230
They mention a worry about adding a branch, but I'm not sure there is
one.
This code
```Rust
#[no_mangle]
pub fn next_if_some(num: i32, b: Option<bool>) -> i32 {
num + b.is_some() as i32
}
```
produces this assembly with opt-level 3
```asm
next_if_some:
xor eax, eax
cmp sil, 2
setne al
add eax, edi
ret
```
## Testing
Added test from #13230, tagged it as ignore as it is only useful in
release mode and very slow if you accidentally invoke it in debug mode.
---
## Changelog
Iterationg of ListIter will no longer overflow and wrap around
## Migration Guide
# Objective
I am emboldened by my last small PR and am here with another.
- **Describe the objective or issue this PR addresses.**
It would be nice if `FrameCount` could be used by downstream plugins
that want to use frame data. The example that I have in mind is
[`leafwing_input_playback`](https://github.com/Leafwing-Studios/leafwing_input_playback/issues/29)
which has a [duplicate implementation of
`FrameCount`](https://github.com/Leafwing-Studios/leafwing_input_playback/blob/main/src/frame_counting.rs#L9-L37)
used in several structs which rely on those derives (or otherwise the
higher-level structs would have to implement these traits manually).
That crate, using `FrameCount`, tracks input frames and timestamps and
enables various playback modes.
I am aware that bevy org refrains from deriving lots of unnecessary
stuff on bevy types to avoid compile time creep. It is worth mentioning
the (equally reasonable) alternative that downstream crates _should_
implement some `FrameCount` themselves if they want special behavior
from it.
## Solution
- **Describe the solution used to achieve the objective above.**
I added derives for `PartialEq, Eq, PartialOrd, Ord` and implementations
for `serde::{Deserialize, Serialize}` to `FrameCount`.
## Testing
Manually confirmed that the serde implementation works, but that's all.
Let me know if I should do more here.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Sometimes it's nice to iterate over all the coordinate axes using
something like `Vec3::AXES`. This was not available for the
corresponding `Dir` types and now it is.
## Solution
We already have things like `Dir2::X`, `Dir3::Z` and so on, so I just
threw them in an array like the vector types do it. I also slightly
refactored the sphere gizmo code to use `Dir3::AXES` and operate on
directions instead of using `Dir3::new_unchecked`.
## Testing
I looked at the sphere in the `3d_gizmos` example and it seems to work,
so I assume I didn't break anything.
# Objective
Unblocks #11659.
Currently the `Reflect` derive macro has to go through a merge process
for each `#[reflect]`/`#[reflet_value]` attribute encountered on a
container type.
Not only is this a bit inefficient, but it also has a soft requirement
that we can compare attributes such that an error can be thrown on
duplicates, invalid states, etc.
While working on #11659 this proved to be challenging due to the fact
that `syn` types don't implement `PartialEq` or `Hash` without enabling
the `extra-traits` feature.
Ideally, we wouldn't have to enable another feature just to accommodate
this one use case.
## Solution
Removed `ContainerAttributes::merge`.
This was a fairly simple change as we could just have the parsing
functions take `&mut self` instead of returning `Self`.
## Testing
CI should build as there should be no user-facing change.
# Objective
Extracts the state mechanisms into a new crate called "bevy_state".
This comes with a few goals:
- state wasn't really an inherent machinery of the ecs system, and so
keeping it within bevy_ecs felt forced
- by mixing it in with bevy_ecs, the maintainability of our more robust
state system was significantly compromised
moving state into a new crate makes it easier to encapsulate as it's own
feature, and easier to read and understand since it's no longer a
single, massive file.
## Solution
move the state-related elements from bevy_ecs to a new crate
## Testing
- Did you test these changes? If so, how? all the automated tests
migrated and passed, ran the pre-existing examples without changes to
validate.
---
## Migration Guide
Since bevy_state is now gated behind the `bevy_state` feature, projects
that use state but don't use the `default-features` will need to add
that feature flag.
Since it is no longer part of bevy_ecs, projects that use bevy_ecs
directly will need to manually pull in `bevy_state`, trigger the
StateTransition schedule, and handle any of the elements that bevy_app
currently sets up.
---------
Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
# Objective
fixes#13224
adds conversions for Vec3 and Vec4 since these appear so often
## Solution
added Covert trait (couldn't think of good name) for [f32; 4], [f32, 3],
Vec4, and Vec3 along with the symmetric implementation
## Changelog
added conversions between arrays and vector to colors and vice versa
#migration
LinearRgba appears to have already had implicit conversions for [f32;4]
and Vec4
# Objective
Finish the `try_apply` implementation started in #6770 by @feyokorenhof.
Supersedes and closes#6770. Closes#6182
## Solution
Add `try_apply` to `Reflect` and implement it in all the places that
implement `Reflect`.
---
## Changelog
Added `try_apply` to `Reflect`.
---------
Co-authored-by: Feyo Korenhof <feyokorenhof@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
Currently, the 2d pipeline only has a transparent pass that is used for
everything. I want to have separate passes for opaque/alpha
mask/transparent meshes just like in 3d.
This PR does the basic work to start adding new phases to the 2d
pipeline and get the current setup a bit closer to 3d.
## Solution
- Use `ViewNode` for `MainTransparentPass2dNode`
- Added `Node2d::StartMainPass`, `Node2d::EndMainPass`
- Rename everything to clarify that the main pass is currently the
transparent pass
---
## Changelog
- Added `Node2d::StartMainPass`, `Node2d::EndMainPass`
## Migration Guide
If you were using `Node2d::MainPass` to order your own custom render
node. You now need to order it relative to `Node2d::StartMainPass` or
`Node2d::EndMainPass`.
WebGL 2 doesn't support variable-length uniform buffer arrays. So we
arbitrarily set the length of the visibility ranges field to 64 on that
platform.
---------
Co-authored-by: IceSentry <c.giguere42@gmail.com>
# Objective
There's a TODO comment above the `AssetMetaCheck` enum mentioning this
should have been done in 0.13
## Solution
Do it in 0.14
## Testing
I've checked that all the asset tests compile. I've also run the
asset_processing and asset_settings tests and they both work.
---
## Changelog
### Changed
-
[`AssetMetaCheck`](https://docs.rs/bevy/latest/bevy/asset/enum.AssetMetaCheck.html)
is no longer a resource and is now a field on the
[`AssetPlugin`](https://docs.rs/bevy/latest/bevy/asset/struct.AssetPlugin.html).
## Migration Guide
Changes to how bevy handles asset meta files now need to be specified
when inserting the `AssetPlugin`.
# Objective
- Adds a basic `Extrusion<T: Primitive2d>` shape, suggestion of #10572
## Solution
- Adds `Measured2d` and `Measured3d` traits for getting the
perimeter/area or area/volume of shapes. This allows implementing
`.volume()` and `.area()` for all extrusions `Extrusion<T: Primitive2d +
Measured2d>` within `bevy_math`
- All existing perimeter, area and volume implementations for primitves
have been moved into implementations of `Measured2d` and `Measured3d`
- Shapes should be extruded along the Z-axis since an extrusion of depth
`0.` should be equivalent in everything but name to the base shape
## Caviats
- I am not sure about the naming. `Extrusion<T>` could also be
`Prism<T>` and the `MeasuredNd` could also be something like
`MeasuredPrimitiveNd`. If you have any other suggestions, please fell
free to share them :)
## Future work
This PR adds a basic `Extrusion` shape and does not implement a lot of
things you might want it to. Some of the future possibilities include:
- [ ] bounding for extrusions
- [ ] making extrusions work with gizmos
- [ ] meshing
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Some of the "large" crates have sub-crates, usually for things such as
macros.
- For an example, see [`bevy_ecs_macros` at
`bevy_ecs/macros`](4f9f987099/crates/bevy_ecs/macros).
- The one crate that does not follow this convention is
[`bevy_reflect_derive`](4f9f987099/crates/bevy_reflect/bevy_reflect_derive),
which is in the `bevy_reflect/bevy_reflect_derive` folder and not
`bevy_reflect/derive` or `bevy_reflect/macros`.
## Solution
- Rename folder `bevy_reflect_derive` to `derive`.
- I chose to use `derive` instead of `macros` because the crate name
itself ends in `_derive`. (One of only two crates to actually use this
convention, funnily enough.)
## Testing
- Build and test `bevy_reflect` and `bevy_reflect_derive`.
- Apply the following patch to `publish.sh` to run it in `--dry-run`
mode, to test that the path has been successfully updated:
- If you have any security concerns about applying random diffs, feel
free to skip this step. Worst case scenario it fails and Cart has to
manually publish a few crates.
```bash
# Apply patch to make `publish.sh` *not* actually publish anything.
git apply path/to/foo.patch
# Make `publish.sh` executable.
chmod +x tools/publish.sh
# Execute `publish.sh`.
./tools/publish.sh
```
```patch
diff --git a/tools/publish.sh b/tools/publish.sh
index b020bad28..fbcc09281 100644
--- a/tools/publish.sh
+++ b/tools/publish.sh
@@ -49,7 +49,7 @@ crates=(
if [ -n "$(git status --porcelain)" ]; then
echo "You have local changes!"
- exit 1
+ # exit 1
fi
pushd crates
@@ -61,15 +61,15 @@ do
cp ../LICENSE-APACHE "$crate"
pushd "$crate"
git add LICENSE-MIT LICENSE-APACHE
- cargo publish --no-verify --allow-dirty
+ cargo publish --no-verify --allow-dirty --dry-run
popd
- sleep 20
+ # sleep 20
done
popd
echo "Publishing root crate"
-cargo publish --allow-dirty
+cargo publish --allow-dirty --dry-run
echo "Cleaning local state"
git reset HEAD --hard
```
---
## Changelog
- Moved `bevy_reflect_derive` from
`crates/bevy_reflect/bevy_reflect_derive` to
`crates/bevy_reflect/derive`.
Copied almost verbatim from the volumetric fog PR
# Objective
- Managing mesh view layouts is complicated
## Solution
- Extract it to it's own struct
- This was done as part of #13057 and is copied almost verbatim. I
wanted to keep this part of the PR it's own atomic commit in case we
ever have to revert fog or run a bisect. This change is good whether or
not we have volumetric fog.
Co-Authored-By: @pcwalton
# Objective
I'm adopting #9122 and pulling some of the non controversial changes out
to make the final pr easier to review.
This pr removes the NonSend resource usage from `bevy_log`.
## Solution
`tracing-chrome` uses a guard that is stored in the world, so that when
it is dropped the json log file is written out. The guard is Send +
!Sync, so we can store it in a SyncCell to hold it in a regular resource
instead of using a non send resource.
## Testing
Tested by running an example with `-F tracing chrome` and making sure
there weren't any errors and the json file was created.
---
## Changelog
- replaced `bevy_log`'s usage of a non send resource.
Switched the return type from `Vec3` to `Dir3` for directional axis
methods within the `GlobalTransform` component.
## Migration Guide
The `GlobalTransform` component's directional axis methods (e.g.,
`right()`, `left()`, `up()`, `down()`, `back()`, `forward()`) have been
updated from returning `Vec3` to `Dir3`.
# Objective
Fixes#12966
## Solution
Renaming multi_threaded feature to match snake case
## Migration Guide
Bevy feature multi-threaded should be refered to multi_threaded from now
on.
Clearcoat is a separate material layer that represents a thin
translucent layer of a material. Examples include (from the [Filament
spec]) car paint, soda cans, and lacquered wood. This commit implements
support for clearcoat following the Filament and Khronos specifications,
marking the beginnings of support for multiple PBR layers in Bevy.
The [`KHR_materials_clearcoat`] specification describes the clearcoat
support in glTF. In Blender, applying a clearcoat to the Principled BSDF
node causes the clearcoat settings to be exported via this extension. As
of this commit, Bevy parses and reads the extension data when present in
glTF. Note that the `gltf` crate has no support for
`KHR_materials_clearcoat`; this patch therefore implements the JSON
semantics manually.
Clearcoat is integrated with `StandardMaterial`, but the code is behind
a series of `#ifdef`s that only activate when clearcoat is present.
Additionally, the `pbr_feature_layer_material_textures` Cargo feature
must be active in order to enable support for clearcoat factor maps,
clearcoat roughness maps, and clearcoat normal maps. This approach
mirrors the same pattern used by the existing transmission feature and
exists to avoid running out of texture bindings on platforms like WebGL
and WebGPU. Note that constant clearcoat factors and roughness values
*are* supported in the browser; only the relatively-less-common maps are
disabled on those platforms.
This patch refactors the lighting code in `StandardMaterial`
significantly in order to better support multiple layers in a natural
way. That code was due for a refactor in any case, so this is a nice
improvement.
A new demo, `clearcoat`, has been added. It's based on [the
corresponding three.js demo], but all the assets (aside from the skybox
and environment map) are my original work.
[Filament spec]:
https://google.github.io/filament/Filament.html#materialsystem/clearcoatmodel
[`KHR_materials_clearcoat`]:
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md
[the corresponding three.js demo]:
https://threejs.org/examples/webgl_materials_physical_clearcoat.html
![Screenshot 2024-04-19
101143](https://github.com/bevyengine/bevy/assets/157897/3444bcb5-5c20-490c-b0ad-53759bd47ae2)
![Screenshot 2024-04-19
102054](https://github.com/bevyengine/bevy/assets/157897/6e953944-75b8-49ef-bc71-97b0a53b3a27)
## Changelog
### Added
* `StandardMaterial` now supports a clearcoat layer, which represents a
thin translucent layer over an underlying material.
* The glTF loader now supports the `KHR_materials_clearcoat` extension,
representing materials with clearcoat layers.
## Migration Guide
* The lighting functions in the `pbr_lighting` WGSL module now have
clearcoat parameters, if `STANDARD_MATERIAL_CLEARCOAT` is defined.
* The `R` reflection vector parameter has been removed from some
lighting functions, as it was unused.
# Objective
- `DynamicUniformBuffer` tries to create a buffer as soon as the changed
flag is set to true. This doesn't work correctly when the buffer wasn't
already created. This currently creates a crash because it's trying to
create a buffer of size 0 if the flag is set but there's no buffer yet.
## Solution
- Don't create a changed buffer until there's data that needs to be
written to a buffer.
## Testing
- run `cargo run --example scene_viewer` and see that it doesn't crash
anymore
Fixes#13235
# Objective
Documentation should mention the two plugins required for your custom
`CameraProjection` to work.
## Solution
Documented!
---
I tried linking to `bevy_pbr::PbrProjectionPlugin` from
`bevy_render:📷:CameraProjection` but it wasn't in scope. Is there
a trick to it?
# Objective
- Per-cluster (instance of a meshlet) data upload is ridiculously
expensive in both CPU and GPU time (8 bytes per cluster, millions of
clusters, you very quickly run into PCIE bandwidth maximums, and lots of
CPU-side copies and malloc).
- We need to be uploading only per-instance/entity data. Anything else
needs to be done on the GPU.
## Solution
- Per instance, upload:
- `meshlet_instance_meshlet_counts_prefix_sum` - An exclusive prefix sum
over the count of how many clusters each instance has.
- `meshlet_instance_meshlet_slice_starts` - The starting index of the
meshlets for each instance within the `meshlets` buffer.
- A new `fill_cluster_buffers` pass once at the start of the frame has a
thread per cluster, and finds its instance ID and meshlet ID via a
binary search of `meshlet_instance_meshlet_counts_prefix_sum` to find
what instance it belongs to, and then uses that plus
`meshlet_instance_meshlet_slice_starts` to find what number meshlet
within the instance it is. The shader then writes out the per-cluster
instance/meshlet ID buffers for later passes to quickly read from.
- I've gone from 45 -> 180 FPS in my stress test scene, and saved
~30ms/frame of overall CPU/GPU time.
# Objective
in response to [13222](https://github.com/bevyengine/bevy/issues/13222)
## Solution
The Image trait was already re-exported in bevy_render/src/lib.rs, So I
added it inline there.
## Testing
Confirmed that it does compile. Simple change, shouldn't cause any
bugs/regressions.
# Objective
`bevy_pbr/utils.wgsl` shader file contains mathematical constants and
color conversion functions. Both of those should be accessible without
enabling `bevy_pbr` feature. For example, tonemapping can be done in non
pbr scenario, and it uses color conversion functions.
Fixes#13207
## Solution
* Move mathematical constants (such as PI, E) from
`bevy_pbr/src/render/utils.wgsl` into `bevy_render/src/maths.wgsl`
* Move color conversion functions from `bevy_pbr/src/render/utils.wgsl`
into new file `bevy_render/src/color_operations.wgsl`
## Testing
Ran multiple examples, checked they are working:
* tonemapping
* color_grading
* 3d_scene
* animated_material
* deferred_rendering
* 3d_shapes
* fog
* irradiance_volumes
* meshlet
* parallax_mapping
* pbr
* reflection_probes
* shadow_biases
* 2d_gizmos
* light_gizmos
---
## Changelog
* Moved mathematical constants (such as PI, E) from
`bevy_pbr/src/render/utils.wgsl` into `bevy_render/src/maths.wgsl`
* Moved color conversion functions from `bevy_pbr/src/render/utils.wgsl`
into new file `bevy_render/src/color_operations.wgsl`
## Migration Guide
In user's shader code replace usage of mathematical constants from
`bevy_pbr::utils` to the usage of the same constants from
`bevy_render::maths`.
# Objective
- Add auto exposure/eye adaptation to the bevy render pipeline.
- Support features that users might expect from other engines:
- Metering masks
- Compensation curves
- Smooth exposure transitions
This PR is based on an implementation I already built for a personal
project before https://github.com/bevyengine/bevy/pull/8809 was
submitted, so I wasn't able to adopt that PR in the proper way. I've
still drawn inspiration from it, so @fintelia should be credited as
well.
## Solution
An auto exposure compute shader builds a 64 bin histogram of the scene's
luminance, and then adjusts the exposure based on that histogram. Using
a histogram allows the system to ignore outliers like shadows and
specular highlights, and it allows to give more weight to certain areas
based on a mask.
---
## Changelog
- Added: AutoExposure plugin that allows to adjust a camera's exposure
based on it's scene's luminance.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Follow-up of #13184 :)
- We use `ui_test` to test compiler errors for our custom macros.
- There are four crates related to compile fail tests
- `bevy_ecs_compile_fail_tests`, `bevy_macros_compile_fail_tests`, and
`bevy_reflect_compile_fail_tests`, which actually test the macros.
-
[`bevy_compile_test_utils`](64c1c65783/crates/bevy_compile_test_utils),
which provides helpers and common patterns for these tests.
- All of these crates reside within the `crates` directory.
- This can be confusing, especially for newcomers. All of the other
folders in `crates` are actual published libraries, except for these 4.
## Solution
- Move all compile fail tests to a `compile_fail` folder under their
corresponding crate.
- E.g. `crates/bevy_ecs_compile_fail_tests` would be moved to
`crates/bevy_ecs/compile_fail`.
- Move `bevy_compile_test_utils` to `tools/compile_fail_utils`.
There are a few benefits to this approach:
1. An internal testing detail is less intrusive (and confusing) for
those who just want to browse the public Bevy interface.
2. Follows a pre-existing approach of organizing related crates inside a
larger crate's folder.
- See `bevy_gizmos/macros` for an example.
4. Makes consistent the terms `compile_test`, `compile_fail`, and
`compile_fail_test` in code. It's all just `compile_fail` now, because
we are specifically testing the error messages on compiler failures.
- To be clear it can still be referred to by these terms in comments and
speech, just the names of the crates and the CI command are now
consistent.
## Testing
Run the compile fail CI command:
```shell
cargo run -p ci -- compile-fail
```
If it still passes, then my refactor was successful.
# Objective
Resolves#13185
## Solution
Move the following methods from `sub_app` to the `Schedules` resource,
and use them in the sub app:
- `add_systems`
- `configure_sets`
- `ignore_ambiguity`
Add an `entry(&mut self, label: impl ScheduleLabel) -> &mut Schedule`
method to the `Schedules` resource, which returns a mutable reference to
the schedule associated with the label, and creates one if it doesn't
already exist. (build on top of the `entry(..).or_insert_with(...)`
pattern in `HashMap`.
## Testing
- Did you test these changes? If so, how? Added 4 unit tests to the
`schedule.rs` - one that validates adding a system to an existing
schedule, one that validates adding a system to a new one, one that
validates configuring sets on an existing schedule, and one that
validates configuring sets on a new schedule.
- I didn't add tests for `entry` since the previous 4 tests use
functions that rely on it.
- I didn't test `ignore_ambiguity` since I didn't see examples of it's
use, and am not familiar enough with it to know how to set up a good
test for it. However, it relies on the `entry` method as well, so it
should work just like the other 2 methods.
This is an adoption of #12670 plus some documentation fixes. See that PR
for more details.
---
## Changelog
* Renamed `BufferVec` to `RawBufferVec` and added a new `BufferVec`
type.
## Migration Guide
`BufferVec` has been renamed to `RawBufferVec` and a new similar type
has taken the `BufferVec` name.
---------
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
# Objective
~Returning a app exit code from the winit runner is complicated and
deadlock prone.~
The code to return a app exit code is rather shoddy. It's use of mutex
is redundant, It uses unwrap when not required and can be broken by a
maintainer simply forgetting to set a value.
## Solution
Switch to using a channel.
- Deals with situations in which a event loop exits unexpectedly.
- Never panics. Even in extreme cases.
Implement visibility ranges, also known as hierarchical levels of detail
(HLODs).
This commit introduces a new component, `VisibilityRange`, which allows
developers to specify camera distances in which meshes are to be shown
and hidden. Hiding meshes happens early in the rendering pipeline, so
this feature can be used for level of detail optimization. Additionally,
this feature is properly evaluated per-view, so different views can show
different levels of detail.
This feature differs from proper mesh LODs, which can be implemented
later. Engines generally implement true mesh LODs later in the pipeline;
they're typically more efficient than HLODs with GPU-driven rendering.
However, mesh LODs are more limited than HLODs, because they require the
lower levels of detail to be meshes with the same vertex layout and
shader (and perhaps the same material) as the original mesh. Games often
want to use objects other than meshes to replace distant models, such as
*octahedral imposters* or *billboard imposters*.
The reason why the feature is called *hierarchical level of detail* is
that HLODs can replace multiple meshes with a single mesh when the
camera is far away. This can be useful for reducing drawcall count. Note
that `VisibilityRange` doesn't automatically propagate down to children;
it must be placed on every mesh.
Crossfading between different levels of detail is supported, using the
standard 4x4 ordered dithering pattern from [1]. The shader code to
compute the dithering patterns should be well-optimized. The dithering
code is only active when visibility ranges are in use for the mesh in
question, so that we don't lose early Z.
Cascaded shadow maps show the HLOD level of the view they're associated
with. Point light and spot light shadow maps, which have no CSMs,
display all HLOD levels that are visible in any view. To support this
efficiently and avoid doing visibility checks multiple times, we
precalculate all visible HLOD levels for each entity with a
`VisibilityRange` during the `check_visibility_range` system.
A new example, `visibility_range`, has been added to the tree, as well
as a new low-poly version of the flight helmet model to go with it. It
demonstrates use of the visibility range feature to provide levels of
detail.
[1]: https://en.wikipedia.org/wiki/Ordered_dithering#Threshold_map
[^1]: Unreal doesn't have a feature that exactly corresponds to
visibility ranges, but Unreal's HLOD system serves roughly the same
purpose.
## Changelog
### Added
* A new `VisibilityRange` component is available to conditionally enable
entity visibility at camera distances, with optional crossfade support.
This can be used to implement different levels of detail (LODs).
## Screenshots
High-poly model:
![Screenshot 2024-04-09
185541](https://github.com/bevyengine/bevy/assets/157897/7e8be017-7187-4471-8866-974e2d8f2623)
Low-poly model up close:
![Screenshot 2024-04-09
185546](https://github.com/bevyengine/bevy/assets/157897/429603fe-6bb7-4246-8b4e-b4888fd1d3a0)
Crossfading between the two:
![Screenshot 2024-04-09
185604](https://github.com/bevyengine/bevy/assets/157897/86d0d543-f8f3-49ec-8fe5-caa4d0784fd4)
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Current config file is hard to extend
## Solution
- Instead of an hard coded list of field, the file now has a list of
`(frame, event)`, and will deal with know events (exiting or taking a
screenshot), or send an event for others that can be dealt by third
party plugins
# Objective
- I've been using the `texture_binding_array` example as a base to use
multiple textures in meshes in my program
- I only realised once I was deep in render code that these helpers
existed to create layouts
- I wish I knew the existed earlier because the alternative (filling in
every struct field) is so much more verbose
## Solution
- Use `BindGroupLayoutEntries::with_indices` to teach users that the
helper exists
- Also fix typo which should be `texture_2d`.
## Alternatives considered
- Just leave it as is to teach users about every single struct field
- However, leaving as is leaves users writing roughly 29 lines versus
roughly 2 lines for 2 entries and I'd prefer the 2 line approach
## Testing
Ran the example locally and compared before and after.
Before:
<img width="1280" alt="image"
src="https://github.com/bevyengine/bevy/assets/135186256/f5897210-2560-4110-b92b-85497be9023c">
After:
<img width="1279" alt="image"
src="https://github.com/bevyengine/bevy/assets/135186256/8d13a939-b1ce-4a49-a9da-0b1779c8cb6a">
Co-authored-by: mgi388 <>
# Objective
- Simplifies/clarifies the winit loop.
- Fixes#12612.
## Solution
The Winit loop runs following this flow:
* NewEvents
* Any number of other events, that can be 0, including RequestRedraw
* AboutToWait
Bevy also uses the UpdateMode, to define how the next loop has to run.
It can be essentially:
* Continuous, using ControlFlow::Wait for windowed apps, and
ControlFlow::Poll for windowless apps
* Reactive/ReactiveLowPower, using ControlFlow::WaitUntil with a
specific wait delay
The changes are made to follow this pattern, so that
* NewEvents define if the WaitUntil has been canceled because we
received a Winit event.
* AboutToWait:
* checks if the window has to be redrawn
* otherwise calls app.update() if the WaitUntil timeout has elapsed
* updates the ControlFlow accordingly
To make the code more logical:
* AboutToWait checks if any Bevy's RequestRedraw event has been emitted
* create_windows is run every cycle, at the beginning of the loop
* the ActiveState (that could be renamed ActivityState) is updated in
AboutToWait, symmetrically for WillSuspend/WillResume
* the AppExit events are checked every loop cycle, to exit the app early
## Platform-specific testing
- [x] Windows
- [x] MacOs
- [x] Linux (x11)
- [x] Linux (Wayland)
- [x] Android
- [x] iOS
- [x] WASM/WebGL2 (Chrome)
- [x] WASM/WebGL2 (Firefox)
- [x] WASM/WebGL2 (Safari)
- [x] WASM/WebGpu (Chrome)
---------
Co-authored-by: François <francois.mockers@vleue.com>
## Summary/Description
This PR extends states to allow support for a wider variety of state
types and patterns, by providing 3 distinct types of state:
- Standard [`States`] can only be changed by manually setting the
[`NextState<S>`] resource. These states are the baseline on which the
other state types are built, and can be used on their own for many
simple patterns. See the [state
example](https://github.com/bevyengine/bevy/blob/latest/examples/ecs/state.rs)
for a simple use case - these are the states that existed so far in
Bevy.
- [`SubStates`] are children of other states - they can be changed
manually using [`NextState<S>`], but are removed from the [`World`] if
the source states aren't in the right state. See the [sub_states
example](https://github.com/lee-orr/bevy/blob/derived_state/examples/ecs/sub_states.rs)
for a simple use case based on the derive macro, or read the trait docs
for more complex scenarios.
- [`ComputedStates`] are fully derived from other states - they provide
a [`compute`](ComputedStates::compute) method that takes in the source
states and returns their derived value. They are particularly useful for
situations where a simplified view of the source states is necessary -
such as having an `InAMenu` computed state derived from a source state
that defines multiple distinct menus. See the [computed state
example](https://github.com/lee-orr/bevy/blob/derived_state/examples/ecs/computed_states.rscomputed_states.rs)
to see a sampling of uses for these states.
# Objective
This PR is another attempt at allowing Bevy to better handle complex
state objects in a manner that doesn't rely on strict equality. While my
previous attempts (https://github.com/bevyengine/bevy/pull/10088 and
https://github.com/bevyengine/bevy/pull/9957) relied on complex matching
capacities at the point of adding a system to application, this one
instead relies on deterministically deriving simple states from more
complex ones.
As a result, it does not require any special macros, nor does it change
any other interactions with the state system once you define and add
your derived state. It also maintains a degree of distinction between
`State` and just normal application state - your derivations have to end
up being discreet pre-determined values, meaning there is less of a
risk/temptation to place a significant amount of logic and data within a
given state.
### Addition - Sub States
closes#9942
After some conversation with Maintainers & SMEs, a significant concern
was that people might attempt to use this feature as if it were
sub-states, and find themselves unable to use it appropriately. Since
`ComputedState` is mainly a state matching feature, while `SubStates`
are more of a state mutation related feature - but one that is easy to
add with the help of the machinery introduced by `ComputedState`, it was
added here as well. The relevant discussion is here:
https://discord.com/channels/691052431525675048/1200556329803186316
## Solution
closes#11358
The solution is to create a new type of state - one implementing
`ComputedStates` - which is deterministically tied to one or more other
states. Implementors write a function to transform the source states
into the computed state, and it gets triggered whenever one of the
source states changes.
In addition, we added the `FreelyMutableState` trait , which is
implemented as part of the derive macro for `States`. This allows us to
limit use of `NextState<S>` to states that are actually mutable,
preventing mis-use of `ComputedStates`.
---
## Changelog
- Added `ComputedStates` trait
- Added `FreelyMutableState` trait
- Converted `NextState` resource to an Enum, with `Unchanged` and
`Pending`
- Added `App::add_computed_state::<S: ComputedStates>()`, to allow for
easily adding derived states to an App.
- Moved the `StateTransition` schedule label from `bevy_app` to
`bevy_ecs` - but maintained the export in `bevy_app` for continuity.
- Modified the process for updating states. Instead of just having an
`apply_state_transition` system that can be added anywhere, we now have
a multi-stage process that has to run within the `StateTransition`
label. First, all the state changes are calculated - manual transitions
rely on `apply_state_transition`, while computed transitions run their
computation process before both call `internal_apply_state_transition`
to apply the transition, send out the transition event, trigger
dependent states, and record which exit/transition/enter schedules need
to occur. Once all the states have been updated, the transition
schedules are called - first the exit schedules, then transition
schedules and finally enter schedules.
- Added `SubStates` trait
- Adjusted `apply_state_transition` to be a no-op if the `State<S>`
resource doesn't exist
## Migration Guide
If the user accessed the NextState resource's value directly or created
them from scratch they will need to adjust to use the new enum variants:
- if they created a `NextState(Some(S))` - they should now use
`NextState::Pending(S)`
- if they created a `NextState(None)` -they should now use
`NextState::Unchanged`
- if they matched on the `NextState` value, they would need to make the
adjustments above
If the user manually utilized `apply_state_transition`, they should
instead use systems that trigger the `StateTransition` schedule.
---
## Future Work
There is still some future potential work in the area, but I wanted to
keep these potential features and changes separate to keep the scope
here contained, and keep the core of it easy to understand and use.
However, I do want to note some of these things, both as inspiration to
others and an illustration of what this PR could unlock.
- `NextState::Remove` - Now that the `State` related mechanisms all
utilize options (#11417), it's fairly easy to add support for explicit
state removal. And while `ComputedStates` can add and remove themselves,
right now `FreelyMutableState`s can't be removed from within the state
system. While it existed originally in this PR, it is a different
question with a separate scope and usability concerns - so having it as
it's own future PR seems like the best approach. This feature currently
lives in a separate branch in my fork, and the differences between it
and this PR can be seen here: https://github.com/lee-orr/bevy/pull/5
- `NextState::ReEnter` - this would allow you to trigger exit & entry
systems for the current state type. We can potentially also add a
`NextState::ReEnterRecirsive` to also re-trigger any states that depend
on the current one.
- More mechanisms for `State` updates - This PR would finally make
states that aren't a set of exclusive Enums useful, and with that comes
the question of setting state more effectively. Right now, to update a
state you either need to fully create the new state, or include the
`Res<Option<State<S>>>` resource in your system, clone the state, mutate
it, and then use `NextState.set(my_mutated_state)` to make it the
pending next state. There are a few other potential methods that could
be implemented in future PRs:
- Inverse Compute States - these would essentially be compute states
that have an additional (manually defined) function that can be used to
nudge the source states so that they result in the computed states
having a given value. For example, you could use set the `IsPaused`
state, and it would attempt to pause or unpause the game by modifying
the `AppState` as needed.
- Closure-based state modification - this would involve adding a
`NextState.modify(f: impl Fn(Option<S> -> Option<S>)` method, and then
you can pass in closures or function pointers to adjust the state as
needed.
- Message-based state modification - this would involve either creating
states that can respond to specific messages, similar to Elm or Redux.
These could either use the `NextState` mechanism or the Event mechanism.
- ~`SubStates` - which are essentially a hybrid of computed and manual
states. In the simplest (and most likely) version, they would work by
having a computed element that determines whether the state should
exist, and if it should has the capacity to add a new version in, but
then any changes to it's content would be freely mutated.~ this feature
is now part of this PR. See above.
- Lastly, since states are getting more complex there might be value in
moving them out of `bevy_ecs` and into their own crate, or at least out
of the `schedule` module into a `states` module. #11087
As mentioned, all these future work elements are TBD and are explicitly
not part of this PR - I just wanted to provide them as potential
explorations for the future.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Marcel Champagne <voiceofmarcel@gmail.com>
Co-authored-by: MiniaczQ <xnetroidpl@gmail.com>
# Objective
- `README.md` is a common file that usually gives an overview of the
folder it is in.
- When on <https://crates.io>, `README.md` is rendered as the main
description.
- Many crates in this repository are lacking `README.md` files, which
makes it more difficult to understand their purpose.
<img width="1552" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/78ebf91d-b0c4-4b18-9874-365d6310640f">
- There are also a few inconsistencies with `README.md` files that this
PR and its follow-ups intend to fix.
## Solution
- Create a `README.md` file for all crates that do not have one.
- This file only contains the title of the crate (underscores removed,
proper capitalization, acronyms expanded) and the <https://shields.io>
badges.
- Remove the `readme` field in `Cargo.toml` for `bevy` and
`bevy_reflect`.
- This field is redundant because [Cargo automatically detects
`README.md`
files](https://doc.rust-lang.org/cargo/reference/manifest.html#the-readme-field).
The field is only there if you name it something else, like `INFO.md`.
- Fix capitalization of `bevy_utils`'s `README.md`.
- It was originally `Readme.md`, which is inconsistent with the rest of
the project.
- I created two commits renaming it to `README.md`, because Git appears
to be case-insensitive.
- Expand acronyms in title of `bevy_ptr` and `bevy_utils`.
- In the commit where I created all the new `README.md` files, I
preferred using expanded acronyms in the titles. (E.g. "Bevy Developer
Tools" instead of "Bevy Dev Tools".)
- This commit changes the title of existing `README.md` files to follow
the same scheme.
- I do not feel strongly about this change, please comment if you
disagree and I can revert it.
- Add <https://shields.io> badges to `bevy_time` and `bevy_transform`,
which are the only crates currently lacking them.
---
## Changelog
- Added `README.md` files to all crates missing it.
# Objective
- Update glam version requirement to latest version.
## Solution
- Updated `glam` version requirement from 0.25 to 0.27.
- Updated `encase` and `encase_derive_impl` version requirement from 0.7
to 0.8.
- Updated `hexasphere` version requirement from 10.0 to 12.0.
- Breaking changes from glam changelog:
- [0.26.0] Minimum Supported Rust Version bumped to 1.68.2 for impl
From<bool> for {f32,f64} support.
- [0.27.0] Changed implementation of vector fract method to match the
Rust implementation instead of the GLSL implementation, that is self -
self.trunc() instead of self - self.floor().
---
## Migration Guide
- When using `glam` exports, keep in mind that `vector` `fract()` method
now matches Rust implementation (that is `self - self.trunc()` instead
of `self - self.floor()`). If you want to use the GLSL implementation
you should now use `fract_gl()`.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
I'm reading through the schedule code, which is somewhat lacking
documentation.
I've been adding some docstrings to help me understand the code; I feel
like some of them could be useful to also help others read this code.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Make `Result<T, E>` implement Reflect such that it is an Enum rather
than a Value
- Fixes#13178
## Solution
- Use the correct macro
## Testing
- Did you test these changes?
I tried it out locally, and it does what it says on the tin. Not sure
how to test it in context of the crate?
---
## Changelog
### Changed
- Result now uses `ReflectKind::Enum` rather than `ReflectKind::Value`,
allowing for inspection of its constituents
## Migration Guide
`Result<T, E>` has had its `Reflect` implementation changed to align it
with `Option<T>` and its intended semantics: A carrier of either an `Ok`
or `Err` value, and the ability to access it. To achieve this it is no
longer a `ReflectKind::Value` but rather a `ReflectKind::Enum` and as
such carries these changes with it:
For `Result<T, E>`
- Both `T` and `E` no longer require to be `Clone` and now require to be
`FromReflect`
- `<Result<T, E> as Reflect>::reflect_*` now returns a
`ReflectKind::Enum`, so any code that previously relied on it being a
`Value` kind will have to be adapted.
- `Result<T, E>` now implements `Enum`
Since the migration is highly dependent on the previous usage, no
automatic upgrade path can be given.
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit expands Bevy's existing tonemapping feature to a complete
set of filmic color grading tools, matching those of engines like Unity,
Unreal, and Godot. The following features are supported:
* White point adjustment. This is inspired by Unity's implementation of
the feature, but simplified and optimized. *Temperature* and *tint*
control the adjustments to the *x* and *y* chromaticity values of [CIE
1931]. Following Unity, the adjustments are made relative to the [D65
standard illuminant] in the [LMS color space].
* Hue rotation. This simply converts the RGB value to [HSV], alters the
hue, and converts back.
* Color correction. This allows the *gamma*, *gain*, and *lift* values
to be adjusted according to the standard [ASC CDL combined function].
* Separate color correction for shadows, midtones, and highlights.
Blender's source code was used as a reference for the implementation of
this. The midtone ranges can be adjusted by the user. To avoid abrupt
color changes, a small crossfade is used between the different sections
of the image, again following Blender's formulas.
A new example, `color_grading`, has been added, offering a GUI to change
all the color grading settings. It uses the same test scene as the
existing `tonemapping` example, which has been factored out into a
shared glTF scene.
[CIE 1931]: https://en.wikipedia.org/wiki/CIE_1931_color_space
[D65 standard illuminant]:
https://en.wikipedia.org/wiki/Standard_illuminant#Illuminant_series_D
[LMS color space]: https://en.wikipedia.org/wiki/LMS_color_space
[HSV]: https://en.wikipedia.org/wiki/HSL_and_HSV
[ASC CDL combined function]:
https://en.wikipedia.org/wiki/ASC_CDL#Combined_Function
## Changelog
### Added
* Many new filmic color grading options have been added to the
`ColorGrading` component.
## Migration Guide
* `ColorGrading::gamma` and `ColorGrading::pre_saturation` are now set
separately for the `shadows`, `midtones`, and `highlights` sections. You
can migrate code with the `ColorGrading::all_sections` and
`ColorGrading::all_sections_mut` functions, which access and/or update
all sections at once.
* `ColorGrading::post_saturation` and `ColorGrading::exposure` are now
fields of `ColorGrading::global`.
## Screenshots
![Screenshot 2024-04-27
143144](https://github.com/bevyengine/bevy/assets/157897/c1de5894-917d-4101-b5c9-e644d141a941)
![Screenshot 2024-04-27
143216](https://github.com/bevyengine/bevy/assets/157897/da393c8a-d747-42f5-b47c-6465044c788d)
# Objective
The `Events` containerr should be reflectable, in order to make dev
tools that examine its state more useful.
Fixes#13148.
## Solution
- Add a `Reflect` derive to `Events`, gated behind the `bevy_reflect`
feature
- Add `Reflect` to the contained types to make everything compile.
---------
Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
# Objective
- Enables support for `Display::Block`
- Enables support for `Overflow::Hidden`
- Allows for cleaner integration with text, image and other content
layout.
- Unblocks https://github.com/bevyengine/bevy/pull/8104
- Unlocks the possibility of Bevy creating a custom layout tree over
which Taffy operates.
- Enables #8808 / #10193 to remove a Mutex around the font system.
## Todo
- [x] ~Fix rendering of text/images to account for padding/border on
nodes (should size/position to content box rather than border box)~ In
order get this into a mergeable state this PR instead zeroes out
padding/border when syncing leaf node styles into Taffy to preserve the
existing behaviour. https://github.com/bevyengine/bevy/issues/6879 can
be fixed in a followup PR.
## Solution
- Update the version of Taffy
- Update code to work with the new version
Note: Taffy 0.4 has not yet been released. This PR is being created in
advance of the release to ensure that there are no blockers to upgrading
once the release occurs.
---
## Changelog
- Bevy now supports the `Display::Block` and `Overflow::Hidden` styles.
# Objective
A `RawWindowHandle` is only valid as long as the window it was retrieved
from is alive. Extend the lifetime of the window, so that the
`RawWindowHandle` doesn't outlive it, and bevy doesn't crash when
closing a window a pipelined renderer is drawing to.
- Fix#11236
- Fix#11150
- Fix#11734
- Alternative to / Closes#12524
## Solution
Introduce a `WindowWrapper` that takes ownership of the window. Require
it to be used when constructing a `RawHandleWrapper`. This forces
windowing backends to store their window in this wrapper.
The `WindowWrapper` is implemented by storing the window in an `Arc<dyn
Any + Send + Sync>`.
We use dynamic dispatch here because we later want the
`RawHandleWrapper` to be able dynamically hold a reference to any
windowing backend's window.
But alas, the `WindowWrapper` itself is still practically invisible to
windowing backends, because it implements `Deref` to the underlying
window, by storing its type in a `PhantomData`.
---
## Changelog
### Added
- Added `WindowWrapper`, which windowing backends are now required to
use to store their underlying window.
### Fixed
- Fixed a safety problem which caused crashes when closing bevy windows
when using pipelined rendering.
## Migration Guide
- Windowing backends now need to store their window in the new
`WindowWrapper`.
In #12889, I mistakenly started dropping unbatchable sorted items on the
floor instead of giving them solitary batches. This caused the objects
in the `shader_instancing` demo to stop showing up. This patch fixes the
issue by giving those items their own batches as expected.
Fixes#13130.
# Objective
- Partially resolves#12639.
## Solution
- Deprecate `ReceivedCharacter`.
- Replace `ReceivedCharacter` with `KeyboardInput` in the relevant
examples.
## Migration Guide
- `ReceivedCharacter` is now deprecated, use `KeyboardInput` instead.
- Before:
```rust
fn listen_characters(events: EventReader<ReceivedCharacter>) {
for event in events.read() {
info!("{}", event.char);
}
}
```
After:
```rust
fn listen_characters(events: EventReader<KeyboardInput>) {
for event in events.read() {
// Only check for characters when the key is pressed.
if event.state == ButtonState::Released {
continue;
}
// Note that some keys such as `Space` and `Tab` won't be detected as
before.
// Instead, check for them with `Key::Space` and `Key::Tab`.
if let Key::Character(character) = &event.logical_key {
info!("{}", character);
}
}
}
```
---------
Co-authored-by: Mike <mike.hsu@gmail.com>
# Objective
- `from_reflect_or_world` is an internal utilty used in the
implementations of `ReflectComponent` and `ReflectBundle` to create a
`T` given a `&dyn Reflect` by trying to use `FromReflect`, and if that
fails it falls back to `ReflectFromWorld`
- reflecting `FromWorld` is not intuitive though: often it is implicitly
implemented by deriving `Default` so people might not even be aware of
it.
- the panic messages mentioning `ReflectFromWorld` are not directly
correlated to what the user would have to do (reflect `FromWorld`)
## Solution
- Also check for `ReflectDefault` in addition to `ReflectFromWorld`.
- Change the panic messages to mention the reflected trait rather than
the `Reflect*` types.
---
## Changelog
- `ReflectComponent` and `ReflectBundle` no longer require `T:
FromReflect` but instead only `T: Reflect`.
- `ReflectComponent` and `ReflectBundle` will also work with types that
only reflected `Default` and not `FromWorld`.
## Migration Guide
- `ReflectBundle::insert` now requires an additional `&TypeRegistry`
parameter.
# Objective
I have been trying to check for the existing of some plugins via
`App::is_plugin_added` to conditionally run some behaviour in the
`Plugin::finish` part of my plugin, before realizing that the plugin
registry is actually not available during this step.
This is because the `App::is_plugin_added` using the plugin registry to
check for previous registration.
## Solution
- Switch the `App::is_plugin_added` to use the list of plugin names to
check for previous registrations
- Add a unit test showcasing that `App::is_plugin_added` works during
`Plugin::finish`
This commit implements opt-in GPU frustum culling, built on top of the
infrastructure in https://github.com/bevyengine/bevy/pull/12773. To
enable it on a camera, add the `GpuCulling` component to it. To
additionally disable CPU frustum culling, add the `NoCpuCulling`
component. Note that adding `GpuCulling` without `NoCpuCulling`
*currently* does nothing useful. The reason why `GpuCulling` doesn't
automatically imply `NoCpuCulling` is that I intend to follow this patch
up with GPU two-phase occlusion culling, and CPU frustum culling plus
GPU occlusion culling seems like a very commonly-desired mode.
Adding the `GpuCulling` component to a view puts that view into
*indirect mode*. This mode makes all drawcalls indirect, relying on the
mesh preprocessing shader to allocate instances dynamically. In indirect
mode, the `PreprocessWorkItem` `output_index` points not to a
`MeshUniform` instance slot but instead to a set of `wgpu`
`IndirectParameters`, from which it allocates an instance slot
dynamically if frustum culling succeeds. Batch building has been updated
to allocate and track indirect parameter slots, and the AABBs are now
supplied to the GPU as `MeshCullingData`.
A small amount of code relating to the frustum culling has been borrowed
from meshlets and moved into `maths.wgsl`. Note that standard Bevy
frustum culling uses AABBs, while meshlets use bounding spheres; this
means that not as much code can be shared as one might think.
This patch doesn't provide any way to perform GPU culling on shadow
maps, to avoid making this patch bigger than it already is. That can be
a followup.
## Changelog
### Added
* Frustum culling can now optionally be done on the GPU. To enable it,
add the `GpuCulling` component to a camera.
* To disable CPU frustum culling, add `NoCpuCulling` to a camera. Note
that `GpuCulling` doesn't automatically imply `NoCpuCulling`.
# Objective
- There is an unfortunate lack of dragons in the meshlet docs.
- Dragons are symbolic of majesty, power, storms, and meshlets.
- A dragon habitat such as our docs requires cultivation to ensure each
winged lizard reaches their fullest, fiery selves.
## Solution
- Fix the link to the dragon image.
- The link originally targeted the `meshlet` branch, but that was later
deleted after it was merged into `main`.
---
## Changelog
- Added a dragon back into the `MeshletPlugin` documentation.
Keeping track of explicit visibility per cluster between frames does not
work with LODs, and leads to worse culling (using the final depth buffer
from the previous frame is more accurate).
Instead, we need to generate a second depth pyramid after the second
raster pass, and then use that in the first culling pass in the next
frame to test if a cluster would have been visible last frame or not.
As part of these changes, the write_index_buffer pass has been folded
into the culling pass for a large performance gain, and to avoid
tracking a lot of extra state that would be needed between passes.
Prepass previous model/view stuff was adapted to work with meshlets as
well.
Also fixed a bug with materials, and other misc improvements.
---------
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
# Objective
- Provide feedback when an extraction plugin fails to add its system.
I had some troubleshooting pain when this happened to me, as the panic
only tells you a resource is missing. This PR adds an error when the
ExtractResource plugin is added before the render world exists, instead
of silently failing.
![image](https://user-images.githubusercontent.com/2632925/172491993-673d9351-215a-4f30-96f7-af239c44686a.png)
# Objective
- Since #12622 example `compute_shader_game_of_life` crashes
```
thread 'Compute Task Pool (2)' panicked at examples/shader/compute_shader_game_of_life.rs:137:65:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `compute_shader_game_of_life::prepare_bind_group`!
thread '<unnamed>' panicked at examples/shader/compute_shader_game_of_life.rs:254:34:
Requested resource compute_shader_game_of_life::GameOfLifeImageBindGroups does not exist in the `World`.
Did you forget to add it using `app.insert_resource` / `app.init_resource`?
Resources are also implicitly added via `app.add_event`,
and can be added by plugins.
Encountered a panic in system `bevy_render::renderer::render_system`!
```
## Solution
- `exhausted()` now checks that there is a limit
# Objective
Make compile fail tests less likely to break with new Rust versions.
Closes#12627
## Solution
Switch from [`trybuild`](https://github.com/dtolnay/trybuild) to
[`ui_test`](https://github.com/oli-obk/ui_test).
## TODO
- [x] Update `bevy_ecs_compile_fail_tests`
- [x] Update `bevy_macros_compile_fail_tests`
- [x] Update `bevy_reflect_compile_fail_tests`
---------
Co-authored-by: Oli Scherer <github35764891676564198441@oli-obk.de>
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
# Objective
Fix https://github.com/bevyengine/bevy/issues/11799 and improve
`CameraProjectionPlugin`
## Solution
`CameraProjectionPlugin` is now an all-in-one plugin for adding a custom
`CameraProjection`. I also added `PbrProjectionPlugin` which is like
`CameraProjectionPlugin` but for PBR.
P.S. I'd like to get this merged after
https://github.com/bevyengine/bevy/pull/11766.
---
## Changelog
- Changed `CameraProjectionPlugin` to be an all-in-one plugin for adding
a `CameraProjection`
- Removed `VisibilitySystems::{UpdateOrthographicFrusta,
UpdatePerspectiveFrusta, UpdateProjectionFrusta}`, now replaced with
`VisibilitySystems::UpdateFrusta`
- Added `PbrProjectionPlugin` for projection-specific PBR functionality.
## Migration Guide
`VisibilitySystems`'s `UpdateOrthographicFrusta`,
`UpdatePerspectiveFrusta`, and `UpdateProjectionFrusta` variants were
removed, they were replaced with `VisibilitySystems::UpdateFrusta`
# Objective
- #12500 broke rotating ui nodes, see examples `pbr` (missing "metallic"
label) or `overflow_debug` (bottom right box is empty)
## Solution
- Pass the untransformed node size to the shader
# Objective
- clean up extract_mesh_(gpu/cpu)_building
## Solution
- gpu_building no need to hold `prev_render_mesh_instances`
- using `insert_unique_unchecked` instead of simple insert as we know
all entities are unique
- direcly get `previous_input_index ` in par_loop
## Performance
this should also bring a slight performance win.
cargo run --release --example many_cubes --features bevy/trace_tracy --
--no-frustum-culling
`extract_meshes_for_gpu_building`
![image](https://github.com/bevyengine/bevy/assets/45868716/a5425e8a-258b-482d-afda-170363ee6479)
---------
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
# Objective
allow throttling of gpu uploads to prevent choppy framerate when many
textures/meshes are loaded in.
## Solution
- `RenderAsset`s can implement `byte_len()` which reports their size.
implemented this for `Mesh` and `Image`
- users can add a `RenderAssetBytesPerFrame` which specifies max bytes
to attempt to upload in a frame
- `render_assets::<A>` checks how many bytes have been written before
attempting to upload assets. the limit is a soft cap: assets will be
written until the total has exceeded the cap, to ensure some forward
progress every frame
notes:
- this is a stopgap until we have multiple wgpu queues for proper
streaming of data
- requires #12606
issues
- ~~fonts sometimes only partially upload. i have no clue why, needs to
be fixed~~ fixed now.
- choosing the #bytes is tricky as it should be hardware / framerate
dependent
- many features are not tested (env maps, light probes, etc) - they
won't break unless `RenderAssetBytesPerFrame` is explicitly used though
---------
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
- Fixes#13094
## Solution
- Added vmin() and vmax() to the `GridTrack` & `RepeatedGridTrack`
impls, repeatedgridtrack impls, and both to the variants of Min & Max
TrackSizingFunction
## Sidenote
This would be my first PR to bevy. Feel free to say anything.
Thanks to the Bevy Team for everything you've done!
---------
Co-authored-by: Franklin <franklinblanco@tutanota.com>
# Objective
- The [`version`] field in `Cargo.toml` is optional for crates not
published on <https://crates.io>.
- We have several `publish = false` tools in this repository that still
have a version field, even when it's not useful.
[`version`]:
https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field
## Solution
- Remove the [`version`] field for all crates where `publish = false`.
- Update the description on a few crates and remove extra newlines as
well.
# Objective
- Provide a way to iterate over the registered TypeData.
## Solution
- a new method on the `TypeRegistry` that iterates over
`TypeRegistrations` with theirs `TypeData`
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
- People have reported bounding volumes being slower than their existing
solution because it doesn't use SIMD aligned types.
## Solution
- Use `Vec3A` internally for bounding volumes, accepting `Into<Vec3A>`
wherever possible
- Change some code to make it more likely SIMD operations are used.
---
## Changelog
- Use `Vec3A` for 3D bounding volumes and raycasts
## Migration Guide
- 3D bounding volumes now use `Vec3A` types internally, return values
from methods on them now return `Vec3A` instead of `Vec3`
# Objective
- Better `SystemId` <-> `Entity` conversion.
## Solution
- Provide a method `SystemId::from_entity` to create a `SystemId<I, O>`
form an `Entity`. When users want to deal with the entities manually
they need a way to convert the `Entity` back to a `SystemId` to actually
run the system with `Commands` or `World`.
- Provide a method `SystemId::entity` that returns an `Entity` from
`SystemId`. The current `From` impl is not very discoverable as it does
not appear on the `SystemId` doc page.
- Remove old `From` impl.
## Migration Guide
```rust
let system_id = world.register_system(my_sys);
// old
let entity = Entity::from(system_id);
// new
let entity = system_id.entity();
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
https://github.com/bevyengine/bevy/assets/2632925/e046205e-3317-47c3-9959-fc94c529f7e0
# Objective
- Adds per-object motion blur to the core 3d pipeline. This is a common
effect used in games and other simulations.
- Partially resolves#4710
## Solution
- This is a post-process effect that uses the depth and motion vector
buffers to estimate per-object motion blur. The implementation is
combined from knowledge from multiple papers and articles. The approach
itself, and the shader are quite simple. Most of the effort was in
wiring up the bevy rendering plumbing, and properly specializing for HDR
and MSAA.
- To work with MSAA, the MULTISAMPLED_SHADING wgpu capability is
required. I've extracted this code from #9000. This is because the
prepass buffers are multisampled, and require accessing with
`textureLoad` as opposed to the widely compatible `textureSample`.
- Added an example to demonstrate the effect of motion blur parameters.
## Future Improvements
- While this approach does have limitations, it's one of the most
commonly used, and is much better than camera motion blur, which does
not consider object velocity. For example, this implementation allows a
dolly to track an object, and that object will remain unblurred while
the background is blurred. The biggest issue with this implementation is
that blur is constrained to the boundaries of objects which results in
hard edges. There are solutions to this by either dilating the object or
the motion vector buffer, or by taking a different approach such as
https://casual-effects.com/research/McGuire2012Blur/index.html
- I'm using a noise PRNG function to jitter samples. This could be
replaced with a blue noise texture lookup or similar, however after
playing with the parameters, it gives quite nice results with 4 samples,
and is significantly better than the artifacts generated when not
jittering.
---
## Changelog
- Added: per-object motion blur. This can be enabled and configured by
adding the `MotionBlurBundle` to a camera entity.
---------
Co-authored-by: Torstein Grindvik <52322338+torsteingrindvik@users.noreply.github.com>
# Objective
- Closes#12958
## Solution
- Find all methods under `Query` that mention panicking, and add
`#[track_caller]` to them.
---
## Changelog
- Added `#[track_caller]` to `Query::many`, `Query::many_mut`,
`Query::transmute_lens`, and `Query::transmute_lens_filtered`.
## For reviewers
I'm unfamiliar with the depths of the `Query` struct. Please check
whether it makes since for the updated methods to have
`#[track_caller]`, and if I missed any!
# Objective
- Clippy raises a few warnings on the latest nightly release. 📎
## Solution
- Use `ptr::from_ref` when possible, because it prevents you from
accidentally changing the mutability as well as its type.
- Use `ptr::addr_eq` when comparing two pointers, ignoring pointer
metadata.
# Objective
- animating a sprite in response to an event is a [common beginner
problem](https://www.reddit.com/r/bevy/comments/13xx4v7/sprite_animation_in_bevy/)
## Solution
- provide a simple example to show how to animate a sprite in response
to an event
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
Both the shedule and winit runners use/reimplement `app_exit_manual`
even tough they can use `app_exit`
## Solution
Nuke `app_exit_manual` from orbit.
# Objective
- Be able to edit animation inside the editor and save them once
modified. This will allow bevy to modify animation assets with code.
- Fixes#13052
## Solution
- Expose the previously const getters of the Animation curves
---
# Objective
Follow up to #13062. As of async-executor 1.11, the crate reexports
FallibleTask, which is the only reason bevy_tasks has a direct
dependency on async-task. This should avoid the two dependencies getting
out of sync in the future and causing spurious compilation failures.
## Solution
Bump async-executor to 1.11, use the reexport, remove the dependency on
async-task.
# Objective
- bevy usually use `Parallel::scope` to collect items from `par_iter`,
but `scope` will be called with every satifified items. it will cause a
lot of unnecessary lookup.
## Solution
- similar to Rayon ,we introduce `for_each_init` for `par_iter` which
only be invoked when spawn a task for a group of items.
---
## Changelog
- added `for_each_init`
## Performance
`check_visibility ` in `many_foxes `
![image](https://github.com/bevyengine/bevy/assets/45868716/030c41cf-0d2f-4a36-a071-35097d93e494)
~40% performance gain in `check_visibility`.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
Allow `Gizmos` to work in `FixedUpdate` without any changes needed. This
changes `Gizmos` from being a purely immediate mode api, but allows the
user to use it as if it were an immediate mode API regardless of
schedule context.
Also allows for extending by other custom schedules by adding their own
`GizmoStorage<Clear>` and the requisite systems:
- `propagate_gizmos::<Clear>` before `update_gizmo_meshes`
- `stash_default_gizmos` when starting a clear context
- `pop_default_gizmos` when ending a clear context
- `collect_default_gizmos` when grabbing the requested gizmos
- `clear_gizmos` for clearing the context's gizmos
## Solution
Adds a generic to `Gizmos` that defaults to `Update` (the current way
gizmos works). When entering a new clear context the default `Gizmos`
gets swapped out for that context's duration so the context can collect
the gizmos requested.
Prior work: https://github.com/bevyengine/bevy/pull/9153
## To do
- [x] `FixedUpdate` should probably get its own First, Pre, Update,
Post, Last system sets for this. Otherwise users will need to make sure
to order their systems before `clear_gizmos`. This could alternatively
be fixed by moving the setup of this to `bevy_time::fixed`?
PR to fix this issue: https://github.com/bevyengine/bevy/pull/10977
- [x] use mem::take internally for the swaps?
- [x] Better name for the `Context` generic on gizmos? `Clear`?
---
## Changelog
- Gizmos drawn in `FixedMain` now last until the next `FixedMain`
iteration runs.
Bumps `async-task` to 4.7.0 , note this is what Cargo.lock has as well.
Building as a dependency gives the following:
```
Compiling async-channel v1.8.0
Compiling futures-lite v1.12.0
error[E0432]: unresolved import `async_task::Builder`
--> /Users/daniel/.cargo/registry/src/index.crates.io-6f17d22bba15001f/async-executor-1.8.0/src/lib.rs:46:18
|
46 | use async_task::{Builder, Runnable};
| ^^^^^^^ no `Builder` in the root
|
= help: consider importing this struct instead:
std:🧵:Builder
For more information about this error, try `rustc --explain E0432`.
error: could not compile `async-executor` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
```
With this change, builds correctly
# Objective
Adds a few extra `#[doc(alias)]` entries to the
`bevy_math::primitives::WindingOrder` enum and its variants to improve
searchability.
## Solution
- Add "Orientation" for `WindingOrder` itself
- Add "AntiClockwise" for `CounterClockwise` variant
- Add "Collinear" for `Invalid` variant
These alternate terms seem to be quite common, especially in the
contexts of rendering and collision-detection.
Signed-off-by: Nullicorn <git@nullicorn.me>
# Objective
Fixes#12470
This adds a examples for `ButtonInput` with `KeyCode`, `MouseButton`,
and `GamepadButton`.
It also includes an example of checking a multi-key combination, and
checking multiple keys to mean roughly the same thing.
# Objective
Closes#13017.
## Solution
- Make `AppExit` a enum with a `Success` and `Error` variant.
- Make `App::run()` return a `AppExit` if it ever returns.
- Make app runners return a `AppExit` to signal if they encountered a
error.
---
## Changelog
### Added
- [`App::should_exit`](https://example.org/)
- [`AppExit`](https://docs.rs/bevy/latest/bevy/app/struct.AppExit.html)
to the `bevy` and `bevy_app` preludes,
### Changed
- [`AppExit`](https://docs.rs/bevy/latest/bevy/app/struct.AppExit.html)
is now a enum with 2 variants (`Success` and `Error`).
- The app's [runner
function](https://docs.rs/bevy/latest/bevy/app/struct.App.html#method.set_runner)
now has to return a `AppExit`.
-
[`App::run()`](https://docs.rs/bevy/latest/bevy/app/struct.App.html#method.run)
now also returns the `AppExit` produced by the runner function.
## Migration Guide
- Replace all usages of
[`AppExit`](https://docs.rs/bevy/latest/bevy/app/struct.AppExit.html)
with `AppExit::Success` or `AppExit::Failure`.
- Any custom app runners now need to return a `AppExit`. We suggest you
return a `AppExit::Error` if any `AppExit` raised was a Error. You can
use the new [`App::should_exit`](https://example.org/) method.
- If not exiting from `main` any other way. You should return the
`AppExit` from `App::run()` so the app correctly returns a error code if
anything fails e.g.
```rust
fn main() -> AppExit {
App::new()
//Your setup here...
.run()
}
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- https://github.com/rust-lang/rust/pull/123905 has been merged, so the
workaround introduced in #12913 is no longer necessary.
- Closes#12968
## Solution
- Remove unecessary `allow` attribute
- This is currently blocked until Rust beta updates.
- Last tested with `rustc 1.78.0-beta.7 (6fd191292 2024-04-12)`.
# Objective
Add support so bevy_ui can correctly handle an UI hierarchy without a
camera present.
- Fixes#12184
## Solution
As there was no default behavior for what should happen when a camera is
not present in a UI hierarchy, the solution
was based in defining that default behavior and improving the overall
handling of this "exception".
## Changelog
- Create default values to be used in upsert_node
- Add flag to control warnings about no camera present
- Create unit test no_camera_ui (to test if ui handles no camera
present)
# Objective
Allow parallel iteration over events, resolve#10766
## Solution
- Add `EventParIter` which works similarly to `QueryParIter`,
implementing a `for_each{_with_id}` operator.
I chose to not mirror `EventIteratorWithId` and instead implement both
operations on a single struct.
- Reuse `BatchingStrategy` from `QueryParIter`
## Changelog
- `EventReader` now supports parallel event iteration using
`par_read().for_each(|event| ...)`.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
# Objective
Makes crate module docs render correctly in the docs for the monolithic
library. Fixes https://github.com/bevyengine/bevy/issues/13055.
## Solution
Swap from
```rust
pub mod foo {
pub use bevy_foo::*;
}
```
to
```rust
pub use bevy_foo as foo;
```
Adjusted the documentation to better describe the performance cost of
`ButtonInput::any_just_pressed|any_just_released|any_pressed`.
Each function iterates the full input, but each check is expected
constant cost. It was described previously as a full input check, and a
full internal list iteration, which I believe is incorrect.
# Objective
- `MeshPipelineKey` use some bits for two things
- First commit in this PR adds an assertion that doesn't work currently
on main
- This leads to some mesh topology not working anymore, for example
`LineStrip`
- With examples `lines`, there should be two groups of lines, the blue
one doesn't display currently
## Solution
- Change the `MeshPipelineKey` to be backed by a `u64` instead, to have
enough bits
# Objective
Fix#2128. Both `Query::new_archetype` and `SystemParam::new_archetype`
do not check if the `Archetype` comes from the same World the state is
initialized from. This could result in unsoundness via invalid accesses
if called incorrectly.
## Solution
Make them `unsafe` functions and lift the invariant to the caller. This
also caught one instance of us not validating the World in
`SystemState::update_archetypes_unsafe_world_cell`'s implementation.
---
## Changelog
Changed: `QueryState::new_archetype` is now an unsafe function.
Changed: `SystemParam::new_archetype` is now an unsafe function.
## Migration Guide
`QueryState::new_archetype` and `SystemParam::new_archetype` are now an
unsafe functions that must be sure that the provided `Archetype` is from
the same `World` that the state was initialized from. Callers may need
to add additional assertions or propagate the safety invariant upwards
through the callstack to ensure safety.
# Objective
- The docs says the WireframeColor is supposed to override the default
global color but it doesn't.
## Solution
- Use WireframeColor to override global color like docs said it was
supposed to do.
- Updated the example to document this feature
- I also took the opportunity to clean up the code a bit
Fixes#13032
# Objective
- Fixes#13024.
## Solution
- Run `cargo clippy --target wasm32-unknown-unknown` until there are no
more errors.
- I recommend reviewing one commit at a time :)
---
## Changelog
- Fixed Clippy lints for `wasm32-unknown-unknown` target.
- Updated `bevy_transform`'s `README.md`.
# Objective
- Closes#12930.
## Solution
- Add a corresponding optional field on `Window` and `ExtractedWindow`
---
## Changelog
### Added
- `wgpu`'s `desired_maximum_frame_latency` is exposed through window
creation. This can be used to override the default maximum number of
queued frames on the GPU (currently 2).
## Migration Guide
- The `desired_maximum_frame_latency` field must be added to instances
of `Window` and `ExtractedWindow` where all fields are explicitly
specified.
# Objective
Sometimes when despawning a ui node in the PostUpdate schedule it
panics. This is because both a despawn command and insert command are
being run on the same entity.
See this example code:
```rs
use bevy::{prelude::*, ui::UiSystem};
#[derive(Resource)]
struct SliceSquare(Handle<Image>);
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, create_ui)
.add_systems(PostUpdate, despawn_nine_slice.after(UiSystem::Layout))
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2dBundle::default());
commands.insert_resource(SliceSquare(asset_server.load("textures/slice_square.png")));
}
fn create_ui(mut commands: Commands, slice_square: Res<SliceSquare>) {
commands.spawn((
NodeBundle {
style: Style {
width: Val::Px(200.),
height: Val::Px(200.),
..default()
},
background_color: Color::WHITE.into(),
..default()
},
UiImage::new(slice_square.0.clone()),
ImageScaleMode::Sliced(TextureSlicer {
border: BorderRect::square(220.),
center_scale_mode: SliceScaleMode::Stretch,
sides_scale_mode: SliceScaleMode::Stretch,
max_corner_scale: 1.,
}),
));
}
fn despawn_nine_slice(mut commands: Commands, mut slices: Query<Entity, With<ImageScaleMode>>) {
for entity in slices.iter_mut() {
commands.entity(entity).despawn_recursive();
}
}
```
This code spawns a UiNode with a sliced image scale mode, and despawns
it in the same frame. The
bevy_ui::texture_slice::compute_slices_on_image_change system tries to
insert the ComputedTextureSlices component on that node, but that entity
is already despawned causing this error:
```md
error[B0003]: Could not insert a bundle (of type `bevy_ui::texture_slice::ComputedTextureSlices`) for entity Entity { index: 2, generation: 3 } because it doesn't
exist in this World. See: https://bevyengine.org/learn/errors/#b0003
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic when applying buffers for system `bevy_ui::texture_slice::compute_slices_on_image_change`!
Encountered a panic in system `bevy_ecs::schedule::executor::apply_deferred`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
```
Note that you might have to run the code a few times before this error
appears.
## Solution
Use try_insert instead of insert for non critical inserts in the bevy_ui
crate.
## Some notes
In a lot of cases it does not makes much sense to despawn ui nodes after
the layout system has finished. Except maybe if you delete the root ui
node of a tree. I personally encountered this issue in bevy `0.13.2`
with a system that was running before the layout system. And in `0.13.2`
the `compute_slices_on_image_change` system was also running before the
layout system. But now it runs after the layout system. So the only way
that this bug appears now is if you despawn ui nodes after the layout
system. So I am not 100% sure if using try_insert in this system is the
best option. But personally I still think it is better then the program
panicking.
However the `update_children_target_camera` system does still run before
the layout system. So I do think it might still be able to panic when ui
nodes are despawned before the layout system. Though I haven't been able
to verify that.
# Objective
- General clenup of the primitives in `bevy_math`
- Add `eccentricity()` to `Ellipse`
## Solution
- Moved `Bounded3d` implementation for `Triangle3d` to the `bounded`
module
- Added `eccentricity()` to `Ellipse`
- `Ellipse::semi_major()` and `::semi_minor()` now accept `&self`
instead of `self`
- `Triangle3d::is_degenerate()` actually uses `f32::EPSILON` as
documented
- Added tests for `Triangle3d`-maths
---------
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
Co-authored-by: Miles Silberling-Cook <nth.tensor@gmail.com>
# Objective
Make visibility system ordering explicit. Fixes#12953.
## Solution
Specify `CheckVisibility` happens after all other `VisibilitySystems`
sets have happened.
---------
Co-authored-by: Elabajaba <Elabajaba@users.noreply.github.com>
# Objective
Missing docs
## Solution
Add docs paraphrased from the Cart's mouth:
https://discord.com/channels/691052431525675048/691052431974465548/1172305792154738759
> It follows the natural "results" of right handed y-up. The default
camera will face "forward" in -Z, with +X being "right". The RH y-up
setup is reasonably common. Thats why I asked for existing examples.I
think we should appeal to the masses here / see how other RH Y-up 3D
packages / engines handle this
---------
Co-authored-by: Robert Swain <robert.swain@gmail.com>
# Objective
When trying to be generic over `Material + Default`, the lack of a
`Default` impl for `ExtendedMaterial`, even when both of its components
implement `Default`, is problematic. I think was probably just
overlooked.
## Solution
Impl `Default` if the material and extension both impl `Default`.
---
## Changelog
## Migration Guide
# Objective
Related to #12981
Presently, there is a footgun where we allow non-normalized vectors to
be passed in the `axis` parameters of `Transform::rotate_axis` and
`Transform::rotate_local_axis`. These methods invoke
`Quat::from_axis_angle` which expects the vector to be normalized. This
PR aims to address this.
## Solution
Require `Dir3`-valued `axis` parameters for these functions so that the
vector's normalization can be enforced at type-level.
---
## Migration Guide
All calls to `Transform::rotate_axis` and `Transform::rotate_local_axis`
will need to be updated to use a `Dir3` for the `axis` parameter rather
than a `Vec3`. For a general input, this means calling `Dir3::new` and
handling the `Result`, but if the previous vector is already known to be
normalized, `Dir3::new_unchecked` can be called instead. Note that
literals like `Vec3::X` also have corresponding `Dir3` literals; e.g.
`Dir3::X`, `Dir3::NEG_Y` and so on.
---
## Discussion
This axis input is unambigiously a direction instead of a vector, and
that should probably be reflected and enforced by the function
signature. In previous cases where we used, e.g., `impl TryInto<Dir3>`,
the associated methods already implemented (and required!) additional
fall-back logic, since the input is conceptually more complicated than
merely specifying an axis. In this case, I think it's fairly
cut-and-dry, and I'm pretty sure these methods just predate our
direction types.
# Objective
As described in #12467, Bevy does not have any spans for any of the
tasks scheduled onto the IO and async compute task pools.
## Solution
Instrument all asset loads and asset processing. Since this change is
restricted to asset tasks, it does not completely solve #12467, but it
does mean we can record the asset path in the trace.
![image](https://github.com/bevyengine/bevy/assets/8494645/59faee63-1f69-40af-bf47-312c4d67d1e2)
---
## Changelog
Tracing will now include spans for asset loading and asset processing.
glTF files that contain lights currently panic when loaded into Bevy,
because Bevy tries to reflect on `Cascades`, which accidentally wasn't
registered.
`EntityHashSet` doesn't seem to implement `Reflect` which seems weird!
Especially since `EntityHashMap` implements `Reflect`.
This PR just added an extra `impl_reflect_value!` for `EntityHashSet`
and this seems to do the trick.
I left out doing the same for `StableHashSet` since it's marked as
deprecated.
---
I'm really wondering what was the issue here. If anyone can explain why
`EntityHashSet` can't use the `Reflect` impl of `bevy_utils::HashSet`
similar to how it's the case with the `...HashMap`s I'd be interested!
# Objective
- Fixes#12976
## Solution
This one is a doozy.
- Run `cargo +beta clippy --workspace --all-targets --all-features` and
fix all issues
- This includes:
- Moving inner attributes to be outer attributes, when the item in
question has both inner and outer attributes
- Use `ptr::from_ref` in more scenarios
- Extend the valid idents list used by `clippy:doc_markdown` with more
names
- Use `Clone::clone_from` when possible
- Remove redundant `ron` import
- Add backticks to **so many** identifiers and items
- I'm sorry whoever has to review this
---
## Changelog
- Added links to more identifiers in documentation.
# Objective
Improve the code quality of the multithreaded executor.
## Solution
* Remove some unused variables.
* Use `Mutex::get_mut` where applicable instead of locking.
* Use a `startup_systems` FixedBitset to pre-compute the starting
systems instead of building it bit-by-bit on startup.
* Instead of using `FixedBitset::clear` and `FixedBitset::union_with`,
use `FixedBitset::clone_from` instead, which does only a single copy and
will not allocate if the target bitset has a large enough allocation.
* Replace the `Mutex` around `Conditions` with `SyncUnsafeCell`, and add
a `Context::try_lock` that forces it to be synchronized fetched
alongside the executor lock.
This might produce minimal performance gains, but the focus here is on
the code quality improvements.
# Objective
Fixes#12408 .
Fixes#12680.
## Solution
- Recaclulated anchor from dimensions of sprite to dimension of each
part of it (each part contains its own anchor)
[Alpha to coverage] (A2C) replaces alpha blending with a
hardware-specific multisample coverage mask when multisample
antialiasing is in use. It's a simple form of [order-independent
transparency] that relies on MSAA. ["Anti-aliased Alpha Test: The
Esoteric Alpha To Coverage"] is a good summary of the motivation for and
best practices relating to A2C.
This commit implements alpha to coverage support as a new variant for
`AlphaMode`. You can supply `AlphaMode::AlphaToCoverage` as the
`alpha_mode` field in `StandardMaterial` to use it. When in use, the
standard material shader automatically applies the texture filtering
method from ["Anti-aliased Alpha Test: The Esoteric Alpha To Coverage"].
Objects with alpha-to-coverage materials are binned in the opaque pass,
as they're fully order-independent.
The `transparency_3d` example has been updated to feature an object with
alpha to coverage. Happily, the example was already using MSAA.
This is part of #2223, as far as I can tell.
[Alpha to coverage]: https://en.wikipedia.org/wiki/Alpha_to_coverage
[order-independent transparency]:
https://en.wikipedia.org/wiki/Order-independent_transparency
["Anti-aliased Alpha Test: The Esoteric Alpha To Coverage"]:
https://bgolus.medium.com/anti-aliased-alpha-test-the-esoteric-alpha-to-coverage-8b177335ae4f
---
## Changelog
### Added
* The `AlphaMode` enum now supports `AlphaToCoverage`, to provide
limited order-independent transparency when multisample antialiasing is
in use.
# Objective
- ~~This PR adds more flexible versions of `set_if_neq` and
`replace_if_neq` to only compare and update certain fields of a
components which is not just a newtype~~
- https://github.com/bevyengine/bevy/pull/12919#issuecomment-2048049786
gave a good solution to the original problem, so let's update the docs
so that this is easier to find
## Solution
- ~~Add `set_if_neq_with` and `replace_if_neq_with` which take an
accessor closure to access the relevant field~~
---
In a recent project, a scenario emerged that required careful
consideration regarding change detection without compromising
performance. The context involves a component that maintains a
collection of `Vec<Vec2>` representing a horizontal surface, alongside a
height field. When the height is updated, there are a few approaches to
consider:
1. Clone the collection of points to utilize the existing `set_if_neq`
method.
2. Inline and adjust the `set_if_neq` code specifically for this
scenario.
3. (Consider splitting the component into more granular components.)
It's worth noting that the third option might be the most suitable in
most cases.
A similar situation arises with the Bevy internal Transform component,
which includes fields for translation, rotation, and scale. These fields
are relatively small (`Vec3` or `Quat` with 3 or 4 `f32` values), but
the creation of a single pointer (`usize`) might be more efficient than
copying the data of the other fields. This is speculative, and insights
from others could be valuable.
Questions remain:
- Is it feasible to develop a more flexible API, and what might that
entail?
- Is there general interest in this change?
There's no hard feelings if this idea or the PR is ultimately rejected.
I just wanted to put this idea out there and hope that this might be
beneficial to others and that feedback could be valuable before
abandoning the idea.
# Objective
- `cargo run --release --example bevymark -- --benchmark --waves 160
--per-wave 1000 --mode mesh2d` runs slower and slower over time due to
`no_gpu_preprocessing::write_batched_instance_buffer<bevy_sprite::mesh2d::mesh::Mesh2dPipeline>`
taking longer and longer because the `BatchedInstanceBuffer` is not
cleared
## Solution
- Split the `clear_batched_instance_buffers` system into CPU and GPU
versions
- Use the CPU version for 2D meshes
# Objective
Fixes a crash when transcoding one- or two-channel KTX2 textures
## Solution
transcoded array has been pre-allocated up to levels.len using a macros.
Rgb8 transcoding already uses that and addresses transcoded array by an
index. R8UnormSrgb and Rg8UnormSrgb were pushing on top of the
transcoded vec, resulting in first levels.len() vectors to stay empty,
and second levels.len() levels actually being transcoded, which then
resulted in out of bounds read when copying levels to gpu
# Objective
- `cargo check --workspace` appears to merge features and dependencies
together, so it does not catch some issues where dependencies are not
properly feature-gated.
- The issues **are** caught, though, by running `cd $crate && cargo
check`.
## Solution
- Manually check each crate for issues.
```shell
# Script used
for i in crates/bevy_* do
pushd $i
cargo check
popd
done
```
- `bevy_color` had an issue where it used `#[derive(Pod, Zeroable)]`
without using `bytemuck`'s `derive` feature.
- The `FpsOverlayPlugin` in `bevy_dev_tools` uses `bevy_ui`'s
`bevy_text` integration without properly enabling `bevy_text` as a
feature.
- `bevy_gizmos`'s `light` module was not properly feature-gated behind
`bevy_pbr`.
- ~~Lights appear to only be implemented in `bevy_pbr` and not
`bevy_sprite`, so I think this is the right call. Can I get a
confirmation by a gizmos person?~~ Confirmed :)
- `bevy_gltf` imported `SmallVec`, but only used it if `bevy_animation`
was enabled.
- There was another issue, but it was more challenging to solve than the
`smallvec` one. Run `cargo check -p bevy_gltf` and it will raise an
issue about `animation_roots`.
<details>
<summary><code>bevy_gltf</code> errors</summary>
```shell
error[E0425]: cannot find value `animation_roots` in this scope
--> crates/bevy_gltf/src/loader.rs:608:26
|
608 | &animation_roots,
| ^^^^^^^^^^^^^^^ not found in this scope
warning: variable does not need to be mutable
--> crates/bevy_gltf/src/loader.rs:1015:5
|
1015 | mut animation_context: Option<AnimationContext>,
| ----^^^^^^^^^^^^^^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
For more information about this error, try `rustc --explain E0425`.
warning: `bevy_gltf` (lib) generated 1 warning
error: could not compile `bevy_gltf` (lib) due to 1 previous error; 1 warning emitted
```
</details>
---
## Changelog
- Fixed `bevy_color`, `bevy_dev_tools`, and `bevy_gizmos` so they can
now compile by themselves.
# Objective
i downloaded a random model from sketchfab
(https://sketchfab.com/3d-models/dragon-glass-fe00cb0ecaca4e4595874b70de7e116b)
to fiddle with bevy and encountered a panic when attempted to play
animations:
```
thread 'Compute Task Pool (3)' panicked at /home/username/code/bevy/crates/bevy_animation/src/lib.rs:848:58:
index out of bounds: the len is 40 but the index is 40
```
"Animation / Animated Fox"
(5caf085dac/examples/animation/animated_fox.rs)
example can be used for reproduction. to reproduce download a model from
sketchfab (link above) and load it instead of loading fox.glb, keep only
`dragon_glass.glb#Animation0` and remove `1` and `2` -> run and wait 1-2
seconds for crash to happen.
## Solution
correct keyframe indexing, i guess
`ExtractComponentPlugin` doesn't check to make sure the component is
actually present unless it's in the `QueryFilter`. This meant we placed
it everywhere. This regressed performance on many examples, such as
`many_cubes`.
Fixes#12956.
# Objective
The system task span is pretty consistent in how much time it uses, so
all it adds is overhead/additional bandwidth when profiling.
## Solution
Remove it.
`Sprite`, `Text`, and `Handle<MeshletMesh>` were types of renderable
entities that the new segregated visible entity system didn't handle, so
they didn't appear.
Because `bevy_text` depends on `bevy_sprite`, and the visibility
computation of text happens in the latter crate, I had to introduce a
new marker component, `SpriteSource`. `SpriteSource` marks entities that
aren't themselves sprites but become sprites during rendering. I added
this component to `Text2dBundle`. Unfortunately, this is technically a
breaking change, although I suspect it won't break anybody in practice
except perhaps editors.
Fixes#12935.
## Changelog
### Changed
* `Text2dBundle` now includes a new marker component, `SpriteSource`.
Bevy uses this internally to optimize visibility calculation.
## Migration Guide
* `Text` now requires a `SpriteSource` marker component in order to
appear. This component has been added to `Text2dBundle`.
# Objective
Improve performance scalability when adding new event types to a Bevy
app. Currently, just using Bevy in the default configuration, all apps
spend upwards of 100+us in the `First` schedule, every app tick,
evaluating if it should update events or not, even if events are not
being used for that particular frame, and this scales with the number of
Events registered in the app.
## Solution
As `Events::update` is guaranteed `O(1)` by just checking if a
resource's value, swapping two Vecs, and then clearing one of them, the
actual cost of running `event_update_system` is *very* cheap. The
overhead of doing system dependency injection, task scheduling ,and the
multithreaded executor outweighs the cost of running the system by a
large margin.
Create an `EventRegistry` resource that keeps a number of function
pointers that update each event. Replace the per-event type
`event_update_system` with a singular exclusive system uses the
`EventRegistry` to update all events instead. Update `SubApp::add_event`
to use `EventRegistry` instead.
## Performance
This speeds reduces the cost of the `First` schedule in both many_foxes
and many_cubes by over 80%. Note this is with system spans on. The
majority of this is now context-switching costs from launching
`time_system`, which should be mostly eliminated with #12869.
![image](https://github.com/bevyengine/bevy/assets/3137680/037624be-21a2-4dc2-a42f-9d0bfa3e9b4a)
The actual `event_update_system` is usually *very* short, using only a
few microseconds on average.
![image](https://github.com/bevyengine/bevy/assets/3137680/01ff1689-3595-49b6-8f09-5c44bcf903e8)
---
## Changelog
TODO
## Migration Guide
TODO
---------
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- I daily drive nightly Rust when developing Bevy, so I notice when new
warnings are raised by `cargo check` and Clippy.
- `cargo +nightly clippy` raises a few of these new warnings.
## Solution
- Fix most warnings from `cargo +nightly clippy`
- I skipped the docs-related warnings because some were covered by
#12692.
- Use `Clone::clone_from` in applicable scenarios, which can sometimes
avoid an extra allocation.
- Implement `Default` for structs that have a `pub const fn new() ->
Self` method.
- Fix an occurrence where generic constraints were defined in both `<C:
Trait>` and `where C: Trait`.
- Removed generic constraints that were implied by the `Bundle` trait.
---
## Changelog
- `BatchingStrategy`, `NonGenericTypeCell`, and `GenericTypeCell` now
implement `Default`.
This commit splits `VisibleEntities::entities` into four separate lists:
one for lights, one for 2D meshes, one for 3D meshes, and one for UI
elements. This allows `queue_material_meshes` and similar methods to
avoid examining entities that are obviously irrelevant. In particular,
this separation helps scenes with many skinned meshes, as the individual
bones are considered visible entities but have no rendered appearance.
Internally, `VisibleEntities::entities` is a `HashMap` from the `TypeId`
representing a `QueryFilter` to the appropriate `Entity` list. I had to
do this because `VisibleEntities` is located within an upstream crate
from the crates that provide lights (`bevy_pbr`) and 2D meshes
(`bevy_sprite`). As an added benefit, this setup allows apps to provide
their own types of renderable components, by simply adding a specialized
`check_visibility` to the schedule.
This provides a 16.23% end-to-end speedup on `many_foxes` with 10,000
foxes (24.06 ms/frame to 20.70 ms/frame).
## Migration guide
* `check_visibility` and `VisibleEntities` now store the four types of
renderable entities--2D meshes, 3D meshes, lights, and UI
elements--separately. If your custom rendering code examines
`VisibleEntities`, it will now need to specify which type of entity it's
interested in using the `WithMesh2d`, `WithMesh`, `WithLight`, and
`WithNode` types respectively. If your app introduces a new type of
renderable entity, you'll need to add an explicit call to
`check_visibility` to the schedule to accommodate your new component or
components.
## Analysis
`many_foxes`, 10,000 foxes: `main`:
![Screenshot 2024-03-31
114444](https://github.com/bevyengine/bevy/assets/157897/16ecb2ff-6e04-46c0-a4b0-b2fde2084bad)
`many_foxes`, 10,000 foxes, this branch:
![Screenshot 2024-03-31
114256](https://github.com/bevyengine/bevy/assets/157897/94dedae4-bd00-45b2-9aaf-dfc237004ddb)
`queue_material_meshes` (yellow = this branch, red = `main`):
![Screenshot 2024-03-31
114637](https://github.com/bevyengine/bevy/assets/157897/f90912bd-45bd-42c4-bd74-57d98a0f036e)
`queue_shadows` (yellow = this branch, red = `main`):
![Screenshot 2024-03-31
114607](https://github.com/bevyengine/bevy/assets/157897/6ce693e3-20c0-4234-8ec9-a6f191299e2d)
# Objective
-
[`clippy::ref_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#/ref_as_ptr)
prevents you from directly casting references to pointers, requiring you
to use `std::ptr::from_ref` instead. This prevents you from accidentally
converting an immutable reference into a mutable pointer (`&x as *mut
T`).
- Follow up to #11818, now that our [`rust-version` is
1.77](11817f4ba4/Cargo.toml (L14)).
## Solution
- Enable lint and fix all warnings.
I ported the two existing PCF techniques to the cubemap domain as best I
could. Generally, the technique is to create a 2D orthonormal basis
using Gram-Schmidt normalization, then apply the technique over that
basis. The results look fine, though the shadow bias often needs
adjusting.
For comparison, Unity uses a 4-tap pattern for PCF on point lights of
(1, 1, 1), (-1, -1, 1), (-1, 1, -1), (1, -1, -1). I tried this but
didn't like the look, so I went with the design above, which ports the
2D techniques to the 3D domain. There's surprisingly little material on
point light PCF.
I've gone through every example using point lights and verified that the
shadow maps look fine, adjusting biases as necessary.
Fixes#3628.
---
## Changelog
### Added
* Shadows from point lights now support percentage-closer filtering
(PCF), and as a result look less aliased.
### Changed
* `ShadowFilteringMethod::Castano13` and
`ShadowFilteringMethod::Jimenez14` have been renamed to
`ShadowFilteringMethod::Gaussian` and `ShadowFilteringMethod::Temporal`
respectively.
## Migration Guide
* `ShadowFilteringMethod::Castano13` and
`ShadowFilteringMethod::Jimenez14` have been renamed to
`ShadowFilteringMethod::Gaussian` and `ShadowFilteringMethod::Temporal`
respectively.
# Objective
Fixes#11996
The deprecated shape Quad's flip field role migrated to
StandardMaterial's flip/flipped methods
## Solution
flip/flipping methods of StandardMaterial is applicable to any mesh
---
## Changelog
- Added flip and flipped methods to the StandardMaterial implementation
- Added FLIP_HORIZONTAL, FLIP_VERTICAL, FLIP_X, FLIP_Y, FLIP_Z constants
## Migration Guide
Instead of using `Quad::flip` field, call `flipped(true, false)` method
on the StandardMaterial instance when adding the mesh.
---------
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
Currently, `MeshUniform`s are rather large: 160 bytes. They're also
somewhat expensive to compute, because they involve taking the inverse
of a 3x4 matrix. Finally, if a mesh is present in multiple views, that
mesh will have a separate `MeshUniform` for each and every view, which
is wasteful.
This commit fixes these issues by introducing the concept of a *mesh
input uniform* and adding a *mesh uniform building* compute shader pass.
The `MeshInputUniform` is simply the minimum amount of data needed for
the GPU to compute the full `MeshUniform`. Most of this data is just the
transform and is therefore only 64 bytes. `MeshInputUniform`s are
computed during the *extraction* phase, much like skins are today, in
order to avoid needlessly copying transforms around on CPU. (In fact,
the render app has been changed to only store the translation of each
mesh; it no longer cares about any other part of the transform, which is
stored only on the GPU and the main world.) Before rendering, the
`build_mesh_uniforms` pass runs to expand the `MeshInputUniform`s to the
full `MeshUniform`.
The mesh uniform building pass does the following, all on GPU:
1. Copy the appropriate fields of the `MeshInputUniform` to the
`MeshUniform` slot. If a single mesh is present in multiple views, this
effectively duplicates it into each view.
2. Compute the inverse transpose of the model transform, used for
transforming normals.
3. If applicable, copy the mesh's transform from the previous frame for
TAA. To support this, we double-buffer the `MeshInputUniform`s over two
frames and swap the buffers each frame. The `MeshInputUniform`s for the
current frame contain the index of that mesh's `MeshInputUniform` for
the previous frame.
This commit produces wins in virtually every CPU part of the pipeline:
`extract_meshes`, `queue_material_meshes`,
`batch_and_prepare_render_phase`, and especially
`write_batched_instance_buffer` are all faster. Shrinking the amount of
CPU data that has to be shuffled around speeds up the entire rendering
process.
| Benchmark | This branch | `main` | Speedup |
|------------------------|-------------|---------|---------|
| `many_cubes -nfc` | 17.259 | 24.529 | 42.12% |
| `many_cubes -nfc -vpi` | 302.116 | 312.123 | 3.31% |
| `many_foxes` | 3.227 | 3.515 | 8.92% |
Because mesh uniform building requires compute shader, and WebGL 2 has
no compute shader, the existing CPU mesh uniform building code has been
left as-is. Many types now have both CPU mesh uniform building and GPU
mesh uniform building modes. Developers can opt into the old CPU mesh
uniform building by setting the `use_gpu_uniform_builder` option on
`PbrPlugin` to `false`.
Below are graphs of the CPU portions of `many-cubes
--no-frustum-culling`. Yellow is this branch, red is `main`.
`extract_meshes`:
![Screenshot 2024-04-02
124842](https://github.com/bevyengine/bevy/assets/157897/a6748ea4-dd05-47b6-9254-45d07d33cb10)
It's notable that we get a small win even though we're now writing to a
GPU buffer.
`queue_material_meshes`:
![Screenshot 2024-04-02
124911](https://github.com/bevyengine/bevy/assets/157897/ecb44d78-65dc-448d-ba85-2de91aa2ad94)
There's a bit of a regression here; not sure what's causing it. In any
case it's very outweighed by the other gains.
`batch_and_prepare_render_phase`:
![Screenshot 2024-04-02
125123](https://github.com/bevyengine/bevy/assets/157897/4e20fc86-f9dd-4e5c-8623-837e4258f435)
There's a huge win here, enough to make batching basically drop off the
profile.
`write_batched_instance_buffer`:
![Screenshot 2024-04-02
125237](https://github.com/bevyengine/bevy/assets/157897/401a5c32-9dc1-4991-996d-eb1cac6014b2)
There's a massive improvement here, as expected. Note that a lot of it
simply comes from the fact that `MeshInputUniform` is `Pod`. (This isn't
a maintainability problem in my view because `MeshInputUniform` is so
simple: just 16 tightly-packed words.)
## Changelog
### Added
* Per-mesh instance data is now generated on GPU with a compute shader
instead of CPU, resulting in rendering performance improvements on
platforms where compute shaders are supported.
## Migration guide
* Custom render phases now need multiple systems beyond just
`batch_and_prepare_render_phase`. Code that was previously creating
custom render phases should now add a `BinnedRenderPhasePlugin` or
`SortedRenderPhasePlugin` as appropriate instead of directly adding
`batch_and_prepare_render_phase`.
# Objective
- Fixes#12905.
## Solution
- Use proper code `` tags for `TaskPoolBuilder::thread_name`.
- Remove leftover documentation in `TaskPool` referencing the deleted
`TaskPoolInner` struct.
- It may be possible to rephrase this, but I do not know enough about
the task pool to write something. (cc @james7132 who made the change
removing `TaskPoolInner`.)
- Ignore a buggy rustdoc lint that thinks `App` is already in scope for
`UpdateMode` doc. (Extracted from #12692.)
# Objective
- All gizmos APIs besides `gizmos.primitive_3d` use `impl Into<Color>`
as their type for `color`.
## Solution
- This PR changes `primitive_3d()` to use `impl Into<Color>` aswell.
# Objective
- Replace `RenderMaterials` / `RenderMaterials2d` / `RenderUiMaterials`
with `RenderAssets` to enable implementing changes to one thing,
`RenderAssets`, that applies to all use cases rather than duplicating
changes everywhere for multiple things that should be one thing.
- Adopts #8149
## Solution
- Make RenderAsset generic over the destination type rather than the
source type as in #8149
- Use `RenderAssets<PreparedMaterial<M>>` etc for render materials
---
## Changelog
- Changed:
- The `RenderAsset` trait is now implemented on the destination type.
Its `SourceAsset` associated type refers to the type of the source
asset.
- `RenderMaterials`, `RenderMaterials2d`, and `RenderUiMaterials` have
been replaced by `RenderAssets<PreparedMaterial<M>>` and similar.
## Migration Guide
- `RenderAsset` is now implemented for the destination type rather that
the source asset type. The source asset type is now the `RenderAsset`
trait's `SourceAsset` associated type.
# Objective
- Ongoing work for #10572
- Implement the `Meshable` trait for `Triangle3d`, allowing 3d triangle
primitives to produce meshes.
## Solution
The `Meshable` trait for `Triangle3d` directly produces a `Mesh`, much
like that of `Triangle2d`. The mesh consists only of a single triangle
(the triangle itself), and its vertex data consists of:
- Vertex positions, which are the triangle's vertices themselves (i.e.
the triangle provides its own coordinates in mesh space directly)
- Normals, which are all the normal of the triangle itself
- Indices, which are directly inferred from the vertex order (note that
this is slightly different than `Triangle2d` which, because of its lower
dimension, has an orientation which can be corrected for so that it
always faces "the right way")
- UV coordinates, which are produced as follows:
1. The first coordinate is coincident with the `ab` direction of the
triangle.
2. The second coordinate maps to be perpendicular to the first in mesh
space, so that the UV-mapping is skew-free.
3. The UV-coordinates map to the smallest rectangle possible containing
the triangle, given the preceding constraints.
Here is a visual demonstration; here, the `ab` direction of the triangle
is horizontal, left to right — the point `c` moves, expanding the
bounding rectangle of the triangle when it pushes past `a` or `b`:
<img width="1440" alt="Screenshot 2024-03-23 at 5 36 01 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/bef4d786-7b82-4207-abd4-ac4557d0f8b8">
<img width="1440" alt="Screenshot 2024-03-23 at 5 38 12 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/c0f72b8f-8e70-46fa-a750-2041ba6dfb78">
<img width="1440" alt="Screenshot 2024-03-23 at 5 37 15 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/db287e4f-2b0b-4fd4-8d71-88f4e7a03b7c">
The UV-mapping of `Triangle2d` has also been changed to use the same
logic.
---
## Changelog
- Implemented `Meshable` for `Triangle3d`.
- Changed UV-mapping of `Triangle2d` to match that of `Triangle3d`.
## Migration Guide
The UV-mapping of `Triangle2d` has changed with this PR; the main
difference is that the UVs are no longer dependent on the triangle's
absolute coordinates, but instead follow translations of the triangle
itself in its definition. If you depended on the old UV-coordinates for
`Triangle2d`, then you will have to update affected areas to use the new
ones which, briefly, can be described as follows:
- The first coordinate is parallel to the line between the first two
vertices of the triangle.
- The second coordinate is orthogonal to this, pointing in the direction
of the third point.
Generally speaking, this means that the first two points will have
coordinates `[_, 0.]`, while the third coordinate will be `[_, 1.]`,
with the exact values depending on the position of the third point
relative to the first two. For acute triangles, the first two vertices
always have UV-coordinates `[0., 0.]` and `[1., 0.]` respectively. For
obtuse triangles, the third point will have coordinate `[0., 1.]` or
`[1., 1.]`, with the coordinate of one of the two other points shifting
to maintain proportionality.
For example:
- The default `Triangle2d` has UV-coordinates `[0., 0.]`, `[0., 1.]`,
[`0.5, 1.]`.
- The triangle with vertices `vec2(0., 0.)`, `vec2(1., 0.)`, `vec2(2.,
1.)` has UV-coordinates `[0., 0.]`, `[0.5, 0.]`, `[1., 1.]`.
- The triangle with vertices `vec2(0., 0.)`, `vec2(1., 0.)`, `vec2(-2.,
1.)` has UV-coordinates `[2./3., 0.]`, `[1., 0.]`, `[0., 1.]`.
## Discussion
### Design considerations
1. There are a number of ways to UV-map a triangle (at least two of
which are fairly natural); for instance, we could instead declare the
second axis to be essentially `bc` so that the vertices are always `[0.,
0.]`, `[0., 1.]`, and `[1., 0.]`. I chose this method instead because it
is skew-free, so that the sampling from textures has only bilinear
scaling. I think this is better for cases where a relatively "uniform"
texture is mapped to the triangle, but it's possible that we might want
to support the other thing in the future. Thankfully, we already have
the capability of easily expanding to do that with Builders if the need
arises. This could also allow us to provide things like barycentric
subdivision.
2. Presently, the mesh-creation code for `Triangle3d` is set up to never
fail, even in the case that the triangle is degenerate. I have mixed
feelings about this, but none of our other primitive meshes fail, so I
decided to take the same approach. Maybe this is something that could be
worth revisiting in the future across the board.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Jakub Marcowski <37378746+Chubercik@users.noreply.github.com>
# Objective
Minimize the number of dependencies low in the tree.
## Solution
* Remove the dependency on rustc-hash in bevy_ecs (not used) and
bevy_macro_utils (only used in one spot).
* Deduplicate the dependency on `sha1_smol` with the existing blake3
dependency already being used for bevy_asset.
* Remove the unused `ron` dependency on `bevy_app`
* Make the `serde` dependency for `bevy_ecs` optional. It's only used
for serializing Entity.
* Change the `wgpu` dependency to `wgpu-types`, and make it optional for
`bevy_color`.
* Remove the unused `thread-local` dependency on `bevy_render`.
* Make multiple dependencies for `bevy_tasks` optional and enabled only
when running with the `multi-threaded` feature. Preferably they'd be
disabled all the time on wasm, but I couldn't find a clean way to do
this.
---
## Changelog
TODO
## Migration Guide
TODO
Fixed a bug where skybox ddsfile would crash from wgpu while trying to
read past the file buffer.
Added a unit-test to prevent regression.
Bumped ddsfile dependency version to 0.5.2
# Objective
Prevents a crash when loading dds skybox.
## Solution
ddsfile already automatically sets array layers to be 6 for skyboxes.
Removed bevy's extra *= 6 multiplication.
---
This is a copy of
[#12598](https://github.com/bevyengine/bevy/pull/12598) ... I made that
one off of main and wasn't able to make more pull requests without
making a new branch.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
- Fix a potential out-of-bounds access in the `pbr_functions.wgsl`
shader.
## Solution
- Correctly compute the `GpuLights::directional_lights` array length.
## Comments
I think this solves this comment in the code, but need someone to test
it:
```rust
//NOTE: When running bevy on Adreno GPU chipsets in WebGL, any value above 1 will result in a crash
// when loading the wgsl "pbr_functions.wgsl" in the function apply_fog.
```
# Objective
- Attempts to solve two items from
https://github.com/bevyengine/bevy/issues/11478.
## Solution
- Moved `intern` module from `bevy_utils` into `bevy_ecs` crate and
updated all relevant imports.
- Moved `label` module from `bevy_utils` into `bevy_ecs` crate and
updated all relevant imports.
---
## Migration Guide
- Replace `bevy_utils::define_label` imports with
`bevy_ecs::define_label` imports.
- Replace `bevy_utils:🏷️:DynEq` imports with
`bevy_ecs:🏷️:DynEq` imports.
- Replace `bevy_utils:🏷️:DynHash` imports with
`bevy_ecs:🏷️:DynHash` imports.
- Replace `bevy_utils::intern::Interned` imports with
`bevy_ecs::intern::Interned` imports.
- Replace `bevy_utils::intern::Internable` imports with
`bevy_ecs::intern::Internable` imports.
- Replace `bevy_utils::intern::Interner` imports with
`bevy_ecs::intern::Interner` imports.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
- Make `ReflectComponent::apply`, `ReflectComponent::reflect_mut` and
`ReflectBundle::apply` work with `EntityMut` too (currently they only
work with the more restricting `EntityWorldMut`);
- Note: support for the `Filtered*` variants has been left out since the
conversion in that case is more expensive. Let me know if I should add
support for them too.
## Solution
- Make `ReflectComponent::apply`, `ReflectComponent::reflect_mut` and
`ReflectBundle::apply` take an `impl Into<EntityMut<'a>>`;
- Make the corresponding `*Fns` function pointers take a `EntityMut`.
---
## Changelog
- `ReflectComponent::apply`, `ReflectComponent::reflect_mut` and
`ReflectBundle::apply` now accept `EntityMut` as well
## Migration Guide
- `ReflectComponentFns`'s `apply` and `reflect_mut` fields now take
`EntityMut` instead of `&mut EntityWorldMut`
- `ReflectBundleFns`'s `apply` field now takes `EntityMut` instead of
`&mut EntityWorldMut`
# Objective
- Upload previous frame's inverse_view matrix to the GPU for use with
https://github.com/bevyengine/bevy/pull/12898.
---
## Changelog
- Added `prepass_bindings::previous_view_uniforms.inverse_view`.
- Renamed `prepass_bindings::previous_view_proj` to
`prepass_bindings::previous_view_uniforms.view_proj`.
- Renamed `PreviousViewProjectionUniformOffset` to
`PreviousViewUniformOffset`.
- Renamed `PreviousViewProjection` to `PreviousViewData`.
## Migration Guide
- Renamed `prepass_bindings::previous_view_proj` to
`prepass_bindings::previous_view_uniforms.view_proj`.
- Renamed `PreviousViewProjectionUniformOffset` to
`PreviousViewUniformOffset`.
- Renamed `PreviousViewProjection` to `PreviousViewData`.
# Objective
make morph targets and tonemapping more tolerant of delayed image
loading.
neither of these actually fail currently unless using a bespoke loader
(and even then it would be rare), but i am working on adding throttling
for asset gpu uploads (as a stopgap until we can do proper asset
streaming) and they break with that.
## Solution
when a mesh with morph targets is uploaded to the gpu, the prepare
function uploads the morph target texture if it's available, otherwise
it uploads without morph targets. this is generally fine as long as
morph targets are typically loaded from bytes (in gltf loader), but may
fail for a custom loader if the asset server async-loads the target
texture and the texture is not available yet. the mesh fails to render
and doesn't update when the image is loaded
-> if morph targets are specified but not ready yet, retry mesh upload
next frame
tonemapping `unwrap`s on the lookup table image. this is never a problem
since the image is added via `include_bytes!`, but could be a problem in
future with asset gpu throttling/streaming.
-> if the lookup texture is not yet available, use a fallback
-> in the node, check if the fallback was used before caching the bind
group
# Objective
- Implement `From<&'w mut EntityMut>` for `EntityMut<'w>`;
- Make it possible to pass `&mut EntityMut` where `impl Into<EntityMut>`
is required;
- Helps with #12895.
## Solution
- Implement `From<&'w mut EntityMut>` for `EntityMut<'w>`
---
## Changelog
- `EntityMut<'w>` now implements `From<&'w mut EntityMut>`
# Objective
- When viewport is set to the same size as the window on creation, when
adjusting to SizedFullscreen, the window may be smaller than the
viewport for a moment, which caused the arguments to be invalid and
panic.
- Fixes#12000.
## Solution
- The fix consists of matching the size of the viewport to the lower
size of the window ( if the x value of the window is lower, I update
only the x value of the viewport, same for the y value). Also added a
test to show that it does not panic anymore.
---
# Objective
- #12791 broke example `irradiance_volumes`
- Fixes#12876
```
wgpu error: Validation Error
Caused by:
In Device::create_render_pipeline
note: label = `pbr_opaque_mesh_pipeline`
Color state [0] is invalid
Sample count 8 is not supported by format Rgba8UnormSrgb on this device. The WebGPU spec guarentees [1, 4] samples are supported by this format. With the TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES feature your device supports [1, 2, 4].
```
## Solution
- Shift bits a bit more
# Objective
- Add a way to easily get currently waiting pipelines IDs.
## Solution
- Added a method to get waiting pipelines `CachedPipelineId`.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
Since BufferVec was first introduced, `bytemuck` has added additional
traits with fewer restrictions than `Pod`. Within BufferVec, we only
rely on the constraints of `bytemuck::cast_slice` to a `u8` slice, which
now only requires `T: NoUninit` which is a strict superset of `Pod`
types.
## Solution
Change out the `Pod` generic type constraint with `NoUninit`. Also
taking the opportunity to substitute `cast_slice` with
`must_cast_slice`, which avoids a runtime panic in place of a compile
time failure if `T` cannot be used.
---
## Changelog
Changed: `BufferVec` now supports working with types containing
`NoUninit` but not `Pod` members.
Changed: `BufferVec` will now fail to compile if used with a type that
cannot be safely read from. Most notably, this includes ZSTs, which
would previously always panic at runtime.
# Objective
Augment Bevy's random sampling capabilities by providing good tools for
producing random directions and rotations.
## Solution
The `rand` crate has a natural tool for providing `Distribution`s whose
output is a type that doesn't require any additional data to sample
values — namely,
[`Standard`](https://docs.rs/rand/latest/rand/distributions/struct.Standard.html).
Here, our existing `ShapeSample` implementations have been put to good
use in providing these, resulting in patterns like the following:
```rust
// Using thread-local rng
let random_direction1: Dir3 = random();
// Using an explicit rng
let random_direction2: Dir3 = rng.gen();
// Using an explicit rng coupled explicitly with Standard
let random_directions: Vec<Dir3> = rng.sample_iter(Standard).take(5).collect();
```
Furthermore, we have introduced a trait `FromRng` which provides sugar
for `rng.gen()` that is more namespace-friendly (in this author's
opinion):
```rust
let random_direction = Dir3::from_rng(rng);
```
The types this has been implemented for are `Dir2`, `Dir3`, `Dir3A`, and
`Quat`. Notably, `Quat` uses `glam`'s implementation rather than an
in-house one, and as a result, `bevy_math`'s "rand" feature now enables
that of `glam`.
---
## Changelog
- Created `standard` submodule in `sampling` to hold implementations and
other items related to the `Standard` distribution.
- "rand" feature of `bevy_math` now enables that of `glam`.
---
## Discussion
From a quick glance at `Quat`'s distribution implementation in `glam`, I
am a bit suspicious, since it is simple and doesn't match any algorithm
that I came across in my research. I will do a little more digging as a
follow-up to this and see if it's actually uniform (maybe even using
those tools I wrote — what a thrill).
As an aside, I'd also like to say that I think
[`Distribution`](https://docs.rs/rand/latest/rand/distributions/trait.Distribution.html)
is really, really good. It integrates with distributions provided
externally (e.g. in `rand` itself and its extensions) along with doing a
good job of isolating the source of randomness, so that output can be
reliably reproduced if need be. Finally, `Distribution::sample_iter` is
quite good for ergonomically acquiring lots of random values. At one
point I found myself writing traits to describe random sampling and
essentially reinvented this one. I just think it's good, and I think
it's worth centralizing around to a significant extent.
# Objective
See https://github.com/gfx-rs/wgpu/issues/5488 for context and
rationale.
## Solution
- Disables `wgpu::Features::RAY_QUERY` and
`wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE` by default. They
must be explicitly opted into now.
---
## Changelog
- Disables `wgpu::Features::RAY_QUERY` and
`wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE` by default. They
must be explicitly opted into now.
## Migration Guide
- If you need `wgpu::Features::RAY_QUERY` or
`wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE`, enable them
explicitly using `WgpuSettings::features`
# Objective
- Fix#7303
- bevy would spawn a lot of tasks in parallel iteration when it matchs a
large storage and many small storage ,it significantly increase the
overhead of schedule.
## Solution
- collect small storage into one task
# Objective
Fix#11931
## Solution
- Make stepping a non-default feature
- Adjust documentation and examples
- In particular, make the breakout example not show the stepping prompt
if compiled without the feature (shows a log message instead)
---
## Changelog
- Removed `bevy_debug_stepping` from default features
## Migration Guide
The system-by-system stepping feature is now disabled by default; to use
it, enable the `bevy_debug_stepping` feature explicitly:
```toml
[dependencies]
bevy = { version = "0.14", features = ["bevy_debug_stepping"] }
```
Code using
[`Stepping`](https://docs.rs/bevy/latest/bevy/ecs/schedule/struct.Stepping.html)
will still compile with the feature disabled, but will print a runtime
error message to the console if the application attempts to enable
stepping.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
A help thread on discord asked how to use signed URLs for assets. This
currently fails because the query parameters are included in the
extension, which causes no suitable loader to be found:
```
Failed to load asset 'http://localhost:4566/dev/1711921849174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject' with asset loader 'bevy_render::texture::image_loader::ImageLoader':
Could not load texture file: Error reading image file localhost:4566/dev/1711921849174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject: invalid image extension: jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject, this is an error in `bevy_render`.
```
## Solution
Make `get_full_extension` remove everything after the first `?`
character.
If this is accepted then it should also be documented in `AssetPath`
that extensions cannot include question marks.
An alternative is to special case this handling only for wasm, but that
would be annoying for the
[bevy_web_asset](https://github.com/johanhelsing/bevy_web_asset) plugin,
and in my opinion also just more confusing overall.
# Objective
- Remove `close_on_esc`
- For context about why we are removing it see:
[discord](https://discordapp.com/channels/691052431525675048/692572690833473578/1225075194524073985)
## Migration Guide
- Users who added `close_on_esc` in their application will have to
replace it with their own solution.
```rust
pub fn close_on_esc(
mut commands: Commands,
focused_windows: Query<(Entity, &Window)>,
input: Res<ButtonInput<KeyCode>>,
) {
for (window, focus) in focused_windows.iter() {
if !focus.focused {
continue;
}
if input.just_pressed(KeyCode::Escape) {
commands.entity(window).despawn();
}
}
}
```
# Objective
- Add `remove_by_id` method to `EntityWorldMut` and `EntityCommands`
- This is a duplicate of the awesome work by @mateuseap, last updated
04/09/23 - #9663
- I'm opening a second one to ensure the feature makes it into `0.14`
- Fixes#9261
## Solution
Almost identical to #9663 with three exceptions
- Uses a closure instead of struct for commands, consistent with other
similar commands
- Does not refactor `EntityCommands::insert`, so no migration guide
- `EntityWorldMut::remove_by_id` is now safe containing unsafe blocks, I
think thats what @SkiFire13 was indicating should happen [in this
comment](https://github.com/bevyengine/bevy/pull/9663#discussion_r1314307525)
## Changelog
- Added `EntityWorldMut::remove_by_id` method and its tests.
- Added `EntityCommands::remove_by_id` method and its tests.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
- Closes#12019
- Related to #4955
- Useful for dev_tools and networking
## Solution
- Create `World::iter_resources()` and `World::iter_resources_mut()`
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
Just updating docs for the arc gizmo so that the argument documentation
matches the order of the function arguments.
Also added docs for the color argument.
# Objective
- Improve docs
## Solution
- Moved the radius argument to the end of the argument list to match the
function
---
## Changelog
> N/A
## Migration Guide
> N/A
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
- As @james7132 said [on
Discord](https://discord.com/channels/691052431525675048/692572690833473578/1224626740773523536),
the `close_on_esc` system is forcing `bevy_window` to depend on
`bevy_input`.
- `close_on_esc` is not likely to be used in production, so it arguably
does not have a place in `bevy_window`.
## Solution
- As suggested by @afonsolage, move `close_on_esc` into
`bevy_dev_tools`.
- Add an example to the documentation too.
- Remove `bevy_window`'s dependency on `bevy_input`.
- Add `bevy_reflect`'s `smol_str` feature to `bevy_window` because it
was implicitly depended upon with `bevy_input` before it was removed.
- Remove any usage of `close_on_esc` from the examples.
- `bevy_dev_tools` is not enabled by default. I personally find it
frustrating to run examples with additional features, so I opted to
remove it entirely.
- This is up for discussion if you have an alternate solution.
---
## Changelog
- Moved `bevy_window::close_on_esc` to `bevy_dev_tools::close_on_esc`.
- Removed usage of `bevy_dev_tools::close_on_esc` from all examples.
## Migration Guide
`bevy_window::close_on_esc` has been moved to
`bevy_dev_tools::close_on_esc`. You will first need to enable
`bevy_dev_tools` as a feature in your `Cargo.toml`:
```toml
[dependencies]
bevy = { version = "0.14", features = ["bevy_dev_tools"] }
```
Finally, modify any imports to use `bevy_dev_tools` instead:
```rust
// Old:
// use bevy:🪟:close_on_esc;
// New:
use bevy::dev_tools::close_on_esc;
App::new()
.add_systems(Update, close_on_esc)
// ...
.run();
```
# Objective
- Since #10811,Bevy uses `assert `in the hot path of iteration. The
`for_each `method has an assert in the outer loop to help the compiler
remove unnecessary branching in the internal loop.
- However , ` for` style iterations do not receive the same treatment.
it still have a branch check in the internal loop, which could
potentially hurt performance.
## Solution
- use `TableRow::from_u32 ` instead of ` TableRow::from_usize` to avoid
unnecessary branch.
Before
![image](https://github.com/bevyengine/bevy/assets/45868716/f6d2a1ac-2129-48ff-97bf-d86713ddeaaf)
After
----------------------------------------------------------------------------
![image](https://github.com/bevyengine/bevy/assets/45868716/bfe5a9ee-ba6c-4a80-85b0-1c6d43adfe8c)
# Objective
`AspectRatio` is a newtype of `f32`, so it can implement basic traits;
`Copy`, `Clone`, `Debug`, `PartialEq` and `PartialOrd`.
## Solution
Derive basic traits for `AspectRatio`.
This is 1 of 5 iterative PR's that affect bevy_ui/layout
---
# Objective
- Extract `UiSurface` into its own file to make diffs in future PR's
easier to digest
## Solution
- Moved `UiSurface` to its own file
This commit makes the following optimizations:
## `MeshPipelineKey`/`BaseMeshPipelineKey` split
`MeshPipelineKey` has been split into `BaseMeshPipelineKey`, which lives
in `bevy_render` and `MeshPipelineKey`, which lives in `bevy_pbr`.
Conceptually, `BaseMeshPipelineKey` is a superclass of
`MeshPipelineKey`. For `BaseMeshPipelineKey`, the bits start at the
highest (most significant) bit and grow downward toward the lowest bit;
for `MeshPipelineKey`, the bits start at the lowest bit and grow upward
toward the highest bit. This prevents them from colliding.
The goal of this is to avoid having to reassemble bits of the pipeline
key for every mesh every frame. Instead, we can just use a bitwise or
operation to combine the pieces that make up a `MeshPipelineKey`.
## `specialize_slow`
Previously, all of `specialize()` was marked as `#[inline]`. This
bloated `queue_material_meshes` unnecessarily, as a large chunk of it
ended up being a slow path that was rarely hit. This commit refactors
the function to move the slow path to `specialize_slow()`.
Together, these two changes shave about 5% off `queue_material_meshes`:
![Screenshot 2024-03-29
130002](https://github.com/bevyengine/bevy/assets/157897/a7e5a994-a807-4328-b314-9003429dcdd2)
## Migration Guide
- The `primitive_topology` field on `GpuMesh` is now an accessor method:
`GpuMesh::primitive_topology()`.
- For performance reasons, `MeshPipelineKey` has been split into
`BaseMeshPipelineKey`, which lives in `bevy_render`, and
`MeshPipelineKey`, which lives in `bevy_pbr`. These two should be
combined with bitwise-or to produce the final `MeshPipelineKey`.
# Objective
Related to #10572
Allow the `Annulus` primitive to be meshed.
## Solution
We introduce a `Meshable` structure, `AnnulusMeshBuilder`, which allows
the `Annulus` primitive to be meshed, leaving optional configuration of
the number of angular sudivisions to the user. Here is a picture of the
annulus's UV-mapping:
<img width="1440" alt="Screenshot 2024-03-26 at 10 39 48 AM"
src="https://github.com/bevyengine/bevy/assets/2975848/b170291d-cba7-441b-90ee-2ad6841eaedb">
Other features are essentially identical to the implementations for
`Circle`/`Ellipse`.
---
## Changelog
- Introduced `AnnulusMeshBuilder`
- Implemented `Meshable` for `Annulus` with `Output =
AnnulusMeshBuilder`
- Implemented `From<Annulus>` and `From<AnnulusMeshBuilder>` for `Mesh`
- Added `impl_reflect!` declaration for `Annulus` and `Triangle3d` in
`bevy_reflect`
---
## Discussion
### Design considerations
The only interesting wrinkle here is that the existing UV-mapping of
`Ellipse` (and hence of `Circle` and `RegularPolygon`) is non-radial
(it's skew-free, created by situating the mesh in a bounding rectangle),
so the UV-mapping of `Annulus` doesn't limit to that of `Circle` as its
inner radius tends to zero, for instance. I don't see this as a real
issue for `Annulus`, which should almost certainly have this kind of
UV-mapping, but I think we ought to at least consider allowing mesh
configuration for `Circle`/`Ellipse` that performs radial UV-mapping
instead. (In these cases in particular, it would be especially easy,
since we wouldn't need a different parameter set in the builder.)
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- #10572
There is no 3D primitive available for the common shape of a tetrahedron
(3-simplex).
## Solution
This PR introduces a new type to the existing math primitives:
- `Tetrahedron`: a polyhedron composed of four triangular faces, six
straight edges, and four vertices
---
## Changelog
### Added
- `Tetrahedron` primitive to the `bevy_math` crate
- `Tetrahedron` tests (`area`, `volume` methods)
- `impl_reflect!` declaration for `Tetrahedron` in the `bevy_reflect`
crate
# Objective
Fixes#12442
## Solution
Change `process_touch_event` to not update previous_position /
previous_force, and change it once per frame in
`touch_screen_input_system`.
# Objective
Sometimes it's useful to iterate over removed entities. For example, in
my library
[bevy_replicon](https://github.com/projectharmonia/bevy_replicon) I need
it to iterate over all removals to replicate them over the network.
Right now we do lookups, but it would be more convenient and faster to
just iterate over all removals.
## Solution
Add `RemovedComponentEvents::iter`.
---
## Changelog
### Added
- `RemovedComponentEvents::iter` to iterate over all removed components.
---------
Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
# Objective
- There are several redundant imports in the tests and examples that are
not caught by CI because additional flags need to be passed.
## Solution
- Run `cargo check --workspace --tests` and `cargo check --workspace
--examples`, then fix all warnings.
- Add `test-check` to CI, which will be run in the check-compiles job.
This should catch future warnings for tests. Examples are already
checked, but I'm not yet sure why they weren't caught.
## Discussion
- Should the `--tests` and `--examples` flags be added to CI, so this is
caught in the future?
- If so, #12818 will need to be merged first. It was also a warning
raised by checking the examples, but I chose to split off into a
separate PR.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
There are currently 2 different warning messages that are logged when
resizing on Linux with Nvidia drivers (introduced in
70c69cdd51).
Fixes#12830
## Solution
Generalize both to say:
```Couldn't get swap chain texture. This often happens with the NVIDIA drivers on Linux. It can be safely ignored.```
# Objective
- Since #12453, `DeterministicRenderingConfig` doesn't do anything
## Solution
- Remove it
---
## Migration Guide
- Removed `DeterministicRenderingConfig`. There shouldn't be any z
fighting anymore in the rendering even without setting
`stable_sort_z_fighting`
# Objective
- The `bundles` parameter in `insert_or_spawn_batch` method has
inconsistent naming with docs (e.g. `bundles_iter`) since #11107.
## Solution
- Replace `bundles` with `bundles_iter`, as `bundles_iter` is more
expressive to its type.
# Objective
Make it easy for crates.io / lib.rs users or automated tools to find the
repository of `bevy_utils_proc_macros`
## Solution
Add the `repository` field to the `Cargo.toml` of
`bevy_utils_proc_macros`
# Objective
This is a necessary precursor to #9122 (this was split from that PR to
reduce the amount of code to review all at once).
Moving `!Send` resource ownership to `App` will make it unambiguously
`!Send`. `SubApp` must be `Send`, so it can't wrap `App`.
## Solution
Refactor `App` and `SubApp` to not have a recursive relationship. Since
`SubApp` no longer wraps `App`, once `!Send` resources are moved out of
`World` and into `App`, `SubApp` will become unambiguously `Send`.
There could be less code duplication between `App` and `SubApp`, but
that would break `App` method chaining.
## Changelog
- `SubApp` no longer wraps `App`.
- `App` fields are no longer publicly accessible.
- `App` can no longer be converted into a `SubApp`.
- Various methods now return references to a `SubApp` instead of an
`App`.
## Migration Guide
- To construct a sub-app, use `SubApp::new()`. `App` can no longer
convert into `SubApp`.
- If you implemented a trait for `App`, you may want to implement it for
`SubApp` as well.
- If you're accessing `app.world` directly, you now have to use
`app.world()` and `app.world_mut()`.
- `App::sub_app` now returns `&SubApp`.
- `App::sub_app_mut` now returns `&mut SubApp`.
- `App::get_sub_app` now returns `Option<&SubApp>.`
- `App::get_sub_app_mut` now returns `Option<&mut SubApp>.`
# Objective
Fix crashing on Linux with latest stable Nvidia 550 driver when
resizing. The crash happens at startup with some setups.
Fixes#12199
I think this would be nice to get into 0.13.1
## Solution
Ignore `wgpu::SurfaceError::Outdated` always on this platform+driver.
It looks like Nvidia considered the previous behaviour of not returning
this error a bug:
"Fixed a bug where vkAcquireNextImageKHR() was not returning
VK_ERROR_OUT_OF_DATE_KHR when it should with WSI X11 swapchains"
(https://www.nvidia.com/Download/driverResults.aspx/218826/en-us/)
What I gather from this is that the surface was outdated on previous
drivers too, but they just didn't report it as an error. So behaviour
shouldn't change.
In the issue conversation we experimented with calling `continue` when
this error happens, but I found that it results in some small issues
like bevy_egui scale not updating with the window sometimes. Just doing
nothing seems to work better.
## Changelog
- Fixed crashing on Linux with Nvidia 550 driver when resizing the
window
## Migration Guide
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
For some asset loaders, it can be useful not to read the entire asset
file and just read a specific region of a file. For this, we need a way
to seek at a specific position inside the file
## Solution
I added support for `AsyncSeek` to `Reader`. In my case, I want to only
read a part of a file, and for that I need to seek to a specific point.
## Migration Guide
Every custom reader (which previously only needed the `AsyncRead` trait
implemented) now also needs to implement the `AsyncSeek` trait to add
the seek capability.
# Objective
- Fix#12746
- When users despawn a scene, the `InstanceId` within `spawned_scenes`
and `spawned_dynamic_scenes` is not removed, causing a potential memory
leak
## Solution
- `spawned_scenes` field was never used, and I removed it
- Add a component remove hook for `Handle<DynamicScene>`, and when the
`Handle<DynamicScene>` component is removed, delete the corresponding
`InstanceId` from `spawned_dynamic_scenes`
- Fixes #[12762](https://github.com/bevyengine/bevy/issues/12762).
## Migration Guide
- `Quat` no longer implements `VectorSpace` as unit quaternions don't
actually form proper vector spaces. If you're absolutely certain that
what you're doing is correct, convert the `Quat` into a `Vec4` and
perform the operations before converting back.
# Objective
Other than the exposed functions for reading matched tables and
archetypes, a `QueryState` does not actually need both internal Vecs for
storing matched archetypes and tables. In practice, it will only use one
of the two depending on if it uses dense or archetypal iteration.
Same vein as #12474. The goal is to reduce the memory overhead of using
queries, which Bevy itself, ecosystem plugins, and end users are already
fairly liberally using.
## Solution
Add `StorageId`, which is a union over `TableId` and `ArchetypeId`, and
store only one of the two at runtime. Read the slice as if it was one ID
depending on whether the query is dense or not.
This follows in the same vein as #5085; however, this one directly
impacts heap memory usage at runtime, while #5085 primarily targeted
transient pointers that might not actually exist at runtime.
---
## Changelog
Changed: `QueryState::matched_tables` now returns an iterator instead of
a reference to a slice.
Changed: `QueryState::matched_archetypes` now returns an iterator
instead of a reference to a slice.
## Migration Guide
`QueryState::matched_tables` and `QueryState::matched_archetypes` does
not return a reference to a slice, but an iterator instead. You may need
to use iterator combinators or collect them into a Vec to use it as a
slice.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Speed up CPU-side rendering.
## Solution
Use `QueryIter::for_each` and `Mut::bypass_change_detection` to minimize
the total amount of data being written and allow autovectorization to
speed up iteration.
## Performance
Tested against the default `many_cubes`, this results in greater than
15x speed up: 281us -> 18.4us.
![image](https://github.com/bevyengine/bevy/assets/3137680/18369285-843e-4eb6-9716-c99c6f5ea4e2)
As `ViewVisibility::HIDDEN` just wraps false, this is likely just
degenerating into `memset(0)`s on the tables.
Today, we sort all entities added to all phases, even the phases that
don't strictly need sorting, such as the opaque and shadow phases. This
results in a performance loss because our `PhaseItem`s are rather large
in memory, so sorting is slow. Additionally, determining the boundaries
of batches is an O(n) process.
This commit makes Bevy instead applicable place phase items into *bins*
keyed by *bin keys*, which have the invariant that everything in the
same bin is potentially batchable. This makes determining batch
boundaries O(1), because everything in the same bin can be batched.
Instead of sorting each entity, we now sort only the bin keys. This
drops the sorting time to near-zero on workloads with few bins like
`many_cubes --no-frustum-culling`. Memory usage is improved too, with
batch boundaries and dynamic indices now implicit instead of explicit.
The improved memory usage results in a significant win even on
unbatchable workloads like `many_cubes --no-frustum-culling
--vary-material-data-per-instance`, presumably due to cache effects.
Not all phases can be binned; some, such as transparent and transmissive
phases, must still be sorted. To handle this, this commit splits
`PhaseItem` into `BinnedPhaseItem` and `SortedPhaseItem`. Most of the
logic that today deals with `PhaseItem`s has been moved to
`SortedPhaseItem`. `BinnedPhaseItem` has the new logic.
Frame time results (in ms/frame) are as follows:
| Benchmark | `binning` | `main` | Speedup |
| ------------------------ | --------- | ------- | ------- |
| `many_cubes -nfc -vpi` | 232.179 | 312.123 | 34.43% |
| `many_cubes -nfc` | 25.874 | 30.117 | 16.40% |
| `many_foxes` | 3.276 | 3.515 | 7.30% |
(`-nfc` is short for `--no-frustum-culling`; `-vpi` is short for
`--vary-per-instance`.)
---
## Changelog
### Changed
* Render phases have been split into binned and sorted phases. Binned
phases, such as the common opaque phase, achieve improved CPU
performance by avoiding the sorting step.
## Migration Guide
- `PhaseItem` has been split into `BinnedPhaseItem` and
`SortedPhaseItem`. If your code has custom `PhaseItem`s, you will need
to migrate them to one of these two types. `SortedPhaseItem` requires
the fewest code changes, but you may want to pick `BinnedPhaseItem` if
your phase doesn't require sorting, as that enables higher performance.
## Tracy graphs
`many-cubes --no-frustum-culling`, `main` branch:
<img width="1064" alt="Screenshot 2024-03-12 180037"
src="https://github.com/bevyengine/bevy/assets/157897/e1180ce8-8e89-46d2-85e3-f59f72109a55">
`many-cubes --no-frustum-culling`, this branch:
<img width="1064" alt="Screenshot 2024-03-12 180011"
src="https://github.com/bevyengine/bevy/assets/157897/0899f036-6075-44c5-a972-44d95895f46c">
You can see that `batch_and_prepare_binned_render_phase` is a much
smaller fraction of the time. Zooming in on that function, with yellow
being this branch and red being `main`, we see:
<img width="1064" alt="Screenshot 2024-03-12 175832"
src="https://github.com/bevyengine/bevy/assets/157897/0dfc8d3f-49f4-496e-8825-a66e64d356d0">
The binning happens in `queue_material_meshes`. Again with yellow being
this branch and red being `main`:
<img width="1064" alt="Screenshot 2024-03-12 175755"
src="https://github.com/bevyengine/bevy/assets/157897/b9b20dc1-11c8-400c-a6cc-1c2e09c1bb96">
We can see that there is a small regression in `queue_material_meshes`
performance, but it's not nearly enough to outweigh the large gains in
`batch_and_prepare_binned_render_phase`.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
This commit changes the `StandardMaterialKey` to be based on a set of
bitflags instead of a structure. We hash it every frame for every mesh,
and `#[derive(Hash)]` doesn't generate particularly efficient code for
large structures full of small types. Packing it into a single `u64`
therefore results in a roughly 10% speedup in `queue_material_meshes` on
`many_cubes --no-frustum-culling`.
![Screenshot 2024-03-29
075124](https://github.com/bevyengine/bevy/assets/157897/78afcab6-b616-489b-8243-da9a117f606c)
# Objective
Wireframes are currently supported for 3D meshes using the
`WireframePlugin` in `bevy_pbr`. This PR adds the same functionality for
2D meshes.
Closes#5881.
## Solution
Since there's no easy way to share material implementations between 2D,
3D, and UI, this is mostly a straight copy and rename from the original
plugin into `bevy_sprite`.
<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/3961616/7aca156f-448a-4c7e-89b8-0a72c5919769">
---
## Changelog
- Added `Wireframe2dPlugin` and related types to support 2D wireframes.
- Added an example to demonstrate how to use 2D wireframes
---------
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
# Objective
- Allow cloning `WinitSettings`. I use this in
[bevy_worldswap](https://github.com/UkoeHB/bevy_worldswap) when
synchronizing secondary app window state.
## Solution
- Add `Clone` to `WinitSettings`.
---
## Changelog
- Added `Clone` to `WinitSettings`.
# Objective
- Reduce the size of `create_windows` and isolate accessibility setup
logic.
## Solution
- Move accessibility setup for new windows to the `accessibility`
module.
## Comments
This is a small refactor, no behavior changes.
# Objective
- Disabling some plugins causes a crash due to ambiguities relying in
feature flags and not checking if both plugins are enabled causing code
like this to crash:
`app.add_plugins(DefaultPlugins.build().disable::<AnimationPlugin>())`
## Solution
- Check if plugins were added before ambiguities.
- Move bevy_gizmos ambiguities from bevy_internal to bevy_gizmos since
they already depend on them.
# Objective
Fixes#12752. Fixes#12750. Document the runtime complexity of all of
the `O(1)` operations on the individual APIs.
## Solution
* Mirror `Query::contains` onto `QueryState::contains`
* Make `QueryState::as_nop` pub(crate)
* Make `NopWorldQuery` pub(crate)
* Document all of the O(1) operations on Query and QueryState.
# Objective
Fixes#12727. All parts that `PersistentGpuBuffer` interact with should
be 100% safe both on the CPU and the GPU: `Queue::write_buffer_with`
zeroes out the slice being written to and when uploading to the GPU, and
all slice writes are bounds checked on the CPU side.
## Solution
Make `PersistentGpuBufferable` a safe trait. Enforce it's correct
implementation via assertions. Re-enable `forbid(unsafe_code)` on
`bevy_pbr`.
# Objective
- A scene usually gets created using the `SceneBundle` or
`DynamicSceneBundle`. This means that the scene's entities get added as
children of the root entity (the entity on which the `SceneBundle` gets
added)
- When the scene gets deleted using the `SceneSpawner`, the scene's
entities are deleted, but the `Children` component of the root entity
doesn't get updated. This means that the hierarchy becomes unsound, with
Children linking to non-existing components.
## Solution
- Update the `despawn_sync` logic to also update the `Children` from any
parents of the scene, if there are any
- Adds a test where a Scene gets despawned and checks for dangling
Children references on the parent. The test fails on `main` but works
here.
## Alternative implementations
- One option could be to add a `parent: Option<Entity>` on the
[InstanceInfo](df15cd7dcc/crates/bevy_scene/src/scene_spawner.rs (L27))
struct that tracks if the SceneInstance was added as a child of a root
entity
# Objective
When I wrote #12747 I neglected to translate random samples from
triangles back to the point where they originated, so they would be
sampled near the origin instead of at the actual triangle location.
## Solution
Translate by the first vertex location so that the samples follow the
actual triangle.
# Objective
Fixes#12392, fixes#12393, and fixes#11387. Implement QueryData for
Archetype and EntityLocation.
## Solution
Add impls for both of the types.
---
## Changelog
Added: `&Archetype` now implements `QueryData`
Added: `EntityLocation` now implements `QueryData`
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Closes https://github.com/bevyengine/bevy/pull/12415
## Solution
- Refactored code that was changed/deprecated in `image` 0.25.
- Please review this PR carefully since I'm just making the changes
without any context or deep knowledge of the module.
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
Fix#12728. Fix unsoundnesss from unhandled null characters in Android
logs.
## Solution
Use `CString` instead of using formatted Strings. Properly document the
safety invariants of the FFI call.
# Objective
- Move `PanicHandlerPlugin` into `bevy_app`
- Fixes#12603 .
## Solution
- I moved the `bevy_panic_handler` into `bevy_app`
- Copy pasted `bevy_panic_handler`'s lib.rs into a separate module in
`bevy_app` as a `panic_handler.rs` module file and added the
`PanicHandlerPlugin` in lib.rs of `bevy_app`
- added the dependency into `cargo.toml`
## Review notes
- I probably want some feedback if I imported App and Plugin correctly
in `panic_handler.rs` line 10 and 11.
- As of yet I have not deleted `bevy_panic_handler` crate, wanted to get
a check if I added it correctly.
- Once validated that my move was correct, I'll probably have to remove
the panic handler find default plugins which I probably need some help
to find.
- And then remove bevy panic_handler and making sure ci passes.
- This is my first issue for contributing to bevy so let me know if I am
doing anything wrong.
## tools context
- rust is 1.76 version
- Windows 11
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Avoid unbounded HashMap growth for opening/closing windows.
## Solution
- Remove map entry in `WinitWindows::remove_window`.
## Migration Guide
- `WinitWindows::get_window_entity` now returns `None` after a window is
closed, instead of a dead entity.
---
## Comments
The comment this PR replaces was added in
https://github.com/bevyengine/bevy/pull/3575. Since `get_window_entity`
now returns an `Entity` instead of a `WindowId`, this no longer seems
useful. Note that `get_window_entity` is only used
[here](56bcbb0975/crates/bevy_winit/src/lib.rs (L436)),
immediately followed by a warning if the entity returned doesn't exist.
# Objective
- Fixes#12677
## Solution
Updated documentation to make it explicit that enabling the appropriate
optional features is required to use the supported audio file format, as
well as provided link to the Bevy docs listing the optional features.
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
## Problem
- A mutable borrow of a handle cannot be directly turned into an AssetId
with `.into()`. You must do a reborrow `&*my_handle`.
## Solution
- Add an impl for From<&mut Handle> to AssetId and UntypedAssetId.
# Objective
Previously, the `Point` trait, which abstracts all of the operations of
a real vector space, was sitting in the submodule of `bevy_math` for
cubic splines. However, the trait has broader applications than merely
cubic splines, and we should use it when possible to avoid code
duplication when performing vector operations.
## Solution
`Point` has been moved into a new submodule in `bevy_math` named
`common_traits`. Furthermore, it has been renamed to `VectorSpace`,
which is more descriptive, and an additional trait `NormedVectorSpace`
has been introduced to expand the API to cover situations involving
geometry in addition to algebra. Additionally, `VectorSpace` itself now
requires a `ZERO` constant and `Neg`. It also supports a `lerp` function
as an automatic trait method.
Here is what that looks like:
```rust
/// A type that supports the mathematical operations of a real vector space, irrespective of dimension.
/// In particular, this means that the implementing type supports:
/// - Scalar multiplication and division on the right by elements of `f32`
/// - Negation
/// - Addition and subtraction
/// - Zero
///
/// Within the limitations of floating point arithmetic, all the following are required to hold:
/// - (Associativity of addition) For all `u, v, w: Self`, `(u + v) + w == u + (v + w)`.
/// - (Commutativity of addition) For all `u, v: Self`, `u + v == v + u`.
/// - (Additive identity) For all `v: Self`, `v + Self::ZERO == v`.
/// - (Additive inverse) For all `v: Self`, `v - v == v + (-v) == Self::ZERO`.
/// - (Compatibility of multiplication) For all `a, b: f32`, `v: Self`, `v * (a * b) == (v * a) * b`.
/// - (Multiplicative identity) For all `v: Self`, `v * 1.0 == v`.
/// - (Distributivity for vector addition) For all `a: f32`, `u, v: Self`, `(u + v) * a == u * a + v * a`.
/// - (Distributivity for scalar addition) For all `a, b: f32`, `v: Self`, `v * (a + b) == v * a + v * b`.
///
/// Note that, because implementing types use floating point arithmetic, they are not required to actually
/// implement `PartialEq` or `Eq`.
pub trait VectorSpace:
Mul<f32, Output = Self>
+ Div<f32, Output = Self>
+ Add<Self, Output = Self>
+ Sub<Self, Output = Self>
+ Neg
+ Default
+ Debug
+ Clone
+ Copy
{
/// The zero vector, which is the identity of addition for the vector space type.
const ZERO: Self;
/// Perform vector space linear interpolation between this element and another, based
/// on the parameter `t`. When `t` is `0`, `self` is recovered. When `t` is `1`, `rhs`
/// is recovered.
///
/// Note that the value of `t` is not clamped by this function, so interpolating outside
/// of the interval `[0,1]` is allowed.
#[inline]
fn lerp(&self, rhs: Self, t: f32) -> Self {
*self * (1. - t) + rhs * t
}
}
```
```rust
/// A type that supports the operations of a normed vector space; i.e. a norm operation in addition
/// to those of [`VectorSpace`]. Specifically, the implementor must guarantee that the following
/// relationships hold, within the limitations of floating point arithmetic:
/// - (Nonnegativity) For all `v: Self`, `v.norm() >= 0.0`.
/// - (Positive definiteness) For all `v: Self`, `v.norm() == 0.0` implies `v == Self::ZERO`.
/// - (Absolute homogeneity) For all `c: f32`, `v: Self`, `(v * c).norm() == v.norm() * c.abs()`.
/// - (Triangle inequality) For all `v, w: Self`, `(v + w).norm() <= v.norm() + w.norm()`.
///
/// Note that, because implementing types use floating point arithmetic, they are not required to actually
/// implement `PartialEq` or `Eq`.
pub trait NormedVectorSpace: VectorSpace {
/// The size of this element. The return value should always be nonnegative.
fn norm(self) -> f32;
/// The squared norm of this element. Computing this is often faster than computing
/// [`NormedVectorSpace::norm`].
#[inline]
fn norm_squared(self) -> f32 {
self.norm() * self.norm()
}
/// The distance between this element and another, as determined by the norm.
#[inline]
fn distance(self, rhs: Self) -> f32 {
(rhs - self).norm()
}
/// The squared distance between this element and another, as determined by the norm. Note that
/// this is often faster to compute in practice than [`NormedVectorSpace::distance`].
#[inline]
fn distance_squared(self, rhs: Self) -> f32 {
(rhs - self).norm_squared()
}
}
```
Furthermore, this PR also demonstrates the use of the
`NormedVectorSpace` combined API to implement `ShapeSample` for
`Triangle2d` and `Triangle3d` simultaneously. Such deduplication is one
of the drivers for developing these APIs.
---
## Changelog
- `Point` from `cubic_splines` becomes `VectorSpace`, exported as
`bevy::math::VectorSpace`.
- `VectorSpace` requires `Neg` and `VectorSpace::ZERO` in addition to
its existing prerequisites.
- Introduced public traits `bevy::math::NormedVectorSpace` for generic
geometry tasks involving vectors.
- Implemented `ShapeSample` for `Triangle2d` and `Triangle3d`.
## Migration Guide
Since `Point` no longer exists, any projects using it must switch to
`bevy::math::VectorSpace`. Additionally, third-party implementations of
this trait now require the `Neg` trait; the constant `VectorSpace::ZERO`
must be provided as well.
---
## Discussion
### Design considerations
Originally, the `NormedVectorSpace::norm` method was part of a separate
trait `Normed`. However, I think that was probably too broad and, more
importantly, the semantics of having it in `NormedVectorSpace` are much
clearer.
As it currently stands, the API exposed here is pretty minimal, and
there is definitely a lot more that we could do, but there are more
questions to answer along the way. As a silly example, we could
implement `NormedVectorSpace::length` as an alias for
`NormedVectorSpace::norm`, but this overlaps with methods in all of the
glam types, so we would want to make sure that the implementations are
effectively identical (for what it's worth, I think they are already).
### Future directions
One example of something that could belong in the `NormedVectorSpace`
API is normalization. Actually, such a thing previously existed on this
branch before I decided to shelve it because of concerns with namespace
collision. It looked like this:
```rust
/// This element, but normalized to norm 1 if possible. Returns an error when the reciprocal of
/// the element's norm is not finite.
#[inline]
#[must_use]
fn normalize(&self) -> Result<Self, NonNormalizableError> {
let reciprocal = 1.0 / self.norm();
if reciprocal.is_finite() {
Ok(*self * reciprocal)
} else {
Err(NonNormalizableError { reciprocal })
}
}
/// An error indicating that an element of a [`NormedVectorSpace`] was non-normalizable due to having
/// non-finite norm-reciprocal.
#[derive(Debug, Error)]
#[error("Element with norm reciprocal {reciprocal} cannot be normalized")]
pub struct NonNormalizableError {
reciprocal: f32
}
```
With this kind of thing in hand, it might be worth considering
eventually making the passage from vectors to directions fully generic
by employing a wrapper type. (Of course, for our concrete types, we
would leave the existing names in place as aliases.) That is, something
like:
```rust
pub struct NormOne<T>
where T: NormedVectorSpace { //... }
```
Utterly separately, the reason that I implemented `ShapeSample` for
`Triangle2d`/`Triangle3d` was to prototype uniform sampling of abstract
meshes, so that's also a future direction.
---------
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
Adopted from and closes https://github.com/bevyengine/bevy/pull/9914 by
@djeedai
# Objective
Fix the use of `TypeRegistry` instead of `TypeRegistryArc` in dynamic
scene and its serializer.
Rename `DynamicScene::serialize_ron()` into `serialize()` to highlight
the fact this is not about serializing to RON specifically, but rather
about serializing to the official Bevy scene format (`.scn` /
`.scn.ron`) which the `SceneLoader` can deserialize (and which happens
to be based in RON, but that not the object here). Also make the link
with the documentation of `SceneLoader` so users understand the full
serializing cycle of a Bevy dynamic scene.
Document `SceneSerializer` with an example showing how to serialize to a
custom format (here: RON), which is easily transposed to serializing
into any other format.
Fixes#9520
## Changelog
### Changed
* `SceneSerializer` and all related serializing helper types now take a
`&TypeRegistry` instead of a `&TypeRegistryArc`. ([SceneSerializer
needlessly uses specifically
&TypeRegistryArc #9520](https://github.com/bevyengine/bevy/issues/9520))
* `DynamicScene::serialize_ron()` was renamed to `serialize()`.
## Migration Guide
* `SceneSerializer` and all related serializing helper types now take a
`&TypeRegistry` instead of a `&TypeRegistryArc`. You can upgrade by
getting the former from the latter with `TypeRegistryArc::read()`,
_e.g._
```diff
let registry_arc: TypeRegistryArc = [...];
- let serializer = SceneSerializer(&scene, ®istry_arc);
+ let registry = registry_arc.read();
+ let serializer = SceneSerializer(&scene, ®istry);
```
* Rename `DynamicScene::serialize_ron()` to `serialize()`.
---------
Co-authored-by: Jerome Humbert <djeedai@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
Since it is common to store a pair of width and height as `Vec2`, it
would be useful to have an easy way to instantiate `AspectRatio` from
`Vec2`.
## Solution
Add `impl From<Vec2> for AspectRatio`.
---
## Changelog
- Added `impl From<Vec2> for AspectRatio`
# Objective
Fixes `cargo test -p bevy_math` as in #12729.
## Solution
As described in
[message](https://github.com/bevyengine/bevy/issues/12729#issuecomment-2022197944)
Added workaround `bevy_math = { path = ".", version = "0.14.0-dev",
features = ["approx"] }` to `bevy_math`'s `dev-dependencies`
---------
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
# Objective
- Fixes#12712
## Solution
- Move the `float_ord.rs` file to `bevy_math`
- Change any `bevy_utils::FloatOrd` statements to `bevy_math::FloatOrd`
---
## Changelog
- Moved `FloatOrd` from `bevy_utils` to `bevy_math`
## Migration Guide
- References to `bevy_utils::FloatOrd` should be changed to
`bevy_math::FloatOrd`
# Objective
Resolves#3824. `unsafe` code should be the exception, not the norm in
Rust. It's obviously needed for various use cases as it's interfacing
with platforms and essentially running the borrow checker at runtime in
the ECS, but the touted benefits of Bevy is that we are able to heavily
leverage Rust's safety, and we should be holding ourselves accountable
to that by minimizing our unsafe footprint.
## Solution
Deny `unsafe_code` workspace wide. Add explicit exceptions for the
following crates, and forbid it in almost all of the others.
* bevy_ecs - Obvious given how much unsafe is needed to achieve
performant results
* bevy_ptr - Works with raw pointers, even more low level than bevy_ecs.
* bevy_render - due to needing to integrate with wgpu
* bevy_window - due to needing to integrate with raw_window_handle
* bevy_utils - Several unsafe utilities used by bevy_ecs. Ideally moved
into bevy_ecs instead of made publicly usable.
* bevy_reflect - Required for the unsafe type casting it's doing.
* bevy_transform - for the parallel transform propagation
* bevy_gizmos - For the SystemParam impls it has.
* bevy_assets - To support reflection. Might not be required, not 100%
sure yet.
* bevy_mikktspace - due to being a conversion from a C library. Pending
safe rewrite.
* bevy_dynamic_plugin - Inherently unsafe due to the dynamic loading
nature.
Several uses of unsafe were rewritten, as they did not need to be using
them:
* bevy_text - a case of `Option::unchecked` could be rewritten as a
normal for loop and match instead of an iterator.
* bevy_color - the Pod/Zeroable implementations were replaceable with
bytemuck's derive macros.
# Objective
- `FloatOrd` currently has a different comparison behavior between its
derived `PartialOrd` impl and manually implemented `Ord` impl (The
[`Ord` doc](https://doc.rust-lang.org/std/cmp/trait.Ord.html) says this
is a logic error). This might be a problem for some `std`
containers/algorithms if they rely on both matching, and a footgun for
Bevy users.
## Solution
- Replace the `PartialEq` and `Ord` impls of `FloatOrd` with some
equivalent ones producing [better
assembly.](https://godbolt.org/z/jaWbjnMKx)
- Manually derive `PartialOrd` with the same behavior as `Ord`,
implement the comparison operators.
- Add some tests.
I first tried using a match-based implementation similar to the
`PartialOrd` impl [of the
std](https://doc.rust-lang.org/src/core/cmp.rs.html#1457) (with added
NaN ordering) but I couldn't get it to produce non-branching assembly.
The current implementation is based on [the one from the `ordered_float`
crate](3641f59e31/src/lib.rs (L121)),
adapted since it uses a different ordering. Should this be mentionned
somewhere in the code?
---
## Changelog
### Fixed
- `FloatOrd` now uses the same ordering for its `PartialOrd` and `Ord`
implementations.
## Migration Guide
- If you were depending on the `PartialOrd` behaviour of `FloatOrd`, it
has changed from matching `f32` to matching `FloatOrd`'s `Ord` ordering,
never returning `None`.
# Objective
We have `ReflectSerializer` and `TypedReflectSerializer`. The former is
the one users will most often use since the latter takes a bit more
effort to deserialize.
However, our deserializers are named `UntypedReflectDeserializer` and
`TypedReflectDeserializer`. There is no obvious indication that
`UntypedReflectDeserializer` must be used with `ReflectSerializer` since
the names don't quite match up.
## Solution
Rename `UntypedReflectDeserializer` back to `ReflectDeserializer`
(initially changed as part of #5723).
Also update the docs for both deserializers (as they were pretty out of
date) and include doc examples.
I also updated the docs for the serializers, too, just so that
everything is consistent.
---
## Changelog
- Renamed `UntypedReflectDeserializer` to `ReflectDeserializer`
- Updated docs for `ReflectDeserializer`, `TypedReflectDeserializer`,
`ReflectSerializer`, and `TypedReflectSerializer`
## Migration Guide
`UntypedReflectDeserializer` has been renamed to `ReflectDeserializer`.
Usages will need to be updated accordingly.
```diff
- let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
+ let reflect_deserializer = ReflectDeserializer::new(®istry);
```
# Objective
- Be more explicit in the name of the module for the ui debug overlay
- Avoid confusion and possible overlap with new overlays
## Solution
- Rename `debug_overlay` to `ui_debug_overlay`
# Objective
CI is currently broken because of `DiagnosticsRecorder` not being Send
and Sync as required by Resource.
## Solution
Wrap `DiagnosticsRecorder` internally with a `WgpuWrapper`.
# Objective
- #10572
There is no 2D primitive available for the common shape of an annulus
(ring).
## Solution
This PR introduces a new type to the existing math primitives:
- `Annulus`: the region between two concentric circles
---
## Changelog
### Added
- `Annulus` primitive to the `bevy_math` crate
- `Annulus` tests (`diameter`, `thickness`, `area`, `perimeter` and
`closest_point` methods)
---------
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
# Objective
I found that some .rs files are unnecessarily executable.
Rust source files may start with a shebang-like statement `#!`, so let's
make sure they are not executable just in case.
Here is the result of the `find` commend that lists executable .rs files
as of main branch `86bd648`.
```console
$ find -name \*.rs -type f -executable
./crates/bevy_gizmos/src/lib.rs
./crates/bevy_tasks/src/lib.rs
./crates/bevy_time/src/lib.rs
./crates/bevy_transform/src/lib.rs
./src/lib.rs
```
It appears that the permissions of those files were originally 644, but
were unexpectedly changed to 755 by commit
52e3f2007b.
## Solution
Make them not executable by using this command;
`find -name \*.rs -type f -executable -exec chmod --verbose a-x -- {}
\+`
# Objective
Fix the regression for Root Node's Layout behavior introduced in
https://github.com/bevyengine/bevy/pull/12268
- Add regression test for Root Node Layout's behaving as they did before
0.13.1
- Restore pre 0.13.1 Root Node Layout behavior (fixes
https://github.com/bevyengine/bevy/issues/12624)
## Solution
This implements [@nicoburns suggestion
](https://discord.com/channels/691052431525675048/743663673393938453/1221593626476548146),
where instead of adding the camera to the taffy node tree, we revert
back to adding a new "parent" node for each root node while maintaining
their relationship with the camera.
> If you can do the ecs change detection to move the node to the correct
Taffy instance for the camera then you should also be able to move it to
a `Vec` of root nodes for that camera.
---
## Changelog
Fixed https://github.com/bevyengine/bevy/issues/12624 - Restores pre
0.13.1 Root Node Layout behavior
## Migration Guide
If you were affected by the 0.13.1 regression and added `position_type:
Absolute` to all your root nodes you might be able to reclaim some LOC
by removing them now that the 0.13 behavior is restored.
# Objective
- Adds line styles to bevy gizmos, suggestion of #9400
- Currently solid and dotted lines are implemented but this can easily
be extended to support dashed lines as well if that is wanted.
## Solution
- Adds the enum `GizmoLineStyle` and uses it in each `GizmoConfig` to
configure the style of the line.
- Each "dot" in a dotted line has the same width and height as the
`line_width` of the corresponding line.
---
## Changelog
- Added `GizmoLineStyle` to `bevy_gizmos`
- Added a `line_style: GizmoLineStyle ` attribute to `GizmoConfig`
- Updated the `lines.wgsl` shader and the pipelines accordingly.
## Migration Guide
- Any manually created `GizmoConfig` must now include the `line_style`
attribute
## Additional information
Some pretty pictures :)
This is the 3d_gizmos example with/without `line_perspective`:
<img width="1440" alt="Screenshot 2024-03-09 at 23 25 53"
src="https://github.com/bevyengine/bevy/assets/62256001/b1b97311-e78d-4de3-8dfe-9e48a35bb27d">
<img width="1440" alt="Screenshot 2024-03-09 at 23 25 39"
src="https://github.com/bevyengine/bevy/assets/62256001/50ee8ecb-5290-484d-ba36-7fd028374f7f">
And the 2d example:
<img width="1440" alt="Screenshot 2024-03-09 at 23 25 06"
src="https://github.com/bevyengine/bevy/assets/62256001/4452168f-d605-4333-bfa5-5461d268b132">
---------
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
# Objective
This gets Bevy building on Wasm when the `atomics` flag is enabled. This
does not yet multithread Bevy itself, but it allows Bevy users to use a
crate like `wasm_thread` to spawn their own threads and manually
parallelize work. This is a first step towards resolving #4078 . Also
fixes#9304.
This provides a foothold so that Bevy contributors can begin to think
about multithreaded Wasm's constraints and Bevy can work towards changes
to get the engine itself multithreaded.
Some flags need to be set on the Rust compiler when compiling for Wasm
multithreading. Here's what my build script looks like, with the correct
flags set, to test out Bevy examples on web:
```bash
set -e
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+mutable-globals' \
cargo build --example breakout --target wasm32-unknown-unknown -Z build-std=std,panic_abort --release
wasm-bindgen --out-name wasm_example \
--out-dir examples/wasm/target \
--target web target/wasm32-unknown-unknown/release/examples/breakout.wasm
devserver --header Cross-Origin-Opener-Policy='same-origin' --header Cross-Origin-Embedder-Policy='require-corp' --path examples/wasm
```
A few notes:
1. `cpal` crashes immediately when the `atomics` flag is set. That is
patched in https://github.com/RustAudio/cpal/pull/837, but not yet in
the latest crates.io release.
That can be temporarily worked around by patching Cpal like so:
```toml
[patch.crates-io]
cpal = { git = "https://github.com/RustAudio/cpal" }
```
2. When testing out `wasm_thread` you need to enable the `es_modules`
feature.
## Solution
The largest obstacle to compiling Bevy with `atomics` on web is that
`wgpu` types are _not_ Send and Sync. Longer term Bevy will need an
approach to handle that, but in the near term Bevy is already configured
to be single-threaded on web.
Therefor it is enough to wrap `wgpu` types in a
`send_wrapper::SendWrapper` that _is_ Send / Sync, but panics if
accessed off the `wgpu` thread.
---
## Changelog
- `wgpu` types that are not `Send` are wrapped in
`send_wrapper::SendWrapper` on Wasm + 'atomics'
- CommandBuffers are not generated in parallel on Wasm + 'atomics'
## Questions
- Bevy should probably add CI checks to make sure this doesn't regress.
Should that go in this PR or a separate PR? **Edit:** Added checks to
build Wasm with atomics
---------
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: daxpedda <daxpedda@gmail.com>
Co-authored-by: François <francois.mockers@vleue.com>
# Objective
This PR fixes#12125
## Solution
The logic in this PR was borrowed from gloo-net and essentially probes
the global Javascript context to see if we are in a window or a worker
before calling `fetch_with_str`.
---------
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
# Objective
Currently the built docs only shows the logo and favicon for the top
level `bevy` crate. This makes views like
https://docs.rs/bevy_ecs/latest/bevy_ecs/ look potentially unrelated to
the project at first glance.
## Solution
Reproduce the docs attributes for every crate that Bevy publishes.
Ideally this would be done with some workspace level Cargo.toml control,
but AFAICT, such support does not exist.
# Objective
Make it easy to get the ids of all the components in a bundle (and
initialise any components not yet initialised). This is fairly similar
to the `Bundle::get_component_ids()` method added in the observers PR
however that will return none for any non-initialised components. This
is exactly the API space covered by `Bundle::component_ids()` however
that isn't possible to call outside of `bevy_ecs` as it requires `&mut
Components` and `&mut Storages`.
## Solution
Added `World.init_bundle<B: Bundle>()` which similarly to
`init_component` and `init_resource`, initialises all components in the
bundle and returns a vector of their component ids.
---
## Changelog
Added the method `init_bundle` to `World` as a counterpart to
`init_component` and `init_resource`.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
- Add serialize feature to bevy_color
- "Fixes #12527".
## Solution
- Added feature for serialization
---
## Changelog
- Serde serialization is now optional, with flag 'serialize'
## Migration Guide
- If user wants color data structures to be serializable, then
application needs to be build with flag 'serialize'
# Objective
- Tiny PR to clarify that `self.world.bundles.init_info::<T>` must have
been called so that the BundleInfo is present in the World
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
We already collect a lot of system information on startup when possible
but we don't make this information available. With the upcoming work on
a diagnostic overlay it would be useful to be able to display this
information.
## Solution
Make the already existing SystemInfo a Resource
---
## Changelog
Added `SystemInfo` Resource
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Afonso Lage <lage.afonso@gmail.com>
# Objective
get_asset_paths tries to check whether a folder is empty, and if so
delete it. However rather than checking whether any subfolder contains
files it checks whether _all_ subfolders have files.
Also cleanup various BoxedFutures in async recursive functions like
these, rust 1.77 now allows recursive async functions (albeit still by
boxing), hurray! This is a followup to #12550 (sorta). More BoxedFuture
stuff can be removed now that rust 1.77 is out, which can use async
recursive functions! This is mainly just cleaner code wise - the
recursion still boxes the future so not much to win there.
PR is mainly whitespace changes so do disable whitespace diffs for
easier review.
# Objective
Follow up from PR #12369 to extract lighting structs from light/mod.rs
into their own file.
Part of the Purdue Refactoring Team's goals issue #12349
## Solution
- Moved PointLight from light/mod.rs to light/point_light.rs
- Moved SpotLight from light/mod.rs to light/spot_light.rs
- Moved DirectionalLight from light/mod.rs to light/directional_light.rs
# Objective
Remove color specialization from `SpritePipeline` after it became
useless in #9597
## Solution
Removed the `COLORED` flag from the pipeline key and removed the
specializing the pipeline over it.
---
## Changelog
### Removed
- `SpritePipelineKey` no longer contains the `COLORED` flag. The flag
has had no effect on how the pipeline operates for a while.
## Migration Guide
- The raw values for the `HDR`, `TONEMAP_IN_SHADER` and `DEBAND_DITHER`
flags have changed, so if you were constructing the pipeline key from
raw `u32`s you'll have to account for that.
# Objective
I was reading some of the Archetype and Bundle code and was getting
confused a little bit in some places (is the `archetype_id` in
`AddBundle` the source or the target archetype id?).
Small PR that adds some docstrings to make it easier for first-time
readers.
# Objective
* Adopted #12025 to fix merge conflicts
* In some cases we used manual impls for certain types, though they are
(at least, now) unnecessary.
## Solution
* Use macros and reflecting-by-value to avoid this clutter.
* Though there were linker issues with Reflect and the CowArc in
AssetPath (see https://github.com/bevyengine/bevy/issues/9747), I
checked these are resolved by using #[reflect_value].
---------
Co-authored-by: soqb <cb.setho@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
- Clarify that `ButtonInput::just_release` and
`ButtonInput::just_pressed` don't imply information about the state of
`ButtonInput::pressed` or their counterparts.
Fixes#12600
## Solution
Removed Into<AssetId<T>> for Handle<T> as proposed in Issue
conversation, fixed dependent code
## Migration guide
If you use passing Handle by value as AssetId, you should pass reference
or call .id() method on it
Before (0.13):
`assets.insert(handle, value);`
After (0.14):
`assets.insert(&handle, value);`
or
`assets.insert(handle.id(), value);`
# Objective
- Implements maths and `Animatable` for `Srgba` as suggested
[here](https://github.com/bevyengine/bevy/issues/12617#issuecomment-2013494774).
## Solution
- Implements `Animatable` and maths for `Srgba` just like their
implemented for other colors.
---
## Changelog
- Updated the example to mention `Srgba`.
## Migration Guide
- The previously existing implementation of mul/div for `Srgba` did not
modify `alpha` but these operations do modify `alpha` now. Users need to
be aware of this change.
# Objective
- Allow registering of systems from Commands with
`Commands::register_one_shot_system`
- Make registering of one shot systems more easy
## Solution
- Add the Command `RegisterSystem` for Commands use.
- Creation of SystemId based on lazy insertion of the System
- Changed the privacy of the fields in SystemId so Commands can return
the SystemId
---
## Changelog
### Added
- Added command `RegisterSystem`
- Added function `Commands::register_one_shot_system`
- Added function `App::register_one_shot_system`
### Changed
- Changed the privacy and the type of struct tuple to regular struct of
SystemId
## Migration Guide
- Changed SystemId fields from tuple struct to a normal struct
If you want to access the entity field, you should use
`SystemId::entity` instead of `SystemId::0`
## Showcase
> Before, if you wanted to register a system with `Commands`, you would
need to do:
```rust
commands.add(|world: &mut World| {
let id = world.register_system(your_system);
// You would need to insert the SystemId inside an entity or similar
})
```
> Now, you can:
```rust
let id = commands.register_one_shot_system(your_system);
// Do what you want with the Id
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Pablo Reinhardt <pabloreinhardt@gmail.com>
# Context
[GitHub Discussion
Link](https://github.com/bevyengine/bevy/discussions/12506)
# Objective
- **Clarity:** More explicit representation of a common geometric
primitive.
- **Convenience:** Provide methods tailored to 3D triangles (area,
perimeters, etc.).
## Solution
- Adding the `Triangle3d` primitive into the `bevy_math` crate.
---
## Changelog
### Added
- `Triangle3d` primitive to the `bevy_math` crate
### Changed
- `Triangle2d::reverse`: the first and last vertices are swapped instead
of the second and third.
---------
Co-authored-by: Miles Silberling-Cook <NthTensor@users.noreply.github.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
# Objective
I'm reading through the ecs query code for the first time, and updating
the docs:
- fixed some typos
- added some docs about things I was confused about (in particular what
the difference between `matches_component_set` and
`update_component_access` was)
# Objective
Fixes#12200 .
## Solution
I added a Hue Trait with the rotate_hue method to enable hue rotation.
Additionally, I modified the implementation of animations in the
animated_material sample.
---
## Changelog
- Added a `Hue` trait to `bevy_color/src/color_ops.rs`.
- Added the `Hue` trait implementation to `Hsla`, `Hsva`, `Hwba`,
`Lcha`, and `Oklcha`.
- Updated animated_material sample.
## Migration Guide
Users of Oklcha need to change their usage to use the with_hue method
instead of the with_h method.
---------
Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Fixes#12202
## Solution
- Implements `Animatable` for all color types implementing arithmetic
operations.
- the colors returned by `Animatable`s methods are already clamped.
- Adds a `color_animation.rs` example.
- Implements the `*Assign` operators for color types that already had
the corresponding operators. This is just a 'nice to have' and I am
happy to remove this if it's not wanted.
---
## Changelog
- `bevy_animation` now depends on `bevy_color`.
- `LinearRgba`, `Laba`, `Oklaba` and `Xyza` implement `Animatable`.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
# Objective
- It can be useful to have access to the path of the current asset being
processed, for example if you want to need a second file that is
relative to the current file being processed.
## Solution
- I added a `path()` function to the `ProcessContext`
# Objective
- Fixes#12570
## Solution
Previously, cardinal splines constructed by `CubicCardinalSpline` would
leave out their endpoints when constructing the cubic curve segments
connecting their points. (See the linked issue for details.)
Now, cardinal splines include the endpoints. For instance, the provided
usage example
```rust
let points = [
vec2(-1.0, -20.0),
vec2(3.0, 2.0),
vec2(5.0, 3.0),
vec2(9.0, 8.0),
];
let cardinal = CubicCardinalSpline::new(0.3, points).to_curve();
let positions: Vec<_> = cardinal.iter_positions(100).collect();
```
will actually produce a spline that connects all four of these points
instead of just the middle two "interior" points.
Internally, this is achieved by duplicating the endpoints of the vector
of control points before performing the construction of the associated
`CubicCurve`. This amounts to specifying that the tangents at the
endpoints `P_0` and `P_n` (say) should be parallel to `P_1 - P_0` and
`P_n - P_{n-1}`.
---
## Migration Guide
Any users relying on the old behavior of `CubicCardinalSpline` will have
to truncate any parametrizations they used in order to access a curve
identical to the one they had previously. This would be done by chopping
off a unit-distance segment from each end of the parametrizing interval.
For instance, if a user's existing code looks as follows
```rust
fn interpolate(t: f32) -> Vec2 {
let points = [
vec2(-1.0, -20.0),
vec2(3.0, 2.0),
vec2(5.0, 3.0),
vec2(9.0, 8.0),
];
let my_curve = CubicCardinalSpline::new(0.3, points).to_curve();
my_curve.position(t)
}
```
then in order to obtain similar behavior, `t` will need to be shifted up
by 1, since the output of `CubicCardinalSpline::to_curve` has introduced
a new segment in the interval [0,1], displacing the old segment from
[0,1] to [1,2]:
```rust
fn interpolate(t: f32) -> Vec2 {
let points = [
vec2(-1.0, -20.0),
vec2(3.0, 2.0),
vec2(5.0, 3.0),
vec2(9.0, 8.0),
];
let my_curve = CubicCardinalSpline::new(0.3, points).to_curve();
my_curve.position(t+1)
}
```
(Note that this does not provide identical output for values of `t`
outside of the interval [0,1].)
On the other hand, any user who was specifying additional endpoint
tangents simply to get the curve to pass through the right points (i.e.
not requiring exactly the same output) can simply omit the endpoints
that were being supplied only for control purposes.
---
## Discussion
### Design considerations
This is one of the two approaches outlined in #12570 — in this PR, we
are basically declaring that the docs are right and the implementation
was flawed.
One semi-interesting question is how the endpoint tangents actually
ought to be defined when we include them, and another option considered
was mirroring the control points adjacent to the endpoints instead of
duplicating them, which would have had the advantage that the expected
length of the corresponding difference should be more similar to that of
the other difference-tangents, provided that the points are equally
spaced.
In this PR, the duplication method (which produces smaller tangents) was
chosen for a couple reasons:
- It seems to be more standard
- It is exceptionally simple to implement
- I was a little concerned that the aforementioned alternative would
result in some over-extrapolation
### An annoyance
If you look at the code, you'll see I was unable to find a satisfactory
way of doing this without allocating a new vector. This doesn't seem
like a big problem given the context, but it does bother me. In
particular, if there is some easy parallel to `slice::windows` for
iterators that doesn't pull in an external dependency, I would love to
know about it.
# Objective
Lets say I have the following `.meta` file:
```RON
(
meta_format_version: "1.0",
asset: Ignore,
)
```
When a file is inside the `assets` directory and processing is enabled,
the processor will copy the file into `imported_assets` although it
should be ignored and therefore not copied.
## Solution
- I added a simple check that does not copy the assets if the
AssetAction is `Ignore`.
## Migration Guide
- The public `ProcessResult` enum now has a `ProcessResult::Ignore`
variant that must be handled.
# Objective
Fix Pr CI failing over dead code in tests and main branch CI failing
over a missing semicolon. Fixes#12620.
## Solution
Add dead_code annotations and a semicolon.
# Objective
- #12500 use the primary window resolution to do all its calculation.
This means bad support for multiple windows or multiple ui camera
## Solution
- Use camera driven UI (https://github.com/bevyengine/bevy/pull/10559)
# Objective
- since #12500, text is a little bit more gray in UI
## Solution
- don't multiply color by alpha. I think this was done in the original
PR (#8973) for shadows which were not added in #12500
# Objective
- Currently the fps_overlay affects any other ui node spawned. This
should not happen
## Solution
- Use position absolute and a ZIndex of `i32::MAX - 32`
- I also modified the example a little bit to center it correctly. It
only worked previously because the overlay was pushing it down. I also
took the opportunity to simplify the text spawning code a little bit.
# Objective
- #12500 broke images and background colors in UI. Try examples
`overflow`, `ui_scaling` or `ui_texture_atlas`
## Solution
- Makes the component `BorderRadius` optional in the query, as it's not
always present. Use `[0.; 4]` as border radius in the extracted node
when none was found
# Objective
Fixes#12224.
## Solution
- Expand `with_` methods for the `Oklch` to their full names.
- Expand `l` to `lightness` in `Oklaba` comments.
## Migration Guide
The following methods have been renamed for the `Oklch` color space:
- `with_l` -> `with_lightness`.
- `with_c` -> `with_chroma`.
- `with_h` -> `with_hue`.
# Objective
- Many types in bevy_render doesn't reflect Default even if it could.
## Solution
- Reflect it.
---
---------
Co-authored-by: Pablo Reinhardt <pabloreinhardt@gmail.com>
# Objective
- Fixes#12202
## Solution
- This PR implements componentwise (including alpha) addition,
subtraction and scalar multiplication/division for some color types.
- The mentioned color types are `Laba`, `Oklaba`, `LinearRgba` and
`Xyza` as all of them are either physically or perceptually linear as
mentioned by @alice-i-cecile in the issue.
---
## Changelog
- Scalar mul/div for `LinearRgba` may modify alpha now.
## Migration Guide
- Users of scalar mul/div for `LinearRgba` need to be aware of the
change and maybe use the `.clamp()` methods or manually set the `alpha`
channel.
# Objective
Implements border radius for UI nodes. Adopted from #8973, but excludes
shadows.
## Solution
- Add a component `BorderRadius` which contains a radius value for each
corner of the UI node.
- Use a fragment shader to generate the rounded corners using a signed
distance function.
<img width="50%"
src="https://github.com/bevyengine/bevy/assets/26204416/16b2ba95-e274-4ce7-adb2-34cc41a776a5"></img>
## Changelog
- `BorderRadius`: New component that holds the border radius values.
- `NodeBundle` & `ButtonBundle`: Added a `border_radius: BorderRadius`
field.
- `extract_uinode_borders`: Stripped down, most of the work is done in
the shader now. Borders are no longer assembled from multiple rects,
instead the shader uses a signed distance function to draw the border.
- `UiVertex`: Added size, border and radius fields.
- `UiPipeline`: Added three vertex attributes to the vertex buffer
layout, to accept the UI node's size, border thickness and border
radius.
- Examples: Added rounded corners to the UI element in the `button`
example, and a `rounded_borders` example.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
# Objective
- Allow configuring of platform-specific panic handlers.
- Remove the silent overwrite of the WASM panic handler
- Closes#12546
## Solution
- Separates the panic handler to a new plugin, `PanicHandlerPlugin`.
- `PanicHandlerPlugin` was added to `DefaultPlugins`.
- Can be disabled on `DefaultPlugins`, in the case someone needs to
configure custom panic handlers.
---
## Changelog
### Added
- A `PanicHandlerPlugin` was added to the `DefaultPlugins`, which now
sets sensible target-specific panic handlers.
### Changed
- On WASM, the panic stack trace was output to the console through the
`BevyLogPlugin`. Since this was separated out into `PanicHandlerPlugin`,
you may need to add the new `PanicHandlerPlugin` (included in
`DefaultPlugins`).
## Migration Guide
- If you used `MinimalPlugins` with `LogPlugin` for a WASM-target build,
you will need to add the new `PanicHandlerPlugin` to set the panic
behavior to output to the console. Otherwise, you will see the default
panic handler (opaque, `unreachable` errors in the console).
# Objective
- This is an adopted version of #10420
- The objective is to help debugging the Ui layout tree with helpful
outlines, that can be easily enabled/disabled
## Solution
- Like #10420, the solution is using the bevy_gizmos in outlining the
nodes
---
## Changelog
### Added
- Added debug_overlay mod to `bevy_dev_tools`
- Added bevy_ui_debug feature to `bevy_dev_tools`
## How to use
- The user must use `bevy_dev_tools` feature in TOML
- The user must use the plugin UiDebugPlugin, that can be found on
`bevy::dev_tools::debug_overlay`
- Finally, to enable the function, the user must set
`UiDebugOptions::enabled` to true
Someone can easily toggle the function with something like:
```rust
fn toggle_overlay(input: Res<ButtonInput<KeyCode>>, options: ResMut<UiDebugOptions>) {
if input.just_pressed(KeyCode::Space) {
// The toggle method will enable if disabled and disable if enabled
options.toggle();
}
}
```
Note that this feature can be disabled from dev_tools, as its in fact
behind a default feature there, being the feature bevy_ui_debug.
# Limitations
Currently, due to limitations with gizmos itself, it's not possible to
support this feature to more the one window, so this tool is limited to
the primary window only.
# Showcase
![image](https://github.com/bevyengine/bevy/assets/126117294/ce9d70e6-0a57-4fa9-9753-ff5a9d82c009)
Ui example with debug_overlay enabled
![image](https://github.com/bevyengine/bevy/assets/126117294/e945015c-5bab-4d7f-9273-472aabaf25a9)
And disabled
---------
Co-authored-by: Nicola Papale <nico@nicopap.ch>
Co-authored-by: Pablo Reinhardt <pabloreinhardt@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Give Bevy a well-designed built-in color palette for users to use while
prototyping or authoring Bevy examples.
## Solution
Generate
([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f7b3a3002fb7727db15c1197e0a1a373),
[gist](https://gist.github.com/rust-play/f7b3a3002fb7727db15c1197e0a1a373))
consts from [Tailwind](https://tailwindcss.com/docs/customizing-colors)
(mit license) json.
## Discussion
Are there other popular alternatives we should be looking at? Something
new and fancy involving a really long acronym like CIELUVLCh? I'm not a
tailwind user or color expert, but I really like the way it's broken up
into distinct but plentiful hue and lightness groups.
It beats needing some shades of red, scrolling through the [current
palette](https://docs.rs/bevy/latest/bevy/prelude/enum.Color.html),
choosing a few of `CRIMSON`, `MAROON`, `RED`, `TOMATO` at random and
calling it a day.
The best information I was able to dig up about the Tailwind palette is
from this thread:
https://twitter.com/steveschoger/status/1303795136703410180. Here are
some key excerpts:
> Tried to the "perceptually uniform" thing for Tailwind UI.
> Ultimately, it just resulted in a bunch of useless shades for colors
like yellow and green that are inherently brighter.
> With that said you're guaranteed to get a contrast ratio of 4.5:1 when
using any 700 shade (in some cases 600) on a 100 shade of the same hue.
> We just spent a lot of time looking at sites to figure out which
colors are popular and tried to fill all the gaps.
> Even the lime green is questionable but felt there needed to be
something in between the jump from yellow to green 😅
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Simplify implementing some asset traits without Box::pin(async move{})
shenanigans.
Fixes (in part) https://github.com/bevyengine/bevy/issues/11308
## Solution
Use async-fn in traits when possible in all traits. Traits with return
position impl trait are not object safe however, and as AssetReader and
AssetWriter are both used with dynamic dispatch, you need a Boxed
version of these futures anyway.
In the future, Rust is [adding
](https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html)proc
macros to generate these traits automatically, and at some point in the
future dyn traits should 'just work'. Until then.... this seemed liked
the right approach given more ErasedXXX already exist, but, no clue if
there's plans here! Especially since these are public now, it's a bit of
an unfortunate API, and means this is a breaking change.
In theory this saves some performance when these traits are used with
static dispatch, but, seems like most code paths go through dynamic
dispatch, which boxes anyway.
I also suspect a bunch of the lifetime annotations on these function
could be simplified now as the BoxedFuture was often the only thing
returned which needed a lifetime annotation, but I'm not touching that
for now as traits + lifetimes can be so tricky.
This is a revival of
[pull/11362](https://github.com/bevyengine/bevy/pull/11362) after a
spectacular merge f*ckup, with updates to the latest Bevy. Just to recap
some discussion:
- Overall this seems like a win for code quality, especially when
implementing these traits, but a loss for having to deal with ErasedXXX
variants.
- `ConditionalSend` was the preferred name for the trait that might be
Send, to deal with wasm platforms.
- When reviewing be sure to disable whitespace difference, as that's 95%
of the PR.
## Changelog
- AssetReader, AssetWriter, AssetLoader, AssetSaver and Process now use
async-fn in traits rather than boxed futures.
## Migration Guide
- Custom implementations of AssetReader, AssetWriter, AssetLoader,
AssetSaver and Process should switch to async fn rather than returning a
bevy_utils::BoxedFuture.
- Simultaniously, to use dynamic dispatch on these traits you should
instead use dyn ErasedXXX.
# Objective
- Not all materials need shadow, but a queue_shadows system is always
added to the `Render` schedule and executed
## Solution
- Make a setting for shadows, it defaults to true
## Changelog
- Added `shadows_enabled` setting to `MaterialPlugin`
## Migration Guide
- `MaterialPlugin` now has a `shadows_enabled` setting, if you didn't
spawn the plugin using `::default()` or `..default()`, you'll need to
set it. `shadows_enabled: true` is the same behavior as the previous
version, and also the default value.
# Objective
Currently in order to retrieve the inner values from direction types is
that you need to use the `Deref` trait or `From`/`Into`. `Deref` that is
currently implemented is an anti-pattern that I believe should be less
relied upon.
This pull-request add getters for retrieving the inner values for
direction types.
Advantages of getters:
- Let rust-analyzer to list out available methods for users to
understand better to on how to get the inner value. (This happens to me.
I really don't know how to get the value until I look through the source
code.)
- They are simple.
- Generally won't be ambiguous in most context. Traits such as
`From`/`Into` will require fully qualified syntax from time to time.
- Unsurprising result.
Disadvantages of getters:
- More verbose
Advantages of deref polymorphism:
- You reduce boilerplate for getting the value and call inner methods
by:
```rust
let dir = Dir3::new(Vec3::UP).unwrap();
// getting value
let value = *dir;
// instead of using getters
let value = dir.vec3();
// calling methods for the inner vector
dir.xy();
// instead of using getters
dir.vec3().xy();
```
Disadvantages of deref polymorphism:
- When under more level of indirection, it will requires more
dereferencing which will get ugly in some part:
```rust
// getting value
let value = **dir;
// instead of using getters
let value = dir.vec3();
// calling methods for the inner vector
dir.xy();
// instead of using getters
dir.vec3().xy();
```
[More detail
here](https://rust-unofficial.github.io/patterns/anti_patterns/deref.html).
Edit: Update information for From/Into trait.
Edit: Advantages and disadvantages.
## Solution
Add `vec2` method for Dir2.
Add `vec3` method for Dir3.
Add `vec3a` method for Dir3A.
# Objective
prevent gpu buffer allocations when running `as_bind_group` for assets
with texture dependencies that are not yet available.
## Solution
reorder the binding creation so that fallible items are created first.
# Objective
Resolves#12431.
## Solution
Added a `skip_taskbar` field to the `Window` struct (defaults to
`false`). Used in `create_windows` if the target OS is Windows.
Updates the requirements on
[base64](https://github.com/marshallpierce/rust-base64) to permit the
latest version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/marshallpierce/rust-base64/blob/master/RELEASE-NOTES.md">base64's
changelog</a>.</em></p>
<blockquote>
<h1>0.22.0</h1>
<ul>
<li><code>DecodeSliceError::OutputSliceTooSmall</code> is now
conservative rather than precise. That is, the error will only occur if
the decoded output <em>cannot</em> fit, meaning that
<code>Engine::decode_slice</code> can now be used with exactly-sized
output slices. As part of this, <code>Engine::internal_decode</code> now
returns <code>DecodeSliceError</code> instead of
<code>DecodeError</code>, but that is not expected to affect any
external callers.</li>
<li><code>DecodeError::InvalidLength</code> now refers specifically to
the <em>number of valid symbols</em> being invalid (i.e. <code>len % 4
== 1</code>), rather than just the number of input bytes. This avoids
confusing scenarios when based on interpretation you could make a case
for either <code>InvalidLength</code> or <code>InvalidByte</code> being
appropriate.</li>
<li>Decoding is somewhat faster (5-10%)</li>
</ul>
<h1>0.21.7</h1>
<ul>
<li>Support getting an alphabet's contents as a str via
<code>Alphabet::as_str()</code></li>
</ul>
<h1>0.21.6</h1>
<ul>
<li>Improved introductory documentation and example</li>
</ul>
<h1>0.21.5</h1>
<ul>
<li>Add <code>Debug</code> and <code>Clone</code> impls for the general
purpose Engine</li>
</ul>
<h1>0.21.4</h1>
<ul>
<li>Make <code>encoded_len</code> <code>const</code>, allowing the
creation of arrays sized to encode compile-time-known data lengths</li>
</ul>
<h1>0.21.3</h1>
<ul>
<li>Implement <code>source</code> instead of <code>cause</code> on Error
types</li>
<li>Roll back MSRV to 1.48.0 so Debian can continue to live in a time
warp</li>
<li>Slightly faster chunked encoding for short inputs</li>
<li>Decrease binary size</li>
</ul>
<h1>0.21.2</h1>
<ul>
<li>Rollback MSRV to 1.57.0 -- only dev dependencies need 1.60, not the
main code</li>
</ul>
<h1>0.21.1</h1>
<ul>
<li>Remove the possibility of panicking during decoded length
calculations</li>
<li><code>DecoderReader</code> no longer sometimes erroneously ignores
padding <a
href="https://redirect.github.com/marshallpierce/rust-base64/issues/226">#226</a></li>
</ul>
<h2>Breaking changes</h2>
<ul>
<li><code>Engine.internal_decode</code> return type changed</li>
<li>Update MSRV to 1.60.0</li>
</ul>
<h1>0.21.0</h1>
<h2>Migration</h2>
<h3>Functions</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5d70ba7576"><code>5d70ba7</code></a>
Merge pull request <a
href="https://redirect.github.com/marshallpierce/rust-base64/issues/269">#269</a>
from marshallpierce/mp/decode-precisely</li>
<li><a
href="efb6c006c7"><code>efb6c00</code></a>
Release notes</li>
<li><a
href="2b91084a31"><code>2b91084</code></a>
Add some tests to boost coverage</li>
<li><a
href="9e9c7abe65"><code>9e9c7ab</code></a>
Engine::internal_decode now returns DecodeSliceError</li>
<li><a
href="a8a60f43c5"><code>a8a60f4</code></a>
Decode main loop improvements</li>
<li><a
href="a25be0667c"><code>a25be06</code></a>
Simplify leftover output writes</li>
<li><a
href="9979cc33bb"><code>9979cc3</code></a>
Keep morsels as separate bytes</li>
<li><a
href="37670c5ec2"><code>37670c5</code></a>
Bump dev toolchain version (<a
href="https://redirect.github.com/marshallpierce/rust-base64/issues/268">#268</a>)</li>
<li><a
href="9652c78773"><code>9652c78</code></a>
v0.21.7</li>
<li><a
href="08deccf703"><code>08deccf</code></a>
provide as_str() method to return the alphabet characters (<a
href="https://redirect.github.com/marshallpierce/rust-base64/issues/264">#264</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/marshallpierce/rust-base64/compare/v0.21.5...v0.22.0">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# Objective
Fixes#12549. WorldCell's support of everything a World can do is
incomplete, and represents an alternative, potentially confusing, and
less performant way of pulling multiple fetches from a `World`. The
typical approach is to use `SystemState` for a runtime cached and safe
way, or `UnsafeWorldCell` if the use of `unsafe` is tolerable.
## Solution
Remove it!
---
## Changelog
Removed: `WorldCell`
Removed: `World::cell`
## Migration Guide
`WorldCell` has been removed. If you were using it to fetch multiple
distinct values from a `&mut World`, use `SystemState` by calling
`SystemState::get` instead. Alternatively, if `SystemState` cannot be
used, `UnsafeWorldCell` can instead be used in unsafe contexts.
# Objective
- working with UI components in Bevy, I found myself wanting some of
these common traits, like `PartialEq` for comparing simple types
## Solution
- I added only (hopefully) uncontroversial `derive`s for some common UI
types
Note that many types, unfortunately, can't have `PartialEq` `derive`d
for them, because they contain `f32`s and / or `Vec`s.
# Objective
I wanted to have reflection for BinaryHeap for a personal project.
I'm running into some issues:
- I wanted to represent BinaryHeap as a reflect::List type since it's
essentially a wrapper around a Vec, however there's no public way to
access the underlying Vec, which makes it hard to implement the
reflect::List methods. I have omitted the reflect::List methods for
now.. I'm not sure if that's a blocker?
- what would be the alternatives? Simply not implement `reflect::List`?
It is possible to implement `FromReflect` without it. Would the type be
`Struct` then?
---------
Co-authored-by: Charles Bournhonesque <cbournhonesque@snapchat.com>
# Objective
Provide component access to `&'w T`, `Ref<'w, T>`, `Mut<'w, T>`,
`Ptr<'w>` and `MutUntyped<'w>` from `EntityMut<'w>`/`EntityWorldMut<'w>`
with the world `'w` lifetime instead of `'_`.
Fixes#12417
## Solution
Add `into_` prefixed methods for `EntityMut<'w>`/`EntityWorldMut<'w>`
that consume `self` and returns component access with the world `'w`
lifetime unlike the `get_` prefixed methods that takes `&'a self` and
returns component access with `'a` lifetime.
Methods implemented:
- EntityMut::into_borrow
- EntityMut::into_ref
- EntityMut::into_mut
- EntityMut::into_borrow_by_id
- EntityMut::into_mut_by_id
- EntityWorldMut::into_borrow
- EntityWorldMut::into_ref
- EntityWorldMut::into_mut
- EntityWorldMut::into_borrow_by_id
- EntityWorldMut::into_mut_by_id
# Objective
fix#12344
## Solution
use existing machinery in track_assets to determine if the asset is
unused before firing Asset::Unused event
~~most extract functions use `AssetEvent::Removed` to schedule deletion
of render world resources. `RenderAssetPlugin` was using
`AssetEvent::Unused` instead.
`Unused` fires when the last strong handle is dropped, even if a new one
is created. `Removed` only fires when a new one is not created.
as far as i can see, `Unused` is the same as `Removed` except for this
"feature", and that it also fires early if all handles for a loading
asset are dropped (`Removed` fires after the loading completes). note
that in that case, processing based on `Loaded` won't have been done
anyway.
i think we should get rid of `Unused` completely, it is not currently
used anywhere (except here, previously) and i think using it is probably
always a mistake.
i also am not sure why we keep loading assets that have been dropped
while loading, we should probably drop the loader task as well and
remove immediately.~~
# Objective
Whenever a nodes size gets changed, its texture slices get updated a
frame later. This results in visual glitches when animating the size of
a node with a texture slice. See this video:
[Screencast from 17-03-24
14:53:13.webm](https://github.com/bevyengine/bevy/assets/46689298/64e711f7-a1ec-41e3-b119-dc8d7e1a7669)
## Solution
Compute texture slices after the layout system has finished.
# Objective
- Resolves#12463
## Solution
- Added `ClampColor`
Due to consistency, `is_within_bounds` is a method of `ClampColor`, like
`is_fully_transparent` is a method of `Alpha`
---
## Changelog
### Added
- `ClampColor` trait
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
It's useful to have access to render pipeline statistics, since they
provide more information than FPS alone. For example, the number of
drawn triangles can be used to debug culling and LODs. The number of
fragment shader invocations can provide a more stable alternative metric
than GPU elapsed time.
See also: Render node GPU timing overlay #8067, which doesn't provide
pipeline statistics, but adds a nice overlay.
## Solution
Add `RenderDiagnosticsPlugin`, which enables collecting pipeline
statistics and CPU & GPU timings.
---
## Changelog
- Add `RenderDiagnosticsPlugin`
- Add `RenderContext::diagnostic_recorder` method
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>