// // Copyright (c) Microsoft. All rights reserved. // This code is licensed under the MIT License (MIT). // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. // // Developed by Minigraph // // Author: James Stanard // #ifndef __PIXEL_PACKING_VELOCITY_HLSLI__ #define __PIXEL_PACKING_VELOCITY_HLSLI__ #if 1 // This is a custom packing that devotes 10 bits each to X and Y velocity but 12 bits to Z velocity. Floats // are used instead of SNORM to increase precision around small deltas, which are the majority of deltas. // With TAA and Motion Blur, velocities are clamped, giving little reason to express them precisely in terms // of the size of the screen. #define packed_velocity_t uint // Designed to compress (-256.0, +256.0) with a signed 6e3 float uint PackXY( float x ) { uint signbit = asuint(x) >> 31; x = clamp(abs(x / 32768.0), 0, asfloat(0x3BFFE000)); return (f32tof16(x) + 8) >> 4 | signbit << 9; } float UnpackXY( uint x ) { return f16tof32((x & 0x1FF) << 4 | (x >> 9) << 15) * 32768.0; } // Designed to compress (-1.0, 1.0) with a signed 8e3 float uint PackZ( float x ) { uint signbit = asuint(x) >> 31; x = clamp(abs(x / 128.0), 0, asfloat(0x3BFFE000)); return (f32tof16(x) + 2) >> 2 | signbit << 11; } float UnpackZ( uint x ) { return f16tof32((x & 0x7FF) << 2 | (x >> 11) << 15) * 128.0; } // Pack the velocity to write to R10G10B10A2_UNORM packed_velocity_t PackVelocity( float3 Velocity ) { return PackXY(Velocity.x) | PackXY(Velocity.y) << 10 | PackZ(Velocity.z) << 20; } // Unpack the velocity from R10G10B10A2_UNORM float3 UnpackVelocity( packed_velocity_t Velocity ) { return float3(UnpackXY(Velocity & 0x3FF), UnpackXY((Velocity >> 10) & 0x3FF), UnpackZ(Velocity >> 20)); } #elif 1 #define packed_velocity_t float4 // Pack the velocity to write to R10G10B10A2_UNORM packed_velocity_t PackVelocity( float3 Velocity ) { // Stretch dx,dy from [-64, 63.875] to [-512, 511] to [-0.5, 0.5) to [0, 1) // Velocity.xy = (0,0) must be representable. return float4(Velocity * float3(8, 8, 4096) / 1024.0 + 512 / 1023.0, 0); } // Unpack the velocity from R10G10B10A2_UNORM float3 UnpackVelocity( packed_velocity_t Velocity ) { return (Velocity.xyz - 512.0 / 1023.0) * float3(1024, 1024, 2) / 8.0; } #else #define packed_velocity_t float4 // Pack the velocity to write to R16G16B16A16_FLOAT packed_velocity_t PackVelocity( float3 Velocity ) { return float4(Velocity * float3(16, 16, 32*1024), 0); } // Unpack the velocity from R10G10B10A2_UNORM float3 UnpackVelocity( packed_velocity_t Velocity ) { return Velocity.xyz / float3(16, 16, 32*1024); } #endif #endif // __PIXEL_PACKING_HLSLI__