export default /* glsl */` vec3 packNormalToRGB( const in vec3 normal ) { return normalize( normal ) * 0.5 + 0.5; } vec3 unpackRGBToNormal( const in vec3 rgb ) { return 2.0 * rgb.xyz - 1.0; } const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1) const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1) const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. ); const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. ); const float ShiftRight8 = 1. / 256.; vec4 packDepthToRGBA( const in float v ) { vec4 r = vec4( fract( v * PackFactors ), v ); r.yzw -= r.xyz * ShiftRight8; // tidy overflow return r * PackUpscale; } float unpackRGBAToDepth( const in vec4 v ) { return dot( v, UnpackFactors ); } vec4 pack2HalfToRGBA( vec2 v ) { vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) ); return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w ); } vec2 unpackRGBATo2Half( vec4 v ) { return vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) ); } // NOTE: viewZ/eyeZ is < 0 when in front of the camera per OpenGL conventions float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) { return ( viewZ + near ) / ( near - far ); } float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) { return linearClipZ * ( near - far ) - near; } // NOTE: https://twitter.com/gonnavis/status/1377183786949959682 float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) { return ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ ); } float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) { return ( near * far ) / ( ( far - near ) * invClipZ - far ); } `;