-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Excessive logging from new mesh_picking
backend
#16065
Comments
Looking into this now |
I think a core issue here is that we're computing mesh intersections across all spawned meshes by default. The performance tradeoff there is not what most people will want in actual games. Ex: when spawning a complex GLTF scene, pretty much nobody wants raw-mesh intersections. The "pick any mesh by default" behavior really only makes sense in editor scenarios, which is not what our defaults should be optimizing for. Physics collision shapes are generally used for in-game picking (similar in concept to At a bare minimum, we should disable the current mesh picking behavior by default. But I'll assert that the current picking behavior (a global PointerHits event queue) has very limited practical applications. What Bevy app developers will want in general for 3D use cases (and what we should push them toward) is a way to explicitly add collider types to their entities (generally simple / easy to compute shapes like AABBs, spheres, capsules, etc with actual meshes being special exceptions), define the layer those types live on, on-demand request a raycast, and then receive the set of matching items in their own collection. Some use cases might benefit from a global "what did I just click across all mesh types" feed, but I suspect, given the diversity of what might be rendered to the screen (and how selection demands will change based on game context), I'm not sure if its even a path we should be pushing people toward. A generic PointerHits (or picking interaction) event across all types isn't going to cut it for most applications, both in 2d and 3d. I think its most practical application is debugging and editor scenarios. And even in those cases, I think finer and more intentional granularity would be good. It seems valuable to provide a way to "picking style" trigger observers for click and hover events (ex scenarios like "I want to write an observer for click/hover events when a 3d player collider is hovered"), but I think we need "scoping" to be an integral part of the system. |
I'll clarify that it is much more likely to be useful in 2D, and that the cost of enabling it by default would be low enough to be worth considering / people will even expect this to be available by default. |
In terms of "pick any mesh by default behavior" I'm fine to have that off by default for 3D. The functionality is there if they want it, and should be easy enough to find an enable.
I agree, I do think this is probably going to be important. We could do a lot more to support this, and I know @Jondolf wants to. But I'm not sure I would use picking for that, that's just raycasting. The mesh-picking backend is intentionally very cut down and narrowly scoped, it's basically just intended for use in the examples (where it's very handy) and the editor prototypes (where it's basically required for a bunch of core interactions). Just so we're all on the same page, So when you say
and
I'm a little confused, because world.observe(|trigger: Trigger<Pointer<Click>>, player_coliders: Query<&PlayerColider>| {
if let Some(colider) = player_coliders.get(trigger.target()) {
// add my logic to coliders here
}
}); Please let me know if I'm misunderstanding your point. |
Thinking about it, I'd be theoretically OK having basically all |
@cart I think you might be fundamentally misunderstanding how this works. All of what you are saying is supported by composing backends. Backends ultimately decide the performance cost, not the picking plugin.
This is a function of the mesh picking backend settings. Downstream, bevy_mod_picking provides this type of backend for debug purposes, but you can also use components to instead opt-in to picking where you need it. Again, this raycasting backend is essentially for debugging. It's fast enough that it's fine for most scenes, but, as I've said before, bevy's default should probably be a physics or shader based backend. We aren't there yet though, and this provides a way to get things working for 3d cases right now. The point of this architecture is that it is completely modular, and users can choose whatever picking backends make sense for their use case. Users are free to disable this backend, and drop in one of the existing 3rd party avian or rapier backends.
Agreed.
These implementation details can exist in the backends, specific to their implementation. For example, the various physics engine backends that mod_picking provides out of the box do use collision shapes like this, but it is specific to each integration, and what they support (e.g. raycast early exit and component filtering).
I completely disagree. This is what allows us to support rich picking events for any entity and across picking backends without prescribing how the hit tests are run. There is no cost to this - the raycasting backend behavior has nothing to do with the unified pointer hit stream. |
To respond to the issue at hand:
|
Yeah this is the space I think the current mesh backend is right for. Glad it seems we're all in agreement on this.
Fundamentally this is all still the same "feed" though in terms of signals being sent out.
This has a number of downsides. In the current impl, it implies that we're computing all intersections for all meshes ahead of time, computing a single global click result, and then filtering down to
Pretty sure I'm not, but I'll keep an open mind. If after reading this message you still think I'm missing something, please let me know.
I understood this much.
This is (one of) my fundamental sticking points (the other being the much more pressing concern of the current mesh picking backend not being a suitable default, which it sounds like we all agree on). I'm asserting that a single unified "pointer event" (and how these relate to each other, such as blocking hover events across entities and types of entities) isn't fine enough granularity for many use cases, especially in 3D. It makes presumptions: Hover ( The system also assumes that the "click stop" information is fixed. Real world apps will have more complicated use cases that fall outside the "ui pointer model". Ex: "click the item under my mouse with the highest rarity". Or based on the state computed this frame, the player might be in "item selection mode", "enemy selection mode", or some combination of the two. This context could be determined based on what is under the mouse currently. A very solid chunk of picking scenarios are best expressed as "describe what intersections you want to check", "retrieve the list of matches", and "from that list select zero or more entities". I'm definitely not saying that the picking system as implemented today is not useful or that it needs to fundamentally change. My one primary goal for this discussion was to convince people that the current mesh picking backend should not be enabled by default (which seems to have been successful). My secondary goals are to (a) convince people that I apologize for my phrasing in these cases: "A generic PointerHits (or picking interaction) event across all types isn't going to cut it for most applications" and "I'll assert that the current picking behavior (a global PointerHits event queue) has very limited practical applications". I could have phrased this (more accurately) in a way that didn't minimize the very real / common / valuable scenarios covered by I also think that a
Agreed. Not being able to pick something doesn't feel like an error to me, unless the developer has explicitly asked for it to be pickable.
Agreed. UI picking makes perfect sense / should of course be enabled by default. Sprite picking falls into a similar category, although 2D games are where I think we start to see the limits of the current unified picking system. |
I'd like to throw my own experience with it in as well, as I hit something similar the other day when updating. I'm using custom attributes with my meshes, so for example I'm packing vertex positions into a u32. This lead to massive spam of |
You are describing the existing raycasting API (and those of rapier/avian) verbatim. My point is that this has nothing to do with picking. Please bear with me. You can invent endlessly complex hypothetical scenarios, but you always have the option of writing a backend that has the performance and layer traversal characteristics you want for your game. If your use case truly does not fit into the paradigm of UI pointer interactions (which seems incredibly unlikely to me), then... don't use the UI pointer interactions. You still have the full ECS toolkit at your disposal. Finding out which thing is directly under the pointer is not as trivial as raycasting into the scene. You can have multiple cameras being layered with UI and each other. The entities on screen are often rendered in completely different ways: UI, 3d meshes, 2d meshes, gizmos, custom renderers. You need to be able to have multiple sources of hit tests that can interleave properly to match the order of what is on screen. That is the hard problem that "picking" solves.
This is what backends are intended for! Just because the picking spec says you should report the top hit(s) and send event(s), that doesn't preclude you from bolting on your own custom logic for entities behind the hoverable ones. You can trigger those hover handlers manually, skipping the built-in focus logic entirely. The focus system is just one way to trigger the pointer events, it (shouldn't) own them.
I just don't see what this has to do with picking. If what you are doing falls outside of the UI pointer model, and all you want to do is hit tests, then do hit tests however you want! I don't see why you can't run arbitrary hit tests and trigger click handlers yourself. The focus system is the entire point of entities participating in the combined stream of hits (i.e. "picking"). If you don't want the focus system, you can still use picking functionality that lives above (pointer events) and below (pointer locations, hit tests) the focus system. This combined focus system is something that I really don't want to lose. I do want to add that I've been repeatedly encouraging others to make a better frontend (pointer events). @NthTensor has done a great job porting the mod_picking version of pointer events to observers, but I'm not particularly attached to it. The frontend was an early attempt at ECS callbacks that predates bevy's observers by more than a year, iirc. I'd also support improvements to the focus system, but I want to be sure we don't end up losing what is, I think, the most valuable part of the picking plugin's current design. |
I think I understand now: My sense is that we are still talking past each-other a little bit. You are coming at this from a much more user-focused prospective than we are (which is good imo) but it also seems like maybe you have not actually tried building the abstractions you are talking about using the new system. I say this, because I think the new system is pretty great for what you are talking about, even if it's only one of the necessary building blocks.
It's probably worth noting that we are not computing a global result, as I think you are aware. A pointer can end up hovering multiple entities, and
This is true within the picking system but you can also just turn off blocking entirely and figure out what interrupts what in user code. It's just an optimization for when these are tied, which is often.
I see, and I don't disagree. But the feedback I've gotten from the few early adopters is that they are pretty painlessly building their own custom "selectors" on top of the bevy picking observer events. Architect of ruin has implemented a heuristics based selection system using it, by combining observers and some additional event streams. You seem to be saying that this functionality should be easier to build, or provided in the engine core. That makes sense, and I think the existing picking
I'm tentatively with you. I think picking is quite flexible, and the feedback i've gotten from users so far is that they are building more complex interactions on top of picking rather than along side it.
Yep. I'm with you for both of these, I think. But @aevyrie and I are asking about scope and relevancy: how much of this is really "picking" and how much is a more general question about bevy's preferred approach to user interaction behavior? I really want to make sure we're on the same page here, so here's a little description of what The fundamental task of The second tasks of Connecting these two modules together is the It seems to me that you are suggesting a third task, and it's still not entirely clear to me what it is. |
I know. Please give me the benefit of the doubt here. I've used raycasting APIs extensively, both in the context of Bevy and elsewhere. I also know what picking is, as you have defined it (which is aligned with how pretty much everyone defines it). I know why One potential hangup here seems to be whether we regard "picking" as "asking questions about what is under my mouse and returning those results" or "finding what is directly under the pointer, solving the specific 'exposing hits across sources, sorting them, and picking the closest' problem". I'm happy to accept that definition and call the scenarios I've described something else. I believe they exist somewhere on the spectrum between "arbitrary raycast scenarios" and "picking a depth sorted result under my mouse, taking blocking into account", in such a way that we might be able to share infrastructure in places (ex: over/out hover tracking, events, etc). But for clarity and to avoid further controversy, I will no longer refer to the more general scenarios as "picking".
This is the category of thing I was trying to touch on (sharing infrastructure with the more general "asking questions about what is/was under my mouse" scenarios). This is the "3rd scenario" as @NthTensor described it, which is what I was trying to describe above.
The "global" result I'm talking about is the "depth sort and block" result, which determines if hover and click events are fired. The choices made by an entity above you (provided by an arbitrary backend) affect whether your hover or click events fire. There is (currently) no way to say "I want hover events no matter what is above me" for a specific entity. The system assumes there is one question to answer each frame (what is being "picked" as defined by Again, I fully acknowledge that this is a Good Thing for picking. We want that. But with a singular focus on answering the "picking question" we have prevented a category of other questions from being asked. My "3rd scenario" is "when people want to ask questions about what is under their mouse (and what was under their mouse) that the global picking sort behavior and individual entity configuration cannot answer (edit: or that a single configuration of that system cannot answer within a given frame) , how can we make that as efficient and ergonomic as possible, and potentially reuse infrastructure that has already been built". Some various (not necessarily related) ideas:
I hope that helps convey where my head is at / illustrates that overlap + generalization is possible. Again this was all a secondary concern relative to disabling the current mesh picking backend by default. We don't have to engage with these ideas further if they are uninteresting to you. Certainly not a high priority right now. |
@cart I'd like to continue discussing this, but maybe we should start a new issue? I'm worried we are OT for this particular issue, and I've opened a PR that would close this if merged. Edit: I'll create one. |
Ok, now I understand and I think I'm totally on board. Thanks for explaining, sorry about the confusion. We can continue that off-shoot in the other thread. For now, I totally support your more direct suggestions for the mesh picking backend. |
# Objective - Mesh picking is noisy when a non triangle list is used - Mesh picking runs even when users don't need it - Resolve #16065 ## Solution - Don't add the mesh picking plugin by default - Remove error spam
# Objective - Mesh picking is noisy when a non triangle list is used - Mesh picking runs even when users don't need it - Resolve #16065 ## Solution - Don't add the mesh picking plugin by default - Remove error spam
commit 78a4bea Author: ickshonpe <david.curthoys@googlemail.com> Date: Sun Oct 27 22:39:32 2024 +0000 Move `ContentSize` requirements from `Node` to the widget defining components (bevyengine#16083) # Objective Missed this in the required components PR review. `ContentSize` isn't used by regular UI nodes, only those with intrinsically sized content that needs a measure func. ## Solution Remove `ContentSize` from `Node`'s required components and add it to the required components of `Text` and `UiImage`. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> commit c4c1c8f Author: mgi388 <135186256+mgi388@users.noreply.github.com> Date: Mon Oct 28 09:38:07 2024 +1100 Undeprecate is_playing_animation (bevyengine#16121) # Objective - Fixes bevyengine#16098 ## Solution - Undeprecate `is_playing_animation` and copy the docs from `animation_is_playing` to it. ## Testing - CI ## Migration https://github.com/bevyengine/bevy-website/blob/68e9a34e3068ed2e7db5ae0b4b32feac94a589dd/release-content/0.15/migration-guides/_guides.toml#L13-L17 needs to be removed. commit 3d72f49 Author: ickshonpe <david.curthoys@googlemail.com> Date: Sun Oct 27 20:08:51 2024 +0000 Layout rounding debug example (bevyengine#16096) # Objective Simple example for debugging layout rounding errors. <img width="1039" height="752" alt="layout_rounding_debug" src="https://github.com/user-attachments/assets/12673000-e267-467e-b25b-3f8001c1347c"> Any white lines are gaps in the layout caused by coordinate rounding errors. commit 86ee8e4 Author: ickshonpe <david.curthoys@googlemail.com> Date: Sun Oct 27 19:14:46 2024 +0000 Move `UiImage` from `ui_node` to the `widget::image` module (bevyengine#16084) # Objective `UiImage` isn't just a general image component now, it's the defining component for the image widget so it belongs in the image widget's module. commit d01db9b Author: Hexroll by Pen, Dice & Paper <143178036+hexroll@users.noreply.github.com> Date: Sun Oct 27 19:08:34 2024 +0000 Adding alpha_threshold to OrderIndependentTransparencySettings for user-level optimization (bevyengine#16090) # Objective Order independent transparency can filter fragment writes based on the alpha value and it is currently hard-coded to anything higher than 0.0. By making that value configurable, users can optimize fragment writes, potentially reducing the number of layers needed and improving performance in favor of some transparency quality. ## Solution This PR adds `alpha_threshold` to the OrderIndependentTransparencySettings component and uses the struct to configure a corresponding shader uniform. This uniform is then used instead of the hard-coded value. To configure OIT with a custom alpha threshold, use: ```rust fn setup(mut commands: Commands) { commands.spawn(( Camera3d::default(), OrderIndependentTransparencySettings { layer_count: 8, alpha_threshold: 0.2, }, )); } ``` ## Testing I tested this change using the included OIT example, as well as with two additional projects. ## Migration Guide If you previously explicitly initialized OrderIndependentTransparencySettings with your own `layer_count`, you will now have to add either a `..default()` statement or an explicit `alpha_threshold` value: ```rust fn setup(mut commands: Commands) { commands.spawn(( Camera3d::default(), OrderIndependentTransparencySettings { layer_count: 16, ..default() }, )); } ``` --------- Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com> commit 3fc2bd7 Author: Rob Parrett <robparrett@gmail.com> Date: Sun Oct 27 12:06:19 2024 -0700 Cosmetic tweaks to `query_gltf_primitives` (bevyengine#16102) # Objective This example is really confusing to look at and tell at a glance whether it's broken or not. It's displaying a strange shape -- a cube with two vertices stretched in a couple dimensions at an odd angle, and doing its vertex position modification in a way where the intent isn't obvious. ## Solution - Change the gltf geometry so that the object is a recognizable regular shape - Change the vertex modification so that the entire cube top is being "lifted" from the cube - Adjust colors, lighting, and camera location so we can see what's going on - Also remove some irrelevant shadow and environment map setup ## Before ![Image](https://github.com/user-attachments/assets/e5dd5075-0480-49d4-b1ed-cf1fe6106f3c) ## After <img width="1280" alt="image" src="https://github.com/user-attachments/assets/59cab60d-efbc-47c3-8688-e4544b462421"> commit 7451900 Author: Miles Silberling-Cook <NthTensor@users.noreply.github.com> Date: Sun Oct 27 15:05:31 2024 -0400 Emit picking event streams (bevyengine#16105) # Objective In `bevy_mod_picking` events are accessible through event listeners or `EventReader`s. When I replaced event listeners with observers, I removed the `EventReader` for simplicity. This adds it back. ## Solution All picking events are now properly registered, and can be accessed through `EventReader<Pointer<E>>`. `Pointer` now tracks the entity the event targeted initially, and this can also be helpful in observers (which don't currently do this). ## Testing The picking examples run fine. This shouldn't really change anything. --------- Co-authored-by: Aevyrie <aevyrie@gmail.com> commit 54b323e Author: Aevyrie <aevyrie@gmail.com> Date: Sun Oct 27 12:03:48 2024 -0700 Mesh picking fixes (bevyengine#16110) # Objective - Mesh picking is noisy when a non triangle list is used - Mesh picking runs even when users don't need it - Resolve bevyengine#16065 ## Solution - Don't add the mesh picking plugin by default - Remove error spam commit a644ac7 Author: Tau Gärtli <git@tau.garden> Date: Sun Oct 27 20:01:50 2024 +0100 More `#[doc(fake_variadic)]` goodness (bevyengine#16108) This PR adds `#[doc(fake_variadic)]` to that were previously not supported by rustdoc. Thanks to an [upstream contribution](rust-lang/rust#132115) by yours truly, `#[doc(fake_variadic)]` is now supported on impls such as `impl QueryData for AnyOf<(T, ...)>` 🎉 Requires the latest nightly compiler (2024-10-25) which is already available on [docs.rs](https://docs.rs/about/builds). ![image](https://github.com/user-attachments/assets/68589c7e-f68f-44fb-9a7b-09d24ccf19c9) ![image](https://github.com/user-attachments/assets/f09d20d6-d89b-471b-9a81-4a72c8968178) This means that the impl sections for `QueryData` and `QueryFilter` are now nice and tidy ✨ --- I also added `fake_variadic` to some impls that use `all_tuples_with_size`, however I'm not entirely happy because the docs are slightly misleading now: ![image](https://github.com/user-attachments/assets/fac93d08-dc02-430f-9f34-c97456256c56) Note that the docs say `IntoBindGroupLayoutEntryBuilderArray<1>` instead of `IntoBindGroupLayoutEntryBuilderArray<N>`. commit 60b2c7c Author: François Mockers <mockersf@gmail.com> Date: Fri Oct 25 22:14:39 2024 +0200 fix bevy_dev_tools build (bevyengine#16099) # Objective - bevy_dev_tools 0.15.0-rc.1 failed to build docs - it use bevy_text feature in bevy_ui but it's not enabled by default - https://docs.rs/crate/bevy_dev_tools/0.15.0-rc.1 - ## Solution - enable bevy_text feature of bevy_ui commit 7c59317 Author: BD103 <59022059+BD103@users.noreply.github.com> Date: Fri Oct 25 16:11:51 2024 -0400 Fix `bevy_picking` plugin suffixes (bevyengine#16082) # Objective - `MeshPickingBackend` and `SpritePickingBackend` do not have the `Plugin` suffix - `DefaultPickingPlugins` is masquerading as a `Plugin` when in reality it should be a `PluginGroup` - Fixes bevyengine#16081. ## Solution - Rename some structures: |Original Name|New Name| |-|-| |`MeshPickingBackend`|`MeshPickingPlugin`| |`MeshPickingBackendSettings`|`MeshPickingSettings`| |`SpritePickingBackend`|`SpritePickingPlugin`| |`UiPickingBackendPlugin`|`UiPickingPlugin`| - Make `DefaultPickingPlugins` a `PluginGroup`. - Because `DefaultPickingPlugins` is within the `DefaultPlugins` plugin group, I also added support for nested plugin groups to the `plugin_group!` macro. ## Testing - I used ripgrep to ensure all references were properly renamed. - For the `plugin_group!` macro, I used `cargo expand` to manually inspect the expansion of `DefaultPlugins`. --- ## Migration Guide > [!NOTE] > > All 3 of the changed structures were added after 0.14, so this does not need to be included in the 0.14 to 0.15 migration guide. - `MeshPickingBackend` is now named `MeshPickingPlugin`. - `MeshPickingBackendSettings` is now named `MeshPickingSettings`. - `SpritePickingBackend` is now named `SpritePickingPlugin`. - `UiPickingBackendPlugin` is now named `UiPickingPlugin`. - `DefaultPickingPlugins` is now a a `PluginGroup` instead of a `Plugin`. commit 611ba8b Author: Ludwig DUBOS <ludwig.dubos@pm.me> Date: Fri Oct 25 22:08:14 2024 +0200 Add `AsyncSeekForwardExt` trait to allows a similar API to the previous Bevy version (bevyengine#16027) # Objective This PR introduces an `AsyncSeekForwardExt` trait, which I forgot in my previous PR bevyengine#14194. This new trait is analogous to `AsyncSeekExt` and allows all implementors of `AsyncSeekForward` to directly use the `seek_forward` function in async contexts. ## Solution - Implement a new `AsyncSeekForwardExt` trait - Automatically implement this trait for all types that implement `AsyncSeekForward` ## Showcase This new trait allows a similar API to the previous Bevy version: ```rust #[derive(Default)] struct UniverseLoader; #[derive(Asset, TypePath, Debug)] struct JustALilAsteroid([u8; 128]); impl AssetLoader for UniverseLoader { type Asset = JustALilAsteroid; type Settings = (); type Error = std::io::Error; async fn load<'a>( &'a self, reader: &'a mut Reader<'a>, _settings: &'a Self::Settings, _context: &'a mut LoadContext<'_>, ) -> Result<Self::Asset, Self::Error> { // read the asteroids entry table let entry_offset: u64 = /* ... */; let current_offset: u64 = reader.seek_forward(0).await?; // jump to the entry reader.seek_forward(entry_offset - current_offset).await?; let mut asteroid_buf = [0; 128]; reader.read_exact(&mut asteroid_buf).await?; Ok(JustALilAsteroid(asteroid_buf)) } fn extensions(&self) -> &[&str] { &["celestial"] } } ``` commit c6a66a7 Author: Patrick Walton <pcwalton@mimiga.net> Date: Thu Oct 24 14:16:00 2024 -0700 Place percentage-closer soft shadows behind a feature gate to save on samplers. (bevyengine#16068) The two additional linear texture samplers that PCSS added caused us to blow past the limit on Apple Silicon macOS and WebGL. To fix the issue, this commit adds a `--feature pbr_pcss` feature gate that disables PCSS if not present. Closes bevyengine#15345. Closes bevyengine#15525. Closes bevyengine#15821. --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com> Co-authored-by: IceSentry <IceSentry@users.noreply.github.com> commit 897404e Author: Patrick Walton <pcwalton@mimiga.net> Date: Thu Oct 24 14:00:11 2024 -0700 Reduce the clusterable object UBO size below 16384 for WebGL 2. (bevyengine#16069) The PCSS PR bevyengine#13497 increased the size of clusterable objects from 64 bytes to 80 bytes but didn't decrease the UBO size to compensate, so we blew past the 16kB limit on WebGL 2. This commit fixes the issue by lowering the maximum number of clusterable objects to 204, which puts us under the 16kB limit again. Closes bevyengine#15998. commit 9274bfe Author: Carter Anderson <mcanders1@gmail.com> Date: Wed Oct 23 18:24:17 2024 -0500 Move TextureAtlas into UiImage and remove impl Component for TextureAtlas (bevyengine#16072) # Objective Fixes bevyengine#16064 ## Solution - Add TextureAtlas to `UiImage::texture_atlas` - Add `TextureAtlas::from_atlas_image` for parity with `Sprite` - Rename `UiImage::texture` to `UiImage::image` for parity with `Sprite` - Port relevant implementations and uses - Remove `derive(Component)` for `TextureAtlas` --- ## Migration Guide Before: ```rust commands.spawn(( UiImage::new(image), TextureAtlas { index, layout }, )); ``` After: ```rust commands.spawn(UiImage::from_atlas_image(image, TextureAtlas { index, layout })); ``` Before: ```rust commands.spawn(UiImage { texture: some_image, ..default() }) ``` After: ```rust commands.spawn(UiImage { image: some_image, ..default() }) ``` commit 2cdad48 Author: Viktor Gustavsson <villor94@gmail.com> Date: Wed Oct 23 23:51:39 2024 +0200 Ensure ghost nodes are skipped when getting parent clipping rect (bevyengine#16058) # Objective - Follow up on bevyengine#16044 - `extract_uinode_borders` uses `bevy_hierarchy` directly instead of going through the traversal utilities, meaning it won't handle `GhostNode`s properly. ## Solution - Replaced the use of `bevy_hierarchy::Parent` with `UIChildren::get_parent` ## Testing - Ran the `overflow` example, clipping looks ok. --- --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com> commit c9a3f34 Author: ickshonpe <david.curthoys@googlemail.com> Date: Wed Oct 23 21:41:42 2024 +0100 Fixes for a few minor borders and outlines bugs (bevyengine#16071) # Objective 1. Nodes with `Display::None` set are removed from the layout and have no position or size. Outlines should not be drawn for a node with `Display::None` set. 2. The outline and border colors are checked for transparency together. If only one of the two is transparent, both will get queued. 3. The `node.is_empty()` check is insufficient to check if a border is present since a non-zero sized node can have a zero width border. ## Solution 1. Add a check to `extract_uinode_borders` and ignore the node if `Display::None` is set. 2. Filter the border and outline optional components by `is_fully_transparent`. 3. Check if all the border widths are zero instead. ## Testing I added dark cyan outlines around the left and right sections in the `display_and_visibility` example. If you run the example and set the outermost node to `Display::None` on the right, then you'll see the that the outline on the left disappears. commit 7577895 Author: Carter Anderson <mcanders1@gmail.com> Date: Wed Oct 23 15:05:28 2024 -0500 Use CosmicFontSystem in public bevy_text APIs and remove cosmic_text re-export (bevyengine#16063) # Objective Fixes bevyengine#16006 ## Solution We currently re-export `cosmic_text`, which is seemingly motivated by the desire to use `cosmic_text::FontSystem` in `bevy_text` public APIs instead of our `CosmicFontSystem` resource wrapper type. This change makes `bevy_text` a "true" abstraction over `cosmic_text` (it in fact, was already built to be that way generally and has this one "leak"). This allows us to remove the `cosmic_text` re-export, which helps clean up the Rust Analyzer imports and generally makes this a "cleaner" API. commit 3fb6cef Author: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Wed Oct 23 12:18:49 2024 -0700 Meshlet fill cluster buffers rewritten (bevyengine#15955) # Objective - Make the meshlet fill cluster buffers pass slightly faster - Address bevyengine#15920 for meshlets - Added PreviousGlobalTransform as a required meshlet component to avoid extra archetype moves, slightly alleviating bevyengine#14681 for meshlets - Enforce that MeshletPlugin::cluster_buffer_slots is not greater than 2^25 (glitches will occur otherwise). Technically this field controls post-lod/culling cluster count, and the issue is on pre-lod/culling cluster count, but it's still valid now, and in the future this will be more true. Needs to be merged after bevyengine#15846 and bevyengine#15886 ## Solution - Old pass dispatched a thread per cluster, and did a binary search over the instances to find which instance the cluster belongs to, and what meshlet index within the instance it is. - New pass dispatches a workgroup per instance, and has the workgroup loop over all meshlets in the instance in order to write out the cluster data. - Use a push constant instead of arrayLength to fix the linked bug - Remap 1d->2d dispatch for software raster only if actually needed to save on spawning excess workgroups ## Testing - Did you test these changes? If so, how? - Ran the meshlet example, and an example with 1041 instances of 32217 meshlets per instance. Profiled the second scene with nsight, went from 0.55ms -> 0.40ms. Small savings. We're pretty much VRAM bandwidth bound at this point. - How can other people (reviewers) test your changes? Is there anything specific they need to know? - Run the meshlet example ## Changelog (non-meshlets) - PreviousGlobalTransform now implements the Default trait commit 6d42830 Author: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Wed Oct 23 09:56:50 2024 -0700 Meshlet builder improvements redux (bevyengine#15886) Take a bunch more improvements from @zeux's nanite.cpp code. * Use position-only vertices (discard other attributes) to determine meshlet connectivity for grouping * Rather than using the lock borders flag when simplifying meshlet groups, provide the locked vertices ourselves. The lock borders flag locks the entire border of the meshlet group, but really we only want to lock the edges between meshlet groups - outwards facing edges are fine to unlock. This gives a really significant increase to the DAG quality. * Add back stuck meshlets (group has only a single meshlet, simplification failed) to the simplification queue to allow them to get used later on and have another attempt at simplifying * Target 8 meshlets per group instead of 4 (second biggest improvement after manual locks) * Provide a seed to metis for deterministic meshlet building * Misc other improvements We can remove the usage of unsafe after the next upstream meshopt release, but for now we need to use the ffi function directly. I'll do another round of improvements later, mainly attribute-aware simplification and using spatial weights for meshlet grouping. Need to merge bevyengine#15846 first. commit 50d38f2 Author: akimakinai <105044389+akimakinai@users.noreply.github.com> Date: Wed Oct 23 08:29:58 2024 +0900 Fix point light count limit (bevyengine#16062) # Objective - I made a mistake in bevyengine#15902, specifically [this diff](bevyengine@e2faedb) -- the `point_light_count` variable is used for all point lights, not just shadow mapped ones, so I cannot add `.min(max_texture_cubes)` there. (Despite `spot_light_count` having `.min(..)`) It may have broken code like this (where `index` is index of `point_light` vec): https://github.com/bevyengine/bevy/blob/9930df83ed42008f7eb2c02cc7350040f0250c2e/crates/bevy_pbr/src/render/light.rs#L848-L850 and also causes panic here: https://github.com/bevyengine/bevy/blob/9930df83ed42008f7eb2c02cc7350040f0250c2e/crates/bevy_pbr/src/render/light.rs#L1173-L1174 ## Solution - Adds `.min(max_texture_cubes)` directly to the loop where texture views for point lights are created. ## Testing - `lighting` example (with the directional light removed; original example doesn't crash as only 1 directional-or-spot light in total is shadow-mapped on webgl) no longer crashes on webgl commit 2223f6e Author: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Tue Oct 22 16:05:40 2024 -0700 Meshlet fix software rasterization (bevyengine#16049) # Objective 1. Prevent weird glitches with stray pixels scattered around the scene ![image](https://github.com/user-attachments/assets/f12adb38-5996-4dc7-bea6-bd326b7317e1) 2. Prevent weird glitchy full-screen triangles that pop-up and destroy perf (SW rasterizing huge triangles is slow) ![image](https://github.com/user-attachments/assets/d3705427-13a5-47bc-a54b-756f0409da0b) ## Solution 1. Use floating point math in the SW rasterizer bounding box calculation to handle negative verticss, and add backface culling 2. Force hardware raster for clusters that clip the near plane, and let the hardware rasterizer handle the clipping I also adjusted the SW rasterizer threshold to < 64 pixels (little bit better perf in my test scene, but still need to do a more comprehensive test), and enabled backface culling for the hardware raster pipeline. ## Testing - Did you test these changes? If so, how? - Yes, on an example scene. Issues no longer occur. - Are there any parts that need more testing? - No. - How can other people (reviewers) test your changes? Is there anything specific they need to know? - Run the meshlet example. commit fe4f44b Author: François Mockers <mockersf@gmail.com> Date: Wed Oct 23 00:37:04 2024 +0200 crate publish order: bevy_animation depends on bevy_animation_derive (bevyengine#16060) # Objective - bevy_animation publication fails because of missed dependency - bevy_animation depends on bevy_animation_derive which is published after ## Solution - Reorder crates bevy_animation and bevy_animation_derive commit fac0b34 Author: François Mockers <mockersf@gmail.com> Date: Tue Oct 22 22:21:19 2024 +0200 remove reference to missing file in bevy_remote cargo.toml (bevyengine#16057) # Objective - bevy_remote Cargo.toml file references a readme that doesn't exist - This is blocking releasing the rc ## Solution - Remove the reference commit 9d54fe0 Author: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Tue Oct 22 13:14:30 2024 -0700 Meshlet new error projection (bevyengine#15846) * New error projection code taken from @zeux's meshoptimizer nanite.cpp demo for determining LOD (thanks zeux!) * Builder: `compute_lod_group_data()` * Runtime: `lod_error_is_imperceptible()` commit 9930df8 Author: ickshonpe <david.curthoys@googlemail.com> Date: Mon Oct 21 23:54:09 2024 +0100 UI borders and outlines clipping fix (bevyengine#16044) # Objective fixes bevyengine#15502 Clipped borders and outlines aren't drawn correctly. ### Borders aren't clipped Spawn two nodes with the same dimensions and border thickness, but clip on of the nodes so that only its top left quarter is visible: <img width="194" alt="clip" src="https://github.com/user-attachments/assets/2d3f6d28-aa20-44df-967a-677725828294"> You can see that instead of clipping the border, instead the border is scaled to fit inside of the unclipped section. ```rust use bevy::color::palettes::css::BLUE; use bevy::prelude::*; use bevy::winit::WinitSettings; fn main() { App::new() .add_plugins(DefaultPlugins) .insert_resource(WinitSettings::desktop_app()) .add_systems(Startup, setup) .run(); } fn setup(mut commands: Commands) { commands.spawn(Camera2d); commands .spawn(Node { width: Val::Percent(100.), height: Val::Percent(100.), justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..Default::default() }) .with_children(|commands| { commands .spawn(Node { column_gap: Val::Px(10.), ..Default::default() }) .with_children(|commands| { commands .spawn(Node { width: Val::Px(100.), height: Val::Px(100.), overflow: Overflow::clip(), ..Default::default() }) .with_child(( Node { position_type: PositionType::Absolute, width: Val::Px(100.), height: Val::Px(100.), border: UiRect::all(Val::Px(10.)), ..Default::default() }, BackgroundColor(Color::WHITE), BorderColor(BLUE.into()), )); commands .spawn(Node { width: Val::Px(50.), height: Val::Px(50.), overflow: Overflow::clip(), ..Default::default() }) .with_child(( Node { position_type: PositionType::Absolute, width: Val::Px(100.), height: Val::Px(100.), border: UiRect::all(Val::Px(10.)), ..Default::default() }, BackgroundColor(Color::WHITE), BorderColor(BLUE.into()), )); }); }); } ``` You can also see this problem in the `overflow` example. If you hover over any of the clipped nodes you'll see that the outline only wraps the visible section of the node ### Outlines are clipped incorrectly A UI nodes Outline's are drawn outside of its bounds, so applying the local clipping rect to the outline doesn't make any sense. Instead an `Outline` should be clipped using its parent's clipping rect. ## Solution * Pass the `point` value into the vertex shader instead of calculating it in the shader. * In `extract_uinode_borders` use the parents clipping rect when clipping outlines. The extra parameter isn't a great solution I think, but I wanted to fix borders for the 0.15 release and this is the most minimal approach I could think of without replacing the whole shader and prepare function. ## Showcase <img width="149" alt="clipp" src="https://github.com/user-attachments/assets/19fbd3cc-e7cd-42e1-a5e0-fd92aad04dcd"> --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> commit d0af199 Author: Stepan Koltsov <stepan.koltsov@gmail.com> Date: Mon Oct 21 16:57:52 2024 +0100 Add a test for Mesh::triangles and fix for TriangleStrip (bevyengine#16026) # Objective - Illustrate behavior with a test - Fix a bug revealed by a test ## Solution - Add a test and fix ## Testing Test added. commit 465d113 Author: Stepan Koltsov <stepan.koltsov@gmail.com> Date: Mon Oct 21 03:17:59 2024 +0100 Replace TwoIterators with Either in bevy_animation (bevyengine#16036) # Objective - Less code - Better iterator (implements `size_hint` for example) ## Solution - Use `either` - This change is free because `bevy_animation` depends on `bevy_asset`, which already depends on `either` ## Testing CI # Conflicts: # Cargo.toml
commit 069291d Author: Clar Fon <15850505+clarfonthey@users.noreply.github.com> Date: Mon Oct 28 17:15:00 2024 -0400 Reduce compile time of bevy_ptr::OwnedPtr::make function (bevyengine#15644) ## Methodology A good metric that correlates with compile time is the amount of code generated by the compiler itself; even if the end binary is exactly the same size, having more copies of the same code can really slow down compile time, since it has to figure out whether it needs to include them or not. The measurement for this used was the [`cargo-llvm-lines` crate](https://docs.rs/crate/cargo-llvm-lines) which can measure which functions are generating the most lines of LLVM IR, which generally means more code compiled. The example compiled was the `breakout` game, to choose something that touches a decent portion of the engine. ## Solution Based upon the measurements, `bevy_ptr::OwnedPtr::make` was taking up 4061 lines of LLVM IR in the example code. So, I separated part of this function into a less-monomorphised version to reduce the amount of generated code. This was by far the most lines emitted by any single function. ## Results After this change, only 2560 lines are emitted, accounting for a 36% decrease. I tried timing the results and it seemed like it did decrease compile times a bit, but honestly, the data is really noisy and I can't be bothered to compile bevy for hours on end to get enough data points. The tweak feels like an improvement, so, I'll offer it, however small. commit 1add4bf Author: ickshonpe <david.curthoys@googlemail.com> Date: Mon Oct 28 21:05:25 2024 +0000 Rename `ComputedNode::calculated_size` to `size` (bevyengine#16131) # Objective Remove `calculated_` from the name `ComputedNode::calculated_size` as redundant, It's obvious from context that it's the resolved size value and it's inconsistant since none of other fields of `ComputedNode` have a `calculated_` prefix. ## Alternatives Rename all the fields of `ComputedNode` to `calculated_*`, this seems worse. commit 33c4945 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 28 13:01:25 2024 +0100 Bump crate-ci/typos from 1.26.0 to 1.26.8 (bevyengine#16128) Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.26.0 to 1.26.8. <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.26.8</h2> <h2>[1.26.8] - 2024-10-24</h2> <h2>v1.26.3</h2> <h2>[1.26.3] - 2024-10-24</h2> <h3>Fixes</h3> <ul> <li>Accept <code>additionals</code></li> </ul> <h2>v1.26.2</h2> <h2>[1.26.2] - 2024-10-24</h2> <h3>Fixes</h3> <ul> <li>Accept <code>tesselate</code> variants</li> </ul> <h2>v1.26.1</h2> <h2>[1.26.1] - 2024-10-23</h2> <h3>Fixes</h3> <ul> <li>Respect <code>--force-exclude</code> for binary files</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.26.8] - 2024-10-24</h2> <h2>[1.26.7] - 2024-10-24</h2> <h2>[1.26.6] - 2024-10-24</h2> <h2>[1.26.5] - 2024-10-24</h2> <h2>[1.26.4] - 2024-10-24</h2> <h2>[1.26.3] - 2024-10-24</h2> <h3>Fixes</h3> <ul> <li>Accept <code>additionals</code></li> </ul> <h2>[1.26.2] - 2024-10-24</h2> <h3>Fixes</h3> <ul> <li>Accept <code>tesselate</code> variants</li> </ul> <h2>[1.26.1] - 2024-10-23</h2> <h3>Fixes</h3> <ul> <li>Respect <code>--force-exclude</code> for binary files</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/crate-ci/typos/commit/0d9e0c2c1bd7f770f6eb90f87780848ca02fc12c"><code>0d9e0c2</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/e5385b07a020af945231c06d33ec490fb77fc7b0"><code>e5385b0</code></a> chore(ci): Fix new release process</li> <li><a href="https://github.com/crate-ci/typos/commit/f08d1171e28430953c39c15beb330811e20ecfe2"><code>f08d117</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/e6e172498c285b815f8cbe3ada1bf51f02fd3b9a"><code>e6e1724</code></a> chore(ci): Fix new release process</li> <li><a href="https://github.com/crate-ci/typos/commit/02afc59fd4633b33c1f7b14b96f46402477dcc75"><code>02afc59</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/f981a1cd200c62b7ce895f09d269b3ee688ccad9"><code>f981a1c</code></a> chore(ci): Fix new release process</li> <li><a href="https://github.com/crate-ci/typos/commit/afbc96c5d3760227ecd31b4ed5f80415beeaaa86"><code>afbc96c</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/d3dcaaeb2d5bb61eadbd393a8803745af7c81290"><code>d3dcaae</code></a> chore(ci): Fix new release process</li> <li><a href="https://github.com/crate-ci/typos/commit/fb8217bd5e6531ce9c1992dd571f7f23d8fdc9c4"><code>fb8217b</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/88ea8ea67dcd07e71f5c9e397a2669c639786dd8"><code>88ea8ea</code></a> chore(ci): Stage releases until done</li> <li>Additional commits viewable in <a href="https://github.com/crate-ci/typos/compare/v1.26.0...v1.26.8">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.26.0&new-version=1.26.8)](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> commit 4b0efda Author: mamekoro <86554319+mamekoro@users.noreply.github.com> Date: Mon Oct 28 12:26:35 2024 +0900 Make some associated functions of `Color` const (bevyengine#16091) # Objective Make the following functions `const` that will be useful to define colors as constants. - `Color::srgb_from_array` - `Color::srgba_u8` - `Color::srgb_u8` The last two require Rust 1.82.0. ## Solution - Make them `const` - Change MSRV to 1.82.0 ## Testing I tested bevy_color only. My machine does not have enough RAM capacity to test the whole bevy. `cargo test -p bevy_color` commit 78a4bea Author: ickshonpe <david.curthoys@googlemail.com> Date: Sun Oct 27 22:39:32 2024 +0000 Move `ContentSize` requirements from `Node` to the widget defining components (bevyengine#16083) # Objective Missed this in the required components PR review. `ContentSize` isn't used by regular UI nodes, only those with intrinsically sized content that needs a measure func. ## Solution Remove `ContentSize` from `Node`'s required components and add it to the required components of `Text` and `UiImage`. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> commit c4c1c8f Author: mgi388 <135186256+mgi388@users.noreply.github.com> Date: Mon Oct 28 09:38:07 2024 +1100 Undeprecate is_playing_animation (bevyengine#16121) # Objective - Fixes bevyengine#16098 ## Solution - Undeprecate `is_playing_animation` and copy the docs from `animation_is_playing` to it. ## Testing - CI ## Migration https://github.com/bevyengine/bevy-website/blob/68e9a34e3068ed2e7db5ae0b4b32feac94a589dd/release-content/0.15/migration-guides/_guides.toml#L13-L17 needs to be removed. commit 3d72f49 Author: ickshonpe <david.curthoys@googlemail.com> Date: Sun Oct 27 20:08:51 2024 +0000 Layout rounding debug example (bevyengine#16096) # Objective Simple example for debugging layout rounding errors. <img width="1039" height="752" alt="layout_rounding_debug" src="https://github.com/user-attachments/assets/12673000-e267-467e-b25b-3f8001c1347c"> Any white lines are gaps in the layout caused by coordinate rounding errors. commit 86ee8e4 Author: ickshonpe <david.curthoys@googlemail.com> Date: Sun Oct 27 19:14:46 2024 +0000 Move `UiImage` from `ui_node` to the `widget::image` module (bevyengine#16084) # Objective `UiImage` isn't just a general image component now, it's the defining component for the image widget so it belongs in the image widget's module. commit d01db9b Author: Hexroll by Pen, Dice & Paper <143178036+hexroll@users.noreply.github.com> Date: Sun Oct 27 19:08:34 2024 +0000 Adding alpha_threshold to OrderIndependentTransparencySettings for user-level optimization (bevyengine#16090) # Objective Order independent transparency can filter fragment writes based on the alpha value and it is currently hard-coded to anything higher than 0.0. By making that value configurable, users can optimize fragment writes, potentially reducing the number of layers needed and improving performance in favor of some transparency quality. ## Solution This PR adds `alpha_threshold` to the OrderIndependentTransparencySettings component and uses the struct to configure a corresponding shader uniform. This uniform is then used instead of the hard-coded value. To configure OIT with a custom alpha threshold, use: ```rust fn setup(mut commands: Commands) { commands.spawn(( Camera3d::default(), OrderIndependentTransparencySettings { layer_count: 8, alpha_threshold: 0.2, }, )); } ``` ## Testing I tested this change using the included OIT example, as well as with two additional projects. ## Migration Guide If you previously explicitly initialized OrderIndependentTransparencySettings with your own `layer_count`, you will now have to add either a `..default()` statement or an explicit `alpha_threshold` value: ```rust fn setup(mut commands: Commands) { commands.spawn(( Camera3d::default(), OrderIndependentTransparencySettings { layer_count: 16, ..default() }, )); } ``` --------- Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com> commit 3fc2bd7 Author: Rob Parrett <robparrett@gmail.com> Date: Sun Oct 27 12:06:19 2024 -0700 Cosmetic tweaks to `query_gltf_primitives` (bevyengine#16102) # Objective This example is really confusing to look at and tell at a glance whether it's broken or not. It's displaying a strange shape -- a cube with two vertices stretched in a couple dimensions at an odd angle, and doing its vertex position modification in a way where the intent isn't obvious. ## Solution - Change the gltf geometry so that the object is a recognizable regular shape - Change the vertex modification so that the entire cube top is being "lifted" from the cube - Adjust colors, lighting, and camera location so we can see what's going on - Also remove some irrelevant shadow and environment map setup ## Before ![Image](https://github.com/user-attachments/assets/e5dd5075-0480-49d4-b1ed-cf1fe6106f3c) ## After <img width="1280" alt="image" src="https://github.com/user-attachments/assets/59cab60d-efbc-47c3-8688-e4544b462421"> commit 7451900 Author: Miles Silberling-Cook <NthTensor@users.noreply.github.com> Date: Sun Oct 27 15:05:31 2024 -0400 Emit picking event streams (bevyengine#16105) # Objective In `bevy_mod_picking` events are accessible through event listeners or `EventReader`s. When I replaced event listeners with observers, I removed the `EventReader` for simplicity. This adds it back. ## Solution All picking events are now properly registered, and can be accessed through `EventReader<Pointer<E>>`. `Pointer` now tracks the entity the event targeted initially, and this can also be helpful in observers (which don't currently do this). ## Testing The picking examples run fine. This shouldn't really change anything. --------- Co-authored-by: Aevyrie <aevyrie@gmail.com> commit 54b323e Author: Aevyrie <aevyrie@gmail.com> Date: Sun Oct 27 12:03:48 2024 -0700 Mesh picking fixes (bevyengine#16110) # Objective - Mesh picking is noisy when a non triangle list is used - Mesh picking runs even when users don't need it - Resolve bevyengine#16065 ## Solution - Don't add the mesh picking plugin by default - Remove error spam commit a644ac7 Author: Tau Gärtli <git@tau.garden> Date: Sun Oct 27 20:01:50 2024 +0100 More `#[doc(fake_variadic)]` goodness (bevyengine#16108) This PR adds `#[doc(fake_variadic)]` to that were previously not supported by rustdoc. Thanks to an [upstream contribution](rust-lang/rust#132115) by yours truly, `#[doc(fake_variadic)]` is now supported on impls such as `impl QueryData for AnyOf<(T, ...)>` 🎉 Requires the latest nightly compiler (2024-10-25) which is already available on [docs.rs](https://docs.rs/about/builds). ![image](https://github.com/user-attachments/assets/68589c7e-f68f-44fb-9a7b-09d24ccf19c9) ![image](https://github.com/user-attachments/assets/f09d20d6-d89b-471b-9a81-4a72c8968178) This means that the impl sections for `QueryData` and `QueryFilter` are now nice and tidy ✨ --- I also added `fake_variadic` to some impls that use `all_tuples_with_size`, however I'm not entirely happy because the docs are slightly misleading now: ![image](https://github.com/user-attachments/assets/fac93d08-dc02-430f-9f34-c97456256c56) Note that the docs say `IntoBindGroupLayoutEntryBuilderArray<1>` instead of `IntoBindGroupLayoutEntryBuilderArray<N>`. commit 60b2c7c Author: François Mockers <mockersf@gmail.com> Date: Fri Oct 25 22:14:39 2024 +0200 fix bevy_dev_tools build (bevyengine#16099) # Objective - bevy_dev_tools 0.15.0-rc.1 failed to build docs - it use bevy_text feature in bevy_ui but it's not enabled by default - https://docs.rs/crate/bevy_dev_tools/0.15.0-rc.1 - ## Solution - enable bevy_text feature of bevy_ui commit 7c59317 Author: BD103 <59022059+BD103@users.noreply.github.com> Date: Fri Oct 25 16:11:51 2024 -0400 Fix `bevy_picking` plugin suffixes (bevyengine#16082) # Objective - `MeshPickingBackend` and `SpritePickingBackend` do not have the `Plugin` suffix - `DefaultPickingPlugins` is masquerading as a `Plugin` when in reality it should be a `PluginGroup` - Fixes bevyengine#16081. ## Solution - Rename some structures: |Original Name|New Name| |-|-| |`MeshPickingBackend`|`MeshPickingPlugin`| |`MeshPickingBackendSettings`|`MeshPickingSettings`| |`SpritePickingBackend`|`SpritePickingPlugin`| |`UiPickingBackendPlugin`|`UiPickingPlugin`| - Make `DefaultPickingPlugins` a `PluginGroup`. - Because `DefaultPickingPlugins` is within the `DefaultPlugins` plugin group, I also added support for nested plugin groups to the `plugin_group!` macro. ## Testing - I used ripgrep to ensure all references were properly renamed. - For the `plugin_group!` macro, I used `cargo expand` to manually inspect the expansion of `DefaultPlugins`. --- ## Migration Guide > [!NOTE] > > All 3 of the changed structures were added after 0.14, so this does not need to be included in the 0.14 to 0.15 migration guide. - `MeshPickingBackend` is now named `MeshPickingPlugin`. - `MeshPickingBackendSettings` is now named `MeshPickingSettings`. - `SpritePickingBackend` is now named `SpritePickingPlugin`. - `UiPickingBackendPlugin` is now named `UiPickingPlugin`. - `DefaultPickingPlugins` is now a a `PluginGroup` instead of a `Plugin`. commit 611ba8b Author: Ludwig DUBOS <ludwig.dubos@pm.me> Date: Fri Oct 25 22:08:14 2024 +0200 Add `AsyncSeekForwardExt` trait to allows a similar API to the previous Bevy version (bevyengine#16027) # Objective This PR introduces an `AsyncSeekForwardExt` trait, which I forgot in my previous PR bevyengine#14194. This new trait is analogous to `AsyncSeekExt` and allows all implementors of `AsyncSeekForward` to directly use the `seek_forward` function in async contexts. ## Solution - Implement a new `AsyncSeekForwardExt` trait - Automatically implement this trait for all types that implement `AsyncSeekForward` ## Showcase This new trait allows a similar API to the previous Bevy version: ```rust #[derive(Default)] struct UniverseLoader; #[derive(Asset, TypePath, Debug)] struct JustALilAsteroid([u8; 128]); impl AssetLoader for UniverseLoader { type Asset = JustALilAsteroid; type Settings = (); type Error = std::io::Error; async fn load<'a>( &'a self, reader: &'a mut Reader<'a>, _settings: &'a Self::Settings, _context: &'a mut LoadContext<'_>, ) -> Result<Self::Asset, Self::Error> { // read the asteroids entry table let entry_offset: u64 = /* ... */; let current_offset: u64 = reader.seek_forward(0).await?; // jump to the entry reader.seek_forward(entry_offset - current_offset).await?; let mut asteroid_buf = [0; 128]; reader.read_exact(&mut asteroid_buf).await?; Ok(JustALilAsteroid(asteroid_buf)) } fn extensions(&self) -> &[&str] { &["celestial"] } } ``` commit c6a66a7 Author: Patrick Walton <pcwalton@mimiga.net> Date: Thu Oct 24 14:16:00 2024 -0700 Place percentage-closer soft shadows behind a feature gate to save on samplers. (bevyengine#16068) The two additional linear texture samplers that PCSS added caused us to blow past the limit on Apple Silicon macOS and WebGL. To fix the issue, this commit adds a `--feature pbr_pcss` feature gate that disables PCSS if not present. Closes bevyengine#15345. Closes bevyengine#15525. Closes bevyengine#15821. --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com> Co-authored-by: IceSentry <IceSentry@users.noreply.github.com> commit 897404e Author: Patrick Walton <pcwalton@mimiga.net> Date: Thu Oct 24 14:00:11 2024 -0700 Reduce the clusterable object UBO size below 16384 for WebGL 2. (bevyengine#16069) The PCSS PR bevyengine#13497 increased the size of clusterable objects from 64 bytes to 80 bytes but didn't decrease the UBO size to compensate, so we blew past the 16kB limit on WebGL 2. This commit fixes the issue by lowering the maximum number of clusterable objects to 204, which puts us under the 16kB limit again. Closes bevyengine#15998. commit 9274bfe Author: Carter Anderson <mcanders1@gmail.com> Date: Wed Oct 23 18:24:17 2024 -0500 Move TextureAtlas into UiImage and remove impl Component for TextureAtlas (bevyengine#16072) # Objective Fixes bevyengine#16064 ## Solution - Add TextureAtlas to `UiImage::texture_atlas` - Add `TextureAtlas::from_atlas_image` for parity with `Sprite` - Rename `UiImage::texture` to `UiImage::image` for parity with `Sprite` - Port relevant implementations and uses - Remove `derive(Component)` for `TextureAtlas` --- ## Migration Guide Before: ```rust commands.spawn(( UiImage::new(image), TextureAtlas { index, layout }, )); ``` After: ```rust commands.spawn(UiImage::from_atlas_image(image, TextureAtlas { index, layout })); ``` Before: ```rust commands.spawn(UiImage { texture: some_image, ..default() }) ``` After: ```rust commands.spawn(UiImage { image: some_image, ..default() }) ``` commit 2cdad48 Author: Viktor Gustavsson <villor94@gmail.com> Date: Wed Oct 23 23:51:39 2024 +0200 Ensure ghost nodes are skipped when getting parent clipping rect (bevyengine#16058) # Objective - Follow up on bevyengine#16044 - `extract_uinode_borders` uses `bevy_hierarchy` directly instead of going through the traversal utilities, meaning it won't handle `GhostNode`s properly. ## Solution - Replaced the use of `bevy_hierarchy::Parent` with `UIChildren::get_parent` ## Testing - Ran the `overflow` example, clipping looks ok. --- --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com> commit c9a3f34 Author: ickshonpe <david.curthoys@googlemail.com> Date: Wed Oct 23 21:41:42 2024 +0100 Fixes for a few minor borders and outlines bugs (bevyengine#16071) # Objective 1. Nodes with `Display::None` set are removed from the layout and have no position or size. Outlines should not be drawn for a node with `Display::None` set. 2. The outline and border colors are checked for transparency together. If only one of the two is transparent, both will get queued. 3. The `node.is_empty()` check is insufficient to check if a border is present since a non-zero sized node can have a zero width border. ## Solution 1. Add a check to `extract_uinode_borders` and ignore the node if `Display::None` is set. 2. Filter the border and outline optional components by `is_fully_transparent`. 3. Check if all the border widths are zero instead. ## Testing I added dark cyan outlines around the left and right sections in the `display_and_visibility` example. If you run the example and set the outermost node to `Display::None` on the right, then you'll see the that the outline on the left disappears. commit 7577895 Author: Carter Anderson <mcanders1@gmail.com> Date: Wed Oct 23 15:05:28 2024 -0500 Use CosmicFontSystem in public bevy_text APIs and remove cosmic_text re-export (bevyengine#16063) # Objective Fixes bevyengine#16006 ## Solution We currently re-export `cosmic_text`, which is seemingly motivated by the desire to use `cosmic_text::FontSystem` in `bevy_text` public APIs instead of our `CosmicFontSystem` resource wrapper type. This change makes `bevy_text` a "true" abstraction over `cosmic_text` (it in fact, was already built to be that way generally and has this one "leak"). This allows us to remove the `cosmic_text` re-export, which helps clean up the Rust Analyzer imports and generally makes this a "cleaner" API. commit 3fb6cef Author: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Wed Oct 23 12:18:49 2024 -0700 Meshlet fill cluster buffers rewritten (bevyengine#15955) # Objective - Make the meshlet fill cluster buffers pass slightly faster - Address bevyengine#15920 for meshlets - Added PreviousGlobalTransform as a required meshlet component to avoid extra archetype moves, slightly alleviating bevyengine#14681 for meshlets - Enforce that MeshletPlugin::cluster_buffer_slots is not greater than 2^25 (glitches will occur otherwise). Technically this field controls post-lod/culling cluster count, and the issue is on pre-lod/culling cluster count, but it's still valid now, and in the future this will be more true. Needs to be merged after bevyengine#15846 and bevyengine#15886 ## Solution - Old pass dispatched a thread per cluster, and did a binary search over the instances to find which instance the cluster belongs to, and what meshlet index within the instance it is. - New pass dispatches a workgroup per instance, and has the workgroup loop over all meshlets in the instance in order to write out the cluster data. - Use a push constant instead of arrayLength to fix the linked bug - Remap 1d->2d dispatch for software raster only if actually needed to save on spawning excess workgroups ## Testing - Did you test these changes? If so, how? - Ran the meshlet example, and an example with 1041 instances of 32217 meshlets per instance. Profiled the second scene with nsight, went from 0.55ms -> 0.40ms. Small savings. We're pretty much VRAM bandwidth bound at this point. - How can other people (reviewers) test your changes? Is there anything specific they need to know? - Run the meshlet example ## Changelog (non-meshlets) - PreviousGlobalTransform now implements the Default trait commit 6d42830 Author: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Wed Oct 23 09:56:50 2024 -0700 Meshlet builder improvements redux (bevyengine#15886) Take a bunch more improvements from @zeux's nanite.cpp code. * Use position-only vertices (discard other attributes) to determine meshlet connectivity for grouping * Rather than using the lock borders flag when simplifying meshlet groups, provide the locked vertices ourselves. The lock borders flag locks the entire border of the meshlet group, but really we only want to lock the edges between meshlet groups - outwards facing edges are fine to unlock. This gives a really significant increase to the DAG quality. * Add back stuck meshlets (group has only a single meshlet, simplification failed) to the simplification queue to allow them to get used later on and have another attempt at simplifying * Target 8 meshlets per group instead of 4 (second biggest improvement after manual locks) * Provide a seed to metis for deterministic meshlet building * Misc other improvements We can remove the usage of unsafe after the next upstream meshopt release, but for now we need to use the ffi function directly. I'll do another round of improvements later, mainly attribute-aware simplification and using spatial weights for meshlet grouping. Need to merge bevyengine#15846 first. commit 50d38f2 Author: akimakinai <105044389+akimakinai@users.noreply.github.com> Date: Wed Oct 23 08:29:58 2024 +0900 Fix point light count limit (bevyengine#16062) # Objective - I made a mistake in bevyengine#15902, specifically [this diff](bevyengine@e2faedb) -- the `point_light_count` variable is used for all point lights, not just shadow mapped ones, so I cannot add `.min(max_texture_cubes)` there. (Despite `spot_light_count` having `.min(..)`) It may have broken code like this (where `index` is index of `point_light` vec): https://github.com/bevyengine/bevy/blob/9930df83ed42008f7eb2c02cc7350040f0250c2e/crates/bevy_pbr/src/render/light.rs#L848-L850 and also causes panic here: https://github.com/bevyengine/bevy/blob/9930df83ed42008f7eb2c02cc7350040f0250c2e/crates/bevy_pbr/src/render/light.rs#L1173-L1174 ## Solution - Adds `.min(max_texture_cubes)` directly to the loop where texture views for point lights are created. ## Testing - `lighting` example (with the directional light removed; original example doesn't crash as only 1 directional-or-spot light in total is shadow-mapped on webgl) no longer crashes on webgl commit 2223f6e Author: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Tue Oct 22 16:05:40 2024 -0700 Meshlet fix software rasterization (bevyengine#16049) # Objective 1. Prevent weird glitches with stray pixels scattered around the scene ![image](https://github.com/user-attachments/assets/f12adb38-5996-4dc7-bea6-bd326b7317e1) 2. Prevent weird glitchy full-screen triangles that pop-up and destroy perf (SW rasterizing huge triangles is slow) ![image](https://github.com/user-attachments/assets/d3705427-13a5-47bc-a54b-756f0409da0b) ## Solution 1. Use floating point math in the SW rasterizer bounding box calculation to handle negative verticss, and add backface culling 2. Force hardware raster for clusters that clip the near plane, and let the hardware rasterizer handle the clipping I also adjusted the SW rasterizer threshold to < 64 pixels (little bit better perf in my test scene, but still need to do a more comprehensive test), and enabled backface culling for the hardware raster pipeline. ## Testing - Did you test these changes? If so, how? - Yes, on an example scene. Issues no longer occur. - Are there any parts that need more testing? - No. - How can other people (reviewers) test your changes? Is there anything specific they need to know? - Run the meshlet example. commit fe4f44b Author: François Mockers <mockersf@gmail.com> Date: Wed Oct 23 00:37:04 2024 +0200 crate publish order: bevy_animation depends on bevy_animation_derive (bevyengine#16060) # Objective - bevy_animation publication fails because of missed dependency - bevy_animation depends on bevy_animation_derive which is published after ## Solution - Reorder crates bevy_animation and bevy_animation_derive commit fac0b34 Author: François Mockers <mockersf@gmail.com> Date: Tue Oct 22 22:21:19 2024 +0200 remove reference to missing file in bevy_remote cargo.toml (bevyengine#16057) # Objective - bevy_remote Cargo.toml file references a readme that doesn't exist - This is blocking releasing the rc ## Solution - Remove the reference commit 9d54fe0 Author: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Tue Oct 22 13:14:30 2024 -0700 Meshlet new error projection (bevyengine#15846) * New error projection code taken from @zeux's meshoptimizer nanite.cpp demo for determining LOD (thanks zeux!) * Builder: `compute_lod_group_data()` * Runtime: `lod_error_is_imperceptible()` commit 9930df8 Author: ickshonpe <david.curthoys@googlemail.com> Date: Mon Oct 21 23:54:09 2024 +0100 UI borders and outlines clipping fix (bevyengine#16044) # Objective fixes bevyengine#15502 Clipped borders and outlines aren't drawn correctly. ### Borders aren't clipped Spawn two nodes with the same dimensions and border thickness, but clip on of the nodes so that only its top left quarter is visible: <img width="194" alt="clip" src="https://github.com/user-attachments/assets/2d3f6d28-aa20-44df-967a-677725828294"> You can see that instead of clipping the border, instead the border is scaled to fit inside of the unclipped section. ```rust use bevy::color::palettes::css::BLUE; use bevy::prelude::*; use bevy::winit::WinitSettings; fn main() { App::new() .add_plugins(DefaultPlugins) .insert_resource(WinitSettings::desktop_app()) .add_systems(Startup, setup) .run(); } fn setup(mut commands: Commands) { commands.spawn(Camera2d); commands .spawn(Node { width: Val::Percent(100.), height: Val::Percent(100.), justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..Default::default() }) .with_children(|commands| { commands .spawn(Node { column_gap: Val::Px(10.), ..Default::default() }) .with_children(|commands| { commands .spawn(Node { width: Val::Px(100.), height: Val::Px(100.), overflow: Overflow::clip(), ..Default::default() }) .with_child(( Node { position_type: PositionType::Absolute, width: Val::Px(100.), height: Val::Px(100.), border: UiRect::all(Val::Px(10.)), ..Default::default() }, BackgroundColor(Color::WHITE), BorderColor(BLUE.into()), )); commands .spawn(Node { width: Val::Px(50.), height: Val::Px(50.), overflow: Overflow::clip(), ..Default::default() }) .with_child(( Node { position_type: PositionType::Absolute, width: Val::Px(100.), height: Val::Px(100.), border: UiRect::all(Val::Px(10.)), ..Default::default() }, BackgroundColor(Color::WHITE), BorderColor(BLUE.into()), )); }); }); } ``` You can also see this problem in the `overflow` example. If you hover over any of the clipped nodes you'll see that the outline only wraps the visible section of the node ### Outlines are clipped incorrectly A UI nodes Outline's are drawn outside of its bounds, so applying the local clipping rect to the outline doesn't make any sense. Instead an `Outline` should be clipped using its parent's clipping rect. ## Solution * Pass the `point` value into the vertex shader instead of calculating it in the shader. * In `extract_uinode_borders` use the parents clipping rect when clipping outlines. The extra parameter isn't a great solution I think, but I wanted to fix borders for the 0.15 release and this is the most minimal approach I could think of without replacing the whole shader and prepare function. ## Showcase <img width="149" alt="clipp" src="https://github.com/user-attachments/assets/19fbd3cc-e7cd-42e1-a5e0-fd92aad04dcd"> --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> commit d0af199 Author: Stepan Koltsov <stepan.koltsov@gmail.com> Date: Mon Oct 21 16:57:52 2024 +0100 Add a test for Mesh::triangles and fix for TriangleStrip (bevyengine#16026) # Objective - Illustrate behavior with a test - Fix a bug revealed by a test ## Solution - Add a test and fix ## Testing Test added. commit 465d113 Author: Stepan Koltsov <stepan.koltsov@gmail.com> Date: Mon Oct 21 03:17:59 2024 +0100 Replace TwoIterators with Either in bevy_animation (bevyengine#16036) # Objective - Less code - Better iterator (implements `size_hint` for example) ## Solution - Use `either` - This change is free because `bevy_animation` depends on `bevy_asset`, which already depends on `either` ## Testing CI
Note: This is in regard to the new
0.15.0-rc.1
release candidate.I understand that this is a pre-release, and considered waiting to see if the official release notes might shed light on this behaviour,
but thought you might want to know about the rough edges sooner than that.
The Issue
After updating to
0.15.0-rc.1
, I get about a thousand of these every second:I am indeed using an alternate
PrimitiveTopology
, though I am not yet utilising anypicking
features within my code.Each of the following is unclear to me:
error_once!
PrimitiveTopology
is used (the other variants work just fine elsewhere in Bevy)Reproduction
You can reproduce this behaviour with the regular
3d/lines
example, with one tweak:RenderAssetUsages::RENDER_WORLD
toRenderAssetUsages::default()
The text was updated successfully, but these errors were encountered: