(xi: (f32, f32), n: [f32; 3], roughness: f32)
| 40 | } |
| 41 | |
| 42 | fn importance_sample_ggx(xi: (f32, f32), n: [f32; 3], roughness: f32) -> [f32; 3] { |
| 43 | let a = roughness * roughness; |
| 44 | let phi = 2.0 * std::f32::consts::PI * xi.0; |
| 45 | let cos_theta = ((1.0 - xi.1) / (1.0 + (a * a - 1.0) * xi.1)).sqrt(); |
| 46 | let sin_theta = (1.0 - cos_theta * cos_theta).max(0.0).sqrt(); |
| 47 | let h_local = [sin_theta * phi.cos(), sin_theta * phi.sin(), cos_theta]; |
| 48 | |
| 49 | // Build TBN around N. |
| 50 | let up = if n[2].abs() < 0.999 { [0.0, 0.0, 1.0] } else { [1.0, 0.0, 0.0] }; |
| 51 | let t = normalize3(cross3(up, n)); |
| 52 | let b = cross3(n, t); |
| 53 | [ |
| 54 | t[0] * h_local[0] + b[0] * h_local[1] + n[0] * h_local[2], |
| 55 | t[1] * h_local[0] + b[1] * h_local[1] + n[1] * h_local[2], |
| 56 | t[2] * h_local[0] + b[2] * h_local[1] + n[2] * h_local[2], |
| 57 | ] |
| 58 | } |
| 59 | |
| 60 | fn cross3(a: [f32; 3], b: [f32; 3]) -> [f32; 3] { |
| 61 | [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]] |
no test coverage detected