vec2 octahedronWrap(vec2 _val) { // Reference(s): // - Octahedron normal vector encoding // https://web.archive.org/web/20191027010600/https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/comment-page-1/ return (1.0 - abs(_val.yx) ) * mix(vec2_splat(-1.0), vec2_splat(1.0), vec2(greaterThanEqual(_val.xy, vec2_splat(0.0) ) ) ); } vec2 EncodeNormal(vec3 _normal) { _normal /= abs(_normal.x) + abs(_normal.y) + abs(_normal.z); _normal.xy = _normal.z >= 0.0 ? _normal.xy : octahedronWrap(_normal.xy); _normal.xy = _normal.xy * 0.5 + 0.5; return _normal.xy; } vec3 DecodeNormal(vec2 _encodedNormal) { _encodedNormal = _encodedNormal * 2.0 - 1.0; vec3 normal; normal.z = 1.0 - abs(_encodedNormal.x) - abs(_encodedNormal.y); normal.xy = normal.z >= 0.0 ? _encodedNormal.xy : octahedronWrap(_encodedNormal.xy); return normalize(normal); }