-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Retain RenderMaterialInstances
and RenderMeshMaterialIds
from frame to frame.
#16878
Conversation
CI is failing |
changed_meshes_query: Extract< | ||
Query< | ||
(Entity, &ViewVisibility, &MeshMaterial3d<M>), | ||
Or<(Changed<ViewVisibility>, Changed<MeshMaterial3d<M>>)>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question on this: MeshMaterial3d might not change, but the asset pointed to by its handle might change. Do we need to handle that here? I don't have the context of what extract is doing here anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to handle that here because the only thing extract_mesh_materials
needs to do is to allocate within the slabs and store the resulting texture indices. If the material changes, then whatever textures (and other bindings) the material has will be updated in-place within the slabs, so the indices won't change, so this system doesn't need to do anything to handle that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind updating extract_mesh_materials_2d
as well to make sure these don't diverge too much?
Maybe #16825 should land first, so we can make sure meshlets don't regress. |
to frame. This commit makes Bevy use change detection to only update `RenderMaterialInstances` and `RenderMeshMaterialIds` when meshes have been added, changed, or removed. `extract_mesh_materials`, the system that extracts these, now follows the pattern that `extract_meshes_for_gpu_building` established. This improves frame time of `many_cubes` from 3.9ms to approximately 3.1ms, which slightly surpasses the performance of Bevy 0.14.
# Objective - To fix a tiny bug in `bevy_ecs::storage::Tables` that, in one case, means it accidentally allocates an additional "empty" `Table`, resulting in two "empty" `Table`s: - The one pre-allocated empty table at index 0 whose index is designed to match up with `TableId::empty()` - One extra empty table, at some non-0 index, that does not match up with `TableId::empty()`. - This PR aims to prevent this extraneous `Table`, ensuring that entities with no components in table-storage reliably have their archetype's table ID be equal to `TableId::empty()`. ## Solution ### Background The issue occurs because: - `Tables` contains: - `tables: Vec<Table>` - The set of all `Table`s allocated in the world. - `table_ids: HashMap<Box<[ComponentId]>, TableId>` - An index to rapidly lookup the `Table` in `tables` by a set of `ComponentId`s. - When `Tables` is constructed it pre-populates the `tables` `Vec` with an empty `Table`. - This ensures that the first entry (index 0) is always the `Table` for entities with no components in table storage. - In particular, `TableId::empty()` is a utility that returns a `TableId` of `0`. - However, the `table_ids` map is not initialised to associate an empty `[ComponentId]` with `TableId` `0`. - This means, the first time a structural change tries to access a `Table` for an archetype with 0 table components: - `Tables::get_id_or_insert` is used to retrieve the target `Table` - The function attempts to lookup the entry in the `table_ids` `HashMap` whose key is the empty `ComponentId` set - The empty `Table` created at startup won't be found, because it was never inserted into `table_ids` - It will instead create a new table, insert it into the `HashMap` (preventing further instances of this issue), and return it. ### Changes - I considered simply initialising the `table_ids` `HashMap` to know about the pre-allocated `Table` - However, I ended up using the proposed solution discussed on Discord [#ecs-dev](https://discord.com/channels/691052431525675048/749335865876021248/1320430933152759958): - Make `Tables::get_id_or_insert` simply early-exit if the requested `component_ids` was empty. - This avoids unnecessarily hashing the empty slice and looking it up in the `HashMap`. - The `table_ids` `HashMap` is not exposed outside this struct, and is only used within `get_id_or_insert`, so it seems wasteful to defensively populate it with the empty `Table`. ## Testing This is my first Bevy contribution, so I don't really know the processes that well. That said: - I have introduced a little test that exercises the original issue and shows that it is now resolved. - I have run the `bevy_ecs` tests locally, so I have reasonable confidence I haven't broken that. - I haven't run any further test suites, mostly as when I tried to run test suites for the whole project it filled my entire SSD with >600GB of target directory output 😱😱😱
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.28.3 to 1.28.4. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/crate-ci/typos/releases">crate-ci/typos's releases</a>.</em></p> <blockquote> <h2>v1.28.4</h2> <h2>[1.28.4] - 2024-12-16</h2> <h3>Features</h3> <ul> <li><code>--format sarif</code> support</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's changelog</a>.</em></p> <blockquote> <h2>[1.28.4] - 2024-12-16</h2> <h3>Features</h3> <ul> <li><code>--format sarif</code> support</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/crate-ci/typos/commit/9d890159570d5018df91fedfa40b4730cd4a81b1"><code>9d89015</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/6b24563a993736342606b02dc6f98c7d86197fac"><code>6b24563</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/bd0a2769ae8d608b6e8152aff91e91d7d2aad0f3"><code>bd0a276</code></a> docs: Update changelog</li> <li><a href="https://github.com/crate-ci/typos/commit/370109dd4d88cfe9d647eb6cc9ed23e64cc75f8a"><code>370109d</code></a> Merge pull request <a href="https://redirect.github.com/crate-ci/typos/issues/1047">#1047</a> from Zxilly/sarif</li> <li><a href="https://github.com/crate-ci/typos/commit/63908449a70239a7719ed21f1caaca964c001470"><code>6390844</code></a> feat: Implement sarif format reporter</li> <li><a href="https://github.com/crate-ci/typos/commit/32b96444b9239039a8977dc5fc82e46732b77844"><code>32b9644</code></a> Merge pull request <a href="https://redirect.github.com/crate-ci/typos/issues/1169">#1169</a> from klensy/deps</li> <li><a href="https://github.com/crate-ci/typos/commit/720258f60bee6e05a3307b2ef7e7574d9d19f2d9"><code>720258f</code></a> Merge pull request <a href="https://redirect.github.com/crate-ci/typos/issues/1176">#1176</a> from Ghaniyyat05/master</li> <li><a href="https://github.com/crate-ci/typos/commit/a42904ad6e5d5533d2dc478538bf379b0189d20a"><code>a42904a</code></a> Update README.md</li> <li><a href="https://github.com/crate-ci/typos/commit/0169b9b9e82ae338ebe6d8af6956ec3b6a3fcc9f"><code>0169b9b</code></a> fix: Remove some unused deps</li> <li>See full diff in <a href="https://github.com/crate-ci/typos/compare/v1.28.3...v1.28.4">compare view</a></li> </ul> </details> <br /> [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=crate-ci/typos&package-manager=github_actions&previous-version=1.28.3&new-version=1.28.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Revert the retry queue for stuck meshlet groups that couldn't simplify added in bevyengine#15886. It was a hack that didn't really work, that was intended to help solve meshlets getting stuck and never getting simplified further. The actual solution is a new DAG building algorithm that I have coming in a followup PR. With that PR, there will be no need for the retry queue, as meshlets will rarely ever get stuck (I checked, the code never gets called). I split this off into it's own PR for easier reviewing. Meshlet IDs during building are back to being relative to the overall list of meshlets across all LODs, instead of starting at 0 for the first meshlet in the simplification queue for the current LOD, regardless of how many meshlets there are in the asset total. Not going to bother to regenerate the bunny asset for this PR.
Noticed these were either incomplete or inconsistent, so I fixed/augmented them.
# Objective Fixes: bevyengine#16578 ## Solution This is a patch fix, proper fix requires a breaking change. Added `Panic` enum variant and using is as the system meta default. Warn once behavior can be enabled same way disabling panic (originally disabling wans) is. To fix an issue with the current architecture, where **all** combinator system params get checked together, combinator systems only check params of the first system. This will result in old, panicking behavior on subsequent systems and will be fixed in 0.16. ## Testing Ran unit tests and `fallible_params` example. --------- Co-authored-by: François Mockers <mockersf@gmail.com> Co-authored-by: François Mockers <francois.mockers@vleue.com>
We have to extract the material ID from the mesh and stuff it in the vertex during visibility buffer resolution.
# Objective Allow users to enable or disable layout rounding for specific UI nodes and their descendants. Fixes bevyengine#16731 ## Solution New component `LayoutConfig` that can be added to any UiNode entity. Setting the `use_rounding` field of `LayoutConfig` determines if the Node and its descendants should be given rounded or unrounded coordinates. ## Testing Not tested this extensively but it seems to work and it's not very complicated. This really basic test app returns fractional coords: ```rust use bevy::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, report) .run(); } fn setup(mut commands: Commands) { commands.spawn(Camera2d); commands.spawn(( Node { left: Val::Px(0.1), width: Val::Px(100.1), height: Val::Px(100.1), ..Default::default() }, LayoutConfig { use_rounding: false }, )); } fn report(node: Query<(Ref<ComputedNode>, &GlobalTransform)>) { for (c, g) in node.iter() { if c.is_changed() { println!("{:#?}", c); println!("position = {:?}", g.to_scale_rotation_translation().2); } } } ``` --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: UkoeHB <37489173+UkoeHB@users.noreply.github.com>
…vyengine#16910) And add a bunch of tests to show that all the monotonic easing functions have roughly the expected shape. # Objective The `EaseFunction::Exponential*` variants aren't actually smooth as currently implemented, because they jump by about 1‰ at the start/end/both. - Fixes bevyengine#16676 - Subsumes bevyengine#16675 ## Solution This PR slightly tweaks the shifting and scaling of all three variants to ensure they hit (0, 0) and (1, 1) exactly while gradually transitioning between them. Graph demonstration of the new easing function definitions: <https://www.desmos.com/calculator/qoc5raus2z> ![desmos-graph](https://github.com/user-attachments/assets/c87e9fe5-47d9-4407-9c94-80135eef5908) (Yes, they look completely identical to the previous ones at that scale. [Here's a zoomed-in comparison](https://www.desmos.com/calculator/ken6nk89of) between the old and the new if you prefer.) The approach taken was to keep the core 2¹⁰ᵗ shape, but to [ask WolframAlpha](https://www.wolframalpha.com/input?i=solve+over+the+reals%3A+pow%282%2C+10-A%29+-+pow%282%2C+-A%29%3D+1) what scaling factor to use such that f(1)-f(0)=1, then shift the curve down so that goes from zero to one instead of ¹/₁₀₂₃ to ¹⁰²⁴/₁₀₂₃. ## Testing I've included in this PR a bunch of general tests for all monotonic easing functions to ensure they hit (0, 0) to (1, 1), that the InOut functions hit (½, ½), and that they have the expected convexity. You can also see by inspection that the difference is small. The change for `exponential_in` is from `exp2(10 * t - 10)` to `exp2(10 * t - 9.99859…) - 0.0009775171…`. The problem for `exponential_in(0)` is also simple to see without a calculator: 2⁻¹⁰ is obviously not zero, but with the new definition `exp2(-LOG2_1023) - FRAC_1_1023` => `1/(exp2(LOG2_1023)) - FRAC_1_1023` => `FRAC_1_1023 - FRAC_1_1023` => `0`. --- ## Migration Guide This release of bevy slightly tweaked the definitions of `EaseFunction::ExponentialIn`, `EaseFunction::ExponentialOut`, and `EaseFunction::ExponentialInOut`. The previous definitions had small discontinuities, while the new ones are slightly rescaled to be continuous. For the output values that changed, that change was less than 0.001, so visually you might not even notice the difference. However, if you depended on them for determinism, you'll need to define your own curves with the previous definitions. --------- Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
# Objective Some types like `RenderEntity` and `MainEntity` are just wrappers around `Entity`, so they should be able to implement `EntityBorrow`/`TrustedEntityBorrow`. This allows using them with `EntitySet` functionality. The `EntityRef` family are more than direct wrappers around `Entity`, but can still benefit from being unique in a collection. ## Solution Implement `EntityBorrow` and `TrustedEntityBorrow` for simple `Entity` newtypes and `EntityRef` types. These impls are an explicit decision to have the `EntityRef` types compare like just `Entity`. `EntityWorldMut` is omitted from this impl, because it explicitly contains a `&mut World` as well, and we do not ever use more than one at a time. Add `EntityBorrow` to the `bevy_ecs` prelude. ## Migration Guide `NormalizedWindowRef::entity` has been replaced with an `EntityBorrow::entity` impl.
# Objective This PR implements `FromStr` for `Val`, so developers can parse values like `10px` and `50%` ## Testing Added tests for this. I think they cover pretty much everything, and it's a fairly simple unit test. ## Limitations Currently the following float values are not parsed: - `inf`, `-inf`, `+infinity`, `NaN` - `2.5E10`, `2.5e10`, `2.5E-10` For my use case this is perfectly fine but other developers might want to support these values
…evyengine#16931) # Objective Now that `variadics_please` has a 1.1 release, we can re-implement the original solution. ## Solution Copy-paste the code from the [original PR](bevyengine#15931) branch :)
… doesn't exist (bevyengine#16932) Fixes a crash when using deferred rendering but disabling the default deferred lighting plugin. # The Issue The `ScreenSpaceReflectionsPlugin` references `NodePbr::DeferredLightingPass`, which hasn't been added when `PbrPlugin::add_default_deferred_lighting_plugin` is `false`. This yields the following crash: ``` thread 'main' panicked at /Users/marius/Documents/dev/bevy/crates/bevy_render/src/render_graph/graph.rs:155:26: InvalidNode(DeferredLightingPass) stack backtrace: 0: rust_begin_unwind at /rustc/90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf/library/std/src/panicking.rs:665:5 1: core::panicking::panic_fmt at /rustc/90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf/library/core/src/panicking.rs:74:14 2: bevy_render::render_graph::graph::RenderGraph::add_node_edges at /Users/marius/Documents/dev/bevy/crates/bevy_render/src/render_graph/graph.rs:155:26 3: <bevy_app::sub_app::SubApp as bevy_render::render_graph::app::RenderGraphApp>::add_render_graph_edges at /Users/marius/Documents/dev/bevy/crates/bevy_render/src/render_graph/app.rs:66:13 4: <bevy_pbr::ssr::ScreenSpaceReflectionsPlugin as bevy_app::plugin::Plugin>::finish at /Users/marius/Documents/dev/bevy/crates/bevy_pbr/src/ssr/mod.rs:234:9 5: bevy_app::app::App::finish at /Users/marius/Documents/dev/bevy/crates/bevy_app/src/app.rs:255:13 6: bevy_winit::state::winit_runner at /Users/marius/Documents/dev/bevy/crates/bevy_winit/src/state.rs:859:9 7: core::ops::function::FnOnce::call_once at /Users/marius/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5 8: core::ops::function::FnOnce::call_once{{vtable.shim}} at /Users/marius/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5 9: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once at /Users/marius/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/boxed.rs:2454:9 10: bevy_app::app::App::run at /Users/marius/Documents/dev/bevy/crates/bevy_app/src/app.rs:184:9 11: bevy_deferred_test::main at ./src/main.rs:9:5 12: core::ops::function::FnOnce::call_once at /Users/marius/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5 ``` ### Minimal reproduction example: ```rust use bevy::core_pipeline::prepass::{DeferredPrepass, DepthPrepass}; use bevy::pbr::{DefaultOpaqueRendererMethod, PbrPlugin, ScreenSpaceReflections}; use bevy::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins.set(PbrPlugin { add_default_deferred_lighting_plugin: false, ..default() })) .add_systems(Startup, setup) .insert_resource(DefaultOpaqueRendererMethod::deferred()) .run(); } /// set up a camera fn setup( mut commands: Commands ) { // camera commands.spawn(( Camera3d::default(), Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y), DepthPrepass, DeferredPrepass, ScreenSpaceReflections::default(), )); } ``` # The Fix When no node under the default lighting node's label exists, this label isn't added to the SSR's graph node edges. It's good to keep the SSRPlugin enabled, this way, users can plug in their own lighting system, which I have successfully done on top of this PR. # Workarounds A current workaround for this issue is to re-use Bevy's `NodePbr::DeferredLightingPass` as the label for your own custom lighting pass node.
This PR simply exposes Bevy PBR's `TONEMAPPING_LUT_TEXTURE_BINDING_INDEX` and `TONEMAPPING_LUT_SAMPLER_BINDING_INDEX`. # Objective Alongside bevyengine#16932, this is the last required change to be able to replace Bevy's built-in deferred lighting pass with a custom one based on the original logic.
…bevyengine#16936) ## Objective I believe these started as structs, back when that was how commands had to be implemented. Now they just hide implementation details. ## Solution Remove the helper functions and move each implementation into its respective method, except for the ones that actually reduce code duplication.
) # Objective bevy_reflect is a big part of bevy_math's dependency footprint, and is often not useful when using bevy_math standalone (as I often do). The goal with this PR is to avoid pulling in those dependencies by default without compromising the usability of bevy_math types within Bevy proper. ## Solution `bevy_reflect` has been removed from default features of `bevy_math`. However, the feature is enabled by `bevy_internal`, so that `bevy_reflect` is enabled when `bevy_math` is used through `bevy`. Philosophically, if there were a feature flag toggling reflection on `bevy` globally, then whether `bevy_math` enabled `bevy_reflect` itself would depend on that, but that doesn't exist for the time being. ## Testing It compiles :) ## Migration Guide `bevy_reflect` has been made a non-default feature of `bevy_math`. (It is still enabled when `bevy_math` is used through `bevy`.) You may need to enable this feature if you are using `bevy_math` on its own and desire for the types it exports to implement `Reflect` and other reflection traits.
# Objective - Fixes bevyengine#16563 - Make sure bevy_image is available when needed ## Solution - Add a new feature for `bevy_image` - Also enable the `bevy_image` feature in `bevy_internal` for all features that use `bevy_image` themselves
# Objective - Fixes bevyengine#16568 ## Solution - `bevy_winit` feature also enables `bevy_window`
# Objective - Fixes bevyengine#16571 ## Solution - When position delta is zero, don't trigger `Drag` or `DragOver` events ## Testing - tested with the code from the issue
# Objective `SubApps` is visible within the documentation for `bevy_app`. However, no way of accessing the `SubApps` field in `App` is currently available. ## Solution Expose two new functions, `App::sub_apps()` and `App::sub_apps_mut()`, which give immutable and mutable access to `SubApps` respectively. The other solution is to hide `SubApps`, which I submitted as a PR at <bevyengine#16953>. ## Testing Because of the simplicity of the changes, I only tested by compiling `bevy_app` - which compiled successfully. Note: `SubApps`, and its corresponding field on `App`, are not used outside of `bevy_app` - which means that compiling the other crates is not necessary.
# Objective With the introduction of bevy_input_focus, the uses of "focus" in bevy_picking are quite confusing and make searching hard. Users will intuitively think these concepts are related, but they actually aren't. ## Solution Rename / rephrase all uses of "focus" in bevy_picking to refer to "hover", since this is ultimately related to creating the `HoverMap`. ## Migration Guide Various terms related to "focus" in `bevy_picking` have been renamed to refer to "hover" to avoid confusion with `bevy_input_focus`. In particular: - The `update_focus` system has been renamed to `generate_hovermap` - `PickSet::Focus` and `PostFocus` have been renamed to `Hover` and `PostHover` - The `bevy_picking::focus` module has been renamed to `bevy_picking::hover` - The `is_focus_enabled` field on `PickingPlugin` has been renamed to `is_hover_enabled` - The `focus_should_run` run condition has been renamed to `hover_should_run`
# Summary - I started experimenting if `TextureAtlas` and friends can be moved to `bevy_image`. See [Discord](https://discord.com/channels/691052431525675048/692572690833473578/1320176054911897642) thread. - While doing that, and moving `DynamicTextureAtlasBuilder` to `bevy_image`, it revealed that `DynamicTextureAtlasBuilder` depends on `bevy_render::GpuImage`, but we can't have `bevy_image` depend on `bevy_render`. - The reason for the dependency is an assertion introduced in [this PR](https://github.com/bevyengine/bevy/pull/12827/files?show-viewed-files=true&file-filters%5B%5D=#diff-d9afd2170466f4aae340b244bdaa2a80aef58e979268c003878ca6c95860eb37R59). - [It doesn't seem like there was a specific reason for that change](https://discord.com/channels/691052431525675048/743663924229963868/1320506862067650580), so should be safe to change it. - So instead of the cast, just look up `asset_usage` directly on the concrete `Image` type. - Also update the message which referred to a non-existent variable `atlas_texture_handle` (it was renamed during a subsequent refactor PR). # Testing - Checked on Discord if there was any known reason this had to stay like this. - CI builds it.
…ne#16957) # Objective Almost all of the `*InOut` easing functions are not actually smooth (`SineInOut` is the one exception). Because they're defined piecewise, they jump from accelerating upwards to accelerating downwards, causing infinite jerk at t=½. ## Solution This PR adds the well-known [smoothstep](https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml), as well as its higher-degree version [smootherstep](https://en.wikipedia.org/wiki/Smoothstep#Variations), as easing functions. Mathematically, these are the classic [Hermite interpolation](https://en.wikipedia.org/wiki/Hermite_interpolation) results: - for smoothstep, the cubic with velocity zero at both ends - for smootherstep, the quintic with velocity zero *and acceleration zero* at both ends And because they're simple polynomials, there's no branching and thus they don't have the acceleration jump in the middle. I also added some more information and cross-linking to the documentation for these and some of the other easing functions, to help clarify why one might want to use these over other existing ones. In particular, I suspect that if people are willing to pay for a quintic they might prefer `SmootherStep` to `QuinticInOut`. For consistency with how everything else has triples, I added `Smooth(er)Step{In,Out}` as well, in case people want to run the `In` and `Out` versions separately for some reason. Qualitatively they're not hugely different from `Quadratic{In,Out}` or `Cubic{In,Out}`, though, so could be removed if you'd rather. They're low cost to keep, though, and convenient for testing. ## Testing These are simple polynomials, so their coefficients can be read directly from the Horner's method implementation and compared to the reference materials. The tests from bevyengine#16910 were updated to also test these 6 new easing functions, ensuring basic behaviour, plus one was updated to better check that the InOut versions of things match their rescaled In and Out versions. Even small changes like ```diff - (((2.5 + (-1.875 + 0.375*t) * t) * t) * t) * t + (((2.5 + (-1.85 + 0.375*t) * t) * t) * t) * t ``` are caught by multiple tests this way. If you want to confirm them visually, here are the 6 new ones graphed: <https://www.desmos.com/calculator/2d3ofujhry> ![smooth-and-smoother-step](https://github.com/user-attachments/assets/a114530e-e55f-4b6a-85e7-86e7abf51482) --- ## Migration Guide This version of bevy marks `EaseFunction` as `#[non_exhaustive]` to that future changes to add more easing functions will be non-breaking. If you were exhaustively matching that enum -- which you probably weren't -- you'll need to add a catch-all (`_ =>`) arm to cover unknown easing functions.
# Objective - To fix the benches panicking on `main` ## Solution - It appears that systems requiring access to a non-existing `Res` now causes a panic - Some of the benches run systems that access resources that have not been inserted into the world - I have made it so that those resources are inserted into the world ## Testing - I ran all the ecs benches and they all run without panicking Co-authored-by: Oliver Maskery <oliver@wellplayed.games>
# Objective Make it so that users can ease between tuples of easeable values. ## Solution Use `variadics_please`'s `all_tuples_enumerated` macro to generate code that creates these trait implementations. For two elements, the result looks like this: ```rust impl<T0: Ease, T1: Ease> Ease for (T0, T1) { fn interpolating_curve_unbounded(start: Self, end: Self) -> impl Curve<Self> { let curve_tuple = ( <T0 as Ease>::interpolating_curve_unbounded(start.0, end.0), <T1 as Ease>::interpolating_curve_unbounded(start.1, end.1), ); FunctionCurve::new(Interval::EVERYWHERE, move |t| { ( curve_tuple.0.sample_unchecked(t), curve_tuple.1.sample_unchecked(t), ) }) } } ``` ## Testing It compiles, and I futzed about with some manual examples, which seem to work as expected. --- ## Showcase Easing curves now support easing tuples of values that can themselves be eased. For example: ```rust // Easing between two `(Vec3, Quat)` values: let easing_curve = EasingCurve::new( (vec3(0.0, 0.0, 0.0), Quat::from_rotation_z(-FRAC_PI_2)), (vec3(1.0, 1.0, 1.0), Quat::from_rotation_z(FRAC_PI_2)), EaseFunction::ExponentialInOut ); ```
# Objective Fixes bevyengine#16850 ## Solution Add a new function `SubApp::take_extract()`, similar to `Option::take()`, which allows stealing the currently installed extract function of a sub-app, with the intent to replace it with a custom one calling the original one via `set_extract()`. This pattern enables registering a custom "world sync" function similar to the existing one `entity_sync_system()`, to run custom world sync logic with mutable access to both the main and render worlds. ## Testing `cargo r -p ci` currently doesn't build locally, event after upgrading rustc to latest and doing a `cargo update`.
4e30455
to
08ee2a9
Compare
I don't know what happened to this branch, but I needed to force-push to fix it, sorry. |
@tychedelia Done |
I'm going to close and resubmit this so that the commit history is cleaned up. |
This commit makes Bevy use change detection to only update
RenderMaterialInstances
andRenderMeshMaterialIds
when meshes have been added, changed, or removed.extract_mesh_materials
, the system that extracts these, now follows the pattern thatextract_meshes_for_gpu_building
established.This improves frame time of
many_cubes
from 3.9ms to approximately 3.1ms, which slightly surpasses the performance of Bevy 0.14.