mirror of
https://github.com/bevyengine/bevy
synced 2025-02-18 06:58:34 +00:00
render: move dynamic_bindings to PipelineSpecialization
This is a temporary step back in ergonomics as we are no longer automatically inferring dynamic bindings from RenderResourceBindings
This commit is contained in:
parent
0931fd0266
commit
74d0055a3d
9 changed files with 171 additions and 54 deletions
|
@ -1,14 +1,16 @@
|
||||||
use crate::{light::Light, material::StandardMaterial};
|
use crate::{light::Light, material::StandardMaterial, pipelines::FORWARD_PIPELINE_HANDLE};
|
||||||
use bevy_asset::Handle;
|
use bevy_asset::Handle;
|
||||||
use bevy_derive::EntityArchetype;
|
use bevy_derive::EntityArchetype;
|
||||||
use bevy_render::{draw::Draw, mesh::Mesh, pipeline::RenderPipelines};
|
use bevy_render::{
|
||||||
|
draw::Draw,
|
||||||
|
mesh::Mesh,
|
||||||
|
pipeline::{DynamicBinding, PipelineSpecialization, RenderPipeline, RenderPipelines},
|
||||||
|
};
|
||||||
use bevy_transform::prelude::{Rotation, Scale, Transform, Translation};
|
use bevy_transform::prelude::{Rotation, Scale, Transform, Translation};
|
||||||
|
|
||||||
#[derive(EntityArchetype, Default)]
|
#[derive(EntityArchetype)]
|
||||||
pub struct MeshEntity {
|
pub struct MeshEntity {
|
||||||
// #[tag]
|
|
||||||
pub mesh: Handle<Mesh>,
|
pub mesh: Handle<Mesh>,
|
||||||
// #[tag]
|
|
||||||
pub material: Handle<StandardMaterial>,
|
pub material: Handle<StandardMaterial>,
|
||||||
pub draw: Draw,
|
pub draw: Draw,
|
||||||
pub render_pipelines: RenderPipelines,
|
pub render_pipelines: RenderPipelines,
|
||||||
|
@ -18,6 +20,38 @@ pub struct MeshEntity {
|
||||||
pub scale: Scale,
|
pub scale: Scale,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for MeshEntity {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::specialized(
|
||||||
|
FORWARD_PIPELINE_HANDLE,
|
||||||
|
PipelineSpecialization {
|
||||||
|
dynamic_bindings: vec![
|
||||||
|
// Transform
|
||||||
|
DynamicBinding {
|
||||||
|
bind_group: 1,
|
||||||
|
binding: 0,
|
||||||
|
},
|
||||||
|
// StandardMaterial_albedo
|
||||||
|
DynamicBinding {
|
||||||
|
bind_group: 2,
|
||||||
|
binding: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)]),
|
||||||
|
mesh: Default::default(),
|
||||||
|
material: Default::default(),
|
||||||
|
draw: Default::default(),
|
||||||
|
transform: Default::default(),
|
||||||
|
translation: Default::default(),
|
||||||
|
rotation: Default::default(),
|
||||||
|
scale: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(EntityArchetype, Default)]
|
#[derive(EntityArchetype, Default)]
|
||||||
pub struct LightEntity {
|
pub struct LightEntity {
|
||||||
pub light: Light,
|
pub light: Light,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{material::StandardMaterial, nodes::LightsNode, pipelines::build_forward_pipeline};
|
use crate::{material::StandardMaterial, nodes::LightsNode, pipelines::{FORWARD_PIPELINE_HANDLE, build_forward_pipeline}};
|
||||||
use bevy_asset::Assets;
|
use bevy_asset::Assets;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
base_render_graph,
|
base_render_graph,
|
||||||
|
@ -36,7 +36,7 @@ impl ForwardPbrRenderGraphBuilder for RenderGraph {
|
||||||
self.add_system_node(node::LIGHTS, LightsNode::new(10));
|
self.add_system_node(node::LIGHTS, LightsNode::new(10));
|
||||||
let mut shaders = resources.get_mut::<Assets<Shader>>().unwrap();
|
let mut shaders = resources.get_mut::<Assets<Shader>>().unwrap();
|
||||||
let mut pipelines = resources.get_mut::<Assets<PipelineDescriptor>>().unwrap();
|
let mut pipelines = resources.get_mut::<Assets<PipelineDescriptor>>().unwrap();
|
||||||
pipelines.add_default(build_forward_pipeline(&mut shaders));
|
pipelines.set(FORWARD_PIPELINE_HANDLE, build_forward_pipeline(&mut shaders));
|
||||||
|
|
||||||
// TODO: replace these with "autowire" groups
|
// TODO: replace these with "autowire" groups
|
||||||
self.add_node_edge(node::STANDARD_MATERIAL, base_render_graph::node::MAIN_PASS)
|
self.add_node_edge(node::STANDARD_MATERIAL, base_render_graph::node::MAIN_PASS)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use bevy_asset::Assets;
|
use bevy_asset::{Handle, Assets};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{
|
pipeline::{
|
||||||
state_descriptors::{
|
state_descriptors::{
|
||||||
|
@ -12,6 +12,8 @@ use bevy_render::{
|
||||||
texture::TextureFormat,
|
texture::TextureFormat,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const FORWARD_PIPELINE_HANDLE: Handle<PipelineDescriptor> =
|
||||||
|
Handle::from_u128(131483623140127713893804825450360211204);
|
||||||
pub fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
pub fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
rasterization_state: Some(RasterizationStateDescriptor {
|
||||||
|
|
|
@ -4,10 +4,9 @@ use super::{
|
||||||
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
|
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
|
||||||
PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor,
|
PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor,
|
||||||
},
|
},
|
||||||
BindType, PipelineLayout, VertexBufferDescriptors,
|
BindType, DynamicBinding, PipelineLayout, VertexBufferDescriptors,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
render_resource::{RenderResourceBinding, RenderResourceBindings},
|
|
||||||
shader::{Shader, ShaderStages},
|
shader::{Shader, ShaderStages},
|
||||||
texture::TextureFormat,
|
texture::TextureFormat,
|
||||||
};
|
};
|
||||||
|
@ -119,17 +118,16 @@ impl PipelineDescriptor {
|
||||||
/// If `bevy_conventions` is true, it will be assumed that the shader follows "bevy shader conventions". These allow
|
/// If `bevy_conventions` is true, it will be assumed that the shader follows "bevy shader conventions". These allow
|
||||||
/// richer reflection, such as inferred Vertex Buffer names and inferred instancing.
|
/// richer reflection, such as inferred Vertex Buffer names and inferred instancing.
|
||||||
///
|
///
|
||||||
|
/// If `dynamic_bindings` has values, shader uniforms will be set to "dynamic" if there is a matching binding in the list
|
||||||
|
///
|
||||||
/// If `vertex_buffer_descriptors` is set, the pipeline's vertex buffers
|
/// If `vertex_buffer_descriptors` is set, the pipeline's vertex buffers
|
||||||
/// will inherit their layouts from global descriptors, otherwise the layout will be assumed to be complete / local.
|
/// will inherit their layouts from global descriptors, otherwise the layout will be assumed to be complete / local.
|
||||||
///
|
|
||||||
/// If `render_resource_bindings` is set, shader uniforms will be set to "dynamic" if there is a matching "dynamic uniform"
|
|
||||||
/// render resource.
|
|
||||||
pub fn reflect_layout(
|
pub fn reflect_layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
shaders: &Assets<Shader>,
|
shaders: &Assets<Shader>,
|
||||||
bevy_conventions: bool,
|
bevy_conventions: bool,
|
||||||
vertex_buffer_descriptors: Option<&VertexBufferDescriptors>,
|
vertex_buffer_descriptors: Option<&VertexBufferDescriptors>,
|
||||||
render_resource_bindings: Option<&RenderResourceBindings>,
|
dynamic_bindings: &[DynamicBinding],
|
||||||
) {
|
) {
|
||||||
let vertex_spirv = shaders.get(&self.shader_stages.vertex).unwrap();
|
let vertex_spirv = shaders.get(&self.shader_stages.vertex).unwrap();
|
||||||
let fragment_spirv = self
|
let fragment_spirv = self
|
||||||
|
@ -148,18 +146,16 @@ impl PipelineDescriptor {
|
||||||
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
|
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(render_resource_bindings) = render_resource_bindings {
|
if !dynamic_bindings.is_empty() {
|
||||||
// set binding uniforms to dynamic if render resource bindings use dynamic
|
// set binding uniforms to dynamic if render resource bindings use dynamic
|
||||||
// TODO: this breaks down if different bindings have different "dynamic" status or if the dynamic status changes.
|
|
||||||
// the fix would be to add "dynamic bindings" to the existing shader_def sets. this would ensure new pipelines are generated
|
|
||||||
// for all permutations of dynamic/non-dynamic
|
|
||||||
for bind_group in layout.bind_groups.iter_mut() {
|
for bind_group in layout.bind_groups.iter_mut() {
|
||||||
for binding in bind_group.bindings.iter_mut() {
|
for binding in bind_group.bindings.iter_mut() {
|
||||||
if let Some(RenderResourceBinding::Buffer {
|
let current = DynamicBinding {
|
||||||
dynamic_index: Some(_),
|
bind_group: bind_group.index,
|
||||||
..
|
binding: binding.index,
|
||||||
}) = render_resource_bindings.get(&binding.name)
|
};
|
||||||
{
|
|
||||||
|
if dynamic_bindings.contains(¤t) {
|
||||||
if let BindType::Uniform {
|
if let BindType::Uniform {
|
||||||
ref mut dynamic, ..
|
ref mut dynamic, ..
|
||||||
} = binding.bind_type
|
} = binding.bind_type
|
||||||
|
|
|
@ -3,18 +3,19 @@ use super::{
|
||||||
VertexBufferDescriptors,
|
VertexBufferDescriptors,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
render_resource::RenderResourceBindings,
|
|
||||||
renderer::RenderResourceContext,
|
renderer::RenderResourceContext,
|
||||||
shader::{Shader, ShaderSource},
|
shader::{Shader, ShaderSource},
|
||||||
};
|
};
|
||||||
use bevy_asset::{Assets, Handle};
|
use bevy_asset::{Assets, Handle, AssetEvent};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use bevy_app::Events;
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Debug, Default)]
|
#[derive(Clone, Eq, PartialEq, Debug, Default)]
|
||||||
pub struct PipelineSpecialization {
|
pub struct PipelineSpecialization {
|
||||||
pub shader_specialization: ShaderSpecialization,
|
pub shader_specialization: ShaderSpecialization,
|
||||||
pub primitive_topology: PrimitiveTopology,
|
pub primitive_topology: PrimitiveTopology,
|
||||||
|
pub dynamic_bindings: Vec<DynamicBinding>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Debug, Default)]
|
#[derive(Clone, Eq, PartialEq, Debug, Default)]
|
||||||
|
@ -32,7 +33,12 @@ struct SpecializedPipeline {
|
||||||
specialization: PipelineSpecialization,
|
specialization: PipelineSpecialization,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: consider using (Typeid, fieldinfo.index) in place of string for hashes
|
#[derive(Clone, Eq, PartialEq, Debug, Default)]
|
||||||
|
pub struct DynamicBinding {
|
||||||
|
pub bind_group: u32,
|
||||||
|
pub binding: u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct PipelineCompiler {
|
pub struct PipelineCompiler {
|
||||||
specialized_shaders: HashMap<Handle<Shader>, Vec<SpecializedShader>>,
|
specialized_shaders: HashMap<Handle<Shader>, Vec<SpecializedShader>>,
|
||||||
|
@ -92,7 +98,6 @@ impl PipelineCompiler {
|
||||||
source_pipeline: Handle<PipelineDescriptor>,
|
source_pipeline: Handle<PipelineDescriptor>,
|
||||||
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||||
pipeline_specialization: &PipelineSpecialization,
|
pipeline_specialization: &PipelineSpecialization,
|
||||||
render_resource_bindings: &RenderResourceBindings,
|
|
||||||
) -> Handle<PipelineDescriptor> {
|
) -> Handle<PipelineDescriptor> {
|
||||||
let source_descriptor = pipelines.get(&source_pipeline).unwrap();
|
let source_descriptor = pipelines.get(&source_pipeline).unwrap();
|
||||||
let mut specialized_descriptor = source_descriptor.clone();
|
let mut specialized_descriptor = source_descriptor.clone();
|
||||||
|
@ -117,7 +122,7 @@ impl PipelineCompiler {
|
||||||
shaders,
|
shaders,
|
||||||
true,
|
true,
|
||||||
Some(vertex_buffer_descriptors),
|
Some(vertex_buffer_descriptors),
|
||||||
Some(render_resource_bindings),
|
&pipeline_specialization.dynamic_bindings,
|
||||||
);
|
);
|
||||||
|
|
||||||
specialized_descriptor.primitive_topology = pipeline_specialization.primitive_topology;
|
specialized_descriptor.primitive_topology = pipeline_specialization.primitive_topology;
|
||||||
|
@ -176,7 +181,6 @@ impl PipelineCompiler {
|
||||||
source_pipeline,
|
source_pipeline,
|
||||||
vertex_buffer_descriptors,
|
vertex_buffer_descriptors,
|
||||||
&render_pipeline.specialization,
|
&render_pipeline.specialization,
|
||||||
&render_pipelines.bindings,
|
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,15 +217,15 @@ pub fn compile_pipelines_system(
|
||||||
mut pipeline_compiler: ResMut<PipelineCompiler>,
|
mut pipeline_compiler: ResMut<PipelineCompiler>,
|
||||||
mut shaders: ResMut<Assets<Shader>>,
|
mut shaders: ResMut<Assets<Shader>>,
|
||||||
mut pipelines: ResMut<Assets<PipelineDescriptor>>,
|
mut pipelines: ResMut<Assets<PipelineDescriptor>>,
|
||||||
// pipeline_asset_events: Res<Events<AssetEvent<PipelineDescriptor>>>,
|
_pipeline_asset_events: Res<Events<AssetEvent<PipelineDescriptor>>>,
|
||||||
vertex_buffer_descriptors: Res<VertexBufferDescriptors>,
|
vertex_buffer_descriptors: Res<VertexBufferDescriptors>,
|
||||||
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
||||||
query: &mut Query<Write<RenderPipelines>>,
|
query: &mut Query<Write<RenderPipelines>>,
|
||||||
) {
|
) {
|
||||||
let render_resource_context = &**render_resource_context;
|
let render_resource_context = &**render_resource_context;
|
||||||
// let default_specialization = PipelineSpecialization::default();
|
|
||||||
// NOTE: this intentionally only handles events that happened prior to this system during this frame. this results in
|
// NOTE: this intentionally only handles events that happened prior to this system during this frame. this results in
|
||||||
// "specialized pipeline" events being ignored.
|
// "new specialized pipeline" events being ignored.
|
||||||
|
// let default_specialization = PipelineSpecialization::default();
|
||||||
// for event in pipeline_asset_events.iter_current_update_events() {
|
// for event in pipeline_asset_events.iter_current_update_events() {
|
||||||
// let handle_to_compile = match event {
|
// let handle_to_compile = match event {
|
||||||
// AssetEvent::Created { handle } => Some(*handle),
|
// AssetEvent::Created { handle } => Some(*handle),
|
||||||
|
@ -229,13 +233,14 @@ pub fn compile_pipelines_system(
|
||||||
// // TODO: clean up old pipelines
|
// // TODO: clean up old pipelines
|
||||||
// Some(*handle)
|
// Some(*handle)
|
||||||
// }
|
// }
|
||||||
// AssetEvent::Removed { handle } => {
|
// AssetEvent::Removed { .. } => {
|
||||||
// // TODO: clean up old pipelines
|
// // TODO: clean up old pipelines
|
||||||
// None
|
// None
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// if let Some(handle_to_compile) = handle_to_compile {
|
// if let Some(handle_to_compile) = handle_to_compile {
|
||||||
|
// // TODO: try updating specialization here.
|
||||||
// pipeline_compiler.compile_pipeline(
|
// pipeline_compiler.compile_pipeline(
|
||||||
// render_resource_context,
|
// render_resource_context,
|
||||||
// &mut pipelines,
|
// &mut pipelines,
|
||||||
|
@ -243,7 +248,6 @@ pub fn compile_pipelines_system(
|
||||||
// handle_to_compile,
|
// handle_to_compile,
|
||||||
// &vertex_buffer_descriptors,
|
// &vertex_buffer_descriptors,
|
||||||
// &default_specialization,
|
// &default_specialization,
|
||||||
// None,
|
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -21,6 +21,14 @@ impl RenderPipeline {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn specialized(pipeline: Handle<PipelineDescriptor>, specialization: PipelineSpecialization) -> Self {
|
||||||
|
RenderPipeline {
|
||||||
|
pipeline,
|
||||||
|
specialization,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Properties)]
|
#[derive(Properties)]
|
||||||
|
@ -31,6 +39,13 @@ pub struct RenderPipelines {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderPipelines {
|
impl RenderPipelines {
|
||||||
|
pub fn from_pipelines(pipelines: Vec<RenderPipeline>) -> Self {
|
||||||
|
Self {
|
||||||
|
pipelines,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_handles<'a, T: IntoIterator<Item = &'a Handle<PipelineDescriptor>>>(
|
pub fn from_handles<'a, T: IntoIterator<Item = &'a Handle<PipelineDescriptor>>>(
|
||||||
handles: T,
|
handles: T,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use bevy_app::EntityArchetype;
|
use bevy_app::EntityArchetype;
|
||||||
use bevy_asset::Handle;
|
use bevy_asset::Handle;
|
||||||
use bevy_render::{draw::Draw, mesh::Mesh, pipeline::RenderPipelines};
|
use bevy_render::{draw::Draw, mesh::Mesh, pipeline::{PipelineSpecialization, RenderPipelines, RenderPipeline, DynamicBinding}};
|
||||||
|
|
||||||
#[derive(EntityArchetype)]
|
#[derive(EntityArchetype)]
|
||||||
pub struct SpriteEntity {
|
pub struct SpriteEntity {
|
||||||
|
@ -19,12 +19,12 @@ pub struct SpriteEntity {
|
||||||
impl Default for SpriteEntity {
|
impl Default for SpriteEntity {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
mesh: QUAD_HANDLE,
|
||||||
|
render_pipelines: RenderPipelines::from_handles(&[SPRITE_PIPELINE_HANDLE]),
|
||||||
sprite: Default::default(),
|
sprite: Default::default(),
|
||||||
quad: Default::default(),
|
quad: Default::default(),
|
||||||
mesh: QUAD_HANDLE,
|
|
||||||
material: Default::default(),
|
material: Default::default(),
|
||||||
draw: Default::default(),
|
draw: Default::default(),
|
||||||
render_pipelines: RenderPipelines::from_handles(&[SPRITE_PIPELINE_HANDLE]),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,11 +45,23 @@ pub struct SpriteSheetEntity {
|
||||||
impl Default for SpriteSheetEntity {
|
impl Default for SpriteSheetEntity {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::specialized(
|
||||||
|
SPRITE_SHEET_PIPELINE_HANDLE,
|
||||||
|
PipelineSpecialization {
|
||||||
|
dynamic_bindings: vec![
|
||||||
|
// TextureAtlasSprite
|
||||||
|
DynamicBinding {
|
||||||
|
bind_group: 2,
|
||||||
|
binding: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)]),
|
||||||
|
mesh: QUAD_HANDLE,
|
||||||
sprite: Default::default(),
|
sprite: Default::default(),
|
||||||
texture_atlas: Default::default(),
|
texture_atlas: Default::default(),
|
||||||
draw: Default::default(),
|
draw: Default::default(),
|
||||||
render_pipelines: RenderPipelines::from_handles(&[SPRITE_SHEET_PIPELINE_HANDLE]),
|
|
||||||
mesh: QUAD_HANDLE,
|
|
||||||
// transform: Default::default(),
|
// transform: Default::default(),
|
||||||
// translation: Default::default(),
|
// translation: Default::default(),
|
||||||
// rotation: Default::default(),
|
// rotation: Default::default(),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_render::base_render_graph;
|
use bevy_render::{pipeline::{PipelineSpecialization, RenderPipeline, DynamicBinding}, base_render_graph};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::build()
|
App::build()
|
||||||
|
@ -78,7 +78,25 @@ fn setup(
|
||||||
// cube
|
// cube
|
||||||
.add_entity(MeshMaterialEntity::<MyMaterial> {
|
.add_entity(MeshMaterialEntity::<MyMaterial> {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
render_pipelines: RenderPipelines::from_handles(&[pipeline_handle]),
|
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::specialized(
|
||||||
|
pipeline_handle,
|
||||||
|
// NOTE: in the future you wont need to manually declare dynamic bindings
|
||||||
|
PipelineSpecialization {
|
||||||
|
dynamic_bindings: vec![
|
||||||
|
// Transform
|
||||||
|
DynamicBinding {
|
||||||
|
bind_group: 1,
|
||||||
|
binding: 0,
|
||||||
|
},
|
||||||
|
// MyMaterial_color
|
||||||
|
DynamicBinding {
|
||||||
|
bind_group: 1,
|
||||||
|
binding: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)]),
|
||||||
material,
|
material,
|
||||||
translation: Translation::new(0.0, 0.0, 0.0),
|
translation: Translation::new(0.0, 0.0, 0.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use bevy::{prelude::*, render::shader};
|
use bevy::{prelude::*, render::shader};
|
||||||
use bevy_render::base_render_graph;
|
use bevy_render::{pipeline::{PipelineSpecialization, RenderPipeline, DynamicBinding}, base_render_graph};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::build()
|
App::build()
|
||||||
|
@ -18,7 +18,7 @@ struct MyMaterial {
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
#[render_resources(ignore)]
|
#[render_resources(ignore)]
|
||||||
#[shader_def]
|
#[shader_def]
|
||||||
pub always_red: bool,
|
pub always_blue: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERTEX_SHADER: &str = r#"
|
const VERTEX_SHADER: &str = r#"
|
||||||
|
@ -44,8 +44,8 @@ layout(set = 1, binding = 1) uniform MyMaterial_color {
|
||||||
void main() {
|
void main() {
|
||||||
o_Target = color;
|
o_Target = color;
|
||||||
|
|
||||||
# ifdef MYMATERIAL_ALWAYS_RED
|
# ifdef MYMATERIAL_ALWAYS_BLUE
|
||||||
o_Target = vec4(0.8, 0.0, 0.0, 1.0);
|
o_Target = vec4(0.0, 0.0, 0.8, 1.0);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
@ -78,13 +78,13 @@ fn setup(
|
||||||
// Create a green material
|
// Create a green material
|
||||||
let green_material = materials.add(MyMaterial {
|
let green_material = materials.add(MyMaterial {
|
||||||
color: Color::rgb(0.0, 0.8, 0.0),
|
color: Color::rgb(0.0, 0.8, 0.0),
|
||||||
always_red: false,
|
always_blue: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a red material, which uses our "always_red" shader def
|
// Create a blue material, which uses our "always_blue" shader def
|
||||||
let red_material = materials.add(MyMaterial {
|
let red_material = materials.add(MyMaterial {
|
||||||
color: Color::rgb(0.0, 0.0, 0.0),
|
color: Color::rgb(0.0, 0.0, 0.0),
|
||||||
always_red: true,
|
always_blue: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a cube mesh which will use our materials
|
// Create a cube mesh which will use our materials
|
||||||
|
@ -95,7 +95,25 @@ fn setup(
|
||||||
// cube
|
// cube
|
||||||
.add_entity(MeshMaterialEntity::<MyMaterial> {
|
.add_entity(MeshMaterialEntity::<MyMaterial> {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
render_pipelines: RenderPipelines::from_handles(&[pipeline_handle]),
|
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::specialized(
|
||||||
|
pipeline_handle,
|
||||||
|
// NOTE: in the future you wont need to manually declare dynamic bindings
|
||||||
|
PipelineSpecialization {
|
||||||
|
dynamic_bindings: vec![
|
||||||
|
// Transform
|
||||||
|
DynamicBinding {
|
||||||
|
bind_group: 1,
|
||||||
|
binding: 0,
|
||||||
|
},
|
||||||
|
// MyMaterial_color
|
||||||
|
DynamicBinding {
|
||||||
|
bind_group: 1,
|
||||||
|
binding: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)]),
|
||||||
material: green_material,
|
material: green_material,
|
||||||
translation: Translation::new(-2.0, 0.0, 0.0),
|
translation: Translation::new(-2.0, 0.0, 0.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -103,7 +121,25 @@ fn setup(
|
||||||
// cube
|
// cube
|
||||||
.add_entity(MeshMaterialEntity::<MyMaterial> {
|
.add_entity(MeshMaterialEntity::<MyMaterial> {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
render_pipelines: RenderPipelines::from_handles(&[pipeline_handle]),
|
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::specialized(
|
||||||
|
pipeline_handle,
|
||||||
|
// NOTE: in the future you wont need to manually declare dynamic bindings
|
||||||
|
PipelineSpecialization {
|
||||||
|
dynamic_bindings: vec![
|
||||||
|
// Transform
|
||||||
|
DynamicBinding {
|
||||||
|
bind_group: 1,
|
||||||
|
binding: 0,
|
||||||
|
},
|
||||||
|
// MyMaterial_color
|
||||||
|
DynamicBinding {
|
||||||
|
bind_group: 1,
|
||||||
|
binding: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)]),
|
||||||
material: red_material,
|
material: red_material,
|
||||||
translation: Translation::new(2.0, 0.0, 0.0),
|
translation: Translation::new(2.0, 0.0, 0.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
Loading…
Add table
Reference in a new issue