From 70bf012641c15e68931370bd38757cafc4e816cb Mon Sep 17 00:00:00 2001 From: Ben Hansen Date: Sun, 15 Aug 2021 10:44:57 -0600 Subject: [PATCH] fixed tangent/bitangent comp and cargo fmt --- code/beginner/tutorial4-buffer/src/main.rs | 2 +- .../tutorial6-uniforms/src/challenge.rs | 3 +- .../beginner/tutorial7-instancing/src/main.rs | 2 +- .../beginner/tutorial8-depth/src/challenge.rs | 4 +- code/beginner/tutorial8-depth/src/main.rs | 7 +- code/beginner/tutorial9-models/src/main.rs | 7 +- .../tutorial10-lighting/src/main.rs | 7 +- .../tutorial11-normals/src/main.rs | 9 +- .../tutorial11-normals/src/model.rs | 36 ++- .../tutorial12-camera/src/camera.rs | 6 +- .../tutorial12-camera/src/main.rs | 7 +- .../tutorial12-camera/src/model.rs | 36 ++- .../tutorial13-threading/src/camera.rs | 6 +- .../tutorial13-threading/src/main.rs | 7 +- .../tutorial13-threading/src/model.rs | 258 +++++++++--------- code/showcase/compute/src/camera.rs | 6 +- code/showcase/compute/src/main.rs | 7 +- code/showcase/framework/src/camera.rs | 6 +- .../intermediate/tutorial11-normals/README.md | 44 ++- 19 files changed, 270 insertions(+), 190 deletions(-) diff --git a/code/beginner/tutorial4-buffer/src/main.rs b/code/beginner/tutorial4-buffer/src/main.rs index 3de9c7b8..e58deb76 100644 --- a/code/beginner/tutorial4-buffer/src/main.rs +++ b/code/beginner/tutorial4-buffer/src/main.rs @@ -198,7 +198,7 @@ impl State { self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); } } - + #[allow(unused_variables)] fn input(&mut self, event: &WindowEvent) -> bool { false diff --git a/code/beginner/tutorial6-uniforms/src/challenge.rs b/code/beginner/tutorial6-uniforms/src/challenge.rs index 9d870e59..399f4874 100644 --- a/code/beginner/tutorial6-uniforms/src/challenge.rs +++ b/code/beginner/tutorial6-uniforms/src/challenge.rs @@ -464,7 +464,8 @@ impl State { self.sc_desc.height = new_size.height; self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); - self.uniform_staging.camera.aspect = self.sc_desc.width as f32 / self.sc_desc.height as f32; + self.uniform_staging.camera.aspect = + self.sc_desc.width as f32 / self.sc_desc.height as f32; } } diff --git a/code/beginner/tutorial7-instancing/src/main.rs b/code/beginner/tutorial7-instancing/src/main.rs index 12d6d239..ad14e2e3 100644 --- a/code/beginner/tutorial7-instancing/src/main.rs +++ b/code/beginner/tutorial7-instancing/src/main.rs @@ -538,7 +538,7 @@ impl State { } fn resize(&mut self, new_size: winit::dpi::PhysicalSize) { - if new_size.width > 0 && new_size.height > 0 { + if new_size.width > 0 && new_size.height > 0 { self.size = new_size; self.sc_desc.width = new_size.width; self.sc_desc.height = new_size.height; diff --git a/code/beginner/tutorial8-depth/src/challenge.rs b/code/beginner/tutorial8-depth/src/challenge.rs index 5961d372..5d3328d6 100644 --- a/code/beginner/tutorial8-depth/src/challenge.rs +++ b/code/beginner/tutorial8-depth/src/challenge.rs @@ -746,12 +746,12 @@ impl State { depth_pass, } } -pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize) { + pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize) { if new_size.width > 0 && new_size.height > 0 { self.size = new_size; self.sc_desc.width = new_size.width; self.sc_desc.height = new_size.height; - + self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); self.depth_pass.resize(&self.device, &self.sc_desc); diff --git a/code/beginner/tutorial8-depth/src/main.rs b/code/beginner/tutorial8-depth/src/main.rs index 16b977ed..ba213e05 100644 --- a/code/beginner/tutorial8-depth/src/main.rs +++ b/code/beginner/tutorial8-depth/src/main.rs @@ -564,8 +564,11 @@ impl State { self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); self.camera.aspect = self.sc_desc.width as f32 / self.sc_desc.height as f32; // NEW! - self.depth_texture = - texture::Texture::create_depth_texture(&self.device, &self.sc_desc, "depth_texture"); + self.depth_texture = texture::Texture::create_depth_texture( + &self.device, + &self.sc_desc, + "depth_texture", + ); } } diff --git a/code/beginner/tutorial9-models/src/main.rs b/code/beginner/tutorial9-models/src/main.rs index ff15a0b6..78eb0719 100644 --- a/code/beginner/tutorial9-models/src/main.rs +++ b/code/beginner/tutorial9-models/src/main.rs @@ -477,8 +477,11 @@ impl State { self.sc_desc.width = new_size.width; self.sc_desc.height = new_size.height; self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); - self.depth_texture = - texture::Texture::create_depth_texture(&self.device, &self.sc_desc, "depth_texture"); + self.depth_texture = texture::Texture::create_depth_texture( + &self.device, + &self.sc_desc, + "depth_texture", + ); } } fn input(&mut self, event: &WindowEvent) -> bool { diff --git a/code/intermediate/tutorial10-lighting/src/main.rs b/code/intermediate/tutorial10-lighting/src/main.rs index 66b6844e..db311521 100644 --- a/code/intermediate/tutorial10-lighting/src/main.rs +++ b/code/intermediate/tutorial10-lighting/src/main.rs @@ -595,8 +595,11 @@ impl State { self.sc_desc.width = new_size.width; self.sc_desc.height = new_size.height; self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); - self.depth_texture = - texture::Texture::create_depth_texture(&self.device, &self.sc_desc, "depth_texture"); + self.depth_texture = texture::Texture::create_depth_texture( + &self.device, + &self.sc_desc, + "depth_texture", + ); } } diff --git a/code/intermediate/tutorial11-normals/src/main.rs b/code/intermediate/tutorial11-normals/src/main.rs index f7f77e14..1c9534cd 100644 --- a/code/intermediate/tutorial11-normals/src/main.rs +++ b/code/intermediate/tutorial11-normals/src/main.rs @@ -642,14 +642,17 @@ impl State { } fn resize(&mut self, new_size: winit::dpi::PhysicalSize) { - if new_size.width > 0 && new_size.height > 0 { + if new_size.width > 0 && new_size.height > 0 { self.camera.aspect = self.sc_desc.width as f32 / self.sc_desc.height as f32; self.size = new_size; self.sc_desc.width = new_size.width; self.sc_desc.height = new_size.height; self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); - self.depth_texture = - texture::Texture::create_depth_texture(&self.device, &self.sc_desc, "depth_texture"); + self.depth_texture = texture::Texture::create_depth_texture( + &self.device, + &self.sc_desc, + "depth_texture", + ); } } diff --git a/code/intermediate/tutorial11-normals/src/model.rs b/code/intermediate/tutorial11-normals/src/model.rs index 2f94faaa..4ce970b0 100644 --- a/code/intermediate/tutorial11-normals/src/model.rs +++ b/code/intermediate/tutorial11-normals/src/model.rs @@ -1,4 +1,5 @@ use anyhow::*; +use cgmath::InnerSpace; use std::ops::Range; use std::path::Path; use tobj::LoadOptions; @@ -183,6 +184,7 @@ impl Model { } let indices = &m.mesh.indices; + let mut triangles_included = (0..vertices.len()).collect::>(); // Calculate tangents and bitangets. We're going to // use the triangles, so we need to loop through the @@ -220,13 +222,35 @@ impl Model { let bitangent = (delta_pos2 * delta_uv1.x - delta_pos1 * delta_uv2.x) * r; // We'll use the same tangent/bitangent for each vertex in the triangle - 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].tangent = + (tangent + cgmath::Vector3::from(vertices[c[0] as usize].tangent)).into(); + vertices[c[1] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[1] as usize].tangent)).into(); + vertices[c[2] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[2] as usize].tangent)).into(); + vertices[c[0] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[0] as usize].bitangent)).into(); + vertices[c[1] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[1] as usize].bitangent)).into(); + vertices[c[2] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[2] as usize].bitangent)).into(); + + // Used to average the tangents/bitangents + triangles_included[c[0] as usize] += 1; + triangles_included[c[1] as usize] += 1; + triangles_included[c[2] as usize] += 1; + } - vertices[c[0] as usize].bitangent = bitangent.into(); - vertices[c[1] as usize].bitangent = bitangent.into(); - vertices[c[2] as usize].bitangent = bitangent.into(); + // Average the tangents/bitangents + for (i, n) in triangles_included.into_iter().enumerate() { + let denom = 1.0 / n as f32; + let mut v = &mut vertices[i]; + v.tangent = (cgmath::Vector3::from(v.tangent) * denom) + .normalize() + .into(); + v.bitangent = (cgmath::Vector3::from(v.bitangent) * denom) + .normalize() + .into(); } let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { diff --git a/code/intermediate/tutorial12-camera/src/camera.rs b/code/intermediate/tutorial12-camera/src/camera.rs index b8b6d22d..633cf713 100644 --- a/code/intermediate/tutorial12-camera/src/camera.rs +++ b/code/intermediate/tutorial12-camera/src/camera.rs @@ -40,11 +40,7 @@ impl Camera { Matrix4::look_to_rh( self.position, - Vector3::new( - cos_pitch * cos_yaw, - sin_pitch, - cos_pitch * sin_yaw - ).normalize(), + Vector3::new(cos_pitch * cos_yaw, sin_pitch, cos_pitch * sin_yaw).normalize(), Vector3::unit_y(), ) } diff --git a/code/intermediate/tutorial12-camera/src/main.rs b/code/intermediate/tutorial12-camera/src/main.rs index d37dd7c5..50091391 100644 --- a/code/intermediate/tutorial12-camera/src/main.rs +++ b/code/intermediate/tutorial12-camera/src/main.rs @@ -528,8 +528,11 @@ impl State { self.sc_desc.width = new_size.width; self.sc_desc.height = new_size.height; self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); - self.depth_texture = - texture::Texture::create_depth_texture(&self.device, &self.sc_desc, "depth_texture"); + self.depth_texture = texture::Texture::create_depth_texture( + &self.device, + &self.sc_desc, + "depth_texture", + ); } } diff --git a/code/intermediate/tutorial12-camera/src/model.rs b/code/intermediate/tutorial12-camera/src/model.rs index 2f94faaa..4ce970b0 100644 --- a/code/intermediate/tutorial12-camera/src/model.rs +++ b/code/intermediate/tutorial12-camera/src/model.rs @@ -1,4 +1,5 @@ use anyhow::*; +use cgmath::InnerSpace; use std::ops::Range; use std::path::Path; use tobj::LoadOptions; @@ -183,6 +184,7 @@ impl Model { } let indices = &m.mesh.indices; + let mut triangles_included = (0..vertices.len()).collect::>(); // Calculate tangents and bitangets. We're going to // use the triangles, so we need to loop through the @@ -220,13 +222,35 @@ impl Model { let bitangent = (delta_pos2 * delta_uv1.x - delta_pos1 * delta_uv2.x) * r; // We'll use the same tangent/bitangent for each vertex in the triangle - 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].tangent = + (tangent + cgmath::Vector3::from(vertices[c[0] as usize].tangent)).into(); + vertices[c[1] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[1] as usize].tangent)).into(); + vertices[c[2] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[2] as usize].tangent)).into(); + vertices[c[0] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[0] as usize].bitangent)).into(); + vertices[c[1] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[1] as usize].bitangent)).into(); + vertices[c[2] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[2] as usize].bitangent)).into(); + + // Used to average the tangents/bitangents + triangles_included[c[0] as usize] += 1; + triangles_included[c[1] as usize] += 1; + triangles_included[c[2] as usize] += 1; + } - vertices[c[0] as usize].bitangent = bitangent.into(); - vertices[c[1] as usize].bitangent = bitangent.into(); - vertices[c[2] as usize].bitangent = bitangent.into(); + // Average the tangents/bitangents + for (i, n) in triangles_included.into_iter().enumerate() { + let denom = 1.0 / n as f32; + let mut v = &mut vertices[i]; + v.tangent = (cgmath::Vector3::from(v.tangent) * denom) + .normalize() + .into(); + v.bitangent = (cgmath::Vector3::from(v.bitangent) * denom) + .normalize() + .into(); } let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { diff --git a/code/intermediate/tutorial13-threading/src/camera.rs b/code/intermediate/tutorial13-threading/src/camera.rs index b8b6d22d..633cf713 100644 --- a/code/intermediate/tutorial13-threading/src/camera.rs +++ b/code/intermediate/tutorial13-threading/src/camera.rs @@ -40,11 +40,7 @@ impl Camera { Matrix4::look_to_rh( self.position, - Vector3::new( - cos_pitch * cos_yaw, - sin_pitch, - cos_pitch * sin_yaw - ).normalize(), + Vector3::new(cos_pitch * cos_yaw, sin_pitch, cos_pitch * sin_yaw).normalize(), Vector3::unit_y(), ) } diff --git a/code/intermediate/tutorial13-threading/src/main.rs b/code/intermediate/tutorial13-threading/src/main.rs index 9a72a750..0400699e 100644 --- a/code/intermediate/tutorial13-threading/src/main.rs +++ b/code/intermediate/tutorial13-threading/src/main.rs @@ -525,8 +525,11 @@ impl State { self.sc_desc.width = new_size.width; self.sc_desc.height = new_size.height; self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); - self.depth_texture = - texture::Texture::create_depth_texture(&self.device, &self.sc_desc, "depth_texture"); + self.depth_texture = texture::Texture::create_depth_texture( + &self.device, + &self.sc_desc, + "depth_texture", + ); } } diff --git a/code/intermediate/tutorial13-threading/src/model.rs b/code/intermediate/tutorial13-threading/src/model.rs index 4735dc3f..4ce970b0 100644 --- a/code/intermediate/tutorial13-threading/src/model.rs +++ b/code/intermediate/tutorial13-threading/src/model.rs @@ -1,5 +1,5 @@ use anyhow::*; -use rayon::prelude::*; +use cgmath::InnerSpace; use std::ops::Range; use std::path::Path; use tobj::LoadOptions; @@ -140,132 +140,138 @@ impl Model { // We're assuming that the texture files are stored with the obj file let containing_folder = path.as_ref().parent().context("Directory has no parent")?; - // UPDATED! - let materials = obj_materials - .par_iter() - .map(|mat| { - // We can also parallelize loading the textures! - let mut textures = [ - (containing_folder.join(&mat.diffuse_texture), false), - (containing_folder.join(&mat.normal_texture), true), - ] - .par_iter() - .map(|(texture_path, is_normal_map)| { - // - texture::Texture::load(device, queue, texture_path, *is_normal_map) - }) - .collect::>>()?; - - // Pop removes from the end of the list. - let normal_texture = textures.pop().unwrap(); - let diffuse_texture = textures.pop().unwrap(); - - Ok(Material::new( - device, - &mat.name, - diffuse_texture, - normal_texture, - layout, - )) - }) - .collect::>>()?; - - // UPDATED! - let meshes = obj_models - .par_iter() - .map(|m| { - let mut vertices = (0..m.mesh.positions.len() / 3) - .into_par_iter() - .map(|i| { - ModelVertex { - 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: [ - m.mesh.normals[i * 3], - m.mesh.normals[i * 3 + 1], - m.mesh.normals[i * 3 + 2], - ] - .into(), - // We'll calculate these later - tangent: [0.0; 3].into(), - bitangent: [0.0; 3].into(), - } - }) - .collect::>(); - - let indices = &m.mesh.indices; - - // Calculate tangents and bitangets. We're going to - // use the triangles, so we need to loop through the - // indices in chunks of 3 - for c in indices.chunks(3) { - let v0 = vertices[c[0] as usize]; - let v1 = vertices[c[1] as usize]; - let v2 = vertices[c[2] as usize]; - - let pos0: cgmath::Vector3<_> = v0.position.into(); - let pos1: cgmath::Vector3<_> = v1.position.into(); - let pos2: cgmath::Vector3<_> = v2.position.into(); - - let uv0: cgmath::Vector2<_> = v0.tex_coords.into(); - let uv1: cgmath::Vector2<_> = v1.tex_coords.into(); - let uv2: cgmath::Vector2<_> = v2.tex_coords.into(); - - // Calculate the edges of the triangle - let delta_pos1 = pos1 - pos0; - let delta_pos2 = pos2 - pos0; - - // This will give us a direction to calculate the - // tangent and bitangent - let delta_uv1 = uv1 - uv0; - let delta_uv2 = uv2 - uv0; - - // Solving the following system of equations will - // give us the tangent and bitangent. - // delta_pos1 = delta_uv1.x * T + delta_u.y * B - // delta_pos2 = delta_uv2.x * T + delta_uv2.y * B - // Luckily, the place I found this equation provided - // the solution! - 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; - - // We'll use the same tangent/bitangent for each vertex in the triangle - 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.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 { - label: Some(&format!("{:?} Vertex Buffer", m.name)), - contents: bytemuck::cast_slice(&vertices), - usage: wgpu::BufferUsage::VERTEX, - }); - let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some(&format!("{:?} Index Buffer", m.name)), - contents: bytemuck::cast_slice(&m.mesh.indices), - usage: wgpu::BufferUsage::INDEX, - }); + let mut materials = Vec::new(); + for mat in obj_materials { + let diffuse_path = mat.diffuse_texture; + let diffuse_texture = + texture::Texture::load(device, queue, containing_folder.join(diffuse_path), false)?; + + let normal_path = mat.normal_texture; + let normal_texture = + texture::Texture::load(device, queue, containing_folder.join(normal_path), true)?; + + materials.push(Material::new( + device, + &mat.name, + diffuse_texture, + normal_texture, + layout, + )); + } - Ok(Mesh { - name: m.name.clone(), - vertex_buffer, - index_buffer, - num_elements: m.mesh.indices.len() as u32, - material: m.mesh.material_id.unwrap_or(0), - }) - }) - .collect::>>()?; + let mut meshes = Vec::new(); + for m in obj_models { + let mut vertices = Vec::new(); + for i in 0..m.mesh.positions.len() / 3 { + vertices.push(ModelVertex { + 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: [ + m.mesh.normals[i * 3], + m.mesh.normals[i * 3 + 1], + m.mesh.normals[i * 3 + 2], + ] + .into(), + // We'll calculate these later + tangent: [0.0; 3].into(), + bitangent: [0.0; 3].into(), + }); + } + + let indices = &m.mesh.indices; + let mut triangles_included = (0..vertices.len()).collect::>(); + + // Calculate tangents and bitangets. We're going to + // use the triangles, so we need to loop through the + // indices in chunks of 3 + for c in indices.chunks(3) { + let v0 = vertices[c[0] as usize]; + let v1 = vertices[c[1] as usize]; + let v2 = vertices[c[2] as usize]; + + let pos0: cgmath::Vector3<_> = v0.position.into(); + let pos1: cgmath::Vector3<_> = v1.position.into(); + let pos2: cgmath::Vector3<_> = v2.position.into(); + + let uv0: cgmath::Vector2<_> = v0.tex_coords.into(); + let uv1: cgmath::Vector2<_> = v1.tex_coords.into(); + let uv2: cgmath::Vector2<_> = v2.tex_coords.into(); + + // Calculate the edges of the triangle + let delta_pos1 = pos1 - pos0; + let delta_pos2 = pos2 - pos0; + + // This will give us a direction to calculate the + // tangent and bitangent + let delta_uv1 = uv1 - uv0; + let delta_uv2 = uv2 - uv0; + + // Solving the following system of equations will + // give us the tangent and bitangent. + // delta_pos1 = delta_uv1.x * T + delta_u.y * B + // delta_pos2 = delta_uv2.x * T + delta_uv2.y * B + // Luckily, the place I found this equation provided + // the solution! + 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; + + // We'll use the same tangent/bitangent for each vertex in the triangle + vertices[c[0] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[0] as usize].tangent)).into(); + vertices[c[1] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[1] as usize].tangent)).into(); + vertices[c[2] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[2] as usize].tangent)).into(); + vertices[c[0] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[0] as usize].bitangent)).into(); + vertices[c[1] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[1] as usize].bitangent)).into(); + vertices[c[2] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[2] as usize].bitangent)).into(); + + // Used to average the tangents/bitangents + triangles_included[c[0] as usize] += 1; + triangles_included[c[1] as usize] += 1; + triangles_included[c[2] as usize] += 1; + } + + // Average the tangents/bitangents + for (i, n) in triangles_included.into_iter().enumerate() { + let denom = 1.0 / n as f32; + let mut v = &mut vertices[i]; + v.tangent = (cgmath::Vector3::from(v.tangent) * denom) + .normalize() + .into(); + v.bitangent = (cgmath::Vector3::from(v.bitangent) * denom) + .normalize() + .into(); + } + + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some(&format!("{:?} Vertex Buffer", path.as_ref())), + contents: bytemuck::cast_slice(&vertices), + usage: wgpu::BufferUsage::VERTEX, + }); + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some(&format!("{:?} Index Buffer", path.as_ref())), + contents: bytemuck::cast_slice(&m.mesh.indices), + usage: wgpu::BufferUsage::INDEX, + }); + + meshes.push(Mesh { + name: m.name, + vertex_buffer, + index_buffer, + num_elements: m.mesh.indices.len() as u32, + material: m.mesh.material_id.unwrap_or(0), + }); + } Ok(Self { meshes, materials }) } diff --git a/code/showcase/compute/src/camera.rs b/code/showcase/compute/src/camera.rs index 5742313b..f6f9c078 100644 --- a/code/showcase/compute/src/camera.rs +++ b/code/showcase/compute/src/camera.rs @@ -40,11 +40,7 @@ impl Camera { Matrix4::look_to_rh( self.position, - Vector3::new( - cos_pitch * cos_yaw, - sin_pitch, - cos_pitch * sin_yaw - ).normalize(), + Vector3::new(cos_pitch * cos_yaw, sin_pitch, cos_pitch * sin_yaw).normalize(), Vector3::unit_y(), ) } diff --git a/code/showcase/compute/src/main.rs b/code/showcase/compute/src/main.rs index edf14b13..bc6ab81a 100644 --- a/code/showcase/compute/src/main.rs +++ b/code/showcase/compute/src/main.rs @@ -452,8 +452,11 @@ impl State { self.sc_desc.width = new_size.width; self.sc_desc.height = new_size.height; self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); - self.depth_texture = - texture::Texture::create_depth_texture(&self.device, &self.sc_desc, "depth_texture"); + self.depth_texture = texture::Texture::create_depth_texture( + &self.device, + &self.sc_desc, + "depth_texture", + ); } } diff --git a/code/showcase/framework/src/camera.rs b/code/showcase/framework/src/camera.rs index b8b6d22d..633cf713 100644 --- a/code/showcase/framework/src/camera.rs +++ b/code/showcase/framework/src/camera.rs @@ -40,11 +40,7 @@ impl Camera { Matrix4::look_to_rh( self.position, - Vector3::new( - cos_pitch * cos_yaw, - sin_pitch, - cos_pitch * sin_yaw - ).normalize(), + Vector3::new(cos_pitch * cos_yaw, sin_pitch, cos_pitch * sin_yaw).normalize(), Vector3::unit_y(), ) } diff --git a/docs/intermediate/tutorial11-normals/README.md b/docs/intermediate/tutorial11-normals/README.md index 9287bb08..4d70686a 100644 --- a/docs/intermediate/tutorial11-normals/README.md +++ b/docs/intermediate/tutorial11-normals/README.md @@ -244,6 +244,7 @@ impl Model { } let indices = &m.mesh.indices; + let mut triangles_included = (0..vertices.len()).collect::>(); // Calculate tangents and bitangets. We're going to // use the triangles, so we need to loop through the @@ -274,24 +275,43 @@ impl Model { // give us the tangent and bitangent. // delta_pos1 = delta_uv1.x * T + delta_u.y * B // delta_pos2 = delta_uv2.x * T + delta_uv2.y * B - // Luckily, the place I found this equation provided + // Luckily, the place I found this equation provided // the solution! - let r = 1.0 / (delta_uv1 .x * delta_uv2.y - delta_uv1.y * delta_uv2.x); + 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; - - // We'll use the same tangent/bitangent for each vertex in the triangle - 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.into(); - vertices[c[1] as usize].bitangent = bitangent.into(); - vertices[c[2] as usize].bitangent = bitangent.into(); + // We'll use the same tangent/bitangent for each vertex in the triangle + vertices[c[0] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[0] as usize].tangent)).into(); + vertices[c[1] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[1] as usize].tangent)).into(); + vertices[c[2] as usize].tangent = + (tangent + cgmath::Vector3::from(vertices[c[2] as usize].tangent)).into(); + vertices[c[0] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[0] as usize].bitangent)).into(); + vertices[c[1] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[1] as usize].bitangent)).into(); + vertices[c[2] as usize].bitangent = + (bitangent + cgmath::Vector3::from(vertices[c[2] as usize].bitangent)).into(); + + // Used to average the tangents/bitangents + triangles_included[c[0] as usize] += 1; + triangles_included[c[1] as usize] += 1; + triangles_included[c[2] as usize] += 1; } - // ... - } + // Average the tangents/bitangents + for (i, n) in triangles_included.into_iter().enumerate() { + let denom = 1.0 / n as f32; + let mut v = &mut vertices[i]; + v.tangent = (cgmath::Vector3::from(v.tangent) * denom) + .normalize() + .into(); + v.bitangent = (cgmath::Vector3::from(v.bitangent) * denom) + .normalize() + .into(); + } Ok(Self { meshes, materials }) }