diff --git a/Cargo.toml b/Cargo.toml index ea97978..cff916d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,5 +28,5 @@ bevy = { version = "0.7", default-features = false, features = [ "x11" ] } bevy_full_throttle = { git = "https://github.com/lightsoutgames/bevy_full_throttle" } -bevy_flycam = "0.6.0" -smooth-bevy-cameras = "0.2.0" +bevy_flycam = "0.7" +smooth-bevy-cameras = "0.3" diff --git a/src/deferred.rs b/src/deferred.rs index 15fb144..d28730a 100644 --- a/src/deferred.rs +++ b/src/deferred.rs @@ -8,10 +8,11 @@ use bevy::{ prelude::FromWorld, prelude::*, render::{ + mesh::MeshVertexBufferLayout, render_asset::RenderAssets, render_graph::{self, SlotInfo, SlotType}, render_phase::{ - sort_phase_system, AddRenderCommand, CachedPipelinePhaseItem, DrawFunctionId, + sort_phase_system, AddRenderCommand, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, EntityPhaseItem, PhaseItem, RenderPhase, SetItemPipeline, TrackedRenderPass, }, @@ -29,7 +30,7 @@ impl Plugin for DeferredPlugin { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { render_app .init_resource::() - .init_resource::>() + .init_resource::>() .init_resource::>>() .init_resource::>>() .init_resource::>>() @@ -82,13 +83,17 @@ impl FromWorld for DeferredPipeline { } } -impl SpecializedPipeline for DeferredPipeline { +impl SpecializedMeshPipeline for DeferredPipeline { type Key = MeshPipelineKey; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + key: Self::Key, + layout: &MeshVertexBufferLayout, + ) -> Result { let shader = ALBEDO_SHADER_HANDLE.typed::(); - let mut descriptor = self.mesh_pipeline.specialize(key); + let mut descriptor = self.mesh_pipeline.specialize(key, layout)?; descriptor.fragment.as_mut().unwrap().shader = shader; descriptor.layout = Some(vec![ self.mesh_pipeline.view_layout.clone(), @@ -96,7 +101,7 @@ impl SpecializedPipeline for DeferredPipeline { self.mesh_pipeline.mesh_layout.clone(), ]); - descriptor + Ok(descriptor) } } @@ -108,11 +113,11 @@ pub type DrawDeferredMesh = ( DrawMesh, ); -pub struct Deferred(T); +pub struct Deferred(T); impl PhaseItem for Deferred where - T: PhaseItem + EntityPhaseItem + CachedPipelinePhaseItem, + T: PhaseItem + EntityPhaseItem + CachedRenderPipelinePhaseItem, { type SortKey = T::SortKey; @@ -127,18 +132,18 @@ where impl EntityPhaseItem for Deferred where - T: PhaseItem + EntityPhaseItem + CachedPipelinePhaseItem, + T: PhaseItem + EntityPhaseItem + CachedRenderPipelinePhaseItem, { fn entity(&self) -> Entity { self.0.entity() } } -impl CachedPipelinePhaseItem for Deferred +impl CachedRenderPipelinePhaseItem for Deferred where - T: PhaseItem + EntityPhaseItem + CachedPipelinePhaseItem, + T: PhaseItem + EntityPhaseItem + CachedRenderPipelinePhaseItem, { - fn cached_pipeline(&self) -> CachedPipelineId { + fn cached_pipeline(&self) -> CachedRenderPipelineId { self.0.cached_pipeline() } } @@ -153,8 +158,8 @@ fn queue_deferred_meshes( material_meshes: Query<(&Handle, &Handle, &MeshUniform)>, render_meshes: Res>, render_materials: Res>, - mut pipelines: ResMut>, - mut pipeline_cache: ResMut, + mut pipelines: ResMut>, + mut pipeline_cache: ResMut, msaa: Res, mut view_query: Query<( &ExtractedView, @@ -195,9 +200,6 @@ fn queue_deferred_meshes( if let Some(mesh) = render_meshes.get(mesh_handle) { let mesh_z = inverse_view_row_2.dot(mesh_uniform.transform.col(3)); - if mesh.has_tangents { - mesh_key |= MeshPipelineKey::VERTEX_TANGENTS; - } mesh_key |= MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); @@ -206,8 +208,14 @@ fn queue_deferred_meshes( mesh_key |= MeshPipelineKey::TRANSPARENT_MAIN_PASS; } - let pipeline_id = - pipelines.specialize(&mut pipeline_cache, &deferred_pipeline, mesh_key); + let pipeline_id = pipelines + .specialize( + &mut pipeline_cache, + &deferred_pipeline, + mesh_key, + &mesh.layout, + ) + .unwrap(); match alpha_mode { AlphaMode::Opaque => opaque_phase.add(Deferred(Opaque3d { diff --git a/src/overlay.rs b/src/overlay.rs index dc388e4..2aca638 100644 --- a/src/overlay.rs +++ b/src/overlay.rs @@ -3,17 +3,18 @@ use bevy::{ core::FloatOrd, ecs::system::{lifetimeless::SRes, SystemParamItem}, pbr::{ - DrawMesh, MaterialPipeline, MeshPipelineKey, SetMaterialBindGroup, SetMeshBindGroup, - SetMeshViewBindGroup, SpecializedMaterial, + DrawMesh, MaterialPipeline, MaterialPipelineKey, MeshPipelineKey, SetMaterialBindGroup, + SetMeshBindGroup, SetMeshViewBindGroup, SpecializedMaterial, }, prelude::*, reflect::TypeUuid, render::{ + mesh::MeshVertexBufferLayout, render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets}, render_component::ExtractComponentPlugin, render_graph::{self, SlotInfo, SlotType}, render_phase::{ - AddRenderCommand, CachedPipelinePhaseItem, DrawFunctionId, DrawFunctions, + AddRenderCommand, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, EntityPhaseItem, PhaseItem, RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::*, @@ -39,7 +40,7 @@ impl Plugin for OverlayPlugin { render_app .init_resource::>() .init_resource::>() - .init_resource::>>() + .init_resource::>>() .add_render_command::>() .add_system_to_stage(RenderStage::Extract, extract_screen_overlay) .add_system_to_stage(RenderStage::Prepare, prepare_screen_overlay) @@ -307,7 +308,12 @@ impl SpecializedMaterial for OverlayMaterial { }) } - fn specialize(_key: Self::Key, descriptor: &mut RenderPipelineDescriptor) { + fn specialize( + _pipeline: &MaterialPipeline, + descriptor: &mut RenderPipelineDescriptor, + key: Self::Key, + _layout: &MeshVertexBufferLayout, + ) -> Result<(), SpecializedMeshPipelineError> { descriptor.fragment.as_mut().unwrap().targets[0].blend = Some(BlendState { color: BlendComponent { src_factor: BlendFactor::One, @@ -319,7 +325,8 @@ impl SpecializedMaterial for OverlayMaterial { dst_factor: BlendFactor::One, operation: BlendOperation::Add, }, - }) + }); + Ok(()) } fn alpha_mode(_material: &::PreparedAsset) -> AlphaMode { @@ -447,8 +454,8 @@ fn prepare_overlay_phase( fn queue_material_meshes( draw_functions: Res>, material_pipeline: Res>, - mut pipelines: ResMut>>, - mut pipeline_cache: ResMut, + mut pipelines: ResMut>>, + mut pipeline_cache: ResMut, msaa: Res, render_meshes: Res>, render_materials: Res>, @@ -467,27 +474,29 @@ fn queue_material_meshes( if let Some(material) = render_materials.get(material) { let mut mesh_key = mesh_key; if let Some(mesh) = render_meshes.get(mesh) { - if mesh.has_tangents { - mesh_key |= MeshPipelineKey::VERTEX_TANGENTS; - } - mesh_key |= MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); + mesh_key |= MeshPipelineKey::from_primitive_topology(mesh.primitive_topology) + | MeshPipelineKey::TRANSPARENT_MAIN_PASS; + + let material_key = OverlayMaterial::key(material); + let pipeline_id = pipelines + .specialize( + &mut pipeline_cache, + &material_pipeline, + MaterialPipelineKey { + mesh_key, + material_key, + }, + &mesh.layout, + ) + .unwrap(); + + phase.add(Overlay { + distance: 0.0, + entity, + pipeline: pipeline_id, + draw_function, + }); } - - mesh_key |= MeshPipelineKey::TRANSPARENT_MAIN_PASS; - - let specialized_key = OverlayMaterial::key(material); - let pipeline_id = pipelines.specialize( - &mut pipeline_cache, - &material_pipeline, - (mesh_key, specialized_key), - ); - - phase.add(Overlay { - distance: 0.0, - entity, - pipeline: pipeline_id, - draw_function, - }); } } } @@ -496,7 +505,7 @@ fn queue_material_meshes( pub struct Overlay { distance: f32, entity: Entity, - pipeline: CachedPipelineId, + pipeline: CachedRenderPipelineId, draw_function: DrawFunctionId, } @@ -518,8 +527,8 @@ impl EntityPhaseItem for Overlay { } } -impl CachedPipelinePhaseItem for Overlay { - fn cached_pipeline(&self) -> CachedPipelineId { +impl CachedRenderPipelinePhaseItem for Overlay { + fn cached_pipeline(&self) -> CachedRenderPipelineId { self.pipeline } } diff --git a/src/tracing.rs b/src/tracing.rs index 7be6398..97e48af 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -12,10 +12,11 @@ use bevy::{ }, prelude::*, render::{ + mesh::MeshVertexBufferLayout, render_asset::RenderAssets, render_graph::{self, SlotInfo, SlotType}, render_phase::{ - sort_phase_system, AddRenderCommand, CachedPipelinePhaseItem, DrawFunctionId, + sort_phase_system, AddRenderCommand, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, EntityPhaseItem, EntityRenderCommand, PhaseItem, RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass, }, @@ -37,7 +38,7 @@ impl Plugin for TracingPlugin { render_app .init_resource::() .init_resource::() - .init_resource::>() + .init_resource::>() .init_resource::>>() .init_resource::>>() .init_resource::>>() @@ -164,13 +165,17 @@ pub struct TracingPipelineKey { pub ambient_occlusion: bool, } -impl SpecializedPipeline for TracingPipeline { +impl SpecializedMeshPipeline for TracingPipeline { type Key = (MeshPipelineKey, TracingPipelineKey); - fn specialize(&self, (mesh_key, tracing_key): Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + (mesh_key, tracing_key): Self::Key, + layout: &MeshVertexBufferLayout, + ) -> Result { let shader = TRACING_SHADER_HANDLE.typed::(); - let mut descriptor = self.mesh_pipeline.specialize(mesh_key); + let mut descriptor = self.mesh_pipeline.specialize(mesh_key, layout)?; let mut fragment = descriptor.fragment.as_mut().unwrap(); fragment.shader = shader; if tracing_key.not_receiver { @@ -199,7 +204,7 @@ impl SpecializedPipeline for TracingPipeline { self.tracing_layout.clone(), ]); - descriptor + Ok(descriptor) } } @@ -275,8 +280,8 @@ fn queue_tracing_meshes( )>, render_meshes: Res>, render_materials: Res>, - mut pipelines: ResMut>, - mut pipeline_cache: ResMut, + mut pipelines: ResMut>, + mut pipeline_cache: ResMut, msaa: Res, mut view_query: Query<( &ExtractedView, @@ -331,9 +336,6 @@ fn queue_tracing_meshes( let mesh_z = inverse_view_row_2.dot(mesh_uniform.transform.col(3)); let not_receiver = not_receiver.is_some(); - if mesh.has_tangents { - mesh_key |= MeshPipelineKey::VERTEX_TANGENTS; - } mesh_key |= MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); @@ -341,11 +343,14 @@ fn queue_tracing_meshes( not_receiver, ambient_occlusion: true, }; - let pipeline_id = pipelines.specialize( - &mut pipeline_cache, - &tracing_pipeline, - (mesh_key, tracing_key), - ); + let pipeline_id = pipelines + .specialize( + &mut pipeline_cache, + &tracing_pipeline, + (mesh_key, tracing_key), + &mesh.layout, + ) + .unwrap(); ambient_occlusion_phase.add(AmbientOcclusion { distance: -mesh_z, @@ -363,11 +368,14 @@ fn queue_tracing_meshes( not_receiver, ambient_occlusion: false, }; - let pipeline_id = pipelines.specialize( - &mut pipeline_cache, - &tracing_pipeline, - (mesh_key, tracing_key), - ); + let pipeline_id = pipelines + .specialize( + &mut pipeline_cache, + &tracing_pipeline, + (mesh_key, tracing_key), + &mesh.layout, + ) + .unwrap(); match alpha_mode { AlphaMode::Opaque => opaque_phase.add(Tracing(Opaque3d { @@ -451,11 +459,11 @@ pub fn queue_tracing_bind_groups( } } -pub struct Tracing(T); +pub struct Tracing(T); impl PhaseItem for Tracing where - T: PhaseItem + EntityPhaseItem + CachedPipelinePhaseItem, + T: PhaseItem + EntityPhaseItem + CachedRenderPipelinePhaseItem, { type SortKey = T::SortKey; @@ -470,18 +478,18 @@ where impl EntityPhaseItem for Tracing where - T: PhaseItem + EntityPhaseItem + CachedPipelinePhaseItem, + T: PhaseItem + EntityPhaseItem + CachedRenderPipelinePhaseItem, { fn entity(&self) -> Entity { self.0.entity() } } -impl CachedPipelinePhaseItem for Tracing +impl CachedRenderPipelinePhaseItem for Tracing where - T: PhaseItem + EntityPhaseItem + CachedPipelinePhaseItem, + T: PhaseItem + EntityPhaseItem + CachedRenderPipelinePhaseItem, { - fn cached_pipeline(&self) -> CachedPipelineId { + fn cached_pipeline(&self) -> CachedRenderPipelineId { self.0.cached_pipeline() } } @@ -489,7 +497,7 @@ where pub struct AmbientOcclusion { distance: f32, entity: Entity, - pipeline: CachedPipelineId, + pipeline: CachedRenderPipelineId, draw_function: DrawFunctionId, } @@ -511,8 +519,8 @@ impl EntityPhaseItem for AmbientOcclusion { } } -impl CachedPipelinePhaseItem for AmbientOcclusion { - fn cached_pipeline(&self) -> CachedPipelineId { +impl CachedRenderPipelinePhaseItem for AmbientOcclusion { + fn cached_pipeline(&self) -> CachedRenderPipelineId { self.pipeline } } @@ -536,7 +544,7 @@ impl EntityRenderCommand for SetTracingBindGroup { query: bevy::ecs::system::SystemParamItem<'w, '_, Self::Param>, pass: &mut bevy::render::render_phase::TrackedRenderPass<'w>, ) -> bevy::render::render_phase::RenderCommandResult { - let (volume_uniform_offset, bind_group) = query.get(view).unwrap(); + let (volume_uniform_offset, bind_group) = query.get_inner(view).unwrap(); pass.set_bind_group(I, &bind_group.value, &[volume_uniform_offset.offset]); RenderCommandResult::Success } diff --git a/src/voxel.rs b/src/voxel.rs index 7f4235b..ea1b1c7 100644 --- a/src/voxel.rs +++ b/src/voxel.rs @@ -17,11 +17,12 @@ use bevy::{ prelude::*, render::{ camera::CameraProjection, + mesh::MeshVertexBufferLayout, primitives::{Aabb, Frustum}, render_asset::RenderAssets, render_graph::{self, SlotInfo, SlotType}, render_phase::{ - AddRenderCommand, CachedPipelinePhaseItem, DrawFunctionId, DrawFunctions, + AddRenderCommand, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, EntityPhaseItem, EntityRenderCommand, PhaseItem, RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass, }, @@ -43,7 +44,7 @@ impl Plugin for VoxelPlugin { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { render_app .init_resource::() - .init_resource::>() + .init_resource::>() .init_resource::>() .add_system_to_stage(RenderStage::Extract, extract_views) .add_system_to_stage(RenderStage::Queue, queue_volume_view_bind_groups) @@ -182,7 +183,7 @@ impl FromWorld for VoxelPipeline { )), }); let mipmap_base_pipeline = - render_device.create_compute_pipeline(&ComputePipelineDescriptor { + render_device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { label: Some("mipmap_base_pipeline"), layout: Some(&mipmap_base_pipeline_layout), module: &shader, @@ -243,7 +244,7 @@ impl FromWorld for VoxelPipeline { let mipmap_pipelines = (0..6) .map(|direction| { - render_device.create_compute_pipeline(&ComputePipelineDescriptor { + render_device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { label: Some(&format!("mipmap_pipeline_{direction}")), layout: Some(&mipmap_pipeline_layout), module: &shader, @@ -252,19 +253,21 @@ impl FromWorld for VoxelPipeline { }) .collect(); - let clear_pipeline = render_device.create_compute_pipeline(&ComputePipelineDescriptor { - label: Some("clear_pipeline"), - layout: Some(&mipmap_pipeline_layout), - module: &shader, - entry_point: "clear", - }); + let clear_pipeline = + render_device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: Some("clear_pipeline"), + layout: Some(&mipmap_pipeline_layout), + module: &shader, + entry_point: "clear", + }); - let fill_pipeline = render_device.create_compute_pipeline(&ComputePipelineDescriptor { - label: Some("fill_pipeline"), - layout: Some(&mipmap_pipeline_layout), - module: &shader, - entry_point: "fill", - }); + let fill_pipeline = + render_device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: Some("fill_pipeline"), + layout: Some(&mipmap_pipeline_layout), + module: &shader, + entry_point: "fill", + }); Self { material_layout, @@ -280,13 +283,17 @@ impl FromWorld for VoxelPipeline { } } -impl SpecializedPipeline for VoxelPipeline { +impl SpecializedMeshPipeline for VoxelPipeline { type Key = MeshPipelineKey; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + key: Self::Key, + layout: &MeshVertexBufferLayout, + ) -> Result { let shader = VOXEL_SHADER_HANDLE.typed::(); - let mut descriptor = self.mesh_pipeline.specialize(key); + let mut descriptor = self.mesh_pipeline.specialize(key, layout)?; descriptor.fragment.as_mut().unwrap().shader = shader; descriptor.layout = Some(vec![ self.mesh_pipeline.view_layout.clone(), @@ -301,7 +308,7 @@ impl SpecializedPipeline for VoxelPipeline { ..Default::default() }; - descriptor + Ok(descriptor) } } @@ -352,9 +359,9 @@ fn check_visibility( (&mut VisibleEntities, &Frustum, Option<&RenderLayers>), With, >, - mut visible_entity_query: QuerySet<( - QueryState<&mut ComputedVisibility>, - QueryState< + mut visible_entity_query: ParamSet<( + Query<&mut ComputedVisibility>, + Query< ( Entity, &Visibility, @@ -368,7 +375,7 @@ fn check_visibility( )>, ) { // Reset the computed visibility to false - for mut computed_visibility in visible_entity_query.q0().iter_mut() { + for mut computed_visibility in visible_entity_query.p0().iter_mut() { computed_visibility.is_visible = false; } @@ -383,7 +390,7 @@ fn check_visibility( maybe_entity_mask, maybe_aabb, maybe_transform, - ) in visible_entity_query.q1().iter_mut() + ) in visible_entity_query.p1().iter_mut() { if !visibility.is_visible { continue; @@ -396,7 +403,7 @@ fn check_visibility( // If we have an aabb and transform, do frustum culling if let (Some(aabb), Some(transform)) = (maybe_aabb, maybe_transform) { - if !frustum.intersects_obb(aabb, &transform.compute_matrix()) { + if !frustum.intersects_obb(aabb, &transform.compute_matrix(), true) { continue; } } @@ -500,17 +507,11 @@ fn queue_volume_view_bind_groups( }, BindGroupEntry { binding: 7, - resource: view_cluster_bindings - .cluster_light_index_lists - .binding() - .unwrap(), + resource: view_cluster_bindings.light_index_lists_binding().unwrap(), }, BindGroupEntry { binding: 8, - resource: view_cluster_bindings - .cluster_offsets_and_counts - .binding() - .unwrap(), + resource: view_cluster_bindings.offsets_and_counts_binding().unwrap(), }, ], label: Some("mesh_view_bind_group"), @@ -579,8 +580,8 @@ pub fn queue_voxel_meshes( material_meshes: Query<(&Handle, &Handle)>, render_meshes: Res>, render_materials: Res>, - mut pipelines: ResMut>, - mut pipeline_cache: ResMut, + mut pipelines: ResMut>, + mut pipeline_cache: ResMut, volumes: Query<&Volume, Without>, config: Res, mut view_query: Query<(&VisibleEntities, &mut RenderPhase), With>, @@ -603,23 +604,20 @@ pub fn queue_voxel_meshes( continue; } - let mut key = MeshPipelineKey::empty(); if let Some(mesh) = render_meshes.get(mesh_handle) { - if mesh.has_tangents { - key |= MeshPipelineKey::VERTEX_TANGENTS; - } - key |= MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); - key |= MeshPipelineKey::from_msaa_samples(1); + let key = MeshPipelineKey::from_primitive_topology(mesh.primitive_topology) + | MeshPipelineKey::from_msaa_samples(1); + + let pipeline_id = pipelines + .specialize(&mut pipeline_cache, &voxel_pipeline, key, &mesh.layout) + .unwrap(); + phase.add(Voxel { + draw_function: draw_mesh, + pipeline: pipeline_id, + entity, + distance: 0.0, + }); } - - let pipeline_id = - pipelines.specialize(&mut pipeline_cache, &voxel_pipeline, key); - phase.add(Voxel { - draw_function: draw_mesh, - pipeline: pipeline_id, - entity, - distance: 0.0, - }); } } } @@ -745,7 +743,7 @@ pub fn queue_mipmap_bind_groups( pub struct Voxel { distance: f32, entity: Entity, - pipeline: CachedPipelineId, + pipeline: CachedRenderPipelineId, draw_function: DrawFunctionId, } @@ -767,8 +765,8 @@ impl EntityPhaseItem for Voxel { } } -impl CachedPipelinePhaseItem for Voxel { - fn cached_pipeline(&self) -> CachedPipelineId { +impl CachedRenderPipelinePhaseItem for Voxel { + fn cached_pipeline(&self) -> CachedRenderPipelineId { self.pipeline } } @@ -792,7 +790,7 @@ impl EntityRenderCommand for SetVoxelBindGroup { query: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let (volume_uniform_offset, bind_group) = query.get(view).unwrap(); + let (volume_uniform_offset, bind_group) = query.get_inner(view).unwrap(); pass.set_bind_group(I, &bind_group.value, &[volume_uniform_offset.offset]); RenderCommandResult::Success }