From 904718410bdac78ad8089f7f12baa9d303affac2 Mon Sep 17 00:00:00 2001 From: Brandon Dyer Date: Thu, 9 Mar 2023 19:50:33 -0600 Subject: [PATCH 1/4] Bevy 0.10 support --- Cargo.toml | 8 +-- bevy_atmosphere_macros/src/model.rs | 26 +++---- examples/cycle.rs | 2 +- examples/splitscreen.rs | 41 +++++------ src/pipeline.rs | 36 ++++------ src/plugin.rs | 13 ++-- src/shaders/nishita.wgsl | 18 ++--- src/skybox.rs | 6 +- src/system_param.rs | 107 +++++++++------------------- 9 files changed, 104 insertions(+), 153 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 83104e3..d2f105f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,13 +11,13 @@ repository = "https://github.com/JonahPlusPlus/bevy_atmosphere" exclude = ["/assets/", "/examples/", "/.github/"] [dependencies] -bevy = { version = "0.9", default-features = false, features = ["bevy_asset", "bevy_render", "bevy_pbr"] } -bevy_atmosphere_macros = { path = "bevy_atmosphere_macros", version = "0.1" } +bevy = {version = "0.10", default-features = false, features = ["bevy_asset", "bevy_render", "bevy_pbr"]} +bevy_atmosphere_macros = {path = "bevy_atmosphere_macros", version = "0.1"} cfg-if = "1.0" [dev-dependencies] -bevy_spectator = "0.1" -bevy = { version = "0.9", features = ["bevy_core_pipeline", "x11"] } # load all in case docs.rs complains +bevy_spectator = "0.2" +bevy = { version = "0.10", features = ["bevy_core_pipeline", "x11"] } # load all in case docs.rs complains [features] default = ["basic", "all_models"] diff --git a/bevy_atmosphere_macros/src/model.rs b/bevy_atmosphere_macros/src/model.rs index fdbebd3..8f75313 100644 --- a/bevy_atmosphere_macros/src/model.rs +++ b/bevy_atmosphere_macros/src/model.rs @@ -112,10 +112,7 @@ pub fn derive_atmospheric(ast: syn::DeriveInput) -> Result { } else if let Some(attr_ident) = attr.path.get_ident() { if attr_ident == EXTERNAL_ATTRIBUTE_NAME { if shader_path != ShaderPathType::None { - return Err(Error::new_spanned( - attr, - format!("Shader path already set") - )); + return Err(Error::new_spanned(attr, format!("Shader path already set"))); } let lit_str = get_shader_path_attr(attr)?; @@ -123,10 +120,7 @@ pub fn derive_atmospheric(ast: syn::DeriveInput) -> Result { shader_path = ShaderPathType::External(lit_str); } else if attr_ident == INTERNAL_ATTRIBUTE_NAME { if shader_path != ShaderPathType::None { - return Err(Error::new_spanned( - attr, - format!("Shader path already set") - )); + return Err(Error::new_spanned(attr, format!("Shader path already set"))); } let lit_str = get_shader_path_attr(attr)?; @@ -324,7 +318,6 @@ pub fn derive_atmospheric(ast: syn::DeriveInput) -> Result { } } - // Produce impls for fields with uniform bindings let struct_name = &ast.ident; let mut field_struct_impls = Vec::new(); @@ -413,7 +406,7 @@ pub fn derive_atmospheric(ast: syn::DeriveInput) -> Result { } } } - + let generics = ast.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); @@ -469,13 +462,14 @@ pub fn derive_atmospheric(ast: syn::DeriveInput) -> Result { let bind_group_layout = Self::bind_group_layout(render_device); let mut pipeline_cache = render_app.world.resource_mut::<#render_path::render_resource::PipelineCache>(); - + let pipeline = pipeline_cache.queue_compute_pipeline(#render_path::render_resource::ComputePipelineDescriptor { label: Some(Cow::from("bevy_atmosphere_compute_pipeline")), - layout: Some(vec![ + layout: vec![ bind_group_layout.clone(), image_bind_group_layout, - ]), + ], + push_constant_ranges: vec![], shader: handle, shader_defs: vec![], entry_point: Cow::from("main"), @@ -495,7 +489,7 @@ pub fn derive_atmospheric(ast: syn::DeriveInput) -> Result { let mut registration = type_registry.get_mut(std::any::TypeId::of::()).expect("Type not registered"); registration.insert(data); - } + } } fn bind_group_layout(render_device: &#render_path::renderer::RenderDevice) -> #render_path::render_resource::BindGroupLayout { @@ -538,7 +532,7 @@ struct BindingIndexOptions { /// Represents the arguments for the `external` and `internal` binding attributes struct ShaderPathMeta { - lit_str: syn::LitStr + lit_str: syn::LitStr, } impl Parse for BindingMeta { @@ -574,7 +568,7 @@ impl Parse for UniformBindingMeta { impl Parse for ShaderPathMeta { fn parse(input: ParseStream) -> Result { Ok(Self { - lit_str: input.parse()? + lit_str: input.parse()?, }) } } diff --git a/examples/cycle.rs b/examples/cycle.rs index e8a87b5..53300d3 100644 --- a/examples/cycle.rs +++ b/examples/cycle.rs @@ -4,7 +4,7 @@ use bevy_spectator::*; fn main() { App::new() - .insert_resource(Msaa { samples: 4 }) + .insert_resource(Msaa::Sample4) .insert_resource(AtmosphereModel::default()) // Default Atmosphere material, we can edit it to simulate another planet .insert_resource(CycleTimer(Timer::new( bevy::utils::Duration::from_millis(50), // Update our atmosphere every 50ms (in a real game, this would be much slower, but for the sake of an example we use a faster update) diff --git a/examples/splitscreen.rs b/examples/splitscreen.rs index 08dcbbd..5b7f88a 100644 --- a/examples/splitscreen.rs +++ b/examples/splitscreen.rs @@ -5,7 +5,7 @@ use bevy::{ core_pipeline::clear_color::ClearColorConfig, prelude::*, render::{camera::Viewport, view::RenderLayers}, - window::{WindowId, WindowResized}, + window::WindowResized, }; use bevy_atmosphere::prelude::*; use bevy_spectator::*; @@ -13,7 +13,7 @@ use bevy_spectator::*; fn main() { println!("Demonstrates using `AtmosphereCamera.render_layers` to have multiple skyboxes in the scene at once\n\t- E: Switch camera"); App::new() - .insert_resource(Msaa { samples: 4 }) + .insert_resource(Msaa::Sample4) .insert_resource(AtmosphereModel::new(Nishita { rayleigh_coefficient: Vec3::new(22.4e-6, 5.5e-6, 13.0e-6), // Change rayleigh coefficient to change color ..default() @@ -34,7 +34,10 @@ fn setup( ) { // Plane commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })), + mesh: meshes.add(Mesh::from(shape::Plane { + size: 100.0, + subdivisions: 0, + })), material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), ..default() }); @@ -74,7 +77,7 @@ fn setup( transform: Transform::from_xyz(100.0, 50.0, 150.0).looking_at(Vec3::ZERO, Vec3::Y), camera: Camera { // Renders the right camera after the left camera, which has a default priority of 0 - priority: 1, + order: 1, ..default() }, camera_3d: Camera3d { @@ -100,7 +103,7 @@ struct LeftCamera; struct RightCamera; fn set_camera_viewports( - windows: Res, + windows: Query<&Window>, mut resize_events: EventReader, mut left_camera: Query<&mut Camera, (With, Without)>, mut right_camera: Query<&mut Camera, With>, @@ -109,22 +112,20 @@ fn set_camera_viewports( // so then each camera always takes up half the screen. // A resize_event is sent when the window is first created, allowing us to reuse this system for initial setup. for resize_event in resize_events.iter() { - if resize_event.id == WindowId::primary() { - let window = windows.primary(); - let mut left_camera = left_camera.single_mut(); - left_camera.viewport = Some(Viewport { - physical_position: UVec2::new(0, 0), - physical_size: UVec2::new(window.physical_width() / 2, window.physical_height()), - ..default() - }); + let window = windows.get(resize_event.window).unwrap(); + let mut left_camera = left_camera.single_mut(); + left_camera.viewport = Some(Viewport { + physical_position: UVec2::new(0, 0), + physical_size: UVec2::new(window.physical_width() / 2, window.physical_height()), + ..default() + }); - let mut right_camera = right_camera.single_mut(); - right_camera.viewport = Some(Viewport { - physical_position: UVec2::new(window.physical_width() / 2, 0), - physical_size: UVec2::new(window.physical_width() / 2, window.physical_height()), - ..default() - }); - } + let mut right_camera = right_camera.single_mut(); + right_camera.viewport = Some(Viewport { + physical_position: UVec2::new(window.physical_width() / 2, 0), + physical_size: UVec2::new(window.physical_width() / 2, window.physical_height()), + ..default() + }); } } diff --git a/src/pipeline.rs b/src/pipeline.rs index 3ddc2c4..9ec9d14 100644 --- a/src/pipeline.rs +++ b/src/pipeline.rs @@ -8,7 +8,7 @@ use bevy::{ prelude::*, render::{ extract_resource::{ExtractResource, ExtractResourcePlugin}, - render_asset::{PrepareAssetLabel, RenderAssets}, + render_asset::{PrepareAssetSet, RenderAssets}, render_graph::{self, RenderGraph}, render_resource::{ BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, @@ -19,7 +19,7 @@ use bevy::{ }, renderer::RenderDevice, texture::FallbackImage, - Extract, RenderApp, RenderStage, + Extract, RenderApp, RenderSet, }, }; @@ -139,24 +139,18 @@ impl Plugin for AtmospherePipelinePlugin { .init_resource::() .init_resource::() .init_resource::>() - .add_system_to_stage(RenderStage::Extract, extract_atmosphere_resources) - .add_system_to_stage( - RenderStage::Prepare, - Events::::update_system, - ) - .add_system_to_stage( - RenderStage::Prepare, + .add_system(extract_atmosphere_resources.in_schedule(ExtractSchedule)) + .add_system(Events::::update_system.in_set(RenderSet::Prepare)) + .add_system( prepare_atmosphere_assets - .label(PrepareAssetLabel::PostAssetPrepare) - .after(PrepareAssetLabel::AssetPrepare), + .in_set(PrepareAssetSet::PostAssetPrepare) + .after(PrepareAssetSet::AssetPrepare), ) - .add_system_to_stage(RenderStage::Queue, queue_atmosphere_bind_group); + .add_system(queue_atmosphere_bind_group.in_set(RenderSet::Queue)); let mut render_graph = render_app.world.resource_mut::(); render_graph.add_node(NAME, AtmosphereNode::default()); - render_graph - .add_node_edge(NAME, bevy::render::main_graph::node::CAMERA_DRIVER) - .unwrap(); + render_graph.add_node_edge(NAME, bevy::render::main_graph::node::CAMERA_DRIVER); } } @@ -323,6 +317,7 @@ pub const ATMOSPHERE_IMAGE_TEXTURE_DESCRIPTOR: fn(u32) -> TextureDescriptor<'sta usage: TextureUsages::COPY_DST | TextureUsages::STORAGE_BINDING | TextureUsages::TEXTURE_BINDING, + view_formats: &[TextureFormat::Rgba16Float], }; /// Whenever settings changed, the texture view needs to be updated to use the new texture. @@ -504,12 +499,11 @@ impl render_graph::Node for AtmosphereNode { data.pipeline }; - let mut pass = - render_context - .command_encoder - .begin_compute_pass(&ComputePassDescriptor { - label: Some("atmosphere_pass"), - }); + let mut pass = render_context.command_encoder().begin_compute_pass( + &ComputePassDescriptor { + label: Some("atmosphere_pass"), + }, + ); pass.set_bind_group(0, &bind_groups.0, &[]); pass.set_bind_group(1, &bind_groups.1, &[]); diff --git a/src/plugin.rs b/src/plugin.rs index 15e6609..c0d3d32 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -57,11 +57,8 @@ impl Plugin for AtmospherePlugin { #[cfg(feature = "detection")] { - app.add_system_set_to_stage( - CoreStage::PostUpdate, - SystemSet::new() - .with_system(atmosphere_insert) - .with_system(atmosphere_remove), + app.add_systems( + (atmosphere_insert, atmosphere_remove).in_base_set(CoreSet::PostUpdate), ); } @@ -106,7 +103,7 @@ fn atmosphere_insert( commands .entity(camera) .insert(VisibilityBundle { - visibility: Visibility { is_visible: true }, + visibility: Visibility::Visible, ..default() }) .with_children(|c| { @@ -137,9 +134,9 @@ fn atmosphere_remove( mut commands: Commands, parents: Query<&Children>, atmosphere_skyboxes: Query>, - atmosphere_cameras: RemovedComponents, + mut atmosphere_cameras: RemovedComponents, ) { - for camera in &atmosphere_cameras { + for camera in atmosphere_cameras.iter() { #[cfg(feature = "bevy/trace")] trace!("Removing skybox from camera entity (ID:{:?})", camera); let Ok(children) = parents.get(camera) else { diff --git a/src/shaders/nishita.wgsl b/src/shaders/nishita.wgsl index fccebdb..6fcf0a0 100644 --- a/src/shaders/nishita.wgsl +++ b/src/shaders/nishita.wgsl @@ -12,9 +12,9 @@ struct Nishita { mie_direction: f32, } -let PI: f32 = 3.141592653589793; -let ISTEPS: u32 = 16u; -let JSTEPS: u32 = 8u; +const PI: f32 = 3.141592653589793; +const ISTEPS: u32 = 16u; +const JSTEPS: u32 = 8u; fn rsi(rd: vec3, r0: vec3, sr: f32) -> vec2 { // ray-sphere intersection that assumes @@ -42,7 +42,7 @@ fn render_nishita(r: vec3, r0: vec3, p_sun: vec3, i_sun: f32, r_p // Calculate the step size of the primary ray. var p = rsi(r, r0, r_atmos); - if (p.x > p.y) { return vec3(0f); } + if p.x > p.y { return vec3(0f); } p.y = min(p.y, rsi(r, r0, r_planet).x); let i_step_size = (p.y - p.x) / f32(ISTEPS); @@ -131,12 +131,12 @@ var image: texture_storage_2d_array; @compute @workgroup_size(8, 8, 1) fn main(@builtin(global_invocation_id) invocation_id: vec3, @builtin(num_workgroups) num_workgroups: vec3) { let size = textureDimensions(image).x; - let scale = f32(size)/2f; - - let dir = vec2((f32(invocation_id.x)/scale) - 1f, (f32(invocation_id.y)/scale) - 1f); + let scale = f32(size) / 2f; + + let dir = vec2((f32(invocation_id.x) / scale) - 1f, (f32(invocation_id.y) / scale) - 1f); var ray: vec3; - + switch invocation_id.z { case 0u { ray = vec3(1f, -dir.y, -dir.x); // +X @@ -159,7 +159,7 @@ fn main(@builtin(global_invocation_id) invocation_id: vec3, @builtin(num_wo } let render = render_nishita( - ray, + ray, nishita.ray_origin, nishita.sun_position, nishita.sun_intensity, diff --git a/src/skybox.rs b/src/skybox.rs index 7de1cc8..e7b8c38 100644 --- a/src/skybox.rs +++ b/src/skybox.rs @@ -6,7 +6,7 @@ use bevy::{ reflect::TypeUuid, render::{ mesh::{Indices, Mesh, MeshVertexBufferLayout, PrimitiveTopology}, - render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderRef}, + render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderDefVal, ShaderRef}, }, }; @@ -52,7 +52,9 @@ impl Material for SkyBoxMaterial { #[cfg(feature = "dithering")] if key.bind_group_data.dithering { if let Some(fragment) = &mut descriptor.fragment { - fragment.shader_defs.push(String::from("DITHER")); + fragment + .shader_defs + .push(ShaderDefVal::Bool(String::from("DITHER"), true)); } } diff --git a/src/system_param.rs b/src/system_param.rs index a1f4c52..f2560c4 100644 --- a/src/system_param.rs +++ b/src/system_param.rs @@ -1,14 +1,11 @@ //! Provides system params for easy reading/modifying of [`Atmospheric`] models. -use std::{ - marker::PhantomData, - ops::{Deref, DerefMut}, -}; +use std::ops::{Deref, DerefMut}; use bevy::{ - ecs::system::{ - ReadOnlySystemParamFetch, ResMutState, ResState, SystemMeta, SystemParam, SystemParamFetch, - SystemParamState, + ecs::{ + component::ComponentId, + system::{ReadOnlySystemParam, SystemMeta, SystemParam}, }, prelude::*, }; @@ -21,7 +18,7 @@ pub struct Atmosphere<'w, T: Atmospheric> { } // SAFETY: Res only reads a single World resource -unsafe impl ReadOnlySystemParamFetch for AtmosphereState {} +unsafe impl ReadOnlySystemParam for Atmosphere<'_, T> {} impl<'w, T: Atmospheric> Deref for Atmosphere<'w, T> { type Target = T; @@ -31,45 +28,28 @@ impl<'w, T: Atmospheric> Deref for Atmosphere<'w, T> { } } -#[doc(hidden)] -pub struct AtmosphereState { - res_state: ResState, - _marker: PhantomData, -} - -impl<'w, T: Atmospheric> SystemParam for Atmosphere<'w, T> { - type Fetch = AtmosphereState; -} +unsafe impl SystemParam for Atmosphere<'_, T> { + type State = ComponentId; + type Item<'w, 's> = Atmosphere<'w, T>; -// SAFETY: Atmosphere ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Atmosphere -// conflicts with any prior access, a panic will occur. -unsafe impl SystemParamState for AtmosphereState { - fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self { - Self { - res_state: ResState::init(world, system_meta), - _marker: PhantomData, - } + fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State { + Res::::init_state(world, system_meta) } -} - -impl<'w, 's, T: Atmospheric> SystemParamFetch<'w, 's> for AtmosphereState { - type Item = Atmosphere<'w, T>; #[inline] - unsafe fn get_param( - state: &'s mut Self, + unsafe fn get_param<'w, 's>( + state: &'s mut Self::State, system_meta: &SystemMeta, world: &'w World, change_tick: u32, - ) -> Self::Item { - let atmosphere_model = - < as SystemParam>::Fetch as SystemParamFetch>::get_param( - &mut state.res_state, - system_meta, - world, - change_tick, - ) - .into_inner(); + ) -> Self::Item<'w, 's> { + let atmosphere_model = as SystemParam>::get_param( + state, + system_meta, + world, + change_tick, + ) + .into_inner(); let value = atmosphere_model .to_ref::() .expect("Wrong type of `Atmospheric` model found"); @@ -96,45 +76,28 @@ impl<'w, T: Atmospheric> DerefMut for AtmosphereMut<'w, T> { } } -#[doc(hidden)] -pub struct AtmosphereMutState { - res_state: ResMutState, - _marker: PhantomData, -} - -impl<'w, T: Atmospheric> SystemParam for AtmosphereMut<'w, T> { - type Fetch = AtmosphereMutState; -} +unsafe impl SystemParam for AtmosphereMut<'_, T> { + type State = ComponentId; + type Item<'w, 's> = AtmosphereMut<'w, T>; -// SAFETY: Atmosphere ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Atmosphere -// conflicts with any prior access, a panic will occur. -unsafe impl SystemParamState for AtmosphereMutState { - fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self { - Self { - res_state: ResMutState::init(world, system_meta), - _marker: PhantomData, - } + fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State { + ResMut::::init_state(world, system_meta) } -} - -impl<'w, 's, T: Atmospheric> SystemParamFetch<'w, 's> for AtmosphereMutState { - type Item = AtmosphereMut<'w, T>; #[inline] - unsafe fn get_param( - state: &'s mut Self, + unsafe fn get_param<'w, 's>( + state: &'s mut Self::State, system_meta: &SystemMeta, world: &'w World, change_tick: u32, - ) -> Self::Item { - let atmosphere_model = - < as SystemParam>::Fetch as SystemParamFetch>::get_param( - &mut state.res_state, - system_meta, - world, - change_tick, - ) - .into_inner(); + ) -> Self::Item<'w, 's> { + let atmosphere_model = as SystemParam>::get_param( + state, + system_meta, + world, + change_tick, + ) + .into_inner(); let value = atmosphere_model .to_mut::() .expect("Wrong type of `Atmospheric` model found"); From 0937df00ee9ed9954cdb2bcda58cbd86434c7579 Mon Sep 17 00:00:00 2001 From: Brandon Dyer Date: Sat, 11 Mar 2023 08:52:28 -0600 Subject: [PATCH 2/4] Update examples/splitscreen.rs Co-authored-by: Hennadii Chernyshchyk --- examples/splitscreen.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/splitscreen.rs b/examples/splitscreen.rs index 5b7f88a..e016333 100644 --- a/examples/splitscreen.rs +++ b/examples/splitscreen.rs @@ -34,10 +34,7 @@ fn setup( ) { // Plane commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Plane { - size: 100.0, - subdivisions: 0, - })), + mesh: meshes.add(Mesh::from(shape::Plane::from_size(100.0))), material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), ..default() }); From d1742d63cadd943c2b814d2a2eae57dddae39db4 Mon Sep 17 00:00:00 2001 From: Brandon Dyer Date: Sat, 11 Mar 2023 08:52:55 -0600 Subject: [PATCH 3/4] Update src/plugin.rs Co-authored-by: Hennadii Chernyshchyk --- src/plugin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin.rs b/src/plugin.rs index c0d3d32..509e2ca 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -136,7 +136,7 @@ fn atmosphere_remove( atmosphere_skyboxes: Query>, mut atmosphere_cameras: RemovedComponents, ) { - for camera in atmosphere_cameras.iter() { + for camera in &mut atmosphere_cameras { #[cfg(feature = "bevy/trace")] trace!("Removing skybox from camera entity (ID:{:?})", camera); let Ok(children) = parents.get(camera) else { From c7c37eb55bae1246c3609aaeba299bc615dbc2fb Mon Sep 17 00:00:00 2001 From: Brandon Dyer Date: Sat, 11 Mar 2023 17:42:10 -0600 Subject: [PATCH 4/4] Added xml-rs exception to deny.toml --- deny.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deny.toml b/deny.toml index fa8f183..38aa23d 100644 --- a/deny.toml +++ b/deny.toml @@ -4,7 +4,8 @@ yanked = "deny" notice = "deny" ignore = [ "RUSTSEC-2020-0056", # ignore stdweb (from gilrs) - "RUSTSEC-2021-0139" # ignore ansi_term until there is a replacement + "RUSTSEC-2021-0139", # ignore ansi_term until there is a replacement + "RUSTSEC-2022-0048", # ignore xml-rs as it is needed by winit ] [licenses]