From c14215dcc69f7d40d983899d86dc63f33a5fe21c Mon Sep 17 00:00:00 2001 From: Florian Amsallem Date: Sun, 5 Nov 2023 00:17:52 +0100 Subject: [PATCH] fix tangent normalization --- src/lib.rs | 5 ++++- src/scene/model/mod.rs | 3 ++- src/scene/model/vertex.rs | 1 + tests/cube.glb | Bin 4288 -> 4908 bytes 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6242f39..ec4f940 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -180,12 +180,15 @@ mod tests { let model = &scene.models[0]; assert!(model.has_normals()); assert!(model.has_tex_coords()); - assert!(!model.has_tangents()); + assert!(model.has_tangents()); for t in model.triangles().unwrap().iter().flatten() { let pos = t.position; assert!(pos.x > -0.01 && pos.x < 1.01); assert!(pos.y > -0.01 && pos.y < 1.01); assert!(pos.z > -0.01 && pos.z < 1.01); + + // Check that the tangent w component is 1 or -1 + assert_eq!(t.tangent.w.abs(), 1.); } } diff --git a/src/scene/model/mod.rs b/src/scene/model/mod.rs index b1d1c4b..d59579e 100644 --- a/src/scene/model/mod.rs +++ b/src/scene/model/mod.rs @@ -312,7 +312,8 @@ impl Model { // Fill tangents let has_tangents = if let Some(tangents) = reader.read_tangents() { for (i, tangent) in tangents.enumerate() { - vertices[i].tangent = Self::apply_transform_tangent(tangent, transform).normalize(); + let tangent = Self::apply_transform_tangent(tangent, transform); + vertices[i].tangent = tangent.truncate().normalize().extend(tangent.w); } true } else { diff --git a/src/scene/model/vertex.rs b/src/scene/model/vertex.rs index 1c85a96..9df025d 100644 --- a/src/scene/model/vertex.rs +++ b/src/scene/model/vertex.rs @@ -15,6 +15,7 @@ pub struct Vertex { /// Normalized normal pub normal: Vector3, /// Tangent normal + /// The w component is the handedness of the tangent basis (can be -1 or 1) pub tangent: Vector4, /// Texture coordinates pub tex_coords: Vector2, diff --git a/tests/cube.glb b/tests/cube.glb index 20b937777af3b6eaa8deb9314c20958fc90aac72..01d07f44cbef5ce2cd3f1524c6d65cefdcd781ae 100644 GIT binary patch delta 1061 zcmbu7%WD%+6vk&_tmZX|38IjSdIjlXI^5^nJG0ReqZMlcF;o$xBz02avm{fb=#cDP zl>@pE#GN35&~DU?!G*Z;FA+CxU3e!dh&5pAVP{BU0iZ3Il&5&W+hJ?FD~j~sTBtE=8eMGrj0Jel(h;E%C9Hims?{48=N6DpZPc8rovYTG$Y+s_x_7R3mxDg?Ih@bDhSS+1l(Mt% zK2wB7_8>gWSVzM3)d2Zuv0C9MvhSnzTBj5A7Q4Z{n7Wj`owrfg>a7H!9?3nI!YEsY zbnZZrDz#m*i~0h$e=eV3IyGvqhe5s5>BqyQ`xm?nUan9gMCc^HZ)LEMn@;Jg;nB6| zV{)sPn=#>SegvD=G`z45!zb(WVE9h|m2nOAb4tHE?8m6)e(^i(2eE&=c$Wiyu;U>= c1H^~<=N^XnsX?53x9i87{)0D-1Vn|(cZombcK`qY delta 504 zcma)&J4*vW5XbLwzAlgR3{eX$k^@EL47+=~x4TyeAsPgYfsi5^WAG6qq7jS;qA9hr z2vb2{-f!QZPx0pono7a~n)O7V{H6A{hC5kbfwa%mr6(!h?Q1T-~iT z8nwe}W^LnOZ{PAt-(M+1Huy2Nn9FBV3zmm%t1w$k=W_X(3bH)Xw5?iwv$j!fSe^qX zp*wgBMIjTO0ve9OX?PGG!%L8gj6ggxpb;T_-`0FZ-)zV*HSP+K#%RzN+AKHY@j0!% UYD}n*Hz%NOzQb962cDyuPubppCIA2c