Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // by Neitri, free of charge, free to redistribute
- // packs and unpacks between:
- // 6 x 32 bit float
- // 4 x 32 bit int
- // during packing each float is converted to 21 bit fixed precision
- // precision is specified here:
- #define DATA_PRECISION_POS 0x800
- #define DATA_PRECISION_VEL 0x10000
- // 0b111111111111111111111 == 2 097 151 // 21 bits are 1
- #define DATA_MAX_21 0x1FFFFF
- #define DATA_MAX_20 0xFFFFF
- // 0b100000000000 // 1 bit is 1, 11 bits are 0
- #define DATA_OFFSET_11 0x800
- // how to do bit shift and mask
- // mask: take only least significant 11 bits = data.y % DATA_OFFSET_11
- // shift: add 11 empty least significant bits = data.y * DATA_OFFSET_11
- // shift: remove 11 least significant bits = data.y / DATA_OFFSET_11
- uint4 DataSave(float3 inPosition, float3 inVelocity)
- {
- uint4 data = 0;
- uint3 uintPosition = clamp(uint3(round(inPosition * float(DATA_PRECISION_POS)) + int(DATA_MAX_20)), uint(0), uint(DATA_MAX_21));
- data.x = uintPosition.x * DATA_OFFSET_11 + (uintPosition.y % DATA_OFFSET_11);
- data.y = uintPosition.z * DATA_OFFSET_11 + (uintPosition.y / DATA_OFFSET_11);
- uint3 uintVelocity = clamp(uint3(round(inVelocity * float(DATA_PRECISION_VEL)) + int(DATA_MAX_20)), uint(0), uint(DATA_MAX_21));
- data.z = uintVelocity.x * DATA_OFFSET_11 + (uintVelocity.y % DATA_OFFSET_11);
- data.w = uintVelocity.z * DATA_OFFSET_11 + (uintVelocity.y / DATA_OFFSET_11);
- // uint4 data layout
- // x pos.x 21 bits | pos.y least significant 11 bits
- // y pos.z 21 bits | | pos.y most significant 10 bits
- // z vel.x 21 bits | vel.y least significant 11 bits
- // w vel.z 21 bits | | vel.y most significant 10 bits
- // 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
- return data;
- }
- Texture2D<uint4> _ParticlesData;
- void DataLoad(out float3 outPosition, out float3 outVelocity, int2 uv)
- {
- uint4 data = _ParticlesData.Load(int3(uv.xy, 0));
- int3 uintPosition = int3(
- data.x / DATA_OFFSET_11,
- data.x % DATA_OFFSET_11 + (data.y % DATA_OFFSET_11) * DATA_OFFSET_11,
- data.y / DATA_OFFSET_11
- );
- outPosition = float3(int3(uintPosition) - int(DATA_MAX_20)) / float(DATA_PRECISION_POS);
- int3 uintVelocity = int3(
- data.z / DATA_OFFSET_11,
- data.z % DATA_OFFSET_11 + (data.w % DATA_OFFSET_11) * DATA_OFFSET_11,
- data.w / DATA_OFFSET_11
- );
- outVelocity = float3(int3(uintVelocity) - int(DATA_MAX_20)) / float(DATA_PRECISION_VEL);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement