# Why encode floats in RGBA?

Working on some effects that require depth (Z) data in Unity, I saw that these use a method to store the depth data encoded in the RGBA channels of a regular texture.

half4 frag(v2f i) : SV_Target
{
d = Linear01Depth(d);

return EncodeFloatRGBA(d);
}


Main question: why do this? Why not just store the result in a single-channel 16-bit float (R16F) texture?

Sub question:

What also surprises me is that the data is used as if these were independent RGBA channels. (the _EncodedDepth below contains the output of function above)

half4 color = float4 (0,0,0,0);
color += 0.40 * tex2D (_EncodedDepth, i.uv);


Then after that, information is decoded into a float value again.

float4 depth = tex2D(_ProcessedDepth, i.uv);
depth.a = DecodeFloatRGBA(hrDepth);
// do something with depth.a


Does this mean that linear operations applied to the encoded values are equivalent to linear operations applied to the original float? I.e.:

DecodeFloatRGBA( 0.5 * EncodeFloatRGBA(d) ) == 0.5 * d   // really?

• There are depth encodings that will encode the depth and depth^2 in the R and G channels. This helps with fuzzy shadows as after interpolation you can derive where the shadow is. – ratchet freak Mar 9 '15 at 10:42
• Floating-point texture formats were not always supported by D3D. On older hardware you have to encode the depth to a traditional 4 channel 8-bit unorm texture if you want 32-bit depth. – Andon M. Coleman Mar 9 '15 at 19:21
• @AndonM.Coleman , that constitutes an answer as far as I'm concerned :) – noio Mar 10 '15 at 10:25

I do not know how EncodeFloatRGBA (...) is implemented, but it is probably a dot product and a few divisions by numbers like 255.0 and 65535.0.