begin porting over lighting

This commit is contained in:
Carter Anderson 2020-02-04 23:14:13 -08:00
parent 48e8967acc
commit 380e59ee23
11 changed files with 285 additions and 50 deletions

View file

@ -4,7 +4,7 @@ use crate::{
core::Time,
legion::prelude::{Runnable, Schedulable, Schedule, Universe, World},
render::render_graph_2,
render::render_graph_2::{pipelines::*, wgpu_renderer::WgpuRenderer, resource_provider::CameraResourceProvider, UniformResourceProvider, StandardMaterial},
render::render_graph_2::{pipelines::*, passes::*, wgpu_renderer::WgpuRenderer, resource_provider::{CameraResourceProvider, LightResourceProvider}, UniformResourceProvider, StandardMaterial},
render::{passes::*, *},
plugin::load_plugin,
ui,
@ -175,6 +175,7 @@ impl AppBuilder {
self.render_graph_builder = self
.render_graph_builder
.add_resource_provider(Box::new(CameraResourceProvider))
.add_resource_provider(Box::new(LightResourceProvider::new(10)))
.add_resource_provider(Box::new(UniformResourceProvider::<StandardMaterial>::new()))
.add_resource_provider(Box::new(UniformResourceProvider::<LocalToWorld>::new()))
.add_forward_pass()

View file

@ -2,6 +2,7 @@ pub mod pipelines;
pub mod resource_name;
pub mod wgpu_renderer;
pub mod resource_provider;
pub mod passes;
mod resource;
mod pipeline;
mod pipeline_layout;

View file

@ -0,0 +1,43 @@
use crate::render::{
render_graph_2::{
resource_name, PassDescriptor,
RenderGraphBuilder, RenderPassColorAttachmentDescriptor,
},
};
pub trait ForwardPassBuilder {
fn add_forward_pass(self) -> Self;
}
impl ForwardPassBuilder for RenderGraphBuilder {
fn add_forward_pass(self) -> Self {
self.add_pass(
"main",
PassDescriptor {
color_attachments: vec![RenderPassColorAttachmentDescriptor {
attachment: resource_name::texture::SWAP_CHAIN.to_string(),
resolve_target: None,
load_op: wgpu::LoadOp::Clear,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color {
r: 0.3,
g: 0.4,
b: 0.5,
a: 1.0,
},
}],
depth_stencil_attachment: None,
// depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor {
// attachment: "forward_depth".to_string(),
// depth_load_op: wgpu::LoadOp::Clear,
// depth_store_op: wgpu::StoreOp::Store,
// stencil_load_op: wgpu::LoadOp::Clear,
// stencil_store_op: wgpu::StoreOp::Store,
// clear_depth: 1.0,
// clear_stencil: 0,
// }),
sample_count: 1,
},
)
}
}

View file

@ -0,0 +1,3 @@
mod forward;
pub use forward::*;

View file

@ -2,8 +2,8 @@ use crate::render::{
Vertex,
{
render_graph_2::{
mesh_draw_target, resource_name, pipeline_layout::*, PassDescriptor, PipelineDescriptor,
RenderGraphBuilder, RenderPassColorAttachmentDescriptor,
mesh_draw_target, pipeline_layout::*, PipelineDescriptor,
RenderGraphBuilder,
},
shader::{Shader, ShaderStage},
},
@ -95,41 +95,4 @@ impl ForwardPipelineBuilder for RenderGraphBuilder {
.build(),
)
}
}
pub trait ForwardPassBuilder {
fn add_forward_pass(self) -> Self;
}
impl ForwardPassBuilder for RenderGraphBuilder {
fn add_forward_pass(self) -> Self {
self.add_pass(
"main",
PassDescriptor {
color_attachments: vec![RenderPassColorAttachmentDescriptor {
attachment: resource_name::texture::SWAP_CHAIN.to_string(),
resolve_target: None,
load_op: wgpu::LoadOp::Clear,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color {
r: 0.3,
g: 0.4,
b: 0.5,
a: 1.0,
},
}],
depth_stencil_attachment: None,
// depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor {
// attachment: "forward_depth".to_string(),
// depth_load_op: wgpu::LoadOp::Clear,
// depth_store_op: wgpu::StoreOp::Store,
// stencil_load_op: wgpu::LoadOp::Clear,
// stencil_store_op: wgpu::StoreOp::Store,
// clear_depth: 1.0,
// clear_stencil: 0,
// }),
sample_count: 1,
},
)
}
}
}

View file

@ -0,0 +1,21 @@
#version 450
layout(location = 0) in vec4 v_Position;
layout(location = 1) in vec3 v_Normal;
layout(location = 2) in vec2 v_Uv;
layout(location = 0) out vec4 o_Target;
layout(set = 0, binding = 0) uniform Camera {
mat4 ViewProj;
};
layout(set = 1, binding = 1) uniform StandardMaterial {
vec4 Albedo;
};
void main() {
// multiply the light by material color
o_Target = vec4(1.0, 0.0, 0.0, 1.0);
o_Target = Albedo;
}

View file

@ -0,0 +1,29 @@
#version 450
layout(location = 0) in vec4 a_Pos;
layout(location = 1) in vec4 a_Normal;
layout(location = 2) in vec2 a_Uv;
layout(location = 0) out vec4 v_Position;
layout(location = 1) out vec3 v_Normal;
layout(location = 2) out vec2 v_Uv;
layout(set = 0, binding = 0) uniform Camera {
mat4 ViewProj;
};
layout(set = 1, binding = 0) uniform Object {
mat4 Model;
};
layout(set = 1, binding = 1) uniform StandardMaterial {
vec4 Albedo;
};
void main() {
v_Normal = mat3(Model) * vec3(a_Normal.xyz);
v_Position = Model * vec4(a_Pos);
// v_Normal = vec3(a_Normal.xyz);
// v_Position = vec4(a_Pos);
gl_Position = ViewProj * v_Position;
}

