# 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! – Olhovsky 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. – Olhovsky Jan 29 '11 at 20:03
What about use 8R8G8B8A used four times? Isn't it easier? – Notabene 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. – Jari Komppa 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`? – Olhovsky 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 – Olhovsky 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. – Jari Komppa Jan 31 '11 at 8:50