Прежде всего, я ничего не знаю о CSM, поэтому я сосредоточен на сглаживании и смешивании. Сначала посмотрите на это:
Они в основном отвечают на ваш вопрос о том, как рассчитать шаблон / пиксели дизеринга.
Также важно иметь хорошую палитру для дизеринга, которая уменьшает ваши 24/32 бит / с в 8 bpp (или меньше). Существует 2 базовых c подхода
уменьшение цветов (квантование цветов)
, поэтому рассчитайте гистограмму исходного изображения и выберите из него значительные цвета это более или менее охватывает всю информацию об изображении. Для получения дополнительной информации см .:
палитра сглаживания
Дизеринг использует усреднение пикселей для генерации желаемого цвета, поэтому нам нужно иметь такие цвета, которые могут генерировать все возможные цвета, которые мы хотим. Поэтому хорошо иметь несколько (2..4) оттенков каждого базового цвета (R, G, B, C, M, Y) и несколько (> = 4) оттенков серого. Из них вы можете комбинировать любой цвет и интенсивность по вашему желанию (если у вас достаточно пикселей)
# 1 является лучшим, но это для каждого изображения, так что вам нужно рассчитать палитру для каждого изображения. Это может быть проблемой, так как эти вычисления являются неприятными процессорами, требующими много ресурсов процессора. Кроме того, в старых 256 цветовых режимах вы не могли одновременно отображать 2 разные палитры (что с истинным цветом больше не является проблемой), поэтому выбор цвета обычно является лучшим выбором.
Вы даже можете комбинировать эти два для впечатляющего результаты.
Чем лучше используемая палитра, тем менее зернистой получается результат ...
Стандартные цветовые палитры VGA 16 и 256 специально разработаны для сглаживания, поэтому рекомендуется использовать их. ...
Стандартная цветовая палитра VGA 16:
Стандартная цветовая палитра VGA 256:
Здесь также код C ++ для 256 цветов:
//---------------------------------------------------------------------------
//--- EGA VGA pallete -------------------------------------------------------
//---------------------------------------------------------------------------
#ifndef _vgapal_h
#define _vgapal_h
//---------------------------------------------------------------------------
unsigned int vgapal[256]=
{
0x00000000,0x00220000,0x00002200,0x00222200,
0x00000022,0x00220022,0x00001522,0x00222222,
0x00151515,0x00371515,0x00153715,0x00373715,
0x00151537,0x00371537,0x00153737,0x00373737,
0x00000000,0x00050505,0x00000000,0x00030303,
0x00060606,0x00111111,0x00141414,0x00101010,
0x00141414,0x00202020,0x00242424,0x00202020,
0x00252525,0x00323232,0x00303030,0x00373737,
0x00370000,0x00370010,0x00370017,0x00370027,
0x00370037,0x00270037,0x00170037,0x00100037,
0x00000037,0x00001037,0x00001737,0x00002737,
0x00003737,0x00003727,0x00003717,0x00003710,
0x00003700,0x00103700,0x00173700,0x00273700,
0x00373700,0x00372700,0x00371700,0x00371000,
0x00371717,0x00371727,0x00371727,0x00371737,
0x00371737,0x00371737,0x00271737,0x00271737,
0x00171737,0x00172737,0x00172737,0x00173737,
0x00173737,0x00173737,0x00173727,0x00173727,
0x00173717,0x00273717,0x00273717,0x00373717,
0x00373717,0x00373717,0x00372717,0x00372717,
0x00372525,0x00372531,0x00372536,0x00372532,
0x00372537,0x00322537,0x00362537,0x00312537,
0x00252537,0x00253137,0x00253637,0x00253237,
0x00253737,0x00253732,0x00253736,0x00253731,
0x00253725,0x00313725,0x00363725,0x00323725,
0x00373725,0x00373225,0x00373625,0x00373125,
0x00140000,0x00140007,0x00140006,0x00140015,
0x00140014,0x00150014,0x00060014,0x00070014,
0x00000014,0x00000714,0x00000614,0x00001514,
0x00001414,0x00001415,0x00001406,0x00001407,
0x00001400,0x00071400,0x00061400,0x00151400,
0x00141400,0x00141500,0x00140600,0x00140700,
0x00140606,0x00140611,0x00140615,0x00140610,
0x00140614,0x00100614,0x00150614,0x00110614,
0x00060614,0x00061114,0x00061514,0x00061014,
0x00061414,0x00061410,0x00061415,0x00061411,
0x00061406,0x00111406,0x00151406,0x00101406,
0x00141406,0x00141006,0x00141506,0x00141106,
0x00141414,0x00141416,0x00141410,0x00141412,
0x00141414,0x00121414,0x00101414,0x00161414,
0x00141414,0x00141614,0x00141014,0x00141214,
0x00141414,0x00141412,0x00141410,0x00141416,
0x00141414,0x00161414,0x00101414,0x00121414,
0x00141414,0x00141214,0x00141014,0x00141614,
0x00100000,0x00100004,0x00100000,0x00100004,
0x00100010,0x00040010,0x00000010,0x00040010,
0x00000010,0x00000410,0x00000010,0x00000410,
0x00001010,0x00001004,0x00001000,0x00001004,
0x00001000,0x00041000,0x00001000,0x00041000,
0x00101000,0x00100400,0x00100000,0x00100400,
0x00100000,0x00100002,0x00100004,0x00100006,
0x00100010,0x00060010,0x00040010,0x00020010,
0x00000010,0x00000210,0x00000410,0x00000610,
0x00001010,0x00001006,0x00001004,0x00001002,
0x00001000,0x00021000,0x00041000,0x00061000,
0x00101000,0x00100600,0x00100400,0x00100200,
0x00100303,0x00100304,0x00100305,0x00100307,
0x00100310,0x00070310,0x00050310,0x00040310,
0x00030310,0x00030410,0x00030510,0x00030710,
0x00031010,0x00031007,0x00031005,0x00031004,
0x00031003,0x00041003,0x00051003,0x00071003,
0x00101003,0x00100703,0x00100503,0x00100403,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
};
//---------------------------------------------------------------------------
class _vgapal_init_class
{
public: _vgapal_init_class();
} vgapal_init_class;
//---------------------------------------------------------------------------
_vgapal_init_class::_vgapal_init_class()
{
int i;
BYTE a;
union { unsigned int dd; BYTE db[4]; } c;
for (i=0;i<256;i++)
{
c.dd=vgapal[i];
c.dd=c.dd<<2;
a =c.db[0];
c.db[0]=c.db[2];
c.db[2]= a;
vgapal[i]=c.dd;
}
}
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//--- end. ------------------------------------------------------------------
//---------------------------------------------------------------------------
Теперь вернемся к вашему вопросу о смешивании путем сглаживания
Смешивание - это слияние 2 изображения одного и того же разрешения вместе на некоторое количество (вес). Таким образом, цвет каждого пикселя вычисляется следующим образом:
color = w0*color0 + w1*color1;
, где color?
- это пиксели в исходных изображениях, а w?
- это веса, где все веса вместе составляют до 1:
w0 + w1 = 1;
Вот пример:
и предварительный просмотр (точки смазываются из моего GIF-кодировщика):
Но смешивание с помощью сглаживания выполняется по-другому. Вместо смешивания цветов мы используем некоторый процент пикселей от одного изображения, а другие от второй. Итак:
if (Random()<w0) color = color0;
else color = color1;
Где Random()
возвращает псевдослучайное число в диапазоне <0,1>
. Как видите, комбинирование цветов не выполняется, просто вы выбираете, из какого изображения вы копируете пиксель ... Вот предварительный просмотр:
Теперь Точки вызваны смешиванием из-за сглаживания, так как интенсивность изображений очень далеко друг от друга, поэтому она выглядит не очень хорошо, но если вы смазываете относительно похожие изображения (например, слои карт теней), результат должен быть достаточно хорошим (с почти без потери производительности).
Чтобы ускорить это, обычно нужно предварительно вычислить Random()
выходы для некоторого блока (8x8, 16x16, ...) и использовать его для всего изображения (оно немного блочное, но это вроде используется как забавный эффект ...). Таким образом, это может быть сделано также без ответвлений (если вы храните указатели на исходные изображения вместо случайных значений). Также это может быть сделано полностью на целых числах (без фиксированной точности), если веса являются целыми числами, например <0..255>
...
Теперь, чтобы сделать каскад / переход от image0
к image1
или что-то еще просто просто сделайте что-то вроде этого:
for (w0=1.0;w0>=0.0;w0-=0.05)
{
w1=1.0-w0;
render blended images;
Sleep(100);
}
render image1;