Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions crates/bevy_pbr/src/lightmap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ use bevy_ecs::{
component::Component,
entity::Entity,
reflect::ReflectComponent,
schedule::IntoSystemConfigs,
system::{Query, Res, ResMut, Resource},
};
use bevy_math::{uvec2, vec4, Rect, UVec2};
Expand All @@ -48,8 +47,6 @@ use bevy_render::{
};
use bevy_utils::HashSet;

use crate::{ExtractMeshesSet, RenderMeshInstances};

/// The ID of the lightmap shader.
pub const LIGHTMAP_SHADER_HANDLE: Handle<Shader> =
Handle::weak_from_u128(285484768317531991932943596447919767152);
Expand Down Expand Up @@ -134,16 +131,15 @@ impl Plugin for LightmapPlugin {

render_app
.init_resource::<RenderLightmaps>()
.add_systems(ExtractSchedule, extract_lightmaps.after(ExtractMeshesSet));
.add_systems(ExtractSchedule, extract_lightmaps);
}
}

/// Extracts all lightmaps from the scene and populates the [`RenderLightmaps`]
/// resource.
fn extract_lightmaps(
mut render_lightmaps: ResMut<RenderLightmaps>,
lightmaps: Extract<Query<(Entity, &ViewVisibility, &Lightmap)>>,
render_mesh_instances: Res<RenderMeshInstances>,
lightmaps: Extract<Query<(Entity, &ViewVisibility, &Lightmap, &Handle<Mesh>)>>,
images: Res<RenderAssets<GpuImage>>,
meshes: Res<RenderAssets<GpuMesh>>,
) {
Expand All @@ -152,14 +148,13 @@ fn extract_lightmaps(
render_lightmaps.all_lightmap_images.clear();

// Loop over each entity.
for (entity, view_visibility, lightmap) in lightmaps.iter() {
for (entity, view_visibility, lightmap, mesh) in lightmaps.iter() {
// Only process visible entities for which the mesh and lightmap are
// both loaded.
if !view_visibility.get()
|| images.get(&lightmap.image).is_none()
|| !render_mesh_instances
.mesh_asset_id(entity)
.and_then(|mesh_asset_id| meshes.get(mesh_asset_id))
|| !meshes
.get(mesh.id())
.is_some_and(|mesh| mesh.layout.0.contains(Mesh::ATTRIBUTE_UV_1.id))
{
continue;
Expand Down
54 changes: 32 additions & 22 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,15 @@ impl Plugin for MeshRenderPlugin {
render_app
.init_resource::<gpu_preprocessing::BatchedInstanceBuffers<MeshUniform, MeshInputUniform>>(
)
.init_resource::<RenderMeshInstanceGpuQueues>()
.add_systems(
ExtractSchedule,
extract_meshes_for_gpu_building.in_set(ExtractMeshesSet),
)
.add_systems(
Render,
(
collect_meshes_for_gpu_building.in_set(RenderSet::CollectMeshes),
gpu_preprocessing::write_batched_instance_buffers::<MeshPipeline>
.in_set(RenderSet::PrepareResourcesFlush),
gpu_preprocessing::delete_old_work_item_buffers::<MeshPipeline>
Expand Down Expand Up @@ -491,7 +493,8 @@ pub struct RenderMeshInstanceGpuBuilder {
pub mesh_flags: MeshFlags,
}

/// The per-thread queues used during [`extract_meshes_for_gpu_building`].
/// One per-thread queue produced during [`extract_meshes_for_gpu_building`] and
/// consumed during [`collect_meshes_for_gpu_building`].
///
/// There are two varieties of these: one for when culling happens on CPU and
/// one for when culling happens on GPU. Having the two varieties avoids wasting
Expand Down Expand Up @@ -891,6 +894,16 @@ pub fn extract_meshes_for_cpu_building(
}
}

/// Holds all per-thread queues produced during
/// [`extract_meshes_for_gpu_building`] and consumed during
/// [`collect_meshes_for_gpu_building`].
///
/// There are two varieties of these: one for when culling happens on CPU and
/// one for when culling happens on GPU. Having the two varieties avoids wasting
/// space if GPU culling is disabled.
#[derive(Resource, Default, Deref, DerefMut)]
pub struct RenderMeshInstanceGpuQueues(Parallel<RenderMeshInstanceGpuQueue>);

/// Extracts meshes from the main world into the render world and queues
/// [`MeshInputUniform`]s to be uploaded to the GPU.
///
Expand All @@ -899,11 +912,7 @@ pub fn extract_meshes_for_cpu_building(
pub fn extract_meshes_for_gpu_building(
mut render_mesh_instances: ResMut<RenderMeshInstances>,
render_visibility_ranges: Res<RenderVisibilityRanges>,
mut batched_instance_buffers: ResMut<
gpu_preprocessing::BatchedInstanceBuffers<MeshUniform, MeshInputUniform>,
>,
mut mesh_culling_data_buffer: ResMut<MeshCullingDataBuffer>,
mut render_mesh_instance_queues: Local<Parallel<RenderMeshInstanceGpuQueue>>,
mut render_mesh_instance_queues: ResMut<RenderMeshInstanceGpuQueues>,
meshes_query: Extract<
Query<(
Entity,
Expand Down Expand Up @@ -1003,13 +1012,6 @@ pub fn extract_meshes_for_gpu_building(
queue.push(entity, gpu_mesh_instance_builder, gpu_mesh_culling_data);
},
);

collect_meshes_for_gpu_building(
render_mesh_instances,
&mut batched_instance_buffers,
&mut mesh_culling_data_buffer,
&mut render_mesh_instance_queues,
);
}

/// A system that sets the [`RenderMeshInstanceFlags`] for each mesh based on
Expand Down Expand Up @@ -1043,22 +1045,29 @@ fn set_mesh_motion_vector_flags(

/// Creates the [`RenderMeshInstanceGpu`]s and [`MeshInputUniform`]s when GPU
/// mesh uniforms are built.
fn collect_meshes_for_gpu_building(
render_mesh_instances: &mut RenderMeshInstancesGpu,
batched_instance_buffers: &mut gpu_preprocessing::BatchedInstanceBuffers<
MeshUniform,
MeshInputUniform,
pub fn collect_meshes_for_gpu_building(
mut render_mesh_instances: ResMut<RenderMeshInstances>,
batched_instance_buffers: ResMut<
gpu_preprocessing::BatchedInstanceBuffers<MeshUniform, MeshInputUniform>,
>,
mesh_culling_data_buffer: &mut MeshCullingDataBuffer,
render_mesh_instance_queues: &mut Parallel<RenderMeshInstanceGpuQueue>,
mut mesh_culling_data_buffer: ResMut<MeshCullingDataBuffer>,
mut render_mesh_instance_queues: ResMut<RenderMeshInstanceGpuQueues>,
) {
// Collect render mesh instances. Build up the uniform buffer.

let RenderMeshInstances::GpuBuilding(ref mut render_mesh_instances) = *render_mesh_instances
else {
panic!(
"`collect_meshes_for_gpu_building` should only be called if we're \
using GPU `MeshUniform` building"
);
};

let gpu_preprocessing::BatchedInstanceBuffers {
ref mut current_input_buffer,
ref mut previous_input_buffer,
..
} = batched_instance_buffers;
} = batched_instance_buffers.into_inner();

// Swap buffers.
mem::swap(current_input_buffer, previous_input_buffer);
Expand Down Expand Up @@ -1087,7 +1096,8 @@ fn collect_meshes_for_gpu_building(
render_mesh_instances,
current_input_buffer,
);
let culling_data_index = mesh_culling_builder.add_to(mesh_culling_data_buffer);
let culling_data_index =
mesh_culling_builder.add_to(&mut *mesh_culling_data_buffer);
debug_assert_eq!(instance_data_index, culling_data_index);
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ pub enum RenderSet {
PrepareAssets,
/// Create any additional views such as those used for shadow mapping.
ManageViews,
/// Collect meshes and produce any per-mesh data the GPU will need
CollectMeshes,
/// Queue drawable entities as phase items in render phases ready for
/// sorting (if necessary)
Queue,
Expand Down Expand Up @@ -171,6 +173,7 @@ impl Render {
.chain()
.in_set(Prepare),
);
schedule.configure_sets((PrepareAssets, CollectMeshes, Queue).chain());

schedule
}
Expand Down