Skip to content

Commit b2f58d0

Browse files
bors[bot]kvark
andcommitted
Merge #71
71: Shadow example r=grovesNL a=kvark ~~I believe all the nuts and bolts are in place, just figuring out some details of making the shadow match between the rendering and sampling (hence the WIP).~~ Most importantly, this PR includes crucial fixes and improvements of our resource tracking, plus a few fixes in the bind group and texture creation code. Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
2 parents 022087b + 616a3dd commit b2f58d0

27 files changed

+1250
-237
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ else
3030
endif
3131

3232

33-
.PHONY: all check test doc clear lib-native lib-rust examples-native examples-rust gfx-cube
33+
.PHONY: all check test doc clear lib-native lib-rust examples-native examples-rust gfx
3434

3535
all: examples-native examples-rust examples-gfx
3636

@@ -65,5 +65,5 @@ examples-rust: lib-rust examples/Cargo.toml $(wildcard wgpu-native/**/*.rs)
6565
examples-gfx: lib-rust gfx-examples/Cargo.toml $(wildcard gfx-examples/*.rs)
6666
cargo build --manifest-path gfx-examples/Cargo.toml --features $(FEATURE_RUST)
6767

68-
gfx-cube:
69-
cargo run --manifest-path gfx-examples/Cargo.toml --bin cube --features $(FEATURE_RUST)
68+
gfx:
69+
cargo run --manifest-path gfx-examples/Cargo.toml --bin $(name) --features $(FEATURE_RUST)

examples/hello_compute_rust/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,14 @@ fn main() {
8686
});
8787

8888
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
89-
encoder.copy_buffer_tobuffer(&staging_buffer, 0, &storage_buffer, 0, size);
89+
encoder.copy_buffer_to_buffer(&staging_buffer, 0, &storage_buffer, 0, size);
9090
{
9191
let mut cpass = encoder.begin_compute_pass();
9292
cpass.set_pipeline(&compute_pipeline);
9393
cpass.set_bind_group(0, &bind_group);
9494
cpass.dispatch(numbers.len() as u32, 1, 1);
9595
}
96-
encoder.copy_buffer_tobuffer(&storage_buffer, 0, &staging_buffer, 0, size);
96+
encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size);
9797

9898
// TODO: read the results back out of the staging buffer
9999

gfx-examples/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,13 @@ publish = false
1212
name = "cube"
1313
path = "src/cube.rs"
1414

15+
[[bin]]
16+
name = "shadow"
17+
path = "src/shadow.rs"
18+
1519
[features]
1620
default = []
21+
metal-auto-capture = ["wgpu/metal-auto-capture"]
1722
metal = ["wgpu/metal"]
1823
dx11 = ["wgpu/dx11"]
1924
dx12 = ["wgpu/dx12"]

gfx-examples/data/cube.vert

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ layout(set = 0, binding = 0) uniform Locals {
1111
void main() {
1212
v_TexCoord = a_TexCoord;
1313
gl_Position = u_Transform * a_Pos;
14+
// convert from -1,1 Z to 0,1
15+
gl_Position.z = 0.5 * (gl_Position.z + gl_Position.w);
1416
}

gfx-examples/data/shadow-bake.frag

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#version 450
2+
3+
void main() {
4+
}

gfx-examples/data/shadow-bake.vert

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#version 450
2+
3+
layout(location = 0) in ivec4 a_Pos;
4+
5+
layout(set = 0, binding = 0) uniform Globals {
6+
mat4 u_ViewProj;
7+
};
8+
9+
layout(set = 1, binding = 0) uniform Entity {
10+
mat4 u_World;
11+
vec4 u_Color;
12+
};
13+
14+
void main() {
15+
gl_Position = u_ViewProj * u_World * vec4(a_Pos);
16+
// convert from -1,1 Z to 0,1
17+
gl_Position.z = 0.5 * (gl_Position.z + gl_Position.w);
18+
}

gfx-examples/data/shadow-forward.frag

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#version 450
2+
3+
const int MAX_LIGHTS = 10;
4+
5+
layout(location = 0) in vec3 v_Normal;
6+
layout(location = 1) in vec4 v_Position;
7+
8+
layout(location = 0) out vec4 o_Target;
9+
10+
struct Light {
11+
mat4 proj;
12+
vec4 pos;
13+
vec4 color;
14+
};
15+
16+
layout(set = 0, binding = 0) uniform Globals {
17+
mat4 u_ViewProj;
18+
uvec4 u_NumLights;
19+
};
20+
layout(set = 0, binding = 1) uniform Lights {
21+
Light u_Lights[MAX_LIGHTS];
22+
};
23+
layout(set = 0, binding = 2) uniform texture2DArray t_Shadow;
24+
layout(set = 0, binding = 3) uniform samplerShadow s_Shadow;
25+
26+
layout(set = 1, binding = 0) uniform Entity {
27+
mat4 u_World;
28+
vec4 u_Color;
29+
};
30+
31+
32+
void main() {
33+
vec3 normal = normalize(v_Normal);
34+
vec3 ambient = vec3(0.05, 0.05, 0.05);
35+
// accumulate color
36+
vec3 color = ambient;
37+
for (int i=0; i<int(u_NumLights.x) && i<MAX_LIGHTS; ++i) {
38+
Light light = u_Lights[i];
39+
// project into the light space
40+
vec4 light_local = light.proj * v_Position;
41+
// compute texture coordinates for shadow lookup
42+
light_local.xyw = (light_local.xyz/light_local.w + 1.0) / 2.0;
43+
light_local.z = i;
44+
// do the lookup, using HW PCF and comparison
45+
float shadow = texture(sampler2DArrayShadow(t_Shadow, s_Shadow), light_local);
46+
// compute Lambertian diffuse term
47+
vec3 light_dir = normalize(light.pos.xyz - v_Position.xyz);
48+
float diffuse = max(0.0, dot(normal, light_dir));
49+
// add light contribution
50+
color += shadow * diffuse * light.color.xyz;
51+
}
52+
// multiply the light by material color
53+
o_Target = vec4(color, 1.0) * u_Color;
54+
}

gfx-examples/data/shadow-forward.vert

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#version 450
2+
3+
layout(location = 0) in ivec4 a_Pos;
4+
layout(location = 1) in ivec4 a_Normal;
5+
6+
layout(location = 0) out vec3 v_Normal;
7+
layout(location = 1) out vec4 v_Position;
8+
9+
layout(set = 0, binding = 0) uniform Globals {
10+
mat4 u_ViewProj;
11+
uvec4 u_NumLights;
12+
};
13+
layout(set = 1, binding = 0) uniform Entity {
14+
mat4 u_World;
15+
vec4 u_Color;
16+
};
17+
18+
void main() {
19+
v_Normal = mat3(u_World) * vec3(a_Normal.xyz);
20+
v_Position = u_World * vec4(a_Pos);
21+
gl_Position = u_ViewProj * v_Position;
22+
// convert from -1,1 Z to 0,1
23+
gl_Position.z = 0.5 * (gl_Position.z + gl_Position.w);
24+
}

gfx-examples/src/cube.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ fn create_texels(size: usize) -> Vec<u8> {
8383
.collect()
8484
}
8585

86-
struct Cube {
86+
struct Example {
8787
vertex_buf: wgpu::Buffer,
8888
index_buf: wgpu::Buffer,
8989
index_count: usize,
@@ -92,20 +92,20 @@ struct Cube {
9292
pipeline: wgpu::RenderPipeline,
9393
}
9494

95-
impl Cube {
95+
impl Example {
9696
fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4<f32> {
9797
let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 10.0);
9898
let mx_view = cgmath::Matrix4::look_at(
9999
cgmath::Point3::new(1.5f32, -5.0, 3.0),
100100
cgmath::Point3::new(0f32, 0.0, 0.0),
101-
cgmath::Vector3::unit_z(),
101+
-cgmath::Vector3::unit_z(),
102102
);
103103
mx_projection * mx_view
104104
}
105105
}
106106

107-
impl framework::Example for Cube {
108-
fn init(device: &mut wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self {
107+
impl framework::Example for Example {
108+
fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self {
109109
use std::mem;
110110

111111
let mut init_encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
@@ -293,7 +293,7 @@ impl framework::Example for Cube {
293293
// Done
294294
let init_command_buf = init_encoder.finish();
295295
device.get_queue().submit(&[init_command_buf]);
296-
Cube {
296+
Example {
297297
vertex_buf,
298298
index_buf,
299299
index_count: index_data.len(),
@@ -303,12 +303,14 @@ impl framework::Example for Cube {
303303
}
304304
}
305305

306-
fn update(&mut self, event: wgpu::winit::WindowEvent) {
307-
if let wgpu::winit::WindowEvent::Resized(size) = event {
308-
let mx_total = Self::generate_matrix(size.width as f32 / size.height as f32);
309-
let mx_ref: &[f32; 16] = mx_total.as_ref();
310-
self.uniform_buf.set_sub_data(0, framework::cast_slice(&mx_ref[..]));
311-
}
306+
fn update(&mut self, _event: wgpu::winit::WindowEvent) {
307+
//empty
308+
}
309+
310+
fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, _device: &mut wgpu::Device) {
311+
let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
312+
let mx_ref: &[f32; 16] = mx_total.as_ref();
313+
self.uniform_buf.set_sub_data(0, framework::cast_slice(&mx_ref[..]));
312314
}
313315

314316
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
@@ -337,5 +339,5 @@ impl framework::Example for Cube {
337339
}
338340

339341
fn main() {
340-
framework::run::<Cube>("cube");
342+
framework::run::<Example>("cube");
341343
}

gfx-examples/src/framework.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,20 @@ pub fn load_glsl(name: &str, stage: ShaderStage) -> Vec<u8> {
3030
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
3131
.join("data")
3232
.join(name);
33-
let code = read_to_string(path).unwrap();
33+
let code = match read_to_string(&path) {
34+
Ok(code) => code,
35+
Err(e) => panic!("Unable to read {:?}: {:?}", path, e),
36+
};
37+
3438
let mut output = glsl_to_spirv::compile(&code, ty).unwrap();
3539
let mut spv = Vec::new();
3640
output.read_to_end(&mut spv).unwrap();
3741
spv
3842
}
3943

4044
pub trait Example {
41-
fn init(device: &mut wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self;
45+
fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self;
46+
fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device);
4247
fn update(&mut self, event: wgpu::winit::WindowEvent);
4348
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device);
4449
}
@@ -79,7 +84,7 @@ pub fn run<E: Example>(title: &str) {
7984
let mut swap_chain = device.create_swap_chain(&surface, &sc_desc);
8085

8186
info!("Initializing the example...");
82-
let mut example = E::init(&mut device, &sc_desc);
87+
let mut example = E::init(&sc_desc, &mut device);
8388

8489
info!("Entering render loop...");
8590
let mut running = true;
@@ -95,7 +100,7 @@ pub fn run<E: Example>(title: &str) {
95100
sc_desc.width = physical.width as u32;
96101
sc_desc.height = physical.height as u32;
97102
swap_chain = device.create_swap_chain(&surface, &sc_desc);
98-
example.update(WindowEvent::Resized(size));
103+
example.resize(&sc_desc, &mut device);
99104
}
100105
Event::WindowEvent { event, .. } => match event {
101106
WindowEvent::KeyboardInput {
@@ -119,5 +124,6 @@ pub fn run<E: Example>(title: &str) {
119124

120125
let frame = swap_chain.get_next_texture();
121126
example.render(&frame, &mut device);
127+
running &= !cfg!(feature = "metal-auto-capture");
122128
}
123129
}

0 commit comments

Comments
 (0)