Skip to content

Commit 312de3f

Browse files
committed
Merge branch 'main' into render-world-use-passhashmap
2 parents ad94257 + bc1f33d commit 312de3f

File tree

37 files changed

+486
-240
lines changed

37 files changed

+486
-240
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ serialize = ["bevy_internal/serialize"]
199199
# Enables multithreaded parallelism in the engine. Disabling it forces all engine tasks to run on a single thread.
200200
multi-threaded = ["bevy_internal/multi-threaded"]
201201

202+
# Use async-io's implementation of block_on instead of futures-lite's implementation. This is preferred if your application uses async-io.
203+
async-io = ["bevy_internal/async-io"]
204+
202205
# Wayland display server support
203206
wayland = ["bevy_internal/wayland"]
204207

crates/bevy_app/src/app.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ impl App {
424424
/// Setup the application to manage events of type `T`.
425425
///
426426
/// This is done by adding a [`Resource`] of type [`Events::<T>`],
427-
/// and inserting an [`update_system`](Events::update_system) into [`First`].
427+
/// and inserting an [`event_update_system`] into [`First`].
428428
///
429429
/// See [`Events`] for defining events.
430430
///
@@ -440,13 +440,18 @@ impl App {
440440
/// #
441441
/// app.add_event::<MyEvent>();
442442
/// ```
443+
///
444+
/// [`event_update_system`]: bevy_ecs::event::event_update_system
443445
pub fn add_event<T>(&mut self) -> &mut Self
444446
where
445447
T: Event,
446448
{
447449
if !self.world.contains_resource::<Events<T>>() {
448-
self.init_resource::<Events<T>>()
449-
.add_systems(First, Events::<T>::update_system);
450+
self.init_resource::<Events<T>>().add_systems(
451+
First,
452+
bevy_ecs::event::event_update_system::<T>
453+
.run_if(bevy_ecs::event::event_update_condition::<T>),
454+
);
450455
}
451456
self
452457
}

crates/bevy_asset/src/processor/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl AssetProcessor {
166166
let processor = _processor.clone();
167167
std::thread::spawn(move || {
168168
processor.process_assets();
169-
futures_lite::future::block_on(processor.listen_for_source_change_events());
169+
bevy_tasks::block_on(processor.listen_for_source_change_events());
170170
});
171171
}
172172
}
@@ -190,7 +190,7 @@ impl AssetProcessor {
190190
});
191191
// This must happen _after_ the scope resolves or it will happen "too early"
192192
// Don't move this into the async scope above! process_assets is a blocking/sync function this is fine
193-
futures_lite::future::block_on(self.finish_processing_assets());
193+
bevy_tasks::block_on(self.finish_processing_assets());
194194
let end_time = std::time::Instant::now();
195195
debug!("Processing finished in {:?}", end_time - start_time);
196196
}

crates/bevy_core_pipeline/src/skybox/skybox.wgsl

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,36 @@
11
#import bevy_render::view View
2+
#import bevy_pbr::utils coords_to_viewport_uv
23

34
@group(0) @binding(0) var skybox: texture_cube<f32>;
45
@group(0) @binding(1) var skybox_sampler: sampler;
56
@group(0) @binding(2) var<uniform> view: View;
67

