# Splitting Floats To Texture Channels

I know, this is a silly question, but since I need this so often, I just want to double check that I made no mistake.

Working with most shader languages, a texture can store $$8$$ bits per channels, which in the shader programm appear as value in the range range $$r_8:=\{0, 1/255, 2/255,\dots,1\}$$. What I want to do is to transform between a single $$32$$ bit floating point value in $$(0, 1)$$ (I don't care about the floating point specifics here and just think of it as real number) and a $$4$$-tuple of values in $$r_8$$, so $$\text{split}:(0,1)\to r_8^4$$ and $$\text{comb}:r_8^4\to(0,1)$$.

I specifically want that $$\text{comb}(\text{split}(x))=\text{round}(256^4 x)/256^4$$ for almost all $$x$$ (I don't care about the ones lying on boundaries between bins).

My implementation is the following:

• $$\text{split}(x)_i := \text{floor}(256^ix)/(255\cdot 256^{i-1})$$
• $$\text{comb}(x_0,\dots,x_3):=255(x_0/256+\dots+x_3/256^4)+256^4/2$$

Is this correct or did I overlook something?

## Edit

I realized that the first part should be $$\text{split}(x)_i:=\lfloor(256(256^ix-\lfloor256^ix\rfloor)\rfloor/255$$ However, it is possible to pack the amount of data you want into a float; the key is that you have to reinterpret the bits of the float as a 32-bit integer or vice versa. In GLSL, this is provided by the functions floatBitsToUint() and uintBitsToFloat(). Once you have the unsigned integer, you can proceed as you intended — but the produced float will not be in the range 0 to 1.
• Hey, thanks a lot for the answer! I realized that I'd need $\text{split}(x)_i:=\lfloor(256(256^ix-\lfloor256^ix\rfloor)\rfloor/255$, but regarding your argument about $32$ bit floats, the specification says that precision highp float; just guarantees at least $32$ bit precision, but it could be higher, so do you think my idea could make more sense in this regard? If the precision is only $32$, I won't get $256^4$ bins, but it also wouldn't lead to any large errors, I think? Feb 6 at 7:02
• @fweth What you care about for this purpose is the number of mantissa bits, not the total number of bits. 32-bit floats have 24 (effective) mantissa bits, and 64-bit floats have 53 mantissa bits. As I already described, 24 bits means you lose 1 of your 4 components. 53 bits is sufficient for everything, but from what I've heard, even if a GPU supports 64-bit floats, they're so slow as to be unwise to use. (I don't know whether highp ever maps to 64-bit.) Feb 6 at 16:09