Octahedral encode/decode — Rust port of `native/shared/shaders/common/imposter.wgsl`. Keep these in sync with the WGSL or the runtime atlas sampler will pick a different cell than the baker wrote. Decode an octahedral UV in `[-1, 1]^2` to a unit direction. Mirror of `octahedral_decode` in imposter.wgsl.
(uv: [f32; 2])
| 7 | /// Decode an octahedral UV in `[-1, 1]^2` to a unit direction. |
| 8 | /// Mirror of `octahedral_decode` in imposter.wgsl. |
| 9 | pub fn octahedral_decode(uv: [f32; 2]) -> [f32; 3] { |
| 10 | let abs_uv = [uv[0].abs(), uv[1].abs()]; |
| 11 | let y = 1.0 - abs_uv[0] - abs_uv[1]; |
| 12 | let v = if y >= 0.0 { |
| 13 | [uv[0], y, uv[1]] |
| 14 | } else { |
| 15 | let sx = if uv[0] >= 0.0 { 1.0 } else { -1.0 }; |
| 16 | let sy = if uv[1] >= 0.0 { 1.0 } else { -1.0 }; |
| 17 | [sx * (1.0 - abs_uv[1]), y, sy * (1.0 - abs_uv[0])] |
| 18 | }; |
| 19 | let len = (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]).sqrt().max(1e-8); |
| 20 | [v[0] / len, v[1] / len, v[2] / len] |
| 21 | } |
| 22 | |
| 23 | /// Cell-center UV in `[-1, 1]^2` for grid coords `(i, j)` of an `N×N` |
| 24 | /// atlas. Matches the runtime `floor(oct * GRID)` cell selection: the |