Skip to content

Commit

Permalink
Merge branch 'main' into render-world-use-passhashmap
Browse files Browse the repository at this point in the history
  • Loading branch information
superdump committed Sep 26, 2023
2 parents ad94257 + bc1f33d commit f904037
Show file tree
Hide file tree
Showing 37 changed files with 486 additions and 240 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ serialize = ["bevy_internal/serialize"]
# Enables multithreaded parallelism in the engine. Disabling it forces all engine tasks to run on a single thread.
multi-threaded = ["bevy_internal/multi-threaded"]

# Use async-io's implementation of block_on instead of futures-lite's implementation. This is preferred if your application uses async-io.
async-io = ["bevy_internal/async-io"]

# Wayland display server support
wayland = ["bevy_internal/wayland"]

Expand Down
11 changes: 8 additions & 3 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ impl App {
/// Setup the application to manage events of type `T`.
///
/// This is done by adding a [`Resource`] of type [`Events::<T>`],
/// and inserting an [`update_system`](Events::update_system) into [`First`].
/// and inserting an [`event_update_system`] into [`First`].
///
/// See [`Events`] for defining events.
///
Expand All @@ -440,13 +440,18 @@ impl App {
/// #
/// app.add_event::<MyEvent>();
/// ```
///
/// [`event_update_system`]: bevy_ecs::event::event_update_system
pub fn add_event<T>(&mut self) -> &mut Self
where
T: Event,
{
if !self.world.contains_resource::<Events<T>>() {
self.init_resource::<Events<T>>()
.add_systems(First, Events::<T>::update_system);
self.init_resource::<Events<T>>().add_systems(
First,
bevy_ecs::event::event_update_system::<T>
.run_if(bevy_ecs::event::event_update_condition::<T>),
);
}
self
}
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_asset/src/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl AssetProcessor {
let processor = _processor.clone();
std::thread::spawn(move || {
processor.process_assets();
futures_lite::future::block_on(processor.listen_for_source_change_events());
bevy_tasks::block_on(processor.listen_for_source_change_events());
});
}
}
Expand All @@ -190,7 +190,7 @@ impl AssetProcessor {
});
// This must happen _after_ the scope resolves or it will happen "too early"
// Don't move this into the async scope above! process_assets is a blocking/sync function this is fine
futures_lite::future::block_on(self.finish_processing_assets());
bevy_tasks::block_on(self.finish_processing_assets());
let end_time = std::time::Instant::now();
debug!("Processing finished in {:?}", end_time - start_time);
}
Expand Down
43 changes: 30 additions & 13 deletions crates/bevy_core_pipeline/src/skybox/skybox.wgsl
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
#import bevy_render::view View
#import bevy_pbr::utils coords_to_viewport_uv

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

fn coords_to_ray_direction(position: vec2<f32>, viewport: vec4<f32>) -> vec3<f32> {
// Using world positions of the fragment and camera to calculate a ray direction
// break down at large translations. This code only needs to know the ray direction.
// The ray direction is along the direction from the camera to the fragment position.
// In view space, the camera is at the origin, so the view space ray direction is
// along the direction of the fragment position - (0,0,0) which is just the
// fragment position.
// Use the position on the near clipping plane to avoid -inf world position
// because the far plane of an infinite reverse projection is at infinity.
let view_position_homogeneous = view.inverse_projection * vec4(
coords_to_viewport_uv(position, viewport) * vec2(2.0, -2.0) + vec2(-1.0, 1.0),
1.0,
1.0,
);
let view_ray_direction = view_position_homogeneous.xyz / view_position_homogeneous.w;
// Transforming the view space ray direction by the view matrix, transforms the
// direction to world space. Note that the w element is set to 0.0, as this is a
// vector direction, not a position, That causes the matrix multiplication to ignore
// the translations from the view matrix.
let ray_direction = (view.view * vec4(view_ray_direction, 0.0)).xyz;

return normalize(ray_direction);
}

struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
@location(0) world_position: vec3<f32>,
@builtin(position) position: vec4<f32>,
};

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

