Ysaneya

09-13-2007, 07:47 AM

In my GLSL shader I compute a depth value in [0-1]. I want to output this value to two channels of a RGBA16f texture, in order to keep the full 32-bits precision.

My initial (naive) approach was to do this:

/// Packing a [0-1] float value into a 2D vector where each component will be a 16-bits float

vec2 packFloatToVec2f(const float value)

{

const vec2 bitSh = vec2(256.0 * 256.0, 1.0);

const vec2 bitMsk = vec2(0.0, 1.0 / (256.0 * 256.0));

vec2 res = fract(value * bitSh);

res -= res.xx * bitMsk;

/// res.x = frac(value * 256^2)

/// res.y = frac(value * 1.0) - frac(value * 256.0^2) / (256.0^2)

return res;

}

/// Unpacking a [0-1] float value from a 2D vector where each component was a 16-bits float

float unpackFloatFromVec2f(const vec2 value)

{

const vec2 bitSh = vec2(1.0 / (256.0 * 256.0), 1.0);

return(dot(value, bitSh));

}It does not work, because I think unlike RGBA8 fixed point, the floating point format isn't uniform in the [0-1] range, but dependant on the IEEE floating-point representation. So I get all sorts of artifacts and loss of accuracy.

Is there a way to pack a float32 into two channels of a RGBA16f texture in GLSL ?

Y.

My initial (naive) approach was to do this:

/// Packing a [0-1] float value into a 2D vector where each component will be a 16-bits float

vec2 packFloatToVec2f(const float value)

{

const vec2 bitSh = vec2(256.0 * 256.0, 1.0);

const vec2 bitMsk = vec2(0.0, 1.0 / (256.0 * 256.0));

vec2 res = fract(value * bitSh);

res -= res.xx * bitMsk;

/// res.x = frac(value * 256^2)

/// res.y = frac(value * 1.0) - frac(value * 256.0^2) / (256.0^2)

return res;

}

/// Unpacking a [0-1] float value from a 2D vector where each component was a 16-bits float

float unpackFloatFromVec2f(const vec2 value)

{

const vec2 bitSh = vec2(1.0 / (256.0 * 256.0), 1.0);

return(dot(value, bitSh));

}It does not work, because I think unlike RGBA8 fixed point, the floating point format isn't uniform in the [0-1] range, but dependant on the IEEE floating-point representation. So I get all sorts of artifacts and loss of accuracy.

Is there a way to pack a float32 into two channels of a RGBA16f texture in GLSL ?

Y.