I am trying to study shadow mapping in WebGL. I see same piece of shader code copied in various libraries and examples that achieve this. However nowhere did I find the explanation of how it works.
The idea is to save a depth value (a single float) into the color buffer (vec4). There is a pack function that saves float to vec4 and unpack function that retrieves the float from vec4.
vec4 pack_depth(const in float depth)
{
const vec4 bit_shift = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);
const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);
vec4 res = fract(depth * bit_shift);
res -= res.xxyz * bit_mask;
return res;
}
float unpack_depth(const in vec4 rgba_depth)
{
const vec4 bit_shift = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);
float depth = dot(rgba_depth, bit_shift);
return depth;
}
I would have imagined that packing a float into vec4 should be a trivial problem, just copy it into one of the 4 slots of vec4 and leave others unused. That's why the bit shifting logic in above code is puzzling to me.
Can anyone shed some light?
It's not storing a GLSL float
in a GLSL vec4
. What it's doing is storing a value in a vec4
which, when written to an RGBA8 framebuffer (32-bit value) can be read as a vec4
and then reconstituted into the same float
that was given previously.
If you did what you suggest, just writing the floating-point value to the red channel of the framebuffer, you'd only get 8 bits of accuracy. With this method, you get all 32-bits working for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With