Skip to content

Meshlet improvement#38

Merged
JMS55 merged 150 commits intoJMS55:meshlet-improvementfrom
jasmine-nominal:meshlet-improvement
Oct 23, 2025
Merged

Meshlet improvement#38
JMS55 merged 150 commits intoJMS55:meshlet-improvementfrom
jasmine-nominal:meshlet-improvement

Conversation

@jasmine-nominal
Copy link
Copy Markdown

No description provided.

kpreid and others added 30 commits September 30, 2025 21:20
…21304)

## Objective

Fixes bevyengine#21303 (but does not add any testing that similar issues will not
recur).

## Solution

Globally replace `feature(doc_auto_cfg)` with `feature(doc_cfg)`.

## Testing

Tested that `RUSTDOCFLAGS=--cfg=docsrs cargo +nightly doc -p
bevy_platform` succeeds. This is not a test of all documentation builds,
but I do not know of a way to do that until bevy’s dependencies catch
up.
# Objective

Primitive types are automatically registered when a `TypeRegistry` is
created, except for unit type `()`.

## Solution

Register `()` alongside other primitives.

## Testing

Run tests in `bevy_reflect`, tested with my code that `()` is being
registered.
…engine#21306)

# Objective

- A few were missed in bevyengine#21304

## Solution

- Change them
# Objective

disable macos/ios check for clustered decals

## Solution

disable macos/ios check for clustered decals
# Objective

- i want to write functions that are generic over aabb type by taking
impl Into<Aabb> as a parameter

## Solution

- impl From

## Testing

-
Follow up to bevyengine#20630.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Dimitrios Loukadakis <dloukadakis@users.noreply.github.com>
# Objective

Fix typo in `Task` docs

## Solution

Get rid of that pesky `s`
# Objective

- Adopted from bevyengine#21271.
- `cargo-binstall` in CI is outdated, let's update!

## Solution

- Update to v1.15.6 from v1.14.1.

## Testing

- As it's run in CI, the best way to test is to run CI! :)

## Notable Changes

