Sample a tangent-space normal from the normal texture, in [-1,1]³. Returns (0,0,1) (i.e. "no perturbation") when the material has no normal map so callers can uniformly apply the TBN transform without a special case.
(&self, material: &Material, uv: Vec2)
| 325 | /// material has no normal map so callers can uniformly apply the |
| 326 | /// TBN transform without a special case. |
| 327 | fn sample_tangent_normal(&self, material: &Material, uv: Vec2) -> Vec3 { |
| 328 | let tex_idx = match material.normal_texture { |
| 329 | Some(i) => i as usize, |
| 330 | None => return Vec3::new(0.0, 0.0, 1.0), |
| 331 | }; |
| 332 | let (r, g, b) = match self.sample_texture_linear(tex_idx, uv) { |
| 333 | Some(c) => c, |
| 334 | None => return Vec3::new(0.0, 0.0, 1.0), |
| 335 | }; |
| 336 | // glTF stores normal maps with Y-up in tangent space: the |
| 337 | // sampled RGB maps linearly from [0,1] to [-1,1]. Apply the |
| 338 | // material's normal_scale to X/Y (Z is derived). |
| 339 | let nx = (r * 2.0 - 1.0) * material.normal_scale; |
| 340 | let ny = (g * 2.0 - 1.0) * material.normal_scale; |
| 341 | let nz = b * 2.0 - 1.0; |
| 342 | Vec3::new(nx, ny, nz).normalize_or_zero() |
| 343 | } |
| 344 | |
| 345 | /// Bilinear linear-space texture sample (no sRGB decode). Used |
| 346 | /// for MR / normal / occlusion textures per glTF spec. |
no test coverage detected