vec3 packNormalToRGB( const in vec3 normal ) { return normalize( normal ) * 0.5 + 0.5; } vec3 unpackRGBToNormal( const in vec3 rgb ) { return 1.0 - 2.0 * rgb.xyz; } vec4 packDepthToRGBA( const in float value ) { const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 ); const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 ); vec4 res = mod( value * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 ); res -= res.xxyz * bit_mask; return res; } float unpackRGBAToDepth( const in vec4 rgba ) { const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 ); return dot( rgba, bitSh ); } // NOTE: viewZ/eyeZ is < 0 when in front of the camera per OpenGL conventions float viewZToOrthoDepth( const in float viewZ, const in float near, const in float far ) { return ( viewZ + near ) / ( near - far ); } float OrthoDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) { return linearClipZ * ( near - far ) - near; } 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 ); }