Commit graph

3564 commits

Author SHA1 Message Date
Jan Češpivo
dcc35120f9
chore: use ExtractComponent derive macro for EnvironmentMapLight and FogSettings (#10191)
I've done tiny cleanup when playing with code.

## Solution

[derive
macro](https://github.com/bevyengine/bevy/blob/main/crates/bevy_render/macros/src/extract_component.rs)
with `extract_component_filter` attribute generate the same code I
removed.

## Migration Guide

No migration needed
2023-10-19 20:18:33 +00:00
Arend van Beelen jr
5d110eb96e
Prevent black frames during startup (#9826)
# Objective

This PR addresses the issue where Bevy displays one or several black
frames before the scene is first rendered. This is particularly
noticeable on iOS, where the black frames disrupt the transition from
the launch screen to the game UI. I have written about my search to
solve this issue on the Bevy discord:
https://discord.com/channels/691052431525675048/1151047604520632352

While I can attest this PR works on both iOS and Linux/Wayland (and even
seems to resolve a slight flicker during startup with the latter as
well), I'm not familiar enough with Bevy to judge the full implications
of these changes. I hope a reviewer or tester can help me confirm
whether this is the right approach, or what might be a cleaner solution
to resolve this issue.

## Solution

I have moved the "startup phase" as well as the plugin finalization into
the `app.run()` function so those things finish synchronously before the
"main schedule" starts. I even move one frame forward as well, using
`app.update()`, to make sure the rendering has caught up with the state
of the finalized plugins as well.

I admit that part of this was achieved through trial-and-error, since
not doing the "startup phase" *before* `app.finish()` resulted in
panics, while not calling an extra `app.update()` didn't fully resolve
the issue.

What I *can* say, is that the iOS launch screen animation works in such
a way that the OS initiates the transition once the framework's
[`didFinishLaunching()`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application)
returns, meaning app developers **must** finish setting up their UI
before that function returns. This is what basically led me on the path
to try to "finish stuff earlier" :)

## Changelog

### Changed

- The startup phase and the first frame are rendered synchronously when
calling `app.run()`, before the "main schedule" is started. This fixes
black frames during the iOS launch transition and possible flickering on
other platforms, but may affect initialization order in your
application.

## Migration Guide

Because of this change, the timing of the first few frames might have
changed, and I think it could be that some things one may expect to be
initialized in a system may no longer be. To be honest, I feel out of my
depth to judge the exact impact here.
2023-10-18 23:24:19 +00:00
ira
4b65a533f1
Add system parameter for computing up-to-date GlobalTransforms (#8603)
# Objective

Add a way to easily compute the up-to-date `GlobalTransform` of an
entity.

## Solution

Add the `TransformHelper`(Name pending) system parameter with the
`compute_global_transform` method that takes an `Entity` and returns a
`GlobalTransform` if successful.

## Changelog
- Added the `TransformHelper` system parameter for computing the
up-to-date `GlobalTransform` of an entity.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Noah <noahshomette@gmail.com>
2023-10-18 20:07:51 +00:00
Surav Shrestha
ffec6645b2
fix typos in crates/bevy_app/src/app.rs (#10173)
ambiguious -> ambiguous
2023-10-18 15:50:05 +00:00
robtfm
c99351f7c2
allow extensions to StandardMaterial (#7820)
# Objective

allow extending `Material`s (including the built in `StandardMaterial`)
with custom vertex/fragment shaders and additional data, to easily get
pbr lighting with custom modifications, or otherwise extend a base
material.

# Solution

- added `ExtendedMaterial<B: Material, E: MaterialExtension>` which
contains a base material and a user-defined extension.
- added example `extended_material` showing how to use it
- modified AsBindGroup to have "unprepared" functions that return raw
resources / layout entries so that the extended material can combine
them

note: doesn't currently work with array resources, as i can't figure out
how to make the OwnedBindingResource::get_binding() work, as wgpu
requires a `&'a[&'a TextureView]` and i have a `Vec<TextureView>`.

# Migration Guide

manual implementations of `AsBindGroup` will need to be adjusted, the
changes are pretty straightforward and can be seen in the diff for e.g.
the `texture_binding_array` example.

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
2023-10-17 21:28:08 +00:00
robtfm
de8a6007b7
check for any prepass phase (#10160)
# Objective

deferred doesn't currently run unless one of `DepthPrepass`,
`ForwardPrepass` or `MotionVectorPrepass` is also present on the camera.

## Solution

modify the `queue_prepass_material_meshes` view query to check for any
relevant phase, instead of requiring `Opaque3dPrepass` and
`AlphaMask3dPrepass` to be present
2023-10-17 19:28:52 +00:00
Niklas Eicker
6b070b1776
Correct Scene loader error description (#10161)
# Objective

- Correct the description of an error type for the scene loader

## Solution

- Correct the description of an error type for the scene loader
2023-10-17 17:58:35 +00:00
Marco Buono
5733d2403e
*_PREPASS Shader Def Cleanup (#10136)
# Objective

- This PR aims to make the various `*_PREPASS` shader defs we have
(`NORMAL_PREPASS`, `DEPTH_PREPASS`, `MOTION_VECTORS_PREPASS` AND
`DEFERRED_PREPASS`) easier to use and understand:
- So that their meaning is now consistent across all contexts; (“prepass
X is enabled for the current view”)
  - So that they're also consistently set across all contexts.
- It also aims to enable us to (with a follow up PR) to conditionally
gate the `BindGroupEntry` and `BindGroupLayoutEntry` items associated
with these prepasses, saving us up to 4 texture slots in WebGL
(currently globally limited to 16 per shader, regardless of bind groups)

## Solution

- We now consistently set these from `PrepassPipeline`, the
`MeshPipeline` and the `DeferredLightingPipeline`, we also set their
`MeshPipelineKey`s;
- We introduce `PREPASS_PIPELINE`, `MESH_PIPELINE` and
`DEFERRED_LIGHTING_PIPELINE` that can be used to detect where the code
is running, without overloading the meanings of the prepass shader defs;
- We also gate the WGSL functions in `bevy_pbr::prepass_utils` with
`#ifdef`s for their respective shader defs, so that shader code can
provide a fallback whenever they're not available.
- This allows us to conditionally include the bindings for these prepass
textures (My next PR, which will hopefully unblock #8015)
- @robtfm mentioned [these were being used to prevent accessing the same
binding as read/write in the
prepass](https://discord.com/channels/691052431525675048/743663924229963868/1163270458393759814),
however even after reversing the `#ifndef`s I had no issues running the
code, so perhaps the compiler is already smart enough even without tree
shaking to know they're not being used, thanks to `#ifdef
PREPASS_PIPELINE`?

## Comparison

### Before

| Shader Def | `PrepassPipeline` | `MeshPipeline` |
`DeferredLightingPipeline` |
| ------------------------ | ----------------- | -------------- |
-------------------------- |
| `NORMAL_PREPASS` | Yes | No | No |
| `DEPTH_PREPASS` | Yes | No | No |
| `MOTION_VECTORS_PREPASS` | Yes | No | No |
| `DEFERRED_PREPASS` | Yes | No | No |

| View Key | `PrepassPipeline` | `MeshPipeline` |
`DeferredLightingPipeline` |
| ------------------------ | ----------------- | -------------- |
-------------------------- |
| `NORMAL_PREPASS` | Yes | Yes | No |
| `DEPTH_PREPASS` | Yes | No | No |
| `MOTION_VECTORS_PREPASS` | Yes | No | No |
| `DEFERRED_PREPASS` | Yes | Yes\* | No |

\* Accidentally was being set twice, once with only
`deferred_prepass.is_some()` as a condition,
and once with `deferred_p repass.is_some() && !forward` as a condition.

### After

| Shader Def | `PrepassPipeline` | `MeshPipeline` |
`DeferredLightingPipeline` |
| ---------------------------- | ----------------- | --------------- |
-------------------------- |
| `NORMAL_PREPASS` | Yes | Yes | Yes |
| `DEPTH_PREPASS` | Yes | Yes | Yes |
| `MOTION_VECTORS_PREPASS` | Yes | Yes | Yes |
| `DEFERRED_PREPASS` | Yes | Yes | Unconditionally |
| `PREPASS_PIPELINE` | Unconditionally | No | No |
| `MESH_PIPELINE` | No | Unconditionally | No |
| `DEFERRED_LIGHTING_PIPELINE` | No | No | Unconditionally |

| View Key | `PrepassPipeline` | `MeshPipeline` |
`DeferredLightingPipeline` |
| ------------------------ | ----------------- | -------------- |
-------------------------- |
| `NORMAL_PREPASS` | Yes | Yes | Yes |
| `DEPTH_PREPASS` | Yes | Yes | Yes |
| `MOTION_VECTORS_PREPASS` | Yes | Yes | Yes |
| `DEFERRED_PREPASS` | Yes | Yes | Unconditionally |

---

## Changelog

- Cleaned up WGSL `*_PREPASS` shader defs so they're now consistently
used everywhere;
- Introduced `PREPASS_PIPELINE`, `MESH_PIPELINE` and
`DEFERRED_LIGHTING_PIPELINE` WGSL shader defs for conditionally
compiling logic based the current pipeline;
- WGSL functions from `bevy_pbr::prepass_utils` are now guarded with
`#ifdef` based on the currently enabled prepasses;

## Migration Guide

- When using functions from `bevy_pbr::prepass_utils`
(`prepass_depth()`, `prepass_normal()`, `prepass_motion_vector()`) in
contexts where these prepasses might be disabled, you should now wrap
your calls with the appropriate `#ifdef` guards, (`#ifdef
DEPTH_PREPASS`, `#ifdef NORMAL_PREPASS`, `#ifdef MOTION_VECTOR_PREPASS`)
providing fallback logic where applicable.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
2023-10-17 00:16:21 +00:00
Gino Valente
01b910a148
bevy_reflect: Fix dynamic type serialization (#10103)
# Objective

Fixes #10086

## Solution

Instead of serializing via `DynamicTypePath::reflect_type_path`, now
uses the `TypePath` found on the `TypeInfo` returned by
`Reflect::get_represented_type_info`.

This issue was happening because the dynamic types implement `TypePath`
themselves and do not (and cannot) forward their proxy's `TypePath`
data. The solution was to access the proxy's type information in order
to get the correct `TypePath` data.

## Changed

- The `Debug` impl for `TypePathTable` now includes output for all
fields.
2023-10-16 23:31:16 +00:00
Griffin
490699c311
Fix unlit missing parameters (#10144)
# Objective

- The refactoring in https://github.com/bevyengine/bevy/pull/10105
missed including the frag_coord and normal in pbr_input.

## Solution

- Add them back
2023-10-16 22:11:51 +00:00
Carter Anderson
a042924a6e
Time: demote delta time clamping warning to debug (#10145)
# Objective

Time clamping happens consistently for apps that load non-trivial
things. While this _is_ an indicator that we should probably try to move
this work to a thread that doesn't block the Update, this is common
enough (and unactionable enough) that I think we should demote it for
now.

```
2023-10-16T18:46:14.918781Z  WARN bevy_time::virt: delta time larger than maximum delta, clamping delta to 250ms and skipping 63.649253ms
2023-10-16T18:46:15.178048Z  WARN bevy_time::virt: delta time larger than maximum delta, clamping delta to 250ms and skipping 1.71611ms
```

## Solution

Change `warn` to `debug` for this message
2023-10-16 19:18:39 +00:00
Bruce Mitchener
6bd3cca0ca
Improve linking within RenderSet docs. (#10143)
# Objective

- Improve formatting and linking within `RenderSet` docs.

## Solution

- Used backticks and intradoc links.
2023-10-16 17:13:20 +00:00
mamekoro
1258ceb62c
Change visibility of bevy::core::update_frame_count to pub (#10111)
# Objective
Closes #10107

The visibility of `bevy::core::update_frame_count` should be `pub` so it
can be used in third-party code like this:

```rust
impl Plugin for MyPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Last, use_frame_count.before(bevy::core::update_frame_count));
    }
}
```

## Solution
Make `bevy::core::update_frame_count` public.

---

## Changelog

### Added
- Documentation for `bevy::core::update_frame_count`

### Changed
- Visibility of `bevy::core::update_frame_count` is now `pub`
2023-10-16 13:43:02 +00:00
Edgar Geier
e23d7cf501
Explain usage of prepass shaders in docs for Material trait (#9025)
# Objective

- Fixes #8696.

## Solution

- Added a paragraph describing the usage of the `prepass_vertex_shader`
and `prepass_fragment_shader`.
2023-10-16 13:39:17 +00:00
Miles Ryan
06d148bae1
Fixed mod.rs in rendering to support Radeon Cards (#10132)
# Objective

- Added support for newer AMD Radeon cards in the mod.rs file located at
``crates/bevy_render/src/view/window/mod.rs``

## Solution

- All I needed to add was ``name.starts_with("Radeon") ||`` to the
existing code on line 347 of
``crates/bevy_render/src/view/window/mod.rs``

---

## Changelog

- Changed ``crates/bevy_render/src/view/window/mod.rs``
2023-10-16 10:45:11 +00:00
Nuutti Kotivuori
3d79dc4cdc
Unify FixedTime and Time while fixing several problems (#8964)
# Objective

Current `FixedTime` and `Time` have several problems. This pull aims to
fix many of them at once.

- If there is a longer pause between app updates, time will jump forward
a lot at once and fixed time will iterate on `FixedUpdate` for a large
number of steps. If the pause is merely seconds, then this will just
mean jerkiness and possible unexpected behaviour in gameplay. If the
pause is hours/days as with OS suspend, the game will appear to freeze
until it has caught up with real time.
- If calculating a fixed step takes longer than specified fixed step
period, the game will enter a death spiral where rendering each frame
takes longer and longer due to more and more fixed step updates being
run per frame and the game appears to freeze.
- There is no way to see current fixed step elapsed time inside fixed
steps. In order to track this, the game designer needs to add a custom
system inside `FixedUpdate` that calculates elapsed or step count in a
resource.
- Access to delta time inside fixed step is `FixedStep::period` rather
than `Time::delta`. This, coupled with the issue that `Time::elapsed`
isn't available at all for fixed steps, makes it that time requiring
systems are either implemented to be run in `FixedUpdate` or `Update`,
but rarely work in both.
- Fixes #8800 
- Fixes #8543 
- Fixes #7439
- Fixes #5692

## Solution

- Create a generic `Time<T>` clock that has no processing logic but
which can be instantiated for multiple usages. This is also exposed for
users to add custom clocks.
- Create three standard clocks, `Time<Real>`, `Time<Virtual>` and
`Time<Fixed>`, all of which contain their individual logic.
- Create one "default" clock, which is just `Time` (or `Time<()>`),
which will be overwritten from `Time<Virtual>` on each update, and
`Time<Fixed>` inside `FixedUpdate` schedule. This way systems that do
not care specifically which time they track can work both in `Update`
and `FixedUpdate` without changes and the behaviour is intuitive.
- Add `max_delta` to virtual time update, which limits how much can be
added to virtual time by a single update. This fixes both the behaviour
after a long freeze, and also the death spiral by limiting how many
fixed timestep iterations there can be per update. Possible future work
could be adding `max_accumulator` to add a sort of "leaky bucket" time
processing to possibly smooth out jumps in time while keeping frame rate
stable.
- Many minor tweaks and clarifications to the time functions and their
documentation.

## Changelog

- `Time::raw_delta()`, `Time::raw_elapsed()` and related methods are
moved to `Time<Real>::delta()` and `Time<Real>::elapsed()` and now match
`Time` API
- `FixedTime` is now `Time<Fixed>` and matches `Time` API. 
- `Time<Fixed>` default timestep is now 64 Hz, or 15625 microseconds.
- `Time` inside `FixedUpdate` now reflects fixed timestep time, making
systems portable between `Update ` and `FixedUpdate`.
- `Time::pause()`, `Time::set_relative_speed()` and related methods must
now be called as `Time<Virtual>::pause()` etc.
- There is a new `max_delta` setting in `Time<Virtual>` that limits how
much the clock can jump by a single update. The default value is 0.25
seconds.
- Removed `on_fixed_timer()` condition as `on_timer()` does the right
thing inside `FixedUpdate` now.

## Migration Guide

- Change all `Res<Time>` instances that access `raw_delta()`,
`raw_elapsed()` and related methods to `Res<Time<Real>>` and `delta()`,
`elapsed()`, etc.
- Change access to `period` from `Res<FixedTime>` to `Res<Time<Fixed>>`
and use `delta()`.
- The default timestep has been changed from 60 Hz to 64 Hz. If you wish
to restore the old behaviour, use
`app.insert_resource(Time::<Fixed>::from_hz(60.0))`.
- Change `app.insert_resource(FixedTime::new(duration))` to
`app.insert_resource(Time::<Fixed>::from_duration(duration))`
- Change `app.insert_resource(FixedTime::new_from_secs(secs))` to
`app.insert_resource(Time::<Fixed>::from_seconds(secs))`
- Change `system.on_fixed_timer(duration)` to
`system.on_timer(duration)`. Timers in systems placed in `FixedUpdate`
schedule automatically use the fixed time clock.
- Change `ResMut<Time>` calls to `pause()`, `is_paused()`,
`set_relative_speed()` and related methods to `ResMut<Time<Virtual>>`
calls. The API is the same, with the exception that `relative_speed()`
will return the actual last ste relative speed, while
`effective_relative_speed()` returns 0.0 if the time is paused and
corresponds to the speed that was set when the update for the current
frame started.

## Todo

- [x] Update pull name and description
- [x] Top level documentation on usage
- [x] Fix examples
- [x] Decide on default `max_delta` value
- [x] Decide naming of the three clocks: is `Real`, `Virtual`, `Fixed`
good?
- [x] Decide if the three clock inner structures should be in prelude
- [x] Decide on best way to configure values at startup: is manually
inserting a new clock instance okay, or should there be config struct
separately?
- [x] Fix links in docs
- [x] Decide what should be public and what not
- [x] Decide how `wrap_period` should be handled when it is changed
- [x] ~~Add toggles to disable setting the clock as default?~~ No,
separate pull if needed.
- [x] Add tests
- [x] Reformat, ensure adheres to conventions etc.
- [x] Build documentation and see that it looks correct

## Contributors

Huge thanks to @alice-i-cecile and @maniwani while building this pull.
It was a shared effort!

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Cameron <51241057+maniwani@users.noreply.github.com>
Co-authored-by: Jerome Humbert <djeedai@gmail.com>
2023-10-16 01:57:55 +00:00
Carter Anderson
02943737b2
Return an error when loading non-existent labels (#9751)
# Objective

Calling `asset_server.load("scene.gltf#SomeLabel")` will silently fail
if `SomeLabel` does not exist.

Referenced in #9714 

## Solution

We now detect this case and return an error. I also slightly refactored
`load_internal` to make the logic / dataflow much clearer.

---------

Co-authored-by: Pascal Hertleif <killercup@gmail.com>
2023-10-15 18:36:51 +00:00
Carter Anderson
49d5c6b8a3
Hot reload labeled assets whose source asset is not loaded (#9736)
# Objective

As called out in #9714, Bevy Asset V2 fails to hot-reload labeled assets
whose source asset has changed (in cases where the root asset is not
alive).

## Solution

Track alive labeled assets for a given source asset and allow hot
reloads in cases where a labeled asset is still alive.
2023-10-15 18:21:49 +00:00
François
5781806e72
only set up processed source if asset plugin is not unprocessed (#10123)
# Objective

- Since #9885, running on an iOS device crashes trying to create the
processed folder
- This only happens on real device, not on the simulator

## Solution

- Setup processed assets only if needed
2023-10-15 18:20:29 +00:00
Carter Anderson
3866b1cc19
Fix load_folder for non-default Asset Sources (#10121)
# Objective

Fixes #10120

## Solution

Assign the folder path source to loaded descendant asset paths in
`load_folder`
2023-10-15 16:57:46 +00:00
Dimitri Belopopsky
56eb362327
Fix missing explicit lifetime name for copy_deferred_lighting_id name (#10128)
# Objective

On nightly there is a warning on a missing lifetime:

```bash
warning: `&` without an explicit lifetime name cannot be used here
```

The details are in https://github.com/rust-lang/rust/issues/115010, but
the bottom line is that in associated constants elided lifetimes are no
longer allowed to be implicitly defined.

This fixes the only place where it is missing.

## Solution

- Add explicit `'static` lifetime
2023-10-15 14:37:53 +00:00
Ame :]
b9ddb37d5b
add and fix shields in Readmes (#9993)
# Objective

Fix shields

## Solution

- Correct shield in the Bevy ECS Readme, where only the MIT license is
displayed
![Screenshot 2023-10-01 at 18 28
27](https://github.com/bevyengine/bevy/assets/104745335/a736a65e-0d47-4d9e-b32d-0b843a00922c)
- Add shields to other Readmes.
- homogenize shields and titles.
2023-10-15 00:52:31 +00:00
Dworv
ca37b92540
Make loading warning for no file ext more descriptive (#10119)
# Objective

Currently, the asset loader outputs 
```
2023-10-14T15:11:09.328850Z  WARN bevy_asset::asset_server: no `AssetLoader` found
```
when user forgets to add an extension to a file. This is very confusing
behaviour, it sounds like there aren't any asset loaders existing.

## Solution

Add an extra message on the end when there are no file extensions.
2023-10-14 22:54:57 +00:00
robtfm
d9a0761eb2
ssao use unlit_color instead of white (#10117)
# Objective

#10105 changed the ssao input color from the material base color to
white. i can't actually see a difference in the example but there should
be one in some cases.

## Solution

change it back.
2023-10-14 18:03:11 +00:00
Thomas Wilgenbus
4ae6a66481
Allow optional extraction of resources from the main world (#10109)
# Objective

From my understanding, although resources are not meant to be created
and removed at every frame, they are still meant to be created
dynamically during the lifetime of the App.
But because the extract_resource API does not allow optional resources
from the main world, it's impossible to use resources in the render
phase that were not created before the render sub-app itself.

## Solution

Because the ECS engine already allows for system parameters to be
`Option<Res>`, it just had to be added.

---

## Changelog

- Changed
    - `extract_resource` now takes an optional main world resource

- Fixed
- `ExtractResourcePlugin` doesn't cause panics anymore if the resource
is not already inserted
2023-10-14 16:07:49 +00:00
Carter Anderson
35073cf7aa
Multiple Asset Sources (#9885)
This adds support for **Multiple Asset Sources**. You can now register a
named `AssetSource`, which you can load assets from like you normally
would:

```rust
let shader: Handle<Shader> = asset_server.load("custom_source://path/to/shader.wgsl");
```

Notice that `AssetPath` now supports `some_source://` syntax. This can
now be accessed through the `asset_path.source()` accessor.

Asset source names _are not required_. If one is not specified, the
default asset source will be used:

```rust
let shader: Handle<Shader> = asset_server.load("path/to/shader.wgsl");
```

The behavior of the default asset source has not changed. Ex: the
`assets` folder is still the default.

As referenced in #9714

## Why?

**Multiple Asset Sources** enables a number of often-asked-for
scenarios:

* **Loading some assets from other locations on disk**: you could create
a `config` asset source that reads from the OS-default config folder
(not implemented in this PR)
* **Loading some assets from a remote server**: you could register a new
`remote` asset source that reads some assets from a remote http server
(not implemented in this PR)
* **Improved "Binary Embedded" Assets**: we can use this system for
"embedded-in-binary assets", which allows us to replace the old
`load_internal_asset!` approach, which couldn't support asset
processing, didn't support hot-reloading _well_, and didn't make
embedded assets accessible to the `AssetServer` (implemented in this pr)

## Adding New Asset Sources

An `AssetSource` is "just" a collection of `AssetReader`, `AssetWriter`,
and `AssetWatcher` entries. You can configure new asset sources like
this:

```rust
app.register_asset_source(
    "other",
    AssetSource::build()
        .with_reader(|| Box::new(FileAssetReader::new("other")))
    )
)
```

Note that `AssetSource` construction _must_ be repeatable, which is why
a closure is accepted.
`AssetSourceBuilder` supports `with_reader`, `with_writer`,
`with_watcher`, `with_processed_reader`, `with_processed_writer`, and
`with_processed_watcher`.

Note that the "asset source" system replaces the old "asset providers"
system.

## Processing Multiple Sources

The `AssetProcessor` now supports multiple asset sources! Processed
assets can refer to assets in other sources and everything "just works".
Each `AssetSource` defines an unprocessed and processed `AssetReader` /
`AssetWriter`.

Currently this is all or nothing for a given `AssetSource`. A given
source is either processed or it is not. Later we might want to add
support for "lazy asset processing", where an `AssetSource` (such as a
remote server) can be configured to only process assets that are
directly referenced by local assets (in order to save local disk space
and avoid doing extra work).

## A new `AssetSource`: `embedded`

One of the big features motivating **Multiple Asset Sources** was
improving our "embedded-in-binary" asset loading. To prove out the
**Multiple Asset Sources** implementation, I chose to build a new
`embedded` `AssetSource`, which replaces the old `load_interal_asset!`
system.

The old `load_internal_asset!` approach had a number of issues:

* The `AssetServer` was not aware of (or capable of loading) internal
assets.
* Because internal assets weren't visible to the `AssetServer`, they
could not be processed (or used by assets that are processed). This
would prevent things "preprocessing shaders that depend on built in Bevy
shaders", which is something we desperately need to start doing.
* Each "internal asset" needed a UUID to be defined in-code to reference
it. This was very manual and toilsome.

The new `embedded` `AssetSource` enables the following pattern:

```rust
// Called in `crates/bevy_pbr/src/render/mesh.rs`
embedded_asset!(app, "mesh.wgsl");

// later in the app
let shader: Handle<Shader> = asset_server.load("embedded://bevy_pbr/render/mesh.wgsl");
```

Notice that this always treats the crate name as the "root path", and it
trims out the `src` path for brevity. This is generally predictable, but
if you need to debug you can use the new `embedded_path!` macro to get a
`PathBuf` that matches the one used by `embedded_asset`.

You can also reference embedded assets in arbitrary assets, such as WGSL
shaders:

```rust
#import "embedded://bevy_pbr/render/mesh.wgsl"
```

This also makes `embedded` assets go through the "normal" asset
lifecycle. They are only loaded when they are actually used!

We are also discussing implicitly converting asset paths to/from shader
modules, so in the future (not in this PR) you might be able to load it
like this:

```rust
#import bevy_pbr::render::mesh::Vertex
```

Compare that to the old system!

```rust
pub const MESH_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(3252377289100772450);

load_internal_asset!(app, MESH_SHADER_HANDLE, "mesh.wgsl", Shader::from_wgsl);

// The mesh asset is the _only_ accessible via MESH_SHADER_HANDLE and _cannot_ be loaded via the AssetServer.
```

## Hot Reloading `embedded`

You can enable `embedded` hot reloading by enabling the
`embedded_watcher` cargo feature:

```
cargo run --features=embedded_watcher
```

## Improved Hot Reloading Workflow

First: the `filesystem_watcher` cargo feature has been renamed to
`file_watcher` for brevity (and to match the `FileAssetReader` naming
convention).

More importantly, hot asset reloading is no longer configured in-code by
default. If you enable any asset watcher feature (such as `file_watcher`
or `rust_source_watcher`), asset watching will be automatically enabled.

This removes the need to _also_ enable hot reloading in your app code.
That means you can replace this:

```rust
app.add_plugins(DefaultPlugins.set(AssetPlugin::default().watch_for_changes()))
```

with this:

```rust
app.add_plugins(DefaultPlugins)
```

If you want to hot reload assets in your app during development, just
run your app like this:

```
cargo run --features=file_watcher
```

This means you can use the same code for development and deployment! To
deploy an app, just don't include the watcher feature

```
cargo build --release
```

My intent is to move to this approach for pretty much all dev workflows.
In a future PR I would like to replace `AssetMode::ProcessedDev` with a
`runtime-processor` cargo feature. We could then group all common "dev"
cargo features under a single `dev` feature:

```sh
# this would enable file_watcher, embedded_watcher, runtime-processor, and more
cargo run --features=dev
```

## AssetMode

`AssetPlugin::Unprocessed`, `AssetPlugin::Processed`, and
`AssetPlugin::ProcessedDev` have been replaced with an `AssetMode` field
on `AssetPlugin`.

```rust
// before 
app.add_plugins(DefaultPlugins.set(AssetPlugin::Processed { /* fields here */ })

// after 
app.add_plugins(DefaultPlugins.set(AssetPlugin { mode: AssetMode::Processed, ..default() })
```

This aligns `AssetPlugin` with our other struct-like plugins. The old
"source" and "destination" `AssetProvider` fields in the enum variants
have been replaced by the "asset source" system. You no longer need to
configure the AssetPlugin to "point" to custom asset providers.

## AssetServerMode

To improve the implementation of **Multiple Asset Sources**,
`AssetServer` was made aware of whether or not it is using "processed"
or "unprocessed" assets. You can check that like this:

```rust
if asset_server.mode() == AssetServerMode::Processed {
    /* do something */
}
```

Note that this refactor should also prepare the way for building "one to
many processed output files", as it makes the server aware of whether it
is loading from processed or unprocessed sources. Meaning we can store
and read processed and unprocessed assets differently!

## AssetPath can now refer to folders

The "file only" restriction has been removed from `AssetPath`. The
`AssetServer::load_folder` API now accepts an `AssetPath` instead of a
`Path`, meaning you can load folders from other asset sources!

## Improved AssetPath Parsing

AssetPath parsing was reworked to support sources, improve error
messages, and to enable parsing with a single pass over the string.
`AssetPath::new` was replaced by `AssetPath::parse` and
`AssetPath::try_parse`.

## AssetWatcher broken out from AssetReader

`AssetReader` is no longer responsible for constructing `AssetWatcher`.
This has been moved to `AssetSourceBuilder`.


## Duplicate Event Debouncing

Asset V2 already debounced duplicate filesystem events, but this was
_input_ events. Multiple input event types can produce the same _output_
`AssetSourceEvent`. Now that we have `embedded_watcher`, which does
expensive file io on events, it made sense to debounce output events
too, so I added that! This will also benefit the AssetProcessor by
preventing integrity checks for duplicate events (and helps keep the
noise down in trace logs).

## Next Steps

* **Port Built-in Shaders**: Currently the primary (and essentially
only) user of `load_interal_asset` in Bevy's source code is "built-in
shaders". I chose not to do that in this PR for a few reasons:
1. We need to add the ability to pass shader defs in to shaders via meta
files. Some shaders (such as MESH_VIEW_TYPES) need to pass shader def
values in that are defined in code.
2. We need to revisit the current shader module naming system. I think
we _probably_ want to imply modules from source structure (at least by
default). Ideally in a way that can losslessly convert asset paths
to/from shader modules (to enable the asset system to resolve modules
using the asset server).
  3. I want to keep this change set minimal / get this merged first.
* **Deprecate `load_internal_asset`**: we can't do that until we do (1)
and (2)
* **Relative Asset Paths**: This PR significantly increases the need for
relative asset paths (which was already pretty high). Currently when
loading dependencies, it is assumed to be an absolute path, which means
if in an `AssetLoader` you call `context.load("some/path/image.png")` it
will assume that is the "default" asset source, _even if the current
asset is in a different asset source_. This will cause breakage for
AssetLoaders that are not designed to add the current source to whatever
paths are being used. AssetLoaders should generally not need to be aware
of the name of their current asset source, or need to think about the
"current asset source" generally. We should build apis that support
relative asset paths and then encourage using relative paths as much as
possible (both via api design and docs). Relative paths are also
important because they will allow developers to move folders around
(even across providers) without reprocessing, provided there is no path
breakage.
2023-10-13 23:17:32 +00:00
François
9290674060
GLTF loader: handle warning NODE_SKINNED_MESH_WITHOUT_SKIN (#9360)
# Objective

- According to the GLTF spec, it should not be possible to have a non
skinned mesh on a skinned node
> When the node contains skin, all mesh.primitives MUST contain JOINTS_0
and WEIGHTS_0 attributes
>
https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-node
- However, the reverse (a skinned mesh on a non skinned node) is just a
warning, see `NODE_SKINNED_MESH_WITHOUT_SKIN` in
https://github.com/KhronosGroup/glTF-Validator/blob/main/ISSUES.md#linkerror
- This causes a crash in Bevy because the bind group layout is made from
the mesh which is skinned, but filled from the entity which is not
```
thread '<unnamed>' panicked at 'wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(0, 5, Metal)>`
    In a set_bind_group command
      note: bind group = `<BindGroup-(27, 1, Metal)>`
    Bind group 2 expects 2 dynamic offsets. However 1 dynamic offset were provided.
```
- Blender can export GLTF files with this kind of issues

## Solution

- When a skinned mesh is only used on non skinned nodes, ignore skinned
information from the mesh and warn the user (this is what three.js is
doing)
- When a skinned mesh is used on both skinned and non skinned nodes, log
an error
2023-10-13 22:40:28 +00:00
Rob Parrett
05c87f3c01
Fix text2d view-visibility (#10100)
# Objective

Fixes #9676
Possible alternative to #9708

`Text2dBundles` are not currently drawn because the render-world-only
entities for glyphs that are created in `extract_text2d_sprite` are not
tracked by the per-view `VisibleEntities`.

## Solution

Add an `Option<Entity>` to `ExtractedSprite` that keeps track of the
original entity that caused a "glyph entity" to be created.

Use that in `queue_sprites` if it exists when checking view visibility.

## Benchmarks

Quick benchmarks. Average FPS over 1500 frames.

| bench | before fps | after fps | diff |
|-|-|-|-|
|many_sprites|884.93|879.00|🟡 -0.7%|
|bevymark -- --benchmark --waves 100 --per-wave 1000 --mode
sprite|75.99|75.93|🟡 -0.1%|
|bevymark -- --benchmark --waves 50 --per-wave 1000 --mode
mesh2d|32.85|32.58|🟡 -0.8%|
2023-10-13 19:14:31 +00:00
robtfm
979c4094d4
pbr shader cleanup (#10105)
# Objective

cleanup some pbr shader code. improve shader stage io consistency and
make pbr.wgsl (probably many people's first foray into bevy shader code)
a little more human-readable. also fix a couple of small issues with
deferred rendering.

## Solution

mesh_vertex_output: 
- rename to forward_io (to align with prepass_io)
- rename `MeshVertexOutput` to `VertexOutput` (to align with prepass_io)
- move `Vertex` from mesh.wgsl into here (to align with prepass_io)

prepass_io: 
- remove `FragmentInput`, use `VertexOutput` directly (to align with
forward_io)
- rename `VertexOutput::clip_position` to `position` (to align with
forward_io)

pbr.wgsl:
- restructure so we don't need `#ifdefs` on the actual entrypoint, use
VertexOutput and FragmentOutput in all cases and use #ifdefs to import
the right struct definitions.
- rearrange to make the flow clearer
- move alpha_discard up from `pbr_functions::pbr` to avoid needing to
call it on some branches and not others
- add a bunch of comments

deferred_lighting:
- move ssao into the `!unlit` block to reflect forward behaviour
correctly
- fix compile error with deferred + premultiply_alpha

## Migration Guide

in custom material shaders:
- `pbr_functions::pbr` no longer calls to
`pbr_functions::alpha_discard`. if you were using the `pbr` function in
a custom shader with alpha mask mode you now also need to call
alpha_discard manually
- rename imports of `bevy_pbr::mesh_vertex_output` to
`bevy_pbr::forward_io`
- rename instances of `MeshVertexOutput` to `VertexOutput`

in custom material prepass shaders:
- rename instances of `VertexOutput::clip_position` to
`VertexOutput::position`
2023-10-13 19:12:40 +00:00
Rob Parrett
26ecfcff43
Fix UI borders (#10078)
# Objective

Fixes #10069

## Solution

Extracted UI nodes were previously stored in a `SparseSet` and had a
predictable iteration order. UI borders and outlines relied on this. Now
they are stored in a HashMap and that is no longer true.

This adds `entity.index()` to the sort key for `TransparentUi` so that
the iteration order is predictable and the "border entities" that get
spawned during extraction are guaranteed to get drawn after their
respective container nodes again.

I **think** that everything still works for overlapping ui nodes etc,
because the z value / primary sort is still controlled by the "ui
stack."

Text above is just my current understanding. A rendering expert should
check this out.

I will do some more testing when I can.
2023-10-13 17:17:16 +00:00
Jan Češpivo
4a61f894b7
chore: Renamed RenderInstance trait to ExtractInstance (#10065)
# Objective

Fixes [#10061]

## Solution

Renamed `RenderInstance` to `ExtractInstance`, `RenderInstances` to
`ExtractedInstances` and `RenderInstancePlugin` to
`ExtractInstancesPlugin`
2023-10-13 17:06:53 +00:00
IceSentry
068e42a01f
Configurable colors for wireframe (#5303)
# Objective

- Make the wireframe colors configurable at the global level and the
single mesh level
- Based on https://github.com/bevyengine/bevy/pull/5314

This video shows what happens when playing with various settings from
the example


https://github.com/bevyengine/bevy/assets/8348954/1ee9aee0-fab7-4da8-bc5d-8d0562bb34e6

## Solution

- Add a `color` field to the `WireframeMaterial`
- Use a `WireframeColor` component to configure the color per entity
- Add a `default_color` field to `WireframeConfig` for global wireframes
or wireframes with no specified color.

## Notes

- Most of the docs and the general idea for `WireframeColor` came from
[UberLambda](https://github.com/UberLambda) in #3677 but the code ended
up completely different so I created a separate branch. ~~I'm not sure
how to correctly credit them on this PR.~~ (I re-created the commit but
I added them as co-author in the commit message)

~~Closes https://github.com/bevyengine/bevy/pull/3677~~
~~Closes https://github.com/bevyengine/bevy/pull/5301~~

~~https://github.com/bevyengine/bevy/pull/5314 should be merged before
this PR.~~
2023-10-13 00:06:24 +00:00
Griffin
a15d152635
Deferred Renderer (#9258)
# Objective

- Add a [Deferred
Renderer](https://en.wikipedia.org/wiki/Deferred_shading) to Bevy.
- This allows subsequent passes to access per pixel material information
before/during shading.
- Accessing this per pixel material information is needed for some
features, like GI. It also makes other features (ex. Decals) simpler to
implement and/or improves their capability. There are multiple
approaches to accomplishing this. The deferred shading approach works
well given the limitations of WebGPU and WebGL2.

Motivation: [I'm working on a GI solution for
Bevy](https://youtu.be/eH1AkL-mwhI)

# Solution
- The deferred renderer is implemented with a prepass and a deferred
lighting pass.
- The prepass renders opaque objects into the Gbuffer attachment
(`Rgba32Uint`). The PBR shader generates a `PbrInput` in mostly the same
way as the forward implementation and then [packs it into the
Gbuffer](ec1465559f/crates/bevy_pbr/src/render/pbr.wgsl (L168)).
- The deferred lighting pass unpacks the `PbrInput` and [feeds it into
the pbr()
function](ec1465559f/crates/bevy_pbr/src/deferred/deferred_lighting.wgsl (L65)),
then outputs the shaded color data.

- There is now a resource
[DefaultOpaqueRendererMethod](ec1465559f/crates/bevy_pbr/src/material.rs (L599))
that can be used to set the default render method for opaque materials.
If materials return `None` from
[opaque_render_method()](ec1465559f/crates/bevy_pbr/src/material.rs (L131))
the `DefaultOpaqueRendererMethod` will be used. Otherwise, custom
materials can also explicitly choose to only support Deferred or Forward
by returning the respective
[OpaqueRendererMethod](ec1465559f/crates/bevy_pbr/src/material.rs (L603))

- Deferred materials can be used seamlessly along with both opaque and
transparent forward rendered materials in the same scene. The [deferred
rendering
example](https://github.com/DGriffin91/bevy/blob/deferred/examples/3d/deferred_rendering.rs)
does this.

- The deferred renderer does not support MSAA. If any deferred materials
are used, MSAA must be disabled. Both TAA and FXAA are supported.

- Deferred rendering supports WebGL2/WebGPU. 

## Custom deferred materials
- Custom materials can support both deferred and forward at the same
time. The
[StandardMaterial](ec1465559f/crates/bevy_pbr/src/render/pbr.wgsl (L166))
does this. So does [this
example](https://github.com/DGriffin91/bevy_glowy_orb_tutorial/blob/deferred/assets/shaders/glowy.wgsl#L56).
- Custom deferred materials that require PBR lighting can create a
`PbrInput`, write it to the deferred GBuffer and let it be rendered by
the `PBRDeferredLightingPlugin`.
- Custom deferred materials that require custom lighting have two
options:
1. Use the base_color channel of the `PbrInput` combined with the
`STANDARD_MATERIAL_FLAGS_UNLIT_BIT` flag.
[Example.](https://github.com/DGriffin91/bevy_glowy_orb_tutorial/blob/deferred/assets/shaders/glowy.wgsl#L56)
(If the unlit bit is set, the base_color is stored as RGB9E5 for extra
precision)
2. A Custom Deferred Lighting pass can be created, either overriding the
default, or running in addition. The a depth buffer is used to limit
rendering to only the required fragments for each deferred lighting
pass. Materials can set their respective depth id via the
[deferred_lighting_pass_id](b79182d2a3/crates/bevy_pbr/src/prepass/prepass_io.wgsl (L95))
attachment. The custom deferred lighting pass plugin can then set [its
corresponding
depth](ec1465559f/crates/bevy_pbr/src/deferred/deferred_lighting.wgsl (L37)).
Then with the lighting pass using
[CompareFunction::Equal](ec1465559f/crates/bevy_pbr/src/deferred/mod.rs (L335)),
only the fragments with a depth that equal the corresponding depth
written in the material will be rendered.

Custom deferred lighting plugins can also be created to render the
StandardMaterial. The default deferred lighting plugin can be bypassed
with `DefaultPlugins.set(PBRDeferredLightingPlugin { bypass: true })`

---------

Co-authored-by: nickrart <nickolas.g.russell@gmail.com>
2023-10-12 22:10:38 +00:00
Tomato
c8fd390ced
Change AxisSettings livezone default (#10090)
# Objective

While using joysticks for player aiming, I noticed that there was as
`0.05` value snap on the axis. After searching through Bevy's code, I
saw it was the default livezone being at `0.95`. This causes any value
higher to snap to `1.0`. I think `1.0` and `-1.0` would be a better
default, as it gives all values to the joystick arc.
 
This default livezone stumped me for a bit as I thought either something
was broken or I was doing something wrong.

## Solution

Change the livezone defaults to ` livezone_upperbound: 1.0` and
`livezone_lowerbound: -1.0`.

---

## Migration Guide

If the default 0.05 was relied on, the default or gamepad `AxisSettings`
on the resource `GamepadSettings` will have to be changed.
2023-10-12 17:58:32 +00:00
Zachary Harrold
bb13d065d3
Removed once_cell (#10079)
# Objective

- Fixes #8303

## Solution

- Replaced 1 instance of `OnceBox<T>` with `OnceLock<T>` in
`NonGenericTypeCell`

## Notes

All changes are in the private side of Bevy, and appear to have no
observable change in performance or compilation time. This is purely to
reduce the quantity of direct dependencies in Bevy.
2023-10-12 10:20:07 +00:00
Nicola Papale
be8ff5d0e1
Extract common wireframe filters in type alias (#10080)
# Objective

- The filter type on the `apply_global_wireframe_material` system had
duplicate filter code and the `clippy::type_complexity` attribute.

## Solution

- Extract the common part of the filter into a type alias
2023-10-11 14:43:17 +00:00
ira
f8cbc735ba
Document that gizmo depth_bias has no effect in 2D (#10074) 2023-10-11 06:23:03 +00:00
IceSentry
e05a9f9315
use Material for wireframes (#5314)
# Objective

- Use the `Material` abstraction for the Wireframes
- Right now this doesn't have many benefits other than simplifying some
of the rendering code
- We can reuse the default vertex shader and avoid rendering
inconsistencies
- The goal is to have a material with a color on each mesh so this
approach will make it easier to implement
- Originally done in https://github.com/bevyengine/bevy/pull/5303 but I
decided to split the Material part to it's own PR and then adding
per-entity colors and globally configurable colors will be a much
simpler diff.

## Solution

- Use the new `Material` abstraction for the Wireframes

## Notes

It's possible this isn't ideal since this adds a
`Handle<WireframeMaterial>` to all the meshes compared to the original
approach that didn't need anything. I didn't notice any performance
impact on my machine.

This might be a surprising usage of `Material` at first, because
intuitively you only have one material per mesh, but the way it's
implemented you can have as many different types of materials as you
want on a mesh.

## Migration Guide
`WireframePipeline` was removed. If you were using it directly, please
create an issue explaining your use case.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-10-10 18:53:22 +00:00
pablo-lua
ca873e767f
Implement serialize and deserialize for some UI types (#10044)
# Objective

- Add serde Deserialize and Serialize for structs that doesn't implement
it, even if they could benefit from it

## Solution

- Derive these traits for the structs Style, BackgroundColor,
BorderColor and Outline.

---
2023-10-10 18:52:48 +00:00
Trashtalk217
e5f5ce5e97
Migrate Quat reflection strategy from "value" to "struct" (#10068)
Adopted from #8954, co-authored by @pyrotechnick 

# Objective

The Bevy ecosystem currently reflects `Quat` via "value" rather than the
more appropriate "struct" strategy. This behaviour is inconsistent to
that of similar types, i.e. `Vec3`. Additionally, employing the "value"
strategy causes instances of `Quat` to be serialised as a sequence `[x,
y, z, w]` rather than structures of shape `{ x, y, z, w }`.

The [comments surrounding the applicable
code](bec299fa6e/crates/bevy_reflect/src/impls/glam.rs (L254))
give context and historical reasons for this discrepancy:

```
// Quat fields are read-only (as of now), and reflection is currently missing
// mechanisms for read-only fields. I doubt those mechanisms would be added,
// so for now quaternions will remain as values. They are represented identically
// to Vec4 and DVec4, so you may use those instead and convert between.
```

This limitation has [since been lifted by the upstream
crate](374625163e),
glam.

## Solution

Migrating the reflect strategy of Quat from "value" to "struct" via
replacing `impl_reflect_value` with `impl_reflect_struct` resolves the
issue.

## Changelog

Migrated `Quat` reflection strategy to "struct" from "value"
Migration Guide

Changed Quat serialization/deserialization from sequences `[x, y, z, w]`
to structures `{ x, y, z, w }`.

---------

Co-authored-by: pyrotechnick <13998+pyrotechnick@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-10-09 22:01:42 +00:00
Elabajaba
665dbcbb21
wgpu 0.17 (#9302)
~~Currently blocked on an upstream bug that causes crashes when
minimizing/resizing on dx12 https://github.com/gfx-rs/wgpu/issues/3967~~
wgpu 0.17.1 is out which fixes it

# Objective

Keep wgpu up to date.

## Solution

Update wgpu and naga_oil.

Currently this depends on an unreleased (and unmerged) branch of
naga_oil, and hasn't been properly tested yet.

The wgpu side of this seems to have been an extremely trivial upgrade
(all the upgrade work seems to be in naga_oil). This also lets us remove
the workarounds for pack/unpack4x8unorm in the SSAO shaders.

Lets us close the dx12 part of
https://github.com/bevyengine/bevy/issues/8888

related: https://github.com/bevyengine/bevy/issues/9304

---

## Changelog

Update to wgpu 0.17 and naga_oil 0.9
2023-10-09 20:15:24 +00:00
Marco Buono
12a2f83edd
Add consuming builder methods for more ergonomic Mesh creation (#10056)
# Objective

- This PR aims to make creating meshes a little bit more ergonomic,
specifically by removing the need for intermediate mutable variables.

## Solution

- We add methods that consume the `Mesh` and return a mesh with the
specified changes, so that meshes can be entirely constructed via
builder-style calls, without intermediate variables;
- Methods are flagged with `#[must_use]` to ensure proper use;
- Examples are updated to use the new methods where applicable. Some
examples are kept with the mutating methods so that users can still
easily discover them, and also where the new methods wouldn't really be
an improvement.

## Examples

Before:

```rust
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vs);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, vns);
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, vts);
mesh.set_indices(Some(Indices::U32(tris)));
mesh
```

After:

```rust
Mesh::new(PrimitiveTopology::TriangleList)
    .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vs)
    .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vns)
    .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, vts)
    .with_indices(Some(Indices::U32(tris)))
```

Before:

```rust
let mut cube = Mesh::from(shape::Cube { size: 1.0 });

cube.generate_tangents().unwrap();

PbrBundle {
    mesh: meshes.add(cube),
    ..default()
}
```

After:

```rust
PbrBundle {
    mesh: meshes.add(
        Mesh::from(shape::Cube { size: 1.0 })
            .with_generated_tangents()
            .unwrap(),
    ),
    ..default()
}
```

---

## Changelog

- Added consuming builder methods for more ergonomic `Mesh` creation:
`with_inserted_attribute()`, `with_removed_attribute()`,
`with_indices()`, `with_duplicated_vertices()`,
`with_computed_flat_normals()`, `with_generated_tangents()`,
`with_morph_targets()`, `with_morph_target_names()`.
2023-10-09 19:47:41 +00:00
Kanabenki
569e2ac80f
Make builder types take and return Self (#10001)
# Objective

Closes #9955.

Use the same interface for all "pure" builder types: taking and
returning `Self` (and not `&mut Self`).

## Solution

Changed `DynamicSceneBuilder`, `SceneFilter` and `TableBuilder` to take
and return `Self`.

## Changelog

### Changed

- `DynamicSceneBuilder` and `SceneBuilder` methods in `bevy_ecs` now
take and return `Self`.

## Migration guide

When using `bevy_ecs::DynamicSceneBuilder` and `bevy_ecs::SceneBuilder`,
instead of binding the builder to a variable, directly use it. Methods
on those types now consume `Self`, so you will need to re-bind the
builder if you don't `build` it immediately.

Before:
```rust
let mut scene_builder = DynamicSceneBuilder::from_world(&world);
let scene = scene_builder.extract_entity(a).extract_entity(b).build();
```

After:
 ```rust
let scene = DynamicSceneBuilder::from_world(&world)
    .extract_entity(a)
    .extract_entity(b)
    .build();
```
2023-10-09 19:46:17 +00:00
Rob Parrett
39c68e3f92
More ergonomic spatial audio (#9800)
# Objective

Spatial audio was heroically thrown together at the last minute for Bevy
0.10, but right now it's a bit of a pain to use -- users need to
manually update audio sinks with the position of the listener / emitter.

Hopefully the migration guide entry speaks for itself.

## Solution

Add a new `SpatialListener` component and automatically update sinks
with the position of the listener and and emitter.

## Changelog

`SpatialAudioSink`s are now automatically updated with positions of
emitters and listeners.

## Migration Guide

Spatial audio now automatically uses the transform of the `AudioBundle`
and of an entity with a `SpatialListener` component.

If you were manually scaling emitter/listener positions, you can use the
`spatial_scale` field of `AudioPlugin` instead.

```rust

// Old

commands.spawn(
    SpatialAudioBundle {
        source: asset_server.load("sounds/Windless Slopes.ogg"),
        settings: PlaybackSettings::LOOP,
        spatial: SpatialSettings::new(listener_position, gap, emitter_position),
    },
);

fn update(
    emitter_query: Query<(&Transform, &SpatialAudioSink)>,
    listener_query: Query<&Transform, With<Listener>>,
) {
    let listener = listener_query.single();

    for (transform, sink) in &emitter_query {
        sink.set_emitter_position(transform.translation);
        sink.set_listener_position(*listener, gap);
    }
}

// New

commands.spawn((
    SpatialBundle::from_transform(Transform::from_translation(emitter_position)),
    AudioBundle {
        source: asset_server.load("sounds/Windless Slopes.ogg"),
        settings: PlaybackSettings::LOOP.with_spatial(true),
    },
));

commands.spawn((
    SpatialBundle::from_transform(Transform::from_translation(listener_position)),
    SpatialListener::new(gap),
));
```

## Discussion

I removed `SpatialAudioBundle` because the `SpatialSettings` component
was made mostly redundant, and without that it was identical to
`AudioBundle`.

`SpatialListener` is a bare component and not a bundle which is feeling
like a maybe a strange choice. That happened from a natural aversion
both to nested bundles and to duplicating `Transform` etc in bundles and
from figuring that it is likely to just be tacked on to some other
bundle (player, head, camera) most of the time.

Let me know what you think about these things / everything else.

---------

Co-authored-by: Mike <mike.hsu@gmail.com>
2023-10-09 19:43:56 +00:00
radiish
262846e702
reflect: TypePath part 2 (#8768)
# Objective

- Followup to #7184.
- ~Deprecate `TypeUuid` and remove its internal references.~ No longer
part of this PR.
- Use `TypePath` for the type registry, and (de)serialisation instead of
`std::any::type_name`.
- Allow accessing type path information behind proxies.

## Solution
- Introduce methods on `TypeInfo` and friends for dynamically querying
type path. These methods supersede the old `type_name` methods.
- Remove `Reflect::type_name` in favor of `DynamicTypePath::type_path`
and `TypeInfo::type_path_table`.
- Switch all uses of `std::any::type_name` in reflection, non-debugging
contexts to use `TypePath`.

---

## Changelog

- Added `TypePathTable` for dynamically accessing methods on `TypePath`
through `TypeInfo` and the type registry.
- Removed `type_name` from all `TypeInfo`-like structs.
- Added `type_path` and `type_path_table` methods to all `TypeInfo`-like
structs.
- Removed `Reflect::type_name` in favor of
`DynamicTypePath::reflect_type_path` and `TypeInfo::type_path`.
- Changed the signature of all `DynamicTypePath` methods to return
strings with a static lifetime.

## Migration Guide

- Rely on `TypePath` instead of `std::any::type_name` for all stability
guarantees and for use in all reflection contexts, this is used through
with one of the following APIs:
  - `TypePath::type_path` if you have a concrete type and not a value.
- `DynamicTypePath::reflect_type_path` if you have an `dyn Reflect`
value without a concrete type.
- `TypeInfo::type_path` for use through the registry or if you want to
work with the represented type of a `DynamicFoo`.
  
- Remove `type_name` from manual `Reflect` implementations.
- Use `type_path` and `type_path_table` in place of `type_name` on
`TypeInfo`-like structs.
- Use `get_with_type_path(_mut)` over `get_with_type_name(_mut)`.

## Note to reviewers

I think if anything we were a little overzealous in merging #7184 and we
should take that extra care here.

In my mind, this is the "point of no return" for `TypePath` and while I
think we all agree on the design, we should carefully consider if the
finer details and current implementations are actually how we want them
moving forward.

For example [this incorrect `TypePath` implementation for
`String`](3fea3c6c0b/crates/bevy_reflect/src/impls/std.rs (L90))
(note that `String` is in the default Rust prelude) snuck in completely
under the radar.
2023-10-09 19:33:03 +00:00
dependabot[bot]
92294de08d
Update toml_edit requirement from 0.19 to 0.20 (#10058)
Updates the requirements on [toml_edit](https://github.com/toml-rs/toml)
to permit the latest version.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ed597ebad1"><code>ed597eb</code></a>
chore: Release</li>
<li><a
href="257a0fdc59"><code>257a0fd</code></a>
docs: Update changelog</li>
<li><a
href="4b44f53a31"><code>4b44f53</code></a>
Merge pull request <a
href="https://redirect.github.com/toml-rs/toml/issues/617">#617</a> from
epage/update</li>
<li><a
href="7eaf286110"><code>7eaf286</code></a>
fix(parser): Failed on mixed inline tables</li>
<li><a
href="e1f20378a2"><code>e1f2037</code></a>
test: Verify with latest data</li>
<li><a
href="2f9253c9eb"><code>2f9253c</code></a>
chore: Update toml-test</li>
<li><a
href="c9b481cab5"><code>c9b481c</code></a>
test(toml): Ensure tables are used for validation</li>
<li><a
href="43d7f29cfd"><code>43d7f29</code></a>
Merge pull request <a
href="https://redirect.github.com/toml-rs/toml/issues/615">#615</a> from
toml-rs/renovate/actions-checkout-4.x</li>
<li><a
href="ef9b8372c8"><code>ef9b837</code></a>
chore(deps): update actions/checkout action to v4</li>
<li><a
href="d308188db7"><code>d308188</code></a>
chore: Release</li>
<li>Additional commits viewable in <a
href="https://github.com/toml-rs/toml/compare/v0.19.0...v0.20.2">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>
2023-10-09 11:55:16 +00:00
robtfm
d2dad4eed2
fix orthographic cluster aabb for spotlight culling (#9614)
# Objective

fix #9605

spotlight culling uses an incorrect cluster aabb for orthographic
projections: it does not take into account the near and far cluster
bounds at all.

## Solution

use z_near and z_far to determine cluster aabb in orthographic mode.

i'm not 100% sure this is the only change that's needed, but i am sure
this change is needed, and the example seems to work well now
(CLUSTERED_FORWARD_DEBUG_CLUSTER_LIGHT_COMPLEXITY shows good bounds
around the cone for a variety of orthographic setups).
2023-10-08 22:53:09 +00:00
Elabajaba
78e4bb2c2a
fix webgl2 crash (#10053)
# Objective

Webgl2 broke when pcf was merged.

Fixes #10048

## Solution

Change the `textureSampleCompareLevel` in shadow_sampling.wgsl to
`textureSampleCompare` to make it work again.
2023-10-08 22:07:16 +00:00
Robert Swain
b6286cf570
Fix 2d_shapes and general 2D mesh instancing (#10051)
# Objective

- Fix #10050 

## Solution

- Push constants needed to be defined in the pipeline layout and
`bevy_sprite` needed to have a `webgl` feature.
2023-10-08 20:17:01 +00:00
Patrick Walton
e67d63aa79
Refactor the render instance logic in #9903 so that it's easier for other components to adopt. (#10002)
# Objective

Currently, the only way for custom components that participate in
rendering to opt into the higher-performance extraction method in #9903
is to implement the `RenderInstances` data structure and the extraction
logic manually. This is inconvenient compared to the `ExtractComponent`
API.

## Solution

This commit creates a new `RenderInstance` trait that mirrors the
existing `ExtractComponent` method but uses the higher-performance
approach that #9903 uses. Additionally, `RenderInstance` is more
flexible than `ExtractComponent`, because it can extract multiple
components at once. This makes high-performance rendering components
essentially as easy to write as the existing ones based on component
extraction.

---

## Changelog

### Added

A new `RenderInstance` trait is available mirroring `ExtractComponent`,
but using a higher-performance method to extract one or more components
to the render world. If you have custom components that rendering takes
into account, you may consider migration from `ExtractComponent` to
`RenderInstance` for higher performance.
2023-10-08 10:34:44 +00:00