From 2820240980664462aa32ef7c90659c0180d3f5c3 Mon Sep 17 00:00:00 2001 From: Adrian G L Date: Thu, 2 Oct 2025 12:15:14 +0200 Subject: [PATCH] fix: compute and use normal matrix for correct normal transformations in shader --- shaders/simple.vert | 3 ++- src/main.rs | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/shaders/simple.vert b/shaders/simple.vert index 568b9d2..bcf427c 100644 --- a/shaders/simple.vert +++ b/shaders/simple.vert @@ -6,9 +6,10 @@ in layout(location=2) vec3 aNormal; out vec4 vColor; out vec3 vNormal; layout(location = 0) uniform mat4 transform; +layout(location = 1) uniform mat3 normalMatrix; void main() { gl_Position = transform * vec4(position, 1.0f); vColor = aColor; - vNormal = aNormal; + vNormal = normalize(normalMatrix * aNormal); } diff --git a/src/main.rs b/src/main.rs index d38d7f4..ef1df74 100644 --- a/src/main.rs +++ b/src/main.rs @@ -130,7 +130,7 @@ unsafe fn create_vao(vertices: &Vec, normals: &Vec, colors: &Vec, } // Scene graph drawing function -unsafe fn draw_scene(node: &scene_graph::SceneNode, transform_loc: i32, view_projection: &glm::Mat4, transform_so_far: &glm::Mat4) { +unsafe fn draw_scene(node: &scene_graph::SceneNode, transform_loc: i32, normal_loc: i32, view_projection: &glm::Mat4, transform_so_far: &glm::Mat4) { // Build model matrix from node transformations let translation = glm::translation(&node.position); let rot_x = glm::rotation(node.rotation.x, &glm::vec3(1.0, 0.0, 0.0)); @@ -148,6 +148,14 @@ unsafe fn draw_scene(node: &scene_graph::SceneNode, transform_loc: i32, view_pro if node.index_count > 0 { let mvp = view_projection * new_transform; gl::UniformMatrix4fv(transform_loc, 1, gl::FALSE, mvp.as_ptr()); + // compute normal matrix (inverse‐transpose of model) + let nm4 = glm::transpose(&glm::inverse(&new_transform)); + let normal_matrix = glm::mat3( + nm4[(0,0)], nm4[(0,1)], nm4[(0,2)], + nm4[(1,0)], nm4[(1,1)], nm4[(1,2)], + nm4[(2,0)], nm4[(2,1)], nm4[(2,2)], + ); + gl::UniformMatrix3fv(normal_loc, 1, gl::FALSE, normal_matrix.as_ptr()); gl::BindVertexArray(node.vao_id); gl::DrawElements(gl::TRIANGLES, node.index_count, gl::UNSIGNED_INT, ptr::null()); } @@ -349,6 +357,7 @@ fn main() { }; // get uniform location for the matrix (named `transform` in your vertex shader) let transform_loc = unsafe { simple_shader.get_uniform_location("transform") }; + let normal_loc = unsafe { simple_shader.get_uniform_location("normalMatrix") }; // Used to demonstrate keyboard handling for exercise 2. let mut _arbitrary_number = 0.0; // feel free to remove @@ -460,7 +469,7 @@ fn main() { // Draw scene via scene graph let view_proj = projection * view; - draw_scene(&*root_node, transform_loc, &view_proj, &glm::identity()); + draw_scene(&*root_node, transform_loc, normal_loc, &view_proj, &glm::identity()); } // Display the new color buffer on the display