From 9e0d29d27e56fabf4ca5b6f0c20f61787f118c54 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Tue, 21 Jan 2020 03:15:28 -0800 Subject: [PATCH] prep flat pipeline --- bevy_derive/src/lib.rs | 2 + examples/simple.rs | 2 +- .../passes/forward_flat/forward_flat.frag | 19 ++ .../passes/forward_flat/forward_flat.vert | 26 +++ src/render/passes/forward_flat/mod.rs | 174 ++++++++++++++++++ src/render/passes/mod.rs | 2 + .../pipelines/forward/forward.frag | 33 +--- .../pipelines/forward/forward.vert | 17 +- 8 files changed, 238 insertions(+), 37 deletions(-) create mode 100644 src/render/passes/forward_flat/forward_flat.frag create mode 100644 src/render/passes/forward_flat/forward_flat.vert create mode 100644 src/render/passes/forward_flat/mod.rs diff --git a/bevy_derive/src/lib.rs b/bevy_derive/src/lib.rs index e60223b87d..1847e73aed 100644 --- a/bevy_derive/src/lib.rs +++ b/bevy_derive/src/lib.rs @@ -1,3 +1,5 @@ +extern crate proc_macro; + use proc_macro::TokenStream; use syn::{parse_macro_input, DeriveInput, Data, DataStruct, Fields}; use quote::quote; diff --git a/examples/simple.rs b/examples/simple.rs index 9240a980af..a0f39b38a4 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -12,7 +12,7 @@ fn setup(world: &mut World) { let mut mesh_storage = world.resources.get_mut::>().unwrap(); (mesh_storage.add(cube), mesh_storage.add(plane)) }; - + world.build() // plane .build_archetype(MeshEntity { diff --git a/src/render/passes/forward_flat/forward_flat.frag b/src/render/passes/forward_flat/forward_flat.frag new file mode 100644 index 0000000000..07cb42f720 --- /dev/null +++ b/src/render/passes/forward_flat/forward_flat.frag @@ -0,0 +1,19 @@ +#version 450 + +layout(location = 0) in vec3 v_Normal; +layout(location = 1) in vec4 v_Position; + +layout(location = 0) out vec4 o_Target; + +layout(set = 0, binding = 0) uniform Camera { + mat4 ViewProj; +}; + +layout(set = 1, binding = 1) uniform Material { + vec4 Albedo; +}; + +void main() { + // multiply the light by material color + o_Target = Color; +} diff --git a/src/render/passes/forward_flat/forward_flat.vert b/src/render/passes/forward_flat/forward_flat.vert new file mode 100644 index 0000000000..4da7ad5bb7 --- /dev/null +++ b/src/render/passes/forward_flat/forward_flat.vert @@ -0,0 +1,26 @@ +#version 450 + +layout(location = 0) in vec4 a_Pos; +layout(location = 1) in vec4 a_Normal; +layout(location = 2) in vec4 a_Uv; + +layout(location = 0) out vec3 v_Normal; +layout(location = 1) out vec4 v_Position; + +layout(set = 0, binding = 0) uniform Camera { + mat4 ViewProj; +}; + +layout(set = 1, binding = 0) uniform Object { + mat4 Model; +}; + +layout(set = 1, binding = 1) uniform Material { + vec4 Albedo; +}; + +void main() { + v_Normal = mat3(Model) * vec3(a_Normal.xyz); + v_Position = Model * vec4(a_Pos); + gl_Position = ViewProj * v_Position; +} diff --git a/src/render/passes/forward_flat/mod.rs b/src/render/passes/forward_flat/mod.rs new file mode 100644 index 0000000000..54ea4c0144 --- /dev/null +++ b/src/render/passes/forward_flat/mod.rs @@ -0,0 +1,174 @@ +use crate::{asset::*, render::*}; +use legion::prelude::*; +use wgpu::SwapChainOutput; + +pub struct ForwardFlatPipeline { + pub pipeline: Option, + pub depth_format: wgpu::TextureFormat, + pub bind_group: Option, + pub msaa_samples: usize, +} + +impl ForwardFlatPipeline { + pub fn new(msaa_samples: usize) -> Self { + ForwardFlatPipeline { + pipeline: None, + bind_group: None, + msaa_samples, + depth_format: wgpu::TextureFormat::Depth32Float, + } + } +} + +impl Pipeline for ForwardFlatPipeline { + fn initialize(&mut self, render_graph: &mut RenderGraphData, _: &mut World) { + let vs_bytes = shader::glsl_to_spirv(include_str!("forward_flat.vert"), shader::ShaderStage::Vertex); + let fs_bytes = + shader::glsl_to_spirv(include_str!("forward_flat.frag"), shader::ShaderStage::Fragment); + + let bind_group_layout = + render_graph + .device + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + bindings: &[ + wgpu::BindGroupLayoutBinding { + binding: 0, // global + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::UniformBuffer { dynamic: false }, + }, + wgpu::BindGroupLayoutBinding { + binding: 1, // lights + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::UniformBuffer { dynamic: false }, + }, + ], + }); + + self.bind_group = Some({ + let forward_uniform_buffer = render_graph + .get_uniform_buffer(render_resources::FORWARD_UNIFORM_BUFFER_NAME) + .unwrap(); + let light_uniform_buffer = render_graph + .get_uniform_buffer(render_resources::LIGHT_UNIFORM_BUFFER_NAME) + .unwrap(); + + // Create bind group + render_graph + .device + .create_bind_group(&wgpu::BindGroupDescriptor { + layout: &bind_group_layout, + bindings: &[ + wgpu::Binding { + binding: 0, + resource: forward_uniform_buffer.get_binding_resource(), + }, + wgpu::Binding { + binding: 1, + resource: light_uniform_buffer.get_binding_resource(), + }, + ], + }) + }); + + let material_bind_group_layout = render_graph + .get_bind_group_layout(render_resources::MATERIAL_BIND_GROUP_LAYOUT_NAME) + .unwrap(); + + let pipeline_layout = + render_graph + .device + .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + bind_group_layouts: &[&bind_group_layout, material_bind_group_layout], + }); + + let vertex_buffer_descriptor = get_vertex_buffer_descriptor(); + + let vs_module = render_graph.device.create_shader_module(&vs_bytes); + let fs_module = render_graph.device.create_shader_module(&fs_bytes); + + self.pipeline = Some(render_graph.device.create_render_pipeline( + &wgpu::RenderPipelineDescriptor { + layout: &pipeline_layout, + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: &vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: &fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: render_graph.swap_chain_descriptor.format, + color_blend: wgpu::BlendDescriptor::REPLACE, + alpha_blend: wgpu::BlendDescriptor::REPLACE, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: self.depth_format, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::Less, + stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE, + stencil_back: wgpu::StencilStateFaceDescriptor::IGNORE, + stencil_read_mask: 0, + stencil_write_mask: 0, + }), + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[vertex_buffer_descriptor], + sample_count: self.msaa_samples as u32, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }, + )); + } + fn render( + &mut self, + render_graph: &RenderGraphData, + pass: &mut wgpu::RenderPass, + _: &SwapChainOutput, + world: &mut World, + ) { + pass.set_bind_group(0, self.bind_group.as_ref().unwrap(), &[]); + + let mut mesh_storage = world.resources.get_mut::>().unwrap(); + let mut last_mesh_id = None; + let mesh_query = + <(Read, Read>)>::query().filter(!component::()); + for (material, mesh) in mesh_query.iter(world) { + let current_mesh_id = mesh.id; + + let mut should_load_mesh = last_mesh_id == None; + if let Some(last) = last_mesh_id { + should_load_mesh = last != current_mesh_id; + } + + if should_load_mesh { + if let Some(mesh_asset) = mesh_storage.get(mesh.id) { + mesh_asset.setup_buffers(&render_graph.device); + pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0); + pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]); + }; + } + + if let Some(ref mesh_asset) = mesh_storage.get(mesh.id) { + pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); + pass.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1); + }; + + last_mesh_id = Some(current_mesh_id); + } + } + + fn resize(&mut self, _: &RenderGraphData) {} + + fn get_pipeline(&self) -> &wgpu::RenderPipeline { + self.pipeline.as_ref().unwrap() + } +} diff --git a/src/render/passes/mod.rs b/src/render/passes/mod.rs index f3266478d3..a17484f918 100644 --- a/src/render/passes/mod.rs +++ b/src/render/passes/mod.rs @@ -1,10 +1,12 @@ mod forward; +mod forward_flat; mod forward_instanced; mod forward_shadow; mod shadow; mod ui; pub use forward::{ForwardPass, ForwardPipeline, ForwardUniforms}; +pub use forward_flat::*; pub use forward_instanced::ForwardInstancedPipeline; pub use forward_shadow::ForwardShadowPassNew; pub use shadow::ShadowPass; diff --git a/src/render/render_graph_2/pipelines/forward/forward.frag b/src/render/render_graph_2/pipelines/forward/forward.frag index 2d93b2b9a3..07cb42f720 100644 --- a/src/render/render_graph_2/pipelines/forward/forward.frag +++ b/src/render/render_graph_2/pipelines/forward/forward.frag @@ -1,44 +1,19 @@ #version 450 -const int MAX_LIGHTS = 10; - layout(location = 0) in vec3 v_Normal; layout(location = 1) in vec4 v_Position; layout(location = 0) out vec4 o_Target; -struct Light { - mat4 proj; - vec4 pos; - vec4 color; -}; - -layout(set = 0, binding = 0) uniform Globals { +layout(set = 0, binding = 0) uniform Camera { mat4 ViewProj; - uvec4 NumLights; -}; -layout(set = 0, binding = 1) uniform Lights { - Light SceneLights[MAX_LIGHTS]; }; -layout(set = 1, binding = 0) uniform Entity { - mat4 World; - vec4 Color; +layout(set = 1, binding = 1) uniform Material { + vec4 Albedo; }; void main() { - vec3 normal = normalize(v_Normal); - vec3 ambient = vec3(0.05, 0.05, 0.05); - // accumulate color - vec3 color = ambient; - for (int i=0; i