Преобразование 8-битного цвета в значение RGB

Я реализую глобальное освещение в своем игровом движке с помощью «отражающих карт теней». RSM имеет в т.ч. цвет текстуры. Для экономии памяти. Я упаковываю 24-битное значение в 8-битное значение. В порядке. Я знаю, как его упаковать. Но как распаковать? У меня была идея создать 1D текстуру с 8-битной палитрой, с 255 различными цветами. Мой 8-битный цвет будет индексом пикселя в этой текстуре. Я не уверен, как создать такую ​​​​текстуру. Существуют ли математические способы преобразования 8-битного значения в rgb?

@edit Цвет в следующем формате:
RRR GGG BB

@edit2: И я упаковываю свой цвет следующим образом:

int packed = (red / 32 << 5) + (green / 32 << 2) + (blue / 64);
//the int is actually a byte, c# compiler is bitching if it's byte.

@edit3:
Хорошо, думаю, я нашел способ сделать это. Скажи мне, если это неправильно.

@edit4 Это неправильно...

int r = (packed >> 5) * 32;    
int g = ((packed >> 2) << 3) * 32;    
int b = (packed << 6) * 64;

person Piotr Joniec    schedule 09.09.2012    source источник


Ответы (2)


В JavaScript

Кодировать

encodedData = (Math.floor((red / 32)) << 5) + (Math.floor((green / 32)) << 2) + Math.floor((blue / 64));

Расшифровать

red = (encodedData >> 5) * 32;
green = ((encodedData & 28) >> 2) * 32;
blue = (encodedData & 3) * 64;

При декодировании мы используем вентиль/оператор И для извлечения нужных битов и отбрасывания начальных битов. С зеленым цветом нам пришлось бы сдвинуться вправо, чтобы отбросить биты справа.

При кодировании Math.floor используется для усечения десятичной части, если его округлить, общее значение будет больше 255, что сделает его 9-битным числом.

ОБНОВЛЕНИЕ 1
Он не дает точных результатов, если мы делим цвет на 32 или 64.

РРРГГГББ

R/G = 3 бита, максимальное значение равно 111 в двоичном формате, что соответствует 7 в десятичном виде. B = 2 бита, максимальное значение равно 11 в двоичном формате, что равно 3 в десятичном формате.

Мы должны разделить R/G на значение, равное или большее 255/7, и B на значение, равное или большее 255/3. Мы также должны отметить, что вместо Math.floor мы должны использовать Math.round, потому что округление дает более точные результаты.

person Jai    schedule 12.08.2014

Чтобы преобразовать 8-битное [0 - 255] значение в 3-битное [0, 7], 0 не проблема, но помните, что 255 нужно преобразовать в 7, поэтому формула должна быть Red3 = Red8 * 7/255.

Чтобы преобразовать 24-битный цвет в 8-битный,

8bit Color = (Red * 7 / 255) << 5 + (Green * 7 / 255) << 2 + (Blue * 3 / 255)

Чтобы повернуть вспять,

Red   = (Color >> 5) * 255 / 7
Green = ((Color >> 2) & 0x07) * 255 / 7
Blue  = (Color & 0x03) * 255 / 3
person Mingjie Li    schedule 17.06.2016