Таблица поиска не 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
. Это приводит к линейной интерполяции цветов на каждом тайле.
Каждая ячейка имеет тексель 64x64. Относительная координата нижнего левого текселя равна (0,5 / 64,0, 0,5 / 64,0), а относительная координата верхнего правого текселя равна (63,5 / 64,0, 63,5 / 64,0).канал зеленого цвета в диапазоне [0, 1] должен отображаться в диапазон [0,5 / 64,0, 63,5 / 64,0]:
vec2 tileUV = mix(0.5/tileSize, (tileSize-0.5)/tileSize, imageColor.rg);
Наконец, координата текстуры для таблицы поиска цветов в диапазоне[0, 1] c может быть рассчитано:
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);
См. Изображение, которое сравнивает исходное изображение (вверху слева) и с измененным изображением поиска цвета (внизу справа):