From b866bb4254726b5fc8400057c62a4c713f8215f8 Mon Sep 17 00:00:00 2001 From: andriyDev Date: Tue, 27 May 2025 15:32:47 -0700 Subject: [PATCH] Remove Shader weak_handles from bevy_pbr (excluding meshlets). (#19365) # Objective - Related to #19024 ## Solution - Use the new `load_shader_library` macro for the shader libraries and `embedded_asset`/`load_embedded_asset` for the "shader binaries" in `bevy_pbr` (excluding meshlets). ## Testing - `atmosphere` example still works - `fog` example still works - `decal` example still works P.S. I don't think this needs a migration guide. Technically users could be using the `pub` weak handles, but there's no actual good use for them, so omitting it seems fine. Alternatively, we could mix this in with the migration guide notes for #19137. --- crates/bevy_pbr/src/atmosphere/mod.rs | 78 +++------------ crates/bevy_pbr/src/atmosphere/resources.rs | 15 +-- crates/bevy_pbr/src/decal/clustered.rs | 16 +-- crates/bevy_pbr/src/decal/forward.rs | 15 +-- .../src/light_probe/environment_map.rs | 10 +- .../src/light_probe/irradiance_volume.rs | 9 +- crates/bevy_pbr/src/light_probe/mod.rs | 36 ++----- crates/bevy_pbr/src/lightmap/mod.rs | 16 +-- crates/bevy_pbr/src/prepass/mod.rs | 55 +++-------- crates/bevy_pbr/src/render/fog.rs | 9 +- crates/bevy_pbr/src/render/gpu_preprocess.rs | 60 ++++++------ crates/bevy_pbr/src/render/mesh.rs | 98 +++++++------------ crates/bevy_pbr/src/ssao/mod.rs | 45 +++------ crates/bevy_pbr/src/ssr/mod.rs | 22 ++--- crates/bevy_pbr/src/volumetric_fog/mod.rs | 12 +-- crates/bevy_pbr/src/volumetric_fog/render.rs | 14 +-- crates/bevy_pbr/src/wireframe.rs | 14 +-- 17 files changed, 158 insertions(+), 366 deletions(-) diff --git a/crates/bevy_pbr/src/atmosphere/mod.rs b/crates/bevy_pbr/src/atmosphere/mod.rs index 12a1f381db..8b08751428 100644 --- a/crates/bevy_pbr/src/atmosphere/mod.rs +++ b/crates/bevy_pbr/src/atmosphere/mod.rs @@ -37,7 +37,7 @@ mod node; pub mod resources; use bevy_app::{App, Plugin}; -use bevy_asset::load_internal_asset; +use bevy_asset::embedded_asset; use bevy_core_pipeline::core_3d::graph::Node3d; use bevy_ecs::{ component::Component, @@ -49,13 +49,14 @@ use bevy_math::{UVec2, UVec3, Vec3}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ extract_component::UniformComponentPlugin, + load_shader_library, render_resource::{DownlevelFlags, ShaderType, SpecializedRenderPipelines}, view::Hdr, }; use bevy_render::{ extract_component::{ExtractComponent, ExtractComponentPlugin}, render_graph::{RenderGraphApp, ViewNodeRunner}, - render_resource::{Shader, TextureFormat, TextureUsages}, + render_resource::{TextureFormat, TextureUsages}, renderer::RenderAdapter, Render, RenderApp, RenderSystems, }; @@ -75,76 +76,21 @@ use self::{ }, }; -mod shaders { - use bevy_asset::{weak_handle, Handle}; - use bevy_render::render_resource::Shader; - - pub const TYPES: Handle = weak_handle!("ef7e147e-30a0-4513-bae3-ddde2a6c20c5"); - pub const FUNCTIONS: Handle = weak_handle!("7ff93872-2ee9-4598-9f88-68b02fef605f"); - pub const BRUNETON_FUNCTIONS: Handle = - weak_handle!("e2dccbb0-7322-444a-983b-e74d0a08bcda"); - pub const BINDINGS: Handle = weak_handle!("bcc55ce5-0fc4-451e-8393-1b9efd2612c4"); - - pub const TRANSMITTANCE_LUT: Handle = - weak_handle!("a4187282-8cb1-42d3-889c-cbbfb6044183"); - pub const MULTISCATTERING_LUT: Handle = - weak_handle!("bde3a71a-73e9-49fe-a379-a81940c67a1e"); - pub const SKY_VIEW_LUT: Handle = weak_handle!("f87e007a-bf4b-4f99-9ef0-ac21d369f0e5"); - pub const AERIAL_VIEW_LUT: Handle = - weak_handle!("a3daf030-4b64-49ae-a6a7-354489597cbe"); - pub const RENDER_SKY: Handle = weak_handle!("09422f46-d0f7-41c1-be24-121c17d6e834"); -} - #[doc(hidden)] pub struct AtmospherePlugin; impl Plugin for AtmospherePlugin { fn build(&self, app: &mut App) { - load_internal_asset!(app, shaders::TYPES, "types.wgsl", Shader::from_wgsl); - load_internal_asset!(app, shaders::FUNCTIONS, "functions.wgsl", Shader::from_wgsl); - load_internal_asset!( - app, - shaders::BRUNETON_FUNCTIONS, - "bruneton_functions.wgsl", - Shader::from_wgsl - ); + load_shader_library!(app, "types.wgsl"); + load_shader_library!(app, "functions.wgsl"); + load_shader_library!(app, "bruneton_functions.wgsl"); + load_shader_library!(app, "bindings.wgsl"); - load_internal_asset!(app, shaders::BINDINGS, "bindings.wgsl", Shader::from_wgsl); - - load_internal_asset!( - app, - shaders::TRANSMITTANCE_LUT, - "transmittance_lut.wgsl", - Shader::from_wgsl - ); - - load_internal_asset!( - app, - shaders::MULTISCATTERING_LUT, - "multiscattering_lut.wgsl", - Shader::from_wgsl - ); - - load_internal_asset!( - app, - shaders::SKY_VIEW_LUT, - "sky_view_lut.wgsl", - Shader::from_wgsl - ); - - load_internal_asset!( - app, - shaders::AERIAL_VIEW_LUT, - "aerial_view_lut.wgsl", - Shader::from_wgsl - ); - - load_internal_asset!( - app, - shaders::RENDER_SKY, - "render_sky.wgsl", - Shader::from_wgsl - ); + embedded_asset!(app, "transmittance_lut.wgsl"); + embedded_asset!(app, "multiscattering_lut.wgsl"); + embedded_asset!(app, "sky_view_lut.wgsl"); + embedded_asset!(app, "aerial_view_lut.wgsl"); + embedded_asset!(app, "render_sky.wgsl"); app.register_type::() .register_type::() diff --git a/crates/bevy_pbr/src/atmosphere/resources.rs b/crates/bevy_pbr/src/atmosphere/resources.rs index 9f6e4801da..8c57fb8eb9 100644 --- a/crates/bevy_pbr/src/atmosphere/resources.rs +++ b/crates/bevy_pbr/src/atmosphere/resources.rs @@ -1,3 +1,4 @@ +use bevy_asset::{load_embedded_asset, Handle}; use bevy_core_pipeline::{ core_3d::Camera3d, fullscreen_vertex_shader::fullscreen_shader_vertex_state, }; @@ -21,7 +22,7 @@ use bevy_render::{ use crate::{GpuLights, LightMeta}; -use super::{shaders, Atmosphere, AtmosphereSettings}; +use super::{Atmosphere, AtmosphereSettings}; #[derive(Resource)] pub(crate) struct AtmosphereBindGroupLayouts { @@ -35,6 +36,7 @@ pub(crate) struct AtmosphereBindGroupLayouts { pub(crate) struct RenderSkyBindGroupLayouts { pub render_sky: BindGroupLayout, pub render_sky_msaa: BindGroupLayout, + pub shader: Handle, } impl FromWorld for AtmosphereBindGroupLayouts { @@ -203,6 +205,7 @@ impl FromWorld for RenderSkyBindGroupLayouts { Self { render_sky, render_sky_msaa, + shader: load_embedded_asset!(world, "render_sky.wgsl"), } } } @@ -273,7 +276,7 @@ impl FromWorld for AtmosphereLutPipelines { label: Some("transmittance_lut_pipeline".into()), layout: vec![layouts.transmittance_lut.clone()], push_constant_ranges: vec![], - shader: shaders::TRANSMITTANCE_LUT, + shader: load_embedded_asset!(world, "transmittance_lut.wgsl"), shader_defs: vec![], entry_point: "main".into(), zero_initialize_workgroup_memory: false, @@ -284,7 +287,7 @@ impl FromWorld for AtmosphereLutPipelines { label: Some("multi_scattering_lut_pipeline".into()), layout: vec![layouts.multiscattering_lut.clone()], push_constant_ranges: vec![], - shader: shaders::MULTISCATTERING_LUT, + shader: load_embedded_asset!(world, "multiscattering_lut.wgsl"), shader_defs: vec![], entry_point: "main".into(), zero_initialize_workgroup_memory: false, @@ -294,7 +297,7 @@ impl FromWorld for AtmosphereLutPipelines { label: Some("sky_view_lut_pipeline".into()), layout: vec![layouts.sky_view_lut.clone()], push_constant_ranges: vec![], - shader: shaders::SKY_VIEW_LUT, + shader: load_embedded_asset!(world, "sky_view_lut.wgsl"), shader_defs: vec![], entry_point: "main".into(), zero_initialize_workgroup_memory: false, @@ -304,7 +307,7 @@ impl FromWorld for AtmosphereLutPipelines { label: Some("aerial_view_lut_pipeline".into()), layout: vec![layouts.aerial_view_lut.clone()], push_constant_ranges: vec![], - shader: shaders::AERIAL_VIEW_LUT, + shader: load_embedded_asset!(world, "aerial_view_lut.wgsl"), shader_defs: vec![], entry_point: "main".into(), zero_initialize_workgroup_memory: false, @@ -365,7 +368,7 @@ impl SpecializedRenderPipeline for RenderSkyBindGroupLayouts { }, zero_initialize_workgroup_memory: false, fragment: Some(FragmentState { - shader: shaders::RENDER_SKY.clone(), + shader: self.shader.clone(), shader_defs, entry_point: "main".into(), targets: vec![Some(ColorTargetState { diff --git a/crates/bevy_pbr/src/decal/clustered.rs b/crates/bevy_pbr/src/decal/clustered.rs index cadcd1b871..dd77d2088d 100644 --- a/crates/bevy_pbr/src/decal/clustered.rs +++ b/crates/bevy_pbr/src/decal/clustered.rs @@ -17,7 +17,7 @@ use core::{num::NonZero, ops::Deref}; use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, weak_handle, AssetId, Handle}; +use bevy_asset::{AssetId, Handle}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ component::Component, @@ -34,10 +34,11 @@ use bevy_platform::collections::HashMap; use bevy_reflect::Reflect; use bevy_render::{ extract_component::{ExtractComponent, ExtractComponentPlugin}, + load_shader_library, render_asset::RenderAssets, render_resource::{ binding_types, BindGroupLayoutEntryBuilder, Buffer, BufferUsages, RawBufferVec, Sampler, - SamplerBindingType, Shader, ShaderType, TextureSampleType, TextureView, + SamplerBindingType, ShaderType, TextureSampleType, TextureView, }, renderer::{RenderAdapter, RenderDevice, RenderQueue}, sync_world::RenderEntity, @@ -52,10 +53,6 @@ use crate::{ binding_arrays_are_usable, prepare_lights, GlobalClusterableObjectMeta, LightVisibilityClass, }; -/// The handle to the `clustered.wgsl` shader. -pub(crate) const CLUSTERED_DECAL_SHADER_HANDLE: Handle = - weak_handle!("87929002-3509-42f1-8279-2d2765dd145c"); - /// The maximum number of decals that can be present in a view. /// /// This number is currently relatively low in order to work around the lack of @@ -152,12 +149,7 @@ impl Default for DecalsBuffer { impl Plugin for ClusteredDecalPlugin { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - CLUSTERED_DECAL_SHADER_HANDLE, - "clustered.wgsl", - Shader::from_wgsl - ); + load_shader_library!(app, "clustered.wgsl"); app.add_plugins(ExtractComponentPlugin::::default()) .register_type::(); diff --git a/crates/bevy_pbr/src/decal/forward.rs b/crates/bevy_pbr/src/decal/forward.rs index 2445c3e723..7d82946346 100644 --- a/crates/bevy_pbr/src/decal/forward.rs +++ b/crates/bevy_pbr/src/decal/forward.rs @@ -3,10 +3,11 @@ use crate::{ MaterialPlugin, StandardMaterial, }; use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, weak_handle, Asset, Assets, Handle}; +use bevy_asset::{weak_handle, Asset, Assets, Handle}; use bevy_ecs::component::Component; use bevy_math::{prelude::Rectangle, Quat, Vec2, Vec3}; use bevy_reflect::{Reflect, TypePath}; +use bevy_render::load_shader_library; use bevy_render::render_asset::RenderAssets; use bevy_render::render_resource::{AsBindGroupShaderType, ShaderType}; use bevy_render::texture::GpuImage; @@ -14,28 +15,20 @@ use bevy_render::{ alpha::AlphaMode, mesh::{Mesh, Mesh3d, MeshBuilder, MeshVertexBufferLayoutRef, Meshable}, render_resource::{ - AsBindGroup, CompareFunction, RenderPipelineDescriptor, Shader, - SpecializedMeshPipelineError, + AsBindGroup, CompareFunction, RenderPipelineDescriptor, SpecializedMeshPipelineError, }, RenderDebugFlags, }; const FORWARD_DECAL_MESH_HANDLE: Handle = weak_handle!("afa817f9-1869-4e0c-ac0d-d8cd1552d38a"); -const FORWARD_DECAL_SHADER_HANDLE: Handle = - weak_handle!("f8dfbef4-d88b-42ae-9af4-d9661e9f1648"); /// Plugin to render [`ForwardDecal`]s. pub struct ForwardDecalPlugin; impl Plugin for ForwardDecalPlugin { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - FORWARD_DECAL_SHADER_HANDLE, - "forward_decal.wgsl", - Shader::from_wgsl - ); + load_shader_library!(app, "forward_decal.wgsl"); app.register_type::(); diff --git a/crates/bevy_pbr/src/light_probe/environment_map.rs b/crates/bevy_pbr/src/light_probe/environment_map.rs index 52ccaef432..b31801f757 100644 --- a/crates/bevy_pbr/src/light_probe/environment_map.rs +++ b/crates/bevy_pbr/src/light_probe/environment_map.rs @@ -44,7 +44,7 @@ //! //! [several pre-filtered environment maps]: https://github.com/KhronosGroup/glTF-Sample-Environments -use bevy_asset::{weak_handle, AssetId, Handle}; +use bevy_asset::{AssetId, Handle}; use bevy_ecs::{ component::Component, query::QueryItem, reflect::ReflectComponent, system::lifetimeless::Read, }; @@ -56,8 +56,8 @@ use bevy_render::{ render_asset::RenderAssets, render_resource::{ binding_types::{self, uniform_buffer}, - BindGroupLayoutEntryBuilder, Sampler, SamplerBindingType, Shader, ShaderStages, - TextureSampleType, TextureView, + BindGroupLayoutEntryBuilder, Sampler, SamplerBindingType, ShaderStages, TextureSampleType, + TextureView, }, renderer::{RenderAdapter, RenderDevice}, texture::{FallbackImage, GpuImage}, @@ -72,10 +72,6 @@ use crate::{ use super::{LightProbeComponent, RenderViewLightProbes}; -/// A handle to the environment map helper shader. -pub const ENVIRONMENT_MAP_SHADER_HANDLE: Handle = - weak_handle!("d38c4ec4-e84c-468f-b485-bf44745db937"); - /// A pair of cubemap textures that represent the surroundings of a specific /// area in space. /// diff --git a/crates/bevy_pbr/src/light_probe/irradiance_volume.rs b/crates/bevy_pbr/src/light_probe/irradiance_volume.rs index 05dd51c379..431d1245a2 100644 --- a/crates/bevy_pbr/src/light_probe/irradiance_volume.rs +++ b/crates/bevy_pbr/src/light_probe/irradiance_volume.rs @@ -137,8 +137,8 @@ use bevy_image::Image; use bevy_render::{ render_asset::RenderAssets, render_resource::{ - binding_types, BindGroupLayoutEntryBuilder, Sampler, SamplerBindingType, Shader, - TextureSampleType, TextureView, + binding_types, BindGroupLayoutEntryBuilder, Sampler, SamplerBindingType, TextureSampleType, + TextureView, }, renderer::{RenderAdapter, RenderDevice}, texture::{FallbackImage, GpuImage}, @@ -146,7 +146,7 @@ use bevy_render::{ use bevy_utils::default; use core::{num::NonZero, ops::Deref}; -use bevy_asset::{weak_handle, AssetId, Handle}; +use bevy_asset::{AssetId, Handle}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use crate::{ @@ -156,9 +156,6 @@ use crate::{ use super::LightProbeComponent; -pub const IRRADIANCE_VOLUME_SHADER_HANDLE: Handle = - weak_handle!("7fc7dcd8-3f90-4124-b093-be0e53e08205"); - /// On WebGL and WebGPU, we must disable irradiance volumes, as otherwise we can /// overflow the number of texture bindings when deferred rendering is in use /// (see issue #11885). diff --git a/crates/bevy_pbr/src/light_probe/mod.rs b/crates/bevy_pbr/src/light_probe/mod.rs index d7323a1e3c..74710ce1d5 100644 --- a/crates/bevy_pbr/src/light_probe/mod.rs +++ b/crates/bevy_pbr/src/light_probe/mod.rs @@ -1,7 +1,7 @@ //! Light probes for baked global illumination. use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, weak_handle, AssetId, Handle}; +use bevy_asset::AssetId; use bevy_core_pipeline::core_3d::Camera3d; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ @@ -19,9 +19,10 @@ use bevy_platform::collections::HashMap; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ extract_instances::ExtractInstancesPlugin, + load_shader_library, primitives::{Aabb, Frustum}, render_asset::RenderAssets, - render_resource::{DynamicUniformBuffer, Sampler, Shader, ShaderType, TextureView}, + render_resource::{DynamicUniformBuffer, Sampler, ShaderType, TextureView}, renderer::{RenderAdapter, RenderDevice, RenderQueue}, settings::WgpuFeatures, sync_world::RenderEntity, @@ -34,18 +35,10 @@ use tracing::error; use core::{hash::Hash, ops::Deref}; -use crate::{ - irradiance_volume::IRRADIANCE_VOLUME_SHADER_HANDLE, - light_probe::environment_map::{ - EnvironmentMapIds, EnvironmentMapLight, ENVIRONMENT_MAP_SHADER_HANDLE, - }, -}; +use crate::light_probe::environment_map::{EnvironmentMapIds, EnvironmentMapLight}; use self::irradiance_volume::IrradianceVolume; -pub const LIGHT_PROBE_SHADER_HANDLE: Handle = - weak_handle!("e80a2ae6-1c5a-4d9a-a852-d66ff0e6bf7f"); - pub mod environment_map; pub mod irradiance_volume; @@ -344,24 +337,9 @@ pub struct ViewEnvironmentMapUniformOffset(u32); impl Plugin for LightProbePlugin { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - LIGHT_PROBE_SHADER_HANDLE, - "light_probe.wgsl", - Shader::from_wgsl - ); - load_internal_asset!( - app, - ENVIRONMENT_MAP_SHADER_HANDLE, - "environment_map.wgsl", - Shader::from_wgsl - ); - load_internal_asset!( - app, - IRRADIANCE_VOLUME_SHADER_HANDLE, - "irradiance_volume.wgsl", - Shader::from_wgsl - ); + load_shader_library!(app, "light_probe.wgsl"); + load_shader_library!(app, "environment_map.wgsl"); + load_shader_library!(app, "irradiance_volume.wgsl"); app.register_type::() .register_type::() diff --git a/crates/bevy_pbr/src/lightmap/mod.rs b/crates/bevy_pbr/src/lightmap/mod.rs index 5ddb1d6c72..cb7aecc2cb 100644 --- a/crates/bevy_pbr/src/lightmap/mod.rs +++ b/crates/bevy_pbr/src/lightmap/mod.rs @@ -32,7 +32,7 @@ //! [`bevy-baked-gi`]: https://github.com/pcwalton/bevy-baked-gi use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, weak_handle, AssetId, Handle}; +use bevy_asset::{AssetId, Handle}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ component::Component, @@ -50,8 +50,9 @@ use bevy_math::{uvec2, vec4, Rect, UVec2}; use bevy_platform::collections::HashSet; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ + load_shader_library, render_asset::RenderAssets, - render_resource::{Sampler, Shader, TextureView, WgpuSampler, WgpuTextureView}, + render_resource::{Sampler, TextureView, WgpuSampler, WgpuTextureView}, renderer::RenderAdapter, sync_world::MainEntity, texture::{FallbackImage, GpuImage}, @@ -66,10 +67,6 @@ use tracing::error; use crate::{binding_arrays_are_usable, MeshExtractionSystems}; -/// The ID of the lightmap shader. -pub const LIGHTMAP_SHADER_HANDLE: Handle = - weak_handle!("fc28203f-f258-47f3-973c-ce7d1dd70e59"); - /// The number of lightmaps that we store in a single slab, if bindless textures /// are in use. /// @@ -188,12 +185,7 @@ pub struct LightmapSlotIndex(pub(crate) NonMaxU16); impl Plugin for LightmapPlugin { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - LIGHTMAP_SHADER_HANDLE, - "lightmap.wgsl", - Shader::from_wgsl - ); + load_shader_library!(app, "lightmap.wgsl"); } fn finish(&self, app: &mut App) { diff --git a/crates/bevy_pbr/src/prepass/mod.rs b/crates/bevy_pbr/src/prepass/mod.rs index 03a797eba1..35182910a9 100644 --- a/crates/bevy_pbr/src/prepass/mod.rs +++ b/crates/bevy_pbr/src/prepass/mod.rs @@ -13,6 +13,7 @@ use bevy_app::{App, Plugin, PreUpdate}; use bevy_render::{ alpha::AlphaMode, batching::gpu_preprocessing::GpuPreprocessingSupport, + load_shader_library, mesh::{allocator::MeshAllocator, Mesh3d, MeshVertexBufferLayoutRef, RenderMesh}, render_asset::prepare_assets, render_resource::binding_types::uniform_buffer, @@ -23,7 +24,7 @@ use bevy_render::{ }; pub use prepass_bindings::*; -use bevy_asset::{load_internal_asset, weak_handle, AssetServer, Handle}; +use bevy_asset::{embedded_asset, load_embedded_asset, AssetServer, Handle}; use bevy_core_pipeline::{ core_3d::CORE_3D_DEPTH_FORMAT, deferred::*, prelude::Camera3d, prepass::*, }; @@ -63,18 +64,6 @@ use bevy_render::view::RenderVisibleEntities; use bevy_render::RenderSystems::{PrepareAssets, PrepareResources}; use core::{hash::Hash, marker::PhantomData}; -pub const PREPASS_SHADER_HANDLE: Handle = - weak_handle!("ce810284-f1ae-4439-ab2e-0d6b204b6284"); - -pub const PREPASS_BINDINGS_SHADER_HANDLE: Handle = - weak_handle!("3e83537e-ae17-489c-a18a-999bc9c1d252"); - -pub const PREPASS_UTILS_SHADER_HANDLE: Handle = - weak_handle!("02e4643a-a14b-48eb-a339-0c47aeab0d7e"); - -pub const PREPASS_IO_SHADER_HANDLE: Handle = - weak_handle!("1c065187-c99b-4b7c-ba59-c1575482d2c9"); - /// Sets up everything required to use the prepass pipeline. /// /// This does not add the actual prepasses, see [`PrepassPlugin`] for that. @@ -91,33 +80,11 @@ where M::Data: PartialEq + Eq + Hash + Clone, { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - PREPASS_SHADER_HANDLE, - "prepass.wgsl", - Shader::from_wgsl - ); + embedded_asset!(app, "prepass.wgsl"); - load_internal_asset!( - app, - PREPASS_BINDINGS_SHADER_HANDLE, - "prepass_bindings.wgsl", - Shader::from_wgsl - ); - - load_internal_asset!( - app, - PREPASS_UTILS_SHADER_HANDLE, - "prepass_utils.wgsl", - Shader::from_wgsl - ); - - load_internal_asset!( - app, - PREPASS_IO_SHADER_HANDLE, - "prepass_io.wgsl", - Shader::from_wgsl - ); + load_shader_library!(app, "prepass_bindings.wgsl"); + load_shader_library!(app, "prepass_utils.wgsl"); + load_shader_library!(app, "prepass_io.wgsl"); let Some(render_app) = app.get_sub_app_mut(RenderApp) else { return; @@ -305,6 +272,7 @@ pub struct PrepassPipelineInternal { pub prepass_material_fragment_shader: Option>, pub deferred_material_vertex_shader: Option>, pub deferred_material_fragment_shader: Option>, + pub default_prepass_shader: Handle, /// Whether skins will use uniform buffers on account of storage buffers /// being unavailable on this platform. @@ -403,6 +371,7 @@ impl FromWorld for PrepassPipeline { ShaderRef::Handle(handle) => Some(handle), ShaderRef::Path(path) => Some(asset_server.load(path)), }, + default_prepass_shader: load_embedded_asset!(world, "prepass.wgsl"), material_layout: M::bind_group_layout(render_device), skins_use_uniform_buffers: skin::skins_use_uniform_buffers(render_device), depth_clip_control_supported, @@ -610,12 +579,12 @@ impl PrepassPipelineInternal { let frag_shader_handle = if mesh_key.contains(MeshPipelineKey::DEFERRED_PREPASS) { match self.deferred_material_fragment_shader.clone() { Some(frag_shader_handle) => frag_shader_handle, - _ => PREPASS_SHADER_HANDLE, + None => self.default_prepass_shader.clone(), } } else { match self.prepass_material_fragment_shader.clone() { Some(frag_shader_handle) => frag_shader_handle, - _ => PREPASS_SHADER_HANDLE, + None => self.default_prepass_shader.clone(), } }; @@ -632,12 +601,12 @@ impl PrepassPipelineInternal { if let Some(handle) = &self.deferred_material_vertex_shader { handle.clone() } else { - PREPASS_SHADER_HANDLE + self.default_prepass_shader.clone() } } else if let Some(handle) = &self.prepass_material_vertex_shader { handle.clone() } else { - PREPASS_SHADER_HANDLE + self.default_prepass_shader.clone() }; let descriptor = RenderPipelineDescriptor { vertex: VertexState { diff --git a/crates/bevy_pbr/src/render/fog.rs b/crates/bevy_pbr/src/render/fog.rs index 9d7fd0b18d..fa09120725 100644 --- a/crates/bevy_pbr/src/render/fog.rs +++ b/crates/bevy_pbr/src/render/fog.rs @@ -1,11 +1,11 @@ use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, weak_handle, Handle}; use bevy_color::{ColorToComponents, LinearRgba}; use bevy_ecs::prelude::*; use bevy_math::{Vec3, Vec4}; use bevy_render::{ extract_component::ExtractComponentPlugin, - render_resource::{DynamicUniformBuffer, Shader, ShaderType}, + load_shader_library, + render_resource::{DynamicUniformBuffer, ShaderType}, renderer::{RenderDevice, RenderQueue}, view::ExtractedView, Render, RenderApp, RenderSystems, @@ -126,15 +126,12 @@ pub struct ViewFogUniformOffset { pub offset: u32, } -/// Handle for the fog WGSL Shader internal asset -pub const FOG_SHADER_HANDLE: Handle = weak_handle!("e943f446-2856-471c-af5e-68dd276eec42"); - /// A plugin that consolidates fog extraction, preparation and related resources/assets pub struct FogPlugin; impl Plugin for FogPlugin { fn build(&self, app: &mut App) { - load_internal_asset!(app, FOG_SHADER_HANDLE, "fog.wgsl", Shader::from_wgsl); + load_shader_library!(app, "fog.wgsl"); app.register_type::(); app.add_plugins(ExtractComponentPlugin::::default()); diff --git a/crates/bevy_pbr/src/render/gpu_preprocess.rs b/crates/bevy_pbr/src/render/gpu_preprocess.rs index 5356c7580e..eaa7e857b7 100644 --- a/crates/bevy_pbr/src/render/gpu_preprocess.rs +++ b/crates/bevy_pbr/src/render/gpu_preprocess.rs @@ -9,7 +9,7 @@ use core::num::{NonZero, NonZeroU64}; use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, weak_handle, Handle}; +use bevy_asset::{embedded_asset, load_embedded_asset, Handle}; use bevy_core_pipeline::{ core_3d::graph::{Core3d, Node3d}, experimental::mip_generation::ViewDepthPyramid, @@ -63,16 +63,6 @@ use crate::{ use super::{ShadowView, ViewLightEntities}; -/// The handle to the `mesh_preprocess.wgsl` compute shader. -pub const MESH_PREPROCESS_SHADER_HANDLE: Handle = - weak_handle!("c8579292-cf92-43b5-9c5a-ec5bd4e44d12"); -/// The handle to the `reset_indirect_batch_sets.wgsl` compute shader. -pub const RESET_INDIRECT_BATCH_SETS_SHADER_HANDLE: Handle = - weak_handle!("045fb176-58e2-4e76-b241-7688d761bb23"); -/// The handle to the `build_indirect_params.wgsl` compute shader. -pub const BUILD_INDIRECT_PARAMS_SHADER_HANDLE: Handle = - weak_handle!("133b01f0-3eaf-4590-9ee9-f0cf91a00b71"); - /// The GPU workgroup size. const WORKGROUP_SIZE: usize = 64; @@ -255,6 +245,8 @@ pub struct PreprocessPhasePipelines { pub struct PreprocessPipeline { /// The bind group layout for the compute shader. pub bind_group_layout: BindGroupLayout, + /// The shader asset handle. + pub shader: Handle, /// The pipeline ID for the compute shader. /// /// This gets filled in `prepare_preprocess_pipelines`. @@ -269,6 +261,8 @@ pub struct PreprocessPipeline { pub struct ResetIndirectBatchSetsPipeline { /// The bind group layout for the compute shader. pub bind_group_layout: BindGroupLayout, + /// The shader asset handle. + pub shader: Handle, /// The pipeline ID for the compute shader. /// /// This gets filled in `prepare_preprocess_pipelines`. @@ -280,6 +274,8 @@ pub struct ResetIndirectBatchSetsPipeline { pub struct BuildIndirectParametersPipeline { /// The bind group layout for the compute shader. pub bind_group_layout: BindGroupLayout, + /// The shader asset handle. + pub shader: Handle, /// The pipeline ID for the compute shader. /// /// This gets filled in `prepare_preprocess_pipelines`. @@ -431,24 +427,9 @@ pub struct SkipGpuPreprocess; impl Plugin for GpuMeshPreprocessPlugin { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - MESH_PREPROCESS_SHADER_HANDLE, - "mesh_preprocess.wgsl", - Shader::from_wgsl - ); - load_internal_asset!( - app, - RESET_INDIRECT_BATCH_SETS_SHADER_HANDLE, - "reset_indirect_batch_sets.wgsl", - Shader::from_wgsl - ); - load_internal_asset!( - app, - BUILD_INDIRECT_PARAMS_SHADER_HANDLE, - "build_indirect_params.wgsl", - Shader::from_wgsl - ); + embedded_asset!(app, "mesh_preprocess.wgsl"); + embedded_asset!(app, "reset_indirect_batch_sets.wgsl"); + embedded_asset!(app, "build_indirect_params.wgsl"); } fn finish(&self, app: &mut App) { @@ -1292,7 +1273,7 @@ impl SpecializedComputePipeline for PreprocessPipeline { } else { vec![] }, - shader: MESH_PREPROCESS_SHADER_HANDLE, + shader: self.shader.clone(), shader_defs, entry_point: "main".into(), zero_initialize_workgroup_memory: false, @@ -1363,18 +1344,27 @@ impl FromWorld for PreprocessPipelines { &build_non_indexed_indirect_params_bind_group_layout_entries, ); + let preprocess_shader = load_embedded_asset!(world, "mesh_preprocess.wgsl"); + let reset_indirect_batch_sets_shader = + load_embedded_asset!(world, "reset_indirect_batch_sets.wgsl"); + let build_indirect_params_shader = + load_embedded_asset!(world, "build_indirect_params.wgsl"); + let preprocess_phase_pipelines = PreprocessPhasePipelines { reset_indirect_batch_sets: ResetIndirectBatchSetsPipeline { bind_group_layout: reset_indirect_batch_sets_bind_group_layout.clone(), + shader: reset_indirect_batch_sets_shader, pipeline_id: None, }, gpu_occlusion_culling_build_indexed_indirect_params: BuildIndirectParametersPipeline { bind_group_layout: build_indexed_indirect_params_bind_group_layout.clone(), + shader: build_indirect_params_shader.clone(), pipeline_id: None, }, gpu_occlusion_culling_build_non_indexed_indirect_params: BuildIndirectParametersPipeline { bind_group_layout: build_non_indexed_indirect_params_bind_group_layout.clone(), + shader: build_indirect_params_shader.clone(), pipeline_id: None, }, }; @@ -1382,27 +1372,33 @@ impl FromWorld for PreprocessPipelines { PreprocessPipelines { direct_preprocess: PreprocessPipeline { bind_group_layout: direct_bind_group_layout, + shader: preprocess_shader.clone(), pipeline_id: None, }, gpu_frustum_culling_preprocess: PreprocessPipeline { bind_group_layout: gpu_frustum_culling_bind_group_layout, + shader: preprocess_shader.clone(), pipeline_id: None, }, early_gpu_occlusion_culling_preprocess: PreprocessPipeline { bind_group_layout: gpu_early_occlusion_culling_bind_group_layout, + shader: preprocess_shader.clone(), pipeline_id: None, }, late_gpu_occlusion_culling_preprocess: PreprocessPipeline { bind_group_layout: gpu_late_occlusion_culling_bind_group_layout, + shader: preprocess_shader, pipeline_id: None, }, gpu_frustum_culling_build_indexed_indirect_params: BuildIndirectParametersPipeline { bind_group_layout: build_indexed_indirect_params_bind_group_layout.clone(), + shader: build_indirect_params_shader.clone(), pipeline_id: None, }, gpu_frustum_culling_build_non_indexed_indirect_params: BuildIndirectParametersPipeline { bind_group_layout: build_non_indexed_indirect_params_bind_group_layout.clone(), + shader: build_indirect_params_shader, pipeline_id: None, }, early_phase: preprocess_phase_pipelines.clone(), @@ -1642,7 +1638,7 @@ impl SpecializedComputePipeline for ResetIndirectBatchSetsPipeline { label: Some("reset indirect batch sets".into()), layout: vec![self.bind_group_layout.clone()], push_constant_ranges: vec![], - shader: RESET_INDIRECT_BATCH_SETS_SHADER_HANDLE, + shader: self.shader.clone(), shader_defs: vec![], entry_point: "main".into(), zero_initialize_workgroup_memory: false, @@ -1696,7 +1692,7 @@ impl SpecializedComputePipeline for BuildIndirectParametersPipeline { label: Some(label.into()), layout: vec![self.bind_group_layout.clone()], push_constant_ranges: vec![], - shader: BUILD_INDIRECT_PARAMS_SHADER_HANDLE, + shader: self.shader.clone(), shader_defs, entry_point: "main".into(), zero_initialize_workgroup_memory: false, diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 4fc6252cab..8c408233e1 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -1,6 +1,6 @@ use crate::material_bind_groups::{MaterialBindGroupIndex, MaterialBindGroupSlot}; use allocator::MeshAllocator; -use bevy_asset::{load_internal_asset, weak_handle, AssetId}; +use bevy_asset::{embedded_asset, load_embedded_asset, AssetId}; use bevy_core_pipeline::{ core_3d::{AlphaMask3d, Opaque3d, Transmissive3d, Transparent3d, CORE_3D_DEPTH_FORMAT}, deferred::{AlphaMask3dDeferred, Opaque3dDeferred}, @@ -101,22 +101,6 @@ impl MeshRenderPlugin { } } -pub const FORWARD_IO_HANDLE: Handle = weak_handle!("38111de1-6e35-4dbb-877b-7b6f9334baf6"); -pub const MESH_VIEW_TYPES_HANDLE: Handle = - weak_handle!("979493db-4ae1-4003-b5c6-fcbb88b152a2"); -pub const MESH_VIEW_BINDINGS_HANDLE: Handle = - weak_handle!("c6fe674b-4c21-4d4b-867a-352848da5337"); -pub const MESH_TYPES_HANDLE: Handle = weak_handle!("a4a3fc2e-a57e-4083-a8ab-2840176927f2"); -pub const MESH_BINDINGS_HANDLE: Handle = - weak_handle!("84e7f9e6-e566-4a61-914e-c568f5dabf49"); -pub const MESH_FUNCTIONS_HANDLE: Handle = - weak_handle!("c46aa0f0-6c0c-4b3a-80bf-d8213c771f12"); -pub const MESH_SHADER_HANDLE: Handle = weak_handle!("1a7bbae8-4b4f-48a7-b53b-e6822e56f321"); -pub const SKINNING_HANDLE: Handle = weak_handle!("7474e812-2506-4cbf-9de3-fe07e5c6ff24"); -pub const MORPH_HANDLE: Handle = weak_handle!("da30aac7-34cc-431d-a07f-15b1a783008c"); -pub const OCCLUSION_CULLING_HANDLE: Handle = - weak_handle!("eaea07d9-7516-482c-aa42-6f8e9927e1f0"); - /// How many textures are allowed in the view bind group layout (`@group(0)`) before /// broader compatibility with WebGL and WebGPU is at risk, due to the minimum guaranteed /// values for `MAX_TEXTURE_IMAGE_UNITS` (in WebGL) and `maxSampledTexturesPerShaderStage` (in WebGPU), @@ -130,45 +114,28 @@ pub const MESH_PIPELINE_VIEW_LAYOUT_SAFE_MAX_TEXTURES: usize = 10; impl Plugin for MeshRenderPlugin { fn build(&self, app: &mut App) { - load_internal_asset!(app, FORWARD_IO_HANDLE, "forward_io.wgsl", Shader::from_wgsl); - load_internal_asset!( - app, - MESH_VIEW_TYPES_HANDLE, - "mesh_view_types.wgsl", - Shader::from_wgsl_with_defs, - vec![ - ShaderDefVal::UInt( - "MAX_DIRECTIONAL_LIGHTS".into(), - MAX_DIRECTIONAL_LIGHTS as u32 - ), - ShaderDefVal::UInt( - "MAX_CASCADES_PER_LIGHT".into(), - MAX_CASCADES_PER_LIGHT as u32, - ) - ] - ); - load_internal_asset!( - app, - MESH_VIEW_BINDINGS_HANDLE, - "mesh_view_bindings.wgsl", - Shader::from_wgsl - ); - load_internal_asset!(app, MESH_TYPES_HANDLE, "mesh_types.wgsl", Shader::from_wgsl); - load_internal_asset!( - app, - MESH_FUNCTIONS_HANDLE, - "mesh_functions.wgsl", - Shader::from_wgsl - ); - load_internal_asset!(app, MESH_SHADER_HANDLE, "mesh.wgsl", Shader::from_wgsl); - load_internal_asset!(app, SKINNING_HANDLE, "skinning.wgsl", Shader::from_wgsl); - load_internal_asset!(app, MORPH_HANDLE, "morph.wgsl", Shader::from_wgsl); - load_internal_asset!( - app, - OCCLUSION_CULLING_HANDLE, - "occlusion_culling.wgsl", - Shader::from_wgsl - ); + load_shader_library!(app, "forward_io.wgsl"); + load_shader_library!(app, "mesh_view_types.wgsl", |settings| *settings = + ShaderSettings { + shader_defs: vec![ + ShaderDefVal::UInt( + "MAX_DIRECTIONAL_LIGHTS".into(), + MAX_DIRECTIONAL_LIGHTS as u32 + ), + ShaderDefVal::UInt( + "MAX_CASCADES_PER_LIGHT".into(), + MAX_CASCADES_PER_LIGHT as u32, + ) + ] + }); + load_shader_library!(app, "mesh_view_bindings.wgsl"); + load_shader_library!(app, "mesh_types.wgsl"); + load_shader_library!(app, "mesh_functions.wgsl"); + load_shader_library!(app, "skinning.wgsl"); + load_shader_library!(app, "morph.wgsl"); + load_shader_library!(app, "occlusion_culling.wgsl"); + + embedded_asset!(app, "mesh.wgsl"); if app.get_sub_app(RenderApp).is_none() { return; @@ -310,13 +277,10 @@ impl Plugin for MeshRenderPlugin { // Load the mesh_bindings shader module here as it depends on runtime information about // whether storage buffers are supported, or the maximum uniform buffer binding size. - load_internal_asset!( - app, - MESH_BINDINGS_HANDLE, - "mesh_bindings.wgsl", - Shader::from_wgsl_with_defs, - mesh_bindings_shader_defs - ); + load_shader_library!(app, "mesh_bindings.wgsl", move |settings| *settings = + ShaderSettings { + shader_defs: mesh_bindings_shader_defs.clone(), + }); } } @@ -1787,6 +1751,8 @@ pub struct MeshPipeline { pub dummy_white_gpu_image: GpuImage, pub clustered_forward_buffer_binding_type: BufferBindingType, pub mesh_layouts: MeshLayouts, + /// The shader asset handle. + pub shader: Handle, /// `MeshUniform`s are stored in arrays in buffers. If storage buffers are available, they /// are used and this will be `None`, otherwise uniform buffers will be used with batches /// of this many `MeshUniform`s, stored at dynamic offsets within the uniform buffer. @@ -1816,6 +1782,7 @@ pub struct MeshPipeline { impl FromWorld for MeshPipeline { fn from_world(world: &mut World) -> Self { + let shader = load_embedded_asset!(world, "mesh.wgsl"); let mut system_state: SystemState<( Res, Res, @@ -1868,6 +1835,7 @@ impl FromWorld for MeshPipeline { clustered_forward_buffer_binding_type, dummy_white_gpu_image, mesh_layouts: MeshLayouts::new(&render_device, &render_adapter), + shader, per_object_buffer_batch_size: GpuArrayBuffer::::batch_size(&render_device), binding_arrays_are_usable: binding_arrays_are_usable(&render_device, &render_adapter), clustered_decals_are_usable: decal::clustered::clustered_decals_are_usable( @@ -2602,13 +2570,13 @@ impl SpecializedMeshPipeline for MeshPipeline { Ok(RenderPipelineDescriptor { vertex: VertexState { - shader: MESH_SHADER_HANDLE, + shader: self.shader.clone(), entry_point: "vertex".into(), shader_defs: shader_defs.clone(), buffers: vec![vertex_buffer_layout], }, fragment: Some(FragmentState { - shader: MESH_SHADER_HANDLE, + shader: self.shader.clone(), shader_defs, entry_point: "fragment".into(), targets: vec![Some(ColorTargetState { diff --git a/crates/bevy_pbr/src/ssao/mod.rs b/crates/bevy_pbr/src/ssao/mod.rs index 9224374c60..dc3ea865f2 100644 --- a/crates/bevy_pbr/src/ssao/mod.rs +++ b/crates/bevy_pbr/src/ssao/mod.rs @@ -1,6 +1,6 @@ use crate::NodePbr; use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, weak_handle, Handle}; +use bevy_asset::{embedded_asset, load_embedded_asset, Handle}; use bevy_core_pipeline::{ core_3d::graph::{Core3d, Node3d}, prelude::Camera3d, @@ -20,6 +20,7 @@ use bevy_render::{ camera::{ExtractedCamera, TemporalJitter}, extract_component::ExtractComponent, globals::{GlobalsBuffer, GlobalsUniform}, + load_shader_library, prelude::Camera, render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner}, render_resource::{ @@ -39,38 +40,16 @@ use bevy_utils::prelude::default; use core::mem; use tracing::{error, warn}; -const PREPROCESS_DEPTH_SHADER_HANDLE: Handle = - weak_handle!("b7f2cc3d-c935-4f5c-9ae2-43d6b0d5659a"); -const SSAO_SHADER_HANDLE: Handle = weak_handle!("9ea355d7-37a2-4cc4-b4d1-5d8ab47b07f5"); -const SPATIAL_DENOISE_SHADER_HANDLE: Handle = - weak_handle!("0f2764a0-b343-471b-b7ce-ef5d636f4fc3"); -const SSAO_UTILS_SHADER_HANDLE: Handle = - weak_handle!("da53c78d-f318-473e-bdff-b388bc50ada2"); - /// Plugin for screen space ambient occlusion. pub struct ScreenSpaceAmbientOcclusionPlugin; impl Plugin for ScreenSpaceAmbientOcclusionPlugin { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - PREPROCESS_DEPTH_SHADER_HANDLE, - "preprocess_depth.wgsl", - Shader::from_wgsl - ); - load_internal_asset!(app, SSAO_SHADER_HANDLE, "ssao.wgsl", Shader::from_wgsl); - load_internal_asset!( - app, - SPATIAL_DENOISE_SHADER_HANDLE, - "spatial_denoise.wgsl", - Shader::from_wgsl - ); - load_internal_asset!( - app, - SSAO_UTILS_SHADER_HANDLE, - "ssao_utils.wgsl", - Shader::from_wgsl - ); + load_shader_library!(app, "ssao_utils.wgsl"); + + embedded_asset!(app, "preprocess_depth.wgsl"); + embedded_asset!(app, "ssao.wgsl"); + embedded_asset!(app, "spatial_denoise.wgsl"); app.register_type::(); @@ -321,6 +300,8 @@ struct SsaoPipelines { hilbert_index_lut: TextureView, point_clamp_sampler: Sampler, linear_clamp_sampler: Sampler, + + shader: Handle, } impl FromWorld for SsaoPipelines { @@ -431,7 +412,7 @@ impl FromWorld for SsaoPipelines { common_bind_group_layout.clone(), ], push_constant_ranges: vec![], - shader: PREPROCESS_DEPTH_SHADER_HANDLE, + shader: load_embedded_asset!(world, "preprocess_depth.wgsl"), shader_defs: Vec::new(), entry_point: "preprocess_depth".into(), zero_initialize_workgroup_memory: false, @@ -445,7 +426,7 @@ impl FromWorld for SsaoPipelines { common_bind_group_layout.clone(), ], push_constant_ranges: vec![], - shader: SPATIAL_DENOISE_SHADER_HANDLE, + shader: load_embedded_asset!(world, "spatial_denoise.wgsl"), shader_defs: Vec::new(), entry_point: "spatial_denoise".into(), zero_initialize_workgroup_memory: false, @@ -463,6 +444,8 @@ impl FromWorld for SsaoPipelines { hilbert_index_lut, point_clamp_sampler, linear_clamp_sampler, + + shader: load_embedded_asset!(world, "ssao.wgsl"), } } } @@ -498,7 +481,7 @@ impl SpecializedComputePipeline for SsaoPipelines { self.common_bind_group_layout.clone(), ], push_constant_ranges: vec![], - shader: SSAO_SHADER_HANDLE, + shader: self.shader.clone(), shader_defs, entry_point: "ssao".into(), zero_initialize_workgroup_memory: false, diff --git a/crates/bevy_pbr/src/ssr/mod.rs b/crates/bevy_pbr/src/ssr/mod.rs index e4cc850d81..9f7dbb2f76 100644 --- a/crates/bevy_pbr/src/ssr/mod.rs +++ b/crates/bevy_pbr/src/ssr/mod.rs @@ -1,7 +1,7 @@ //! Screen space reflections implemented via raymarching. use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, weak_handle, Handle}; +use bevy_asset::{load_embedded_asset, Handle}; use bevy_core_pipeline::{ core_3d::{ graph::{Core3d, Node3d}, @@ -23,7 +23,6 @@ use bevy_ecs::{ }; use bevy_image::BevyDefault as _; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::render_graph::RenderGraph; use bevy_render::{ extract_component::{ExtractComponent, ExtractComponentPlugin}, render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner}, @@ -39,6 +38,7 @@ use bevy_render::{ view::{ExtractedView, Msaa, ViewTarget, ViewUniformOffset}, Render, RenderApp, RenderSystems, }; +use bevy_render::{load_shader_library, render_graph::RenderGraph}; use bevy_utils::{once, prelude::default}; use tracing::info; @@ -49,9 +49,6 @@ use crate::{ ViewLightsUniformOffset, }; -const SSR_SHADER_HANDLE: Handle = weak_handle!("0b559df2-0d61-4f53-bf62-aea16cf32787"); -const RAYMARCH_SHADER_HANDLE: Handle = weak_handle!("798cc6fc-6072-4b6c-ab4f-83905fa4a19e"); - /// Enables screen-space reflections for a camera. /// /// Screen-space reflections are currently only supported with deferred rendering. @@ -158,6 +155,7 @@ pub struct ScreenSpaceReflectionsPipeline { depth_nearest_sampler: Sampler, bind_group_layout: BindGroupLayout, binding_arrays_are_usable: bool, + shader: Handle, } /// A GPU buffer that stores the screen space reflection settings for each view. @@ -179,13 +177,8 @@ pub struct ScreenSpaceReflectionsPipelineKey { impl Plugin for ScreenSpaceReflectionsPlugin { fn build(&self, app: &mut App) { - load_internal_asset!(app, SSR_SHADER_HANDLE, "ssr.wgsl", Shader::from_wgsl); - load_internal_asset!( - app, - RAYMARCH_SHADER_HANDLE, - "raymarch.wgsl", - Shader::from_wgsl - ); + load_shader_library!(app, "ssr.wgsl"); + load_shader_library!(app, "raymarch.wgsl"); app.register_type::() .add_plugins(ExtractComponentPlugin::::default()); @@ -404,6 +397,9 @@ impl FromWorld for ScreenSpaceReflectionsPipeline { depth_nearest_sampler, bind_group_layout, binding_arrays_are_usable: binding_arrays_are_usable(render_device, render_adapter), + // Even though ssr was loaded using load_shader_library, we can still access it like a + // normal embedded asset (so we can use it as both a library or a kernel). + shader: load_embedded_asset!(world, "ssr.wgsl"), } } } @@ -542,7 +538,7 @@ impl SpecializedRenderPipeline for ScreenSpaceReflectionsPipeline { layout: vec![mesh_view_layout.clone(), self.bind_group_layout.clone()], vertex: fullscreen_vertex_shader::fullscreen_shader_vertex_state(), fragment: Some(FragmentState { - shader: SSR_SHADER_HANDLE, + shader: self.shader.clone(), shader_defs, entry_point: "fragment".into(), targets: vec![Some(ColorTargetState { diff --git a/crates/bevy_pbr/src/volumetric_fog/mod.rs b/crates/bevy_pbr/src/volumetric_fog/mod.rs index 4af1bbb421..efc3c5370a 100644 --- a/crates/bevy_pbr/src/volumetric_fog/mod.rs +++ b/crates/bevy_pbr/src/volumetric_fog/mod.rs @@ -30,7 +30,7 @@ //! [Henyey-Greenstein phase function]: https://www.pbr-book.org/4ed/Volume_Scattering/Phase_Functions#TheHenyeyndashGreensteinPhaseFunction use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, Assets, Handle}; +use bevy_asset::{embedded_asset, Assets, Handle}; use bevy_color::Color; use bevy_core_pipeline::core_3d::{ graph::{Core3d, Node3d}, @@ -48,7 +48,7 @@ use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ mesh::{Mesh, Meshable}, render_graph::{RenderGraphApp, ViewNodeRunner}, - render_resource::{Shader, SpecializedRenderPipelines}, + render_resource::SpecializedRenderPipelines, sync_component::SyncComponentPlugin, view::Visibility, ExtractSchedule, Render, RenderApp, RenderSystems, @@ -56,7 +56,6 @@ use bevy_render::{ use bevy_transform::components::Transform; use render::{ VolumetricFogNode, VolumetricFogPipeline, VolumetricFogUniformBuffer, CUBE_MESH, PLANE_MESH, - VOLUMETRIC_FOG_HANDLE, }; use crate::graph::NodePbr; @@ -189,12 +188,7 @@ pub struct FogVolume { impl Plugin for VolumetricFogPlugin { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - VOLUMETRIC_FOG_HANDLE, - "volumetric_fog.wgsl", - Shader::from_wgsl - ); + embedded_asset!(app, "volumetric_fog.wgsl"); let mut meshes = app.world_mut().resource_mut::>(); meshes.insert(&PLANE_MESH, Plane3d::new(Vec3::Z, Vec2::ONE).mesh().into()); diff --git a/crates/bevy_pbr/src/volumetric_fog/render.rs b/crates/bevy_pbr/src/volumetric_fog/render.rs index 07012a72e2..45f694e546 100644 --- a/crates/bevy_pbr/src/volumetric_fog/render.rs +++ b/crates/bevy_pbr/src/volumetric_fog/render.rs @@ -2,7 +2,7 @@ use core::array; -use bevy_asset::{weak_handle, AssetId, Handle}; +use bevy_asset::{load_embedded_asset, weak_handle, AssetId, Handle}; use bevy_color::ColorToComponents as _; use bevy_core_pipeline::{ core_3d::Camera3d, @@ -77,10 +77,6 @@ bitflags! { } } -/// The volumetric fog shader. -pub const VOLUMETRIC_FOG_HANDLE: Handle = - weak_handle!("481f474c-2024-44bb-8f79-f7c05ced95ea"); - /// The plane mesh, which is used to render a fog volume that the camera is /// inside. /// @@ -121,6 +117,9 @@ pub struct VolumetricFogPipeline { /// /// Since there aren't too many of these, we precompile them all. volumetric_view_bind_group_layouts: [BindGroupLayout; VOLUMETRIC_FOG_BIND_GROUP_LAYOUT_COUNT], + + // The shader asset handle. + shader: Handle, } /// The two render pipelines that we use for fog volumes: one for when a 3D @@ -266,6 +265,7 @@ impl FromWorld for VolumetricFogPipeline { VolumetricFogPipeline { mesh_view_layouts: mesh_view_layouts.clone(), volumetric_view_bind_group_layouts: bind_group_layouts, + shader: load_embedded_asset!(world, "volumetric_fog.wgsl"), } } } @@ -564,7 +564,7 @@ impl SpecializedRenderPipeline for VolumetricFogPipeline { layout: vec![mesh_view_layout.clone(), volumetric_view_bind_group_layout], push_constant_ranges: vec![], vertex: VertexState { - shader: VOLUMETRIC_FOG_HANDLE, + shader: self.shader.clone(), shader_defs: shader_defs.clone(), entry_point: "vertex".into(), buffers: vec![vertex_format], @@ -576,7 +576,7 @@ impl SpecializedRenderPipeline for VolumetricFogPipeline { depth_stencil: None, multisample: MultisampleState::default(), fragment: Some(FragmentState { - shader: VOLUMETRIC_FOG_HANDLE, + shader: self.shader.clone(), shader_defs, entry_point: "fragment".into(), targets: vec![Some(ColorTargetState { diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 7b748c2535..cc64ad2e4f 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -4,7 +4,7 @@ use crate::{ }; use bevy_app::{App, Plugin, PostUpdate, Startup, Update}; use bevy_asset::{ - load_internal_asset, prelude::AssetChanged, weak_handle, AsAssetId, Asset, AssetApp, + embedded_asset, load_embedded_asset, prelude::AssetChanged, AsAssetId, Asset, AssetApp, AssetEventSystems, AssetId, Assets, Handle, UntypedAssetId, }; use bevy_color::{Color, ColorToComponents}; @@ -56,9 +56,6 @@ use bevy_render::{ use core::{hash::Hash, ops::Range}; use tracing::error; -pub const WIREFRAME_SHADER_HANDLE: Handle = - weak_handle!("2646a633-f8e3-4380-87ae-b44d881abbce"); - /// A [`Plugin`] that draws wireframes. /// /// Wireframes currently do not work when using webgl or webgpu. @@ -83,12 +80,7 @@ impl WireframePlugin { impl Plugin for WireframePlugin { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - WIREFRAME_SHADER_HANDLE, - "render/wireframe.wgsl", - Shader::from_wgsl - ); + embedded_asset!(app, "render/wireframe.wgsl"); app.add_plugins(( BinnedRenderPhasePlugin::::new(self.debug_flags), @@ -341,7 +333,7 @@ impl FromWorld for Wireframe3dPipeline { fn from_world(render_world: &mut World) -> Self { Wireframe3dPipeline { mesh_pipeline: render_world.resource::().clone(), - shader: WIREFRAME_SHADER_HANDLE, + shader: load_embedded_asset!(render_world, "render/wireframe.wgsl"), } } }