Advertisement
Neitri

packs/unpack 6 x 32 bit float <-> 4 x 32 bit int

Jul 22nd, 2018
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.60 KB | None | 0 0
  1. // by Neitri, free of charge, free to redistribute
  2.  
  3. // packs and unpacks between:
  4. // 6 x 32 bit float
  5. // 4 x 32 bit int
  6. // during packing each float is converted to 21 bit fixed precision
  7. // precision is specified here:
  8. #define DATA_PRECISION_POS 0x800
  9. #define DATA_PRECISION_VEL 0x10000
  10.  
  11. // 0b111111111111111111111 == 2 097 151 // 21 bits are 1
  12. #define DATA_MAX_21 0x1FFFFF
  13. #define DATA_MAX_20 0xFFFFF
  14.  
  15. // 0b100000000000 // 1 bit is 1, 11 bits are 0
  16. #define DATA_OFFSET_11 0x800
  17.  
  18. // how to do bit shift and mask
  19. // mask: take only least significant 11 bits = data.y % DATA_OFFSET_11
  20. // shift: add 11 empty least significant bits = data.y * DATA_OFFSET_11
  21. // shift: remove 11 least significant bits = data.y / DATA_OFFSET_11
  22.  
  23. uint4 DataSave(float3 inPosition, float3 inVelocity)
  24. {
  25. uint4 data = 0;
  26.  
  27. uint3 uintPosition = clamp(uint3(round(inPosition * float(DATA_PRECISION_POS)) + int(DATA_MAX_20)), uint(0), uint(DATA_MAX_21));
  28. data.x = uintPosition.x * DATA_OFFSET_11 + (uintPosition.y % DATA_OFFSET_11);
  29. data.y = uintPosition.z * DATA_OFFSET_11 + (uintPosition.y / DATA_OFFSET_11);
  30.  
  31.  
  32. uint3 uintVelocity = clamp(uint3(round(inVelocity * float(DATA_PRECISION_VEL)) + int(DATA_MAX_20)), uint(0), uint(DATA_MAX_21));
  33. data.z = uintVelocity.x * DATA_OFFSET_11 + (uintVelocity.y % DATA_OFFSET_11);
  34. data.w = uintVelocity.z * DATA_OFFSET_11 + (uintVelocity.y / DATA_OFFSET_11);
  35.  
  36. // uint4 data layout
  37. // x pos.x 21 bits | pos.y least significant 11 bits
  38. // y pos.z 21 bits | | pos.y most significant 10 bits
  39. // z vel.x 21 bits | vel.y least significant 11 bits
  40. // w vel.z 21 bits | | vel.y most significant 10 bits
  41. // 32|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1
  42.  
  43. return data;
  44. }
  45.  
  46. Texture2D<uint4> _ParticlesData;
  47.  
  48. void DataLoad(out float3 outPosition, out float3 outVelocity, int2 uv)
  49. {
  50. uint4 data = _ParticlesData.Load(int3(uv.xy, 0));
  51.  
  52. int3 uintPosition = int3(
  53. data.x / DATA_OFFSET_11,
  54. data.x % DATA_OFFSET_11 + (data.y % DATA_OFFSET_11) * DATA_OFFSET_11,
  55. data.y / DATA_OFFSET_11
  56. );
  57. outPosition = float3(int3(uintPosition) - int(DATA_MAX_20)) / float(DATA_PRECISION_POS);
  58.  
  59. int3 uintVelocity = int3(
  60. data.z / DATA_OFFSET_11,
  61. data.z % DATA_OFFSET_11 + (data.w % DATA_OFFSET_11) * DATA_OFFSET_11,
  62. data.w / DATA_OFFSET_11
  63. );
  64. outVelocity = float3(int3(uintVelocity) - int(DATA_MAX_20)) / float(DATA_PRECISION_VEL);
  65. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement