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