Commit graph

7681 commits

Author SHA1 Message Date
akimakinai
61350cd36f
Remove components if not extracted (#15948)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/15871
(Camera is done in #15946)

## Solution

- Do the same as #15904 for other extraction systems
- Added missing `SyncComponentPlugin` for DOF, TAA, and SSAO
(According to the
[documentation](https://dev-docs.bevyengine.org/bevy/render/sync_component/struct.SyncComponentPlugin.html),
this plugin "needs to be added for manual extraction implementations."
We may need to check this is done.)

## Testing

Modified example locally to add toggles if not exist.
- [x] DOF - toggling DOF component and perspective in `depth_of_field`
example
- [x] TAA - toggling `Camera.is_active` and TAA component
- [x] clusters - not entirely sure, toggling `Camera.is_active` in
`many_lights` example (no crash/glitch even without this PR)
- [x] previous_view - toggling `Camera.is_active` in `skybox` (no
crash/glitch even without this PR)
- [x] lights - toggling `Visibility` of `DirectionalLight` in `lighting`
example
- [x] SSAO - toggling `Camera.is_active` and SSAO component in `ssao`
example
- [x] default UI camera view - toggling `Camera.is_active` (nop without
#15946 because UI defaults to some camera even if `DefaultCameraView` is
not there)
- [x] volumetric fog - toggling existence of volumetric light. Looks
like optimization, no change in behavior/visuals
2024-10-19 15:13:39 +00:00
Rafał Harabień
fe7f98f7f0
Fix deactivated camera still being used in render world (#15946)
# Objective

Switch to retained render world causes the extracted cameras in render
world to not be removed until camera in main world is despawned. When
extracting data from main world inactive cameras are skipped. Therefore
camera that was active and became inactive has a retained
`ExtractedCamera` component from previous frames (when it was active)
and is processed the same way as if it were active (there is no `active`
field on `ExtractedCamera`). This breakes switching between cameras in
`render_primitives` example.
Fixes #15822

## Solution

Fix it by removing `ExtractedCamera` and related components from
inactive cameras.
Note that despawning inactive camera seems to be bad option because they
are spawned using `SyncToRenderWorld` component.

## Testing

Switching camera in `render_primitives` example now works correctly.

---------

Co-authored-by: akimakinai <105044389+akimakinai@users.noreply.github.com>
2024-10-19 15:13:14 +00:00
Carter Anderson
d15d901cab
OIT style tweaks (#15999)
Just some very minor fixes to the OIT example.
2024-10-19 01:24:58 +00:00
IceSentry
fcf6067a10
Fix OIT depth test (#15991)
# Objective

- The depth test was only using the final depth but it should be testing
each fragments
- Fully transparent fragments should not be added to the list

## Solution

- Test each fragment after sorting

## Testing

before:
TODO

after:
TODO
2024-10-19 01:16:17 +00:00
Jake Swenson
16b39c2b36
examples(shaders/glsl): Update GLSL Shader Example Camera View uniform (#15865)
# Objective
The Custom Material GLSL shader example has an old version of the camera
view uniform structure.
This PR updates the example GLSL custom material shader to have the
latest structure.


## Solution

I was running into issues using the camera world position (it wasn't
changing) and someone in discord pointed me to the source of truth.
  `crates/bevy_render/src/view/view.wgsl`

After using this latest uniform structure in my project I'm now able to
work with the camera position in my shader.

## Testing
I tested this change by running the example with:
```bash
cargo run --features shader_format_glsl --example shader_material_glsl
```
<img width="1392" alt="image"
src="https://github.com/user-attachments/assets/39fc82ec-ff3b-4864-ad73-05f3a25db483">

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-10-19 01:08:55 +00:00
Rob Parrett
c65f2920bb
Fix animation_masks example's buttons (#15996)
# Objective

Fixes #15995

## Solution

Corrects a mistake made during the example migration in #15591.

`AnimationControl` was meant to be on the parent, not the child. So the
query in `update_ui` was no longer matching.

## Testing

`cargo run --example animation_masks`
2024-10-18 23:53:10 +00:00
Sou1gh0st
3a478ad5c1
Fix lightmaps break when deferred rendering is enabled (#14599)
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/13552

## Solution
- Thanks for the guidance from @DGriffin91, the current solution is to
transmit the light_map through the emissive channel to avoid increasing
the bandwidth of deferred shading.
- <del>Store lightmap sample result into G-Buffer and pass them into the
`Deferred Lighting Pipeline`, therefore we can get the correct indirect
lighting via the `apply_pbr_lighting` function.</del>
- <del>The original G-Buffer lacks storage for lightmap data, therefore
a new buffer is added. We can only use Rgba16Uint here due to the
32-byte limit on the render targets.</del>

## Testing
- Need to test all the examples that contains a prepass, with both the
forward and deferred rendering mode.
- I have tested the ones below.
- `lightmaps` (adjust the code based on the issue and check the
rendering result)
    - `transmission` (it contains a prepass)
    - `ssr` (it also uses the G-Bufffer)
    - `meshlet` (forward and deferred)
    - `pbr`

## Showcase
By updating the `lightmaps` example to use deferred rendering, this pull
request enables correct rendering result of the Cornell Box.

```
diff --git a/examples/3d/lightmaps.rs b/examples/3d/lightmaps.rs
index 564a3162b..11a748fba 100644
--- a/examples/3d/lightmaps.rs
+++ b/examples/3d/lightmaps.rs
@@ -1,12 +1,14 @@
 //! Rendering a scene with baked lightmaps.
 
-use bevy::pbr::Lightmap;
+use bevy::core_pipeline::prepass::DeferredPrepass;
+use bevy::pbr::{DefaultOpaqueRendererMethod, Lightmap};
 use bevy::prelude::*;
 
 fn main() {
     App::new()
         .add_plugins(DefaultPlugins)
         .insert_resource(AmbientLight::NONE)
+        .insert_resource(DefaultOpaqueRendererMethod::deferred())
         .add_systems(Startup, setup)
         .add_systems(Update, add_lightmaps_to_meshes)
         .run();
@@ -19,10 +21,12 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
         ..default()
     });
 
-    commands.spawn(Camera3dBundle {
-        transform: Transform::from_xyz(-278.0, 273.0, 800.0),
-        ..default()
-    });
+    commands
+        .spawn(Camera3dBundle {
+            transform: Transform::from_xyz(-278.0, 273.0, 800.0),
+            ..default()
+        })
+        .insert(DeferredPrepass);
 }
 
 fn add_lightmaps_to_meshes(
```

<img width="1280" alt="image"
src="https://github.com/user-attachments/assets/17fd3367-61cc-4c23-b956-e7cfc751af3c">

## Emissive Issue
**The emissive light object appears incorrectly rendered because the
alpha channel of emission is set to 1 in deferred rendering and 0 in
forward rendering, leading to different emissive light result. Could
this be a bug?**

```wgsl
// pbr_deferred_functions.wgsl - pbr_input_from_deferred_gbuffer
let emissive = rgb9e5::rgb9e5_to_vec3_(gbuffer.g);
if ((pbr.material.flags & STANDARD_MATERIAL_FLAGS_UNLIT_BIT) != 0u) {
    pbr.material.base_color = vec4(emissive, 1.0);
    pbr.material.emissive = vec4(vec3(0.0), 1.0);
} else {
    pbr.material.base_color = vec4(pow(base_rough.rgb, vec3(2.2)), 1.0);
    pbr.material.emissive = vec4(emissive, 1.0);
}

// pbr_functions.wgsl - apply_pbr_lighting
emissive_light = emissive_light * mix(1.0, view_bindings::view.exposure, emissive.a);
```

---------

Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2024-10-18 23:18:11 +00:00
Carter Anderson
015f2c69ca
Merge Style properties into Node. Use ComputedNode for computed properties. (#15975)
# Objective

Continue improving the user experience of our UI Node API in the
direction specified by [Bevy's Next Generation Scene / UI
System](https://github.com/bevyengine/bevy/discussions/14437)

## Solution

As specified in the document above, merge `Style` fields into `Node`,
and move "computed Node fields" into `ComputedNode` (I chose this name
over something like `ComputedNodeLayout` because it currently contains
more than just layout info. If we want to break this up / rename these
concepts, lets do that in a separate PR). `Style` has been removed.

This accomplishes a number of goals:

## Ergonomics wins

Specifying both `Node` and `Style` is now no longer required for
non-default styles

Before:
```rust
commands.spawn((
    Node::default(),
    Style {
        width:  Val::Px(100.),
        ..default()
    },
));
```

After:

```rust
commands.spawn(Node {
    width:  Val::Px(100.),
    ..default()
});
```

## Conceptual clarity

`Style` was never a comprehensive "style sheet". It only defined "core"
style properties that all `Nodes` shared. Any "styled property" that
couldn't fit that mold had to be in a separate component. A "real" style
system would style properties _across_ components (`Node`, `Button`,
etc). We have plans to build a true style system (see the doc linked
above).

By moving the `Style` fields to `Node`, we fully embrace `Node` as the
driving concept and remove the "style system" confusion.

## Next Steps

* Consider identifying and splitting out "style properties that aren't
core to Node". This should not happen for Bevy 0.15.

---

## Migration Guide

Move any fields set on `Style` into `Node` and replace all `Style`
component usage with `Node`.

Before:
```rust
commands.spawn((
    Node::default(),
    Style {
        width:  Val::Px(100.),
        ..default()
    },
));
```

After:

```rust
commands.spawn(Node {
    width:  Val::Px(100.),
    ..default()
});
```

For any usage of the "computed node properties" that used to live on
`Node`, use `ComputedNode` instead:

Before:
```rust
fn system(nodes: Query<&Node>) {
    for node in &nodes {
        let computed_size = node.size();
    }
}
```

After:
```rust
fn system(computed_nodes: Query<&ComputedNode>) {
    for computed_node in &computed_nodes {
        let computed_size = computed_node.size();
    }
}
```
2024-10-18 22:25:33 +00:00
Rob Parrett
624f573443
Fix pbr example camera scale (#15977)
# Objective

Fixes #15976

## Solution

I haven't been following the recent camera changes but on a whim I
inverted the scale and it restored the old behavior.

It seems that a similar inversion was done when migrating the
`pixel_grid_snap` example in #15976.

## Testing

`cargo run --example pbr`
2024-10-18 07:24:31 +00:00
VitalyR
eb19a9ea0b
Migrate UI bundles to required components (#15898)
# Objective

- Migrate UI bundles to required components, fixes #15889

## Solution

- deprecate `NodeBundle` in favor of `Node`
- deprecate `ImageBundle` in favor of `UiImage`
- deprecate `ButtonBundle` in favor of `Button`

## Testing

CI.

## Migration Guide

- Replace all uses of `NodeBundle` with `Node`. e.g.
```diff
     commands
-        .spawn(NodeBundle {
-            style: Style {
+        .spawn((
+            Node::default(),
+            Style {
                 width: Val::Percent(100.),
                 align_items: AlignItems::Center,
                 justify_content: JustifyContent::Center,
                 ..default()
             },
-            ..default()
-        })
+        ))
``` 
- Replace all uses of `ButtonBundle` with `Button`. e.g.
```diff
                     .spawn((
-                        ButtonBundle {
-                            style: Style {
-                                width: Val::Px(w),
-                                height: Val::Px(h),
-                                // horizontally center child text
-                                justify_content: JustifyContent::Center,
-                                // vertically center child text
-                                align_items: AlignItems::Center,
-                                margin: UiRect::all(Val::Px(20.0)),
-                                ..default()
-                            },
-                            image: image.clone().into(),
+                        Button,
+                        Style {
+                            width: Val::Px(w),
+                            height: Val::Px(h),
+                            // horizontally center child text
+                            justify_content: JustifyContent::Center,
+                            // vertically center child text
+                            align_items: AlignItems::Center,
+                            margin: UiRect::all(Val::Px(20.0)),
                             ..default()
                         },
+                        UiImage::from(image.clone()),
                         ImageScaleMode::Sliced(slicer.clone()),
                     ))
```
- Replace all uses of `ImageBundle` with `UiImage`. e.g.
```diff
-    commands.spawn(ImageBundle {
-        image: UiImage {
+    commands.spawn((
+        UiImage {
             texture: metering_mask,
             ..default()
         },
-        style: Style {
+        Style {
             width: Val::Percent(100.0),
             height: Val::Percent(100.0),
             ..default()
         },
-        ..default()
-    });
+    ));
 ```

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-10-17 21:11:02 +00:00
Clar Fon
683d6c90a9
Remove AVIF feature (#15973)
Resolves #15968. Since this feature never worked, and enabling it in the
`image` crate requires system dependencies, we've decided that it's best
to just remove it and let other plugin crates offer support for it as
needed.

## Migration Guide

AVIF images are no longer supported. They never really worked, and
require system dependencies (libdav1d) to work correctly, so, it's
better to simply offer this support via an unofficial plugin instead as
needed. The corresponding types have been removed from Bevy to account
for this.
2024-10-17 19:47:28 +00:00
Alice Cecile
2bd328220b
Improve API for scaling orthographic cameras (#15969)
# Objective

Fixes #15791.

As raised in #11022, scaling orthographic cameras is confusing! In Bevy
0.14, there were multiple completely redundant ways to do this, and no
clear guidance on which to use.

As a result, #15075 removed the `scale` field from
`OrthographicProjection` completely, solving the redundancy issue.

However, this resulted in an unintuitive API and a painful migration, as
discussed in #15791. Users simply want to change a single parameter to
zoom, rather than deal with the irrelevant details of how the camera is
being scaled.

## Solution

This PR reverts #15075, and takes an alternate, more nuanced approach to
the redundancy problem. `ScalingMode::WindowSize` was by far the biggest
offender. This was the default variant, and stored a float that was
*fully* redundant to setting `scale`.

All of the other variants contained meaningful semantic information and
had an intuitive scale. I could have made these unitless, storing an
aspect ratio, but this would have been a worse API and resulted in a
pointlessly painful migration.

In the course of this work I've also:

- improved the documentation to explain that you should just set `scale`
to zoom cameras
- swapped to named fields for all of the variants in `ScalingMode` for
more clarity about the parameter meanings
- substantially improved the `projection_zoom` example
- removed the footgunny `Mul` and `Div` impls for `ScalingMode`,
especially since these no longer have the intended effect on
`ScalingMode::WindowSize`.
- removed a rounding step because this is now redundant 🎉 

## Testing

I've tested these changes as part of my work in the `projection_zoom`
example, and things seem to work fine.

## Migration Guide

`ScalingMode` has been refactored for clarity, especially on how to zoom
orthographic cameras and their projections:

- `ScalingMode::WindowSize` no longer stores a float, and acts as if its
value was 1. Divide your camera's scale by any previous value to achieve
identical results.
- `ScalingMode::FixedVertical` and `FixedHorizontal` now use named
fields.

---------

Co-authored-by: MiniaczQ <xnetroidpl@gmail.com>
2024-10-17 17:50:06 +00:00
Rob Parrett
90b5ed6c93
Adjust some example text to match visual guidelines (#15966)
# Objective

Adjust instruction text in some newer examples to match the [example
visual
guidelines](https://bevyengine.org/learn/contribute/helping-out/creating-examples/#visual-guidelines).

## Solution

Move text 12px from edge of screen

## Testing

```
cargo run --example alter_mesh
cargo run --example alter_sprite
cargo run --example camera_orbit
cargo run --example projection_zoom
cargo run --example irradiance_volumes
cargo run --example log_layers_ecs
cargo run --example multi_asset_sync
cargo run --example multiple_windows
cargo run --example order_independent_transparency
```

## Additional information

This isn't comprehensive, just the most trivial cases. I'll double check
my notes and probably follow up with an issue to look into visual
guidelines for a few other examples.
2024-10-17 01:01:32 +00:00
Lynn
b4e04f9d9f
Remove write access to ConvexPolygon.vertices (#15965)
# Objective

- Fixes #15963

## Solution

- Implement `TryFrom<Polygon<N> for ConvexPolygon<N>`
- Implement `From<ConvexPolygon<N>> for Polygon<N>`
- Remove `pub` from `vertices`
- Add `ConvexPolygon::vertices()` to get read only access to the
vertices of a convex polygon.
2024-10-16 22:21:01 +00:00
Alice Cecile
76744bf58c
Mark ghost nodes as experimental and partially feature flag them (#15961)
# Objective

As discussed in #15341, ghost nodes are a contentious and experimental
feature. In the interest of enabling ecosystem experimentation, we've
decided to keep them in Bevy 0.15.

That said, we don't use them internally, and don't expect third-party
crates to support them. If the experimentation returns a negative result
(they aren't very useful, an alternative design is preferred etc) they
will be removed.

We should clearly communicate this status to users, and make sure that
users don't use ghost nodes in their projects without a very clear
understanding of what they're getting themselves into.

## Solution

To make life easy for users (and Bevy), `GhostNode` and all associated
helpers remain public and are always available.

However, actually constructing these requires enabling a feature flag
that's clearly marked as experimental. To do so, I've added a
meaningless private field.

When the feature flag is enabled, our constructs (`new` and `default`)
can be used. I've added a `new` constructor, which should be preferred
over `Default::default` as that can be readily deprecated, allowing us
to prompt users to swap over to the much nicer `GhostNode` syntax once
this is a unit struct again.

Full credit: this was mostly @cart's design: I'm just implementing it!

## Testing

I've run the ghost_nodes example and it fails to compile without the
feature flag. With the feature flag, it works fine :)

---------

Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2024-10-16 22:20:48 +00:00
Tim
f4d9c52c0d
Add read-only access to PointerInteraction (#15964)
# Objective
Re-add missing read-only access to `PointerInteraction`. This was missed
when bevy_mod_picking was upstreamed.
See
[here](https://docs.rs/bevy_mod_picking/latest/bevy_mod_picking/pointer/struct.PointerInteraction.html).
2024-10-16 21:21:19 +00:00
andristarr
7482a0d26d
aligning public apis of Time,Timer and Stopwatch (#15962)
Fixes #15834

## Migration Guide

The APIs of `Time`, `Timer` and `Stopwatch` have been cleaned up for
consistency with each other and the standard library's `Duration` type.
The following methods have been renamed:

- `Stowatch::paused` -> `Stopwatch::is_paused`
- `Time::elapsed_seconds` -> `Time::elasped_secs` (including `_f64` and
`_wrapped` variants)
2024-10-16 21:09:32 +00:00
François Mockers
7495d68b41
UI materials: don't reserve in loop when enough capacity (#15919)
# Objective

- UI materials reserve too much capacity in a vec: for every node in the
transparent phase, it reserves enough memory to store all the nodes
- Update #10437 

## Solution

- Only reserve extra memory if there's not enough
- Only reserve the needed memory, not more
2024-10-16 17:59:30 +00:00
Alice Cecile
ad9f197150
Update label used for breaking changes (#15958)
# Objective

This label was out-of-date, causing our nag-bot to fail to run.

## Solution

Update the workflow with the newly renamed label.

Companion to https://github.com/bevyengine/bevy-website/pull/1646.
2024-10-16 17:50:39 +00:00
François Mockers
e1b9f545fb
Introduce testbed examples starting with 2d (#15954)
# Objective

- Make progress for #15918 
- Start with 2d

## Solution

- Remove screenshots for existing examples as they're not deterministic
- Create new "testbed" example category, with a 2d one to start

## Testing

- Run `CI_TESTING_CONFIG=.github/example-run/testbed_2d.ron cargo run
--example testbed_2d --features "bevy_ci_testing"`
- ???
- Check the screenshots
2024-10-16 17:37:47 +00:00
ickshonpe
fc659a6143
Default UI shadow samples fix (#15953)
# Objective

In `queue_shadows`, the `UiBoxShadows` option is unwrapped incorrectly
which results in the number of shadow samples being set to
`u32::default()` instead of `UiBoxShadows::default()` if the camera
entity doesn't have the component.

## Solution

Just use `unwrap_or_default` directly without `map`.
2024-10-16 17:01:10 +00:00
ickshonpe
eb67c81059
Add shadows to ui example (#15952)
# Objective

Add some shadows to the stacked nodes in the ui example.

## Showcase

<img width="565" alt="ui-shadows"
src="https://github.com/user-attachments/assets/fc5d3c64-0fa6-4378-821e-a1bcbca641d9">
2024-10-16 16:47:11 +00:00
ickshonpe
396aff906e
Remove bevy_ui's "bevy_text" feature (#15951)
# Objective

Remove `bevy-ui`'s non-functional "bevy_text" feature.

Fixes #15900

## Solution

Remove all the "bevy_text" cfg gates.

I tried to fix it at first but couldn't figure it out. I'll happily
withdraw this in favour of another PR that gets the feature gate
working.
2024-10-16 16:43:57 +00:00
Rob Parrett
ab797630c5
Visual improvements to log_layers_ecs example (#15949)
# Objective

Beautify this example, and make adjustments for [example visual
guidelines](https://bevyengine.org/learn/contribute/helping-out/creating-examples/#visual-guidelines).

Also make the example less flaky in CI by removing system info and
window entity logs from the visual output.

## Solution

- Add padding to text container
- Add colors
- Other small tweaks

## Before
<img width="1280" alt="Screenshot 2024-10-16 at 7 04 00 AM"
src="https://github.com/user-attachments/assets/82886a31-e916-4ae1-a134-b95e8e12a052">

## After
<img width="1280" alt="Screenshot 2024-10-16 at 7 03 41 AM"
src="https://github.com/user-attachments/assets/5fa7ccda-971a-4b25-be50-3fcee4d3f967">


## Testing

`cargo run --example log_layer_ecs_improvements`
2024-10-16 16:42:35 +00:00
poopy
40b9a0ae52
register TextFont and TextColor in app type registry (#15950)
# Objective

`TextFont` and `TextColor` is not registered in the app type registry
and serializing a scene with a a `Text2d` doesn't save the color and
font of the text entity.

## Solution

register `TextFont`  and `TextColor`  in the type registry
2024-10-16 15:49:43 +00:00
Rafał Harabień
e4f501cb4a
Fix asset_settings example regression (#15945)
# Objective

In PR #15812 ImageLoader was moved from bevy_render to bevy_image but a
reference to old path was left in a meta file used by `asset_settings`
example. This resulted in one of sprites used by this example to not be
displayed.

Fixes #15932

## Solution

Correct the loader reference in the meta file used by `asset_settings`
example (I've found no other meta files referencing this loader).

## Testing

I've run `bevy_assets` example. It now displays 3 sprites (as expected)
and outputs no errors.

## Migration Guide

This PR obviously requires no migration guide as this is just a bug-fix,
but I believe that #15812 should mention that meta files needs updating.
Proposal:

* Asset loader name must be updated in `.meta` files for images.
Change: `loader: "bevy_render::texture::image_loader::ImageLoader",`
to: `loader: "bevy_image::image_loader::ImageLoader",`
It will fix the following error: ``no `AssetLoader` found with the name
'bevy_render::texture::image_loader::ImageLoader``
2024-10-16 14:16:23 +00:00
ickshonpe
6d3965f520
Overflow clip margin (#15561)
# Objective

Limited implementation of the CSS property `overflow-clip-margin`
https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-margin

Allows you to control the visible area for clipped content when using
overfllow-clip, -hidden, or -scroll and expand it with a margin.

Based on #15442

Fixes #15468

## Solution

Adds a new field to Style: `overflow_clip_margin: OverflowClipMargin`.
The field is ignored unless overflow-clip, -hidden or -scroll is set on
at least one axis.

`OverflowClipMargin` has these associated constructor functions:
```
pub const fn content_box() -> Self;
pub const fn padding_box() -> Self;
pub const fn border_box() -> Self;
```
You can also use the method `with_margin` to increases the size of the
visible area:
```
commands
  .spawn(NodeBundle {
      style: Style {
          width: Val::Px(100.),
          height: Val::Px(100.),
          padding: UiRect::all(Val::Px(20.)),
          border: UiRect::all(Val::Px(5.)),
          overflow: Overflow::clip(),
          overflow_clip_margin: OverflowClipMargin::border_box().with_margin(25.),
          ..Default::default()
      },
      border_color: Color::BLACK.into(),
      background_color: GRAY.into(),
      ..Default::default()
  })
```
`with_margin` expects a length in logical pixels, negative values are
clamped to zero.

## Notes
* To keep this PR as simple as possible I omitted responsive margin
values support. This could be added in a follow up if we want it.
* CSS also supports a `margin-box` option but we don't have access to
the margin values in `Node` so it's probably not feasible to implement
atm.

## Testing

```cargo run --example overflow_clip_margin```

<img width="396" alt="overflow-clip-margin" src="https://github.com/user-attachments/assets/07b51cd6-a565-4451-87a0-fa079429b04b">

## Migration Guide

Style has a new field `OverflowClipMargin`.  It allows users to set the visible area for clipped content when using overflow-clip, -hidden, or -scroll and expand it with a margin.

There are three associated constructor functions `content_box`, `padding_box` and `border_box`:
* `content_box`: elements painted outside of the content box area (the innermost part of the node excluding the padding and border) of the node are clipped. This is the new default behaviour.
* `padding_box`: elements painted outside outside of the padding area of the node are clipped. 
* `border_box`:  elements painted outside of the bounds of the node are clipped. This matches the behaviour from Bevy 0.14.

There is also a `with_margin` method that increases the size of the visible area by the given number in logical pixels, negative margin values are clamped to zero.

`OverflowClipMargin` is ignored unless overflow-clip, -hidden or -scroll is also set on at least one axis of the UI node.

---------

Co-authored-by: UkoeHB <37489173+UkoeHB@users.noreply.github.com>
2024-10-16 13:17:49 +00:00
mgi388
87c33da139
Fix typos from greyscale -> grayscale (#15947)
# Objective

I was grepping for "grayscale" and thought I'd fix these while I'm here
so I don't need to look for both forms.

## Solution

From [wikipedia]:

> In [digital
photography](https://en.wikipedia.org/wiki/Digital_photography),
[computer-generated
imagery](https://en.wikipedia.org/wiki/Computer-generated_imagery), and
[colorimetry](https://en.wikipedia.org/wiki/Colorimetry), a greyscale
(more common in [Commonwealth
English](https://en.wikipedia.org/wiki/Commonwealth_English)) or
grayscale (more common in [American
English](https://en.wikipedia.org/wiki/American_English))

[wikipedia]: https://en.wikipedia.org/wiki/Grayscale
2024-10-16 12:30:23 +00:00
andriyDev
b109787764
Delete ImageLoader::COUNT in favour of ImageLoader::SUPPORTED_FORMATS.len(). (#15939)
# Objective

- This is a followup to #15812.

## Solution

I just deleted the `COUNT` const and replaced it. I didn't realize for
loops are not const yet, so improving the other const variables is not
obvious.

Note: `slice::len` has been const since Rust 1.39, so we're not relying
on a brand new feature or anything.

## Testing

- It builds!
2024-10-16 00:50:50 +00:00
andriyDev
fbb53140e9
Fix bevy_color not compiling standalone. (#15938)
# Objective

On HEAD, `bevy_color` does not compile on its own with `--all-features`
enabled. This PR fixes that.

## Solution

- Added the `curve` feature on `bevy_math` to `bevy_color`.
- Added the `serialize` feature on `bevy_math` to
`bevy_color/serialize`.

## Testing

- Compiled with `cargo b -p bevy_color --all-features` on HEAD and on
this PR: it fails to compile on HEAD but compiles with this PR.
2024-10-15 23:52:45 +00:00
Zachary Harrold
a588ceeb49
Improve and Debug CI compile-check-no-std Command (#15935)
# Objective

- Fix bug where `cargo run -p ci` fails due to differing implementations
for default values between `Default` trait and `argh`
- Automatically install target via `rustup` to make first-run simpler.

## Solution

The command will now attempt to install the target via `rustup` by
default, which will provide a cleaner error message if a malformed
target is passed. It will also avoid confusion when people attempt to
use this tool for the first time without the target already installed.

I've added a flag, --skip-install, to disable the attempted installation
just-in-case. (e.g., maybe rustup isn't in their path but cargo is?).

Also fixed a bug where the default value for `target` was different
between the `Default` trait and `argh`, causing `cargo run -p ci` to
fail.

## Testing

- CI
- Subcommand ran directly

## Notes

This issue was originally discovered by @targrub (on Discord):

> Unfortunately, running `cargo run -p ci` still gives that same error
as I initially reported (though `cargo run -p ci --
compile-check-no-std` succeeds). This is after having run `rustup target
add x86_64-unknown-none`.
2024-10-15 23:45:23 +00:00
akimakinai
c78886e649
Remove ExtractComponent::Out (#15926)
# Objective

- `C: ExtractComponent` inserts `C::Out` instead of `C`, so we need to
remove `C::Out`. cc #15904.

## Solution

- `C` -> `C::Out`

## Testing

- CAS has `<ContrastAdaptiveSharpening as ExtractComponent>::Out =
(DenoiseCas, CasUniform)`. Setting its strength to zero correctly
removes the effect after this change.
2024-10-15 23:42:35 +00:00
Tau Gärtli
ed351294ec
Use #[doc(fake_variadic)] on StableInterpolate (#15933)
This is a follow-up to #15931 that adds `#[doc(fake_variadic)]` for
improved docs output :)
2024-10-15 23:40:42 +00:00
Shane Celis
5157fef84b
Add window drag move and drag resize without decoration example. (#15814)
# Objective

Add an example for the new drag move and drag resize introduced by PR
#15674 and fix #15734.

## Solution

I created an example that allows the user to exercise drag move and drag
resize separately. The user can also choose what direction the resize
works in.

![Screenshot 2024-10-10 at 4 06
43 AM](https://github.com/user-attachments/assets/1da558ab-a80f-49af-8b7d-bb635b0f038f)

### Name

The example is called `window_drag_move`. Happy to have that
bikeshedded.

### Contentious Refactor?

This PR removed the `ResizeDirection` enumeration in favor of using
`CompassOctant` which had the same variants. Perhaps this is
contentious.

### Unsafe?

In PR #15674 I mentioned that `start_drag_move()` and
`start_drag_resize()`'s requirement to only be called in the presence of
a left-click looks like a compiler-unenforceable contract that can cause
intermittent panics when not observed, so perhaps the functions should
be marked them unsafe. **I have not made that change** here since I
didn't see a clear consensus on that.

## Testing

I exercised this on x86 macOS. However, winit for macOS does not support
drag resize. It reports a good error when `start_drag_resize()` is
called. I'd like to see it tested on Windows and Linux.

---

## Showcase

Example window_drag_move shows how to drag or resize a window without
decoration.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-10-15 23:38:35 +00:00
Matty
a09104b62c
Infer StableInterpolate on tuples (#15931)
# Objective

Make `StableInterpolate` "just work" on tuples whose parts are each
`StableInterpolate` types. These types arise notably through
`Curve::zip` (or just through explicit mapping of a similar form). It
would otherwise be kind of frustrating to stumble upon such a thing and
then realize that, e.g., automatic resampling just doesn't work, even
though there is a very "obvious" way to do it.

## Solution

Infer `StableInterpolate` on tuples of up to size 11. I can make that
number bigger, if desired. Unfortunately, I don't think that our
standard "fake variadics" tools actually work for this; the anonymous
field accessors of tuples are `:tt` for purposes of macro expansion,
which means that you can't simplify away the identifiers by doing
something clever like using recursion (which would work if they were
`:expr`). Maybe someone who knows some incredibly dark magic could chime
in with a better solution.

The expanded impls look like this:
```rust
impl<
        T0: StableInterpolate,
        T1: StableInterpolate,
        T2: StableInterpolate,
        T3: StableInterpolate,
        T4: StableInterpolate,
    > StableInterpolate for (T0, T1, T2, T3, T4)
{
    fn interpolate_stable(&self, other: &Self, t: f32) -> Self {
        (
            <T0 as StableInterpolate>::interpolate_stable(&self.0, &other.0, t),
            <T1 as StableInterpolate>::interpolate_stable(&self.1, &other.1, t),
            <T2 as StableInterpolate>::interpolate_stable(&self.2, &other.2, t),
            <T3 as StableInterpolate>::interpolate_stable(&self.3, &other.3, t),
            <T4 as StableInterpolate>::interpolate_stable(&self.4, &other.4, t),
        )
    }
}
```

## Testing

Expanded macros; it compiles.

## Future

Make a version of the fake variadics workflow that supports this kind of
thing.
2024-10-15 19:55:36 +00:00
Joona Aalto
c1a4b82762
Revert default mesh materials (#15930)
# Objective

Closes #15799.

Many rendering people and maintainers are in favor of reverting default
mesh materials added in #15524, especially as the migration to required
component is already large and heavily breaking.

## Solution

Revert default mesh materials, and adjust docs accordingly.

- Remove `extract_default_materials`
- Remove `clear_material_instances`, and move the logic back into
`extract_mesh_materials`
- Remove `HasMaterial2d` and `HasMaterial3d`
- Change default material handles back to pink instead of white
- 2D uses `Color::srgb(1.0, 0.0, 1.0)`, while 3D uses `Color::srgb(1.0,
0.0, 0.5)`. Not sure if this is intended.

There is now no indication at all about missing materials for `Mesh2d`
and `Mesh3d`. Having a mesh without a material renders nothing.

## Testing

I ran `2d_shapes`, `mesh2d_manual`, and `3d_shapes`, with and without
mesh material components.
2024-10-15 19:47:40 +00:00
Rob Parrett
424e563184
Make contributors example deterministic in CI (#15901)
# Objective

- Make the example deterministic when run with CI, so that the
[screenshot
comparison](https://thebevyflock.github.io/bevy-example-runner/) is
stable
- Preserve the "truly random on each run" behavior so that every page
load in the example showcase shows a different contributor first

## Solution

- Fall back to the static default contributor list in CI
- Store contributors in a `Vec` so that we can show repeats of the
fallback contributor list, giving the appearance of lots of overlapping
contributors in CI
- Use a shared seeded RNG throughout the app
- Give contributor birds a `z` value so that their depth is stable
- Remove the shuffle, which was redundant because contributors are first
collected into a hashmap
- `chain` the systems so that the physics is deterministic from run to
run

## Testing

```bash
echo '(setup: (fixed_frame_time: Some(0.05)), events: [(100, Screenshot), (500, AppExit)])' > config.ron
CI_TESTING_CONFIG=config.ron cargo run --example contributors --features=bevy_ci_testing
mv screenshot-100.png screenshot-100-a.png
CI_TESTING_CONFIG=config.ron cargo run --example contributors --features=bevy_ci_testing
diff screenshot-100.png screenshot-100-a.png
```

## Alternatives

I'd also be fine with removing this example from the list of examples
that gets screenshot-tested in CI. Coverage from other 2d examples is
probably adequate.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-10-15 18:32:51 +00:00
andriyDev
15440c189b
Move SUPPORTED_FILE_EXTENSIONS to ImageLoader and remove unsupported formats. (#15917)
# Objective

Fixes #15730.

## Solution

As part of #15586, we made a constant to store all the supported image
formats. However since the `ImageFormat` does actually include Hdr and
OpenExr, it also included the `"hdr"` and `"exr"` file extensions. These
are supported by separate loaders though: `HdrTextureLoader` and
`ExrTextureLoader`. This led to a warning about duplicate asset loaders.

Therefore, instead of having the constant for `ImageFormat`, I made the
constant just for `ImageLoader`. This lets us correctly remove `"hdr"`
and `"exr"` from the image formats supported by `ImageLoader`, returning
us to having a single asset loader for every image format.

Note: we could have just removed `hdr` and `exr` from
`ImageFormat::SUPPORTED_FILE_EXTENSIONS`, but this would be very
confusing. Then the list of `ImageFormat`s would not match the list of
supported formats!

## Testing

- I ran the `sprite` example and got no warning! I also replaced the
sprite in that example with an HDR file and everything worked as
expected.
2024-10-15 18:06:34 +00:00
François Mockers
812e599f77
don't clip text that is rotated (#15925)
# Objective

- Fixes #15922 , #15853 
- Don't clip text that is rotated by some angles

## Solution

- Compare to the absolute size before clipping
2024-10-15 15:21:28 +00:00
Lucas
af93e78b72
Fix overflow panic on Stopwatch at Duration::MAX (#15927)
See #15924 for more details
close #15924

from the issue, this code panic:
```rust
use bevy::time::Stopwatch;
use std::time::Duration;

fn main() {
    let second = Duration::from_secs(1);

    let mut stopwatch = Stopwatch::new();
    // lot of time has passed... or a timer with Duration::MAX that was artificially set has "finished":
    // timer.set_elapsed(timer.remaining());
    stopwatch.set_elapsed(Duration::MAX);
    // panic
    stopwatch.tick(second);

    let mut stopwatch = Stopwatch::new();
    stopwatch.set_elapsed(Duration::MAX - second);
    // this doesnt panic as its still one off the max
    stopwatch.tick(second);
    // this panic
    stopwatch.tick(second);
}
```

with this PR changes, the code now doesn't panic.

have a good day !
2024-10-15 14:14:44 +00:00
Brett Striker
de08fb2afa
[bevy_ui/layout] Add tests, missing asserts, and missing debug fields for UiSurface (#12803)
This is 3 of 5 iterative PR's that affect bevy_ui/layout

- [x] Blocked by https://github.com/bevyengine/bevy/pull/12801
- [x] Blocked by https://github.com/bevyengine/bevy/pull/12802

---

# Objective

- Add tests to `UiSurface`
- Add missing asserts in `_assert_send_sync_ui_surface_impl_safe`
- Add missing Debug field print for `camera_entity_to_taffy`

## Solution

- Adds tests to `UiSurface`
- Adds missing asserts in `_assert_send_sync_ui_surface_impl_safe`
- Adds missing impl Debug field print for `camera_entity_to_taffy`

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-10-15 14:06:17 +00:00
akimakinai
4ac528a579
Despawn unused light-view entity (#15902)
# Objective

- Fixes #15897

## Solution

- Despawn light view entities when they go unused or when the
corresponding view is not alive.

## Testing

- `scene_viewer` example no longer prints "The preprocessing index
buffer wasn't present" warning
- modified an example to try toggling shadows for all kinds of light:
https://gist.github.com/akimakinai/ddb0357191f5052b654370699d2314cf
2024-10-15 13:54:09 +00:00
charlotte
acbed6040e
Attempt to remove component from render world if not extracted. (#15904)
# Objective

Ensure that components that are conditionally extracted do not linger in
the render world when not extracted from the main world.

## Solution

If the `ExtractComponent` returns `None`, we'll remove the render world
component. I think this is the most sensible behavior here. In the
future if there really is a use case for keeping the previous render
component around, we could add a `Option<Self::Out>` parameter for the
previous render component to the method, or something similar. I think
that this follows the principle of least surprise here relative to what
`None` would suggest and the way that render nodes are typically
written. The alternative would be to add an `enabled` field to pretty
much every camera settings component, or duplicate the extraction
condition as #15856 does.

## Testing

`transmission` no longer crashes.

## Migration Guide

Components that implement `ExtractComponent` and return `None` will
cause the extracted component to be removed from the render world.
2024-10-15 04:21:53 +00:00
Zachary Harrold
c1bb4b255d
[Adopted] Add a method for asynchronously waiting for an asset to load (#15913)
# Objective

Currently, is is very painful to wait for an asset to load from the
context of an `async` task. While bevy's `AssetServer` is asynchronous
at its core, the public API is mainly focused on being used from
synchronous contexts such as bevy systems. Currently, the best way of
waiting for an asset handle to finish loading is to have a system that
runs every frame, and either listens for `AssetEvents` or manually polls
the asset server. While this is an acceptable interface for bevy
systems, it is extremely awkward to do this in a way that integrates
well with the `async` task system. At my work we had to create our own
(inefficient) abstraction that encapsulated the boilerplate of checking
an asset's load status and waking up a task when it's done.

## Solution

Add the method `AssetServer::wait_for_asset`, which returns a future
that suspends until the asset associated with a given `Handle` either
finishes loading or fails to load.

## Testing

- CI

## Notes

This is an adoption of #14431, the above description is directly from
that original PR.

---------

Co-authored-by: Joseph <21144246+JoJoJet@users.noreply.github.com>
Co-authored-by: andriyDev <andriydzikh@gmail.com>
2024-10-15 02:50:33 +00:00
Benjamin Brienen
63a3a987c6
Fix detailed_trace module scope (#15912)
# Objective

Fixes #15615

## Solution

`$crate` is a cool keyword metavariable

## Testing

Created a test crate and used the macro

## Showcase

![image](https://github.com/user-attachments/assets/f0567224-126d-44e4-8905-26103da4ba14)
2024-10-15 02:48:36 +00:00
Matty
8a655e4d27
Add module-level docs for Curve (#15905)
# Objective

Improve the average user's ability to understand what the heck is going
on with the Curve API.

## Solution

I wrote some docs. I doubt these are perfect; I'm probably far too close
to this for that to be the case. :)
2024-10-15 02:45:45 +00:00
MiniaczQ
e5e44888c6
Validate param benchmarks (#15885)
# Objective

Benchmark overhead of validation for:
- `DynSystemParam`,
- `ParamSet`,
- combinator systems.

Needed for #15606

## Solution

As noted in objective, I've added 3 benchmarks, where each uses an
excessive amount of the specific functionality.
I benchmark on the level of schedules, rather than individual
`validate_param` calls, so we get a better idea how changes to the code
impact memory-lookup, etc. related side effects.

## Testing

```
param/combinator_system/8_piped_systems
                        time:   [1.7560 µs 1.7865 µs 1.8180 µs]
                        change: [+4.5244% +6.7955% +9.1413%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) high mild
  1 (1.00%) high severe

param/combinator_system/8_dyn_params_system
                        time:   [89.354 ns 89.790 ns 90.300 ns]
                        change: [+0.6751% +1.6825% +2.6842%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 9 outliers among 100 measurements (9.00%)
  6 (6.00%) high mild
  3 (3.00%) high severe

param/combinator_system/8_variant_param_set_system
                        time:   [88.295 ns 89.202 ns 90.208 ns]
                        change: [+0.1320% +1.0060% +1.8482%] (p = 0.02 < 0.05)
                        Change within noise threshold.
Found 4 outliers among 100 measurements (4.00%)
  4 (4.00%) high mild
```

2 back-to-back runs of the benchmarks, there is quire a lot of noise,
can use feedback on fixing that
2024-10-15 02:38:22 +00:00
Rob Parrett
d17de6c105
Fix panic due to malformed mesh in specialized_mesh_pipeline (#15899)
# Objective

Fixes #15891

## Solution

Just remove the invalid triangle. I'm assuming that line of code was
originally copied from one that was drawing a quad.

## Testing

- `cargo run --example specialized_mesh_pipeline`
- hover over over the triangles

Tested on macos
2024-10-15 02:34:33 +00:00
MiniaczQ
f602edad09
Text Rework cleanup (#15887)
# Objective

Cleanup naming and docs, add missing migration guide after #15591 

All text root nodes now use `Text` (UI) / `Text2d`.
All text readers/writers use `Text<Type>Reader`/`Text<Type>Writer`
convention.

---

## Migration Guide

Doubles as #15591 migration guide.

Text bundles (`TextBundle` and `Text2dBundle`) were removed in favor of
`Text` and `Text2d`.
Shared configuration fields were replaced with `TextLayout`, `TextFont`
and `TextColor` components.
Just `TextBundle`'s additional field turned into `TextNodeFlags`
component,
while `Text2dBundle`'s additional fields turned into `TextBounds` and
`Anchor` components.

Text sections were removed in favor of hierarchy-based approach.
For root text entities with `Text` or `Text2d` components, child
entities with `TextSpan` will act as additional text sections.
To still access text spans by index, use the new `TextUiReader`,
`Text2dReader` and `TextUiWriter`, `Text2dWriter` system parameters.
2024-10-15 02:32:34 +00:00
andriyDev
73f7fd0c12
Move ImageLoader and CompressedImageSaver to bevy_image. (#15812)
# Objective

This is a follow-up to #15650. While the core `Image` stuff moved from
`bevy_render` to `bevy_image`, the `ImageLoader` and the
`CompressedImageSaver` remained in `bevy_render`.

## Solution

I moved `ImageLoader` and `CompressedImageSaver` to `bevy_image` and
re-exported everything out from `bevy_render`. The second step isn't
strictly necessary, but `bevy_render` is already doing this for all the
other `bevy_image` types, so I kept it the same for consistency.

Unfortunately I had to give `ImageLoader` a constructor so I can keep
the `RenderDevice` stuff in `bevy_render`.

## Testing

It compiles!

## Migration Guide

- `ImageLoader` can no longer be initialized directly through
`init_asset_loader`. Now you must use
`app.register_asset_loader(ImageLoader::new(supported_compressed_formats))`
(check out the implementation of `bevy_render::ImagePlugin`). This only
affects you if you are initializing the loader manually and does not
affect users of `bevy_render::ImagePlugin`.

## Followup work

- We should be able to move most of the `ImagePlugin` to `bevy_image`.
This would likely require an `ImagePlugin` and a `RenderImagePlugin` or
something though.
2024-10-15 02:18:10 +00:00