diff --git a/models/plane.glb b/models/plane.glb index db26e9c..ac61066 100644 Binary files a/models/plane.glb and b/models/plane.glb differ diff --git a/shaders/triangle.frag b/shaders/triangle.frag index 859df85..19b75d0 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -15,13 +15,14 @@ layout(binding = 2) uniform sampler2D normal_tex; layout(location = 0) in vec2 tex_coords; layout(location = 1) in vec3 normal_wld; layout(location = 2) in vec3 position_wld; +layout(location = 3) in mat3 tbn; layout(location = 0) out vec4 out_color; void main() { -// vec3 normal_cam_u = normalize(normal_wld); // TODO vec3 normal_cam_u = texture(normal_tex, tex_coords).rgb; - normal_cam_u = normalize(normal_cam_u * 2.0 - 1.0); + normal_cam_u = normal_cam_u * 2.0 - 1.0; + normal_cam_u = normalize(tbn * normal_cam_u); vec3 light_direction_cam_u = normalize(ubo.light_position - position_wld); float ambient_strength = 0.1; diff --git a/shaders/triangle.vert b/shaders/triangle.vert index 145d379..875d44a 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -16,21 +16,35 @@ layout(binding = 0) uniform ObjectUniformData { layout(location = 0) in vec3 position; layout(location = 1) in vec2 uv; layout(location = 2) in vec3 normal; -layout(location = 3) in ivec4 bone_index; -layout(location = 4) in vec4 bone_weight; +layout(location = 3) in vec4 tangent; +layout(location = 4) in ivec4 bone_index; +layout(location = 5) in vec4 bone_weight; layout(location = 0) out vec2 tex_coords; layout(location = 1) out vec3 normal_wld; layout(location = 2) out vec3 position_wld; +layout(location = 3) out mat3 tbn; out gl_PerVertex { vec4 gl_Position; }; void main() { + // Vertex position gl_Position = ubo.projection * ubo.view * push.model * vec4(position, 1.0); + position_wld = vec3(push.model * vec4(position, 1.0)); + + // Just interpolate UV coords, no transformation needed tex_coords = uv; - position_wld = vec3(push.model * vec4(position, 1.0)); + // This should probably be in object space? idk normal_wld = vec3(mat3(transpose(inverse(push.model))) * normal); + + // Tangent->object space matrix + vec3 tangent3 = vec3(tangent.xy, 1.0); + vec3 bitangent = -cross(tangent3, normal_wld); + vec3 t = normalize(vec3(push.model * vec4(tangent3, 0.0))); + vec3 b = normalize(vec3(push.model * vec4(bitangent, 0.0))); + vec3 n = normalize(vec3(push.model * vec4(normal_wld, 0.0))); + tbn = mat3(t, b, n); } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c5c2d67..74b4b64 100644 --- a/src/main.rs +++ b/src/main.rs @@ -104,11 +104,11 @@ fn _matrix_vector_mul(matrix: &Matrix4, vector: &Vector3) -> Vector3 Result<(Vec, V let texture_index = primitive.material().pbr_metallic_roughness().base_color_texture().map(|tex_info| tex_info.texture().index()); let normal_map_index = primitive.material().normal_texture().map(|tex_info| tex_info.texture().index()); + let reader = primitive.reader(|buffer| Some(&buffers[buffer.index()])); let indices = reader.read_indices().ok_or(NoIndices)?; - let vertices_result = create_vertices(reader.read_positions(), reader.read_tex_coords(0), reader.read_normals(), reader.read_joints(0), reader.read_weights(0)); + let vertices_result = create_vertices( + reader.read_positions(), + reader.read_tex_coords(0), + reader.read_normals(), + reader.read_tangents(), + reader.read_joints(0), + reader.read_weights(0)); let vertices = vertices_result?; let cpu_mesh = CPUMesh { vertices, @@ -90,18 +98,21 @@ pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, V fn create_vertices(positions: Option, tex_coords: Option, normals: Option, + tangents: Option, joints: Option, weights: Option) -> Result, String> { - match (positions, tex_coords, normals, joints, weights) { + match (positions, tex_coords, normals, tangents, joints, weights) { (Some(positions), Some(tex_coords), Some(normals), + Some(tangents), Some(joints), Some(weights)) => { Ok(positions .zip(tex_coords.into_f32()) .zip(normals) + .zip(tangents) .zip(joints.into_u16().map(|arr| { let mut casted_joints: [i32; 4] = [0; 4]; for i in 0..4 { @@ -110,10 +121,11 @@ fn create_vertices(positions: Option, casted_joints })) .zip(weights.into_f32()) - .map(|((((p, t), n), i), w)| Vertex { + .map(|(((((p, t), n), ta), i), w)| Vertex { position: p, uv: t, normal: n, + tangent: ta, bone_index: i, bone_weight: w }).collect()) @@ -121,22 +133,26 @@ fn create_vertices(positions: Option, (Some(positions), Some(tex_coords), Some(normals), + Some(tangents), None, None) => { Ok(positions .zip(tex_coords.into_f32()) .zip(normals) - .map(|((p, t), n)| Vertex { + .zip(tangents) + .map(|(((p, t), n), ta)| Vertex { position: p, uv: t, normal: n, + tangent: ta, bone_index: [-1; 4], bone_weight: [0.0; 4] }).collect()) }, - (None, _, _, _, _) => Err("Vertex positions missing!".to_string()), - (_, None, _, _, _) => Err("Tex coords missing!".to_string()), - (_, _, None, _, _) => Err("Normals missing!".to_string()), - (_, _, _, Some(_), None) => Err("Bone indices exist, but bone weights are missing!".to_string()), - (_, _, _, None, Some(_)) => Err("Bone weights exist, but bone incides are missing!".to_string()), + (None, _, _, _, _, _) => Err("Vertex positions missing!".to_string()), + (_, None, _, _, _, _) => Err("Tex coords missing!".to_string()), + (_, _, None, _, _, _) => Err("Normals missing!".to_string()), + (_, _, _, None, _, _) => Err("Tangents missing!".to_string()), + (_, _, _, _, Some(_), None) => Err("Bone indices exist, but bone weights are missing!".to_string()), + (_, _, _, _, None, Some(_)) => Err("Bone weights exist, but bone incides are missing!".to_string()), } } \ No newline at end of file diff --git a/src/vulkan.rs b/src/vulkan.rs index 5d33cad..4ea6993 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -30,8 +30,8 @@ use winit::window::{Window, WindowBuilder}; use line_vs::ty::LinePushConstants; use vs::ty::PushConstants; -use crate::mesh::CPUMesh; use crate::gameobject::{GameObject, GameObjectHandle}; +use crate::mesh::CPUMesh; const VALIDATION_LAYERS: &[&str] = &[ ]; @@ -41,10 +41,11 @@ pub struct Vertex { pub position: [f32; 3], pub uv: [f32; 2], pub normal: [f32; 3], + pub tangent: [f32; 4], pub bone_index: [i32; 4], pub bone_weight: [f32; 4], } -vulkano::impl_vertex!(Vertex, position, uv, normal, bone_index, bone_weight); +vulkano::impl_vertex!(Vertex, position, uv, normal, tangent, bone_index, bone_weight); #[derive(Default, Debug, Clone)] pub struct LinePoint {