From 056cc64eb4cb6616305275d9d7fe18c98d07719d Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 22 Feb 2019 10:26:29 -0500 Subject: [PATCH] Shadow example shaders and improvements --- Makefile | 6 ++-- examples/hello_compute_rust/main.rs | 4 +-- gfx-examples/data/shadow-bake.frag | 4 +++ gfx-examples/data/shadow-bake.vert | 16 +++++++++ gfx-examples/data/shadow-forward.frag | 10 ++++++ gfx-examples/data/shadow-forward.vert | 25 +++++++++++++ gfx-examples/src/framework.rs | 6 +++- gfx-examples/src/shadow.rs | 51 ++++++++++++++++++--------- wgpu-rs/src/lib.rs | 2 +- 9 files changed, 101 insertions(+), 23 deletions(-) create mode 100644 gfx-examples/data/shadow-bake.frag create mode 100644 gfx-examples/data/shadow-bake.vert create mode 100644 gfx-examples/data/shadow-forward.frag create mode 100644 gfx-examples/data/shadow-forward.vert diff --git a/Makefile b/Makefile index ef08a5b1e..9b183aec1 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ else endif -.PHONY: all check test doc clear lib-native lib-rust examples-native examples-rust gfx-cube +.PHONY: all check test doc clear lib-native lib-rust examples-native examples-rust gfx all: examples-native examples-rust examples-gfx @@ -65,5 +65,5 @@ examples-rust: lib-rust examples/Cargo.toml $(wildcard wgpu-native/**/*.rs) examples-gfx: lib-rust gfx-examples/Cargo.toml $(wildcard gfx-examples/*.rs) cargo build --manifest-path gfx-examples/Cargo.toml --features $(FEATURE_RUST) -gfx-cube: - cargo run --manifest-path gfx-examples/Cargo.toml --bin cube --features $(FEATURE_RUST) +gfx: + cargo run --manifest-path gfx-examples/Cargo.toml --bin $(name) --features $(FEATURE_RUST) diff --git a/examples/hello_compute_rust/main.rs b/examples/hello_compute_rust/main.rs index d2e74ca8c..310426b24 100644 --- a/examples/hello_compute_rust/main.rs +++ b/examples/hello_compute_rust/main.rs @@ -86,14 +86,14 @@ fn main() { }); let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - encoder.copy_buffer_tobuffer(&staging_buffer, 0, &storage_buffer, 0, size); + encoder.copy_buffer_to_buffer(&staging_buffer, 0, &storage_buffer, 0, size); { let mut cpass = encoder.begin_compute_pass(); cpass.set_pipeline(&compute_pipeline); cpass.set_bind_group(0, &bind_group); cpass.dispatch(numbers.len() as u32, 1, 1); } - encoder.copy_buffer_tobuffer(&storage_buffer, 0, &staging_buffer, 0, size); + encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size); // TODO: read the results back out of the staging buffer diff --git a/gfx-examples/data/shadow-bake.frag b/gfx-examples/data/shadow-bake.frag new file mode 100644 index 000000000..f0bcb49bf --- /dev/null +++ b/gfx-examples/data/shadow-bake.frag @@ -0,0 +1,4 @@ +#version 450 + +void main() { +} diff --git a/gfx-examples/data/shadow-bake.vert b/gfx-examples/data/shadow-bake.vert new file mode 100644 index 000000000..e4426b745 --- /dev/null +++ b/gfx-examples/data/shadow-bake.vert @@ -0,0 +1,16 @@ +#version 450 + +layout(location = 0) in ivec4 a_Pos; + +layout(set = 0, binding = 0) uniform Globals { + mat4 u_ViewProj; +}; + +layout(set = 1, binding = 0) uniform Entity { + mat4 u_World; + vec4 u_Color; +}; + +void main() { + gl_Position = u_ViewProj * u_World * vec4(a_Pos); +} diff --git a/gfx-examples/data/shadow-forward.frag b/gfx-examples/data/shadow-forward.frag new file mode 100644 index 000000000..22c79b3e9 --- /dev/null +++ b/gfx-examples/data/shadow-forward.frag @@ -0,0 +1,10 @@ +#version 450 + +layout(location = 0) out vec4 o_Target; + +layout(set = 0, binding = 2) uniform texture2D u_ShadowTexture; +layout(set = 0, binding = 3) uniform sampler u_ShadowSampler; + +void main() { + o_Target = vec4(1.0); +} diff --git a/gfx-examples/data/shadow-forward.vert b/gfx-examples/data/shadow-forward.vert new file mode 100644 index 000000000..c100fed42 --- /dev/null +++ b/gfx-examples/data/shadow-forward.vert @@ -0,0 +1,25 @@ +#version 450 + +layout(location = 0) in ivec4 a_Pos; +layout(location = 1) in ivec4 a_Normal; + +struct Light { + mat4 proj; + vec4 color; +}; + +layout(set = 0, binding = 0) uniform Globals { + mat4 u_ViewProj; + uvec4 u_NumLights; +}; +layout(set = 0, binding = 1) uniform Lights { + Light u_Lights[]; +}; +layout(set = 1, binding = 0) uniform Entity { + mat4 u_World; + vec4 u_Color; +}; + +void main() { + gl_Position = u_ViewProj * u_World * vec4(a_Pos); +} diff --git a/gfx-examples/src/framework.rs b/gfx-examples/src/framework.rs index ec0514ef7..dec148427 100644 --- a/gfx-examples/src/framework.rs +++ b/gfx-examples/src/framework.rs @@ -30,7 +30,11 @@ pub fn load_glsl(name: &str, stage: ShaderStage) -> Vec { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("data") .join(name); - let code = read_to_string(path).unwrap(); + let code = match read_to_string(&path) { + Ok(code) => code, + Err(e) => panic!("Unable to read {:?}: {:?}", path, e), + }; + let mut output = glsl_to_spirv::compile(&code, ty).unwrap(); let mut spv = Vec::new(); output.read_to_end(&mut spv).unwrap(); diff --git a/gfx-examples/src/shadow.rs b/gfx-examples/src/shadow.rs index 55b59efeb..f0dd5ce40 100644 --- a/gfx-examples/src/shadow.rs +++ b/gfx-examples/src/shadow.rs @@ -1,3 +1,4 @@ +use std::mem; use std::ops::Range; use std::rc::Rc; @@ -82,6 +83,7 @@ fn create_plane(size: i8) -> (Vec, Vec) { struct Entity { mx_world: cgmath::Matrix4, + color: wgpu::Color, vertex_buf: Rc, index_buf: Rc, index_count: usize, @@ -99,9 +101,9 @@ struct Light { #[repr(C)] struct LightRaw { + proj: [[f32; 4]; 4], pos: [f32; 4], color: [f32; 4], - proj: [[f32; 4]; 4], } impl Light { @@ -131,10 +133,15 @@ impl Light { #[repr(C)] struct ForwardUniforms { proj: [[f32; 4]; 4], - color: [f32; 4], num_lights: [u32; 4], } +#[repr(C)] +struct EntityUniforms { + model: [[f32; 4]; 4], + color: [f32; 4], +} + #[repr(C)] struct ShadowUniforms { proj: [[f32; 4]; 4], @@ -177,8 +184,6 @@ impl Example { impl framework::Example for Example { fn init(device: &mut wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self { - use std::mem; - // Create the vertex and index buffers let vertex_size = mem::size_of::(); let (cube_vertex_data, cube_index_data) = create_cube(); @@ -204,8 +209,9 @@ impl framework::Example for Example { usage: wgpu::BufferUsageFlags::INDEX | wgpu::BufferUsageFlags::TRANSFER_DST, }); plane_index_buf.set_sub_data(0, framework::cast_slice(&plane_index_data)); + let entity_uniform_size = mem::size_of::() as u32; let plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { - size: 64, + size: entity_uniform_size, usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST, }); @@ -229,13 +235,14 @@ impl framework::Example for Example { binding: 0, resource: wgpu::BindingResource::Buffer { buffer: &plane_uniform_buf, - range: 0 .. 64, + range: 0 .. entity_uniform_size, }, }, ], }); Entity { mx_world: cgmath::Matrix4::identity(), + color: wgpu::Color::WHITE, vertex_buf: Rc::new(plane_vertex_buf), index_buf: Rc::new(plane_index_buf), index_count: plane_index_data.len(), @@ -284,11 +291,12 @@ impl framework::Example for Example { scale: cube.scale, }; let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { - size: 64, + size: entity_uniform_size, usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST, }); entities.push(Entity { mx_world: cgmath::Matrix4::from(transform), + color: wgpu::Color::GREEN, vertex_buf: Rc::clone(&cube_vertex_buf), index_buf: Rc::clone(&cube_index_buf), index_count: cube_index_data.len(), @@ -299,7 +307,7 @@ impl framework::Example for Example { binding: 0, resource: wgpu::BindingResource::Buffer { buffer: &uniform_buf, - range: 0 .. 64, + range: 0 .. entity_uniform_size, }, }, ], @@ -421,7 +429,7 @@ impl framework::Example for Example { }); // Create the render pipeline - let vs_bytes = framework::load_glsl("shadow-base.vert", framework::ShaderStage::Vertex); + let vs_bytes = framework::load_glsl("shadow-bake.vert", framework::ShaderStage::Vertex); let fs_bytes = framework::load_glsl("shadow-bake.frag", framework::ShaderStage::Fragment); let vs_module = device.create_shader_module(&vs_bytes); let fs_module = device.create_shader_module(&fs_bytes); @@ -507,7 +515,6 @@ impl framework::Example for Example { let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let data = ForwardUniforms { proj: *mx_total.as_ref(), - color: [1.0; 4], num_lights: [lights.len() as u32, 0, 0, 0], }; uniform_buf.set_sub_data(0, framework::cast_slice(&[data])); @@ -606,8 +613,11 @@ impl framework::Example for Example { fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) { for entity in &self.entities { - let raw: &[f32; 16] = entity.mx_world.as_ref(); - entity.uniform_buf.set_sub_data(0, framework::cast_slice(&raw[..])); + let data = EntityUniforms { + model: *entity.mx_world.as_ref(), + color: [entity.color.r, entity.color.g, entity.color.b, entity.color.a], + }; + entity.uniform_buf.set_sub_data(0, framework::cast_slice(&[data])); } if self.lights_are_dirty { self.lights_are_dirty = false; @@ -620,8 +630,17 @@ impl framework::Example for Example { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - for (_i, light) in self.lights.iter().enumerate() { - //TODO: update light uniforms + for (i, light) in self.lights.iter().enumerate() { + // The light uniform buffer already has the projection, + // let's just copy it over to the shadow uniform buffer. + encoder.copy_buffer_to_buffer( + &self.light_uniform_buf, + (i * mem::size_of::()) as u32, + &self.shadow_pass.uniform_buf, + 0, + 64, + ); + let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { color_attachments: &[], depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor { @@ -656,8 +675,8 @@ impl framework::Example for Example { }], depth_stencil_attachment: None, }); - pass.set_pipeline(&self.shadow_pass.pipeline); - pass.set_bind_group(0, &self.shadow_pass.bind_group); + pass.set_pipeline(&self.forward_pass.pipeline); + pass.set_bind_group(0, &self.forward_pass.bind_group); for entity in &self.entities { pass.set_bind_group(1, &entity.bind_group); diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs index 1c678b88e..c0ad705dc 100644 --- a/wgpu-rs/src/lib.rs +++ b/wgpu-rs/src/lib.rs @@ -535,7 +535,7 @@ impl CommandEncoder { } } - pub fn copy_buffer_tobuffer( + pub fn copy_buffer_to_buffer( &mut self, source: &Buffer, source_offset: u32,