8+
fn coords_to_ray_direction(position: vec2<f32>, viewport: vec4<f32>) -> vec3<f32> {
9+
// Using world positions of the fragment and camera to calculate a ray direction
10+
// break down at large translations. This code only needs to know the ray direction.
11+
// The ray direction is along the direction from the camera to the fragment position.
12+
// In view space, the camera is at the origin, so the view space ray direction is
13+
// along the direction of the fragment position - (0,0,0) which is just the
14+
// fragment position.
15+
// Use the position on the near clipping plane to avoid -inf world position
16+
// because the far plane of an infinite reverse projection is at infinity.
17+
let view_position_homogeneous = view.inverse_projection * vec4(
18+
coords_to_viewport_uv(position, viewport) * vec2(2.0, -2.0) + vec2(-1.0, 1.0),
19+
1.0,
20+
1.0,
21+
);
22+
let view_ray_direction = view_position_homogeneous.xyz / view_position_homogeneous.w;
23+
// Transforming the view space ray direction by the view matrix, transforms the
24+
// direction to world space. Note that the w element is set to 0.0, as this is a
25+
// vector direction, not a position, That causes the matrix multiplication to ignore
26+
// the translations from the view matrix.
27+
let ray_direction = (view.view * vec4(view_ray_direction, 0.0)).xyz;
28+
29+
return normalize(ray_direction);
30+
}
31+
732
struct VertexOutput {
8-
@builtin(position) clip_position: vec4<f32>,
9-
@location(0) world_position: vec3<f32>,
33+
@builtin(position) position: vec4<f32>,
1034
};
1135

1236
// 3 | 2.
@@ -29,21 +53,14 @@ fn skybox_vertex(@builtin(vertex_index) vertex_index: u32) -> VertexOutput {
2953
0.25,
3054
0.5
3155
) * 4.0 - vec4(1.0);
32-
// Use the position on the near clipping plane to avoid -inf world position
33-
// because the far plane of an infinite reverse projection is at infinity.
34-
// NOTE: The clip position has a w component equal to 1.0 so we don't need
35-
// to apply a perspective divide to it before inverse-projecting it.
36-
let world_position_homogeneous = view.inverse_view_proj * vec4(clip_position.xy, 1.0, 1.0);
37-
let world_position = world_position_homogeneous.xyz / world_position_homogeneous.w;
3856

39-
return VertexOutput(clip_position, world_position);
57+
return VertexOutput(clip_position);
4058
}
4159

4260
@fragment
4361
fn skybox_fragment(in: VertexOutput) -> @location(0) vec4<f32> {
44-
// The skybox cubemap is sampled along the direction from the camera world
45-
// position, to the fragment world position on the near clipping plane
46-
let ray_direction = in.world_position - view.world_position;
47-
// cube maps are left-handed so we negate the z coordinate
62+
let ray_direction = coords_to_ray_direction(in.position.xy, view.viewport);
63+
64+
// Cube maps are left-handed so we negate the z coordinate.
4865
return textureSample(skybox, skybox_sampler, ray_direction * vec3(1.0, 1.0, -1.0));
4966
}

