Таблица поиска не 64*64*64, а 64*64 в растре 8*8. Цветовые каналы, которые считывает texture2D
, находятся в диапазоне [0, 1], а координаты текстуры также находятся в диапазоне [0, 1].
vec2 tiles = vec2(8.0);
vec2 tileSize = vec2(64.0);
vec3 imageColor = texture(src_i, samplerCoord(src_i)).rgb;
Индекс тайла кодируется в канал синего цвета. Имеется 64 плитки, первая плитка имеет индекс 0, а последняя плитка имеет индекс 63. Это означает, что канал синего цвета в диапазоне [0, 1] должен быть сопоставлен с диапазоном [0, 63]:
float index = imageColor.b * (tiles.x * tiles.y - 1.0);
Из этого линейного индекса плитки необходимо рассчитать двумерный индекс плитки в диапазоне [0, 8]:
vec2 tileIndex;
tileIndex.y = floor(index / tiles.x);
tileIndex.x = floor(index - tileIndex.y * tiles.x);
Функция минимизации текстуры (GL_TEXTURE_MIN_FILTER
) и увеличение текстуры функция (GL_TEXTURE_MAG_FILTER
должна быть установлена на GL_LINEAR
. Это приводит к тому, что цвета на каждой плитке могут быть линейными. интерполированный.
Каждая плитка имеет тексели 64 x 64. Относительная координата нижнего левого текселя – (0,5/64,0, 0,5/64,0), а относительная координата верхнего правого текселя – (63,5/64,0, 63,5/64,0).< br> Красный и зеленый цветовые каналы в диапазоне [0, 1] должны быть сопоставлены с диапазоном [0,5/64,0, 63,5/64,0]:
vec2 tileUV = mix(0.5/tileSize, (tileSize-0.5)/tileSize, imageColor.rg);
Наконец, можно вычислить координату текстуры для справочной таблицы цвета в диапазоне [0, 1]:
vec2 tableUV = tileIndex / tiles + tileUV / tiles;
Окончательный код, который декодирует цвет во фрагментном шейдере, может выглядеть так:
vec2 tiles = vec2(8.0, 8.0);
vec2 tileSize = vec2(64.0);
vec4 imageColor = texture(src_i, samplerCoord(src_i));
float index = imageColor.b * (tiles.x * tiles.y - 1.0);
vec2 tileIndex;
tileIndex.y = floor(index / tiles.x);
tileIndex.x = floor(index - tileIndex.y * tiles.x);
vec2 tileUV = mix(0.5/tileSize, (tileSize-0.5)/tileSize, imageColor.rg);
vec2 tableUV = tileIndex / tiles + tileUV / tiles;
vec3 lookUpColor = texture(src_l, tableUV).rgb;
Этот алгоритм можно дополнительно улучшить путем интерполяции между двумя тайлами таблицы. Вычислить индекс плитки ниже канала синего цвета и индекс плитки выше канала синего цвета:
float index = imageColor.b * (tiles.x * tiles.y - 1.0);
float index_min = min(62.0, floor(index));
float index_max = index_min + 1.0;
Наконец, выполните интерполяцию между цветами обеих плиток, используя mix
а> функция:
vec3 lookUpColor_1 = texture(src_l, tableUV_1).rgb;
vec3 lookUpColor_2 = texture(src_l, tableUV_1).rgb;
vec3 lookUpColor = mix(lookUpColor_1, lookUpColor_2, index-index_min);
Окончательный код:
vec2 tiles = vec2(8.0, 8.0);
vec2 tileSize = vec2(64.0);
vec4 imageColor = texture(src_i, samplerCoord(src_i));
float index = imageColor.b * (tiles.x * tiles.y - 1.0);
float index_min = min(62.0, floor(index));
float index_max = index_min + 1.0;
vec2 tileIndex_min;
tileIndex_min.y = floor(index_min / tiles.x);
tileIndex_min.x = floor(index_min - tileIndex_min.y * tiles.x);
vec2 tileIndex_max;
tileIndex_max.y = floor(index_max / tiles.x);
tileIndex_max.x = floor(index_max - tileIndex_max.y * tiles.x);
vec2 tileUV = mix(0.5/tileSize, (tileSize-0.5)/tileSize, imageColor.rg);
vec2 tableUV_1 = tileIndex_min / tiles + tileUV / tiles;
vec2 tableUV_2 = tileIndex_max / tiles + tileUV / tiles;
vec3 lookUpColor_1 = texture(src_l, tableUV_1).rgb;
vec3 lookUpColor_2 = texture(src_l, tableUV_2).rgb;
vec3 lookUpColor = mix(lookUpColor_1, lookUpColor_2, index-index_min);
Посмотрите изображение, которое сравнивает исходное изображение (вверху слева) и измененное изображение с поиском цвета (внизу справа):
а>
person
Rabbid76
schedule
17.02.2019