diff --git a/crates/bevy_core_pipeline/src/blit/mod.rs b/crates/bevy_core_pipeline/src/blit/mod.rs index 3cb17d0864db4..8fd57dc691ca7 100644 --- a/crates/bevy_core_pipeline/src/blit/mod.rs +++ b/crates/bevy_core_pipeline/src/blit/mod.rs @@ -77,14 +77,18 @@ pub struct BlitPipelineKey { impl SpecializedRenderPipeline for BlitPipeline { type Key = BlitPipelineKey; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + key: Self::Key, + shader_defs: Vec, + ) -> RenderPipelineDescriptor { RenderPipelineDescriptor { label: Some("blit pipeline".into()), layout: vec![self.texture_bind_group.clone()], - vertex: fullscreen_shader_vertex_state(), + vertex: fullscreen_shader_vertex_state(shader_defs.clone()), fragment: Some(FragmentState { shader: BLIT_SHADER_HANDLE.typed(), - shader_defs: vec![], + shader_defs, entry_point: "fs_main".into(), targets: vec![Some(ColorTargetState { format: key.texture_format, diff --git a/crates/bevy_core_pipeline/src/bloom/downsampling_pipeline.rs b/crates/bevy_core_pipeline/src/bloom/downsampling_pipeline.rs index 8c91065d5888e..91a4512b24642 100644 --- a/crates/bevy_core_pipeline/src/bloom/downsampling_pipeline.rs +++ b/crates/bevy_core_pipeline/src/bloom/downsampling_pipeline.rs @@ -99,7 +99,11 @@ impl FromWorld for BloomDownsamplingPipeline { impl SpecializedRenderPipeline for BloomDownsamplingPipeline { type Key = BloomDownsamplingPipelineKeys; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + key: Self::Key, + mut shader_defs: Vec, + ) -> RenderPipelineDescriptor { let layout = vec![self.bind_group_layout.clone()]; let entry_point = if key.first_downsample { @@ -108,8 +112,6 @@ impl SpecializedRenderPipeline for BloomDownsamplingPipeline { "downsample".into() }; - let mut shader_defs = vec![]; - if key.first_downsample { shader_defs.push("FIRST_DOWNSAMPLE".into()); } @@ -128,7 +130,7 @@ impl SpecializedRenderPipeline for BloomDownsamplingPipeline { .into(), ), layout, - vertex: fullscreen_shader_vertex_state(), + vertex: fullscreen_shader_vertex_state(shader_defs.clone()), fragment: Some(FragmentState { shader: BLOOM_SHADER_HANDLE.typed::(), shader_defs, diff --git a/crates/bevy_core_pipeline/src/bloom/upsampling_pipeline.rs b/crates/bevy_core_pipeline/src/bloom/upsampling_pipeline.rs index eadd7e269d5a2..59462b3fe2e63 100644 --- a/crates/bevy_core_pipeline/src/bloom/upsampling_pipeline.rs +++ b/crates/bevy_core_pipeline/src/bloom/upsampling_pipeline.rs @@ -74,7 +74,11 @@ impl FromWorld for BloomUpsamplingPipeline { impl SpecializedRenderPipeline for BloomUpsamplingPipeline { type Key = BloomUpsamplingPipelineKeys; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + key: Self::Key, + shader_defs: Vec, + ) -> RenderPipelineDescriptor { let texture_format = if key.final_pipeline { ViewTarget::TEXTURE_FORMAT_HDR } else { @@ -116,10 +120,10 @@ impl SpecializedRenderPipeline for BloomUpsamplingPipeline { RenderPipelineDescriptor { label: Some("bloom_upsampling_pipeline".into()), layout: vec![self.bind_group_layout.clone()], - vertex: fullscreen_shader_vertex_state(), + vertex: fullscreen_shader_vertex_state(shader_defs.clone()), fragment: Some(FragmentState { shader: BLOOM_SHADER_HANDLE.typed::(), - shader_defs: vec![], + shader_defs, entry_point: "upsample".into(), targets: vec![Some(ColorTargetState { format: texture_format, diff --git a/crates/bevy_core_pipeline/src/fullscreen_vertex_shader/mod.rs b/crates/bevy_core_pipeline/src/fullscreen_vertex_shader/mod.rs index 7227cfa3bc0cb..242e79189f96f 100644 --- a/crates/bevy_core_pipeline/src/fullscreen_vertex_shader/mod.rs +++ b/crates/bevy_core_pipeline/src/fullscreen_vertex_shader/mod.rs @@ -1,6 +1,9 @@ use bevy_asset::HandleUntyped; use bevy_reflect::TypeUuid; -use bevy_render::{prelude::Shader, render_resource::VertexState}; +use bevy_render::{ + prelude::Shader, + render_resource::{ShaderDefVal, VertexState}, +}; pub const FULLSCREEN_SHADER_HANDLE: HandleUntyped = HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 7837534426033940724); @@ -16,10 +19,10 @@ pub const FULLSCREEN_SHADER_HANDLE: HandleUntyped = /// ``` /// from the vertex shader. /// The draw call should render one triangle: `render_pass.draw(0..3, 0..1);` -pub fn fullscreen_shader_vertex_state() -> VertexState { +pub fn fullscreen_shader_vertex_state(shader_defs: Vec) -> VertexState { VertexState { shader: FULLSCREEN_SHADER_HANDLE.typed(), - shader_defs: Vec::new(), + shader_defs, entry_point: "fullscreen_vertex_shader".into(), buffers: Vec::new(), } diff --git a/crates/bevy_core_pipeline/src/fxaa/mod.rs b/crates/bevy_core_pipeline/src/fxaa/mod.rs index 6c4181d1f4350..aa10d9154f5af 100644 --- a/crates/bevy_core_pipeline/src/fxaa/mod.rs +++ b/crates/bevy_core_pipeline/src/fxaa/mod.rs @@ -177,17 +177,24 @@ pub struct FxaaPipelineKey { impl SpecializedRenderPipeline for FxaaPipeline { type Key = FxaaPipelineKey; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + key: Self::Key, + shader_defs: Vec, + ) -> RenderPipelineDescriptor { RenderPipelineDescriptor { label: Some("fxaa".into()), layout: vec![self.texture_bind_group.clone()], - vertex: fullscreen_shader_vertex_state(), + vertex: fullscreen_shader_vertex_state(shader_defs.clone()), fragment: Some(FragmentState { shader: FXAA_SHADER_HANDLE.typed(), - shader_defs: vec![ - format!("EDGE_THRESH_{}", key.edge_threshold.get_str()).into(), - format!("EDGE_THRESH_MIN_{}", key.edge_threshold_min.get_str()).into(), - ], + shader_defs: shader_defs + .into_iter() + .chain([ + format!("EDGE_THRESH_{}", key.edge_threshold.get_str()).into(), + format!("EDGE_THRESH_MIN_{}", key.edge_threshold_min.get_str()).into(), + ]) + .collect(), entry_point: "fragment".into(), targets: vec![Some(ColorTargetState { format: key.texture_format, diff --git a/crates/bevy_core_pipeline/src/tonemapping/mod.rs b/crates/bevy_core_pipeline/src/tonemapping/mod.rs index 31ecd12177d93..2a116916960bc 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/mod.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/mod.rs @@ -184,8 +184,11 @@ pub struct TonemappingPipelineKey { impl SpecializedRenderPipeline for TonemappingPipeline { type Key = TonemappingPipelineKey; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { - let mut shader_defs = Vec::new(); + fn specialize( + &self, + key: Self::Key, + mut shader_defs: Vec, + ) -> RenderPipelineDescriptor { if let DebandDither::Enabled = key.deband_dither { shader_defs.push("DEBAND_DITHER".into()); } @@ -208,7 +211,7 @@ impl SpecializedRenderPipeline for TonemappingPipeline { RenderPipelineDescriptor { label: Some("tonemapping pipeline".into()), layout: vec![self.texture_bind_group.clone()], - vertex: fullscreen_shader_vertex_state(), + vertex: fullscreen_shader_vertex_state(shader_defs.clone()), fragment: Some(FragmentState { shader: TONEMAPPING_SHADER_HANDLE.typed(), shader_defs, diff --git a/crates/bevy_gizmos/src/pipeline_2d.rs b/crates/bevy_gizmos/src/pipeline_2d.rs index f3ab5be25cba8..4a65b6f04f689 100644 --- a/crates/bevy_gizmos/src/pipeline_2d.rs +++ b/crates/bevy_gizmos/src/pipeline_2d.rs @@ -41,6 +41,7 @@ impl SpecializedMeshPipeline for GizmoLinePipeline { &self, key: Self::Key, layout: &MeshVertexBufferLayout, + shader_defs: Vec, ) -> Result { let vertex_buffer_layout = layout.get_layout(&[ Mesh::ATTRIBUTE_POSITION.at_shader_location(0), @@ -57,12 +58,12 @@ impl SpecializedMeshPipeline for GizmoLinePipeline { vertex: VertexState { shader: self.shader.clone_weak(), entry_point: "vertex".into(), - shader_defs: vec![], + shader_defs: shader_defs.clone(), buffers: vec![vertex_buffer_layout], }, fragment: Some(FragmentState { shader: self.shader.clone_weak(), - shader_defs: vec![], + shader_defs, entry_point: "fragment".into(), targets: vec![Some(ColorTargetState { format, diff --git a/crates/bevy_gizmos/src/pipeline_3d.rs b/crates/bevy_gizmos/src/pipeline_3d.rs index 6064a60a566de..f0fbc396c4bfe 100644 --- a/crates/bevy_gizmos/src/pipeline_3d.rs +++ b/crates/bevy_gizmos/src/pipeline_3d.rs @@ -45,8 +45,8 @@ impl SpecializedMeshPipeline for GizmoPipeline { &self, (depth_test, key): Self::Key, layout: &MeshVertexBufferLayout, + mut shader_defs: Vec, ) -> Result { - let mut shader_defs = Vec::new(); shader_defs.push("GIZMO_LINES_3D".into()); shader_defs.push(ShaderDefVal::Int( "MAX_DIRECTIONAL_LIGHTS".to_string(), diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index be28f2e13a5e9..8de03935cb847 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -29,8 +29,8 @@ use bevy_render::{ }, render_resource::{ AsBindGroup, AsBindGroupError, BindGroup, BindGroupLayout, OwnedBindingResource, - PipelineCache, RenderPipelineDescriptor, Shader, ShaderRef, SpecializedMeshPipeline, - SpecializedMeshPipelineError, SpecializedMeshPipelines, + PipelineCache, RenderPipelineDescriptor, Shader, ShaderDefVal, ShaderRef, + SpecializedMeshPipeline, SpecializedMeshPipelineError, SpecializedMeshPipelines, }, renderer::RenderDevice, texture::FallbackImage, @@ -292,8 +292,11 @@ where &self, key: Self::Key, layout: &MeshVertexBufferLayout, + shader_defs: Vec, ) -> Result { - let mut descriptor = self.mesh_pipeline.specialize(key.mesh_key, layout)?; + let mut descriptor = self + .mesh_pipeline + .specialize(key.mesh_key, layout, shader_defs)?; if let Some(vertex_shader) = &self.vertex_shader { descriptor.vertex.shader = vertex_shader.clone(); } diff --git a/crates/bevy_pbr/src/prepass/mod.rs b/crates/bevy_pbr/src/prepass/mod.rs index b2a50c5f37576..1e6d668acf868 100644 --- a/crates/bevy_pbr/src/prepass/mod.rs +++ b/crates/bevy_pbr/src/prepass/mod.rs @@ -230,9 +230,9 @@ where &self, key: Self::Key, layout: &MeshVertexBufferLayout, + mut shader_defs: Vec, ) -> Result { let mut bind_group_layout = vec![self.view_layout.clone()]; - let mut shader_defs = Vec::new(); let mut vertex_attributes = Vec::new(); // NOTE: Eventually, it would be nice to only add this when the shaders are overloaded by the Material. diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index a76ff0f470712..915c5b97aebe4 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -653,8 +653,8 @@ impl SpecializedMeshPipeline for MeshPipeline { &self, key: Self::Key, layout: &MeshVertexBufferLayout, + mut shader_defs: Vec, ) -> Result { - let mut shader_defs = Vec::new(); let mut vertex_attributes = Vec::new(); if layout.contains(Mesh::ATTRIBUTE_POSITION) { diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 7e885f9231558..5098e0b75a5e8 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -7,6 +7,7 @@ use bevy_ecs::{prelude::*, reflect::ReflectComponent}; use bevy_reflect::std_traits::ReflectDefault; use bevy_reflect::{Reflect, TypeUuid}; use bevy_render::extract_component::{ExtractComponent, ExtractComponentPlugin}; +use bevy_render::render_resource::ShaderDefVal; use bevy_render::Render; use bevy_render::{ extract_resource::{ExtractResource, ExtractResourcePlugin}, @@ -86,8 +87,9 @@ impl SpecializedMeshPipeline for WireframePipeline { &self, key: Self::Key, layout: &MeshVertexBufferLayout, + shader_defs: Vec, ) -> Result { - let mut descriptor = self.mesh_pipeline.specialize(key, layout)?; + let mut descriptor = self.mesh_pipeline.specialize(key, layout, shader_defs)?; descriptor.vertex.shader = self.shader.clone_weak(); descriptor.fragment.as_mut().unwrap().shader = self.shader.clone_weak(); descriptor.primitive.polygon_mode = PolygonMode::Line; diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index 783d35abb2c78..19a2b3f4eab17 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -193,25 +193,13 @@ impl ShaderCache { let module = match data.processed_shaders.entry(shader_defs.to_vec()) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { - let mut shader_defs = shader_defs.to_vec(); - #[cfg(feature = "webgl")] - { - shader_defs.push("NO_ARRAY_TEXTURES_SUPPORT".into()); - shader_defs.push("SIXTEEN_BYTE_ALIGNMENT".into()); - } - - shader_defs.push(ShaderDefVal::UInt( - String::from("AVAILABLE_STORAGE_BUFFER_BINDINGS"), - render_device.limits().max_storage_buffers_per_shader_stage, - )); - debug!( "processing shader {:?}, with shader defs {:?}", handle, shader_defs ); let processed = self.processor.process( shader, - &shader_defs, + shader_defs, &self.shaders, &self.import_path_shaders, )?; @@ -311,6 +299,7 @@ impl ShaderCache { } type LayoutCacheKey = (Vec, Vec); + #[derive(Default)] struct LayoutCache { layouts: HashMap, @@ -362,6 +351,7 @@ pub struct PipelineCache { pipelines: Vec, waiting_pipelines: HashSet, new_pipelines: Mutex>, + base_shader_defs: Vec, } impl PipelineCache { @@ -369,8 +359,25 @@ impl PipelineCache { self.pipelines.iter() } + pub fn base_shader_defs(&self) -> Vec { + self.base_shader_defs.clone() + } + /// Create a new pipeline cache associated with the given render device. pub fn new(device: RenderDevice) -> Self { + let mut base_shader_defs = Vec::new(); + + #[cfg(feature = "webgl")] + { + base_shader_defs.push("NO_ARRAY_TEXTURES_SUPPORT".into()); + base_shader_defs.push("SIXTEEN_BYTE_ALIGNMENT".into()); + } + + base_shader_defs.push(ShaderDefVal::UInt( + String::from("AVAILABLE_STORAGE_BUFFER_BINDINGS"), + device.limits().max_storage_buffers_per_shader_stage, + )); + Self { device, layout_cache: default(), @@ -378,6 +385,7 @@ impl PipelineCache { waiting_pipelines: default(), new_pipelines: default(), pipelines: default(), + base_shader_defs, } } diff --git a/crates/bevy_render/src/render_resource/pipeline_specializer.rs b/crates/bevy_render/src/render_resource/pipeline_specializer.rs index eba7ccb8e409c..f632575ca5384 100644 --- a/crates/bevy_render/src/render_resource/pipeline_specializer.rs +++ b/crates/bevy_render/src/render_resource/pipeline_specializer.rs @@ -14,9 +14,15 @@ use bevy_utils::{ use std::{fmt::Debug, hash::Hash}; use thiserror::Error; +use super::ShaderDefVal; + pub trait SpecializedRenderPipeline { type Key: Clone + Hash + PartialEq + Eq; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor; + fn specialize( + &self, + key: Self::Key, + shader_defs: Vec, + ) -> RenderPipelineDescriptor; } #[derive(Resource)] @@ -38,7 +44,7 @@ impl SpecializedRenderPipelines { key: S::Key, ) -> CachedRenderPipelineId { *self.cache.entry(key.clone()).or_insert_with(|| { - let descriptor = specialize_pipeline.specialize(key); + let descriptor = specialize_pipeline.specialize(key, cache.base_shader_defs()); cache.queue_render_pipeline(descriptor) }) } @@ -46,7 +52,11 @@ impl SpecializedRenderPipelines { pub trait SpecializedComputePipeline { type Key: Clone + Hash + PartialEq + Eq; - fn specialize(&self, key: Self::Key) -> ComputePipelineDescriptor; + fn specialize( + &self, + key: Self::Key, + shader_defs: Vec, + ) -> ComputePipelineDescriptor; } #[derive(Resource)] @@ -68,7 +78,7 @@ impl SpecializedComputePipelines { key: S::Key, ) -> CachedComputePipelineId { *self.cache.entry(key.clone()).or_insert_with(|| { - let descriptor = specialize_pipeline.specialize(key); + let descriptor = specialize_pipeline.specialize(key, cache.base_shader_defs()); cache.queue_compute_pipeline(descriptor) }) } @@ -80,6 +90,7 @@ pub trait SpecializedMeshPipeline { &self, key: Self::Key, layout: &MeshVertexBufferLayout, + shader_defs: Vec, ) -> Result; } @@ -115,7 +126,7 @@ impl SpecializedMeshPipelines { Entry::Occupied(entry) => Ok(*entry.into_mut()), Entry::Vacant(entry) => { let descriptor = specialize_pipeline - .specialize(key.clone(), layout) + .specialize(key.clone(), layout, cache.base_shader_defs()) .map_err(|mut err| { { let SpecializedMeshPipelineError::MissingVertexAttribute(err) = diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index ed03db9a48484..56645aac82d5b 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -26,8 +26,8 @@ use bevy_render::{ }, render_resource::{ AsBindGroup, AsBindGroupError, BindGroup, BindGroupLayout, OwnedBindingResource, - PipelineCache, RenderPipelineDescriptor, Shader, ShaderRef, SpecializedMeshPipeline, - SpecializedMeshPipelineError, SpecializedMeshPipelines, + PipelineCache, RenderPipelineDescriptor, Shader, ShaderDefVal, ShaderRef, + SpecializedMeshPipeline, SpecializedMeshPipelineError, SpecializedMeshPipelines, }, renderer::RenderDevice, texture::FallbackImage, @@ -245,8 +245,11 @@ where &self, key: Self::Key, layout: &MeshVertexBufferLayout, + shader_defs: Vec, ) -> Result { - let mut descriptor = self.mesh2d_pipeline.specialize(key.mesh_key, layout)?; + let mut descriptor = self + .mesh2d_pipeline + .specialize(key.mesh_key, layout, shader_defs)?; if let Some(vertex_shader) = &self.vertex_shader { descriptor.vertex.shader = vertex_shader.clone(); } diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 070898df554e9..9ec6254b594f3 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -211,6 +211,7 @@ impl FromWorld for Mesh2dPipeline { }], label: Some("mesh2d_layout"), }); + // A 1x1x1 'all 1.0' texture to use as a dummy texture to use in place of optional StandardMaterial textures let dummy_white_gpu_image = { let image = Image::default(); @@ -256,6 +257,7 @@ impl FromWorld for Mesh2dPipeline { mip_level_count: image.texture_descriptor.mip_level_count, } }; + Mesh2dPipeline { view_layout, mesh_layout, @@ -361,8 +363,8 @@ impl SpecializedMeshPipeline for Mesh2dPipeline { &self, key: Self::Key, layout: &MeshVertexBufferLayout, + mut shader_defs: Vec, ) -> Result { - let mut shader_defs = Vec::new(); let mut vertex_attributes = Vec::new(); if layout.contains(Mesh::ATTRIBUTE_POSITION) { diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index 89d7cbbcce871..45231669893a5 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -205,7 +205,11 @@ impl SpritePipelineKey { impl SpecializedRenderPipeline for SpritePipeline { type Key = SpritePipelineKey; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + key: Self::Key, + mut shader_defs: Vec, + ) -> RenderPipelineDescriptor { let mut formats = vec![ // position VertexFormat::Float32x3, @@ -221,7 +225,6 @@ impl SpecializedRenderPipeline for SpritePipeline { let vertex_layout = VertexBufferLayout::from_vertex_formats(VertexStepMode::Vertex, formats); - let mut shader_defs = Vec::new(); if key.contains(SpritePipelineKey::COLORED) { shader_defs.push("COLORED".into()); } diff --git a/crates/bevy_ui/src/render/pipeline.rs b/crates/bevy_ui/src/render/pipeline.rs index 84cc74d11ebd7..132486b8b0dd2 100644 --- a/crates/bevy_ui/src/render/pipeline.rs +++ b/crates/bevy_ui/src/render/pipeline.rs @@ -67,7 +67,11 @@ pub struct UiPipelineKey { impl SpecializedRenderPipeline for UiPipeline { type Key = UiPipelineKey; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + key: Self::Key, + shader_defs: Vec, + ) -> RenderPipelineDescriptor { let vertex_layout = VertexBufferLayout::from_vertex_formats( VertexStepMode::Vertex, vec![ @@ -79,7 +83,6 @@ impl SpecializedRenderPipeline for UiPipeline { VertexFormat::Float32x4, ], ); - let shader_defs = Vec::new(); RenderPipelineDescriptor { vertex: VertexState { diff --git a/examples/2d/mesh2d_manual.rs b/examples/2d/mesh2d_manual.rs index 4e761edbfe4bb..c87cc3d0a1834 100644 --- a/examples/2d/mesh2d_manual.rs +++ b/examples/2d/mesh2d_manual.rs @@ -16,8 +16,9 @@ use bevy::{ render_resource::{ BlendState, ColorTargetState, ColorWrites, Face, FragmentState, FrontFace, MultisampleState, PipelineCache, PolygonMode, PrimitiveState, PrimitiveTopology, - RenderPipelineDescriptor, SpecializedRenderPipeline, SpecializedRenderPipelines, - TextureFormat, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, + RenderPipelineDescriptor, ShaderDefVal, SpecializedRenderPipeline, + SpecializedRenderPipelines, TextureFormat, VertexBufferLayout, VertexFormat, + VertexState, VertexStepMode, }, texture::BevyDefault, view::{ExtractedView, ViewTarget, VisibleEntities}, @@ -133,7 +134,11 @@ impl FromWorld for ColoredMesh2dPipeline { impl SpecializedRenderPipeline for ColoredMesh2dPipeline { type Key = Mesh2dPipelineKey; - fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + fn specialize( + &self, + key: Self::Key, + shader_defs: Vec, + ) -> RenderPipelineDescriptor { // Customize how to store the meshes' vertex attributes in the vertex buffer // Our meshes only have position and color let formats = vec![ @@ -156,14 +161,14 @@ impl SpecializedRenderPipeline for ColoredMesh2dPipeline { // Use our custom shader shader: COLORED_MESH2D_SHADER_HANDLE.typed::(), entry_point: "vertex".into(), - shader_defs: Vec::new(), + shader_defs: shader_defs.clone(), // Use our custom vertex buffer buffers: vec![vertex_layout], }, fragment: Some(FragmentState { // Use our custom shader shader: COLORED_MESH2D_SHADER_HANDLE.typed::(), - shader_defs: Vec::new(), + shader_defs, entry_point: "fragment".into(), targets: vec![Some(ColorTargetState { format, diff --git a/examples/shader/post_process_pass.rs b/examples/shader/post_process_pass.rs index 63d0627f42d14..d99d3c925351d 100644 --- a/examples/shader/post_process_pass.rs +++ b/examples/shader/post_process_pass.rs @@ -283,6 +283,8 @@ impl FromWorld for PostProcessPipeline { .resource::() .load("shaders/post_process_pass.wgsl"); + let shader_defs = world.resource::().base_shader_defs(); + let pipeline_id = world .resource_mut::() // This will add the pipeline to the cache and queue it's creation @@ -290,10 +292,10 @@ impl FromWorld for PostProcessPipeline { label: Some("post_process_pipeline".into()), layout: vec![layout.clone()], // This will setup a fullscreen triangle for the vertex state - vertex: fullscreen_shader_vertex_state(), + vertex: fullscreen_shader_vertex_state(shader_defs.clone()), fragment: Some(FragmentState { shader, - shader_defs: vec![], + shader_defs, // Make sure this matches the entry point of your shader. // It can be anything as long as it matches here and in the shader. entry_point: "fragment".into(), diff --git a/examples/shader/shader_instancing.rs b/examples/shader/shader_instancing.rs index dd533e32af711..775ce7588bfd7 100644 --- a/examples/shader/shader_instancing.rs +++ b/examples/shader/shader_instancing.rs @@ -190,8 +190,9 @@ impl SpecializedMeshPipeline for CustomPipeline { &self, key: Self::Key, layout: &MeshVertexBufferLayout, + shader_defs: Vec, ) -> Result { - let mut descriptor = self.mesh_pipeline.specialize(key, layout)?; + let mut descriptor = self.mesh_pipeline.specialize(key, layout, shader_defs)?; descriptor.vertex.shader = self.shader.clone(); descriptor.vertex.buffers.push(VertexBufferLayout { array_stride: std::mem::size_of::() as u64,