steal some stuff from sotrh/learn-wgpu/tree/cleanup-nov2020
This commit is contained in:
parent
003338b828
commit
51e8263503
9 changed files with 605 additions and 489 deletions
784
Cargo.lock
generated
784
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
26
Cargo.toml
26
Cargo.toml
|
@ -8,18 +8,18 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
wgpu = "0.6.0"
|
||||
winit = "0.22.2"
|
||||
image = "0.23.9"
|
||||
futures = "0.3.5"
|
||||
bytemuck = "1.4.1"
|
||||
anyhow = "1.0.33"
|
||||
env_logger = "0.7.1"
|
||||
log = "0.4.11"
|
||||
tobj = "2.0.2"
|
||||
cgmath = "0.17.0"
|
||||
winit = "0.23.0"
|
||||
image = "0.23"
|
||||
futures = "0.3"
|
||||
bytemuck = { version="1.4", features = ["derive"] }
|
||||
anyhow = "1"
|
||||
env_logger = "0.8"
|
||||
log = "0.4"
|
||||
tobj = "2"
|
||||
cgmath = "0.17"
|
||||
|
||||
[build-dependencies]
|
||||
shaderc = "0.6.2"
|
||||
fs_extra = "1.2"
|
||||
anyhow = "1.0.33"
|
||||
glob = "0.3.0"
|
||||
shaderc = "0.7"
|
||||
fs_extra = "1"
|
||||
anyhow = "1"
|
||||
glob = "0.3"
|
||||
|
|
6
build.rs
6
build.rs
|
@ -41,8 +41,6 @@ impl ShaderData {
|
|||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
println!("cargo:rerun-if-changed=src/*");
|
||||
|
||||
let mut shader_paths = [
|
||||
glob("./src/**/*.vert")?,
|
||||
glob("./src/**/*.frag")?,
|
||||
|
@ -58,6 +56,10 @@ fn main() -> Result<()> {
|
|||
let mut compiler = shaderc::Compiler::new().context("Unable to create shader compiler")?;
|
||||
|
||||
for shader in shaders? {
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
&shader.src_path.as_os_str().to_str().unwrap()
|
||||
);
|
||||
let compiled = compiler.compile_into_spirv(
|
||||
&shader.src,
|
||||
shader.kind,
|
||||
|
|
|
@ -88,27 +88,33 @@ impl CameraController {
|
|||
}
|
||||
|
||||
pub fn update_camera(&self, camera: &mut Camera) {
|
||||
let forward = camera.target - camera.eye;
|
||||
let forward_norm = forward.normalize();
|
||||
let forward_mag = forward.magnitude();
|
||||
let mut forward = camera.target - camera.eye;
|
||||
let mut forward_norm = forward.normalize();
|
||||
let mut forward_mag = forward.magnitude();
|
||||
|
||||
// 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;
|
||||
if self.is_forward_pressed != self.is_backward_pressed {
|
||||
// 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;
|
||||
}
|
||||
else if self.is_backward_pressed {
|
||||
camera.eye -= forward_norm * self.speed;
|
||||
}
|
||||
forward = camera.target - camera.eye;
|
||||
forward_norm = forward.normalize();
|
||||
forward_mag = forward.magnitude();
|
||||
}
|
||||
|
||||
let right = forward_norm.cross(camera.up);
|
||||
|
||||
if self.is_right_pressed {
|
||||
camera.eye = camera.target - (forward - right * self.speed).normalize() * forward_mag;
|
||||
}
|
||||
|
||||
if self.is_left_pressed {
|
||||
camera.eye = camera.target - (forward + right * self.speed).normalize() * forward_mag;
|
||||
if self.is_right_pressed != self.is_left_pressed {
|
||||
if self.is_right_pressed {
|
||||
camera.eye = camera.target - (forward - right * self.speed).normalize() * forward_mag;
|
||||
}
|
||||
else if self.is_left_pressed {
|
||||
camera.eye = camera.target - (forward + right * self.speed).normalize() * forward_mag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
src/light.rs
13
src/light.rs
|
@ -1,21 +1,18 @@
|
|||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
pub struct Light {
|
||||
pub position: cgmath::Vector3<f32>,
|
||||
pub position: [f32; 3],
|
||||
// according to the tutorial I'm following, uniforms require 16 byte padding. So that's why this thing is here.
|
||||
_padding: u32,
|
||||
pub color: cgmath::Vector3<f32>,
|
||||
pub color: [f32; 3],
|
||||
}
|
||||
|
||||
impl Light {
|
||||
pub fn new(position: cgmath::Vector3<f32>, color: cgmath::Vector3<f32>) -> Self {
|
||||
Self {
|
||||
position,
|
||||
position: position.into(),
|
||||
_padding: 0,
|
||||
color,
|
||||
color: color.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl bytemuck::Pod for Light {}
|
||||
unsafe impl bytemuck::Zeroable for Light {}
|
||||
|
|
161
src/main.rs
161
src/main.rs
|
@ -8,13 +8,20 @@ use winit::{
|
|||
|
||||
use cgmath::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.5, 0.0,
|
||||
0.0, 0.0, 0.5, 1.0,
|
||||
);
|
||||
|
||||
mod camera;
|
||||
mod light;
|
||||
mod model;
|
||||
mod texture;
|
||||
|
||||
type Vec3 = cgmath::Vector3<f32>;
|
||||
type Mat4 = cgmath::Matrix4<f32>;
|
||||
|
||||
const NUM_INSTANCES_PER_ROW: u32 = 11;
|
||||
|
||||
|
@ -56,7 +63,15 @@ fn main() {
|
|||
}
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
state.render();
|
||||
match state.render() {
|
||||
Ok(_) => {}
|
||||
Err(wgpu::SwapChainError::Lost) => state.resize(state.size),
|
||||
Err(wgpu::SwapChainError::OutOfMemory) => {
|
||||
eprintln!("Recieved a swapchain OOM error, exiting...");
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
Err(_) => {}
|
||||
};
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
state.update();
|
||||
|
@ -67,29 +82,26 @@ fn main() {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
struct Uniforms {
|
||||
view_position: cgmath::Vector4<f32>,
|
||||
view_proj: Mat4,
|
||||
view_position: [f32; 4],
|
||||
view_proj: [[f32; 4]; 4],
|
||||
}
|
||||
|
||||
impl Uniforms {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
view_position: Zero::zero(),
|
||||
view_proj: cgmath::Matrix4::identity(),
|
||||
view_position: [0.0; 4],
|
||||
view_proj: cgmath::Matrix4::identity().into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn update_view_proj(&mut self, camera: &camera::Camera) {
|
||||
self.view_position = camera.eye.to_homogeneous();
|
||||
self.view_proj = camera.build_view_projection_matrix();
|
||||
self.view_position = camera.eye.to_homogeneous().into();
|
||||
self.view_proj = (OPENGL_TO_WGPU_MATRIX * camera.build_view_projection_matrix()).into();
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl bytemuck::Pod for Uniforms {}
|
||||
unsafe impl bytemuck::Zeroable for Uniforms {}
|
||||
|
||||
struct Instance {
|
||||
position: cgmath::Vector3<f32>,
|
||||
rotation: cgmath::Quaternion<f32>,
|
||||
|
@ -98,21 +110,58 @@ struct Instance {
|
|||
impl Instance {
|
||||
fn to_raw(&self) -> InstanceRaw {
|
||||
InstanceRaw {
|
||||
model: cgmath::Matrix4::from_translation(self.position)
|
||||
* cgmath::Matrix4::from(self.rotation),
|
||||
model: (cgmath::Matrix4::from_translation(self.position)
|
||||
* cgmath::Matrix4::from(self.rotation))
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl model::Vertex for InstanceRaw {
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<InstanceRaw>() as wgpu::BufferAddress,
|
||||
// We need to switch from using a step mode of Vertex to Instance
|
||||
// This means that our shaders will only change to use the next
|
||||
// instance when the shader starts processing a new instance
|
||||
step_mode: wgpu::InputStepMode::Instance,
|
||||
attributes: &[
|
||||
wgpu::VertexAttributeDescriptor {
|
||||
offset: 0,
|
||||
// While our vertex shader only uses locations 0, and 1 now, in later tutorials we'll
|
||||
// be using 2, 3, and 4, for Vertex. We'll start at slot 5 not conflict with them later
|
||||
shader_location: 5,
|
||||
format: wgpu::VertexFormat::Float4,
|
||||
},
|
||||
// A mat4 takes up 4 vertex slots as it is technically 4 vec4s. We need to define a slot
|
||||
// for each vec4. We don't have to do this in code though.
|
||||
wgpu::VertexAttributeDescriptor {
|
||||
offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
|
||||
shader_location: 6,
|
||||
format: wgpu::VertexFormat::Float4,
|
||||
},
|
||||
wgpu::VertexAttributeDescriptor {
|
||||
offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
|
||||
shader_location: 7,
|
||||
format: wgpu::VertexFormat::Float4,
|
||||
},
|
||||
wgpu::VertexAttributeDescriptor {
|
||||
offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress,
|
||||
shader_location: 8,
|
||||
format: wgpu::VertexFormat::Float4,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
struct InstanceRaw {
|
||||
model: Mat4,
|
||||
model: [[f32; 4]; 4],
|
||||
}
|
||||
|
||||
unsafe impl bytemuck::Pod for InstanceRaw {}
|
||||
unsafe impl bytemuck::Zeroable for InstanceRaw {}
|
||||
|
||||
struct State {
|
||||
_instance: wgpu::Instance,
|
||||
surface: wgpu::Surface,
|
||||
|
@ -133,7 +182,7 @@ struct State {
|
|||
|
||||
obj_model: Model,
|
||||
instances: Vec<Instance>,
|
||||
_instance_buffer: wgpu::Buffer,
|
||||
instance_buffer: wgpu::Buffer,
|
||||
|
||||
light: light::Light,
|
||||
light_buffer: wgpu::Buffer,
|
||||
|
@ -238,9 +287,9 @@ impl State {
|
|||
(0..NUM_INSTANCES_PER_ROW).map(move |x| {
|
||||
let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
|
||||
let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
|
||||
let position: Vec3 = (x, 0.0, z).into();
|
||||
let position = Vec3 {x, y: 0.0, z};
|
||||
|
||||
let rotation = if Vec3::zero() == position {
|
||||
let rotation = if position.is_zero() {
|
||||
cgmath::Quaternion::from_axis_angle(Vec3::unit_z(), cgmath::Deg(0.0))
|
||||
} else {
|
||||
cgmath::Quaternion::from_axis_angle(position.normalize(), cgmath::Deg(45.0))
|
||||
|
@ -254,13 +303,13 @@ impl State {
|
|||
let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("instance_buffer"),
|
||||
contents: bytemuck::cast_slice(&instance_data),
|
||||
usage: wgpu::BufferUsage::STORAGE,
|
||||
usage: wgpu::BufferUsage::VERTEX,
|
||||
});
|
||||
|
||||
let camera = camera::Camera {
|
||||
eye: (0.0, 1.0, 2.0).into(),
|
||||
eye: (0.0, 5.0, -10.0).into(),
|
||||
target: (0.0, 0.0, 0.0).into(),
|
||||
up: (0.0, 1.0, 0.0).into(),
|
||||
up: cgmath::Vector3::unit_y(),
|
||||
aspect: sc_desc.width as f32 / sc_desc.height as f32,
|
||||
fovy: 45.0,
|
||||
znear: 0.1,
|
||||
|
@ -281,42 +330,24 @@ impl State {
|
|||
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 | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX,
|
||||
ty: wgpu::BindingType::StorageBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
readonly: true,
|
||||
},
|
||||
count: 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(..)),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::Buffer(instance_buffer.slice(..)),
|
||||
},
|
||||
],
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer(uniform_buffer.slice(..)),
|
||||
}],
|
||||
});
|
||||
|
||||
// Lights
|
||||
|
@ -367,7 +398,7 @@ impl State {
|
|||
&layout,
|
||||
sc_desc.format,
|
||||
Some(texture::Texture::DEPTH_FORMAT),
|
||||
&[model::ModelVertex::desc()],
|
||||
&[model::ModelVertex::desc(), InstanceRaw::desc()],
|
||||
wgpu::include_spirv!("shader.vert.spv"),
|
||||
wgpu::include_spirv!("shader.frag.spv"),
|
||||
)
|
||||
|
@ -414,7 +445,7 @@ impl State {
|
|||
light_bind_group,
|
||||
light_render_pipeline,
|
||||
instances,
|
||||
_instance_buffer: instance_buffer,
|
||||
instance_buffer,
|
||||
render_pipeline,
|
||||
size,
|
||||
}
|
||||
|
@ -460,20 +491,19 @@ impl State {
|
|||
std::mem::size_of::<Uniforms>() as wgpu::BufferAddress,
|
||||
);
|
||||
|
||||
let old_pos: cgmath::Vector3<f32> = self.light.position.into();
|
||||
self.light.position =
|
||||
cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(1.0))
|
||||
* self.light.position;
|
||||
(cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(1.0))
|
||||
* old_pos)
|
||||
.into();
|
||||
self.queue
|
||||
.write_buffer(&self.light_buffer, 0, bytemuck::cast_slice(&[self.light]));
|
||||
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
}
|
||||
|
||||
fn render(&mut self) {
|
||||
let frame = self
|
||||
.swap_chain
|
||||
.get_current_frame()
|
||||
.expect("Failed getting frame");
|
||||
fn render(&mut self) -> Result<(), wgpu::SwapChainError> {
|
||||
let frame = self.swap_chain.get_current_frame()?;
|
||||
|
||||
let mut encoder = self
|
||||
.device
|
||||
|
@ -505,6 +535,7 @@ impl State {
|
|||
}),
|
||||
});
|
||||
|
||||
render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..));
|
||||
render_pass.set_pipeline(&self.light_render_pipeline);
|
||||
render_pass.draw_light_model_instanced(
|
||||
&self.obj_model,
|
||||
|
@ -524,6 +555,8 @@ impl State {
|
|||
drop(render_pass);
|
||||
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
59
src/model.rs
59
src/model.rs
|
@ -9,13 +9,13 @@ pub trait Vertex {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
pub struct ModelVertex {
|
||||
position: cgmath::Vector3<f32>,
|
||||
tex_coords: cgmath::Vector2<f32>,
|
||||
normal: cgmath::Vector3<f32>,
|
||||
tangent: cgmath::Vector3<f32>,
|
||||
bitangent: cgmath::Vector3<f32>,
|
||||
position: [f32; 3],
|
||||
tex_coords: [f32; 2],
|
||||
normal: [f32; 3],
|
||||
tangent: [f32; 3],
|
||||
bitangent: [f32; 3],
|
||||
}
|
||||
|
||||
impl Vertex for ModelVertex {
|
||||
|
@ -56,9 +56,6 @@ impl Vertex for ModelVertex {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl bytemuck::Pod for ModelVertex {}
|
||||
unsafe impl bytemuck::Zeroable for ModelVertex {}
|
||||
|
||||
pub struct Material {
|
||||
pub name: String,
|
||||
pub diffuse_texture: texture::Texture,
|
||||
|
@ -162,21 +159,19 @@ impl Model {
|
|||
let mut vertices = Vec::with_capacity(m.mesh.positions.len() / 3);
|
||||
for i in 0..m.mesh.positions.len() / 3 {
|
||||
vertices.push(ModelVertex {
|
||||
position: (
|
||||
position: [
|
||||
m.mesh.positions[i * 3],
|
||||
m.mesh.positions[i * 3 + 1],
|
||||
m.mesh.positions[i * 3 + 2],
|
||||
)
|
||||
.into(),
|
||||
tex_coords: (m.mesh.texcoords[i * 2], m.mesh.texcoords[i * 2 + 1]).into(),
|
||||
normal: (
|
||||
],
|
||||
tex_coords: [m.mesh.texcoords[i * 2], m.mesh.texcoords[i * 2 + 1]],
|
||||
normal: [
|
||||
m.mesh.normals[i * 3],
|
||||
m.mesh.normals[i * 3 + 1],
|
||||
m.mesh.normals[i * 3 + 2],
|
||||
)
|
||||
.into(),
|
||||
tangent: [0.0; 3].into(),
|
||||
bitangent: [0.0; 3].into(),
|
||||
],
|
||||
tangent: [0.0; 3],
|
||||
bitangent: [0.0; 3],
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -185,23 +180,31 @@ impl Model {
|
|||
let v1 = vertices[c[1] as usize];
|
||||
let v2 = vertices[c[2] as usize];
|
||||
|
||||
let delta_pos1 = v1.position - v0.position;
|
||||
let delta_pos2 = v2.position - v0.position;
|
||||
let pos0: cgmath::Vector3<_> = v0.position.into();
|
||||
let pos1: cgmath::Vector3<_> = v1.position.into();
|
||||
let pos2: cgmath::Vector3<_> = v2.position.into();
|
||||
|
||||
let delta_uv1 = v1.tex_coords - v0.tex_coords;
|
||||
let delta_uv2 = v2.tex_coords - v0.tex_coords;
|
||||
let uv0: cgmath::Vector2<_> = v0.tex_coords.into();
|
||||
let uv1: cgmath::Vector2<_> = v1.tex_coords.into();
|
||||
let uv2: cgmath::Vector2<_> = v2.tex_coords.into();
|
||||
|
||||
let delta_pos1 = pos1 - pos0;
|
||||
let delta_pos2 = pos2 - pos0;
|
||||
|
||||
let delta_uv1 = uv1 - uv0;
|
||||
let delta_uv2 = uv2 - uv0;
|
||||
|
||||
let r = 1.0 / (delta_uv1.x * delta_uv2.y - delta_uv1.y * delta_uv2.x);
|
||||
let tangent = (delta_pos1 * delta_uv2.y - delta_pos2 * delta_uv1.y) * r;
|
||||
let bitangent = (delta_pos2 * delta_uv1.x - delta_pos1 * delta_uv2.x) * r;
|
||||
|
||||
vertices[c[0] as usize].tangent = tangent;
|
||||
vertices[c[1] as usize].tangent = tangent;
|
||||
vertices[c[2] as usize].tangent = tangent;
|
||||
vertices[c[0] as usize].tangent = tangent.into();
|
||||
vertices[c[1] as usize].tangent = tangent.into();
|
||||
vertices[c[2] as usize].tangent = tangent.into();
|
||||
|
||||
vertices[c[0] as usize].bitangent = bitangent;
|
||||
vertices[c[1] as usize].bitangent = bitangent;
|
||||
vertices[c[2] as usize].bitangent = bitangent;
|
||||
vertices[c[0] as usize].bitangent = bitangent.into();
|
||||
vertices[c[1] as usize].bitangent = bitangent.into();
|
||||
vertices[c[2] as usize].bitangent = bitangent.into();
|
||||
}
|
||||
|
||||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
|
|
|
@ -5,6 +5,7 @@ layout(location=1) in vec2 a_tex_coords;
|
|||
layout(location=2) in vec3 a_normal;
|
||||
layout(location=3) in vec3 a_tangent;
|
||||
layout(location=4) in vec3 a_bitangent;
|
||||
layout(location=5) in mat4 model_matrix;
|
||||
|
||||
layout(location=0) out vec2 v_tex_coords;
|
||||
layout(location=1) out vec3 v_position;
|
||||
|
@ -16,9 +17,6 @@ layout(set=1, binding=0) uniform Uniforms {
|
|||
mat4 u_view_proj; // TODO: pass in view and projection matrix seperately
|
||||
};
|
||||
|
||||
layout(set=1, binding=1) buffer Instances {
|
||||
mat4 s_models[];
|
||||
};
|
||||
|
||||
layout(set=2, binding=0) uniform Light {
|
||||
vec3 light_position;
|
||||
|
@ -27,7 +25,6 @@ layout(set=2, binding=0) uniform Light {
|
|||
|
||||
void main() {
|
||||
v_tex_coords = a_tex_coords;
|
||||
mat4 model_matrix = s_models[gl_InstanceIndex];
|
||||
mat3 normal_matrix = mat3(transpose(inverse(model_matrix))); // TODO: calculate this on CPU and pass in as an uniform
|
||||
|
||||
vec3 normal = normalize(normal_matrix * a_normal);
|
||||
|
|
|
@ -28,7 +28,7 @@ impl Texture {
|
|||
is_normal_map: bool,
|
||||
label: Option<&str>,
|
||||
) -> Result<Self> {
|
||||
let rgba = img.to_rgba();
|
||||
let rgba = img.to_rgba8();
|
||||
|
||||
let (width, height) = img.dimensions();
|
||||
let size = wgpu::Extent3d {
|
||||
|
|
Loading…
Reference in a new issue