2015-05-14 8 views
0

Я пытаюсь сделать следующий в GLSL-ES:GLSL - сжатия/упаковки Множественные 0-1 цветов (var4) в одной Var4 переменной

Учитывая число (скажем, 4, например) нормированных var4 переменных (RGBA) уменьшают свою битовую глубину и упаковывают результаты в один 0-1 зажатый var4. Это будет сохранено как текстура 8 бит (на канал), а затем распакована. Я понимаю, что это приведет к потере качества, но это приемлемо.

Таким образом, в этом примере:

RGBA 8 битого
-> сводится к RGBA 2 бита
-> упакован с 3 другим RGBA 2 битых var4s
-> сохранен как одна 8 битой RGBA текстура
-> распакован назад в 4 x RGBA 2-битные переменные
-> уменьшен до версии исходного качества с пониженным качеством.

Я понимаю, что я не могу выполнять бит-сдвиг в GLSL, поэтому мне нужно будет сделать некоторую коллекцию умножений, магическая комбинация которой до сих пор ускользнула от меня! Другие говорили о упаковочных поплавках в vec4s, но моя проблема немного отличается.

Спасибо!

+0

Или, может быть, более простой способ, чтобы сказать, что это было бы просто выжать четыре 8 битных каналов в пространстве одного 8-битового канала , – Child

+0

Вы имеете в виду 'vec4', когда вы пишете' var4'? – derhass

+0

Да, глупая ошибка. Я действительно имел ввиду vec4 – Child

ответ

0

Ну, смещение битов может быть представлено умножением (для левых сдвигов) или делением (для правых сдвигов) с степенями двух. Вам просто нужно принять во внимание, что поплавки будут обрабатывать дробные части, которые обычно смещаются «вне» в нормальных целочисленных битах.

Так упаковать 4 нормированных поплавки a, b, c, d в нормализованный поплавок x, вы можете просто использовать

x = 1.0/255.0 * (floor(a*255.0/64.0)*64.0 + floor(b*255.0/64.0)*16.0 + floor(c*255.0/64.0)*4.0 + floor(d*255.0/64.0)); 

Распаковка является немного более сложной, потому что вы не можете просто маскировать отдельные биты , Вместо этого, вы можете вычесть наиболее значимые биты, как вы их восстановить, например, как это:

a = floor(x*255.0/64.0)*64.0/255.0; 
x -= a; 
b = floor(x*255.0/16.0)*16.0/255.0; 
x -= b; 
b *= 4.0; 
c = floor(x*255.0/4.0)*4.0/255.0; 
x -= c; 
c *= 16.0; 
d = x*255.0 * 64.0/255.0; // scan be simplified to just x*64.0 
+0

Спасибо за ответ. Тем не менее, я думаю, что здесь что-то немного в коде упаковки: если поплавки a, b, c и d нормализованы и перекрываются после деления на 64, они всегда равны 0. Этот код упаковки предполагает, что эти переменные находятся в диапазоне 0 -255? – Child

+0

@Child: Вы правы, у меня был ненормализованный диапазон [0,255], на мой взгляд, почему попытался имитировать бит-сдвиг, который будет делать на целых числах. Я обновил свой ответ. – derhass

+0

Спасибо, я все равно внес изменения в свой код, и он работает хорошо! Еще раз спасибо. – Child