Упаковка с плавающей точкой в vec4 - как работает этот код?

Я пытаюсь изучить карты теней в WebGL. Я вижу один и тот же фрагмент кода шейдера, скопированный в различные библиотеки и примеры, которые достигают этого. Однако нигде я не нашел объяснения того, как это работает.

Идея состоит в том, чтобы сохранить значение глубины (одиночное значение с плавающей точкой) в цветовом буфере (vec4). Существует функция упаковки, которая сохраняет float в vec4, и функция распаковки, которая извлекает float из 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;
}

Я предположил бы, что упаковка float в vec4 должна быть тривиальной проблемой, просто скопируйте его в один из 4 слотов vec4 и оставьте другие неиспользованными. Вот почему логика сдвига битов в приведенном выше коде озадачивает меня.

Кто-нибудь может пролить свет?

Ответы на вопрос(3)

Ваш ответ на вопрос