Bevy – Bevy 0.10
Because of 173 contributors, 689 pull requests, neighborhood reviewers, and our generous sponsors, I am completely satisfied to announce the Bevy 0.10 launch on crates.io!
For individuals who do not know, Bevy is a refreshingly easy data-driven sport engine inbuilt Rust. You’ll be able to try our Quick Start Guide to attempt it immediately. It is free and open supply ceaselessly! You’ll be able to seize the total source code on GitHub. Try Bevy Assets for a set of community-developed plugins, video games, and studying assets.
To replace an current Bevy App or Plugin to Bevy 0.10, try our 0.9 to 0.10 Migration Guide.
Since our final launch just a few months in the past we have added a ton of latest options, bug fixes, and high quality of life tweaks, however listed here are a number of the highlights:
- ECS Schedule v3: Bevy now has a lot less complicated, extra versatile scheduling. Techniques at the moment are saved in a unified schedule, instructions could be utilized explicitly by way of
apply_system_buffers
, and a complete lot of high quality of life and bug fixes. - Cascaded Shadow Maps: Greater high quality shadow maps that cowl bigger distances, the place the standard follows the digicam.
- Setting Map Lighting: 360 diploma ambient picture based mostly lighting that may cheaply and drastically enhance the visible high quality of a scene.
- Depth and Regular Prepass: Render depth and regular textures for a scene previous to the primary cross, enabling new results and (in some instances) improved efficiency. Shadow mapping makes use of the prepass shaders, which permits clear textures to solid shadows.
- Easy Skeletal Animation Transitions: Easily transition between two skeletal animations enjoying on the identical time!
- Improved Android Assist: Bevy now works out of the field on extra Android gadgets (with a few caveats)
- Revamped Bloom: Bloom now seems to be higher, is less complicated to manage, and has fewer visible artifacts.
- Distance and Atmospheric Fog: Add depth and ambiance to your scene with 3D distance and atmospheric fog results!
- StandardMaterial Mix Modes: Obtain a wide range of fascinating results with extra PBR materials mix modes.
- Extra Tonemapping Decisions: Select one among 7 well-liked tonemapping algorithms in your HDR scenes to attain the visible fashion you might be on the lookout for.
- Coloration Grading: Management per-camera publicity, gamma, “pre-tonemapping saturation”, and “post-tonemapping saturation”.
- Parallel Pipelined Rendering: App logic and render logic now run in parallel robotically, yielding important efficiency wins.
- Home windows as Entities: Home windows at the moment are represented as entities as an alternative of assets, bettering the person expertise and unlocking new eventualities.
- Renderer Optimizations: We spent a ton of effort optimizing the renderer this cycle. Bevy’s renderer is snappier than ever!
- ECS Optimizations: Likewise, we have turbocharged many frequent ECS operations. Bevy apps get a pleasant velocity enhance!
ECS Schedule v3
#
authors: @alice-i-cecile, @maniwani, @WrongShoe, @cart, @jakobhellermann, @JoJoJet, @geieredgar and a complete lot extra
Because of the improbable work of our ECS group, the hotly awaited “stageless” scheduling RFC has been carried out!
Schedule v3 is the end result of serious design and implementation work. Scheduling APIs are a central and defining a part of the Bevy developer expertise, so we needed to be very considerate and meticulous about this subsequent evolution of the API. Along with the RFC PR, the initial implementation PR by @maniwani
and the Bevy Engine internals port PR by @alice-i-cecile
are nice locations to start out if you want a view into our course of and rationale. As everyone knows, plans and implementations are two various things. Our last implementation is a bit totally different from the preliminary RFC (in a great way).
There are a ton of modifications, however we have put numerous care into guaranteeing the migration path for current purposes is comparatively easy. Do not sweat it!
Let’s check out what shipped in 0.10!
A Single Unified Schedule
#
Have you ever ever needed to specify that system_a
runs earlier than system_b
, solely to be met with complicated warnings that system_b
is not discovered as a result of it is in a distinct stage?
No extra! All programs inside a single Schedule
at the moment are saved in a single knowledge construction with a worldwide consciousness of what is going on on.
This simplifies our inner logic, makes your code extra strong to refactoring, and permits plugin authors to specify high-level invariants (e.g. “motion should happen earlier than collision checking”) with out locking themselves into an actual schedule location.
This diagram made with @jakobhellermann’s bevy_mod_debugdump
crate exhibits a simplified model of Bevy’s default schedule.
Including Techniques
#
Systems
(that are simply normal Rust functions!) are the way you outline sport logic in Bevy ECS. With Schedule v3, you may add programs to your App
similar to you probably did in earlier variations:
app.add_system(gravity)
Nevertheless Schedule v3 has some new methods up its sleeve! Now you can add a number of programs without delay:
app.add_systems((apply_acceleration, apply_velocity))
By default, Bevy runs programs in parallel to one another. In earlier variations of Bevy, you ordered programs like this:
app
.add_system(stroll.earlier than(leap))
.add_system(leap))
.add_system(collide.after(leap))
You’ll be able to nonetheless do this! However now you can compress this utilizing add_systems
:
// a lot cleaner!
app.add_systems((
stroll.earlier than(leap),
leap,
collide.after(leap),
))
earlier than()
and after()
are undoubtedly helpful instruments! Nevertheless, due to the brand new chain()
perform, it’s now a lot simpler to run programs in a particular order:
// That is equal to the earlier instance
app.add_systems((stroll, leap, collide).chain())
chain()
will run the programs within the order they had been outlined. Chaining additionally pairs with per-system configuration:
app.add_systems((stroll.after(enter), leap, collide).chain())
Configurable System Units
#
In Schedule v3, the thought of the “system set” has been redefined to assist extra pure and versatile management over how programs are run and scheduled. The outdated “system label” idea has been mixed with the “set” idea, leading to one easy however highly effective abstraction.
SystemSets
are named collections of programs that share system configuration throughout all of their members. Ordering programs relative to a SystemSet
applies that ordering to all programs in that set, along with any configuration on every particular person system.
Let’s leap proper into what this might appear to be. You outline SystemSets
like this:
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
enum PhysicsSet {
Motion,
CollisionDetection,
}
You’ll be able to add programs to units by calling the in_set
methodology:
app.add_system(gravity.in_set(PhysicsSet::Motion))
You’ll be able to mix this with the brand new system options talked about above:
app.add_systems(
(apply_acceleration, apply_velocity)
.chain()
.in_set(PhysicsSet::Motion)
)
Techniques can belong to any variety of units:
app.add_system(
move_player
.in_set(MoveSet::Participant)
.in_set(PhysicsSet::Motion)
)
Configuration is added to units like this:
app.configure_set(
// Run programs within the Motion set earlier than programs within the CollisionDetection set
PhysicsSet::Motion.earlier than(PhysicsSet::CollisionDetection)
)
Units could be nested inside different units, which can trigger them to inherit the configuration of their mum or dad set:
app.configure_set(MoveSet::Enemy.in_set(PhysicsSet::Motion))
Units could be configured a number of instances:
// In PlayerPlugin:
app.configure_set(MoveSet::Participant.earlier than(MoveSet::Enemy))
// In PlayerTeleportPlugin
app.configure_set(MoveSet::Participant.after(PortalSet::Teleport))
Crucially system configuration is strictly additive: you can not take away guidelines added elsewhere. That is each an “anti-spaghetti” and “plugin privateness” consideration. When this rule is mixed with Rust’s strong kind privateness guidelines, plugin authors could make cautious choices about which actual invariants must be upheld, and reorganize code and programs internally with out breaking shoppers.
Configuration guidelines should be suitable with one another: any paradoxes (like a system set within itself, a system that should run each earlier than and after a set, order cycles, and so on) will lead to a runtime panic with a useful error message.
Instantly Schedule Unique Techniques
#
“Unique programs” are Systems
which have mutable direct entry to the whole ECS World
. Because of this, they can’t be run in parallel with different Systems
.
Since Bevy’s inception, Bevy devs have needed to schedule unique programs (and flush instructions) relative to regular programs.
Now you may! Unique programs can now be scheduled and ordered like every other system.
app
.add_system(ordinary_system)
// This works!
.add_system(exclusive_system.after(ordinary_system))
That is significantly highly effective, as command flushes (which apply queued-up Commands
added in programs to do issues like spawn and despawn entities) at the moment are merely carried out within the apply_system_buffers
unique system.
app.add_systems(
(
// This method produces some instructions
system_a,
// This can apply the queued instructions from system_a
apply_system_buffers,
// This method may have entry to the outcomes of
// system_a's instructions
system_b,
// This chain ensures the programs above run within the order
// they're outlined
).chain()
)
Do watch out with this sample although: it is easy to shortly find yourself with many poorly ordered unique programs, creating bottlenecks and chaos.
What is going to you do with this a lot energy? We’re eager to search out out!
Managing Advanced Management Move with Schedules
#
However what if you wish to do one thing bizarre together with your Schedule
? One thing non-linear, branching, or looping. What do you have to attain for?
It seems, Bevy already had a fantastic instrument for this: schedules that run within an unique system. The thought is fairly easy:
- Assemble a schedule, that shops no matter advanced logic you need to run.
- Retailer that schedule within a useful resource.
- In an unique system, carry out any arbitrary Rust logic you need to resolve if and the way your schedule runs.
- Quickly take the schedule out of the
World
, run it on the remainder of the world to mutate each the schedule and the world, after which put it again in.
With the addition of the brand new Schedules
useful resource and the world.run_schedule()
API it is extra ✨ ergonomic ✨ than ever.
// A Schedule!
let mut my_schedule = Schedule::new();
schedule.add_system(my_system);
// A label for our new Schedule!
#[derive(ScheduleLabel, Debug, Hash, PartialEq, Eq, Clone)]
struct MySchedule;
// An unique system to run this schedule
fn run_my_schedule(world: &mut World) {
whereas very_complex_logic() {
world.run_schedule(MySchedule);
}
}
// Behold the ergonomics!
app
.add_schedule(MySchedule, my_schedule)
.add_system(run_my_schedule);
Bevy makes use of this sample for 5 somewhat various things in Bevy 0.10:
- Startup programs: these now dwell in their very own schedule, which is run as soon as initially of the app.
- Fastened timestep programs: one other schedule?! The unique system that runs this schedule accumulates time, working some time loop that repeatedly runs
CoreSchedule::FixedUpdate
till the entire amassed time has been spent. - Getting into and exiting states: a bonanza of schedules. Every assortment of programs that runs logic to enter and exit a state variant is saved in its personal schedule, which is known as based mostly on the change in state within the
apply_state_transitions::<S>
unique system. - Rendering: all rendering logic is saved in its personal schedule to permit it to run asynchronously relative to gameplay logic.
- Controlling the outermost loop: with the intention to deal with the “startup schedule first, then essential schedule” logic, we wrap all of it up in a minimal overhead
CoreSchedule::Outer
after which run our schedules as the only real unique system there.
Comply with the breadcrumbs beginning at CoreSchedule
for more information.
Run Situations
#
Systems
can have any variety of run circumstances, that are “simply” programs that return a bool
. If the bool
s returned by all of a system’s run circumstances are true
, the system will run. In any other case the system might be skipped for the present run of the schedule:
// Let's make our personal run situation
fn game_win_condition(question: Question<&Participant>, rating: Res<Rating>) -> bool {
let participant = question.single();
participant.is_alive() && rating.0 > 9000
}
app.add_system(win_game.run_if(game_win_condition));
Run circumstances even have plenty of “combinator” operations, due to @JoJoJet and @Shatur:
They are often negated with not()
:
app.add_system(continue_game.run_if(not(game_win_condition)))
They may also be mixed with and_then
and or_else
:
app.add_system(move_player.run_if(is_alive.or_else(is_zombie)))
Bevy 0.10 is transport with a beautiful assortment of built-in common run conditions. You’ll be able to simply run programs if there are occasions to course of, timers that elapsed, assets that modified, enter state modifications, states that modified, and extra (due to @maniwani
, @inodentry
, @jakobhellermann
, and @jabuwu
).
Run circumstances may also function a light-weight optimization instrument. Run circumstances are evaluated on the primary thread, and every run standards is evaluated precisely as soon as every schedule replace, on the time of the primary system within the set that depends on it. Techniques disabled by run circumstances do not spawn a activity, which might add up throughout many programs. Like at all times although: benchmark!
Run circumstances have changed the “run standards” in earlier variations of Bevy. We will lastly eliminate the dreaded “looping run standards”! ShouldRun::YesAndCheckAgain
was not precisely easy to motive about, both for engine devs or customers. It is at all times a foul signal when your bool-like enums have 4 doable values. For those who crave extra advanced management circulate: use the “schedules in unique programs” sample within the section above. For the opposite 99% of use instances, benefit from the less complicated bool
-based run circumstances!
Easier States
#
Schedule v3 provides a brand new, a lot less complicated “state system”. States
permit you to simply configure totally different App
logic to run based mostly on the present “state” of the App
.
You outline States
like this:
#[derive(States, PartialEq, Eq, Debug, Default)]
enum AppState {
#[default]
MainMenu,
InGame,
}
Every variant of the enum corresponds to a distinct state the App
could be in.
You add States
to your App
like this:
app.add_state::<AppState>()
This can setup your App
to make use of the given state. It provides the State
useful resource, which can be utilized to search out the present state the App
is in:
fn check_state(state: Res<State<AppState>>) {
data!("We're within the {} state", state.0);
}
Moreover, add_state
will create an OnUpdate
set for every doable worth, which you’ll be able to then add your programs to. These units run as a part of the conventional app replace, however solely when the app is in a given state:
app
.add_systems(
(main_menu, start_game)
.in_set(OnUpdate(AppState::MainMenu))
)
.add_system(fun_gameplay.in_set(OnUpdate(AppState::InGame)));
It is going to additionally create OnEnter
and OnExit
schedules for every state, which can solely run when transitioning from one state to a different:
app
.add_system(load_main_menu.in_schedule(OnEnter(AppState::MainMenu)))
.add_system(cleanup_main_menu.in_schedule(OnExit(AppState::MainMenu)))
add_state
additionally provides the NextState
useful resource, which can be utilized to queue a state change:
fn start_game(
button_query: Question<&Interplay, With<StartGameButton>>,
next_state: ResMut<NextState<AppState>>,
){
if button_query.single() == Interplay::Pressed {
*next_state = NextState(AppState::InGame);
}
}
This replaces Bevy’s earlier state system, which was very arduous to cope with. It had state stacks, elaborate queued transitions, and error dealing with (that most individuals simply unwrapped). The state stack was very advanced to be taught, very liable to exasperating bugs, and largely ignored.
Consequently, in Bevy 0.10 states at the moment are “stackless”: just one queued state of every kind at a time. After a number of alpha testing, we’re fairly assured that this should not be too dangerous emigrate away from. For those who had been counting on the state stack, you’ve loads of choices:
- Construct the “stack” logic on high of the core state system
- Cut up your state into a number of states, which seize orthogonal parts of your app’s standing
- Construct your individual state stack abstraction utilizing the identical patterns as Bevy’s first-party model. Not one of the new state logic is difficult coded! For those who construct one thing, let the rest of the community know so you may collaborate!
Base Units: Getting Default Conduct Proper
#
An astute reader could level out that:
- Bevy robotically runs its programs in parallel.
- The order of systems is nondeterministic unless there is an explicit ordering relationship between them
- All the programs at the moment are saved in a single
Schedule
object with no obstacles between them - Techniques can belong to any variety of system units, every of which might add their very own habits
- Bevy is a strong engine with many inner programs.
Will not this result in utter chaos and tedious spaghetti-flavored work to resolve each final ordering ambiguity?
Many customers preferred phases, they had been useful for understanding the construction of an App
!
Properly, I am glad you requested, rhetorical skeptic. To cut back this chaos (and ease migration), Bevy 0.10 comes with a model new assortment of system units offered by DefaultPlugins
: CoreSet
, StartupSet
, and RenderSet
. The similarity of their names to the outdated CoreStage
, StartupStage
, and RenderStage
will not be a coincidence. Very like phases, there are command flush factors between every set, and current programs have been migrated straight.
Some components of the stage-centric structure had been interesting: a transparent high-level construction, coordination on flush factors (to scale back extreme bottlenecks), and good default habits.
To maintain these bits (whereas excising the irritating ones), we have launched the idea of Base Units (added by @cart). Base Units are simply regular SystemSets
, besides:
- Each system can belong to at most one base set.
- Techniques that don’t specify a base set might be added to the default base set for the schedule (if the schedule has one).
// You outline base units precisely like regular units, with the
// addition of the system_set(base) attribute
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
#[system_set(base)]
enum MyBaseSet {
Early,
Late,
}
app
// This results in CoreSet::Replace by default
.add_system(no_explicit_base_set)
// You should use .in_base_set somewhat than .in_set for explicitness
// This can be a high-impact choice!
.add_system(post_update.in_base_set(CoreSet::PostUpdate))
// Look, it really works!
.add_system(custom_base_set.in_base_set(MyBaseSet::Early))
// Ordering your base units relative to CoreSet might be clever
.configure_set(MyBaseSet::Early.earlier than(CoreSet::Replace))
.configure_set(MyBaseSet::Late.after(CoreSet::Replace));
Let me let you know a narrative, set in a world with out Base Units:
- A brand new person provides the
make_player_run
system to their app. - Typically this technique runs earlier than enter dealing with, resulting in randomly dropped inputs. Typically it runs after rendering, resulting in unusual glints.
- After a lot frustration, the person discovers that these are resulting from “system execution order ambiguities”.
- The person runs a specialised detection instrument, digs into the supply code of the engine, figures out what order their system ought to run in relative to the engine’s system units, after which continues on their merry method, doing this for every new system.
- Bevy (or one among their third-party plugins) updates, breaking all of our poor customers system ordering as soon as once more.
The clear drawback this illustrates is that most gameplay programs mustn’t have to know or care about “inner programs”.
We have discovered that in apply, there are three broad courses of programs: gameplay logic (nearly all of all finish person programs), stuff that should occur earlier than gameplay logic (like occasion cleanup and enter dealing with), and stuff that should occur after gameplay logic (like rendering and audio).
By broadly ordering the schedule by way of Base Units, Bevy apps can have good default habits and clear high-level construction with out compromising on the scheduling flexibility and explicitness that superior customers crave.
Tell us the way it works out for you!
Improved System Ambiguity Detection
#
When a number of programs work together with an ECS useful resource in conflicting methods, however do not have an ordering constraint between them, we name this an “ambiguity”. In case your App
has ambiguities, this will trigger bugs. We have considerably improved our ambiguity reporting, which could be configured within the new ScheduleBuildSettings
. Try the docs for more information. If you have not tried this out in your app but: you need to have a look!
Single Threaded Execution
#
Now you can simply swap a Schedule
to single-threaded analysis by way of the SingleThreadedExecutor
for customers who don’t need or want parallelism.
schedule.set_executor_kind(ExecutorKind::SingleThreaded);
Cascaded Shadow Maps
#
authors: @danchia, Rob Swain (@superdump)
Bevy makes use of “shadow maps” to solid shadows for lights / objects. Earlier variations of Bevy used a easy however restricted shadow map implementation for directional mild sources. For a given mild, you’d outline the decision of the shadow map and a handbook “view projection” that will decide how the shadow is solid. This had plenty of downsides:
- The decision of the shadow map was fastened. You had to decide on one thing between “cowl a big space, however have a decrease decision” and “cowl a smaller space, however have a better decision”.
- The decision did not adapt to digicam positioning. Shadows would possibly look nice in a single place, however horrible in one other place.
- The “shadow projection” needed to be manually outlined. This made it arduous and unapproachable to configure shadows to match a given scene.
Bevy 0.10 provides “cascaded shadow maps”, which breaks up the digicam’s view frustum right into a sequence of configurable “cascades”, which every have their very own shadow map. This permits shadows within the cascade “near the digicam” to be extremely detailed, whereas permitting shadows “removed from the digicam” to cowl a wider space with much less element. As a result of it makes use of the digicam’s view frustum to outline the shadow projections, the shadow high quality stays constant because the digicam strikes by way of the scene. This additionally signifies that customers need not manually configure shadow projections anymore. They’re robotically calculated!
Discover how the close by shadows are extremely detailed whereas the shadows within the distance develop into much less detailed as they get farther away (which does not matter as a lot as a result of they’re far-off).
Whereas shadow cascades clear up necessary issues, in addition they introduce new ones. What number of cascades do you have to use? What’s the minimal and most distance from the digicam the place shadows ought to seem? How a lot overlap ought to there be between cascades? Make sure you dial in these parameters to suit your scenes.
Setting Map Lighting
#
authors: @JMS55
Setting maps are a well-liked and computationally low cost solution to considerably enhance the standard of a scene’s lighting. It makes use of a dice map texture to offer 360 diploma lighting “from all instructions”. That is particularly obvious for reflective surfaces, however it applies to all lit supplies.
That is what the PBR materials seems to be like with out surroundings map lighting:
And that is what the PBR materials seems to be like with surroundings map lighting:
For scenes that want fixed lighting (particularly out of doors scenes), surroundings maps are a fantastic answer. And since surroundings maps are arbitrary photos, artists have numerous management over the character of the scene’s lighting.
Depth and Regular Prepass
#
authors: @icesentry, Rob Swain (@superdump), @robtfm, @JMS55
This impact makes use of the depth from the prepass to search out the intersection between the bottom and the drive area
Bevy now has the power to run a depth and/or regular prepass. This implies the depth and regular textures might be generated in a render cross that runs earlier than the primary cross and may due to this fact be used throughout the primary cross. This permits varied particular results like Display Area Ambient Occlusion, Temporal Anti Aliasing, and lots of extra. These are presently being labored on and ought to be available in the next release of Bevy.
Within the picture on the correct, inexperienced strains are edges detected within the regular texture and blue strains are edges detected within the depth texture
The depth and regular textures generated by the prepass
Utilizing the prepass primarily means rendering every little thing twice. The prepass itself is far quicker because it does quite a bit much less work than the primary cross. The results of the prepass can be utilized to scale back overdraw in the primary cross, but when your scene did not already undergo from overdraw then enabling the prepass will negatively have an effect on efficiency. There are lots of issues that may be completed to enhance this and we’ll preserve working in direction of this objective. Like with something efficiency associated, ensure to measure it in your use case and see if it helps or not.
The prepass continues to be very helpful when engaged on particular results that require a depth or regular texture, so if you wish to use it you may merely add the DepthPrepass
or NormalPrepass
elements to your digicam.
Shadow Mapping utilizing Prepass Shaders
#
authors: @geieredgar
Beforehand, the shader used for shadow mapping was hard-coded and had no data of the fabric, solely meshes. Now in Bevy 0.10, a Materials
‘s depth prepass shaders are used for shadow mapping. Because of this the shaders used to do the shadow mapping for a Materials
are customizable!
As a bonus, the supply of Materials
data throughout shadow mapping signifies that we might immediately allow alpha masks shadows permitting foliage to solid shadows in accordance with the alpha values of their texture somewhat than solely based mostly on their geometry.
Easy Skeletal Animation Transitions
#
authors: @smessmer
Now you can easily transition between two (or extra) skeletal animations!
Character mannequin and animations are royalty free belongings from Mixamo.
With the brand new play_with_transition
methodology on the AnimationPlayer
part, now you can specify a transition length throughout which the brand new animation might be linearly blended with the presently enjoying animation, whose weight will lower throughout that length till it reaches 0.0
.
#[derive(Component, Default)]
struct ActionTimer(Timer);
#[derive(Component)]
struct Animations {
run: Deal with<AnimationClip>,
assault: Deal with<AnimationClip>,
}
fn run_or_attack(
mut question: Question<(&mut AnimationPlayer, &mut ActionTimer, &Animations)>,
keyboard_input: Res<Enter<KeyCode>>,
animation_clips: Res<Property<AnimationClip>>,
time: Res<Time>,
) {
for (mut animation_player, mut timer, animations) in question.iter_mut() {
// Set off the assault animation when urgent <area>
if keyboard_input.just_pressed(KeyCode::Area) {
let clip = animation_clips.get(&animations.assault).unwrap();
// Set a timer for when to restart the run animation
timer.0 = Timer::new(
Period::from_secs_f32(clip.length() - 0.5),
TimerMode::As soon as,
);
// Will transition over half a second to the assault animation
animation_player
.play_with_transition(animations.assault.clone(), Period::from_secs_f32(0.5));
}
if timer.0.tick(time.delta()).just_finished() {
// As soon as the assault animation is completed, restart the run animation
animation_player
.play_with_transition(animations.run.clone(), Period::from_secs_f32(0.5))
.repeat();
}
}
}
Improved Android Assist
#
authors: @mockersf, @slyedoc
Bevy now runs out of the field on Android on extra gadgets. This was unlocked by ready for the Resumed
occasion to create the window as an alternative of doing it on startup, matching the onResume()
callback on Android.
To comply with the suggestions on the Suspended
occasion, Bevy will now exit on receiving that occasion. This can be a momentary answer till Bevy is ready to recreate rendering assets when being resumed.
Please take a look at in your gadgets and report successes or points you might encounter! There’s a identified subject round contact place on some gadgets with software program buttons, as winit does not expose (yet) the inset dimension, solely the inside dimension.
As this brings Bevy nearer to full assist of Android, there is not a necessity anymore for separate examples for Android and iOS. They’ve been regrouped in a single “mobile” example, and the directions up to date (for Android and for iOS).
Right here is similar instance working on iOS!
Revamped Bloom
#
authors: @StarLederer, @JMS55
Bloom has undergone some main modifications and now seems to be higher, is less complicated to manage, and has fewer visible artifacts.
Together with the brand new tonemapping choices, bloom has been a lot improved because the earlier launch!
- In Bevy 0.9, bloom regarded like this.
- Switching the tonemapper to one thing like
AcesFitted
is already a giant enchancment. - In Bevy 0.10, bloom now seems to be like this. It is far more managed and fewer overbearing.
- To make the bloom stronger, somewhat than elevate the
BloomSettings
depth,
let’s double theemissive
worth of every dice. - Lastly, in order for you extra excessive bloom much like the outdated algorithm, you may change
BloomSettings::composite_mode
fromBloomCompositeMode::EnergyConserving
toBloomCompositeMode::Additive
. - Discover the brand new bloom settings in an interactive playground utilizing the brand new
bloom_3d
(andbloom_2d
) examples.
Distance and Atmospheric Fog
#
writer: Marco Buono (@coreh)
Bevy can now render distance and atmospheric fog results, bringing a heightened sense of depth and ambiance to your scenes by making objects seem dimmer the additional away they’re from view.
Fog is controllable per digicam by way of the brand new FogSettings
part. Particular care has been put into exposing a number of knobs to present you full creative management over the look of your fog, together with the power to fade the fog out and in by controlling the alpha channel of the fog colour.
instructions.spawn((
Camera3dBundle::default(),
FogSettings {
colour: Coloration::rgba(0.1, 0.2, 0.4, 1.0),
falloff: FogFalloff::Linear { begin: 50.0, finish: 100.0 },
},
));
Precisely how fog behaves with regard to distance is managed by way of the FogFalloff
enum. All the “conventional” fog falloff modes from the fixed-function OpenGL 1.x / DirectX 7 days are supported:
FogFalloff::Linear
will increase in depth linearly from 0 to 1 between begin
and finish
parameters. (This instance makes use of values of 0.8 and a pair of.2, respectively.)
FogFalloff::Exponential
will increase in accordance with an (inverse) exponential system, managed by a density
parameter.
FogFalloff::ExponentialSquared
grows in accordance with a barely modified (inverse) exponential sq. system, additionally managed by a density
parameter.
Moreover, a extra subtle FogFalloff::Atmospheric
mode is on the market which offers extra bodily correct outcomes by taking mild extinction
and inscattering
under consideration individually.
DirectionalLight
affect can also be supported for all fog modes by way of the directional_light_color
and directional_light_exponent
parameters, mimicking the sunshine dispersion impact seen in sunny out of doors environments.
Since straight controlling the non-linear fog falloff parameters “by hand” could be tough to get proper, plenty of helper capabilities based mostly on meteorological visibility can be found, resembling FogFalloff::from_visibility()
:
FogSettings {
// objects retain visibility (>= 5% distinction) for as much as 15 items
falloff: FogFalloff::from_visibility(15.0),
..default()
}
Fog is utilized “ahead rendering-style” on the PBR fragment shader, as an alternative of as a post-processing impact, which permits it to correctly deal with semi-transparent meshes.
The atmospheric fog implementation is basically based mostly on this great article by Inigo Quilez, Shadertoy co-creator, and pc graphics legend. Thanks for the good write up and inspiration!
StandardMaterial Mix Modes
#
writer: Marco Buono (@coreh)
The AlphaMode
enum has been prolonged in Bevy 0.10, bringing assist for additive and multiplicative mixing to the StandardMaterial
. These two mix modes are staples of the “traditional” (non physically-based) pc graphics toolbelt, and are generally used to attain a wide range of results.
Demo showcasing the usage of mix modes to create stained glass and hearth results. (Source Code)
Moreover, assist for semi-transparent textures with premultiplied alpha has been added, by way of a devoted alpha mode.
Here is a high-level overview of the brand new modes:
AlphaMode::Add
— Combines the colours of the fragments with the colours behind them in an additive course of, (i.e. like mild) producing brighter outcomes. Helpful for results like hearth, holograms, ghosts, lasers and different vitality beams. Often known as Linear Dodge in graphics software program.AlphaMode::Multiply
— Combines the colours of the fragments with the colours behind them in a multiplicative course of, (i.e. like pigments) producing darker outcomes. Helpful for results approximating partial mild transmission like stained glass, window tint movie and a few coloured liquids.AlphaMode::Premultiplied
— Behaves very equally toAlphaMode::Blend
, however assumes the colour channels have premultiplied alpha. Can be utilized to keep away from discolored “define” artifacts that may happen when utilizing plain alpha-blended textures, or to cleverly create supplies that mix additive and common alpha mixing in a single texture, due to the truth that for in any other case fixed RGB values,Premultiplied
behaves extra likeMix
for alpha values nearer to 1.0, and extra likeAdd
for alpha values nearer to 0.0.
Notice: Meshes utilizing the brand new mix modes are drawn on the present Transparent3d
render part, and due to this fact the identical z-sorting concerns/limitations from AlphaMode::Mix
apply.
Extra Tonemapping Decisions
#
authors: @DGriffin91, @JMS55
Tonemapping is the method of remodeling uncooked Excessive Dynamic Vary (HDR) data into precise “display colours” utilizing a “show rendering rework” (DRT). In earlier variations of Bevy you had precisely two tonemapping choices: Reinhard Luminance or none in any respect. In Bevy 0.10 we have added a ton of selections!
No Tonemapping
#
That is usually not really helpful as HDR lighting will not be meant for use as colour.
Reinhard
#
A easy methodology that adapts to the colour in a scene: r = colour / (1.0 + colour)
. A number of hue shifting, brights do not desaturate naturally. Shiny primaries and secondaries do not desaturate in any respect.
Reinhard Luminance
#
A well-liked methodology much like regular Reinhard that includes luminance. It adapts to the quantity of sunshine in a scene. That is what we had in earlier variations of Bevy. It’s nonetheless our default algorithm, however this may seemingly change sooner or later. Hues shift. Brights do not desaturate a lot in any respect throughout the spectrum.
ACES Fitted
#
A particularly well-liked algorithm utilized in movie and trade (ex: ACES is the default Unreal tonemapping algorithm). When folks say “filmic”, that is typically what they imply.
Not impartial, has a really particular aesthetic, intentional and dramatic hue shifting.
Shiny greens and reds flip orange. Shiny blues flip magenta. Considerably elevated distinction. Brights desaturate throughout the spectrum.
AgX
#
Very impartial. Picture is considerably desaturated when in comparison with different transforms. Little to no hue shifting. Delicate Abney shifting. Created by Troy Sobotka
Considerably Boring Show Remodel
#
Has little hue shifting within the darks and mids, however tons within the brights. Brights desaturate throughout the spectrum.
Is type of between Reinhard and Reinhard Luminance. Conceptually much like reinhard-jodie.
Designed as a compromise in order for you e.g. first rate pores and skin tones in low mild, however cannot afford to re-do your
VFX to look good with out hue shifting. Created by Tomasz Stachowiak.
TonyMcMapface
#
Very impartial. Delicate however intentional hue shifting. Brights desaturate throughout the spectrum.
From the writer: Tony is a show rework meant for real-time purposes resembling video games.
It’s deliberately boring, doesn’t improve distinction or saturation, and stays near the
enter stimulus the place compression is not essential.
Brightness-equivalent luminance of the enter stimulus is compressed. The non-linearity resembles Reinhard.
Coloration hues are preserved throughout compression, apart from a deliberate Bezold–Brücke shift.
To keep away from posterization, selective desaturation is employed, with care to keep away from the Abney effect. Created by Tomasz Stachowiak
Blender Filmic
#
Default Filmic Show Remodel from Blender. Considerably impartial. Hues shift. Brights desaturate throughout the spectrum.
Coloration Grading Management
#
authors: @DGriffin91
We have added some primary management over colour grading parameters resembling publicity, gamma, “pre-tonemapping saturation”, and “post-tonemapping saturation”. These could be configured per digicam utilizing the brand new ColorGrading
part.
0.5 Publicity
#
2.25 Publicity
#
Parallel Pipelined Rendering
#
authors: @hymm, @james7132
On multithreaded platforms, Bevy 0.10 will now run considerably quicker by working simulation and
rendering in parallel. The renderer was rearchitected in Bevy 0.6
to allow this, however the last step of really working them in parallel was not completed till now.
There was a little bit of tough work to determine. The render world has a system that has to run on
the primary thread, however the activity pool solely had the power to run on the world’s thread. So, once we ship
the render world to a different thread we have to accommodate nonetheless working render programs on the primary
thread. To perform this, we added the power to spawn duties onto the primary thread along with the world’s thread.
In testing totally different Bevy examples, the good points had been usually within the 10% to 30% vary.
As seen within the above histogram, the imply body time of the “many foxes” stress take a look at
is 1.8ms quicker than earlier than.
To make use of pipelined rendering, you simply want so as to add the PipelinedRenderingPlugin
. For those who’re
utilizing DefaultPlugins
then it would robotically be added for you on all platforms besides
wasm. Bevy doesn’t presently assist multithreading on wasm which is required for this
characteristic to work. If you’re not utilizing DefaultPlugins
you may add the plugin manually.
Home windows as Entities
#
authors: @aceeri, @Weibye, @cart
In earlier variations of Bevy, Window
was represented as an ECS useful resource (contained within the Home windows
useful resource). In Bevy 0.10 Window
is now a part (and due to this fact home windows are represented as entities).
This accomplishes plenty of targets:
- It opens the doorways to representing Home windows in Bevy’s scene system
- It exposes
Home windows
to Bevy’s highly effective ECS queries - It offers granular per-window change detection
- Improves the readability/discoverability of making, utilizing, and shutting home windows
- Altering the properties of a window is similar for each initializing and modifying. No extra
WindowDescriptor
fuss! - It permits Bevy builders and customers to simply connect new part knowledge to home windows
fn create_window(mut instructions: Instructions) {
instructions.spawn(Window {
title: "My window :D".to_string(),
..default()
});
}
fn modify_windows(mut home windows: Question<&mut Window>) {
for window in &mut home windows {
window.title = "My modified window! :D".to_string();
}
}
fn close_windows(mut instructions: Instructions, home windows: Question<Entity, With<Window>>) {
for entity in &home windows {
instructions.entity(entity).despawn();
}
}
Renderer Optimizations
#
authors: @danchia, Rob Swain (@superdump), james7132, @kurtkuehnert, @robfm
Bevy’s renderer was ripe for optimization. So we optimized it!
The most important bottleneck when rendering something in Bevy is the ultimate render stage, the place we acquire the entire knowledge within the render world to subject draw calls to the GPU. The core loops listed here are extraordinarily scorching and any additional overhead is noticeable. In Bevy 0.10, we have thrown the kitchen sink at this drawback and have attacked it from each angle. General, these following optimizations ought to make the render stage 2-3 instances quicker than it was in 0.9:
- In #7639 by @danchia, we discovered that even disabled logging has a robust affect on scorching loops, netting us 20-50% speedups within the stage.
- In #6944 by @james7132, we shrank the core knowledge constructions concerned within the stage, decreasing reminiscence fetches and netting us 9% speedups.
- In #6885 by @james7132, we rearchitected our
PhaseItem
andRenderCommand
infrastructure to mix frequent operations when fetching part knowledge from theWorld
, netting us a 7% speedup. - In #7053 by @james7132, we modified
TrackedRenderPass
‘s allocation patterns to reduce branching inside these loops, netting a 6% speedup. - In #7084 by @james7132, we altered how we’re fetching assets from the World to reduce the usage of atomics within the stage, netting a 2% speedup.
- In #6988 by @kurtkuehnert, we modified our inner useful resource IDs to make use of atomically incremented counters as an alternative of UUIDs, decreasing the comparability value of a number of the branches within the stage.
One different ongoing growth is enabling the render stage to correctly parallelize command encoding throughout a number of threads. Following #7248 by @james7132, we now assist ingesting externally created CommandBuffer
s into the render graph, which ought to permit customers to encode GPU instructions in parallel and import them into the render graph. That is presently blocked by wgpu, which locks the GPU gadget when encoding render passes, however we must always be capable to assist parallel command encoding as quickly as that is addressed.
On the same observe, we have made steps to allow increased parallelism in different phases of the rendering pipeline. PipelineCache
has been a useful resource that nearly each Queue stage system wanted to entry mutably, but in addition solely not often wanted to be written to. In #7205, @danchia modified this to make use of inner mutability to permit for these programs to parallelize. This does not totally permit each system on this stage to parallelize simply but, as there nonetheless stay just a few frequent blockers, however it ought to permit non-conflicting render phases to queue instructions on the identical time.
Optimization is not all about CPU time! We have additionally improved reminiscence utilization, compile instances, and GPU efficiency as nicely!
- We have additionally lowered the reminiscence utilization of
ComputedVisibility
by 50% due to @james7132. This was completed by changing the inner storage with a set of bitflags as an alternative of a number of booleans. - @robfm additionally used kind erasure as a work-around a rustc performance regression to make sure that rendering associated crates have higher compile instances, with a number of the crates compiling as much as 60% quicker! Full particulars could be seen in #5950.
- In #7069, Rob Swain (@superdump) lowered the variety of lively registers used on the GPU to stop register spilling, considerably bettering GPU-side efficiency.
Lastly, we have now made some enhancements on particular utilization eventualities:
- In #6833, @james7132 improved the extraction of bones for mesh skinning by 40-50% by omitting an pointless buffer copy.
- In #7311, @james7132 improved UI extraction by 33% by lifting a standard computation out of a scorching loop.
Parallelized Remodel Propagation and Animation Kinematics
#
authors: @james7132
Remodel propagation is among the core programs of any sport engine. For those who transfer a mum or dad entity, you count on its kids to maneuver in worldspace. Bevy’s rework propagation system occurs to be one of many largest bottlenecks for a number of programs: rendering, UI, physics, animation, and so on. can not run till it is full. It is crucial that rework propagation is quick to keep away from blocking all of those programs. In Bevy 0.9 and earlier than, rework propagation has at all times been single-threaded and at all times requires a full hierarchy traversal. As worlds received bigger, so did the time spent on this key bottleneck. In Bevy 0.10, rework propagation leverages the construction of a well-formed hierarchy to completely run over a number of threads. The complete efficiency advantages completely depend upon how the hierarchy is structured and what number of CPU cores can be found. In our testing, this has made rework propagation in our many_foxes
benchmark 4 instances quicker on our testing {hardware}.
If rework propagation could be parallelized, so can ahead kinematics for animation. We leveraged the identical assured construction of nicely shaped hierarchies to completely parallelize enjoying skeletal animations. We additionally enabled a primary entity-path cache lookup to scale back the additional lookups the system was doing. Altogether, we had been capable of make the animation participant system on the identical many_foxes
benchmark 10 instances quicker.
Mixed with the entire different optimizations seen on this launch, our assessments on the many_foxes
benchmark has sped up from ~10ms per body (~100 FPS) to ~2.3ms per body (~434 FPS), a close to 5x speedup!
ECS Optimizations
#
authors: @james7132, @JoJoJet
ECS underlies the whole engine, so eliminating overhead within the ECS leads to engine-wide speedups. In Bevy 0.10, we have discovered fairly just a few areas the place we had been capable of massively scale back the overhead and enhance CPU utilization for the whole engine.
In #6547, we enabled autovectorization when utilizing Question::for_each
, and its parallel variants. Relying on the goal structure the engine is being compiled for, this may end up in a 50-87.5% velocity up in question iteration time. In 0.11, we could also be extending this optimization to all iterator combinators based mostly on Iterator::fold
, resembling Iterator::depend
. See this PR for extra particulars.
In #6681, by tightly packing entity location metadata and avoiding additional reminiscence lookups, we have considerably lowered the overhead when making random question lookups by way of Question::get
, seeing as much as a 43% discount within the overhead spent in Question::get
and World::get
.
In #6800 and #6902, we have discovered that rustc can optimize out compile-time fixed branches throughout perform boundaries, shifting the department from runtime to compile time, has resulted in as much as a 50% discount in overhead when utilizing EntityRef::get
, EntityMut::insert
, EntityMut::take away
, and their variants.
In #6391, we have reworked CommandQueue
‘s internals to be extra CPU-cache pleasant, which has proven as much as a 37% speedup when encoding and making use of instructions.
SystemParam
Enhancements
#
authors: @JoJoJet
Central to Bevy’s ECS are SystemParam
s: these sorts, resembling Question
and Res
, dictate what a system can and may’t do.
Beforehand, manually creating one required implementing a household of 4 inseparable traits.
In Bevy 0.10, we have used generic associated types to reduce this to just two traits: SystemParam
and ReadOnlySystemParam
.
Moreover, the #[derive(SystemParam)]
macro has acquired a number of miscellaneous usability enhancements:
- Extra Versatile: you might be not compelled to declare lifetimes you do not use. Tuple structs at the moment are allowed, and const generics do not break issues.
- Encapsulated: a long-standing bug has been fastened that leaked the kinds of personal fields. Now,
SystemParam
s can correctly encapsulate personal world knowledge. - Limitless: the 16-field restrict has been lifted, so you can also make your params as ridiculously advanced as you need. That is most helpful for generated code.
Deferred World Mutations
#
authors: @JoJoJet
You in all probability know that whenever you ship a Command
, it does not mutate the world straight away. The command will get saved within the system and utilized in a while
within the schedule. Deferring mutations on this method has just a few advantages:
- Minimizing world accesses: in contrast to mutable queries (and assets), deferred mutations are free from knowledge entry conflicts, which affords better parallelizability to programs utilizing this sample.
- Order independence: when performing idempotent operations (like setting a worldwide flag), deferred mutations permit you to not fear about system execution order.
- Structural mutations: deferred mutations are capable of change the construction of the world in ways in which
Question
andResMut
can not, resembling including elements or spawning and despawning entities.
Bevy 0.10 provides first-class assist for this sample by way of the Deferred
system parameter, which accepts a SystemBuffer
trait impl. This allows you to create programs with customized deferred mutation habits whereas skipping the overhead related to Instructions
!
/// Sends occasions with a delay, however can run in parallel with different occasion writers.
pub struct EventBuffer<E>(Vec<E>);
// The `SystemBuffer` trait controls how deferred mutations get utilized to the world.
impl<E> SystemBuffer for EventBuffer<E> { ... }
fn my_system(mut occasions: Deferred<EventBuffer<MyEvent>>) {
// Queue up an occasion to get despatched when instructions are utilized.
occasions.0.push(MyEvent);
}
Notice that this characteristic ought to be used with care — regardless of the potential efficiency advantages, inappropriate utilization can truly worsen efficiency. Any time you carry out an optimization, be sure you verify that it truly speeds issues up!
Ref<T> Queries
#
authors: @Guvante, @JoJoJet
Since Bevy 0.1, Mut<T>
has been used to allow change detection (together with associated sorts like ResMut<T>
). It is a easy wrapper kind that gives mutable entry to a part alongside its change tick metadata, robotically marking a change when the worth is mutated.
In Bevy 0.10, the change detection household has grown with Ref<T>
, the immutable variant of Mut<T>
. Like its mutable sibling, it means that you can react to modifications made exterior of the present system.
use bevy::prelude::*;
fn inspect_changes_system<T: Element + Debug>(q: Question<Ref<T>>) {
// Iterate over every part of kind `T` and log its modified standing.
for val in &q {
if val.is_changed() {
println!("Worth `{val:?}` was final modified at tick {}.", val.last_changed());
} else {
println!("Worth `{val:?}` is unchanged.");
}
}
}
We’re additionally deprecating ChangeTrackers<T>
, which is the outdated method of inspecting a part’s change ticks. This kind might be eliminated within the subsequent model of Bevy.
Cubic Curves
#
authors: @aevyrie
This video exhibits 4 sorts of cubic curves being easily animated with bezier easing. The curve itself is white, inexperienced is velocity, pink is acceleration, and blue are the management factors that decide the form of the curve.
In preparation for UI animation and hand-tweaked animation curves, cubic curves have been added to bevy_math
. The implementation offers a number of curves out of the field, helpful in varied purposes:
Bezier
: user-drawn splines, and cubic-bezier animation easing for UI – helper strategies are offered for cubic animation easing as demonstrated within the above video.Hermite
: easy interpolation between two closing dates the place each the place and velocity, resembling community prediction.Cardinal
: straightforward interpolation between any variety of management factors, robotically computing tangents; Catmull-Rom is a kind of Cardinal spline.B-Spline
: acceleration-continuous movement, significantly helpful for digicam paths the place a easy change in velocity (acceleration) is necessary to stop harsh jerking movement.
The CubicGenerator
trait is public, permitting you to outline your individual customized splines that generate CubicCurve
s!
Efficiency
#
The place, velocity, and acceleration of a CubicCurve
could be evaluated at any level. These evaluations all have the identical efficiency value, no matter the kind of cubic curve getting used. On a contemporary CPU, these evaluations take 1-2 ns, and animation easing – which is an iterative course of – takes 15-20 ns.
AccessKit integration into bevy_ui
#
authors: @ndarilek
Video games are for everybody: and the way in which they’re constructed ought to replicate that.
Accessible video games are uncommon, and correct assist is commonly an afterthought, each at an engine and a sport stage.
By constructing our UI answer with accessibility in thoughts, we hope to repair that.
Bevy has joined egui
in making the primary steps in direction of cross-platform accessibility-by-default, with the assistance of the excellent AccessKit crate.
To our data, this makes Bevy the primary common objective sport engine with first-party accessibility assist.
We have uncovered Bevy’s UI hierarchy and textual content parts to display readers and different assistive gadgets, managed by the brand new on-by-default bevy_a11y
crate.
That is finally powered by the brand new AccessibilityNode
part, which mixes with the present hierarchy to reveal this data on to AccessKit and the Focus
useful resource, which shops the entity that has keyboard focus.
There’s nonetheless much more to be completed right here: integrating the main focus system with a gamepad-driven UI controls answer, cleansing up the info mannequin to make sure “accessible by default” is a reality), and including assist for remaining options in AccessKit.
Particular due to @mwcampbell
, the lead writer of AccessKit, for reviewing our integration and dealing with us to scale back the variety of dependencies upstream, substantially improving both compile times and final executable size. That is still a serious challenge on Linux, and so the accesskit_unix
characteristic flag is disabled by default for now.
Spatial Audio
#
authors: @mockersf, @DGriffin91, @harudagondi, @alice-i-cecile
The library Bevy makes use of for audio, rodio
, comprises assist for spatial audio. Bevy 0.10 exposes primary spatial audio. There are nonetheless just a few caveats, like no HRTF and no top notch assist for Emitter
and Listener
elements.
Apparently, through the growth of this particular characteristic, @harudagondi
discovered a bug the place the audio channels reverse when working the app in both debug or launch mode. This seems to be a rodio
subject, and this additionally impacts earlier variations of Bevy. Because of @dis-da-moe
, the bug has been fixed upstream. See the linked PR for fascinating particulars about audio programming quirks and efficiency points.
Now you can have spatial audio in your sport! Clone the bevy
repository and invoke cargo run --example spatial_audio_3d --release
within the command line for a showcase of 3D spatial audio in Bevy.
Customized Audio Sources
#
authors: @dis-da-moe
Bevy helps customized audio sources by way of the Decodable
trait, however the way in which to register to the bevy app could be very boilerplatey and sparsely documented. In Bevy 0.10, a brand new extension trait for App
is added and the documentation for Decodable
has vastly improved.
As such, as an alternative of doing this:
struct MyCustomAudioSource { /* ... */ }
app.add_asset::<MyCustomAudioSource>()
.init_resource::<Audio<MyCustomAudioSource>>()
.init_resource::<AudioOutput<MyCustomAudioSource>>()
.add_system(play_queued_audio_system::<MyCustomAudioSource>.in_base_set(CoreSet::PostUpdate))
You solely have to do that:
app.add_audio_source::<MyCustomAudioSource>()
A lot cleaner!
ShaderDef Values
#
authors: @mockersf
Bevy’s shader processor now helps ShaderDefs with values, utilizing the brand new ShaderDefVal
. This enables builders to cross fixed values into their shaders:
let shader_defs = vec![
ShaderDefVal::Int("MAX_DIRECTIONAL_LIGHTS".to_string(), 10),
];
These can be utilized in #if
statements to selectively allow shader code based mostly on the worth:
#if MAX_DIRECTIONAL_LIGHTS >= 10
let colour = vec4<f32>(1.0, 0.0, 0.0, 1.0);
#else
let colour = vec4<f32>(0.0, 1.0, 0.0, 1.0);
#endif
ShaderDef values could be inlined into shaders:
for (var i: u32 = 0u; i < #{MAX_DIRECTIONAL_LIGHTS}; i = i + 1u) {
}
They may also be outlined inline in shaders:
#outline MAX_DIRECTIONAL_LIGHTS 10
ShaderDefs outlined in shaders override values handed in from Bevy.
#else ifdef
Chains in Shaders
#
authors: @torsteingrindvik
Bevy’s shader processor now additionally helps #else ifdef
chains like this:
#ifdef FOO
// foo code
#else ifdef BAR
// bar code
#else ifdef BAZ
// baz code
#else
// fallback code
#endif
New Shader Imports: World and View
#
authors: @torsteingrindvik
The World
and View
structs at the moment are importable in shaders utilizing #import bevy_render::globals
and #import bevy_render::view
. Bevy’s inner shaders now use these imports (saving numerous redundancy). Beforehand you both wanted to re-define in every shader or import the bigger bevy_pbr::mesh_view_types
(which wasn’t at all times what was wanted).
Beforehand this was wanted:
struct View {
view_proj: mat4x4<f32>,
inverse_view_proj: mat4x4<f32>,
view: mat4x4<f32>,
inverse_view: mat4x4<f32>,
projection: mat4x4<f32>,
inverse_projection: mat4x4<f32>,
world_position: vec3<f32>,
// viewport(x_origin, y_origin, width, peak)
viewport: vec4<f32>,
};
Now you may simply do that!
#import bevy_render::view
Adaptive Batching for Parallel Question Iteration
#
authors: @james7132
Question::par_for_each
has been the instrument everybody reaches for when their queries get too large to run single-threaded. Received 100,000 entities working round in your display? No drawback, Question::par_for_each
chunks it up into smaller batches and distributes the workload over a number of threads. Nevertheless, in Bevy 0.9 and earlier than, Question::par_for_each
required callers to offer a batch dimension to assist tune these batches for max efficiency. This somewhat opaque knob typically resulted in customers simply randomly selecting a worth and rolling with it, or tremendous tuning the worth based mostly on their growth machines. Sadly, the simplest worth relies on the runtime surroundings (i.e. what number of logical cores does a participant’s pc have) and the state of the ECS World (i.e. what number of entities are matched?). Finally most customers of the API simply selected a flat quantity and lived with the outcomes, good or dangerous.
// 0.9
const QUERY_BATCH_SIZE: usize = 32;
question.par_for_each(QUERY_BATCH_SIZE, |mut part| {
// ...
});
In 0.10, you not want to offer a batch dimension! For those who use Query::par_iter
, Bevy will robotically consider the state of the World and activity swimming pools and choose a batch dimension using a heuristic to make sure ample parallelism, with out incurring an excessive amount of overhead. This makes parallel queries as straightforward to make use of as regular single-threaded queries! Whereas nice for most common use instances, these heuristics might not be appropriate for each workload, so we have offered an escape hatch for many who want finer management over the workload distribution. Sooner or later, we could additional tune the backing heuristics to attempt to get the default to be nearer to optimum in these workloads.
// 0.10
question.par_iter().for_each(|part| {
// ...
});
// Pretty straightforward to transform from a single-threaded for_each. Simply change iter to par_iter!
question.iter().for_each(|part| {
// ...
});
You may also use BatchingStrategy
for extra management over batching:
question
.par_iter_mut()
// run with batches of 100
.batching_strategy(BatchingStrategy::fastened(100))
.for_each(|mut part| { /* ... */ });
See the BatchingStrategy
docs for more information.
UnsafeWorldCell
and UnsafeEntityCell
#
authors: @jakobhellermann, @BoxyUwU and @JoJoJet
UnsafeWorldCell
and UnsafeEntityCell
permit shared mutable entry to components of the world by way of unsafe code. It serves the same objective as UnsafeCell
, permitting folks to construct inside mutability abstractions resembling Cell
Mutex
Channel
and so on. In bevy UnsafeWorldCell
might be used to assist the scheduler and system param implementations as these are inside mutability abstractions for World
, it additionally presently is used to implement WorldCell
. We’re planning to make use of UnsafeEntityCell
to implement variations of EntityRef
/EntityMut
that solely have entry to the elements on the entity somewhat than the whole world.
These abstractions had been launched in #6404, #7381 and #7568.
Cylinder Form
#
authors: @JayPavlinas, @rparrett, @davidhof
The cylinder form primitive has joined our zoo of built-in shapes!
Subdividable Airplane Form
#
authors: @woodroww
Bevy’s Plane
form can now be subdivided any variety of instances.
Digicam Output Modes
#
authors: @cart, @robtfm
The camera-driven post-processing options added in Bevy 0.9 add intuitive management over post-processing throughout a number of cameras in a scene, however there were a few corner cases that did not fairly match into the hard-coded digicam output mannequin. And there have been some bugs and limitations associated to double-buffered goal texture sources of reality being incorrect throughout cameras and MSAA’s sampled texture not containing what it ought to below some circumstances.
Bevy 0.10 provides a CameraOutputMode
area to Camera
, which provides Bevy app builders the power to manually configure precisely how (and if) a Camera
‘s render outcomes ought to be written to the ultimate output texture:
// Configure the digicam to jot down to the ultimate output texture
digicam.output_mode = CameraOutputMode::Write {
// Don't mix with the present state of the output texture
blend_state: None,
// Clear the output texture
color_attachment_load_op: LoadOp::Clear(Default::default()),
};
// Configure the digicam to skip writing to the ultimate output texture
// This may save a cross when there are a number of cameras, and could be helpful for
// some post-processing conditions
digicam.output_mode = CameraOutputMode::Skip;
Most single-camera and multi-camera setups is not going to want to the touch this setting in any respect. However if you happen to want it, will probably be ready for you!
MSAA requires an additional intermediate “multisampled” texture, which will get resolved to the “precise” unsampled texture. In some nook case multi-camera setups that render to the identical texture, this will create bizarre / inconsistent outcomes based mostly on whether or not or not MSAA is enabled or disabled. We have added a brand new Digicam::msaa_writeback
bool
area which (when enabled) will write the present state of the unsampled texture to the intermediate MSAA texture (if a earlier digicam has already rendered to the goal on a given body). This ensures that the state is constant no matter MSAA configuration. This defaults to true, so that you solely want to consider this when you have a multi-camera setup and also you do not need MSAA writeback.
Configurable Visibility Element
#
authors: @ickk
The Visibility
part controls whether or not or not an Entity
ought to be rendered. Bevy 0.10 reworked the sort definition: somewhat than having a single is_visible: bool
area, we now use an enum with an extra mode:
pub enum Visibility {
Hidden, // unconditionally hidden
Seen, // unconditionally seen
Inherited, // inherit visibility from mum or dad
}
A lot simpler to grasp! In earlier Bevy variations, “inherited visibility” and “hidden” had been primarily the one two choices. Now entities can decide to be seen, even when their mum or dad is hidden!
AsBindGroup
Storage Buffers
#
authors: @IceSentry, @AndrewB330
AsBindGroup
is a helpful Bevy trait that makes it very easy to pass data into shaders.
Bevy 0.10 expands this with assist for “storage buffer bindings”, that are very helpful when passing in giant / unbounded chunks of knowledge:
#[derive(AsBindGroup)]
struct CoolMaterial {
#[uniform(0)]
colour: Coloration,
#[texture(1)]
#[sampler(2)]
color_texture: Deal with<Picture>,
#[storage(3)]
values: Vec<f32>,
#[storage(4, read_only, buffer)]
buffer: Buffer,
}
ExtractComponent
Derive
#
authors: @torsteingrindvik
To cross part knowledge from the “essential app” to the “render app” for pipelined rendering, we run an “extract step”. The ExtractComponent
trait is used to repeat knowledge over. In earlier variations of Bevy, you needed to implement it manually, however now you may derive it!
#[derive(Component, Clone, ExtractComponent)]
pub struct Automotive {
pub wheels: usize,
}
This expands to this:
impl ExtractComponent for Automotive
{
kind Question = &'static Self;
kind Filter = ();
kind Out = Self;
fn extract_component(merchandise: QueryItem<'_, Self::Question>) -> Possibility<Self::Out> {
Some(merchandise.clone())
}
}
It additionally helps filters!
#[derive(Component, Clone, ExtractComponent)]
#[extract_component_filter(With<Fuel>)]
pub struct Automotive {
pub wheels: usize,
}
Upgraded wgpu to 0.15
#
authors: @Elabajaba
Bevy 0.10 now makes use of the most recent and best wgpu
(our alternative of low stage graphics layer). Along with a number of nice API improvements and bug fixes, wgpu
now makes use of the DXC shader compiler for DX12, which is quicker, much less buggy, and permits for brand new options.
Enabled OpenGL Backend by Default
#
authors: @wangling12
Bevy has supported wgpu
‘s OpenGL backend for some time now, however it was opt-in. This triggered Bevy to fail to start out up on some machines that do not assist trendy apis like Vulkan. In Bevy 0.10 the OpenGL backend is enabled by default, which implies machines will robotically fall again to OpenGL if no different API is on the market.
Uncovered Non-Uniform Indexing Assist (Bindless)
#
authors: @cryscan
Bevy 0.10 wired up preliminary assist for non-uniform indexing of textures and storage buffers. This is a crucial step towards trendy “bindless / gpu-driven rendering”, which might unlock important efficiency on platforms that assist it. Notice that that is simply making the characteristic out there to render plugin builders. Bevy’s core rendering options don’t (but) use the bindless strategy.
We have added a new example illustrating the right way to use this characteristic:
Gamepad API Enhancements
#
authors: @DevinLeamy
The GamepadEventRaw
kind has been eliminated in favor of separate GamepadConnectionEvent
, GamepadAxisChangedEvent
, and GamepadButtonChangedEvent
, and the internals have been reworked to accommodate this.
This enables for less complicated, extra granular occasion entry with out filtering down the final GamepadEvent
kind. Good!
fn system(mut occasions: EventReader<GamepadConnectionEvent>)
for occasion in occasions.iter() {
}
}
Enter Methodology Editor (IME) Assist
#
authors: @mockersf
Window
can now configure IME assist utilizing ime_enabled
and ime_position
, which permits the usage of “useless keys”, which add assist for French, Pinyin, and so on:
Reflection Paths: Enums and Tuples
#
authors: @MrGVSV
Bevy’s “reflection paths” allow navigating Rust values utilizing a easy (and dynamic) string syntax. Bevy 0.10 expands this technique by including assist for tuples and enums in replicate paths:
#[derive(Reflect)]
struct MyStruct {
knowledge: Information,
some_tuple: (u32, u32),
}
#[derive(Reflect)]
enum Information {
Foo(u32, u32),
Bar(bool)
}
let x = MyStruct {
knowledge: Information::Foo(123),
some_tuple: (10, 20),
};
assert_eq!(*x.path::<u32>("knowledge.1").unwrap(), 123);
assert_eq!(*x.path::<u32>("some_tuple.0").unwrap(), 10);
Pre-Parsed Reflection Paths
#
authors: @MrGVSV, @james7132
Reflection paths allow numerous fascinating and dynamic editor eventualities, however they do have a draw back: calling path()
requires parsing strings each time. To unravel this drawback we added ParsedPath
, which permits pre-parsing paths after which reusing these outcomes on every entry:
let parsed_path = ParsedPath::parse("foo.bar[0]").unwrap();
let aspect = parsed_path.aspect::<usize>(&some_value);
Way more appropriate for repeated entry, resembling doing the identical lookup each body!
ReflectFromReflect
#
authors: @MrGVSV
When utilizing Bevy’s Rust reflection system, we generally find yourself in a situation the place we have now a “dynamic replicate worth” representing a sure kind MyType
(although below the hood, it is not actually that kind). Such eventualities occur once we name Mirror::clone_value
, use the reflection deserializers, or create the dynamic worth ourselves. Sadly, we will not simply name MyType::from_reflect
as we shouldn’t have data of the concrete MyType
at runtime.
ReflectFromReflect
is a brand new “kind knowledge” struct within the TypeRegistry
that permits FromReflect
trait operations with none concrete references to a given kind. Very cool!
#[derive(Reflect, FromReflect)]
#[reflect(FromReflect)] // <- Register `ReflectFromReflect`
struct MyStruct(String);
let type_id = TypeId::of::<MyStruct>();
// Register our kind
let mut registry = TypeRegistry::default();
registry.register::<MyStruct>();
// Create a concrete occasion
let my_struct = MyStruct("Hiya world".to_string());
// `Mirror::clone_value` will generate a `DynamicTupleStruct` for tuple struct sorts
// Notice that that is _not_ a MyStruct occasion
let dynamic_value: Field<dyn Mirror> = my_struct.clone_value();
// Get the `ReflectFromReflect` kind knowledge from the registry
let rfr: &ReflectFromReflect = registry
.get_type_data::<ReflectFromReflect>(type_id)
.unwrap();
// Name `FromReflect::from_reflect` on our Dynamic worth
let concrete_value: Field<dyn Mirror> = rfr.from_reflect(&dynamic_value);
assert!(concrete_value.is::<MyStruct>());
Different Reflection Enhancements
#
authors: @james7132, @soqb, @cBournhonesque, @SkiFire13
Reflect
is now carried out forstd::collections::VecDeque
- Mirrored
List
sorts now haveinsert
andtake away
operations - Mirrored
Map
sorts now have thetake away
operation - Mirrored generic sorts now robotically implement
Reflect
if the generics additionally implement Mirror. No want so as to add handbookT: Mirror
bounds! - Element Reflection now makes use of
EntityRef
/EntityMut
as an alternative of eachWorld
andEntity
, which permits it for use in additional eventualities - The Reflection deserializer now avoids unnecessarily cloning strings in some eventualities!
Upgraded Taffy To 0.3
#
authors: @ickshonpe, @rparret
Taffy is the library we use to compute layouts for bevy_ui
. Taffy 0.2 considerably improves the efficiency of nested UIs (our many_buttons
instance is now 8% quicker and extra deeply nested UIs ought to see even greater good points!). It additionally brings assist for the gap property which makes it simpler to creates UI with evenly spaced objects. Taffy 0.3 provides some good API tweaks (and likewise a grid structure characteristic, which we have now disabled for now because it nonetheless wants some integration work).
Relative Cursor Place
#
authors: @Pietrek14
We have added a brand new RelativeCursorPosition
UI part, which when added to a UI entity tracks the cursor place relative to the node. Some((0, 0))
represents the top-left nook of the node, Some((1,1))
represents the bottom-right nook of the node, and None
represents the cursor being “exterior of the node”.
instructions.spawn((
NodeBundle::default(),
RelativeCursorPosition::default(),
));
Const Bevy UI Defaults
#
authors: @james-j-obrien
Bevy makes use of the Default
trait quite a bit to make it straightforward to assemble sorts. Bevy UI sorts usually implement Default
. Nevertheless, it has one draw back (which is key to Rust): Default
can’t be utilized in const
contexts (yet!). To allow UI structure config to be outlined as constants, we have added DEFAULT
related constants to many of the Bevy UI sorts. For instance, you need to use Fashion::DEFAULT
to outline a const fashion:
const COOL_STYLE: Fashion = Fashion {
dimension: Measurement::width(Val::Px(200.0)),
border: UiRect::all(Val::Px(2.0)),
..Fashion::DEFAULT
};
Iterating by way of a World’s Entities
#
authors: @james7132
In Bevy 0.9, World::iter_entities
permits customers to get an iterator over the entire entities within the World
in Entity
type. In Bevy 0.10, this has been modified to be an iterator over EntityRef
, which provides full read-only entry to the entire entity’s elements as an alternative of simply getting its ID. Its new implementation also needs to be considerably quicker than fetching the EntityRef
by hand (although observe {that a} Question
will nonetheless be quicker if the precise elements you are on the lookout for). This provides customers free rein to arbitrarily learn any entity knowledge from the World, and might even see use in scripting language integrations and reflection-heavy workflows.
// Bevy 0.9
for entity in world.iter_entities() {
if let Some(entity_ref) = world.get_entity(entity) {
if let Some(part) = entity_ref.get::<MyComponent>() {
...
}
}
}
// Bevy 0.10
for entity_ref in world.iter_entities() {
if let Some(part) = entity_ref.get::<MyComponent>() {
...
}
}
Sooner or later, we could have a World::iter_entities_mut
that exposes this performance, however provides arbitrary mutable entry to all entities within the World
. We prevented implementing this for now because of the potential security considerations of returning an iterator of EntityMut
. For extra particulars, see this GitHub issue.
LCH Coloration Area
#
authors: @ldubos
Bevy’s Color
kind now helps the LCH colour area (Lightness, Chroma, Hue). LCH has numerous arguments for it, together with that it offers entry to about 50% extra colours over sRGB. Try this article for extra data.
Coloration::Lcha {
lightness: 1.0,
chroma: 0.5,
hue: 200.0,
alpha: 1.0,
}
Optimized Coloration::hex
Efficiency
#
authors: @wyhaya
Color::hex
is now a const
perform, which introduced the runtime of hex
from ~14ns to ~4ns!
Cut up Up CorePlugin
#
authors: @targrub
CorePlugin
has traditionally been a little bit of a “kitchen sink plugin”. “Core” issues that did not match anyplace else ended up there. This is not a fantastic organizational technique, so we broke it up into particular person items: TaskPoolPlugin
, TypeRegistrationPlugin
, and FrameCountPlugin
.
EntityCommand
s
#
authors: @JoJoJet
Commands
are “deferred ECS” operations. They permit builders to outline customized ECS operations which are utilized after a parallel system has completed working. Many Commands
ran on particular person entities, however this sample was a bit cumbersome:
struct MyCustomCommand(Entity);
impl Command for MyCustomCommand {
fn write(self, world: &mut World) {
// do one thing with the entity at self.0
}
}
let id = instructions.spawn(SpriteBundle::default()).id();
commmands.add(MyCustomCommand(id));
To unravel this, in Bevy 0.10 we added the EntityCommand
trait. This enables the command to be ergonomically utilized to spawned entities:
struct MyCustomCommand;
impl EntityCommand for MyCustomCommand {
fn write(self, id: Entity, world: &mut World) {
// do one thing with the given entity id
}
}
instructions.spawn(SpriteBundle::default()).add(MyCustomCommand);
Pixel Excellent Instance
#
authors: @Ian-Yy
We now have a brand new “pixel perfect” example that illustrates the right way to arrange pixel-perfect sprites. It makes use of a cute new Bevy emblem sprite!
UI Textual content Structure Instance
#
authors: @ickshonpe
We have added a pleasant “text layout” example that illustrates the assorted Bevy UI textual content structure settings:
CI Enhancements
#
authors: @mockersf
We take CI fairly critically in Bevy land and we’re at all times looking out for brand new methods to make our lives higher. We made plenty of good enhancements this cycle:
- We now set an MSRV (minimal supported Rust model) for the
bevy
crate and we have now a CI job that checks the MSRV - CI provides new contributors a pleasant welcome message!
- CI now asks for a migration information when a PR is labeled as a breaking change and no migration information is current
The First Topic Matter Professional Launch
#
This was our first launch utilizing our new Subject Matter Expert (SME) system. We merged a fully large quantity of modifications, and this was regardless of our Venture Lead @cart
being away for a few month for Christmas and snowboarding holidays. We maintained a top quality bar and constructed superb issues. Suffice it to say the longer term is wanting vivid (and sustainable)! Keep tuned for extra SME appointments in additional areas.
What’s Subsequent?
#
- Asset System Evolution: We have made good progress on the next iteration of the Bevy Asset System, which can add the power to preprocess belongings and enhance the flexibleness and value of the asset system.
- Kicking off the Bevy Editor Effort: We’re prepared to start out shifting our focus to constructing out the Bevy Editor! We have began gathering requirements and want to begin the preliminary design part within the Bevy 0.11 cycle.
- Temporal Anti-Aliasing (TAA): We have largely carried out TAA, which makes use of movement vectors and time to supply a very talked-about display area anti-aliasing impact.
- Display Area Ambient Occlusion (SSAO): This can be a well-liked, comparatively low cost illumination method that may make scenes look far more pure. It builds on the Depth Prepass work.
- Automated Render Batching and Instancing: Robotically lower down draw calls by combining geometry or utilizing instancing. This can allow Bevy to render tons of of 1000’s of objects with out grinding to a halt. We technically already assist this, however it should be carried out manually exterior of our normal pipeline. This can convey batching and instancing wins “at no cost” in our built-in render pipeline.
- One-shot programs: Run arbitrary programs in a push-based fashion via commands, and retailer them as callback elements for ultra-flexible habits customization.
- Higher plugins: Clearer and extra standardized instruments for adapting third-party plugins to your app’s unique architecture, eliminating order-dependence in their initialization and defining dependencies between them.
- Pull
!Ship
knowledge out of theWorld
: storing non thread-safe knowledge in a construction designed to be despatched throughout threads has triggered us no finish of complications. We plan on pulling these out into theApp
, resolving a serious blocker for a first-class multiple worlds design. - Timestamp window and enter occasions: As mentioned in #5984, monitoring the precise timing of enter occasions is crucial to making sure that occasion ordering and timing could be exactly reconstructed.
- Choose-out change detection: enhance efficiency for tiny elements by turning off change detection at compile or run-time.
- Complete Animation Composition: Supporting non-transitional animation composition (i.e. arbitrary weighted mixing of animations). For extra full data, see the RFC.
Try the Bevy 0.11 Milestone for an up-to-date checklist of present work being thought-about for Bevy 0.11.
Assist Bevy
#
Sponsorships assist make our work on Bevy sustainable. For those who imagine in Bevy’s mission, take into account sponsoring us … each bit helps!
Contributors
#
Bevy is made by a large group of people. An enormous due to the 173 contributors that made this launch (and related docs) doable! In random order:
- @killercup
- @torsteingrindvik
- @utilForever
- @garychia
- @lewiszlw
- @myreprise1
- @tomaspecl
- @jinleili
- @nicopap
- @edgarssilva
- @aevyrie
- @laundmo
- @AxiomaticSemantics
- @polygon
- @SkiFire13
- @SludgePhD
- @abnormalbrain
- @Testare
- @ldubos
- @SpeedRoll
- @rodolphito
- @hymm
- @rdbo
- @AndrewB330
- @13ros27
- @lupan
- @iwek7
- @ErickMVdO
- @kerkmann
- @davidhof
- @Pietrek14
- @Guvante
- @lidong63
- @Tirthnp
- @x-52
- @Suficio
- @pascualex
- @xgbwei
- @BoxyUwU
- @superdump
- @TheRawMeatball
- @wackbyte
- @StarLederer
- @MrGunflame
- @akimakinai
- @doup
- @komadori
- @darthdeus
- @phuocthanhdo
- @DanielJin21
- @LiamGallagher737
- @oliviacrain
- @IceSentry
- @Vrixyz
- @johanhelsing
- @Dessix
- @woodroww
- @SDesya74
- @alphastrata
- @wyhaya
- @foxzool
- @DasLixou
- @nakedible
- @soqb
- @Dorumin
- @maniwani
- @Elabajaba
- @geieredgar
- @stephenmartindale
- @TimJentzsch
- @holyfight6
- @targrub
- @smessmer
- @redwarp
- @LoopyAshy
- @mareq
- @bjrnt
- @slyedoc
- @kurtkuehnert
- @Charles Bournhonesque
- @cryscan
- @A-Walrus
- @JMS55
- @cBournhonesque
- @SpecificProtagonist
- @Shatur
- @VitalyAnkh
- @aktaboot
- @dis-da-moe
- @chrisjuchem
- @wilk10
- @2ne1ugly
- @zeroacez
- @jabuwu
- @Aceeri
- @coreh
- @SuperSodaSea
- @DGriffin91
- @DanielHZhang
- @mnmaita
- @elbertronnie
- @Zeenobit
- @oCaioOliveira
- @Sjael
- @JonahPlusPlus
- @devmitch
- @alice-i-cecile
- @remiCzn
- @Sasy00
- @sQu1rr
- @Ptipiak
- @zardini123
- @alradish
- @adam-shih
- @LinusKall
- @jakobhellermann
- @Andrii Borziak
- @figsoda
- @james7132
- @l1npengtul
- @danchia
- @AjaxGb
- @VVishion
- @CatThingy
- @zxygentoo
- @nfagerlund
- @silvestrpredko
- @ameknite
- @shuoli84
- @CrystaLamb
- @Nanox19435
- @james-j-obrien
- @mockersf
- @R2Boyo25
- @NeoRaider
- @MrGVSV
- @GuillaumeGomez
- @wangling12
- @AndrewJakubowicz
- @rick68
- @RedMachete
- @tbillington
- @ndarilek
- @Ian-Yy
- @Edwox
- @DevinLeamy
- @TehPers
- @cart
- @mvlabat
- @NiklasEi
- @ItsDoot
- @JayPavlina
- @ickk
- @Molot2032
- @devil-ira
- @inodentry
- @MinerSebas
- @JoJoJet
- @Neo-Zhixing
- @rparrett
- @djeedai
- @Pixelstormer
- @iiYese
- @harudagondi
- @1e1001
- @ickshonpe
- @rezural
- @arewerage
- @ld000
- @imustend
- @robtfm
- @frewsxcv
Full Changelog
#
Added
#
- Accessibility: Added
Label
for marking text specifically as a label for UI controls. - Accessibility: Integrate with and expose AccessKit accessibility.
- App:
App::setup
- App:
SubApp::new
- App: Bevy apps will now log system information on startup by default
- Audio Expose symphonia features from rodio in bevy_audio and bevy
- Audio: Basic spatial audio
- ECS:
bevy_ptr::dangling_with_align
: creates a well-aligned dangling pointer to a type whose alignment is not known at compile time. - ECS:
Column::get_added_ticks
- ECS:
Column::get_column_ticks
- ECS:
DetectChanges::set_if_neq
: triggering change detection when the new and previous values are equal. This will work on both components and resources. - ECS:
SparseSet::get_added_ticks
- ECS:
SparseSet::get_column_ticks
- ECS:
Tick
, a wrapper around a single change detection tick. - ECS:
UnsafeWorldCell::world_mut
now exists and can be used to get a&mut World
out ofUnsafeWorldCell
- ECS:
WorldId
now implements theFromWorld
trait. - ECS: A
core::fmt::Pointer
impl toPtr
,PtrMut
andOwnedPtr
. - ECS: Add
bevy_ecs::schedule_v3
module - ECS: Add
EntityMap::iter()
- ECS: Add
Ref
to the prelude - ECS: Add
report_sets
option toScheduleBuildSettings
- ECS: add
Resources::iter
to iterate over all resource IDs - ECS: add
UnsafeWorldCell
abstraction - ECS: Add
World::clear_resources
&World::clear_all
- ECS: Add a basic example for system ordering
- ECS: Add a missing impl of
ReadOnlySystemParam
forOption<NonSend<>>
- ECS: add a spawn_on_external method to allow spawning on the scope’s thread or an external thread
- ECS: Add const
Entity::PLACEHOLDER
- ECS: Add example to show how to use
apply_system_buffers
- ECS: Add logging variants of system piping
- ECS: Add safe constructors for untyped pointers
Ptr
andPtrMut
- ECS: Add unit test with system that panics
- ECS: Add wrapping_add to change_tick
- ECS: Added “base sets” and ported CoreSet to use them.
- ECS: Added
as_mut
andas_ref
methods toMutUntyped
. - ECS: Added
bevy::ecs::system::assert_is_read_only_system
. - ECS: Added
Components::resource_id
. - ECS: Added
DebugName
world query for more human friendly debug names of entities. - ECS: Added
distributive_run_if
toIntoSystemConfigs
to enable adding a run condition to each system when usingadd_systems
. - ECS: Added
EntityLocation::table_id
- ECS: Added
EntityLocation::table_row
. - ECS: Added
IntoIterator
implementation forEventReader
so you can now do&mut reader
instead ofreader.iter()
for events. - ECS: Added
len
,is_empty
,iter
methods on SparseSets. - ECS: Added
ManualEventReader::clear()
- ECS: Added
MutUntyped::with_type
which allows converting into aMut<T>
- ECS: Added
new_for_test
onComponentInfo
to make test code easy. - ECS: Added
not
condition. - ECS: Added
on_timer
andon_fixed_timer
run conditions - ECS: Added
OwningPtr::read_unaligned
. - ECS: Added
ReadOnlySystem
, which is implemented for anySystem
type whose parameters all implementReadOnlySystemParam
. - ECS: Added
Ref
which allows inspecting change detection flags in an immutable way - ECS: Added
shrink
andas_ref
methods toPtrMut
. - ECS: Added
SystemMeta::name
- ECS: Added
SystemState::get_manual_mut
- ECS: Added
SystemState::get_manual
- ECS: Added
SystemState::update_archetypes
- ECS: Added a large number of methods on
App
to work with schedules ergonomically - ECS: Added conversions from
Ptr
,PtrMut
, andOwningPtr
toNonNull<u8>
. - ECS: Added rore common run conditions:
on_event
, resource change detection,state_changed
,any_with_component
- ECS: Added support for variants of
bevy_ptr
types that do not require being correctly aligned for the pointee type. - ECS: Added the
CoreSchedule
enum - ECS: Added the
SystemParam
typeDeferred<T>
, which can be used to deferWorld
mutations. Powered by the new traitSystemBuffer
. - ECS: Added the extension methods
.and_then(...)
and.or_else(...)
to run conditions, which allows combining run conditions with short-circuiting behavior. - ECS: Added the marker trait
BaseSystemSet
, which is distinguished from aFreeSystemSet
. These are both subtraits ofSystemSet
. - ECS: Added the method
reborrow
toMut
,ResMut
,NonSendMut
, andMutUntyped
. - ECS: Added the private
prepare_view_uniforms
system now has a public system set for scheduling purposes, calledViewSet::PrepareUniforms
- ECS: Added the trait
Combine
, which can be used with the newCombinatorSystem
to create system combinators with custom behavior. - ECS: Added the trait
EntityCommand
. This is a counterpart ofCommand
for types that execute code for a single entity. - ECS: introduce EntityLocation::INVALID const and adjust Entities::get comment
- ECS: States derive macro
- ECS: support for tuple structs and unit structs to the
SystemParam
derive macro. - Hierarchy: Add
Transform::look_to
- Hierarchy: Added
add_child
,set_parent
andremove_parent
toEntityMut
- Hierarchy: Added
clear_children(&mut self) -> &mut Self
andreplace_children(&mut self, children: &[Entity]) -> &mut Self
function inBuildChildren
trait - Hierarchy: Added
ClearChildren
andReplaceChildren
struct - Hierarchy: Added
push_and_replace_children_commands
andpush_and_clear_children_commands
test - Hierarchy: Added the
BuildChildrenTransformExt
trait - Input: add Input Method Editor support
- Input: Added
Axis<T>::devices
- INput: Added common run conditions for
bevy_input
- Macro: add helper for macro to get either bevy::x or bevy_x depending on how it was imported
- Math:
CubicBezier2d
,CubicBezier3d
,QuadraticBezier2d
, andQuadraticBezier3d
types with methods for sampling position, velocity, and acceleration. The genericBezier
type is also available, and generic over any degree of Bezier curve. - Math:
CubicBezierEasing
, with additional methods to allow for smooth easing animations. - Math: Added a generic cubic curve trait, and implementation for Cardinal splines (including Catmull-Rom), B-Splines, Beziers, and Hermite Splines. 2D cubic curve segments also implement easing functionality for animation.
- New reflection path syntax: struct field access by index (example syntax:
foo#1
) - Reflect
State
generics other than justRandomState
can now be reflected for bothhashbrown::HashMap
andcollections::HashMap
- Reflect:
Aabb
now implementsFromReflect
. - Reflect:
derive(Reflect)
now supports structs and enums that contain generic types - Reflect:
ParsedPath
for cached reflection paths - Reflect:
std::collections::HashMap
can now be reflected - Reflect:
std::collections::VecDeque
now implementsReflect
and all relevant traits. - Reflect: Add reflection path support for
Tuple
types - Reflect: Added
ArrayIter::new
. - Reflect: Added
FromReflect::take_from_reflect
- Reflect: Added
List::insert
andList::remove
. - Reflect: Added
Map::remove
- Reflect: Added
ReflectFromReflect
- Reflect: Added
TypeRegistrationDeserializer
, which simplifies getting a&TypeRegistration
while deserializing a string. - Reflect: Added methods to
List
that were previously provided byArray
- Reflect: Added support for enums in reflection paths
- Reflect: Added the
bevy_reflect_compile_fail_tests
crate for testing compilation errors - Reflect: bevy_reflect: Add missing primitive registrations
- Reflect: impl
Reflect
for&'static Path
- Reflect: implement
Reflect
forFxaa
- Reflect: implement
TypeUuid
for primitives and fix multiple-parameter generics having the sameTypeUuid
- Reflect: Implemented
Reflect
+FromReflect
for window events and related types. These types are automatically registered when adding theWindowPlugin
. - Reflect: Register Hash for glam types
- Reflect: Register missing reflected types for
bevy_render
- Render: A pub field
extras
toGltfNode
/GltfMesh
/GltfPrimitive
which store extras - Render: A pub field
material_extras
toGltfPrimitive
which store material extras - Render: Add ‘Color::as_lcha’ function (#7757)
- Render: Add
Camera::viewport_to_world_2d
- Render: Add a more familiar hex color entry
- Render: add ambient lighting hook
- Render: Add bevy logo to the lighting example to demo alpha mask shadows
- Render: Add Box::from_corners method
- Render: add OpenGL and DX11 backends
- Render: Add orthographic camera support back to directional shadows
- Render: add standard material depth bias to pipeline
- Render: Add support for Rgb9e5Ufloat textures
- Render: Added buffer usage field to buffers
- Render: can define a value from inside a shader
- Render: EnvironmentMapLight support for WebGL2
- Render: Implement
ReadOnlySystemParam
forExtract<>
- Render: Initial tonemapping options
- Render: ShaderDefVal: add an
UInt
option - Render: Support raw buffers in AsBindGroup macro
- Rendering:
Aabb
now implementsCopy
. - Rendering:
ExtractComponent
can specify output type, and outputting is optional. - Rendering:
Mssaa::samples
- Rendering: Add
#else ifdef
to shader preprocessing. - Rendering: Add a field
push_constant_ranges
to RenderPipelineDescriptor and ComputePipelineDescriptor - Rendering: Added
Material::prepass_vertex_shader()
andMaterial::prepass_fragment_shader()
to control the prepass from theMaterial
- Rendering: Added
BloomSettings:lf_boost
,BloomSettings:lf_boost_curvature
,BloomSettings::high_pass_frequency
andBloomSettings::composite_mode
. - Rendering: Added
BufferVec::extend
- Rendering: Added
BufferVec::truncate
- Rendering: Added
Camera::msaa_writeback
which can enable and disable msaa writeback. - Rendering: Added
CascadeShadowConfigBuilder
to help with creatingCascadeShadowConfig
- Rendering: Added
DepthPrepass
andNormalPrepass
component to control which textures will be created by the prepass and available in later passes. - Rendering: Added
Draw<T>::prepare
optional trait function. - Rendering: Added
DrawFunctionsInternals::id()
- Rendering: Added
FallbackImageCubemap
. - Rendering: Added
FogFalloff
enum for selecting between three widely used “traditional” fog falloff modes:Linear
,Exponential
andExponentialSquared
, as well as a more advancedAtmospheric
fog; - Rendering: Added
get_input_node
- Rendering: Added
Lcha
member tobevy_render::color::Color
enum - Rendering: Added
MainTaret::main_texture_other
- Rendering: Added
PhaseItem::entity
- Rendering: Added
prepass_enabled
flag to theMaterialPlugin
that will control if a material uses the prepass or not. - Rendering: Added
prepass_enabled
flag to thePbrPlugin
to control if the StandardMaterial uses the prepass. Currently defaults to false. - Rendering: Added
PrepassNode
that runs before the main pass - Rendering: Added
PrepassPlugin
to extract/prepare/queue the necessary data - Rendering: Added
RenderCommand::ItemorldQuery
associated type. - Rendering: Added
RenderCommand::ViewWorldQuery
associated type. - Rendering: Added
RenderContext::add_command_buffer
- Rendering: Added
RenderContext::begin_tracked_render_pass
. - Rendering: Added
RenderContext::finish
- Rendering: Added
RenderContext::new
- Rendering: Added
SortedCameras
, exposing information that was previously internal to the camera driver node. - Rendering: Added
try_add_node_edge
- Rendering: Added
try_add_slot_edge
- Rendering: Added
with_r
,with_g
,with_b
, andwith_a
toColor
. - Rendering: Added 2x and 8x sample counts for MSAA.
- Rendering: Added a
#[storage(index)]
attribute to the deriveAsBindGroup
macro. - Rendering: Added an
EnvironmentMapLight
camera component that adds additional ambient light to a scene. - Rendering: Added argument to
ScalingMode::WindowSize
that specifies the number of pixels that equals one world unit. - Rendering: Added cylinder shape
- Rendering: Added example
shaders/texture_binding_array
. - Rendering: Added new capabilities for shader validation.
- Rendering: Added specializable
BlitPipeline
and ported the upscaling node to use this. - Rendering: Added subdivisions field to shape::Plane
- Rendering: Added support for additive and multiplicative blend modes in the PBR
StandardMaterial
, viaAlphaMode::Add
andAlphaMode::Multiply
; - Rendering: Added support for distance-based fog effects for PBR materials, controllable per-camera via the new
FogSettings
component; - Rendering: Added support for KTX2
R8_SRGB
,R8_UNORM
,R8G8_SRGB
,R8G8_UNORM
,R8G8B8_SRGB
,R8G8B8_UNORM
formats by converting to supported wgpu formats as appropriate - Rendering: Added support for premultiplied alpha in the PBR
StandardMaterial
, viaAlphaMode::Premultiplied
; - Rendering: Added the ability to
#[derive(ExtractComponent)]
with an optional filter. - Rendering: Added:
bevy_render::color::LchRepresentation
struct - Rendering: Clone impl for MaterialPipeline
- Rendering: Implemented
Clone
for all pipeline types. - Rendering: Smooth Transition between Animations
- Support optional env variable
BEVY_ASSET_ROOT
to explicitly specify root assets directory. - Task: Add thread create/destroy callbacks to TaskPool
- Tasks: Added
ThreadExecutor
that can only be ticked on one thread. - the extension methods
in_schedule(label)
andon_startup()
for configuring the schedule a system belongs to. - Transform: Added
GlobalTransform::reparented_to
- UI:
Size::new
is nowconst
- UI: Add const to methods and const defaults to bevy_ui
- UI: Added
all
,width
andheight
functions toSize
. - UI: Added
Anchor
component toText2dBundle
- UI: Added
CalculatedSize::preserve_aspect_ratio
- UI: Added
Component
derive toAnchor
- UI: Added
RelativeCursorPosition
, and an example showcasing it - UI: Added
Text::with_linebreak_behaviour
- UI: Added
TextBundle::with_linebreak_behaviour
- UI: Added a
BackgroundColor
component toTextBundle
. - UI: Added a helper method
with_background_color
toTextBundle
. - UI: Added the
SpaceEvenly
variant toAlignContent
. - UI: Added the
Start
andEnd
variants toAlignItems
,AlignSelf
,AlignContent
andJustifyContent
. - UI: Adds
flip_x
andflip_y
fields toExtractedUiNode
. - Utils: Added
SyncCell::read
, which allows shared access to values that already implement theSync
trait. - Utils: Added the guard type
bevy_utils::OnDrop
. - Window: Add
Windows::get_focused(_mut)
- Window: add span to winit event handler
- Window: Transparent window on macos
- Windowing:
WindowDescriptor
renamed toWindow
. - Windowing: Added
hittest
toWindowAttributes
- Windowing: Added
Window::prevent_default_event_handling
. This allows bevy apps to not override default browser behavior on hotkeys like F5, F12, Ctrl+R etc. - Windowing: Added
WindowDescriptor.always_on_top
which configures a window to stay on top. - Windowing: Added an example
cargo run --example fallthrough
- Windowing: Added the
hittest
’s setters/getters - Windowing: Modifed the
WindowDescriptor
’sDefault
impl. - Windowing: Modified the
WindowBuilder
Modified
#
- Animation:
AnimationPlayer
that are on a child or descendant of another entity with another player will no longer be run. - Animation: Animation sampling now runs fully multi-threaded using threads from
ComputeTaskPool
. - App: Adapt path type of dynamically_load_plugin
- App: Break CorePlugin into TaskPoolPlugin, TypeRegistrationPlugin, FrameCountPlugin.
- App: Increment FrameCount in CoreStage::Last.
- App::run() will now panic when called from Plugin::build()
- Asset:
AssetIo::watch_path_for_changes
allows watched path and path to reload to differ - Asset: make HandleUntyped::id private
- Audio:
AudioOutput
is now aResource
. It’s no longer!Send
- Audio: AudioOutput is actually a normal resource now, not a non-send resource
- ECS:
.label(SystemLabel)
is now referred to as.in_set(SystemSet)
- ECS:
App::add_default_labels
is nowApp::add_default_sets
- ECS:
App::add_system_set
was renamed toApp::add_systems
- ECS:
Archetype
indices andTable
rows have been newtyped asArchetypeRow
andTableRow
. - ECS:
ArchetypeGeneration
now implementsOrd
andPartialOrd
. - ECS:
bevy_pbr::add_clusters
is no longer an exclusive system - ECS:
Bundle::get_components
now takes aFnMut(StorageType, OwningPtr)
. The provided storage type must be correct for the component being fetched. - ECS:
ChangeTrackers<T>
has been deprecated. It will be removed in Bevy 0.11. - ECS:
Command
closures no longer need to implement the marker traitstd::marker::Sync
. - ECS:
CoreStage
andStartupStage
enums are nowCoreSet
andStartupSet
- ECS:
EntityMut::world_scope
now allows returning a value from the immediately-computed closure. - ECS:
EntityMut
: renameremove_intersection
toremove
andremove
totake
- ECS:
EventReader::clear
now takes a mutable reference instead of consuming the event reader. - ECS:
EventWriter::send_batch
will only log a TRACE level log if the batch is non-empty. - ECS:
oldest_id
andget_event
convenience methods added toEvents<T>
. - ECS:
OwningPtr::drop_as
will now panic in debug builds if the pointer is not aligned. - ECS:
OwningPtr::read
will now panic in debug builds if the pointer is not aligned. - ECS:
Ptr::deref
will now panic in debug builds if the pointer is not aligned. - ECS:
PtrMut::deref_mut
will now panic in debug builds if the pointer is not aligned. - ECS:
Query::par_for_each(_mut)
has been changed toQuery::par_iter(_mut)
and will now automatically try to produce a batch size for callers based on the currentWorld
state. - ECS:
RemovedComponents
now internally uses anEvents<RemovedComponentsEntity>
instead of anEvents<Entity>
- ECS:
SceneSpawnerSystem
now runs underCoreSet::Update
, rather thanCoreStage::PreUpdate.at_end()
. - ECS:
StartupSet
is now a base set - ECS:
System::default_labels
is nowSystem::default_system_sets
. - ECS:
SystemLabel
trait was replaced bySystemSet
- ECS:
SystemParamState::apply
now takes a&SystemMeta
parameter in addition to the provided&mut World
. - ECS:
SystemTypeIdLabel<T>
was replaced bySystemSetType<T>
- ECS:
tick_global_task_pools_on_main_thread
is no longer run as an exclusive system. Instead, it has been replaced bytick_global_task_pools
, which uses aNonSend
resource to force running on the main thread. - ECS:
Tick::is_older_than
was renamed toTick::is_newer_than
. This is not a functional change, since that was what was always being calculated, despite the wrong name. - ECS:
UnsafeWorldCell::world
is now used to get immutable access to the whole world instead of just the metadata which can now be done viaUnsafeWorldCell::world_metadata
- ECS:
World::init_non_send_resource
now returns the generatedComponentId
. - ECS:
World::init_resource
now returns the generatedComponentId
. - ECS:
World::iter_entities
now returns an iterator ofEntityRef
instead ofEntity
. - ECS:
World
s can now only hold a maximum of 2^32 – 1 tables. - ECS:
World
s can now only hold a maximum of 2^32- 1 archetypes. - ECS:
WorldId
now implementsSystemParam
and will return the id of the world the system is running in - ECS: Adding rendering extraction systems now panics rather than silently failing if no subapp with the
RenderApp
label is found. - ECS: Allow adding systems to multiple sets that share the same base set
- ECS: change
is_system_type() -> bool
tosystem_type() -> Option<TypeId>
- ECS: changed some
UnsafeWorldCell
methods to takeself
instead of&self
/&mut self
since there is literally no point to them doing that - ECS: Changed:
Query::for_each(_mut)
,QueryParIter
will now leverage autovectorization to speed up query iteration where possible. - ECS: Default to using ExecutorKind::SingleThreaded on wasm32
- ECS: Ensure
Query
does not use the wrongWorld
- ECS: Exclusive systems may now be used with system piping.
- ECS: expose
ScheduleGraph
for use in third party tools - ECS: extract topsort logic to a new method, one pass to detect cycles and …
- ECS: Fixed time steps now use a schedule (
CoreSchedule::FixedTimeStep
) rather than a run criteria. - ECS: for disconnected, use Vec instead of HashSet to reduce insert overhead
- ECS: Implement
SparseSetIndex
forWorldId
- ECS: Improve the panic message for schedule build errors
- ECS: Lift the 16-field limit from the
SystemParam
derive - ECS: Make
EntityRef::new
unsafe - ECS: Make
Query
fields private - ECS: make
ScheduleGraph::initialize
public - ECS: Make boxed conditions read-only
- ECS: Make RemovedComponents mirror EventReaders api surface
- ECS: Mark TableRow and TableId as repr(transparent)
- ECS: Most APIs returning
&UnsafeCell<ComponentTicks>
now returnsTickCells
instead, which contains two separate&UnsafeCell<Tick>
for either component ticks. - ECS: Move MainThreadExecutor for stageless migration.
- ECS: Move safe operations out of
unsafe
blocks inQuery
- ECS: Optimize
.nth()
and.last()
for event iterators - ECS: Optimize
Iterator::count
for event iterators - ECS: Provide public
EntityRef::get_change_ticks_by_id
that takesComponentId
- ECS: refactor: move internals from
entity_ref
toWorld
, addSAFETY
comments - ECS: Rename
EntityId
toEntityIndex
- ECS: Rename
UnsafeWorldCellEntityRef
toUnsafeEntityCell
- ECS: Rename schedule v3 to schedule
- ECS: Rename state_equals condition to in_state
- ECS: Replace
World::read_change_ticks
withWorld::change_ticks
withinbevy_ecs
crate - ECS: Replaced the trait
ReadOnlySystemParamFetch
withReadOnlySystemParam
. - ECS: Simplified the
SystemParamFunction
andExclusiveSystemParamFunction
traits. - ECS: Speed up
CommandQueue
by storing commands more densely - ECS: Stageless: move final apply outside of spawned executor
- ECS: Stageless: prettier cycle reporting
- ECS: Systems without
Commands
andParallelCommands
will no longer show asystem_commands
span when profiling. - ECS: The
ReportHierarchyIssue
resource now has a public constructor (new
), and implementsPartialEq
- ECS: The
StartupSchedule
label is now defined as part of theCoreSchedules
enum - ECS: The
SystemParam
derive is now more flexible, allowing you to omit unused lifetime parameters. - ECS: the top level
bevy_ecs::schedule
module was replaced withbevy_ecs::scheduling
- ECS: Use
World
helper methods for sendingHierarchyEvent
s - ECS: Use a bounded channel in the multithreaded executor
- ECS: Use a default implementation for
set_if_neq
- ECS: Use consistent names for marker generics
- ECS: Use correct terminology for a
NonSend
run condition panic - ECS: Use default-implemented methods for
IntoSystemConfig<>
- ECS: use try_send to replace send.await, unbounded channel should always b…
- General: The MSRV of the engine is now 1.67.
- Input: Bump gilrs version to 0.10
- IOS, Android… same thing
- Math: Update
glam
to0.23
- Math: use
Mul<f32>
to double the value ofVec3
- Reflect: bevy_reflect now uses a fixed state for its hasher, which means the output of
Reflect::reflect_hash
is now deterministic across processes. - Reflect: Changed function signatures of
ReflectComponent
methods,apply
,remove
,contains
, andreflect
. - Reflect: Changed the
List::push
andList::pop
to have default implementations. - Reflect: Registered
SmallVec<[Entity; 8]>
in the type registry - Renamed methods on
GetPath
:path
->reflect_path
path_mut
->reflect_path_mut
get_path
->path
get_path_mut
->path_mut
- Render: Allow prepass in webgl
- Render: bevy_pbr: Avoid copying structs and using registers in shaders
- Render: bevy_pbr: Clear fog DynamicUniformBuffer before populating each frame
- Render: bevy_render: Run calculate_bounds in the end-of-update exclusive systems
- Render: Change the glTF loader to use
Camera3dBundle
- Render: Changed &mut PipelineCache to &PipelineCache
- Render: Intepret glTF colors as linear instead of sRGB
- Render: Move ‘startup’ Resource
WgpuSettings
into theRenderPlugin
- Render: Move prepass functions to prepass_utils
- Render: Only compute sprite color once per quad
- Render: Only execute
#define
if current scope is accepting lines - Render: Pipelined Rendering
- Render: Refactor Globals and View structs into separate shaders
- Render: Replace UUID based IDs with a atomic-counted ones
- Render: run clear trackers on render world
- Render: set cull mode: None for Mesh2d
- Render: Shader defs can now have a value
- Render: Shrink ComputedVisibility
- Render: Use prepass shaders for shadows
- Rendering:
add_node_edge
is now infallible (panics on error) - Rendering:
add_slot_edge
is now infallible (panics on error) - Rendering:
AsBindGroup
is now object-safe. - Rendering:
BloomSettings::knee
renamed toBloomPrefilterSettings::softness
. - Rendering:
BloomSettings::threshold
renamed toBloomPrefilterSettings::threshold
. - Rendering:
HexColorError::Hex
has been renamed toHexColorError::Char
- Rendering:
input_node
now panics onNone
- Rendering:
ktx2
andzstd
are now part of bevy’s default enabled features - Rendering:
Msaa
is now enum - Rendering:
PipelineCache
no longer requires mutable access in order to queue render / compute pipelines. - Rendering:
RenderContext::command_encoder
is now private. Use the accessorRenderContext::command_encoder()
instead. - Rendering:
RenderContext::render_device
is now private. Use the accessorRenderContext::render_device()
instead. - Rendering:
RenderContext
now supports adding externalCommandBuffer
s for inclusion into the render graphs. These buffers can be encoded outside of the render graph (i.e. in a system). - Rendering:
scale
is now applied before updatingarea
. Reading from it will takescale
into account. - Rendering:
SkinnedMeshJoints::build
now takes a&mut BufferVec
instead of a&mut Vec
as a parameter. - Rendering:
StandardMaterial
now defaults to a dielectric material (0.0metallic
) with 0.5perceptual_roughness
. - Rendering:
TrackedRenderPass
now requires a&RenderDevice
on construction. - Rendering:
Visibility
is now an enum - Rendering: Bloom now looks different.
- Rendering: Directional lights now use cascaded shadow maps for improved shadow quality.
- Rendering: ExtractedMaterials, extract_materials and prepare_materials are now public
- Rendering: For performance reasons, some detailed renderer trace logs now require the use of cargo feature
detailed_trace
in addition to setting the log level toTRACE
in order to be shown. - Rendering: Made cameras with the same target share the same
main_texture
tracker, which ensures continuity across cameras. - Rendering: Renamed
ScalingMode::Auto
toScalingMode::AutoMin
. - Rendering: Renamed
ScalingMode::None
toScalingMode::Fixed
- Rendering: Renamed
window_origin
toviewport_origin
- Rendering: Renamed the
priority
field onCamera
toorder
. - Rendering: Replaced
left
,right
,bottom
, andtop
fields with a singlearea: Rect
- Rendering: StandardMaterials will now appear brighter and more saturated at high roughness, due to internal material changes. This is more physically correct.
- Rendering: The
layout
field ofRenderPipelineDescriptor
andComputePipelineDescriptor
is now mandatory. - Rendering: The
rangefinder
module has been moved into therender_phase
module. - Rendering: The bloom example has been renamed to bloom_3d and improved. A bloom_2d example was added.
- Rendering: the SubApp Extract stage has been separated from running the sub app schedule.
- Rendering: To enable multiple
RenderPhases
to share the sameTrackedRenderPass
, theRenderPhase::render
signature has changed. - Rendering: update its
Transform
in order to preserve itsGlobalTransform
after the parent change - Rendering: Updated to wgpu 0.15, wgpu-hal 0.15.1, and naga 0.11
- Rendering: Users can now use the DirectX Shader Compiler (DXC) on Windows with DX12 for faster shader compilation and ShaderModel 6.0+ support (requires
dxcompiler.dll
anddxil.dll
) - Rendering: You can now set up the rendering code of a
RenderPhase
directly using theRenderPhase::render
method, instead of implementing it manually in your render graph node. - Scenes:
SceneSpawner::spawn_dynamic
now returnsInstanceId
instead of()
. - Shape: Change
From<Icosphere>
toTryFrom<Icosphere>
- Tasks:
Scope
now usesFallibleTask
to await the cancellation of all remaining tasks when it’s dropped. - Time:
Time::set_relative_speed_fXX
now allows a relative speed of -0.0. - UI:
FocusPolicy
default has changed fromFocusPolicy::Block
toFocusPolicy::Pass
- UI:
TextPipeline::queue_text
andGlyphBrush::compute_glyphs
now need a TextLineBreakBehaviour argument, in order to pass through the new field. - UI:
update_image_calculated_size_system
setspreserve_aspect_ratio
to true for nodes with images. - UI: Added
Changed<Node>
to the change detection query oftext_system
. This ensures that any change in the size of a text node will cause any text it contains to be recomputed. - UI: Changed
Size::height
so it sets thewidth
toVal::AUTO
. - UI: Changed
Size::width
so it sets theheight
toVal::AUTO
. - UI: Changed
TextAlignment
into an enum withLeft
,Center
, andRight
variants. - UI: Changed extract_uinodes to extract the flip_x and flip_y values from UiImage.
- UI: Changed prepare_uinodes to swap the UV coordinates as required.
- UI: Changed Taffy version to 0.3.3 and disabled its
grid
feature. - UI: Changed the
Size
width
andheight
default values toVal::Auto
- UI: Changed the
size
field ofCalculatedSize
to a Vec2. - UI: Changed UiImage derefs to texture field accesses.
- UI: Changed UiImage to a struct with texture, flip_x, and flip_y fields.
- UI: Modified the
text2d
example to show both linebreaking behaviours. - UI: Renamed
image_node_system
toupdate_image_calculated_size_system
- UI: Renamed the
background_color
field ofExtractedUiNode
tocolor
. - UI: Simplified the UI examples. Replaced numeric values with the Flex property enums or elided them where possible, and removed the remaining use of auto margins.
- UI: The
MeasureFunc
only preserves the aspect ratio whenpreserve_aspect_ratio
is true. - UI: Updated
from_style
for Taffy 0.3.3. - UI: Upgraded to Taffy 0.2, improving UI layout performance significantly and adding the flexbox
gap
property andAlignContent::SpaceEvenly
. - UI: Use
f32::INFINITY
instead off32::MAX
to represent unbounded text in Text2dBounds - Window: expose cursor position with scale
- Window: Make WindowId::primary() const
- Window: revert stage changed for window closing
- Windowing:
WindowId
is nowEntity
. - Windowing: Moved
changed_window
anddespawn_window
systems toCoreStage::Last
to avoid systems making changes to theWindow
betweenchanged_window
and the end of the frame as they would be ignored. - Windowing: Requesting maximization/minimization is done on the [
Window::state
] field. - Windowing: Width/height consolidated into a
WindowResolution
component.