Commit Graph

982 Commits

Author SHA1 Message Date
Eero Lehtinen
125fbb05d3 Fix spot light shadow glitches (#19273)
# Objective

Spot light shadows are still broken after fixing point lights in #19265

## Solution

Fix spot lights in the same way, just using the spot light specific
visible entities component. I also changed the query to be directly in
the render world instead of being extracted to be more accurate.

## Testing

Tested with the same code but changing `PointLight` to `SpotLight`.
2025-05-30 22:59:10 +02:00
Eero Lehtinen
aab1ae8457 Make sure prepass notices changes in alpha mode (#19170)
# Objective

Fixes #19150

## Solution

Normally the `validate_cached_entity` in 

86cc02dca2/crates/bevy_pbr/src/prepass/mod.rs (L1109-L1126)
marks unchanged entites as clean, which makes them remain in the phase.

If a material is changed to an `alpha_mode` that isn't supposed to be
added to the prepass pipeline, the specialization system just
`continue`s and doesn't indicate to the cache that the entity is not
clean anymore.

I made these invalid entities get removed from the pipeline cache so
that they are correctly not marked clean and then removed from the
phase.

## Testing

Tested with the example code from the issue.
2025-05-30 22:59:10 +02:00
Eero Lehtinen
2811a034b8 Fix point light shadow glitches (#19265)
# Objective

Fixes #18945

## Solution

Entities that are not visible in any view (camera or light), get their
render meshes removed. When they become visible somewhere again, the
meshes get recreated and assigned possibly different ids.

Point/spot light visible entities weren't cleared when the lights
themseves went out of view, which caused them to try to queue these fake
visible entities for rendering every frame. The shadow phase cache
usually flushes non visible entites, but because of this bug it never
flushed them and continued to queue meshes with outdated ids.

The simple solution is to every frame clear all visible entities for all
point/spot lights that may or may not be visible. The visible entities
get repopulated directly afterwards. I also renamed the
`global_point_lights` to `global_visible_clusterable` to make it clear
that it includes only visible things.

## Testing

- Tested with the code from the issue.
2025-05-30 22:59:10 +02:00
atlv
82f193284a Fix specular cutoff on lights with radius overlapping with mesh (#19157)
# Objective

- Fixes #13318

## Solution

- Clamp a dot product to be positive to avoid choosing a `centerToRay`
which is not on the ray but behind it.

## Testing

- Repro in #13318

Main:
<img width="963" alt="{DA2A2B99-27C7-4A76-83B6-CCB70FB57CAD}"
src="https://github.com/user-attachments/assets/afae8001-48ee-4762-9522-e247bbe3577a"
/>

This PR:
<img width="963" alt="{2C4BC3E7-C6A6-4736-A916-0366FBB618DA}"
src="https://github.com/user-attachments/assets/5bea4162-0b58-4df0-bf22-09fcb27dc167"
/>

Eevee reference:

![329697008-ff28a5f3-27f3-4e98-9cee-d836a6c76aee](https://github.com/user-attachments/assets/a1b566ab-16ee-40d3-a0b6-ad179ca0fe3a)
2025-05-30 22:59:10 +02:00
Daniel Gallups
efde13a827 Fix: Provide CPU mesh processing with MaterialBindingId (#19083)
# Objective
Fixes #19027

## Solution
Query for the material binding id if using fallback CPU processing

## Testing
I've honestly no clue how to test for this, and I imagine that this
isn't entirely failsafe :( but would highly appreciate a suggestion!

To verify this works, please run the the texture.rs example using WebGL
2.

Additionally, I'm extremely naive about the nuances of pbr. This PR is
essentially to kinda *get the ball rolling* of sorts. Thanks :)

---------

Co-authored-by: Gilles Henaux <ghx_github_priv@fastmail.com>
Co-authored-by: charlotte <charlotte.c.mcelwain@gmail.com>
2025-05-30 22:59:10 +02:00
François Mockers
e9418b3845 Release 0.16.0 2025-04-21 23:14:00 +02:00
François Mockers
608f902d1a Release 0.16.0-rc.5 2025-04-15 09:11:38 +02:00
charlotte
b9f117979e Swap order of eviction/extraction when extracting for specialization (#18846)
# Objective

Fixes #18843 

## Solution

We need to account for the material being added and removed in the
course of the same frame. We evict the caches first because the entity
will be re-added if it was marked as needing specialization, which
avoids another check on removed components to see if it was "really"
despawned.
2025-04-15 09:10:28 +02:00
Patrick Walton
fc7705c0a6 Fix the ordering of the systems introduced in #18734. (#18825)
There's still a race resulting in blank materials whenever a material of
type A is added on the same frame that a material of type B is removed.
PR #18734 improved the situation, but ultimately didn't fix the race
because of two issues:

1. The `late_sweep_material_instances` system was never scheduled. This
PR fixes the problem by scheduling that system.

2. `early_sweep_material_instances` needs to be called after *every*
material type has been extracted, not just when the material of *that*
type has been extracted. The `chain()` added during the review process
in PR #18734 broke this logic. This PR reverts that and fixes the
ordering by introducing a new `SystemSet` that contains all material
extraction systems.

I also took the opportunity to switch a manual reference to
`AssetId::<StandardMaterial>::invalid()` to the new
`DUMMY_MESH_MATERIAL` constant for clarity.

Because this is a bug that can affect any application that switches
material types in a single frame, I think this should be uplifted to
Bevy 0.16.
2025-04-14 23:43:09 +02:00
charlotte
495798c00b Make sure the mesh actually exists before we try to specialize. (#18836)
Fixes #18809
Fixes #18823

Meshes despawned in `Last` can still be in visisible entities if they
were visible as of `PostUpdate`. Sanity check that the mesh actually
exists before we specialize. We still want to unconditionally assume
that the entity is in `EntitySpecializationTicks` as its absence from
that cache would likely suggest another bug.
2025-04-14 22:45:49 +02:00
Carter Anderson
9666a7e688 Rename bevy_platform_support to bevy_platform (#18813)
The goal of `bevy_platform_support` is to provide a set of platform
agnostic APIs, alongside platform-specific functionality. This is a high
traffic crate (providing things like HashMap and Instant). Especially in
light of https://github.com/bevyengine/bevy/discussions/18799, it
deserves a friendlier / shorter name.

Given that it hasn't had a full release yet, getting this change in
before Bevy 0.16 makes sense.

- Rename `bevy_platform_support` to `bevy_platform`.
2025-04-14 22:45:27 +02:00
François Mockers
c4b3d75b46 Release 0.16.0-rc.4 2025-04-11 09:12:55 +02:00
Greeble
1c3a63ad47 Fix newline in PointLightShadowMap comment (#18791)
A clippy failure slipped into #18768, although I'm not sure why CI
didn't catch it.

```sh
> cargo clippy --version
clippy 0.1.85 (4eb161250e 2025-03-15)

> cargo run -p ci
...
error: empty line after doc comment
   --> crates\bevy_pbr\src\light\mod.rs:105:5
    |
105 | /     /// The width and height of each of the 6 faces of the cubemap.
106 | |
    | |_^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_doc_comments
    = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]`
    = help: if the empty line is unintentional remove it
help: if the documentation should include the empty line include it in the comment
    |
106 |     ///
    |
```
2025-04-10 22:29:10 +02:00
jf908
50b00c8dc2 Small docs PR for PointLightShadowMap/DirectionalLightShadowMap (#18768)
# Objective

- Improve the docs for `PointLightShadowMap` and
`DirectionalLightShadowMap`

## Solution

- Add example for how to use `PointLightShadowMap` and move the
`DirectionalLightShadowMap` example from `DirectionalLight`.
- Match `PointLight` and `DirectionalLight` docs about shadows.
- Describe what `size` means.

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
2025-04-10 01:19:35 +02:00
charlotte
ef8a4e0100 Fix forward decal depth_fade_factor. (#18772)
Fixes #18758
2025-04-10 01:19:34 +02:00
charlotte
8c2ef6bf43 Add binned 2d/3d Wireframe render phase (#18587)
# Objective

Fixes #16896
Fixes #17737

## Solution

Adds a new render phase, including all the new cold specialization
patterns, for wireframes. There's a *lot* of regrettable duplication
here between 3d/2d.

## Testing

All the examples.

## Migration Guide
- `WireframePlugin` must now be created with
`WireframePlugin::default()`.
2025-04-10 01:19:34 +02:00
Patrick Walton
d55f47d00a Unify RenderMaterialInstances and RenderMeshMaterialIds, and fix an associated race condition. (#18734)
Currently, `RenderMaterialInstances` and `RenderMeshMaterialIds` are
very similar render-world resources: the former maps main world meshes
to typed material asset IDs, and the latter maps main world meshes to
untyped material asset IDs. This is needlessly-complex and wasteful, so
this patch unifies the two in favor of a single untyped
`RenderMaterialInstances` resource.

This patch also fixes a subtle issue that could cause mesh materials to
be incorrect if a `MeshMaterial3d<A>` was removed and replaced with a
`MeshMaterial3d<B>` material in the same frame. The problematic pattern
looks like:

1. `extract_mesh_materials<B>` runs and, seeing the
`Changed<MeshMaterial3d<B>>` condition, adds an entry mapping the mesh
to the new material to the untyped `RenderMeshMaterialIds`.

2. `extract_mesh_materials<A>` runs and, seeing that the entity is
present in `RemovedComponents<MeshMaterial3d<A>>`, removes the entry
from `RenderMeshMaterialIds`.

3. The material slot is now empty, and the mesh will show up as whatever
material happens to be in slot 0 in the material data slab.

This commit fixes the issue by splitting out `extract_mesh_materials`
into *three* phases: *extraction*, *early sweeping*, and *late
sweeping*, which run in that order:

1. The *extraction* system, which runs for each material, updates
`RenderMaterialInstances` records whenever `MeshMaterial3d` components
change, and updates a change tick so that the following system will know
not to remove it.

2. The *early sweeping* system, which runs for each material, processes
entities present in `RemovedComponents<MeshMaterial3d>` and removes each
such entity's record from `RenderMeshInstances` only if the extraction
system didn't update it this frame. This system runs after *all*
extraction systems have completed, fixing the race condition.

3. The *late sweeping* system, which runs only once regardless of the
number of materials in the scene, processes entities present in
`RemovedComponents<ViewVisibility>` and, as in the early sweeping phase,
removes each such entity's record from `RenderMeshInstances` only if the
extraction system didn't update it this frame. At the end, the late
sweeping system updates the change tick.

Because this pattern happens relatively frequently, I think this PR
should land for 0.16.
2025-04-10 01:19:34 +02:00
charlotte
553c322d54 Initialize pre-processing pipelines only when culling is enabled. (#18759)
Better fix for #18463 that still allows enabling mesh preprocessing on
webgpu.

Fixes #18463
2025-04-10 01:19:34 +02:00
Patrick Walton
76422f71cd Make the StandardMaterial bindless index table have a fixed size regardless of the features that are enabled. (#18771)
Due to the preprocessor usage in the shader, different combinations of
features could cause the fields of `StandardMaterialBindings` to shift
around. In certain cases, this could cause them to not line up with the
bindings specified in `StandardMaterial`. This resulted in #18104.

This commit fixes the issue by making `StandardMaterialBindings` have a
fixed size. On the CPU side, it uses the
`#[bindless(index_table(range(M..N)))]` feature I added to `AsBindGroup`
in #18025 to do so. Thus this patch has a dependency on #18025.

Closes #18104.

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
2025-04-10 01:19:34 +02:00
Patrick Walton
8a066faea9 Add bindless support back to ExtendedMaterial. (#18025)
PR #17898 disabled bindless support for `ExtendedMaterial`. This commit
adds it back. It also adds a new example, `extended_material_bindless`,
showing how to use it.
2025-04-10 01:19:33 +02:00
Máté Homolya
6e147d35f2 Web support for atmosphere (#18582)
# Objective

Add web support to atmosphere by gating dual source blending and using a
macro to determine the target platform.
The main objective of this PR is to ensure that users of Bevy's
atmosphere feature can also run it in a web-based context where WebGPU
support is enabled.

## Solution

- Make use of the `#[cfg(not(target_arch = "wasm32"))]` macro to gate
the dual source blending, as this is not (yet) supported in web
browsers.
- Rename the function `sample_sun_illuminance` to `sample_sun_radiance`
and move calls out of conditionals to ensure the shader compiles and
runs in both native and web-based contexts.
- Moved the multiplication of the transmittance out when calculating the
sun color, because calling the `sample_sun_illuminance` function was
causing issues in web. Overall this results in cleaner code and more
readable.

## Testing

- Tested by building a wasm target and loading it in a web page with
Vite dev server using `mate-h/bevy-webgpu` repo template.
- Tested the native build with `cargo run --example atmosphere` to
ensure it still works with dual source blending.

---

## Showcase

Screenshots show the atmosphere example running in two different
contexts:

<img width="1281" alt="atmosphere-web-showcase"
src="https://github.com/user-attachments/assets/40b1ee91-89ae-41a6-8189-89630d1ca1a6"
/>

---------

Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2025-04-09 00:21:41 +02:00
Greeble
3d17865c2e Fix many_foxes + motion blur = crash on WebGL (#18715)
## Objective

Fix  #18714.

## Solution

Make sure `SkinUniforms::prev_buffer` is resized at the same time as
`current_buffer`.

There will be a one frame visual glitch when the buffers are resized,
since `prev_buffer` is incorrectly initialised with the current joint
transforms.

Note that #18074 includes the same fix. I'm assuming this smaller PR
will land first.

## Testing

See repro instructions in #18714. Tested on `animated_mesh`,
`many_foxes`, `custom_skinned_mesh`, Win10/Nvidia with Vulkan,
WebGL/Chrome, WebGPU/Chrome.
2025-04-09 00:21:40 +02:00
Greeble
76318d99d7 Fix motion blur on skinned meshes (#18712)
## Objective

Fix motion blur not working on skinned meshes.

## Solution

`set_mesh_motion_vector_flags` can set
`RenderMeshInstanceFlags::HAS_PREVIOUS_SKIN` after specialization has
already cached the material. This can lead to
`MeshPipelineKey::HAS_PREVIOUS_SKIN` never getting set, disabling motion
blur.

The fix is to make sure `set_mesh_motion_vector_flags` happens before
specialization.

Note that the bug is fixed in a different way by #18074, which includes
other fixes but is a much larger change.

## Testing

Open the `animated_mesh` example and add these components to the
`Camera3d` entity:

```rust
MotionBlur {
    shutter_angle: 5.0,
    samples: 2,
    #[cfg(all(feature = "webgl2", target_arch = "wasm32", not(feature = "webgpu")))]
    _webgl2_padding: Default::default(),
},
#[cfg(all(feature = "webgl2", target_arch = "wasm32", not(feature = "webgpu")))]
Msaa::Off,
```

Tested on `animated_mesh`, `many_foxes`, `custom_skinned_mesh`,
Win10/Nvidia with Vulkan, WebGL/Chrome, WebGPU/Chrome. Note that testing
`many_foxes` WebGL requires #18715.
2025-04-05 01:08:55 +02:00
François Mockers
bdfd7a3443 Release 0.16.0-rc.3 2025-03-31 23:07:43 +02:00
Lucas Franca
eb37e86a1f Make bindings behind pbr_specular_textures flag consistent with other gated fields (#18645)
# Objective

Make all feature gated bindings consistent with each other

## Solution

Make the bindings of fields gated by `pbr_specular_textures` feature
consistent with the other gated bindings
2025-03-31 22:33:28 +02:00
andriyDev
4fc4fa4559 Delete unused weak handle and remove duplicate loads. (#18635)
# Objective

- Cleanup

## Solution

- Remove completely unused weak_handle
(`MESH_PREPROCESS_TYPES_SHADER_HANDLE`). This value is not used
directly, and is never populated.
- Delete multiple loads of `BUILD_INDIRECT_PARAMS_SHADER_HANDLE`. We
load it three times right after one another. This looks to be a
copy-paste error.

## Testing

- None.
2025-03-31 22:33:28 +02:00
Aevyrie
cba6698033 Parallelize bevy 0.16-rc bottlenecks (#18632)
# Objective

- Found stuttering and performance degradation while updating big_space
stress tests.

## Solution

- Identify and fix slow spots using tracy. Patch to verify fixes.

## Testing

- Tracy
- Before: 

![image](https://github.com/user-attachments/assets/ab7f440d-88c1-4ad9-9ad9-dca127c9421f)
- prev_gt parallelization and mutating instead of component insertion: 

![image](https://github.com/user-attachments/assets/9279a663-c0ba-4529-b709-d0f81f2a1d8b)
- parallelize visibility ranges and mesh specialization

![image](https://github.com/user-attachments/assets/25b70e7c-5d30-48ab-9bb2-79211d4d672f)

---------

Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2025-03-31 22:33:28 +02:00
Robin KAY
d5d57bbd26 Expose symbols needed to replicate SetMeshBindGroup in ecosystem crates. (#18613)
# Objective

My ecosystem crate, bevy_mod_outline, currently uses `SetMeshBindGroup`
as part of its custom rendering pipeline. I would like to allow for
possibility that, due to changes in 0.16, I need to customise the
behaviour of `SetMeshBindGroup` in order to make it work. However, not
all of the symbol needed to implement this render command are public
outside of Bevy.

## Solution

- Include `MorphIndices` in re-export list. I feel this is morally
equivalent to `SkinUniforms` already being exported.
- Change `MorphIndex::index` field to be public. I feel this is morally
equivalent to the `SkinByteOffset::byte_offset` field already being
public.
- Change `RenderMeshIntances::mesh_asset_id()` to be public (although
since all the fields of `RenderMeshInstances` are public it's possible
to work around this one by reimplementing).

These changes exclude:
- Making any change to the `RenderLightmaps` type as I don't need to
bind the light-maps for my use-case and I wanted to keep these changes
minimal. It has a private field which would need to be public or have
access methods.
- The changes already included in #18612.

## Testing

Confirmed that a copy of `SetMeshBindGroup` can be compiled outside of
Bevy with these changes, provided that the light-map code is removed.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-03-31 22:33:28 +02:00
charlotte
754d1fa7ca Remove entities from specialization caches when despawned. (#18627)
# Objective

Fixes #17872 

## Solution

This should have basically no impact on static scenes. We can optimize
more later if anything comes up. Needing to iterate the two level bin is
a bit unfortunate but shouldn't matter for apps that use a single
camera.
2025-03-31 22:33:27 +02:00
charlotte
8edeb85f01 Fix mesh extraction for meshes without associated material. (#18631)
# Objective

Fixes #17986
Fixes #18608

## Solution

Guard against situations where an extracted mesh does not have an
associated material. The way that mesh is dependent on the material api
(although decoupled) here is a bit unfortunate and we might consider
ways in the future to support these material features without this
indirect dependency.
2025-03-31 22:33:27 +02:00
charlotte
4ddab0af39 Add required shader defs for environment map binding arrays in deferred (#18634)
# Objective

Fixes #18468

## Solution

Missing shader defs caused shader compilation failure.
2025-03-31 22:33:27 +02:00
Vic
8723096d57 reexport entity set collections in entity module (#18413)
# Objective

Unlike for their helper typers, the import paths for
`unique_array::UniqueEntityArray`, `unique_slice::UniqueEntitySlice`,
`unique_vec::UniqueEntityVec`, `hash_set::EntityHashSet`,
`hash_map::EntityHashMap`, `index_set::EntityIndexSet`,
`index_map::EntityIndexMap` are quite redundant.

When looking at the structure of `hashbrown`, we can also see that while
both `HashSet` and `HashMap` have their own modules, the main types
themselves are re-exported to the crate level.

## Solution

Re-export the types in their shared `entity` parent module, and simplify
the imports where they're used.
2025-03-30 10:24:00 +02:00
JMS55
f8f7dfe792 Fix diffuse transmission for anisotropic materials (#18610)
Expand the diff, this was obviously just a copy paste bug at some point.
2025-03-30 10:21:20 +02:00
Robin KAY
d0c92de937 Expose skins_use_uniform_buffers() necessary to use pre-existing setup_morph_and_skinning_defs() API. (#18612)
# Objective

As of bevy 0.16-dev, the pre-existing public function
`bevy::pbr::setup_morph_and_skinning_defs()` is now passed a boolean
flag called `skins_use_uniform_buffers`. The value of this boolean is
computed by the function
`bevy_pbr::render::skin::skins_use_uniform_buffers()`, but it is not
exported publicly.

Found while porting
[bevy_mod_outline](https://github.com/komadori/bevy_mod_outline) to
0.16.

## Solution

Add `skin::skins_use_uniform_buffers` to the re-export list of
`bevy_pbr::render`.

## Testing

Confirmed test program can access public API.
2025-03-30 10:21:20 +02:00
aloucks
002cb73e38 Fix shader pre-pass compile failure when using AlphaMode::Blend and a Mesh without UVs (0.16.0-rc.2) (#18602)
# Objective

The flags are referenced later outside of the VERTEX_UVS ifdef/endif
block. The current behavior causes the pre-pass shader to fail to
compile when UVs are not present in the mesh, such as when using a
`LineStrip` to render a grid.

Fixes #18600

## Solution

Move the definition of the `flags` outside of the ifdef/endif block.

## Testing

Ran a modified `3d_example` that used a mesh and material with
alpha_mode blend, `LineStrip` topology, and no UVs.
2025-03-30 10:21:20 +02:00
JMS55
7bcacb6609 Tracy GPU support (#18490)
# Objective

- Add tracy GPU support

## Solution

- Build on top of the existing render diagnostics recording to also
upload gpu timestamps to tracy
- Copy code from https://github.com/Wumpf/wgpu-profiler

## Showcase

![image](https://github.com/user-attachments/assets/4dd7a7cd-bc0b-43c3-8390-6783dfda6473)
2025-03-28 23:33:00 +01:00
François Mockers
1f44b56310 Release 0.16.0-rc.2 2025-03-26 19:18:20 +01:00
Carter Anderson
f647482237 Improved Require Syntax (#18555)
# Objective

Requires are currently more verbose than they need to be. People would
like to define inline component values. Additionally, the current
`#[require(Foo(custom_constructor))]` and `#[require(Foo(|| Foo(10))]`
syntax doesn't really make sense within the context of the Rust type
system. #18309 was an attempt to improve ergonomics for some cases, but
it came at the cost of even more weirdness / unintuitive behavior. Our
approach as a whole needs a rethink.

## Solution

Rework the `#[require()]` syntax to make more sense. This is a breaking
change, but I think it will make the system easier to learn, while also
improving ergonomics substantially:

```rust
#[derive(Component)]
#[require(
    A, // this will use A::default()
    B(1), // inline tuple-struct value
    C { value: 1 }, // inline named-struct value
    D::Variant, // inline enum variant
    E::SOME_CONST, // inline associated const
    F::new(1), // inline constructor
    G = returns_g(), // an expression that returns G
    H = SomethingElse::new(), // expression returns SomethingElse, where SomethingElse: Into<H> 
)]
struct Foo;
```

## Migration Guide

Custom-constructor requires should use the new expression-style syntax:

```rust
// before
#[derive(Component)]
#[require(A(returns_a))]
struct Foo;

// after
#[derive(Component)]
#[require(A = returns_a())]
struct Foo;
```

Inline-closure-constructor requires should use the inline value syntax
where possible:

```rust
// before
#[derive(Component)]
#[require(A(|| A(10))]
struct Foo;

// after
#[derive(Component)]
#[require(A(10)]
struct Foo;
```

In cases where that is not possible, use the expression-style syntax:

```rust
// before
#[derive(Component)]
#[require(A(|| A(10))]
struct Foo;

// after
#[derive(Component)]
#[require(A = A(10)]
struct Foo;
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2025-03-26 19:07:30 +01:00
IceSentry
af9fd4e939 Move non-generic parts of the PrepassPipeline to internal field (#18322)
# Objective

- The prepass pipeline has a generic bound on the specialize function
but 95% of it doesn't need it

## Solution

- Move most of the fields to an internal struct and use a separate
specialize function for those fields

## Testing

- Ran the 3d_scene and it worked like before

---

## Migration Guide

If you were using a field of the `PrepassPipeline`, most of them have
now been move to `PrepassPipeline::internal`.

## Notes

Here's the cargo bloat size comparison (from this tool
https://github.com/bevyengine/bevy/discussions/14864):

```
before:
    (
        "<bevy_pbr::prepass::PrepassPipeline<M> as bevy_render::render_resource::pipeline_specializer::SpecializedMeshPipeline>::specialize",
        25416,
        0.05582993,
    ),

after:
    (
        "<bevy_pbr::prepass::PrepassPipeline<M> as bevy_render::render_resource::pipeline_specializer::SpecializedMeshPipeline>::specialize",
        2496,
        0.005490916,
    ),
    (
        "bevy_pbr::prepass::PrepassPipelineInternal::specialize",
        11444,
        0.025175499,
    ),
```

The size for the specialize function that is generic is now much
smaller, so users won't need to recompile it for every material.
2025-03-25 22:59:04 +01:00
HugoPeters1024
df26bc3387 bugfix(frustra of point lights were not recalculated when a camera changes) (#18519)
# Objective

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

## Solution

- https://github.com/bevyengine/bevy/pull/4086 introduced an
optimization to not do redundant calculations, but did not take into
account changes to the resource `global_lights`. I believe that my patch
includes the optimization benefit but adds the required nuance to fix
said bug.

## Testing

The example originally given by
[@kirillsurkov](https://github.com/kirillsurkov) and then updated by me
to bevy 15.3 here:
https://github.com/bevyengine/bevy/issues/11682#issuecomment-2746287416
will not have shadows without this patch:

```rust
use bevy::prelude::*;

#[derive(Resource)]
struct State {
    x: f32,
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, update)
        .insert_resource(State { x: -40.0 })
        .run();
}

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    commands.spawn((
        Mesh3d(meshes.add(Circle::new(4.0))),
        MeshMaterial3d(materials.add(Color::WHITE)),
    ));
    commands.spawn((
        Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
        MeshMaterial3d(materials.add(Color::linear_rgb(0.0, 1.0, 0.0))),
    ));
    commands.spawn((
        PointLight {
            shadows_enabled: true,
            ..default()
        },
        Transform::from_xyz(4.0, 8.0, 4.0),
    ));
    commands.spawn(Camera3d::default());
}

fn update(mut state: ResMut<State>, mut camera: Query<&mut Transform, With<Camera3d>>) {
    let mut camera = camera.single_mut().unwrap();

    let t = Vec3::new(state.x, 0.0, 10.0);
    camera.translation = t;
    camera.look_at(t - Vec3::Z, Vec3::Y);

    state.x = 0.0;
}
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2025-03-25 22:59:04 +01:00
JMS55
62f7f2d159 Fix specialize_shadows system ordering (#18412)
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/18332

## Solution

- Move specialize_shadows to ManageViews so that it can run after
prepare_lights, so that shadow views exist for specialization.
- Unfortunately this means that specialize_shadows is no longer in
PrepareMeshes like the rest of the specialization systems.

## Testing
- Ran anti_aliasing example, switched between the different AA options,
observed no glitches.
2025-03-19 21:36:18 +01:00
charlotte
48fc396f04 Fix unecessary specialization checks for apps with many materials (#18410)
# Objective

For materials that aren't being used or a visible entity doesn't have an
instance of, we were unnecessarily constantly checking whether they
needed specialization, saying yes (because the material had never been
specialized for that entity), and failing to look up the material
instance.

## Solution

If an entity doesn't have an instance of the material, it can't possibly
need specialization, so exit early before spending time doing the check.

Fixes #18388.
2025-03-19 21:36:18 +01:00
François Mockers
920515adab Release 0.16.0-rc.1 2025-03-18 21:48:22 +01:00
Gino Valente
9b32e09551
bevy_reflect: Add clone registrations project-wide (#18307)
# Objective

Now that #13432 has been merged, it's important we update our reflected
types to properly opt into this feature. If we do not, then this could
cause issues for users downstream who want to make use of
reflection-based cloning.

## Solution

This PR is broken into 4 commits:

1. Add `#[reflect(Clone)]` on all types marked `#[reflect(opaque)]` that
are also `Clone`. This is mandatory as these types would otherwise cause
the cloning operation to fail for any type that contains it at any
depth.
2. Update the reflection example to suggest adding `#[reflect(Clone)]`
on opaque types.
3. Add `#[reflect(clone)]` attributes on all fields marked
`#[reflect(ignore)]` that are also `Clone`. This prevents the ignored
field from causing the cloning operation to fail.
   
Note that some of the types that contain these fields are also `Clone`,
and thus can be marked `#[reflect(Clone)]`. This makes the
`#[reflect(clone)]` attribute redundant. However, I think it's safer to
keep it marked in the case that the `Clone` impl/derive is ever removed.
I'm open to removing them, though, if people disagree.
4. Finally, I added `#[reflect(Clone)]` on all types that are also
`Clone`. While not strictly necessary, it enables us to reduce the
generated output since we can just call `Clone::clone` directly instead
of calling `PartialReflect::reflect_clone` on each variant/field. It
also means we benefit from any optimizations or customizations made in
the `Clone` impl, including directly dereferencing `Copy` values and
increasing reference counters.

Along with that change I also took the liberty of adding any missing
registrations that I saw could be applied to the type as well, such as
`Default`, `PartialEq`, and `Hash`. There were hundreds of these to
edit, though, so it's possible I missed quite a few.

That last commit is **_massive_**. There were nearly 700 types to
update. So it's recommended to review the first three before moving onto
that last one.

Additionally, I can break the last commit off into its own PR or into
smaller PRs, but I figured this would be the easiest way of doing it
(and in a timely manner since I unfortunately don't have as much time as
I used to for code contributions).

## Testing

You can test locally with a `cargo check`:

```
cargo check --workspace --all-features
```
2025-03-17 18:32:35 +00:00
Rob Parrett
770059c539
Fix clippy lints on Rust beta (#18361)
# Objective

Fixes #18360

## Solution

```
rustup toolchain install beta
rustup default beta
cargo run -p ci
```

Make suggested changes

## Testing

`cargo run -p ci`
2025-03-17 18:00:27 +00:00
Patrick Walton
528e68f5bb
Pad out binding arrays to their full length if partially bound binding arrays aren't supported. (#18126)
I mistakenly thought that with the wgpu upgrade we'd have
`PARTIALLY_BOUND_BINDING_ARRAY` everywhere. Unfortunately this is not
the case. This PR adds a workaround back in.

Closes #18098.
2025-03-16 10:57:33 +00:00
JMS55
195a74afad
Add missing system ordering constraint to prepare_lights (#18308)
Fix https://github.com/bevyengine/bevy/issues/18094.
2025-03-15 22:57:52 +00:00
Robert Swain
bc7416aa22
Use 4-byte LightmapSlabIndex for batching instead of 16-byte AssetId<Image> (#18326)
Less data accessed and compared gives better batching performance.

# Objective

- Use a smaller id to represent the lightmap in batch data to enable a
faster implementation of draw streams.
- Improve batching performance for 3D sorted render phases.

## Solution

- 3D batching can use `LightmapSlabIndex` (a `NonMaxU32` which is 4
bytes) instead of the lightmap `AssetId<Image>` (an enum where the
largest variant is a 16-byte UUID) to discern the ability to batch.

## Testing

Tested main (yellow) vs this PR (red) on an M4 Max using the
`many_cubes` example with `WGPU_SETTINGS_PRIO=webgl2` to avoid
GPU-preprocessing, and modifying the materials in `many_cubes` to have
`AlphaMode::Blend` so that they would rely on the less efficient sorted
render phase batching.
<img width="1500" alt="Screenshot_2025-03-15_at_12 17 21"
src="https://github.com/user-attachments/assets/14709bd3-6d06-40fb-aa51-e1d2d606ebe3"
/>
A 44.75us or 7.5% reduction in median execution time of the batch and
prepare sorted render phase system for the `Transparent3d` phase
(handling 160k cubes).

---

## Migration Guide

- Changed: `RenderLightmap::new()` no longer takes an `AssetId<Image>`
argument for the asset id of the lightmap image.
2025-03-15 14:16:32 +00:00
newclarityex
ecccd57417
Generic system config (#17962)
# Objective
Prevents duplicate implementation between IntoSystemConfigs and
IntoSystemSetConfigs using a generic, adds a NodeType trait for more
config flexibility (opening the door to implement
https://github.com/bevyengine/bevy/issues/14195?).

## Solution
Followed writeup by @ItsDoot:
https://hackmd.io/@doot/rJeefFHc1x

Removes IntoSystemConfigs and IntoSystemSetConfigs, instead using
IntoNodeConfigs with generics.

## Testing
Pending

---

## Showcase
N/A

## Migration Guide
SystemSetConfigs -> NodeConfigs<InternedSystemSet>
SystemConfigs -> NodeConfigs<ScheduleSystem>
IntoSystemSetConfigs -> IntoNodeConfigs<InternedSystemSet, M>
IntoSystemConfigs -> IntoNodeConfigs<ScheduleSystem, M>

---------

Co-authored-by: Christian Hughes <9044780+ItsDoot@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-03-12 00:12:30 +00:00
Patrick Walton
913eb46324
Reimplement bindless storage buffers. (#17994)
Support for bindless storage buffers was temporarily removed with the
bindless revamp. This commit restores that support.
2025-03-10 21:32:19 +00:00