mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 08:13:27 +00:00
Shadow example shaders and improvements
This commit is contained in:
parent
957a5b57dd
commit
056cc64eb4
6
Makefile
6
Makefile
@ -30,7 +30,7 @@ else
|
|||||||
endif
|
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
|
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)
|
examples-gfx: lib-rust gfx-examples/Cargo.toml $(wildcard gfx-examples/*.rs)
|
||||||
cargo build --manifest-path gfx-examples/Cargo.toml --features $(FEATURE_RUST)
|
cargo build --manifest-path gfx-examples/Cargo.toml --features $(FEATURE_RUST)
|
||||||
|
|
||||||
gfx-cube:
|
gfx:
|
||||||
cargo run --manifest-path gfx-examples/Cargo.toml --bin cube --features $(FEATURE_RUST)
|
cargo run --manifest-path gfx-examples/Cargo.toml --bin $(name) --features $(FEATURE_RUST)
|
||||||
|
@ -86,14 +86,14 @@ fn main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
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();
|
let mut cpass = encoder.begin_compute_pass();
|
||||||
cpass.set_pipeline(&compute_pipeline);
|
cpass.set_pipeline(&compute_pipeline);
|
||||||
cpass.set_bind_group(0, &bind_group);
|
cpass.set_bind_group(0, &bind_group);
|
||||||
cpass.dispatch(numbers.len() as u32, 1, 1);
|
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
|
// TODO: read the results back out of the staging buffer
|
||||||
|
|
||||||
|
4
gfx-examples/data/shadow-bake.frag
Normal file
4
gfx-examples/data/shadow-bake.frag
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
}
|
16
gfx-examples/data/shadow-bake.vert
Normal file
16
gfx-examples/data/shadow-bake.vert
Normal file
@ -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);
|
||||||
|
}
|
10
gfx-examples/data/shadow-forward.frag
Normal file
10
gfx-examples/data/shadow-forward.frag
Normal file
@ -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);
|
||||||
|
}
|
25
gfx-examples/data/shadow-forward.vert
Normal file
25
gfx-examples/data/shadow-forward.vert
Normal file
@ -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);
|
||||||
|
}
|
@ -30,7 +30,11 @@ pub fn load_glsl(name: &str, stage: ShaderStage) -> Vec<u8> {
|
|||||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||||
.join("data")
|
.join("data")
|
||||||
.join(name);
|
.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 output = glsl_to_spirv::compile(&code, ty).unwrap();
|
||||||
let mut spv = Vec::new();
|
let mut spv = Vec::new();
|
||||||
output.read_to_end(&mut spv).unwrap();
|
output.read_to_end(&mut spv).unwrap();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::mem;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -82,6 +83,7 @@ fn create_plane(size: i8) -> (Vec<Vertex>, Vec<u16>) {
|
|||||||
|
|
||||||
struct Entity {
|
struct Entity {
|
||||||
mx_world: cgmath::Matrix4<f32>,
|
mx_world: cgmath::Matrix4<f32>,
|
||||||
|
color: wgpu::Color,
|
||||||
vertex_buf: Rc<wgpu::Buffer>,
|
vertex_buf: Rc<wgpu::Buffer>,
|
||||||
index_buf: Rc<wgpu::Buffer>,
|
index_buf: Rc<wgpu::Buffer>,
|
||||||
index_count: usize,
|
index_count: usize,
|
||||||
@ -99,9 +101,9 @@ struct Light {
|
|||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct LightRaw {
|
struct LightRaw {
|
||||||
|
proj: [[f32; 4]; 4],
|
||||||
pos: [f32; 4],
|
pos: [f32; 4],
|
||||||
color: [f32; 4],
|
color: [f32; 4],
|
||||||
proj: [[f32; 4]; 4],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Light {
|
impl Light {
|
||||||
@ -131,10 +133,15 @@ impl Light {
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct ForwardUniforms {
|
struct ForwardUniforms {
|
||||||
proj: [[f32; 4]; 4],
|
proj: [[f32; 4]; 4],
|
||||||
color: [f32; 4],
|
|
||||||
num_lights: [u32; 4],
|
num_lights: [u32; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct EntityUniforms {
|
||||||
|
model: [[f32; 4]; 4],
|
||||||
|
color: [f32; 4],
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct ShadowUniforms {
|
struct ShadowUniforms {
|
||||||
proj: [[f32; 4]; 4],
|
proj: [[f32; 4]; 4],
|
||||||
@ -177,8 +184,6 @@ impl Example {
|
|||||||
|
|
||||||
impl framework::Example for Example {
|
impl framework::Example for Example {
|
||||||
fn init(device: &mut wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self {
|
fn init(device: &mut wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self {
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
// Create the vertex and index buffers
|
// Create the vertex and index buffers
|
||||||
let vertex_size = mem::size_of::<Vertex>();
|
let vertex_size = mem::size_of::<Vertex>();
|
||||||
let (cube_vertex_data, cube_index_data) = create_cube();
|
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,
|
usage: wgpu::BufferUsageFlags::INDEX | wgpu::BufferUsageFlags::TRANSFER_DST,
|
||||||
});
|
});
|
||||||
plane_index_buf.set_sub_data(0, framework::cast_slice(&plane_index_data));
|
plane_index_buf.set_sub_data(0, framework::cast_slice(&plane_index_data));
|
||||||
|
let entity_uniform_size = mem::size_of::<EntityUniforms>() as u32;
|
||||||
let plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
let plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
size: 64,
|
size: entity_uniform_size,
|
||||||
usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST,
|
usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -229,13 +235,14 @@ impl framework::Example for Example {
|
|||||||
binding: 0,
|
binding: 0,
|
||||||
resource: wgpu::BindingResource::Buffer {
|
resource: wgpu::BindingResource::Buffer {
|
||||||
buffer: &plane_uniform_buf,
|
buffer: &plane_uniform_buf,
|
||||||
range: 0 .. 64,
|
range: 0 .. entity_uniform_size,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
Entity {
|
Entity {
|
||||||
mx_world: cgmath::Matrix4::identity(),
|
mx_world: cgmath::Matrix4::identity(),
|
||||||
|
color: wgpu::Color::WHITE,
|
||||||
vertex_buf: Rc::new(plane_vertex_buf),
|
vertex_buf: Rc::new(plane_vertex_buf),
|
||||||
index_buf: Rc::new(plane_index_buf),
|
index_buf: Rc::new(plane_index_buf),
|
||||||
index_count: plane_index_data.len(),
|
index_count: plane_index_data.len(),
|
||||||
@ -284,11 +291,12 @@ impl framework::Example for Example {
|
|||||||
scale: cube.scale,
|
scale: cube.scale,
|
||||||
};
|
};
|
||||||
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
size: 64,
|
size: entity_uniform_size,
|
||||||
usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST,
|
usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST,
|
||||||
});
|
});
|
||||||
entities.push(Entity {
|
entities.push(Entity {
|
||||||
mx_world: cgmath::Matrix4::from(transform),
|
mx_world: cgmath::Matrix4::from(transform),
|
||||||
|
color: wgpu::Color::GREEN,
|
||||||
vertex_buf: Rc::clone(&cube_vertex_buf),
|
vertex_buf: Rc::clone(&cube_vertex_buf),
|
||||||
index_buf: Rc::clone(&cube_index_buf),
|
index_buf: Rc::clone(&cube_index_buf),
|
||||||
index_count: cube_index_data.len(),
|
index_count: cube_index_data.len(),
|
||||||
@ -299,7 +307,7 @@ impl framework::Example for Example {
|
|||||||
binding: 0,
|
binding: 0,
|
||||||
resource: wgpu::BindingResource::Buffer {
|
resource: wgpu::BindingResource::Buffer {
|
||||||
buffer: &uniform_buf,
|
buffer: &uniform_buf,
|
||||||
range: 0 .. 64,
|
range: 0 .. entity_uniform_size,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -421,7 +429,7 @@ impl framework::Example for Example {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Create the render pipeline
|
// 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 fs_bytes = framework::load_glsl("shadow-bake.frag", framework::ShaderStage::Fragment);
|
||||||
let vs_module = device.create_shader_module(&vs_bytes);
|
let vs_module = device.create_shader_module(&vs_bytes);
|
||||||
let fs_module = device.create_shader_module(&fs_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 mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
|
||||||
let data = ForwardUniforms {
|
let data = ForwardUniforms {
|
||||||
proj: *mx_total.as_ref(),
|
proj: *mx_total.as_ref(),
|
||||||
color: [1.0; 4],
|
|
||||||
num_lights: [lights.len() as u32, 0, 0, 0],
|
num_lights: [lights.len() as u32, 0, 0, 0],
|
||||||
};
|
};
|
||||||
uniform_buf.set_sub_data(0, framework::cast_slice(&[data]));
|
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) {
|
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
|
||||||
for entity in &self.entities {
|
for entity in &self.entities {
|
||||||
let raw: &[f32; 16] = entity.mx_world.as_ref();
|
let data = EntityUniforms {
|
||||||
entity.uniform_buf.set_sub_data(0, framework::cast_slice(&raw[..]));
|
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 {
|
if self.lights_are_dirty {
|
||||||
self.lights_are_dirty = false;
|
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 });
|
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||||
|
|
||||||
for (_i, light) in self.lights.iter().enumerate() {
|
for (i, light) in self.lights.iter().enumerate() {
|
||||||
//TODO: update light uniforms
|
// 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::<LightRaw>()) as u32,
|
||||||
|
&self.shadow_pass.uniform_buf,
|
||||||
|
0,
|
||||||
|
64,
|
||||||
|
);
|
||||||
|
|
||||||
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
color_attachments: &[],
|
color_attachments: &[],
|
||||||
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
|
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
|
||||||
@ -656,8 +675,8 @@ impl framework::Example for Example {
|
|||||||
}],
|
}],
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
});
|
});
|
||||||
pass.set_pipeline(&self.shadow_pass.pipeline);
|
pass.set_pipeline(&self.forward_pass.pipeline);
|
||||||
pass.set_bind_group(0, &self.shadow_pass.bind_group);
|
pass.set_bind_group(0, &self.forward_pass.bind_group);
|
||||||
|
|
||||||
for entity in &self.entities {
|
for entity in &self.entities {
|
||||||
pass.set_bind_group(1, &entity.bind_group);
|
pass.set_bind_group(1, &entity.bind_group);
|
||||||
|
@ -535,7 +535,7 @@ impl CommandEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_buffer_tobuffer(
|
pub fn copy_buffer_to_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
source: &Buffer,
|
source: &Buffer,
|
||||||
source_offset: u32,
|
source_offset: u32,
|
||||||
|
Loading…
Reference in New Issue
Block a user