Ysaneya
09-13-2007, 06: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.