# 24bit float to RGB

There's solutions to convert float to RGBA but I would like to encode a float depth value in RGB format and save the three components in three separated unused alpha channels and recompose when needed. I prefer 24bit float because the decoded value is to be compared to regular 24+8 bit depthstencil buffer.

there's this code for float to RGBA (https://gamedev.net/forums/topic/684158-rgba-to-float-percision/5321338/)

vec4 pack(float depth)
{
const vec4 bitSh = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
const vec4 bitMsk = vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
vec4 comp = fract(depth * bitSh);
comp -= comp.xxyz * bitMsk;
return comp;
}

float unpack(vec2 pos)
{
const vec4 bitShifts = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1);
float shadow = dot(packedZValue , bitShifts);
}


I tried to change to vec3 by removing the first component as below but get weird results (see picture below).

Note: left panels are showing the alpha chanel were the depth is stored as 3 component (1rt = x, 3rd = y and 4th = z, second is something else) by default the alpha channel is 1 (so it appears white) as it is for depth buffer and I perform a alpha OP_MIN test to write new value as if it was comparison_less. So we can see something in panel 1/3 but in 4 it is still white suggesting that the z value is 1 or more.

vec3 pack(float depth)
{
const vec3 bitSh = vec3(256.0 * 256.0, 256.0, 1.0);
const vec3 bitMsk = vec3(0, 1.0 / 256.0, 1.0 / 256.0);
vec3 comp = fract(depth * bitSh);
comp -= comp.xyz * bitMsk;
return comp;
}

float unpack()
{
vec3 packedZValue = float3(textureA.a, textureB.a, textureC.a);
const vec3 bitShifts = vec4(1.0 / (256.0 * 256.0), 1.0 / 256.0, 1);
float shadow = dot(packedZValue , bitShifts);
}


• What "weird results" do you get? Jun 4, 2022 at 0:45
• I added a picture and some other informations for clarity Jun 7, 2022 at 8:06

Finally I change from RGB to RG encoding of depth with the code found here that is fine (https://blog.katastros.com/a?ID=00300-1312986b-8ead-4a41-8d1e-1845010de79a). Importantly I made a final test to have correct value for depth = 1 as the method seems not able to give full 1.0f. The code is recalled below with added the special depth =1 test in the depth decode part as well as a picture of the result.

encode :

 float2 FloatToRG(float v)
{
float2 kEncodeMul = float2(1.0f, 255.0f);
float kEncodeBit = 1.0f/255.0f;
float2 color = kEncodeMul*v;
color = frac(color);
color.x -= color.y * kEncodeBit;
return color;
}


decode

 //TexS is an int3