title: Pack four bytes in a float
body: <p>I'm writing a shader (HLSL), and I need to pack a color value into the R32 format. I've found various pieces of code for packing a float into the R8G8B8A8 format, but none of them seem to work in reverse. I'm targeting SM3.0, so (afaik) bit operations are not an option.</p>
  
  <p>To sum it up, I need to be able to do this:</p>
  
  <pre><code>float4 color = ...; // Where color ranges from 0 -&gt; 1
  float packedValue = pack(color);
  </code></pre>
  
  <p>Anyone know how to do this?</p>
  
  <p><strong>UPDATE</strong><br>
  I've gotten <em>some</em> headway... perhaps this will help to clarify the question.<br>
  My temporary solution is as such:</p>
  
  <pre><code>const int PRECISION = 64;
  
  float4 unpack(float value)
  {   
      float4 color;
  
      color.a = value % PRECISION;
      value = floor(value / PRECISION);
  
      color.b = value % PRECISION;
      value = floor(value / PRECISION);
  
      color.g = value % PRECISION;
      value = floor(value / PRECISION);
  
      color.r = value;
  
      return color / (PRECISION - 1);
  }
  
  float pack(float4 color)
  {   
      int4 iVal = floor(color * (PRECISION - 1));
  
      float output = 0;
  
      output += iVal.r * PRECISION * PRECISION * PRECISION;
      output += iVal.g * PRECISION * PRECISION;
      output += iVal.b * PRECISION;
      output += iVal.a;
  
      return output;
  }
  </code></pre>
  
  <p>I'm basically... pretending I'm using integer types :s<br>
  Through guess and check, 64 was the highest number I could use while still maintaining a [0...1] range. Unfortunately, that also means I'm losing some precision - 6 bits instead of 8.</p>