Commit graph

1784 commits

Author SHA1 Message Date
mgi388
1bb8007dce
Fix typo in sprite_picking.rs example (#15292)
Simple typo I noticed while reading example.
2024-09-19 00:46:40 +00:00
Patrick Walton
2ae5a21009
Implement percentage-closer soft shadows (PCSS). (#13497)
[*Percentage-closer soft shadows*] are a technique from 2004 that allow
shadows to become blurrier farther from the objects that cast them. It
works by introducing a *blocker search* step that runs before the normal
shadow map sampling. The blocker search step detects the difference
between the depth of the fragment being rasterized and the depth of the
nearby samples in the depth buffer. Larger depth differences result in a
larger penumbra and therefore a blurrier shadow.

To enable PCSS, fill in the `soft_shadow_size` value in
`DirectionalLight`, `PointLight`, or `SpotLight`, as appropriate. This
shadow size value represents the size of the light and should be tuned
as appropriate for your scene. Higher values result in a wider penumbra
(i.e. blurrier shadows).

When using PCSS, temporal shadow maps
(`ShadowFilteringMethod::Temporal`) are recommended. If you don't use
`ShadowFilteringMethod::Temporal` and instead use
`ShadowFilteringMethod::Gaussian`, Bevy will use the same technique as
`Temporal`, but the result won't vary over time. This produces a rather
noisy result. Doing better would likely require downsampling the shadow
map, which would be complex and slower (and would require PR #13003 to
land first).

In addition to PCSS, this commit makes the near Z plane for the shadow
map configurable on a per-light basis. Previously, it had been hardcoded
to 0.1 meters. This change was necessary to make the point light shadow
map in the example look reasonable, as otherwise the shadows appeared
far too aliased.

A new example, `pcss`, has been added. It demonstrates the
percentage-closer soft shadow technique with directional lights, point
lights, spot lights, non-temporal operation, and temporal operation. The
assets are my original work.

Both temporal and non-temporal shadows are rather noisy in the example,
and, as mentioned before, this is unavoidable without downsampling the
depth buffer, which we can't do yet. Note also that the shadows don't
look particularly great for point lights; the example simply isn't an
ideal scene for them. Nevertheless, I felt that the benefits of the
ability to do a side-by-side comparison of directional and point lights
outweighed the unsightliness of the point light shadows in that example,
so I kept the point light feature in.

Fixes #3631.

[*Percentage-closer soft shadows*]:
https://developer.download.nvidia.com/shaderlibrary/docs/shadow_PCSS.pdf

## Changelog

### Added

* Percentage-closer soft shadows (PCSS) are now supported, allowing
shadows to become blurrier as they stretch away from objects. To use
them, set the `soft_shadow_size` field in `DirectionalLight`,
`PointLight`, or `SpotLight`, as applicable.

* The near Z value for shadow maps is now customizable via the
`shadow_map_near_z` field in `DirectionalLight`, `PointLight`, and
`SpotLight`.

## Screenshots

PCSS off:
![Screenshot 2024-05-24
120012](https://github.com/bevyengine/bevy/assets/157897/0d35fe98-245b-44fb-8a43-8d0272a73b86)

PCSS on:
![Screenshot 2024-05-24
115959](https://github.com/bevyengine/bevy/assets/157897/83397ef8-1317-49dd-bfb3-f8286d7610cd)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Torstein Grindvik <52322338+torsteingrindvik@users.noreply.github.com>
2024-09-18 18:07:17 +00:00
no-materials
b884f96598
Implement enabled flag for fps overlay (#15246)
# Objective

Fixes #15223 

## Solution

Adds an `enabled` flag to the `FpsOverlayConfig` resource with a system
that detects it's change, and adjusts the visibility of the overlay text
entity.

## Testing

I extended the `fps_overlay` example with the option to toggle the
overlay. Run with:
```
cargo run --features="bevy_dev_tools" --example fps_overlay
```
2024-09-17 15:16:28 +00:00
Patrick Walton
3c41586154
Add EntityRefExcept and EntityMutExcept world queries, in preparation for generalized animation. (#15207)
This commit adds two new `WorldQuery` types: `EntityRefExcept` and
`EntityMutExcept`. These types work just like `EntityRef` and
`EntityMut`, but they prevent access to a statically-specified list of
components. For example, `EntityMutExcept<(AnimationPlayer,
Handle<AnimationGraph>)>` provides mutable access to all components
except for `AnimationPlayer` and `Handle<AnimationGraph>`. These types
are useful when you need to be able to process arbitrary queries while
iterating over the results of another `EntityMut` query.

The motivating use case is *generalized animation*, which is an upcoming
feature that allows animation of any component property, not just
rotation, translation, scaling, or morph weights. To implement this, we
must change the current `AnyOf<(&mut Transform, &mut MorphWeights)>` to
instead be `EntityMutExcept<(AnimationPlayer, Handle<AnimationGraph>)>`.
It's possible to use `FilteredEntityMut` in conjunction with a
dynamically-generated system instead, but `FilteredEntityMut` isn't
optimized for the use case of a large number of allowed components
coupled with a small set of disallowed components. No amount of
optimization of `FilteredEntityMut` produced acceptable performance on
the `many_foxes` benchmark. `Query<EntityMut, Without<AnimationPlayer>>`
will not suffice either, as it's legal and idiomatic for an
`AnimationTarget` and an `AnimationPlayer` to coexist on the same
entity.

An alternate proposal was to implement a somewhat-more-general
`Except<Q, CL>` feature, where Q is a `WorldQuery` and CL is a
`ComponentList`. I wasn't able to implement that proposal in a
reasonable way, because of the fact that methods like
`EntityMut::get_mut` and `EntityRef::get` are inherent methods instead
of methods on `WorldQuery`, and therefore there was no way to delegate
methods like `get` and `get_mut` to the inner query in a generic way.
Refactoring those methods into a trait would probably be possible.
However, I didn't see a use case for a hypothetical `Except` with
arbitrary queries: `Query<Except<(&Transform, &Visibility),
Visibility>>` would just be a complicated equivalent to
`Query<&Transform>`, for instance. So, out of a desire for simplicity, I
omitted a generic `Except` mechanism.

I've tested the performance of generalized animation on `many_foxes` and
found that, with this patch, `animate_targets` has a 7.4% slowdown over
`main`. With `FilteredEntityMut` optimized to use `Arc<Access>`, the
slowdown is 75.6%, due to contention on the reference count. Without
`Arc<Access>`, the slowdown is even worse, over 2x.

## Testing

New tests have been added that check that `EntityRefExcept` and
`EntityMutExcept` allow and disallow access to components properly and
that the query engine can correctly reject conflicting queries involving
those types.

A Tracy profile of `many_foxes` with 10,000 foxes showing generalized
animation using `FilteredEntityMut` (red) vs. main (yellow) is as
follows:

![Screenshot 2024-09-12
225914](https://github.com/user-attachments/assets/2993d74c-a513-4ba4-85bd-225672e7170a)

A Tracy profile of `many_foxes` with 10,000 foxes showing generalized
animation using this `EntityMutExcept` (yellow) vs. main (red) is as
follows:

![Screenshot 2024-09-14
205831](https://github.com/user-attachments/assets/4241015e-0c5d-44ef-835b-43f78a24e604)
2024-09-17 14:53:39 +00:00
Benjamin Brienen
29508f065f
Fix floating point math (#15239)
# Objective

- Fixes #15236

## Solution

- Use bevy_math::ops instead of std floating point operations.

## Testing

- Did you test these changes? If so, how?
Unit tests and `cargo run -p ci -- test`

- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
Execute `cargo run -p ci -- test` on Windows.

- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
Windows

## Migration Guide

- Not a breaking change
- Projects should use bevy math where applicable

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2024-09-16 23:28:12 +00:00
Taylor Neal
23a77ca5eb
Rename push children to add children (#15196)
# Objective

- Makes naming between add_child and add_children more consistent
- Fixes #15101 

## Solution

renamed push_children to add_children

## Testing

- Did you test these changes? If so, how?
Ran tests + grep search for any instance of `push_child`

- Are there any parts that need more testing?

- How can other people (reviewers) test your changes? Is there anything
specific they need to know?

- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
ran tests on WSL2

---

## Migration Guide

> This section is optional. If there are no breaking changes, you can
delete this section.

- If this PR is a breaking change (relative to the last release of
Bevy), describe how a user might need to migrate their code to support
these changes

rename any use of `push_children()` to the updated `add_children()`
2024-09-16 23:16:04 +00:00
Tero Laxström
522d82b21a
Fixing text sizes for examples (#15190)
# Objective

- Fixes #14265

## Solution

- Go through Pixel Eagle examples (and examples all in all)
- If default size is used it is usually left there
- If size of font is touched try dividing with 1.2 and round it to
nearest whole number

## Testing

- Run example before and after
- Make sure examples text are readable or like before cosmic-text change

---

## Showcase

Before:

![image](https://github.com/user-attachments/assets/beb2d5af-d1ee-4c2c-89c4-8e59c53b53b4)

After:

![image](https://github.com/user-attachments/assets/fef28a8d-dc26-4e0e-9870-6b216de906e8)
2024-09-16 23:14:37 +00:00
Tero Laxström
cf5afecd9f
Increase border_rect for TextureSlicer to match image (#15177)
# Objective

- Fixes #14550 

## Solution

Increased the _border_rect_ for _TextureSampler_ to match image.

## Testing

- Compiled main branch from source and made sure problem exists
- Applied fix and rebuild to make sure problem doesn't exist anymore

## Showcase

### main

After some clicking on the buttons problem exists on main branch:

![image](https://github.com/user-attachments/assets/29636390-f33d-495d-8068-e652c20c12f3)

### this PR
Can not get the problem with the fix:

![image](https://github.com/user-attachments/assets/b891f188-e025-49c0-8523-7a98cb784b19)
2024-09-16 23:12:13 +00:00
Gino Valente
37443e0f3f
bevy_reflect: Add DynamicTyped trait (#15108)
# Objective

Thanks to #7207, we now have a way to validate at the type-level that a
reflected value is actually the type it says it is and not just a
dynamic representation of that type.

`dyn PartialReflect` values _might_ be a dynamic type, but `dyn Reflect`
values are guaranteed to _not_ be a dynamic type.

Therefore, we can start to add methods to `Reflect` that weren't really
possible before. For example, we should now be able to always get a
`&'static TypeInfo`, and not just an `Option<&'static TypeInfo>`.

## Solution

Add the `DynamicTyped` trait.

This trait is similar to `DynamicTypePath` in that it provides a way to
use the non-object-safe `Typed` trait in an object-safe way.

And since all types that derive `Reflect` will also derive `Typed`, we
can safely add `DynamicTyped` as a supertrait of `Reflect`. This allows
us to use it when just given a `dyn Reflect` trait object.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```

---

## Showcase

`Reflect` now has a supertrait of `DynamicTyped`, allowing `TypeInfo` to
be retrieved from a `dyn Reflect` trait object without having to unwrap
anything!

```rust
let value: Box<dyn Reflect> = Box::new(String::from("Hello!"));

// BEFORE
let info: &'static TypeInfo = value.get_represented_type_info().unwrap();

// AFTER
let info: &'static TypeInfo = value.reflect_type_info();
```

## Migration Guide

`Reflect` now has a supertrait of `DynamicTyped`. If you were manually
implementing `Reflect` and did not implement `Typed`, you will now need
to do so.
2024-09-13 17:17:10 +00:00
Wybe Westra
ae80a20690
Reccomend using AssetPlugin.file_path instead of CARGO_MANIFEST_DIR (#15176)
Fixes #15175.

One question I have: I see that the scene_viewer example uses the
CARGO_MANIFEST_DIR. Should that line be removed, or would that break the
tool?

1fd478277e/examples/tools/scene_viewer/main.rs (L40)
2024-09-13 16:16:23 +00:00
Rich Churcher
c454db88a3
2580 Split examples PR feedback (#15181)
# Objective

Applies feedback from previous PR #15135 'cause it got caught up in the
merge train 🚂

I couldn't resist including roll, both for completeness and due to
playing too many games that implemented it as a child.

cc: @janhohenheim
2024-09-13 15:47:04 +00:00
charlotte
1fd478277e
Fix mesh 2d non indexed draw. (#15155)
Closes #15154. Looks like 2d was just missed in
d235d41af1.


![image](https://github.com/user-attachments/assets/1656d320-fed2-4a25-b2b0-14755e10faf7)
2024-09-12 12:38:56 +00:00
Klaas-Jan Boon
37316c7706
Fix "game_menu" example buttons not changing color on Interaction (#15153)
# Objective

Fixes #15079 , repairing the `game_menu` example

## Solution

- Changed the target component for the color updates from `UiImage` to
`BackgroundColor`.
- Changed the width of the `button_style` to `300px` to prevent overlap
with the text.

## Testing

Checked that buttons now correctly update their background color on
hover/exit/press.

---

## Showcase



https://github.com/user-attachments/assets/8f7ede9b-c271-4b59-91f9-27d9e3db1429
2024-09-11 00:49:27 +00:00
Rich Churcher
8e7ef64bb1
Split zoom/orbit into separate examples (#15135)
# Objective

As previously discussed, split camera zoom and orbiting examples to keep
things less cluttered. See discussion on #15092 for context.
2024-09-10 23:40:48 +00:00
UkoeHB
fa51e26052
Trim cosmic-text's shape run cache (#15037)
# Objective

- Fixes https://github.com/bevyengine/bevy/pull/14991. The `cosmic-text`
shape run cache requires manual cleanup for old text that no longer
needs to be cached.

## Solution

- Add a system to trim the cache.
- Add an `average fps` indicator to the `text_debug` example.

## Testing

Tested with `cargo run --example text_debug`.
- **No shape run cache**: 82fps with ~1fps variance.
- **Shape run cache no trim**: 90-100fps with ~2-4fps variance
- **Shape run cache trim age = 1**: 90-100fps with ~2-8fps variance
- **Shape run cache trim age = 2**: 90-100fps with ~2-4fps variance
- **Shape run cache trim age = 2000**: 80-120fps with ~2-6fps variance

The shape run cache seems to increase average FPS but also increases
frame time variance (when there is dynamic text).
2024-09-10 23:28:05 +00:00
Jan Hohenheim
4de67b5cdb
Improve first person camera in example (#15109)
# Objective

- I've seen quite a few people on discord copy-paste the camera code of
the first-person example and then run into problems with the pitch.
- ~~Additionally, the code is framerate-dependent.~~ it's not, see
comment in PR

## Solution

- Make the code good enough to be copy-pasteable 
- ~~Use `dt` to make the code framerate-independent~~ Add comment
explaining why we don't use `dt`
	- Clamp the pitch
- Move the camera sensitivity into a component for better
configurability

## Testing

Didn't run the example again, but the code is straight from another
project I have open, so I'm not worried.

---------

Co-authored-by: Antony <antony.m.3012@gmail.com>
2024-09-10 03:53:32 +00:00
Joona Aalto
afbbbd7335
Rename rendering components for improved consistency and clarity (#15035)
# Objective

The names of numerous rendering components in Bevy are inconsistent and
a bit confusing. Relevant names include:

- `AutoExposureSettings`
- `AutoExposureSettingsUniform`
- `BloomSettings`
- `BloomUniform` (no `Settings`)
- `BloomPrefilterSettings`
- `ChromaticAberration` (no `Settings`)
- `ContrastAdaptiveSharpeningSettings`
- `DepthOfFieldSettings`
- `DepthOfFieldUniform` (no `Settings`)
- `FogSettings`
- `SmaaSettings`, `Fxaa`, `TemporalAntiAliasSettings` (really
inconsistent??)
- `ScreenSpaceAmbientOcclusionSettings`
- `ScreenSpaceReflectionsSettings`
- `VolumetricFogSettings`

Firstly, there's a lot of inconsistency between `Foo`/`FooSettings` and
`FooUniform`/`FooSettingsUniform` and whether names are abbreviated or
not.

Secondly, the `Settings` post-fix seems unnecessary and a bit confusing
semantically, since it makes it seem like the component is mostly just
auxiliary configuration instead of the core *thing* that actually
enables the feature. This will be an even bigger problem once bundles
like `TemporalAntiAliasBundle` are deprecated in favor of required
components, as users will expect a component named `TemporalAntiAlias`
(or similar), not `TemporalAntiAliasSettings`.

## Solution

Drop the `Settings` post-fix from the component names, and change some
names to be more consistent.

- `AutoExposure`
- `AutoExposureUniform`
- `Bloom`
- `BloomUniform`
- `BloomPrefilter`
- `ChromaticAberration`
- `ContrastAdaptiveSharpening`
- `DepthOfField`
- `DepthOfFieldUniform`
- `DistanceFog`
- `Smaa`, `Fxaa`, `TemporalAntiAliasing` (note: we might want to change
to `Taa`, see "Discussion")
- `ScreenSpaceAmbientOcclusion`
- `ScreenSpaceReflections`
- `VolumetricFog`

I kept the old names as deprecated type aliases to make migration a bit
less painful for users. We should remove them after the next release.
(And let me know if I should just... not add them at all)

I also added some very basic docs for a few types where they were
missing, like on `Fxaa` and `DepthOfField`.

## Discussion

- `TemporalAntiAliasing` is still inconsistent with `Smaa` and `Fxaa`.
Consensus [on
Discord](https://discord.com/channels/691052431525675048/743663924229963868/1280601167209955431)
seemed to be that renaming to `Taa` would probably be fine, but I think
it's a bit more controversial, and it would've required renaming a lot
of related types like `TemporalAntiAliasNode`,
`TemporalAntiAliasBundle`, and `TemporalAntiAliasPlugin`, so I think
it's better to leave to a follow-up.
- I think `Fog` should probably have a more specific name like
`DistanceFog` considering it seems to be distinct from `VolumetricFog`.
~~This should probably be done in a follow-up though, so I just removed
the `Settings` post-fix for now.~~ (done)

---

## Migration Guide

Many rendering components have been renamed for improved consistency and
clarity.

- `AutoExposureSettings` → `AutoExposure`
- `BloomSettings` → `Bloom`
- `BloomPrefilterSettings` → `BloomPrefilter`
- `ContrastAdaptiveSharpeningSettings` → `ContrastAdaptiveSharpening`
- `DepthOfFieldSettings` → `DepthOfField`
- `FogSettings` → `DistanceFog`
- `SmaaSettings` → `Smaa`
- `TemporalAntiAliasSettings` → `TemporalAntiAliasing`
- `ScreenSpaceAmbientOcclusionSettings` → `ScreenSpaceAmbientOcclusion`
- `ScreenSpaceReflectionsSettings` → `ScreenSpaceReflections`
- `VolumetricFogSettings` → `VolumetricFog`

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-09-10 01:11:46 +00:00
Rich Churcher
b9b43ad89c
Add examples for orthographic and perspective zoom (#15092)
# Objective

Add examples for zooming (and orbiting) orthographic and perspective
cameras.

I'm pretty green with 3D, so please treat with suspicion! I note that
if/when #15075 is merged, `.scale` will go away so this example uses
`.scaling_mode`.

Closes #2580
2024-09-09 23:30:52 +00:00
Rich Churcher
f326705cab
Remove OrthographicProjection.scale (adopted) (#15075)
# Objective

Hello! I am adopting #11022 to resolve conflicts with `main`. tldr: this
removes `scale` in favour of `scaling_mode`. Please see the original PR
for explanation/discussion.

Also relates to #2580.

## Migration Guide

Replace all uses of `scale` with `scaling_mode`, keeping in mind that
`scale` is (was) a multiplier. For example, replace
```rust
    scale: 2.0,
    scaling_mode: ScalingMode::FixedHorizontal(4.0),

```
with
```rust
    scaling_mode: ScalingMode::FixedHorizontal(8.0),
```

---------

Co-authored-by: Stepan Koltsov <stepan.koltsov@gmail.com>
2024-09-09 22:34:58 +00:00
akimakinai
bafffe1c5f
Fix screenshot example (#15094)
# Objective

I noticed some issues in `screenshot` example:
1. Cursor icon won't return from `SystemCursorIcon::Progress` to default
icon, even though screen shot saving is done.
2. Panics when exiting window: ``called `Result::unwrap()` on an `Err`
value:
NoEntities("bevy_ecs::query::state::QueryState<bevy_ecs::entity::Entity,
bevy_ecs::query::filter::With<bevy_window:🪟:Window>>")``

## Solution

1. Caused by cursor updating system not responding to [`CursorIcon`
component
removal](5cfcbf47ed/examples/window/screenshot.rs (L38)).
I believe it should, so change it to react to
`RemovedComponents<CursorIcon>`. (a suggestion)
2. Use `get_single` for window.

## Testing

- run screenshot example

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-09-09 16:53:20 +00:00
ickshonpe
09d2292016
Add a border to the UI material example (#15120)
# Objective

There aren't any examples of how to draw a ui material with borders.

## Solution

Add border rendering to the `ui_material` example's shader.

## Showcase

<img width="395" alt="bordermat"
src="https://github.com/user-attachments/assets/109c59c1-f54b-4542-96f7-acff63f5057f">

---------

Co-authored-by: charlotte <charlotte.c.mcelwain@gmail.com>
2024-09-09 16:34:24 +00:00
Christian Hughes
79f6fcd1eb
EntityRef/Mut get_components (immutable variants only) (#15089)
# Objective

Smaller scoped version of #13375 without the `_mut` variants which
currently have unsoundness issues.

## Solution

Same as #13375, but without the `_mut` variants.

## Testing

- The same test from #13375 is reused.

---

## Migration Guide

- Renamed `FilteredEntityRef::components` to
`FilteredEntityRef::accessed_components` and
`FilteredEntityMut::components` to
`FilteredEntityMut::accessed_components`.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: Periwink <charlesbour@gmail.com>
2024-09-09 16:29:44 +00:00
Alix Bott
82e416dc48
Split OrthographicProjection::default into 2d & 3d (Adopted) (#15073)
Adopted PR from dmlary, all credit to them!
https://github.com/bevyengine/bevy/pull/9915

Original description:

# Objective

The default value for `near` in `OrthographicProjection` should be
different for 2d & 3d.

For 2d using `near = -1000` allows bevy users to build up scenes using
background `z = 0`, and foreground elements `z > 0` similar to css.
However in 3d `near = -1000` results in objects behind the camera being
rendered. Using `near = 0` works for 3d, but forces 2d users to assign
`z <= 0` for rendered elements, putting the background at some arbitrary
negative value.

There is no common value for `near` that doesn't result in a footgun or
usability issue for either 2d or 3d, so they should have separate
values.

There was discussion about other options in the discord
[0](https://discord.com/channels/691052431525675048/1154114310042292325),
but splitting `default()` into `default_2d()` and `default_3d()` seemed
like the lowest cost approach.

Related/past work https://github.com/bevyengine/bevy/issues/9138,
https://github.com/bevyengine/bevy/pull/9214,
https://github.com/bevyengine/bevy/pull/9310,
https://github.com/bevyengine/bevy/pull/9537 (thanks to @Selene-Amanita
for the list)

## Solution

This commit splits `OrthographicProjection::default` into `default_2d`
and `default_3d`.

## Migration Guide

- In initialization of `OrthographicProjection`, change `..default()` to
`..OrthographicProjection::default_2d()` or
`..OrthographicProjection::default_3d()`

Example:
```diff
--- a/examples/3d/orthographic.rs
+++ b/examples/3d/orthographic.rs
@@ -20,7 +20,7 @@ fn setup(
         projection: OrthographicProjection {
             scale: 3.0,
             scaling_mode: ScalingMode::FixedVertical(2.0),
-            ..default()
+            ..OrthographicProjection::default_3d()
         }
         .into(),
         transform: Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
```

---------

Co-authored-by: David M. Lary <dmlary@gmail.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2024-09-09 15:51:28 +00:00
charlotte
5eca832cee
Add convenience methods for constructing and setting storage buffer data (#15044)
Adds some methods to assist in building `ShaderStorageBuffer` without
using `bytemuck`. We keep the `&[u8]` constructors since this is still
modeled as a thin wrapper around the buffer descriptor, but should make
it easier to interact with at the cost of an extra allocation in the
`ShaderType` path for the buffer writer.

Follow up from #14663
2024-09-09 15:28:31 +00:00
Christian Hughes
e939d6c33f
Remove remnant EntityHash and related types from bevy_utils (#15039)
# Objective

`EntityHash` and related types were moved from `bevy_utils` to
`bevy_ecs` in #11498, but seemed to have been accidentally reintroduced
a week later in #11707.

## Solution

Remove the old leftover code.

---

## Migration Guide

- Uses of `bevy::utils::{EntityHash, EntityHasher, EntityHashMap,
EntityHashSet}` now have to be imported from `bevy::ecs::entity`.
2024-09-09 15:24:17 +00:00
JMS55
a0faf9cd01
More triangles/vertices per meshlet (#15023)
### Builder changes
- Increased meshlet max vertices/triangles from 64v/64t to 255v/128t
(meshoptimizer won't allow 256v sadly). This gives us a much greater
percentage of meshlets with max triangle count (128). Still not perfect,
we still end up with some tiny <=10 triangle meshlets that never really
get simplified, but it's progress.
- Removed the error target limit. Now we allow meshoptimizer to simplify
as much as possible. No reason to cap this out, as the cluster culling
code will choose a good LOD level anyways. Again leads to higher quality
LOD trees.
- After some discussion and consulting the Nanite slides again, changed
meshlet group error from _adding_ the max child's error to the group
error, to doing `group_error = max(group_error, max_child_error)`. Error
is already cumulative between LODs as the edges we're collapsing during
simplification get longer each time.
- Bumped the 65% simplification threshold to allow up to 95% of the
original geometry (e.g. accept simplification as valid even if we only
simplified 5% of the triangles). This gives us closer to
log2(initial_meshlet_count) LOD levels, and fewer meshlet roots in the
DAG.

Still more work to be done in the future here. Maybe trying METIS for
meshlet building instead of meshoptimizer.

Using ~8 clusters per group instead of ~4 might also make a big
difference. The Nanite slides say that they have 8-32 meshlets per
group, suggesting some kind of heuristic. Unfortunately meshopt's
compute_cluster_bounds won't work with large groups atm
(https://github.com/zeux/meshoptimizer/discussions/750#discussioncomment-10562641)
so hard to test.

Based on discussion from
https://github.com/bevyengine/bevy/discussions/14998,
https://github.com/zeux/meshoptimizer/discussions/750, and discord.

### Runtime changes
- cluster:triangle packed IDs are now stored 25:7 instead of 26:6 bits,
as max triangles per cluster are now 128 instead of 64
- Hardware raster now spawns 128 * 3 vertices instead of 64 * 3 vertices
to account for the new max triangles limit
- Hardware raster now outputs NaN triangles (0 / 0) instead of
zero-positioned triangles for extra vertex invocations over the cluster
triangle count. Shouldn't really be a difference idt, but I did it
anyways.
- Software raster now does 128 threads per workgroup instead of 64
threads. Each thread now loads, projects, and caches a vertex (vertices
0-127), and then if needed does so again (vertices 128-254). Each thread
then rasterizes one of 128 triangles.
- Fixed a bug with `needs_dispatch_remap`. I had the condition backwards
in my last PR, I probably committed it by accident after testing the
non-default code path on my GPU.
2024-09-08 17:55:57 +00:00
Alexander Stein
bbecc05da9
Fix comment in example (#15096)
Commit 65252bb87 (Consistently use `PI` to specify angles in examples.
(#5825)) changed from using push_children to add_child without adjusting
the comment

# Objective

- Fix the comments to align with the code

Co-authored-by: Alexander Stein <alexander.stein@mailbox.org>
2024-09-08 16:59:37 +00:00
François Mockers
5cfcbf47ed
fix imports in example ui_texture_slice_flip_and_tile (#15064)
# Objective

- don't use a sub crate in an example

## Solution

- fix imports
2024-09-06 06:00:43 +00:00
ickshonpe
8ac745ab10
UI texture slice texture flipping reimplementation (#15034)
# Objective

Fixes #15032

## Solution

Reimplement support for the `flip_x` and `flip_y` fields.
This doesn't flip the border geometry, I'm not really sure whether that
is desirable or not.
Also fixes a bug that was causing the side and center slices to tile
incorrectly.

### Testing

```
cargo run --example ui_texture_slice_flip_and_tile
```

## Showcase
<img width="787" alt="nearest"
src="https://github.com/user-attachments/assets/bc044bae-1748-42ba-92b5-0500c87264f6">
With tiling need to use nearest filtering to avoid bleeding between the
slices.

---------

Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-09-04 19:31:41 +00:00
Hamir Mahal
ec728c31c1
style: simplify string formatting for readability (#15033)
# Objective

The goal of this change is to improve code readability and
maintainability.
2024-09-03 23:35:49 +00:00
Chris Juchem
c620eb7833
Return Results from Camera's world/viewport conversion methods (#14989)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/14593.

## Solution

- Add `ViewportConversionError` and return it from viewport conversion
methods on Camera.

## Testing

- I successfully compiled and ran all changed examples.

## Migration Guide

The following methods on `Camera` now return a `Result` instead of an
`Option` so that they can provide more information about failures:
 - `world_to_viewport`
 - `world_to_viewport_with_depth`
 - `viewport_to_world`
 - `viewport_to_world_2d`

Call `.ok()` on the `Result` to turn it back into an `Option`, or handle
the `Result` directly.

---------

Co-authored-by: Lixou <82600264+DasLixou@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2024-09-03 19:45:15 +00:00
Steve Frampton
323aa70e3c
Utilise new method for 2d circle example. (#15022)
# Objective
Replaced the existing instantiation of the 2D Circle in the 2d_shapes.rs
file with the `new` method.
- Ensures consistency in instantiating 2D primitive shapes in the
examples.

## Solution
Replaced the existing instantiation of the 2D Circle in the 2d_shapes.rs
file with the `new` method.
- Ensures consistency in instantiating 2D primitive shapes in the
examples.

## Testing
- None: Should be straight-forward enough to not warrant a test (I will
eat my words if I am wrong).

---
2024-09-03 00:36:22 +00:00
Rob Parrett
659860dfe5
Cosmetic improvements for text_input example (#15016)
# Objective

Minor cosmetic improvements and code cleanup for this example

## Solution

- Use the default font and shorter constructor where the the full font
is not needed
- Use 12px padding for instruction text to match other examples
- Clean up formatting of instruction text
- Fix one instance of a font handle not being reused

<details>
<summary>Before / After</summary>


*Question mark boxes are expected. We don't include a font with the
glyphs I'm testing the IME with*

<img width="1280" alt="Screenshot 2024-09-02 at 11 14 17 AM"
src="https://github.com/user-attachments/assets/e0a904a3-c01b-4c18-b71f-41fbc1d09169">
<img width="1280" alt="Screenshot 2024-09-02 at 11 13 14 AM"
src="https://github.com/user-attachments/assets/4b2a2d31-6b9f-4b9a-a245-4258a6aa9519">
</details>

## Testing

Tested all functionality of the example (macOS)
2024-09-02 22:49:12 +00:00
Rob Parrett
86d5944b2e
Fix some examples having different instruction text positions (#15017)
# Objective

Thought I had found all of these... noticed some `10px` in #15013 and
did another sweep.

Continuation of #8478, #13583.

## Solution

- Position example text (and other elements) 12px from the edge of the
screen
2024-09-02 22:48:48 +00:00
Patrick Walton
d2624765d0
Implement animation masks, allowing fine control of the targets that animations affect. (#15013)
This commit adds support for *masks* to the animation graph. A mask is a
set of animation targets (bones) that neither a node nor its descendants
are allowed to animate. Animation targets can be assigned one or more
*mask group*s, which are specific to a single graph. If a node masks out
any mask group that an animation target belongs to, animation curves for
that target will be ignored during evaluation.

The canonical use case for masks is to support characters holding
objects. Typically, character animations will contain hand animations in
the case that the character's hand is empty. (For example, running
animations may close a character's fingers into a fist.) However, when
the character is holding an object, the animation must be altered so
that the hand grips the object.

Bevy currently has no convenient way to handle this. The only workaround
that I can see is to have entirely separate animation clips for
characters' hands and bodies and keep them in sync, which is burdensome
and doesn't match artists' expectations from other engines, which all
effectively have support for masks. However, with mask group support,
this task is simple. We assign each hand to a mask group and parent all
character animations to a node. When a character grasps an object in
hand, we position the fingers as appropriate and then enable the mask
group for that hand in that node. This allows the character's animations
to run normally, while the object remains correctly attached to the
hand.

Note that even with this PR, we won't have support for running separate
animations for a character's hand and the rest of the character. This is
because we're missing additive blending: there's no way to combine the
two masked animations together properly. I intend that to be a follow-up
PR.

The major engines all have support for masks, though the workflow varies
from engine to engine:

* Unity has support for masks [essentially as implemented here], though
with layers instead of a tree. However, when using the Mecanim
("Humanoid") feature, precise control over bones is lost in favor of
predefined muscle groups.

* Unreal has a feature named [*layered blend per bone*]. This allows for
separate blend weights for different bones, effectively achieving masks.
I believe that the combination of blend nodes and masks make Bevy's
animation graph as expressible as that of Unreal, once we have support
for additive blending, though you may have to use more nodes than you
would in Unreal. Moreover, separating out the concepts of "blend weight"
and "which bones this node applies to" seems like a cleaner design than
what Unreal has.

* Godot's `AnimationTree` has the notion of [*blend filters*], which are
essentially the same as masks as implemented in this PR.

Additionally, this patch fixes a bug with weight evaluation whereby
weights weren't properly propagated down to grandchildren, because the
weight evaluation for a node only checked its parent's weight, not its
evaluated weight. I considered submitting this as a separate PR, but
given that this PR refactors that code entirely to support masks and
weights under a unified "evaluated node" concept, I simply included the
fix here.

A new example, `animation_masks`, has been added. It demonstrates how to
toggle masks on and off for specific portions of a skin.

This is part of #14395, but I'm going to defer closing that issue until
we have additive blending.

[essentially as implemented here]:
https://docs.unity3d.com/560/Documentation/Manual/class-AvatarMask.html

[*layered blend per bone*]:
https://dev.epicgames.com/documentation/en-us/unreal-engine/using-layered-animations-in-unreal-engine

[*blend filters*]:
https://docs.godotengine.org/en/stable/tutorials/animation/animation_tree.html

## Migration Guide

* The serialized format of animation graphs has changed with the
addition of animation masks. To upgrade animation graph RON files, add
`mask` and `mask_groups` fields as appropriate. (They can be safely set
to zero.)
2024-09-02 17:10:34 +00:00
charlotte
a4640046fc
Adds ShaderStorageBuffer asset (#14663)
Adds a new `Handle<Storage>` asset type that can be used as a render
asset, particularly for use with `AsBindGroup`.

Closes: #13658 

# Objective

Allow users to create storage buffers in the main world without having
to access the `RenderDevice`. While this resource is technically
available, it's bad form to use in the main world and requires mixing
rendering details with main world code. Additionally, this makes storage
buffers easier to use with `AsBindGroup`, particularly in the following
scenarios:
- Sharing the same buffers between a compute stage and material shader.
We already have examples of this for storage textures (see game of life
example) and these changes allow a similar pattern to be used with
storage buffers.
- Preventing repeated gpu upload (see the previous easier to use `Vec`
`AsBindGroup` option).
- Allow initializing custom materials using `Default`. Previously, the
lack of a `Default` implement for the raw `wgpu::Buffer` type made
implementing a `AsBindGroup + Default` bound difficult in the presence
of buffers.

## Solution

Adds a new `Handle<Storage>` asset type that is prepared into a
`GpuStorageBuffer` render asset. This asset can either be initialized
with a `Vec<u8>` of properly aligned data or with a size hint. Users can
modify the underlying `wgpu::BufferDescriptor` to provide additional
usage flags.

## Migration Guide

The `AsBindGroup` `storage` attribute has been modified to reference the
new `Handle<Storage>` asset instead. Usages of Vec` should be converted
into assets instead.

---------

Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
2024-09-02 16:46:34 +00:00
Zachary Harrold
bc13161416
Migrated NonZero* to NonZero<*> (#14978)
# Objective

- Fixes #14974

## Solution

- Replace all* instances of `NonZero*` with `NonZero<*>`

## Testing

- CI passed locally.

---

## Notes

Within the `bevy_reflect` implementations for `std` types,
`impl_reflect_value!()` will continue to use the type aliases instead,
as it inappropriately parses the concrete type parameter as a generic
argument. If the `ZeroablePrimitive` trait was stable, or the macro
could be modified to accept a finite list of types, then we could fully
migrate.
2024-08-30 02:37:47 +00:00
Robert Walter
9e78433427
Curve gizmos integration (#14971)
# Objective

- Add gizmos integration for the new `Curve` things in the math lib

## Solution

- Add the following methods
  - `curve_2d(curve, sample_times, color)`
  - `curve_3d(curve, sample_times, color)`
  - `curve_gradient_2d(curve, sample_times_with_colors)`
  - `curve_gradient_3d(curve, sample_times_with_colors)`

## Testing

- I added examples of the 2D and 3D variants of the gradient curve
gizmos to the gizmos examples.

## Showcase

### 2D


![image](https://github.com/user-attachments/assets/01a75706-a7b4-4fc5-98d5-18018185c877)

```rust
    let domain = Interval::EVERYWHERE;
    let curve = function_curve(domain, |t| Vec2::new(t, (t / 25.0).sin() * 100.0));
    let resolution = ((time.elapsed_seconds().sin() + 1.0) * 50.0) as usize;
    let times_and_colors = (0..=resolution)
        .map(|n| n as f32 / resolution as f32)
        .map(|t| (t - 0.5) * 600.0)
        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
    gizmos.curve_gradient_2d(curve, times_and_colors);
```

### 3D


![image](https://github.com/user-attachments/assets/3fd23983-1ec9-46cd-baed-5b5e2dc935d0)

```rust
    let domain = Interval::EVERYWHERE;
    let curve = function_curve(domain, |t| {
        (Vec2::from((t * 10.0).sin_cos())).extend(t - 6.0)
    });
    let resolution = ((time.elapsed_seconds().sin() + 1.0) * 100.0) as usize;
    let times_and_colors = (0..=resolution)
        .map(|n| n as f32 / resolution as f32)
        .map(|t| t * 5.0)
        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
    gizmos.curve_gradient_3d(curve, times_and_colors);
```
2024-08-29 16:48:22 +00:00
Robert Walter
565324daa3
Improve the gizmo for Plane3d, reusing grid (#14650)
# Objective

With the current implementation of `Plane3d` gizmos, it's really hard to
get a good feeling for big planes. Usually I tend to add more axes as a
user but that doesn't scale well and is pretty wasteful. It's hard to
recognize the plane in the distance here. Especially if there would've
been other rendered objects in the scene


![image](https://github.com/user-attachments/assets/b65b7015-c08c-46d7-aa27-c7c0d49b2021)

## Solution

- Since we got grid gizmos in the mean time, I went ahead and just
reused them here.

## Testing

I added an instance of the new `Plane3D` to the `3d_gizmos.rs` example.
If you want to look at it you need to look around a bit. I didn't
position it in the center since that was too crowded already.

---

## Showcase


![image](https://github.com/user-attachments/assets/e4982afe-7296-416c-9801-7dd85cd975c1)

## Migration Guide

The optional builder methods on 

```rust

gizmos.primitive_3d(&Plane3d { }, ...);

```

changed from

- `segment_length`
- `segment_count`
- `axis_count`

to 

- `cell_count`
- `spacing`
2024-08-29 15:51:36 +00:00
Allen Pocket
d93b78a66e
Remove unnecessary muts in RenderSet::QueueMeshes (#14953)
# Objective

Fixes #14952
2024-08-28 11:38:38 +00:00
Robert Walter
210c79c9f9
Gizmos: arc_2d utility helpers (#14932)
# Objective

Since https://github.com/bevyengine/bevy/pull/14731 is merged, it
unblocked a few utility methods for 2D arcs. In 2D the pendant to
`long_arc_3d_between` and `short_arc_3d_between` are missing. Since
`arc_2d` can be a bit hard to use, this PR is trying to plug some holes
in the `arcs` API.

## Solution

Implement

- `long_arc_2d_between(center, from, tp, color)`
- `short_arc_2d_between(center, from, tp, color)`

## Testing

- There are new doc tests
- The `2d_gizmos` example has been extended a bit to include a few more
arcs which can easily be checked with respect to the grid

---

## Showcase


![image](https://github.com/user-attachments/assets/b90ad8b1-86c2-4304-a481-4f9a5246c457)

Code related to the screenshot (from outer = first line to inner = last
line)

```rust
    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
```
2024-08-28 11:33:11 +00:00
Robert Walter
8895113784
Use Isometry in bevy_gizmos wherever we can (#14676)
# Objective

- Solves the last bullet in and closes #14319
- Make better use of the `Isometry` types
- Prevent issues like #14655
- Probably simplify and clean up a lot of code through the use of Gizmos
as well (i.e. the 3D gizmos for cylinders circles & lines don't connect
well, probably due to wrong rotations)

## Solution

- go through the `bevy_gizmos` crate and give all methods a slight
workover

## Testing

- For all the changed examples I run `git switch main && cargo rr
--example <X> && git switch <BRANCH> && cargo rr --example <X>` and
compare the visual results
- Check if all doc tests are still compiling
- Check the docs in general and update them !!! 

---

## Migration Guide

The gizmos methods function signature changes as follows:

- 2D
- if it took `position` & `rotation_angle` before ->
`Isometry2d::new(position, Rot2::radians(rotation_angle))`
- if it just took `position` before ->
`Isometry2d::from_translation(position)`
- 3D
- if it took `position` & `rotation` before ->
`Isometry3d::new(position, rotation)`
- if it just took `position` before ->
`Isometry3d::from_translation(position)`
2024-08-28 01:37:19 +00:00
Shane
484721be80
Have EntityCommands methods consume self for easier chaining (#14897)
# Objective

Fixes #14883

## Solution

Pretty simple update to `EntityCommands` methods to consume `self` and
return it rather than taking `&mut self`. The things probably worth
noting:

* I added `#[allow(clippy::should_implement_trait)]` to the `add` method
because it causes a linting conflict with `std::ops::Add`.
* `despawn` and `log_components` now return `Self`. I'm not sure if
that's exactly the desired behavior so I'm happy to adjust if that seems
wrong.

## Testing

Tested with `cargo run -p ci`. I think that should be sufficient to call
things good.

## Migration Guide

The most likely migration needed is changing code from this:

```
        let mut entity = commands.get_or_spawn(entity);

        if depth_prepass {
            entity.insert(DepthPrepass);
        }
        if normal_prepass {
            entity.insert(NormalPrepass);
        }
        if motion_vector_prepass {
            entity.insert(MotionVectorPrepass);
        }
        if deferred_prepass {
            entity.insert(DeferredPrepass);
        }
```

to this:

```
        let mut entity = commands.get_or_spawn(entity);

        if depth_prepass {
            entity = entity.insert(DepthPrepass);
        }
        if normal_prepass {
            entity = entity.insert(NormalPrepass);
        }
        if motion_vector_prepass {
            entity = entity.insert(MotionVectorPrepass);
        }
        if deferred_prepass {
            entity.insert(DeferredPrepass);
        }
```

as can be seen in several of the example code updates here. There will
probably also be instances where mutable `EntityCommands` vars no longer
need to be mutable.
2024-08-26 18:24:59 +00:00
JoshValjosh
3540b87e17
Add bevy_picking sprite backend (#14757)
# Objective

Add `bevy_picking` sprite backend as part of the `bevy_mod_picking`
upstreamening (#12365).

## Solution

More or less a copy/paste from `bevy_mod_picking`, with the changes
[here](https://github.com/aevyrie/bevy_mod_picking/pull/354). I'm
putting that link here since those changes haven't yet made it through
review, so should probably be reviewed on their own.

## Testing

I couldn't find any sprite-backend-specific tests in `bevy_mod_picking`
and unfortunately I'm not familiar enough with Bevy's testing patterns
to write tests for code that relies on windowing and input. I'm willing
to break the pointer hit system into testable blocks and add some more
modular tests if that's deemed important enough to block, otherwise I
can open an issue for adding tests as follow-up.

## Follow-up work

- More docs/tests
- Ignore pick events on transparent sprite pixels with potential opt-out

---------

Co-authored-by: Aevyrie <aevyrie@gmail.com>
2024-08-26 18:01:32 +00:00
Robert Walter
6819e998c0
Fix arc_2d Gizmos (#14731)
# Objective

`arc_2d` wasn't actually doing what the docs were saying. The arc wasn't
offset by what was previously `direction_angle` but by `direction_angle
- arc_angle / 2.0`. This meant that the arcs center was laying on the
`Vec2::Y` axis and then it was offset. This was probably done to fit the
behavior of the `Arc2D` primitive. I would argue that this isn't
desirable for the plain `arc_2d` gizmo method since

- a) the docs get longer to explain the weird centering
- b) the mental model the user has to know gets bigger with more
implicit assumptions

given the code

```rust
    my_gizmos.arc_2d(Vec2::ZERO, 0.0, FRAC_PI_2, 75.0, ORANGE_RED);
```

we get


![image](https://github.com/user-attachments/assets/84894c6d-42e4-451b-b3e2-811266486ede)

where after the fix with

```rust
    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 75.0, ORANGE_RED);
```

we get


![image](https://github.com/user-attachments/assets/16b0aba0-f7b5-4600-ac49-a22be0315c40)

To get the same result with the previous implementation you would have
to randomly add `arc_angle / 2.0` to the `direction_angle`.

```rust
    my_gizmos.arc_2d(Vec2::ZERO, FRAC_PI_4, FRAC_PI_2, 75.0, ORANGE_RED);
```

This makes constructing similar helping functions as they already exist
in 3D like

- `long_arc_2d_between`
- `short_arc_2d_between`

 much harder.

## Solution

- Make the arc really start at `Vec2::Y * radius` in counter-clockwise
direction + offset by an angle as the docs state it
- Use `Isometry2d` instead of `position : Vec2` and `direction_angle :
f32` to reduce the chance of messing up rotation/translation
- Adjust the docs for the changes above
- Adjust the gizmo rendering of some primitives

## Testing

- check `2d_gizmos.rs` and `render_primitives.rs` examples

## Migration Guide

- users have to adjust their usages of `arc_2d`:
  - before: 
  ```rust
  arc_2d(
    pos,
    angle,
    arc_angle,
    radius,
    color
  )
  ```
  - after: 
  ```rust
  arc_2d(
// this `+ arc_angle * 0.5` quirk is only if you want to preserve the
previous behavior
    // with the new API.
// feel free to try to fix this though since your current calls to this
function most likely
// involve some computations to counter-act that quirk in the first
place
    Isometry2d::new(pos, Rot2::radians(angle + arc_angle * 0.5),
    arc_angle,
    radius,
    color
  )
  ```
2024-08-26 17:57:57 +00:00
JMS55
6cc96f4c1f
Meshlet software raster + start of cleanup (#14623)
# Objective
- Faster meshlet rasterization path for small triangles
- Avoid having to allocate and write out a triangle buffer
- Refactor gpu_scene.rs

## Solution
- Replace the 32bit visbuffer texture with a 64bit visbuffer buffer,
where the left 32 bits encode depth, and the right 32 bits encode the
existing cluster + triangle IDs. Can't use 64bit textures, wgpu/naga
doesn't support atomic ops on textures yet.
- Instead of writing out a buffer of packed cluster + triangle IDs (per
triangle) to raster, the culling pass now writes out a buffer of just
cluster IDs (per cluster, so less memory allocated, cheaper to write
out).
  - Clusters for software raster are allocated from the left side
- Clusters for hardware raster are allocated in the same buffer, from
the right side
- The buffer size is fixed at MeshletPlugin build time, and should be
set to a reasonable value for your scene (no warning on overflow, and no
good way to determine what value you need outside of renderdoc - I plan
to fix this in a future PR adding a meshlet stats overlay)
- Currently I don't have a heuristic for software vs hardware raster
selection for each cluster. The existing code is just a placeholder. I
need to profile on a release scene and come up with a heuristic,
probably in a future PR.
- The culling shader is getting pretty hard to follow at this point, but
I don't want to spend time improving it as the entire shader/pass is
getting rewritten/replaced in the near future.
- Software raster is a compute workgroup per-cluster. Each workgroup
loads and transforms the <=64 vertices of the cluster, and then
rasterizes the <=64 triangles of the cluster.
- Two variants are implemented: Scanline for clusters with any larger
triangles (still smaller than hardware is good at), and brute-force for
very very tiny triangles
- Once the shader determines that a pixel should be filled in, it does
an atomicMax() on the visbuffer to store the results, copying how Nanite
works
- On devices with a low max workgroups per dispatch limit, an extra
compute pass is inserted before software raster to convert from a 1d to
2d dispatch (I don't think 3d would ever be necessary).
- I haven't implemented the top-left rule or subpixel precision yet, I'm
leaving that for a future PR since I get usable results without it for
now
- Resources used:
https://kristoffer-dyrkorn.github.io/triangle-rasterizer and chapters
6-8 of
https://fgiesen.wordpress.com/2013/02/17/optimizing-sw-occlusion-culling-index
- Hardware raster now spawns 64*3 vertex invocations per meshlet,
instead of the actual meshlet vertex count. Extra invocations just
early-exit.
- While this is slower than the existing system, hardware draws should
be rare now that software raster is usable, and it saves a ton of memory
using the unified cluster ID buffer. This would be fixed if wgpu had
support for mesh shaders.
- Instead of writing to a color+depth attachment, the hardware raster
pass also does the same atomic visbuffer writes that software raster
uses.
- We have to bind a dummy render target anyways, as wgpu doesn't
currently support render passes without any attachments
- Material IDs are no longer written out during the main rasterization
passes.
- If we had async compute queues, we could overlap the software and
hardware raster passes.
- New material and depth resolve passes run at the end of the visbuffer
node, and write out view depth and material ID depth textures

### Misc changes
- Fixed cluster culling importing, but never actually using the previous
view uniforms when doing occlusion culling
- Fixed incorrectly adding the LOD error twice when building the meshlet
mesh
- Splitup gpu_scene module into meshlet_mesh_manager, instance_manager,
and resource_manager
- resource_manager is still too complex and inefficient (extract and
prepare are way too expensive). I plan on improving this in a future PR,
but for now ResourceManager is mostly a 1:1 port of the leftover
MeshletGpuScene bits.
- Material draw passes have been renamed to the more accurate material
shade pass, as well as some other misc renaming (in the future, these
will be compute shaders even, and not actual draw calls)

---

## Migration Guide
- TBD (ask me at the end of the release for meshlet changes as a whole)

---------

Co-authored-by: vero <email@atlasdostal.com>
2024-08-26 17:54:34 +00:00
charlotte
1caa64d948
Refactor AsBindGroup to use a associated SystemParam. (#14909)
# Objective

Adding more features to `AsBindGroup` proc macro means making the trait
arguments uglier. Downstream implementors of the trait without the proc
macro might want to do different things than our default arguments.

## Solution

Make `AsBindGroup` take an associated `Param` type.

## Migration Guide

`AsBindGroup` now allows the user to specify a `SystemParam` to be used
for creating bind groups.
2024-08-25 20:16:34 +00:00
Rob Parrett
2c3f5a00ac
Add AnimationGraph::from_clips and simplify animated_fox example (#14853)
# Objective

Add a convenience constructor to make simple animation graphs easier to
build.

I've had some notes about attempting this since #11989 that I just
remembered after seeing #14852.

This partially addresses #14852, but I don't really know animation well
enough to write all of the documentation it's asking for.

## Solution

Add `AnimationGraph::from_clips` and use it to simplify `animated_fox`.

Do some other little bits of incidental cleanup and documentation .

## Testing

I ran `cargo run --example animated_fox`.
2024-08-25 14:16:04 +00:00
IceSentry
d46a05e387
Simplify render_to_texture examples (#14855)
# Objective

- The examples use a more verbose than necessary way to initialize the
image
- The order of the camera doesn't need to be specified. At least I
didn't see a difference in my testing

## Solution

- Use `Image::new_fill()` to fill the image instead of abusing
`resize()`
- Remove the camera ordering
2024-08-25 14:15:11 +00:00
charlotte
d9527c101c
Rewrite screenshots. (#14833)
# Objective

Rewrite screenshotting to be able to accept any `RenderTarget`.

Closes #12478 

## Solution

Previously, screenshotting relied on setting a variety of state on the
requested window. When extracted, the window's `swap_chain_texture_view`
property would be swapped out with a texture_view created that frame for
the screenshot pipeline to write back to the cpu.

Besides being tightly coupled to window in a way that prevented
screenshotting other render targets, this approach had the drawback of
relying on the implicit state of `swap_chain_texture_view` being
returned from a `NormalizedRenderTarget` when view targets were
prepared. Because property is set every frame for windows, that wasn't a
problem, but poses a problem for render target images. Namely, to do the
equivalent trick, we'd have to replace the `GpuImage`'s texture view,
and somehow restore it later.

As such, this PR creates a new `prepare_view_textures` system which runs
before `prepare_view_targets` that allows a new `prepare_screenshots`
system to be sandwiched between and overwrite the render targets texture
view if a screenshot has been requested that frame for the given target.

Additionally, screenshotting itself has been changed to use a component
+ observer pattern. We now spawn a `Screenshot` component into the
world, whose lifetime is tracked with a series of marker components.
When the screenshot is read back to the CPU, we send the image over a
channel back to the main world where an observer fires on the screenshot
entity before being despawned the next frame. This allows the user to
access resources in their save callback that might be useful (e.g.
uploading the screenshot over the network, etc.).

## Testing


![image](https://github.com/user-attachments/assets/48f19aed-d9e1-4058-bb17-82b37f992b7b)


TODO:
- [x] Web
- [ ] Manual texture view

---

## Showcase

render to texture example:
<img
src="https://github.com/user-attachments/assets/612ac47b-8a24-4287-a745-3051837963b0"
width=200/>

web saving still works:
<img
src="https://github.com/user-attachments/assets/e2a15b17-1ff5-4006-ab2a-e5cc74888b9c"
width=200/>

## Migration Guide

`ScreenshotManager` has been removed. To take a screenshot, spawn a
`Screenshot` entity with the specified render target and provide an
observer targeting the `ScreenshotCaptured` event. See the
`window/screenshot` example to see an example.

---------

Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
2024-08-25 14:14:32 +00:00