-
[v1.14.2](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.14.2)
- Dependency updates
-
[v1.14.3](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.14.3)
- Fixes race condition
-
[v1.14.4](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.14.4)
- Switch from `fs4` to `std` for file locking
-
[v1.15.0](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.15.0)
- Prompt when using Quickinstall. ~~This may cause some issues in CI, I
need to investigate it further.~~
-
[v1.15.1](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.15.1)
- Fix issues with manifest file and Quickinstall prompt
-
[v1.15.2](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.15.2)
- Fix updating telemetry config file
-
[v1.15.3](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.15.3)
- Stop building for x86 MacOS
-
[v1.15.4](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.15.4)
- Docs and dependencies
-
[v1.15.5](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.15.5)
- Support Socks5 proxy
-
[v1.15.6](https://github.com/cargo-bins/cargo-binstall/releases/tag/v1.15.6)
- Update dependencies

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# Objective

- enabling prepass/shadows should be done like the rest of a material's
properties

## Solution

- remove `Prepass/ShadowsEnabled` resources and associated fields on
`MaterialPlugin`
- add `Material::enable_prepass` and `Material::enable_shadows`
# Objective

`WinitSettings::update_mode` setting `UpdateMode::Reactive` is
documented as setting the time "from the start of one update to the
next". currently it sets the winit wake time to the wait time after the
start of the current tick, which shifts each frame by whatever
additional latency exists before the frame is triggered.
also, redraws only seem to trigger every 2 wakeups.

in wasm this is the only way to cap framerates below default
refresh-rate (on native we can just sleep), but this issue manifests on
both native and wasm.

## Solution

solve 1 by recording scheduled start time and setting the next wakeup as
scheduled + wait time.
solve 2 by setting redraw_requested explicitly when wait time elapses

## Testing

```rs
const FPS: u32 = 10;

#[wasm_bindgen]
pub fn engine_run() {
    #[cfg(target_arch="wasm32")]
    let _ = console_log::init_with_level(log::Level::Info);
    App::new()
        .insert_resource(WinitSettings {
            focused_mode: UpdateMode::Reactive {
                wait: Duration::from_micros((1.0 / (FPS as f32) * 1000000.0) as u64),
                react_to_device_events: false,
                react_to_user_events: false,
                react_to_window_events: false,
            },
            unfocused_mode: UpdateMode::Reactive {
                wait: Duration::from_micros((1.0 / (FPS as f32) * 1000000.0) as u64),
                react_to_device_events: false,
                react_to_user_events: false,
                react_to_window_events: false,
            },
            ..Default::default()
        })
        .add_plugins(DefaultPlugins)
        .add_plugins(FrameTimeDiagnosticsPlugin::default())
        .add_plugins(LogDiagnosticsPlugin::default())
        .run();
}
```
## Objective

Add flexibility by refactoring `AnimationTarget` into two separate
components. This will smooth the path for future animation features.

## Background

`bevy_animation` animates entities by assigning them `AnimationTarget`
components:

```rust
struct AnimationTarget {
    player: Entity,
    id: AnimationTargetId,
}
```

- `player: Entity` links to an entity that contains an `AnimationPlayer`
component. An `AnimationPlayer` plays `AnimationClip` assets.
- `id: AnimationTargetId` identifies which tracks in an `AnimationClip`
apply to the target entity.

When loading a glTF these components are automatically created. They can
also be created manually.

## Problem

The two parts of `AnimationTarget` often go together but sometimes would
be better separated:

1. I might want to calculate the `AnimationTargetId` first, but not link
it up to an `AnimationPlayer` until later (see bevyengine#18262 for an example).
2. I might want to use `AnimationTargetId` but not use `AnimationPlayer`
- maybe I've got a different component that plays `AnimationClip`s.

In theory `player` could be left as `Entity::PLACEHOLDER`, but that's
messy and will trigger a warning in `animate_targets`.

## Solution

This PR splits `AnimationTarget` into two components:

1. `AnimationTargetId` is just the original struct with a component
derive.
2. `AnimationPlayerTarget` is a new unit struct `(Entity)`.

I'm not convinced `AnimationPlayerTarget` is a good name, but it does
fit the usual source/target naming for entity relationships.
`AnimationPlayerRef` was another candidate.

`AnimationPlayerTarget` could be a relationship target, but there would
be a performance cost from making `AnimationPlayer` a relationship
source. Maybe it's still a good idea, but that's probably best left to
another PR.

### Performance

Profiled on `many_foxes` - difference was negligible.

### Testing

Examples `animated_mesh`, `animated_transform`, `animated_ui`,
`animation_masks`, `eased_motion`, `scene_viewer`.

## Future

If this PR lands then I'll probably file a follow up that adds more
flexibility to the the glTF loader creation of `AnimationTargetId` and
`AnimationPlayer`. This will help bevyengine#18262 and enable some other features.
…st (bevyengine#21321)

# Objective

It should be possible to enable minimal bevy features by disabling all
and then progressively enabling them until everything works.
This however requires, that bevy has good error reporting and gracefully
supports different featuresets.

I ran my code with minimal features and got this unhelpful error:
```
thread 'main' (993068) panicked at /home/jakob/dev/rust/bevy/crates/bevy_render/src/render_graph/graph.rs:158:26:
InvalidNode(PostProcessing)
```

## Solution

With this PR it looks like this:
```
thread 'main' (989393) panicked at /home/jakob/dev/rust/bevy/crates/bevy_pbr/src/wireframe.rs:136:14:
node PostProcessing does not exist
```

Which immediately helps me figure out that I need some feature for the
`WireframePlugin` I added.

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective

Resolves bevyengine#21291

## Solution

Remove the empty DevToolsPlugin
…gine#21332)

# Objective

bevyengine#21297 removed the restriction
that prevented macos/ios from using clustered decals

## Solution

Remove them from the list of "unsupported" targets.
<img width="2564" height="1500" alt="image"
src="https://github.com/user-attachments/assets/8bd37bda-88b0-436a-9c01-a22fb63e9e87"
/>

* ClearColor is not supported for the pathtracer still
* Tonemapping makes the clear color appear incorrect (the above image is
supposed to be pure white), which is a little wonky. That's a separate
issue though.
…incorrect pass ordering (bevyengine#21348)

Light tiles used to be generated _after_ the world cache update, despite
the world cache update relying on them. This means that the world cache
update used last frame's light tiles, which is fine for static lights,
but completely wrong for dynamic lights and lead to missing GI
contributions from dynamic lights.

Moving the presample light tile step to before the world cache update
fixes this.

Can be tested by running the solari example, turning off the directional
light so there's only the emissive robot light, enabling
VISUALIZE_WORLD_CACHE, and then comparing before/after this PR.
# Objective

Splitting off some trivial changes from the text rework.

This adds a method that counts the number of rasterized fonts stored in
`FontAtlasSets`.

# Solution

Return the sum of the lengths of all the sets.
…ne#21338)

# Objective

Fixes bevyengine#21319.

## Solution

In the "about_to_wait" state of Bevy's winit event loop, we borrow
WINIT_WINDOWS only to check the conditions for a redraw, and perform the
call after that check is concluded.

## Testing

Tested by confirming that the RefCell error no longer occurs in my
application. In my application, the error occurred when the
`bevy-egui-inspector` crate was used.

I do not know whether the original reporter of bevyengine#21319 was also using
third-party Bevy plugins that might have caused the issue. It would be
good if they could check whether this change fixes it for them.

Tested on Windows 11, where the bug is known to occur. The code that was
changed is only included in Windows builds so there is little need to
test on other platforms.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Dimitrios Loukadakis <dloukadakis@users.noreply.github.com>
# Objective

`CameraOutputMode` doesn't Implement `Reflect` and is ignored in
`Camera`.

## Solution

Like bevyengine#15355, this Implements opaque `Reflect` for `wgpu::BlendState`
thus we can add `#derive(Reflect)` for `CameraOutputMode`.

As the commnent says, it can also implement `Reflect` througth
`reflect_remote` (bevyengine#6042), but I'm not sure if we should do this for wgpu
types.

## Testing

ci
# Objective

Fixes bevyengine#21275 

Pasting the content of the Issue to provide context,

> bevy_ecs::entity::EntityIndexMap has the entry() method because it
derefs to indexmap::IndexMap, but it doesn't re-export IndexMap::Entry
so I have to import the indexmap crate manually.

> It would be convenient to re-export indexmap::Entry in
bevy_ecs::entity::index_map
…1364)

# Objective

Fixes bevyengine#21293
Fixes bevyengine#17314 to ensure that this is tested correctly.

## Solution
when despawning an entity, previously the swapped in (archetype) or
moved in entity (table) (which both require extra bookkeeping to update
archetype or table rows) were marked as `spawned_or_despawned` by the
location and tick that the to-be-removed entity was meant to be marked,
while the to-be-removed entity wasn't marked.
As pointed out by @akimakinai in
[bevyengine#19047](bevyengine#19047), I've re-added
the correct `mark_spawn_despawn` call to `despawn_with_caller`.

## Testing

I've added a test `spawned_after_swap_remove` that ensures that
despawning an entity by swapping doesn't effect other entities
`spawned_or_despawned` location, and that it does effect the despawned
entity's index's `spawned_or_despawned` location.

Co-Authored By: waterwhisperer24@qq.com

---------

Co-authored-by: WaterWhisperer <waterwhisperer24@qq.com>
# Objective

The slider label doesn't format consistently. For example, for precision
`2` it might jump between: `20`, `20.01`, `20.02` ... `20.1`, `20.11`…
which is noisy and ugly.

## Solution

Format the label using the precision.

## Testing

Checked the feathers example with `2`, `0` and `-1` precision.

## Showcase


https://github.com/user-attachments/assets/9f30200a-a832-43df-937a-123c8d3168cf
# Objective

Fixes bevyengine#20177 

## Solution

Remove unnecessary calls to `world.flush()` in observer tests 

## Testing

Ran `cargo test --package bevy_ecs --lib observer` and all tests passed
<img width="1569" height="718" alt="image"
src="https://github.com/user-attachments/assets/7fdb1959-3d4a-49f6-832a-15650e8ee94a"
/>
# Objective
Fix typo in viewport_node example 
## Solution
- the comment should point to
[widget](https://docs.rs/bevy/latest/bevy/ui/widget/fn.viewport_picking.html)
not widgets.
# Objective

Addresses the immediate blocker in bevyengine#21354 by relaxing the `(crate)`
visibility restriction on `DeferredWorld::as_unsafe_world_cell`.

This method already has documentation, including a safety comment. While
sparse, I think they communicate the function clearly.
# Objective

bevy v0.17.1, archlinux + i3wm.

`cargo run --example 2d_viewport_to_world`

```
thread 'Compute Task Pool (1)' (470531) panicked at /home/go/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glam-0.30.8/src/u32/uvec2.rs:1071:23:
attempt to subtract with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `2d_viewport_to_world::controls`!
Encountered a panic in system `bevy_app::main_schedule::FixedMain::run_fixed_main`!
Encountered a panic in system `bevy_time::fixed::run_fixed_main_schedule`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
```

## Solution

Consider window resize。

## Testing

no panic.

---
# Objective

Fixes bevyengine#21327 
Volumetric fog contribution was not proportional to the light intensity
for point and spotlights.

## Solution

Take into account `exposure` value for Point and Spotlights to match the
Directional light implementation.

## Testing

- Run the updated `volumetric_fog` example. You can see the volumetric
effect of point and spotlights now match the intensity of this light on
the surfaces of the room.

---

## Showcase

Point and spotlight intensities in the original `volumetric_fog` example
were too low to light up the room despite having a very strong
volumetric contribution. This update boosts the light intensity and
lowers the volumetric contribution of point and spotlights

Before this change `volumetric_fog` example with 10x light intensity for
point and spotlights:
<img width="1922" height="1126" alt="brightness_10x_on"
src="https://github.com/user-attachments/assets/7562585c-bc1b-4cbf-9d52-4ffb083d65f4"
/>

After change:
<img width="1922" height="1126" alt="brightness_10x_on_fix"
src="https://github.com/user-attachments/assets/2a17fec8-0272-4c4e-9d88-d0916027a7c5"
/>
Improve grammar, clarity, and documentation style in lib.rs
…ne#21382)

# Objective
Fixes bevyengine#21381 

## Solution

- Describe the solution used to achieve the objective above.

## Testing

- I tested the changes on examples/ui/viewport_node

---------

Co-authored-by: 0xfff <patx0331@gmail.com>
janhohenheim and others added 29 commits October 18, 2025 16:44
# Objective

`log_components` looks like this:
<img width="1609" height="266" alt="image"
src="https://github.com/user-attachments/assets/6e4e5173-9f9e-4cf6-8ed1-a64d4b991a8a"
/>

eek! what is going on??? I could pretty-print this by fiddling with the
logging filters, but that
- is weird boilerplate, just arcane enough that I would not be able to
do it without looking it up or copy-pasting it from somewhere and
- would change ALL debug prints to use newlines, which would flood my
terminal.

Can I just pretty print the component log plz?

## Solution

Add `log_components_pretty`:

<img width="1480" height="125" alt="image"
src="https://github.com/user-attachments/assets/ffecc45c-8bb9-4156-8aeb-623c3db65900"
/>

much better! 

- The name and the entity ID of the logged entity
- All component names without the `DebugName` wrapper
- Alphanumerically sorted components

And we can go one step further when downstream (thanks Chris!)
```rust
DefaultPlugins.set(bevy::log::LogPlugin {
            fmt_layer: |_| {
                Some(Box::new(
                    bevy::log::tracing_subscriber::fmt::Layer::default()
                        .map_fmt_fields(|f| f.debug_alt())
                        .with_writer(std::io::stderr),
                ))
            },
            ..default()
        })
```

which gives us newlines:

<img width="939" height="339" alt="image"
src="https://github.com/user-attachments/assets/ed4c327e-12ab-46cd-b698-1d911a2d762e"
/>


## Additional info

Added a `debug` feature because the experience of getting blasted with
30 strings telling me to enable a feature is suboptimal.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
…inful to type (bevyengine#21597)

# Objective
To be honest, typing tool commands suck due to just how long the
commands are.

Also, what is a `ci` alias doing in a config file meant for fast
builds...?

## Solution
Create a config file for cargo aliases, under
`.cargo/config_aliases.toml`, with many short aliases to useful
commands.

Now instead of typing `cargo run -p build-templated-pages -- update
features`, you can just run `cargo update-feature-docs`. :D

## Testing
This change was tested by copying `.cargo/config_aliases.toml` to
`.cargo/config.toml`, and running `cargo --list` to confirm that they
showed up.

I also ran a few (but not all) of these aliases to ensure they work.
…tion` (bevyengine#21577)

# Objective

Fixes bevyengine#14309 

## Solution

Renamed the `bevy_reflect` feature from `documentation` to
`reflect_documentation` to follow the naming convention where features
are prefixed with their module name.

## Changes

- Renamed feature `documentation` to `reflect_documentation` in:
  - `bevy_reflect/Cargo.toml`
  - `bevy_reflect/derive/Cargo.toml`
  - `bevy_internal/Cargo.toml`
- Updated all conditional compilation attributes from `#[cfg(feature =
"documentation")]` to `#[cfg(feature = "reflect_documentation")]`
- Updated example documentation in `reflect_docs.rs`

## Testing

<img width="1414" height="688" alt="截图 2025-10-17 18-52-14"
src="https://github.com/user-attachments/assets/461d827a-c958-4c0d-862d-aae25598f2f7"
/>
## Objective

While tinkering with change detection, I've collected some nitpicks:

- The word "ticks" is kind of overloaded; ticks are used by components,
systems, and the world, but "ticks" is often used to refer to the "added
+ changed" pair of ticks that only components have (and resources, but
they're close enough to components).
- `Ticks` is a nice name for a struct, but it's taken by a `pub(crate)`
struct that's pretty niche. (I don't have any plans for the `Ticks`
name, but it could be useful for something.)
- Every use of `Ticks`, `TicksMut`, and `TickCells` is accompanied by a
`MaybeLocation` that represents the calling location that last modified
the component, so it should just be part of the structs.
- `NonSend` seems to be in the wrong file, and doesn't implement methods
with the macros that every other change-detecting query parameter uses.

## Solution

Renamed the following structs:
- `Ticks` -> `RefComponentTicks`
- `TicksMut` -> `MutComponentTicks`
- `TickCells` -> `ComponentTickCells`

Added a `changed_by: MaybeLocation` field to `RefComponentTicks`,
`MutComponentTicks`, and `ComponentTickCells` and folded in the loose
`MaybeLocation`s.

Moved `NonSend` from `system/system_param.rs` to `change_detection.rs`
and updated its implementation to match similar query parameters.

Removed `ComponentTickCells::read` because it is now unused (and not
public).
# Objective

- Fixes bevyengine#16654 

## Solution

- Updated the doc string and linked to TemporaryRenderEntity.

## Testing

- Built the documentation locally and verified that the links render and
navigate correctly.
…`bevy` main crate to be more accurate (bevyengine#21590)

# Objective
The `bevy` main crate's `lib.rs` file contains an expectation for the
`clippy::doc_markdown` lint. However, it only references one of the many
times that `clippy::doc_markdown` lints on that file. Many of the other
`clippy::doc_markdown` instances are within the cargo features list.

## Solution
Rewrite the reason for this expectation to be more clear. Additionally,
mark `GameActivity` as an allowed doc ident for Clippy.

## Testing
`cargo clippy` returned no errors.
# Objective

Multiple tests derive both `Resource` and `Component` on a single
struct. In the current resources-for-components plan (bevyengine#19731), this
leads to a conflict.

## Solution

```rust
#[derive(Resource, Component)]
struct A;
```

Becomes

```rust
#[derive(Component)]
struct A;

#[derive(Resource)]
struct ResA;
```

and the tests are changed accordingly.

There was one test that had to be removed as it specifically tested that
a query could both query a resource and a component with the same name.
That test doesn't make any sense anymore, so I removed it.

## Testing

I tested the changes by adding code into `Resource` derive macro, that
also derives `Component`, so any conflicts showed up by running `cargo
build`.

## Future work

`AmbientLight` in `bevy_light` still derives both, but since that
requires a little more work, I'm saving it for later.
…misleading docs surrounding it (bevyengine#21593)

# Objective

- The current name and docs tell you this is the animation player
entity. But it's not necessarily! When adding an event via
`AnimationClip::add_event_to_target`, that entity actually points to the
`AnimationTargetId`, not the animation player!
- This just caused some major confusion for me while debugging a system
that was supposed to play a sound effect from a specific bone (namely a
footstep from the foot).

## Solution

- Rename the field to `target`
- Change the docs to mention the nuance

## Testing

- Verified behavior in a test scene
…ngine#21605)

# Objective

`world/entity_ref.rs` is the biggest single source file in Bevy at ~6800
lines. It can be a bit hard to navigate.

## Solution

Rename the `entity_ref` module to `entity_access` and split it into 8
files:
- `mod.rs`: Re-exports and testing, ~1600 lines
- `entity_ref.rs`: `EntityRef` type, ~340 lines
- `entity_mut.rs`: `EntityMut` type, ~760 lines
- `world_mut.rs`: `EntityWorldMut` type, ~2200 lines
- `filtered.rs`: `FilteredEntityRef` and `FilteredEntityMut` types, ~780
lines
- `except.rs`: `EntityRefExcept` and `EntityMutExcept` types, ~500 lines
- `entry.rs`: `ComponentEntry` type, ~330 lines
- `component_fetch.rs`: `DynamicComponentFetch` trait, ~360 lines

`world_mut` is still sizable, but that's just the sheer number of
methods `EntityWorldMut` has. Splitting the methods across multiple
files is possible, but that might be more annoying than a large file.
…evyengine#21604)

## Objective

`change_detection.rs` is a bit big at ~1900 lines and its contents are
pretty varied, so it ought to be split up.

## Solution

Split `change_detection.rs` into 4 files:
- `mod.rs`: Re-exports, some constants, testing
- `params.rs`: Change-detecting system/query parameters like `Ref` and
`Res`
- `traits.rs`: The `DetectChanges` and `DetectChangesMut` traits and the
macros used internally to implement those traits (and some others) for
the above parameters
- `maybe_location.rs`: `MaybeLocation` and its impls

This shouldn't change anything publicly, since everything's still in the
same module.

I'd also like to move `component/tick.rs` into this module, but that
would break stuff, so that'll be its own PR.
# Objective

bevyengine/bevy-website#2293 proposed a rename
of our `M-Needs-Release-Note` and `M-Needs-Migration-Guide` labels for
improved clarity.

This has been approved, so I'm merging that PR.

This repo lists these labels in a few places for automation /
contributor help, and they need to be updated.

## Solution

Grep for these like @BD103 told me to in
bevyengine/bevy-website#2293 (comment)

## Follow-up work

Once this PR is merged I'll actually rename the label.
…1571)

# Objective

Fixes bevyengine#16809 

## Solution

- Correct NDC coordinate ranges and depth interpretation
- Fix method reference from world_to_viewport to viewport_to_world
- Update parameter name in error condition from world_position to
ndc_point
- Clarify that returned world position is not limited to NDC
…1592)

# Objective

This PR fixes bevyengine#21569, which proposes renaming the newly introduced
camera controller modules `FreeCam` and `PanCam` to use the full term
`Camera`.

## Solution

* Renamed the `PanCam` controller, `PanCamPlugin`, and related methods
to use the full term `Camera` instead of the abbreviation `Cam`.
* Renamed the module from `pan_cam` to `pan_camera` for consistency with
naming conventions.
* Updated the example `pan_camera_controller` and adjusted usage of the
renamed controller and plugin.
* Updated documentation and release notes accordingly.


## Follow-up Work

I see two options from here:

1. **Use this PR as a reference** for renaming `FreeCam`. The process is
similar and could be a great first issue for someone looking to
contribute to the new camera modules or Bevy in general. Most of the
changes follow the same pattern, although `FreeCam` has more examples
that need updating. One could find them using `grep` (e.g., `grep
FreeCam`) or by reviewing the diff from the PR that introduced
`FreeCam`: bevyengine#20215

2. **I can continue and update this PR** to also handle the `FreeCam`
renaming, if you'd prefer to resolve the entire issue in one go.

---------

Co-authored-by: syszery <syszery@users.noreply.github.com>
…ic contexts (bevyengine#21601)

# Objective
Currently there is no way to traverse relationships in type-erased
contexts or to define dynamic relationship components, which is a hole
in the current relationships api.

## Solution
Introduce `RelationshipAccessor` to describe a way to get `Entity`
values from any registered relationships in dynamic contexts and store
it on `ComponentDescriptor`. This allows to traverse relationships
without knowing their type, which is useful for working with entity
hierarchies using non-default components.

## Testing
Added a simple test/example of how to use this api to traverse
hierarchies in a type-erased context.
…evyengine#21608)

# Objective

- Part of bevyengine#20115
- Since bevyengine#20256, `ScheduleGraph::topsort_graph` no longer uses `self`, so
let's put it directly on `DiGraph`.

## Solution

- Moved `ScheduleGraph::topsort_graph` to `DiGraph::toposort`.
- Added `DiGraphToposortError` with `Loop` and `Cycle` variants, which
is wrapped to replace `ScheduleBuildError::HierarchyLoop`,
`HierarchyCycle`, `DependencyLoop`, and `DependencyCycle`.
- Added `ScheduleBuildError::FlatDependencySort` variant to detect
issues specifically with the flattened dependency graph.
- Removed `ReportCycles`: `DiGraph::toposort` returns an error that
should be wrapped at the callsite, negating the need for this type.
- Moved `simple_cycles_in_component` onto `DiGraph` (formerly a
free-floating function).

## Testing

Updated and reused current tests.
Follow-up to bevyengine#21604.

`Tick` and friends should be in the `change_detection` module, not
`component`.
…ters (bevyengine#21616)

# Objective

- Fixes bevyengine#21579
- Fixes bevyengine#20167

## Solution

- Allow at least the engine-internal default filters until we have
bevyengine#21615
## Testing

- None. I think this is trivial enough.
…#21611)

# Objective

As discussed in bevyengine#19285, Bevy has reused the same conceptual names for
multiple types across different crates, creating confusion for
autocomplete tooling and users. This PR addresses one of those conflicts
by removing the `ron` re-export from `bevy_scene` and `bevy_asset`

## Solution

- Removed `pub use bevy_asset::ron;` from `bevy_scene::lib` and `pub use
ron;` from `bevy_asset::lib`
- Updated `crates/bevy_scene/Cargo.toml`
- Updated all internal references to use `ron` directly:
  - `crates/bevy_scene/src/dynamic_scene.rs`
  - `crates/bevy_scene/src/scene_loader.rs`
  - `crates/bevy_scene/src/serde.rs` (including doc examples and tests)

## Testing

- `cargo check --workspace` - all checks pass
- `cargo test -p bevy_scene` - tests pass (4 pre-existing test failures
unrelated to this change)
-  `cargo test -p bevy_asset` - tests pass
- `cargo clippy` - no new warnings
# Objective

- dont re-export SamplerBindingType twice for no reason

## Solution

- dont re-export SamplerBindingType twice for no reason

## Testing

- ci
# Objective

- Address [this
comment](bevyengine#21566 (comment)).

## Solution

- Move all the asset processor tests into their own file.

## Testing

- Ran the tests in single threaded and multi threaded mode.
# Objective

For resources-as-components (bevyengine#19731), structs mustn't doubly derive both
`Component` and `Resource`.

## Solution

Split `AmbientLight` in two: `AmbientLight` (the resource) and
`AmbientLightOverride` (the component).

## Testing

I initially made two structs `AmbientLightComponent` and
`AmbientLightResource`, and replaced every mention with the relevant one
to ensure that I didn't confuse the two.

## Notes

- I don't know if the names are correct. I kept the easiest name for the
resource, as that's the one most often used.
- I haven't provided any conversion methods as there are already plans
to replace the component variant with something else.

---------

Co-authored-by: atlv <email@atlasdostal.com>
# Objective

Add minimal strikethrough support for text.

## Solution

* Insert the new `Strikethrough` component on any `Text`, `Text2d`, or
`TextSpan` entity and its text will be drawn with strikethrough.
* The strikethrough geometry is stored in `TextLayoutInfo` in the vec
with the section bounding rects.
* Rendering is trivial, identical to drawing text background colours
except it's a narrower rect drawn in front instead of behind.
* Text shadows also have strikethrough if the text does.

#

This implementation can easily be expanded to support underline, I've
already made a follow up PR that does this here: bevyengine#21559.

## Testing

```
cargo run --example strikethrough
```

## Showcase

<img width="1422" height="924" alt="strikeout"
src="https://github.com/user-attachments/assets/c8ea2578-e40c-4c46-ae0d-df9e3f261f3a"
/>
at some point, the things it was pointing to were moved from bevy/sprite
to bevy/prelude, so fix the link to point there
# Objective

Despite initially advocating for its inclusion in bevyengine#20204, I've been
increasingly unconvinced by the edge cases and user-facing complexity
and surprise that `Internal` brings.

Accidental queries are quite hard to write, and the entitiy-inspector
concerns are really a UX problem for each tool to solve that `Internal`
doesn't help with.

@cart feels similarly: as a result I'm marking this PR as X-Blessed.

Closes bevyengine#21363.

## Solution

- Remove `Internal` as a type.
- Follow the compiler errors to remove all references.
- Write a migration guide.
# Objective

- Allow the asset processor to run single-threaded so that asset
processor tests can run in single-threaded mode too!

## Solution

- Make asset hot reloading use an async channel for events instead of a
crossbeam channel (which requires blocking).
- Have asset processing first find all the assets it wants to process,
then join all those processing tasks together.
- Make the asset processing listening loop await on a stream of async
channels instead of "spin-polling" (spin-lock but with polling). This
should make asset processing consume less CPU!

## Testing

- Tested asset processing in single threaded! It works!
# Objective

Text Underline

## Solution

New `Underline` marker component, add to text entities to draw an
underline.
This PR is based on bevyengine#21555, that should probably be reviewed and merged
first.
# Objective

Right now, only a very small set of atmospheres are possible with Bevy's
atmospheric scattering system because of the fixed set of scattering
terms available. For example, a scene set in a dry, desert environment
might want a dense low-lying layer of dust particulate separate from the
ambient dust in the atmosphere. This PR introduces a mechanism for
generalized scattering media, replacing the fixed scattering terms with
a customizable asset.

## Solution

```rust
#[derive(TypePath, Asset, Clone)]
pub struct ScatteringMedium {
    pub label: Option<Cow<'static, str>>,
    pub falloff_resolution: u32,
    pub phase_resolution: u32,
    pub terms: SmallVec<[ScatteringTerm; 1]>,
}
```

<details>
  <summary>see other new types</summary>

```rust
#[derive(Default, Clone)]
pub struct ScatteringTerm {
    pub absorption: Vec3,
    pub scattering: Vec3,
    pub falloff: Falloff,
    pub phase: PhaseFunction,
}

#[derive(Default, Clone)]
pub enum Falloff {
    #[default]
    Linear,
    Exponential {
        scale: f32,
    },
    Tent {
        center: f32,
        width: f32,
    },
    /// A falloff function defined by a custom curve.
    ///
    /// domain: [0, 1),
    /// range: [0, 1],
    Curve(Arc<dyn Curve<f32> + Send + Sync>),
}

#[derive(Clone)]
pub enum PhaseFunction {
    Isotropic,
    Rayleigh,
    Mie {
        /// domain: [-1, 1]
        bias: f32,
    },
    /// A phase function defined by a custom curve.
    ///
    /// domain: [-1, 1]
    /// range: [0, 1]
    Curve(Arc<dyn Curve<f32> + Send + Sync>),
}
```
</details>

`ScatteringMedium` contains a list of `ScatteringTerms`, which are
processed into a set of two LUTs:

- The "density LUT", a 2D `falloff_resolution x 2` LUT which contains
the medium's optical density with respect to the atmosphere's "falloff
parameter", a linear value which is 1.0 at the planet's surface and 0.0
at the edge of space. Absorption density and scattering density
correspond to the first and second rows respectively.
- The "scattering LUT", a 2D `falloff_resolution x phase_resolution` LUT
which contains the medium's scattering density multiplied by the phase
function, with the U axis corresponding to the falloff parameter and the
V axis corresponding to `neg_LdotV * 0.5 + 0.5`, where `neg_LdotV` is
the dot product of the light direction and the outgoing view vector.

## Testing

- Need to verify output, should be almost exactly the same
- exponential falloff is slightly different now, but verified new
parameters against the old in Desmos.

## TODOS: 

- Docs Docs Docs
- Cleanup
- profile perf
- reduce memory usage/traffic. This approach requires a few extra
texture samples in the inner loop of each pass. Each atmosphere LUT is
still quite small, but texture samples are expensive and the new LUTs
use f32 texels currently.

## Showcase

<details>
  <summary>Click to view showcase</summary>

```rust
fn init_atmosphere(mut commands: Commands, scattering_media: ResMut<Assets<ScatteringMedium>>) {
  let earth_atmosphere = scattering_media.add(
    ScatteringMedium::new(
      256,
      256,
      [
          // rayleigh scattering
          ScatteringTerm {
              absorption: Vec3::ZERO,
              scattering: Vec3::new(5.802e-6, 13.558e-6, 33.100e-6),
              falloff: Falloff::Exponential { scale: 12.5 },
              phase: PhaseFunction::Rayleigh,
          },
          // mie scattering
          ScatteringTerm {
              absorption: Vec3::splat(3.996e-6),
              scattering: Vec3::splat(0.444e-6),
              falloff: Falloff::Exponential { scale: 83.5 },
              phase: PhaseFunction::Mie { bias: 0.8 },
          },
          // ozone
          ScatteringTerm {
              absorption: Vec3::new(0.650e-6, 1.881e-6, 0.085e-6),
              scattering: Vec3::ZERO,
              falloff: Falloff::Tent {
                  center: 0.75,
                  width: 0.3,
              },
              phase: PhaseFunction::Isotropic,
          },
      ],
  ));

  commands.spawn((
    Camera3d::default(), 
    Atmosphere {
      bottom_radius: 6_360_000.0,
      top_radius: 6_460_000.0,
      ground_albedo: Vec3::splat(0.3),
      medium: earth_atmosphere,
    },
  ));
}
```
</details>

---------

Co-authored-by: Máté Homolya <mate.homolya@gmail.com>
@JMS55 JMS55 merged commit 6bf165b into JMS55:meshlet-improvement Oct 23, 2025
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.