# HLSL: Pack 4 values into 32 bit float

I can't find any useful information on packing 4 values into a 32 bit float in HLSL.

Ideally, what I want to be able to do in HLSL is:

float4 values = ... // Some values where each component is between 0 and 1.
float packedValues = pack32R(values);
float4 values2 = unpack32R(packedValues);


I realize that there will be precision limitations, and performance tradeoffs between different precisions in different methods. I'm just wondering what ideas are out there.

• Also, I'll monitor this question and vote for good answers! Jan 29 '11 at 19:34
• Is there a reason you must pack the data into a float, or would packing them into a 32 bit integer as a fixed point format work?
– user744
Jan 29 '11 at 19:49
• I'm using 32R32R32R32R and want to maximize the amount of data that I can fit in there. So it has to be a float. Jan 29 '11 at 20:03
• What about use 8R8G8B8A used four times? Isn't it easier? Jan 31 '11 at 13:38

32bit floats have 24 bits of significant precision, so the best precision you're going to get is 6 bits per component.

I haven't tested this, but basically all you need is:

// C side, params in 0..63 ints
#define PACKI(a,b,c,d) ((a) << 18) | ((b) << 12) | ((c) << 6) | (d)
// C side, params in 0..1 floats
#define PACKF(a,b,c,d) \
((int)floor((a)*63) << 18) | \
((int)floor((b)*63) <<  12) | \
((int)floor((c)*63) <<   6) | \
((int)floor((d)*63))

// GLSL side
vec4 unpack(float i)
{
return mod(vec4(i / 262144.0, i / 4096.0, i / 64.0, i), 64.0);
}

• Oopsie, this was in glsl - I'm fairly certain hlsl isn't far off, though. Jan 31 '11 at 8:41
• The HLSL is almost the same, however, bitshifts cant be used on floats in SM 3.0. Can I safely replace those shifts with multiplies? E.g. << 8 becomes *= 2^18? Jan 31 '11 at 8:44
• Also, the bitwise OR operation is not permitted on floats in SM 3.0. Correct me if I'm wrong. en.wikipedia.org/wiki/High_Level_Shader_Language Jan 31 '11 at 8:45
• You can safely replace shifts with multiples, but like I commented above, those #defines are for C side. ORs can be replaced with additions. Jan 31 '11 at 8:50