prep flat pipeline

This commit is contained in:
Carter Anderson 2020-01-21 03:15:28 -08:00
parent de9b91eeb5
commit 9e0d29d27e
8 changed files with 238 additions and 37 deletions

View file

@ -1,3 +1,5 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput, Data, DataStruct, Fields};
use quote::quote;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -0,0 +1,174 @@
use crate::{asset::*, render::*};
use legion::prelude::*;
use wgpu::SwapChainOutput;
pub struct ForwardFlatPipeline {
pub pipeline: Option<wgpu::RenderPipeline>,
pub depth_format: wgpu::TextureFormat,
pub bind_group: Option<wgpu::BindGroup>,
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::<AssetStorage<Mesh>>().unwrap();
let mut last_mesh_id = None;
let mesh_query =
<(Read<Material>, Read<Handle<Mesh>>)>::query().filter(!component::<Instanced>());
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()
}
}

View file

@ -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;

View file

@ -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<int(NumLights.x) && i<MAX_LIGHTS; ++i) {
Light light = SceneLights[i];
// compute Lambertian diffuse term
vec3 light_dir = normalize(light.pos.xyz - v_Position.xyz);
float diffuse = max(0.0, dot(normal, light_dir));
// add light contribution
color += diffuse * light.color.xyz;
}
// multiply the light by material color
o_Target = vec4(color, 1.0) * Color;
o_Target = Color;
}

View file

@ -7,17 +7,20 @@ 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 Globals {
layout(set = 0, binding = 0) uniform Camera {
mat4 ViewProj;
uvec4 NumLights;
};
layout(set = 1, binding = 0) uniform Entity {
mat4 World;
vec4 Color;
layout(set = 1, binding = 0) uniform Object {
mat4 Model;
};
layout(set = 1, binding = 1) uniform Material {
vec4 Albedo;
};
void main() {
v_Normal = mat3(World) * vec3(a_Normal.xyz);
v_Position = World * vec4(a_Pos);
v_Normal = mat3(Model) * vec3(a_Normal.xyz);
v_Position = Model * vec4(a_Pos);
gl_Position = ViewProj * v_Position;
}