return VertexOutput(clip_position, world_position);
return VertexOutput(clip_position);
}

@fragment
fn skybox_fragment(in: VertexOutput) -> @location(0) vec4<f32> {
// The skybox cubemap is sampled along the direction from the camera world
// position, to the fragment world position on the near clipping plane
let ray_direction = in.world_position - view.world_position;
// cube maps are left-handed so we negate the z coordinate
let ray_direction = coords_to_ray_direction(in.position.xy, view.viewport);

// Cube maps are left-handed so we negate the z coordinate.
return textureSample(skybox, skybox_sampler, ray_direction * vec3(1.0, 1.0, -1.0));
}
2 changes: 1 addition & 1 deletion crates/bevy_ecs/examples/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn main() {
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
pub struct FlushEvents;

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

// Add systems sending and receiving events after the events are flushed.
schedule.add_systems((
Expand Down
18 changes: 12 additions & 6 deletions crates/bevy_ecs/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ struct EventInstance<E: Event> {
/// This collection is meant to be paired with a system that calls
/// [`Events::update`] exactly once per update/frame.
///
/// [`Events::update_system`] is a system that does this, typically initialized automatically using
/// [`event_update_system`] is a system that does this, typically initialized automatically using
/// [`add_event`](https://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event).
/// [`EventReader`]s are expected to read events from this collection at least once per loop/frame.
/// Events will persist across a single frame boundary and so ordering of event producers and
Expand Down Expand Up @@ -251,11 +251,6 @@ impl<E: Event> Events<E> {
iter.map(|e| e.event)
}

/// A system that calls [`Events::update`] once per frame.
pub fn update_system(mut events: ResMut<Self>) {
events.update();
}

#[inline]
fn reset_start_event_count(&mut self) {
self.events_a.start_event_count = self.event_count;
Expand Down Expand Up @@ -754,6 +749,17 @@ impl<'a, E: Event> ExactSizeIterator for EventIteratorWithId<'a, E> {
}
}

/// A system that calls [`Events::update`] once per frame.
pub fn event_update_system<T: Event>(mut events: ResMut<Events<T>>) {
events.update();
}

/// A run condition that checks if the event's [`event_update_system`]
/// needs to run or not.
pub fn event_update_condition<T: Event>(events: Res<Events<T>>) -> bool {
!events.events_a.is_empty() || !events.events_b.is_empty()
}

#[cfg(test)]
mod tests {
use crate::system::assert_is_read_only_system;
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/reflect/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
},
reflect_unchecked_mut: |entity| {
// SAFETY: reflect_unchecked_mut is an unsafe function pointer used by
// `reflect_unchecked_mut` which must be called with an UnsafeEntityCell with access to the the component `C` on the `entity`
// `reflect_unchecked_mut` which must be called with an UnsafeEntityCell with access to the component `C` on the `entity`
unsafe {
entity.get_mut::<C>().map(|c| Mut {
value: c.value as &mut dyn Reflect,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/schedule/condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ pub mod common_conditions {
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// # world.init_resource::<Events<MyEvent>>();
/// # app.add_systems(Events::<MyEvent>::update_system.before(my_system));
/// # app.add_systems(bevy_ecs::event::event_update_system::<MyEvent>.before(my_system));
///
/// app.add_systems(
/// my_system.run_if(on_event::<MyEvent>()),
Expand Down
10 changes: 10 additions & 0 deletions crates/bevy_hierarchy/src/components/parent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ impl Parent {
pub fn get(&self) -> Entity {
self.0
}

/// Gets the parent [`Entity`] as a slice of length 1.
///
/// Useful for making APIs that require a type or homogenous storage
/// for both [`Children`] & [`Parent`] that is agnostic to edge direction.
///
/// [`Children`]: super::children::Children
pub fn as_slice(&self) -> &[Entity] {
std::slice::from_ref(&self.0)
}
}

// TODO: We need to impl either FromWorld or Default so Parent can be registered as Reflect.
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ shader_format_spirv = ["bevy_render/shader_format_spirv"]

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

# Display server protocol support (X11 is enabled by default)
wayland = ["bevy_winit/wayland"]
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/pbr_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ pub struct StandardMaterial {
/// - It will look weird on bent/non-planar surfaces.
/// - The depth of the pixel does not reflect its visual position, resulting
/// in artifacts for depth-dependent features such as fog or SSAO.
/// - For the same reason, the the geometry silhouette will always be
/// - For the same reason, the geometry silhouette will always be
/// the one of the actual geometry, not the parallaxed version, resulting
/// in awkward looks on intersecting parallaxed surfaces.
///
Expand Down
19 changes: 11 additions & 8 deletions crates/bevy_pbr/src/prepass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,9 +668,16 @@ pub fn prepare_previous_view_projection_uniforms(
With<MotionVectorPrepass>,
>,
) {
view_uniforms.uniforms.clear();

for (entity, camera, maybe_previous_view_proj) in &views {
let views_iter = views.iter();
let view_count = views_iter.len();
let Some(mut writer) =
view_uniforms
.uniforms
.get_writer(view_count, &render_device, &render_queue)
else {
return;
};
for (entity, camera, maybe_previous_view_proj) in views_iter {
let view_projection = match maybe_previous_view_proj {
Some(previous_view) => previous_view.clone(),
None => PreviousViewProjection {
Expand All @@ -680,13 +687,9 @@ pub fn prepare_previous_view_projection_uniforms(
commands
.entity(entity)
.insert(PreviousViewProjectionUniformOffset {
offset: view_uniforms.uniforms.push(view_projection),
offset: writer.write(&view_projection),
});
}

view_uniforms
.uniforms
.write_buffer(&render_device, &render_queue);
}

#[derive(Default, Resource)]
Expand Down
18 changes: 10 additions & 8 deletions crates/bevy_pbr/src/render/fog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,15 @@ pub fn prepare_fog(
mut fog_meta: ResMut<FogMeta>,
views: Query<(Entity, Option<&FogSettings>), With<ExtractedView>>,
) {
fog_meta.gpu_fogs.clear();

for (entity, fog) in &views {
let views_iter = views.iter();
let view_count = views_iter.len();
let Some(mut writer) = fog_meta
.gpu_fogs
.get_writer(view_count, &render_device, &render_queue)
else {
return;
};
for (entity, fog) in views_iter {
let gpu_fog = if let Some(fog) = fog {
match &fog.falloff {
FogFalloff::Linear { start, end } => GpuFog {
Expand Down Expand Up @@ -103,13 +109,9 @@ pub fn prepare_fog(

// This is later read by `SetMeshViewBindGroup<I>`
commands.entity(entity).insert(ViewFogUniformOffset {
offset: fog_meta.gpu_fogs.push(gpu_fog),
offset: writer.write(&gpu_fog),
});
}

fog_meta
.gpu_fogs
.write_buffer(&render_device, &render_queue);
}

/// Inserted on each `Entity` with an `ExtractedView` to keep track of its offset
Expand Down
16 changes: 10 additions & 6 deletions crates/bevy_pbr/src/render/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,15 @@ pub fn prepare_lights(
point_lights: Query<(Entity, &ExtractedPointLight)>,
directional_lights: Query<(Entity, &ExtractedDirectionalLight)>,
) {
light_meta.view_gpu_lights.clear();
let views_iter = views.iter();
let views_count = views_iter.len();
let Some(mut view_gpu_lights_writer) =
light_meta
.view_gpu_lights
.get_writer(views_count, &render_device, &render_queue)
else {
return;
};

// Pre-calculate for PointLights
let cube_face_projection =
Expand Down Expand Up @@ -1197,14 +1205,10 @@ pub fn prepare_lights(
lights: view_lights,
},
ViewLightsUniformOffset {
offset: light_meta.view_gpu_lights.push(gpu_lights),
offset: view_gpu_lights_writer.write(&gpu_lights),
},
));
}

light_meta
.view_gpu_lights
.write_buffer(&render_device, &render_queue);
}

// this must match CLUSTER_COUNT_SIZE in pbr.wgsl
Expand Down
Loading

0 comments on commit f904037

Please sign in to comment.