pipeline specialization (support different primitive topologies within the same pipeline)
This commit is contained in:
		
							parent
							
								
									86d0ae6470
								
							
						
					
					
						commit
						7fe2288814
					
				| @ -118,7 +118,7 @@ impl<T> AssetStorage<T> { | ||||
|         AssetStorage { | ||||
|             assets: HashMap::new(), | ||||
|             names: HashMap::new(), | ||||
|             current_index: 1, | ||||
|             current_index: DEFAULT_HANDLE_ID + 1, // ensure we don't start on the default handle id
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -39,7 +39,7 @@ use self::{ | ||||
|     }, | ||||
|     render_graph::RenderGraph, | ||||
|     render_resource::{ | ||||
|         build_entity_render_resource_assignments_system, | ||||
|         entity_render_resource_assignments_system, | ||||
|         resource_providers::{ | ||||
|             Camera2dResourceProvider, CameraResourceProvider, LightResourceProvider, | ||||
|             UniformResourceProvider, | ||||
| @ -111,8 +111,12 @@ impl AppPlugin for RenderPlugin { | ||||
|             .add_resource(EntityRenderResourceAssignments::default()) | ||||
|             .add_resource(asset_batchers) | ||||
|             // core systems
 | ||||
|             .add_system(build_entity_render_resource_assignments_system()) | ||||
|             .add_system(entity_render_resource_assignments_system()) | ||||
|             .add_system_to_stage_init(stage::POST_UPDATE, camera::camera_update_system) | ||||
|             .add_system_to_stage( | ||||
|                 stage::POST_UPDATE, | ||||
|                 mesh::mesh_specializer_system(), | ||||
|             ) | ||||
|             .add_system_to_stage(stage::POST_UPDATE, mesh::mesh_batcher_system()) | ||||
|             .add_system_to_stage( | ||||
|                 stage::POST_UPDATE, | ||||
|  | ||||
| @ -6,7 +6,7 @@ use crate::{ | ||||
|     render_resource::AssetBatchers, | ||||
|     Renderable, | ||||
| }; | ||||
| use bevy_asset::Handle; | ||||
| use bevy_asset::{AssetStorage, Handle}; | ||||
| use glam::*; | ||||
| use legion::prelude::*; | ||||
| use std::borrow::Cow; | ||||
| @ -224,7 +224,7 @@ pub mod shape { | ||||
|             ]; | ||||
| 
 | ||||
|             Mesh { | ||||
|                 primitive_topology: PrimitiveTopology::TriangleStrip, | ||||
|                 primitive_topology: PrimitiveTopology::TriangleList, | ||||
|                 attributes: vec![ | ||||
|                     VertexAttribute::position(positions), | ||||
|                     VertexAttribute::normal(normals), | ||||
| @ -283,7 +283,7 @@ pub mod shape { | ||||
|             } | ||||
| 
 | ||||
|             Mesh { | ||||
|                 primitive_topology: PrimitiveTopology::TriangleStrip, | ||||
|                 primitive_topology: PrimitiveTopology::TriangleList, | ||||
|                 attributes: vec![ | ||||
|                     VertexAttribute::position(positions), | ||||
|                     VertexAttribute::normal(normals), | ||||
| @ -321,6 +321,20 @@ pub fn mesh_batcher_system() -> Box<dyn Schedulable> { | ||||
|         }) | ||||
| } | ||||
| 
 | ||||
| pub fn mesh_specializer_system() -> Box<dyn Schedulable> { | ||||
|     SystemBuilder::new("mesh_batcher") | ||||
|         .read_resource::<AssetStorage<Mesh>>() | ||||
|         .with_query( | ||||
|             <(Read<Handle<Mesh>>, Write<Renderable>)>::query().filter(changed::<Handle<Mesh>>() | changed::<Renderable>()), | ||||
|         ) | ||||
|         .build(|_, world, meshes, query| { | ||||
|             for (mesh_handle, mut renderable) in query.iter_mut(world) { | ||||
|                 let mesh = meshes.get(&mesh_handle).unwrap(); | ||||
|                 renderable.render_resource_assignments.pipeline_specialization.primitive_topology = mesh.primitive_topology; | ||||
|             } | ||||
|         }) | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::{Vertex, pipeline::state_descriptors::PrimitiveTopology, shader::AsUniforms}; | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| use super::{ | ||||
|     BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType, VertexBufferDescriptors, | ||||
|     state_descriptors::PrimitiveTopology, BindType, PipelineDescriptor, PipelineLayout, | ||||
|     PipelineLayoutType, VertexBufferDescriptors, | ||||
| }; | ||||
| use crate::{ | ||||
|     render_resource::{ | ||||
| @ -14,11 +15,25 @@ use std::collections::{HashMap, HashSet}; | ||||
| 
 | ||||
| use legion::prelude::*; | ||||
| 
 | ||||
| #[derive(Clone, Eq, PartialEq, Debug, Default)] | ||||
| pub struct PipelineSpecialization { | ||||
|     pub shader_specialization: ShaderSpecialization, | ||||
|     pub primitive_topology: PrimitiveTopology, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Eq, PartialEq, Debug, Default)] | ||||
| pub struct ShaderSpecialization { | ||||
|     pub shader_defs: HashSet<String>, | ||||
| } | ||||
| 
 | ||||
| // TODO: consider using (Typeid, fieldinfo.index) in place of string for hashes
 | ||||
| pub struct PipelineCompiler { | ||||
|     pub shader_source_to_compiled: HashMap<Handle<Shader>, Vec<(HashSet<String>, Handle<Shader>)>>, | ||||
|     pub pipeline_source_to_compiled: | ||||
|         HashMap<Handle<PipelineDescriptor>, Vec<(HashSet<String>, Handle<PipelineDescriptor>)>>, | ||||
|     pub shader_source_to_compiled: | ||||
|         HashMap<Handle<Shader>, Vec<(ShaderSpecialization, Handle<Shader>)>>, | ||||
|     pub pipeline_source_to_compiled: HashMap< | ||||
|         Handle<PipelineDescriptor>, | ||||
|         Vec<(PipelineSpecialization, Handle<PipelineDescriptor>)>, | ||||
|     >, | ||||
| } | ||||
| 
 | ||||
| impl PipelineCompiler { | ||||
| @ -86,7 +101,7 @@ impl PipelineCompiler { | ||||
|         &mut self, | ||||
|         shader_storage: &mut AssetStorage<Shader>, | ||||
|         shader_handle: &Handle<Shader>, | ||||
|         shader_defs: &HashSet<String>, | ||||
|         shader_specialization: &ShaderSpecialization, | ||||
|     ) -> Handle<Shader> { | ||||
|         let compiled_shaders = self | ||||
|             .shader_source_to_compiled | ||||
| @ -100,18 +115,26 @@ impl PipelineCompiler { | ||||
|             return *shader_handle; | ||||
|         } | ||||
| 
 | ||||
|         if let Some((_compiled_shader_defs, compiled_shader)) = compiled_shaders | ||||
|             .iter() | ||||
|             .find(|(compiled_shader_defs, _compiled_shader)| *compiled_shader_defs == *shader_defs) | ||||
|         if let Some((_shader_specialization, compiled_shader)) = | ||||
|             compiled_shaders | ||||
|                 .iter() | ||||
|                 .find(|(current_shader_specialization, _compiled_shader)| { | ||||
|                     *current_shader_specialization == *shader_specialization | ||||
|                 }) | ||||
|         { | ||||
|             // if shader has already been compiled with current configuration, use existing shader
 | ||||
|             *compiled_shader | ||||
|         } else { | ||||
|             // if no shader exists with the current configuration, create new shader and compile
 | ||||
|             let shader_def_vec = shader_defs.iter().cloned().collect::<Vec<String>>(); | ||||
|             let shader_def_vec = shader_specialization | ||||
|                 .shader_defs | ||||
|                 .iter() | ||||
|                 .cloned() | ||||
|                 .collect::<Vec<String>>(); | ||||
|             let compiled_shader = shader.get_spirv_shader(Some(&shader_def_vec)); | ||||
|             compiled_shaders.push((shader_defs.clone(), *shader_handle)); | ||||
|             shader_storage.add(compiled_shader) | ||||
|             let compiled_handle = shader_storage.add(compiled_shader); | ||||
|             compiled_shaders.push((shader_specialization.clone(), compiled_handle)); | ||||
|             compiled_handle | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -128,7 +151,9 @@ impl PipelineCompiler { | ||||
|         compiled_pipeline_descriptor.shader_stages.vertex = self.compile_shader( | ||||
|             shader_storage, | ||||
|             &pipeline_descriptor.shader_stages.vertex, | ||||
|             &render_resource_assignments.shader_defs, | ||||
|             &render_resource_assignments | ||||
|                 .pipeline_specialization | ||||
|                 .shader_specialization, | ||||
|         ); | ||||
|         compiled_pipeline_descriptor.shader_stages.fragment = pipeline_descriptor | ||||
|             .shader_stages | ||||
| @ -138,7 +163,9 @@ impl PipelineCompiler { | ||||
|                 self.compile_shader( | ||||
|                     shader_storage, | ||||
|                     fragment, | ||||
|                     &render_resource_assignments.shader_defs, | ||||
|                     &render_resource_assignments | ||||
|                         .pipeline_specialization | ||||
|                         .shader_specialization, | ||||
|                 ) | ||||
|             }); | ||||
| 
 | ||||
| @ -150,6 +177,9 @@ impl PipelineCompiler { | ||||
|             render_resource_assignments, | ||||
|         ); | ||||
| 
 | ||||
|         compiled_pipeline_descriptor.primitive_topology = render_resource_assignments | ||||
|             .pipeline_specialization | ||||
|             .primitive_topology; | ||||
|         compiled_pipeline_descriptor | ||||
|     } | ||||
| 
 | ||||
| @ -174,8 +204,8 @@ impl PipelineCompiler { | ||||
|                 .get_mut(pipeline_handle) | ||||
|                 .unwrap() | ||||
|                 .iter() | ||||
|                 .find(|(shader_defs, _macroed_pipeline_handle)| { | ||||
|                     *shader_defs == render_resource_assignments.shader_defs | ||||
|                 .find(|(pipeline_specialization, _macroed_pipeline_handle)| { | ||||
|                     *pipeline_specialization == render_resource_assignments.pipeline_specialization | ||||
|                 }) { | ||||
|                 *macroed_pipeline_handle | ||||
|             } else { | ||||
| @ -194,7 +224,7 @@ impl PipelineCompiler { | ||||
|                     .get_mut(pipeline_handle) | ||||
|                     .unwrap(); | ||||
|                 macro_pipelines.push(( | ||||
|                     render_resource_assignments.shader_defs.clone(), | ||||
|                     render_resource_assignments.pipeline_specialization.clone(), | ||||
|                     compiled_pipeline_handle, | ||||
|                 )); | ||||
|                 compiled_pipeline_handle | ||||
| @ -277,7 +307,12 @@ pub fn update_shader_assignments( | ||||
|             ); | ||||
| 
 | ||||
|             // reset shader_defs so they can be changed next frame
 | ||||
|             renderable.render_resource_assignments.shader_defs.clear(); | ||||
|             renderable | ||||
|                 .render_resource_assignments | ||||
|                 .pipeline_specialization | ||||
|                 .shader_specialization | ||||
|                 .shader_defs | ||||
|                 .clear(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -55,7 +55,7 @@ impl<'a, 'b, 'c> ForwardPipelineBuilder for RenderGraphBuilder<'a, 'b, 'c> { | ||||
|                     }, | ||||
|                     write_mask: ColorWrite::ALL, | ||||
|                 }) | ||||
|                 .add_draw_target(resource_name::draw_target::ASSIGNED_BATCHES); | ||||
|                 .add_draw_target(resource_name::draw_target::ASSIGNED_MESHES); | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -60,6 +60,12 @@ pub enum PrimitiveTopology { | ||||
|     TriangleStrip = 4, | ||||
| } | ||||
| 
 | ||||
| impl Default for PrimitiveTopology { | ||||
|     fn default() -> Self { | ||||
|         PrimitiveTopology::TriangleList | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] | ||||
| pub enum FrontFace { | ||||
|     Ccw = 0, | ||||
| @ -172,3 +178,9 @@ pub enum IndexFormat { | ||||
|     Uint16 = 0, | ||||
|     Uint32 = 1, | ||||
| } | ||||
| 
 | ||||
| impl Default for IndexFormat { | ||||
|     fn default() -> Self { | ||||
|         IndexFormat::Uint16 | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -19,7 +19,7 @@ impl EntityRenderResourceAssignments { | ||||
| } | ||||
| 
 | ||||
| // TODO: make sure this runs right before rendering
 | ||||
| pub fn build_entity_render_resource_assignments_system() -> Box<dyn Schedulable> { | ||||
| pub fn entity_render_resource_assignments_system() -> Box<dyn Schedulable> { | ||||
|     SystemBuilder::new("entity_render_resource_assignments") | ||||
|         .write_resource::<EntityRenderResourceAssignments>() | ||||
|         .with_query(<Write<Renderable>>::query().filter(changed::<Renderable>())) | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use super::RenderResource; | ||||
| use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId}; | ||||
| use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization}; | ||||
| use std::{ | ||||
|     collections::{hash_map::DefaultHasher, HashMap, HashSet}, | ||||
|     hash::{Hash, Hasher}, | ||||
| @ -15,7 +15,7 @@ pub struct RenderResourceAssignments { | ||||
|     bind_group_resource_sets: | ||||
|         HashMap<BindGroupDescriptorId, (RenderResourceSetId, Option<Vec<u32>>)>, | ||||
|     dirty_bind_groups: HashSet<BindGroupDescriptorId>, | ||||
|     pub(crate) shader_defs: HashSet<String>, | ||||
|     pub pipeline_specialization: PipelineSpecialization, | ||||
| } | ||||
| 
 | ||||
| impl RenderResourceAssignments { | ||||
|  | ||||
| @ -1,80 +1,96 @@ | ||||
| use crate::{ | ||||
|     mesh::{self, Mesh}, | ||||
|     pipeline::{state_descriptors::IndexFormat, VertexBufferDescriptors}, | ||||
|     render_resource::{AssetBatchers, BufferInfo, BufferUsage}, | ||||
|     renderer_2::GlobalRenderResourceContext, | ||||
|     pipeline::{state_descriptors::IndexFormat, VertexBufferDescriptor, VertexBufferDescriptors}, | ||||
|     render_resource::{AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments}, | ||||
|     renderer_2::{GlobalRenderResourceContext, RenderResourceContext}, | ||||
|     shader::AsUniforms, | ||||
|     Vertex, | ||||
|     Renderable, Vertex, | ||||
| }; | ||||
| use bevy_asset::AssetStorage; | ||||
| use bevy_asset::{AssetStorage, Handle}; | ||||
| use legion::prelude::*; | ||||
| 
 | ||||
| fn setup_mesh_resource( | ||||
|     render_resources: &dyn RenderResourceContext, | ||||
|     render_resource_assignments: &mut RenderResourceAssignments, | ||||
|     vertex_buffer_descriptor: &VertexBufferDescriptor, | ||||
|     handle: Handle<Mesh>, | ||||
|     meshes: &AssetStorage<Mesh>, | ||||
| ) { | ||||
|     log::trace!("setup mesh for {:?}", render_resource_assignments.id); | ||||
|     let index_format = IndexFormat::Uint16; | ||||
|     let (vertex_buffer, index_buffer) = if let Some(vertex_buffer) = | ||||
|         render_resources.get_asset_resource(handle, mesh::VERTEX_BUFFER_ASSET_INDEX) | ||||
|     { | ||||
|         ( | ||||
|             vertex_buffer, | ||||
|             render_resources.get_asset_resource(handle, mesh::INDEX_BUFFER_ASSET_INDEX), | ||||
|         ) | ||||
|     } else { | ||||
|         let mesh_asset = meshes.get(&handle).unwrap(); | ||||
|         let vertex_bytes = mesh_asset | ||||
|             .get_vertex_buffer_bytes(&vertex_buffer_descriptor) | ||||
|             .unwrap(); | ||||
|         // TODO: use a staging buffer here
 | ||||
|         let vertex_buffer = render_resources.create_buffer_with_data( | ||||
|             BufferInfo { | ||||
|                 buffer_usage: BufferUsage::VERTEX, | ||||
|                 ..Default::default() | ||||
|             }, | ||||
|             &vertex_bytes, | ||||
|         ); | ||||
|         let index_bytes = mesh_asset.get_index_buffer_bytes(index_format).unwrap(); | ||||
|         let index_buffer = render_resources.create_buffer_with_data( | ||||
|             BufferInfo { | ||||
|                 buffer_usage: BufferUsage::INDEX, | ||||
|                 ..Default::default() | ||||
|             }, | ||||
|             &index_bytes, | ||||
|         ); | ||||
| 
 | ||||
|         render_resources.set_asset_resource(handle, vertex_buffer, mesh::VERTEX_BUFFER_ASSET_INDEX); | ||||
|         render_resources.set_asset_resource(handle, index_buffer, mesh::INDEX_BUFFER_ASSET_INDEX); | ||||
|         (vertex_buffer, Some(index_buffer)) | ||||
|     }; | ||||
| 
 | ||||
|     render_resource_assignments.set_vertex_buffer("Vertex", vertex_buffer, index_buffer); | ||||
| } | ||||
| 
 | ||||
| pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box<dyn Schedulable> { | ||||
|     let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap(); | ||||
|     // TODO: allow pipelines to specialize on vertex_buffer_descriptor and index_format
 | ||||
|     let vertex_buffer_descriptor = Vertex::get_vertex_buffer_descriptor().unwrap(); | ||||
|     let index_format = IndexFormat::Uint16; | ||||
|     vertex_buffer_descriptors.set(vertex_buffer_descriptor.clone()); | ||||
|     SystemBuilder::new("mesh_resource_provider") | ||||
|         .read_resource::<GlobalRenderResourceContext>() | ||||
|         .read_resource::<AssetStorage<Mesh>>() | ||||
|         .write_resource::<AssetBatchers>() | ||||
|         .with_query(<(Read<Handle<Mesh>>, Write<Renderable>)>::query()) | ||||
|         .build( | ||||
|             move |_, _, (render_resource_context, meshes, asset_batchers), _| { | ||||
|                 let render_resources = &render_resource_context.context; | ||||
|             move |_, world, (render_resource_context, meshes, asset_batchers), query| { | ||||
|                 let render_resources = &*render_resource_context.context; | ||||
|                 if let Some(batches) = asset_batchers.get_handle_batches_mut::<Mesh>() { | ||||
|                     for batch in batches { | ||||
|                         let handle = batch.get_handle::<Mesh>().unwrap(); | ||||
|                         log::trace!("setup mesh for {:?}", batch.render_resource_assignments.id); | ||||
|                         let (vertex_buffer, index_buffer) = if let Some(vertex_buffer) = | ||||
|                             render_resources | ||||
|                                 .get_asset_resource(handle, mesh::VERTEX_BUFFER_ASSET_INDEX) | ||||
|                         { | ||||
|                             ( | ||||
|                                 vertex_buffer, | ||||
|                                 render_resources | ||||
|                                     .get_asset_resource(handle, mesh::INDEX_BUFFER_ASSET_INDEX), | ||||
|                             ) | ||||
|                         } else { | ||||
|                             let mesh_asset = meshes.get(&handle).unwrap(); | ||||
|                             let vertex_bytes = mesh_asset.get_vertex_buffer_bytes(&vertex_buffer_descriptor).unwrap(); | ||||
|                             // TODO: use a staging buffer here
 | ||||
|                             let vertex_buffer = render_resources.create_buffer_with_data( | ||||
|                                 BufferInfo { | ||||
|                                     buffer_usage: BufferUsage::VERTEX, | ||||
|                                     ..Default::default() | ||||
|                                 }, | ||||
|                                 &vertex_bytes, | ||||
|                             ); | ||||
|                             let index_bytes = mesh_asset.get_index_buffer_bytes(index_format).unwrap(); | ||||
|                             let index_buffer = render_resources.create_buffer_with_data( | ||||
|                                 BufferInfo { | ||||
|                                     buffer_usage: BufferUsage::INDEX, | ||||
|                                     ..Default::default() | ||||
|                                 }, | ||||
|                                 &index_bytes, | ||||
|                             ); | ||||
| 
 | ||||
|                             render_resources.set_asset_resource( | ||||
|                                 handle, | ||||
|                                 vertex_buffer, | ||||
|                                 mesh::VERTEX_BUFFER_ASSET_INDEX, | ||||
|                             ); | ||||
|                             render_resources.set_asset_resource( | ||||
|                                 handle, | ||||
|                                 index_buffer, | ||||
|                                 mesh::INDEX_BUFFER_ASSET_INDEX, | ||||
|                             ); | ||||
|                             (vertex_buffer, Some(index_buffer)) | ||||
|                         }; | ||||
| 
 | ||||
|                         batch.render_resource_assignments.set_vertex_buffer( | ||||
|                             "Vertex", | ||||
|                             vertex_buffer, | ||||
|                             index_buffer, | ||||
|                         setup_mesh_resource( | ||||
|                             render_resources, | ||||
|                             &mut batch.render_resource_assignments, | ||||
|                             &vertex_buffer_descriptor, | ||||
|                             handle, | ||||
|                             &meshes, | ||||
|                         ); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 // TODO: remove this once batches are pipeline specific and deprecate assigned_meshes draw target
 | ||||
|                 for (handle, mut renderable) in query.iter_mut(world) { | ||||
|                     setup_mesh_resource( | ||||
|                         render_resources, | ||||
|                         &mut renderable.render_resource_assignments, | ||||
|                         &vertex_buffer_descriptor, | ||||
|                         *handle, | ||||
|                         &meshes, | ||||
|                     ); | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
| } | ||||
|  | ||||
| @ -31,6 +31,8 @@ where | ||||
|                 if let Some(shader_defs) = uniforms.get_shader_defs() { | ||||
|                     renderable | ||||
|                         .render_resource_assignments | ||||
|                         .pipeline_specialization | ||||
|                         .shader_specialization | ||||
|                         .shader_defs | ||||
|                         .extend(shader_defs) | ||||
|                 } | ||||
| @ -58,6 +60,8 @@ where | ||||
|             if let Some(shader_defs) = uniforms.get_shader_defs() { | ||||
|                 renderable | ||||
|                     .render_resource_assignments | ||||
|                     .pipeline_specialization | ||||
|                     .shader_specialization | ||||
|                     .shader_defs | ||||
|                     .extend(shader_defs) | ||||
|             } | ||||
|  | ||||
| @ -10,7 +10,6 @@ fn main() { | ||||
| 
 | ||||
| /// set up a simple scene
 | ||||
| fn setup(world: &mut World, resources: &mut Resources) { | ||||
|     env_logger::init(); | ||||
|     // create a cube and a plane mesh
 | ||||
|     let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap(); | ||||
|     let cube_handle = mesh_storage.add(Mesh::from(shape::Cube)); | ||||
| @ -45,13 +44,6 @@ fn setup(world: &mut World, resources: &mut Resources) { | ||||
|             translation: Translation::new(0.0, 0.0, 1.0), | ||||
|             ..Default::default() | ||||
|         }) | ||||
|         // cube
 | ||||
|         .add_entity(MeshEntity { | ||||
|             mesh: cube_handle, | ||||
|             material: cube_material_handle, | ||||
|             translation: Translation::new(2.0, 0.0, 1.0), | ||||
|             ..Default::default() | ||||
|         }) | ||||
|         // light
 | ||||
|         .add_entity(LightEntity { | ||||
|             translation: Translation::new(4.0, -4.0, 5.0), | ||||
|  | ||||
| @ -1,13 +1,9 @@ | ||||
| use bevy::{prelude::*, render::shader}; | ||||
| use bevy::prelude::*; | ||||
| 
 | ||||
| fn main() { | ||||
|     App::build() | ||||
|         .add_default_plugins() | ||||
|         .add_startup_system(setup) | ||||
|         .add_system_to_stage( | ||||
|             stage::POST_UPDATE, | ||||
|             shader::asset_handle_batcher_system::<MyMaterial>(), | ||||
|         ) | ||||
|         .run(); | ||||
| } | ||||
| 
 | ||||
| @ -32,8 +28,7 @@ fn add_shader_to_render_graph(resources: &mut Resources) { | ||||
|                     ShaderStage::Vertex, | ||||
|                     r#" | ||||
|                     #version 450 | ||||
|                     layout(location = 0) in vec4 Vertex_Position; | ||||
|                     layout(location = 0) out vec4 v_Position; | ||||
|                     layout(location = 0) in vec3 Vertex_Position; | ||||
|                     layout(set = 0, binding = 0) uniform Camera { | ||||
|                         mat4 ViewProj; | ||||
|                     }; | ||||
| @ -41,8 +36,7 @@ fn add_shader_to_render_graph(resources: &mut Resources) { | ||||
|                         mat4 Model; | ||||
|                     }; | ||||
|                     void main() { | ||||
|                         v_Position = Model * Vertex_Position; | ||||
|                         gl_Position = ViewProj * v_Position; | ||||
|                         gl_Position = ViewProj * Model * vec4(Vertex_Position, 1.0); | ||||
|                     } | ||||
|                 "#,
 | ||||
|                 )) | ||||
| @ -50,7 +44,6 @@ fn add_shader_to_render_graph(resources: &mut Resources) { | ||||
|                     ShaderStage::Fragment, | ||||
|                     r#" | ||||
|                     #version 450 | ||||
|                     layout(location = 0) in vec4 v_Position; | ||||
|                     layout(location = 0) out vec4 o_Target; | ||||
|                     layout(set = 1, binding = 1) uniform MyMaterial_color { | ||||
|                         vec4 color; | ||||
| @ -73,13 +66,8 @@ fn setup(world: &mut World, resources: &mut Resources) { | ||||
|     let material = material_storage.add(MyMaterial { | ||||
|         color: Color::rgb(0.0, 0.8, 0.0), | ||||
|     }); | ||||
| 
 | ||||
|     resources.insert(material_storage); | ||||
| 
 | ||||
|     // batch materials to improve performance
 | ||||
|     let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap(); | ||||
|     asset_batchers.batch_types2::<Mesh, MyMaterial>(); | ||||
| 
 | ||||
|     // get a handle to our newly created shader pipeline
 | ||||
|     let mut pipeline_storage = resources | ||||
|         .get_mut::<AssetStorage<PipelineDescriptor>>() | ||||
|  | ||||
| @ -4,10 +4,6 @@ fn main() { | ||||
|     App::build() | ||||
|         .add_default_plugins() | ||||
|         .add_startup_system(setup) | ||||
|         .add_system_to_stage( | ||||
|             stage::POST_UPDATE, | ||||
|             shader::asset_handle_batcher_system::<MyMaterial>(), | ||||
|         ) | ||||
|         .add_system_to_stage( | ||||
|             stage::POST_UPDATE, | ||||
|             shader::asset_handle_shader_def_system::<MyMaterial>(), | ||||
| @ -38,8 +34,7 @@ fn add_shader_to_render_graph(resources: &mut Resources) { | ||||
|                     ShaderStage::Vertex, | ||||
|                     r#" | ||||
|                     #version 450 | ||||
|                     layout(location = 0) in vec4 Vertex_Position; | ||||
|                     layout(location = 0) out vec4 v_Position; | ||||
|                     layout(location = 0) in vec3 Vertex_Position; | ||||
|                     layout(set = 0, binding = 0) uniform Camera { | ||||
|                         mat4 ViewProj; | ||||
|                     }; | ||||
| @ -47,8 +42,7 @@ fn add_shader_to_render_graph(resources: &mut Resources) { | ||||
|                         mat4 Model; | ||||
|                     }; | ||||
|                     void main() { | ||||
|                         v_Position = Model * Vertex_Position; | ||||
|                         gl_Position = ViewProj * v_Position; | ||||
|                         gl_Position = ViewProj * Model * vec4(Vertex_Position, 1.0); | ||||
|                     } | ||||
|                 "#,
 | ||||
|                 )) | ||||
| @ -56,7 +50,6 @@ fn add_shader_to_render_graph(resources: &mut Resources) { | ||||
|                     ShaderStage::Fragment, | ||||
|                     r#" | ||||
|                     #version 450 | ||||
|                     layout(location = 0) in vec4 v_Position; | ||||
|                     layout(location = 0) out vec4 o_Target; | ||||
|                     layout(set = 1, binding = 1) uniform MyMaterial_color { | ||||
|                         vec4 color; | ||||
| @ -92,10 +85,6 @@ fn setup(world: &mut World, resources: &mut Resources) { | ||||
| 
 | ||||
|     resources.insert(material_storage); | ||||
| 
 | ||||
|     // batch materials to improve performance
 | ||||
|     let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap(); | ||||
|     asset_batchers.batch_types2::<Mesh, MyMaterial>(); | ||||
| 
 | ||||
|     // get a handle to our newly created shader pipeline
 | ||||
|     let mut pipeline_storage = resources | ||||
|         .get_mut::<AssetStorage<PipelineDescriptor>>() | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson