Для того, чтобы оставить ответ в протоколе и предположить, что вы не можете выполнить дальнейшую оптимизацию, вы можете:
1) Загрузить значение яркости в альфа-канал
Установите объект framebuffer, того же размера, что и исходная текстура. Используйте glColorMask, чтобы включить или отключить запись на разные каналы. Прежде всего, включите красный, зеленый и синий каналы и отключите альфа-канал. Нарисуйте текстуру нормально. Это дублирует информацию о цвете текстуры.
Затем включите альфа-канал и отключите красный, зеленый и синий каналы. Используйте расширение dot3 (которое поддерживается на iPhone с самого начала), чтобы заполнить целевой альфа-канал значениями яркости.
2) Разделить текстуру на три текстуры в зависимости от яркости
Простая схема будет просто разделить на яркость = 0,5 и игнорировать линейное смешение. Если бы вы сделали это, вы могли бы снова использовать объекты кадрового буфера, чтобы разделить текстуру на GPU. На этот раз используйте альфа-функцию (glAlphaFunc и обязательно включите ее), чтобы передать все эти области с альфа-значением больше 0,50 при рисовании на одну текстуру, чтобы передать все эти объекты с альфа-значением меньше 0,50 при рисовании на другую.
Хотя вы можете выполнить только один альфа-тест на пиксель, то есть вы не можете выделить диапазон от 0,45 до 0,55 за один шаг, вы можете сделать это за два шага.
3) Используйте обычные режимы наложения, чтобы объединить две или три текстуры в буфер кадров
При необходимости вы можете отключить систему освещения для смещения и масштабирования альфа-каналов во время рендеринга.
Очевидно, что вы оптимизируете, выполняя те шаги, которые идентичны для каждого розыгрыша, только один раз, при запуске. Что, вероятно, означает постоянное хранение того, что в данный момент является одной текстурой, двумя или тремя.