Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
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
up vote 4 down vote accepted

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) | \

// GLSL side
vec4 unpack(float i)
   return mod(vec4(i / 262144.0, i / 4096.0, i / 64.0, i), 64.0);
share|improve this answer
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. – 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

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.