View file

@ -0,0 +1,98 @@
use crate::render::{
Vertex,
{
render_graph_2::{
mesh_draw_target, pipeline_layout::*, PipelineDescriptor,
RenderGraphBuilder,
},
shader::{Shader, ShaderStage},
},
};
pub trait ForwardFlatPipelineBuilder {
fn add_forward_flat_pipeline(self) -> Self;
}
impl ForwardFlatPipelineBuilder for RenderGraphBuilder {
fn add_forward_flat_pipeline(self) -> Self {
self.add_pipeline(
"forward_flat",
PipelineDescriptor::build(Shader::from_glsl(
include_str!("forward_flat.vert"),
ShaderStage::Vertex,
))
.with_fragment_shader(Shader::from_glsl(
include_str!("forward_flat.frag"),
ShaderStage::Fragment,
))
.add_bind_group(BindGroup::new(
vec![
Binding {
name: "Camera".to_string(),
bind_type: BindType::Uniform {
dynamic: false,
properties: vec![
UniformProperty {
name: "ViewProj".to_string(),
property_type: UniformPropertyType::Mat4,
},
]
}
},
]
))
.add_bind_group(BindGroup::new(
vec![
Binding {
name: "Object".to_string(),
bind_type: BindType::Uniform {
dynamic: true,
properties: vec![
UniformProperty {
name: "Model".to_string(),
property_type: UniformPropertyType::Mat4,
},
]
}
},
Binding {
name: "StandardMaterial".to_string(),
bind_type: BindType::Uniform {
dynamic: true,
properties: vec![
UniformProperty {
name: "Albedo".to_string(),
property_type: UniformPropertyType::Vec4,
},
]
}
},
]
))
.with_rasterization_state(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,
})
// .with_depth_stencil_state(wgpu::DepthStencilStateDescriptor {
// format: wgpu::TextureFormat::Depth32Float,
// 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,
// })
.add_color_state(wgpu::ColorStateDescriptor {
format: wgpu::TextureFormat::Bgra8UnormSrgb,
color_blend: wgpu::BlendDescriptor::REPLACE,
alpha_blend: wgpu::BlendDescriptor::REPLACE,
write_mask: wgpu::ColorWrite::ALL,
})
.add_vertex_buffer_descriptor(Vertex::get_vertex_buffer_descriptor())
.add_draw_target(mesh_draw_target)
.build(),
)
}
}

View file

@ -1,3 +1,5 @@
mod forward;
mod forward_flat;
pub use forward::*;
pub use forward::*;
pub use forward_flat::*;

View file

@ -4,4 +4,5 @@ pub mod texture {
pub mod uniform {
pub const CAMERA: &str = "Camera";
pub const LIGHTS: &str = "Lights";
}

View file

@ -1,7 +1,7 @@
use crate::render::{
use crate::{render::{
render_graph_2::{resource_name, Renderer},
ActiveCamera, Camera,
};
ActiveCamera, Camera, Light, LightRaw,
}, transform::prelude::Translation};
use bevy_transform::prelude::LocalToWorld;
use legion::prelude::*;
use zerocopy::AsBytes;
@ -33,11 +33,84 @@ impl ResourceProvider for CameraResourceProvider {
let camera_matrix: [[f32; 4]; 4] =
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
renderer.create_buffer_mapped("camera_tmp", matrix_size, wgpu::BufferUsage::COPY_SRC, &mut |data| {
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
});
renderer.create_buffer_mapped(
"camera_tmp",
matrix_size,
wgpu::BufferUsage::COPY_SRC,
&mut |data| {
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
},
);
renderer.copy_buffer_to_buffer("camera_tmp", 0, resource_name::uniform::CAMERA, 0, matrix_size as u64);
renderer.copy_buffer_to_buffer(
"camera_tmp",
0,
resource_name::uniform::CAMERA,
0,
matrix_size as u64,
);
}
}
}
}
pub struct LightResourceProvider {
pub lights_are_dirty: bool,
pub max_lights: usize,
}
impl LightResourceProvider {
pub fn new(max_lights: usize) -> Self {
LightResourceProvider {
lights_are_dirty: true,
max_lights: max_lights,
}
}
}
impl ResourceProvider for LightResourceProvider {
fn initialize(&mut self, renderer: &mut dyn Renderer, _world: &mut World) {
let light_uniform_size =
(self.max_lights * std::mem::size_of::<LightRaw>()) as wgpu::BufferAddress;
renderer.create_buffer(
resource_name::uniform::LIGHTS,
light_uniform_size,
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::COPY_DST,
);
}
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World) {
if self.lights_are_dirty {
let light_query = <(Read<Light>, Read<LocalToWorld>, Read<Translation>)>::query();
let light_count = light_query.iter(world).count();
if light_count == 0 {
return;
}
self.lights_are_dirty = false;
let size = std::mem::size_of::<LightRaw>();
let total_size = size * light_count;
renderer
.create_buffer_mapped("LIGHT_TMP", total_size, wgpu::BufferUsage::COPY_SRC, &mut |data| {
for ((light, local_to_world, translation), slot) in light_query
.iter(world)
.zip(data.chunks_exact_mut(size))
{
slot.copy_from_slice(
LightRaw::from(&light, &local_to_world.0, &translation).as_bytes(),
);
}
});
renderer.copy_buffer_to_buffer(
"LIGHT_TMP",
0,
resource_name::uniform::LIGHTS,
0,
total_size as wgpu::BufferAddress,
);
}
}
fn resize(&mut self, renderer: &mut dyn Renderer, world: &mut World, width: u32, height: u32) {}
}