crates/bevy_ecs/examples/events.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn main() {
1616
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
1717
pub struct FlushEvents;
1818

19-
schedule.add_systems(Events::<MyEvent>::update_system.in_set(FlushEvents));
19+
schedule.add_systems(bevy_ecs::event::event_update_system::<MyEvent>.in_set(FlushEvents));
2020

2121
// Add systems sending and receiving events after the events are flushed.
2222
schedule.add_systems((

crates/bevy_ecs/src/event.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ struct EventInstance<E: Event> {
103103
/// This collection is meant to be paired with a system that calls
104104
/// [`Events::update`] exactly once per update/frame.
105105
///
106-
/// [`Events::update_system`] is a system that does this, typically initialized automatically using
106+
/// [`event_update_system`] is a system that does this, typically initialized automatically using
107107
/// [`add_event`](https://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event).
108108
/// [`EventReader`]s are expected to read events from this collection at least once per loop/frame.
109109
/// Events will persist across a single frame boundary and so ordering of event producers and
@@ -251,11 +251,6 @@ impl<E: Event> Events<E> {
251251
iter.map(|e| e.event)
252252
}
253253

254-
/// A system that calls [`Events::update`] once per frame.
255-
pub fn update_system(mut events: ResMut<Self>) {
256-
events.update();
257-
}
258-
259254
#[inline]
260255
fn reset_start_event_count(&mut self) {
261256
self.events_a.start_event_count = self.event_count;
@@ -754,6 +749,17 @@ impl<'a, E: Event> ExactSizeIterator for EventIteratorWithId<'a, E> {
754749
}
755750
}
756751

752+
/// A system that calls [`Events::update`] once per frame.
753+
pub fn event_update_system<T: Event>(mut events: ResMut<Events<T>>) {
754+
events.update();
755+
}
756+
757+
/// A run condition that checks if the event's [`event_update_system`]
758+
/// needs to run or not.
759+
pub fn event_update_condition<T: Event>(events: Res<Events<T>>) -> bool {
760+
!events.events_a.is_empty() || !events.events_b.is_empty()
761+
}
762+
757763
#[cfg(test)]
758764
mod tests {
759765
use crate::system::assert_is_read_only_system;

crates/bevy_ecs/src/reflect/component.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
279279
},
280280
reflect_unchecked_mut: |entity| {
281281
// SAFETY: reflect_unchecked_mut is an unsafe function pointer used by
282-
// `reflect_unchecked_mut` which must be called with an UnsafeEntityCell with access to the the component `C` on the `entity`
282+
// `reflect_unchecked_mut` which must be called with an UnsafeEntityCell with access to the component `C` on the `entity`
283283
unsafe {
284284
entity.get_mut::<C>().map(|c| Mut {
285285
value: c.value as &mut dyn Reflect,

crates/bevy_ecs/src/schedule/condition.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ pub mod common_conditions {
867867
/// # let mut world = World::new();
868868
/// # world.init_resource::<Counter>();
869869
/// # world.init_resource::<Events<MyEvent>>();
870-
/// # app.add_systems(Events::<MyEvent>::update_system.before(my_system));
870+
/// # app.add_systems(bevy_ecs::event::event_update_system::<MyEvent>.before(my_system));
871871
///
872872
/// app.add_systems(
873873
/// my_system.run_if(on_event::<MyEvent>()),

crates/bevy_hierarchy/src/components/parent.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ impl Parent {
2323
pub fn get(&self) -> Entity {
2424
self.0
2525
}
26+
27+
/// Gets the parent [`Entity`] as a slice of length 1.
28+
///
29+
/// Useful for making APIs that require a type or homogenous storage
30+
/// for both [`Children`] & [`Parent`] that is agnostic to edge direction.
31+
///
32+
/// [`Children`]: super::children::Children
33+
pub fn as_slice(&self) -> &[Entity] {
34+
std::slice::from_ref(&self.0)
35+
}
2636
}
2737

2838
// TODO: We need to impl either FromWorld or Default so Parent can be registered as Reflect.

crates/bevy_internal/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ shader_format_spirv = ["bevy_render/shader_format_spirv"]
6363

6464
serialize = ["bevy_core/serialize", "bevy_input/serialize", "bevy_time/serialize", "bevy_window/serialize", "bevy_transform/serialize", "bevy_math/serialize", "bevy_scene?/serialize"]
6565
multi-threaded = ["bevy_asset/multi-threaded", "bevy_ecs/multi-threaded", "bevy_tasks/multi-threaded"]
66+
async-io = ["bevy_tasks/async-io"]
6667

6768
# Display server protocol support (X11 is enabled by default)
6869
wayland = ["bevy_winit/wayland"]

crates/bevy_pbr/src/pbr_material.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ pub struct StandardMaterial {
254254
/// - It will look weird on bent/non-planar surfaces.
255255
/// - The depth of the pixel does not reflect its visual position, resulting
256256
/// in artifacts for depth-dependent features such as fog or SSAO.
257-
/// - For the same reason, the the geometry silhouette will always be
257+
/// - For the same reason, the geometry silhouette will always be
258258
/// the one of the actual geometry, not the parallaxed version, resulting
259259
/// in awkward looks on intersecting parallaxed surfaces.
260260
///

crates/bevy_pbr/src/prepass/mod.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -668,9 +668,16 @@ pub fn prepare_previous_view_projection_uniforms(
668668
With<MotionVectorPrepass>,
669669
>,
670670
) {
671-
view_uniforms.uniforms.clear();
672-
673-
for (entity, camera, maybe_previous_view_proj) in &views {
671+
let views_iter = views.iter();
672+
let view_count = views_iter.len();
673+
let Some(mut writer) =
674+
view_uniforms
675+
.uniforms
676+
.get_writer(view_count, &render_device, &render_queue)
677+
else {
678+
return;
679+
};
680+
for (entity, camera, maybe_previous_view_proj) in views_iter {
674681
let view_projection = match maybe_previous_view_proj {
675682
Some(previous_view) => previous_view.clone(),
676683
None => PreviousViewProjection {
@@ -680,13 +687,9 @@ pub fn prepare_previous_view_projection_uniforms(
680687
commands
681688
.entity(entity)
682689
.insert(PreviousViewProjectionUniformOffset {
683-
offset: view_uniforms.uniforms.push(view_projection),
690+
offset: writer.write(&view_projection),
684691
});
685692
}
686-
687-
view_uniforms
688-
.uniforms
689-
.write_buffer(&render_device, &render_queue);
690693
}
691694

692695
#[derive(Default, Resource)]

crates/bevy_pbr/src/render/fog.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,15 @@ pub fn prepare_fog(
5252
mut fog_meta: ResMut<FogMeta>,
5353
views: Query<(Entity, Option<&FogSettings>), With<ExtractedView>>,
5454
) {
55-
fog_meta.gpu_fogs.clear();
56-
57-
for (entity, fog) in &views {
55+
let views_iter = views.iter();
56+
let view_count = views_iter.len();
57+
let Some(mut writer) = fog_meta
58+
.gpu_fogs
59+
.get_writer(view_count, &render_device, &render_queue)
60+
else {
61+
return;
62+
};
63+
for (entity, fog) in views_iter {
5864
let gpu_fog = if let Some(fog) = fog {
5965
match &fog.falloff {
6066
FogFalloff::Linear { start, end } => GpuFog {
@@ -103,13 +109,9 @@ pub fn prepare_fog(
103109

104110
// This is later read by `SetMeshViewBindGroup<I>`
105111
commands.entity(entity).insert(ViewFogUniformOffset {
106-
offset: fog_meta.gpu_fogs.push(gpu_fog),
112+
offset: writer.write(&gpu_fog),
107113
});
108114
}
109-
110-
fog_meta
111-
.gpu_fogs
112-
.write_buffer(&render_device, &render_queue);
113115
}
114116

115117
/// Inserted on each `Entity` with an `ExtractedView` to keep track of its offset

crates/bevy_pbr/src/render/light.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,15 @@ pub fn prepare_lights(
666666
point_lights: Query<(Entity, &ExtractedPointLight)>,
667667
directional_lights: Query<(Entity, &ExtractedDirectionalLight)>,
668668
) {
669-
light_meta.view_gpu_lights.clear();
669+
let views_iter = views.iter();
670+
let views_count = views_iter.len();
671+
let Some(mut view_gpu_lights_writer) =
672+
light_meta
673+
.view_gpu_lights
674+
.get_writer(views_count, &render_device, &render_queue)
675+
else {
676+
return;
677+
};
670678

671679
// Pre-calculate for PointLights
672680
let cube_face_projection =
@@ -1197,14 +1205,10 @@ pub fn prepare_lights(
11971205
lights: view_lights,
11981206
},
11991207
ViewLightsUniformOffset {
1200-
offset: light_meta.view_gpu_lights.push(gpu_lights),
1208+
offset: view_gpu_lights_writer.write(&gpu_lights),
12011209
},
12021210
));
12031211
}
1204-
1205-
light_meta
1206-
.view_gpu_lights
1207-
.write_buffer(&render_device, &render_queue);
12081212
}
12091213

12101214
// this must match CLUSTER_COUNT_SIZE in pbr.wgsl

0 commit comments

Comments
 (0)