1
0
Fork 0

tutorial6-uniforms

This commit is contained in:
Adrian Hedqvist 2020-09-13 21:30:10 +02:00
parent 176317f511
commit e9ae142a90
4 changed files with 429 additions and 32 deletions

188
Cargo.lock generated
View file

@ -557,6 +557,26 @@ dependencies = [
"byteorder",
]
[[package]]
name = "generic-array"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
dependencies = [
"typenum",
]
[[package]]
name = "getrandom"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "gfx-auxil"
version = "0.6.0"
@ -744,7 +764,7 @@ dependencies = [
"gif",
"jpeg-decoder",
"num-iter",
"num-rational",
"num-rational 0.3.0",
"num-traits",
"png",
"scoped_threadpool",
@ -895,6 +915,15 @@ dependencies = [
"libc",
]
[[package]]
name = "matrixmultiply"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f"
dependencies = [
"rawpointer",
]
[[package]]
name = "maybe-uninit"
version = "2.0.0"
@ -1015,6 +1044,36 @@ dependencies = [
"thiserror",
]
[[package]]
name = "nalgebra"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a3f0b89b0a44cb7bb9b62c5e6fd485145ddc6bc14483ab005355e96029b3fbf"
dependencies = [
"approx",
"generic-array",
"matrixmultiply",
"num-complex",
"num-rational 0.2.4",
"num-traits",
"rand",
"rand_distr",
"simba",
"typenum",
]
[[package]]
name = "nalgebra-glm"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e34d489ea638e56cec175e7dd7b253fc3cf21982f37d596a69d7b0cf3b0db235"
dependencies = [
"approx",
"nalgebra",
"num-traits",
"simba",
]
[[package]]
name = "ndk"
version = "0.1.0"
@ -1070,6 +1129,16 @@ dependencies = [
"void",
]
[[package]]
name = "num-complex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.43"
@ -1091,6 +1160,17 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.3.0"
@ -1233,6 +1313,25 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "paste"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
dependencies = [
"paste-impl",
"proc-macro-hack",
]
[[package]]
name = "paste-impl"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
dependencies = [
"proc-macro-hack",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
@ -1283,6 +1382,12 @@ dependencies = [
"miniz_oxide 0.3.7",
]
[[package]]
name = "ppv-lite86"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
[[package]]
name = "proc-macro-crate"
version = "0.1.5"
@ -1340,6 +1445,56 @@ dependencies = [
"proc-macro2 1.0.21",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_distr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
dependencies = [
"rand",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "range-alloc"
version = "0.1.1"
@ -1355,6 +1510,12 @@ dependencies = [
"libc",
]
[[package]]
name = "rawpointer"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
name = "rayon"
version = "1.4.0"
@ -1459,6 +1620,18 @@ dependencies = [
"libc",
]
[[package]]
name = "simba"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1585d831b5c904e42c4df7a4fcfa03e4b56a8cfa445aff0a04f4effe397ecac9"
dependencies = [
"approx",
"num-complex",
"num-traits",
"paste",
]
[[package]]
name = "slab"
version = "0.4.2"
@ -1614,6 +1787,12 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
[[package]]
name = "typenum"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
[[package]]
name = "unicode-xid"
version = "0.1.0"
@ -1643,6 +1822,12 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasm-bindgen"
version = "0.2.68"
@ -1837,6 +2022,7 @@ dependencies = [
"failure",
"futures",
"image",
"nalgebra-glm",
"shaderc",
"wgpu",
"winit",

View file

@ -14,3 +14,4 @@ futures = "0.3.5"
shaderc = "0.6.2"
bytemuck = "1.4.1"
failure = "0.1.8"
nalgebra-glm = "0.8.0"

View file

@ -5,8 +5,26 @@ use winit::{
window::{Window, WindowBuilder},
};
use nalgebra_glm as glm;
mod texture;
#[rustfmt::skip]
const VERTICES: &[Vertex] = &[
Vertex { position: [-0.0868241, 0.49240386, 0.0], tex_coords: [0.4131759, 0.00759614], },
Vertex { position: [-0.49513406, 0.06958647, 0.0], tex_coords: [0.0048659444, 0.43041354], },
Vertex { position: [-0.21918549, -0.44939706, 0.0], tex_coords: [0.28081453, 0.949397057], },
Vertex { position: [0.35966998, -0.3473291, 0.0], tex_coords: [0.85967, 0.84732911], },
Vertex { position: [0.44147372, 0.2347359, 0.0], tex_coords: [0.9414737, 0.2652641], },
];
#[rustfmt::skip]
const INDICES: &[u16] = &[
0, 1, 4,
1, 2, 4,
2, 3, 4
];
fn main() {
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
@ -53,6 +71,141 @@ fn main() {
});
}
struct Camera {
eye: glm::Vec3,
target: glm::Vec3,
up: glm::Vec3,
aspect: f32,
fovy: f32,
znear: f32,
zfar: f32,
}
impl Camera {
fn build_view_projection_matrix(&self) -> glm::Mat4 {
let view = glm::look_at(&self.eye, &self.target, &self.up);
let proj = glm::perspective(self.aspect, self.fovy, self.znear, self.zfar);
return proj * view;
}
}
struct CameraController {
speed: f32,
is_up_pressed: bool,
is_down_pressed: bool,
is_forward_pressed: bool,
is_backward_pressed: bool,
is_left_pressed: bool,
is_right_pressed: bool,
}
impl CameraController {
fn new(speed: f32) -> Self {
Self {
speed,
is_up_pressed: false,
is_down_pressed: false,
is_forward_pressed: false,
is_backward_pressed: false,
is_left_pressed: false,
is_right_pressed: false,
}
}
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input: KeyboardInput {
state,
virtual_keycode: Some(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::Space => {
self.is_up_pressed = is_pressed;
true
},
VirtualKeyCode::LControl => {
self.is_down_pressed = is_pressed;
true
},
VirtualKeyCode::W | VirtualKeyCode::Up => {
self.is_forward_pressed = is_pressed;
true
},
VirtualKeyCode::A | VirtualKeyCode::Left => {
self.is_left_pressed = is_pressed;
true
},
VirtualKeyCode::S | VirtualKeyCode::Down => {
self.is_backward_pressed = is_pressed;
true
},
VirtualKeyCode::D | VirtualKeyCode::Right => {
self.is_right_pressed = is_pressed;
true
},
_ => false
}
},
_ => false,
}
}
fn update_camera(&self, camera: &mut Camera) {
let forward = camera.target - camera.eye;
let forward_norm = glm::normalize(&forward);
let forward_mag = glm::magnitude(&forward);
// Prevents glitching when camera gets too close to the
// center of the scene.
if self.is_forward_pressed && forward_mag > self.speed {
camera.eye += forward_norm * self.speed;
}
if self.is_backward_pressed {
camera.eye -= forward_norm * self.speed;
}
let right = glm::cross(&forward_norm, &camera.up);
let forward = camera.target - camera.eye;
let forward_mag = glm::magnitude(&forward);
if self.is_right_pressed {
camera.eye = camera.target - glm::normalize(&(forward + right * self.speed)) * forward_mag;
}
if self.is_left_pressed {
camera.eye = camera.target - glm::normalize(&(forward - right * self.speed)) * forward_mag;
}
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct Uniforms {
view_proj: glm::Mat4,
}
impl Uniforms {
fn new() -> Self {
Self {
view_proj: glm::identity(),
}
}
fn update_view_proj(&mut self, camera: &Camera) {
self.view_proj = camera.build_view_projection_matrix();
}
}
unsafe impl bytemuck::Pod for Uniforms {}
unsafe impl bytemuck::Zeroable for Uniforms {}
struct State {
instance: wgpu::Instance,
surface: wgpu::Surface,
@ -65,6 +218,13 @@ struct State {
diffuse_texture: texture::Texture,
diffuse_bind_group: wgpu::BindGroup,
camera: Camera,
camera_controller: CameraController,
uniforms: Uniforms,
uniform_buffer: wgpu::Buffer,
uniform_bind_group: wgpu::BindGroup,
vertex_buffer: wgpu::Buffer,
index_buffer: wgpu::Buffer,
num_indices: u32,
@ -155,6 +315,56 @@ impl State {
],
});
// Camera
let camera = Camera {
eye: glm::vec3(0.0, 1.0, 2.0),
target: glm::vec3(0.0, 0.0, 0.0),
up: glm::vec3(0.0, 1.0, 0.0),
aspect: (sc_desc.width / sc_desc.height) as f32,
fovy: 45.0,
znear: 0.1,
zfar: 100.0,
};
let camera_controller = CameraController::new(0.2);
// Uniforms
let mut uniforms = Uniforms::new();
uniforms.update_view_proj(&camera);
let uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("uniform_buffer"),
contents: bytemuck::cast_slice(&[uniforms]),
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
});
let uniform_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("uniform_bind_group_layout"),
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX,
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
}
],
});
let uniform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("uniform_bind_group"),
layout: &uniform_bind_group_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer(uniform_buffer.slice(0..std::mem::size_of_val(&uniforms) as wgpu::BufferAddress)),
}
],
});
// Compile & load shaders
let vs_src = include_str!("shader.vert");
let fs_src = include_str!("shader.frag");
@ -203,7 +413,7 @@ impl State {
let render_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("render_pipeline_layout"),
bind_group_layouts: &[&texture_bind_group_layout],
bind_group_layouts: &[&texture_bind_group_layout, &uniform_bind_group_layout],
push_constant_ranges: &[],
});
@ -253,6 +463,11 @@ impl State {
swap_chain,
diffuse_texture,
diffuse_bind_group,
camera,
camera_controller,
uniforms,
uniform_buffer,
uniform_bind_group,
vertex_buffer,
index_buffer,
num_indices,
@ -269,12 +484,27 @@ impl State {
}
fn input(&mut self, event: &WindowEvent) -> bool {
match event {
_ => false,
}
self.camera_controller.process_events(event)
}
fn update(&mut self) {}
fn update(&mut self) {
self.camera_controller.update_camera(&mut self.camera);
self.uniforms.update_view_proj(&self.camera);
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("update encoder"),
});
let staging_buffer = self.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("staging_buffer"),
contents: bytemuck::cast_slice(&[self.uniforms]),
usage: wgpu::BufferUsage::COPY_SRC,
});
encoder.copy_buffer_to_buffer(&staging_buffer, 0, &self.uniform_buffer, 0, std::mem::size_of::<Uniforms>() as wgpu::BufferAddress);
self.queue.submit(Some(encoder.finish()));
}
fn render(&mut self) {
let frame = self
@ -307,6 +537,7 @@ impl State {
render_pass.set_pipeline(&self.render_pipeline);
render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]);
render_pass.set_bind_group(1, &self.uniform_bind_group, &[]);
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(0..));
render_pass.set_index_buffer(self.index_buffer.slice(0..));
render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
@ -348,28 +579,3 @@ impl Vertex {
}
}
}
const VERTICES: &[Vertex] = &[
Vertex {
position: [-0.0868241, 0.49240386, 0.0],
tex_coords: [0.4131759, 0.00759614],
},
Vertex {
position: [-0.49513406, 0.06958647, 0.0],
tex_coords: [0.0048659444, 0.43041354],
},
Vertex {
position: [-0.21918549, -0.44939706, 0.0],
tex_coords: [0.28081453, 0.949397057],
},
Vertex {
position: [0.35966998, -0.3473291, 0.0],
tex_coords: [0.85967, 0.84732911],
},
Vertex {
position: [0.44147372, 0.2347359, 0.0],
tex_coords: [0.9414737, 0.2652641],
},
];
const INDICES: &[u16] = &[0, 1, 4, 1, 2, 4, 2, 3, 4];

View file

@ -5,7 +5,11 @@ layout(location=1) in vec2 a_tex_coords;
layout(location=0) out vec2 v_tex_coords;
layout(set=1, binding=0) uniform Uniforms {
mat4 u_view_proj;
};
void main() {
gl_Position = vec4(a_position, 1.0);
v_tex_coords = a_tex_coords;
gl_Position = u_view_proj * vec4(a_position, 1.0);
}