#opengl #colors #filter
#opengl #Цвет #Фильтр
Вопрос:
У меня есть open GL quad, который отображается с градиентом оттенков серого. Я хотел бы раскрасить его, применив фильтр, что-то вроде:
Если color = 0,0,0, то установите цвет равным 255,255,255
, Если color = 0,0,1, то установите цвет равным 255,255,254
и т.д., Или какую-нибудь схему, которую я выберу.
Обратите внимание на причину, по которой я делаю это в оттенках серого, потому что алгоритм, который я использую, был разработан для рисования в оттенках серого, а затем раскрашен, поскольку цвета могут быть известны не сразу.
Это было бы похоже на поисковую систему Javahttp://download.oracle.com/javase/6/docs/api/java/awt/image/LookupOp.html .
Есть ли способ сделать это в OpenGL?
спасибо,
Джефф
Комментарии:
1. Кстати — пожалуйста, никогда не забывайте указывать свою версию OpenGL при публикации вопросов, связанных с OpenGL.
Ответ №1:
Вы могли бы интерпретировать эти цвета из градиента в оттенках серого как координаты одномерной текстуры, а затем указать вашу справочную таблицу как одномерную текстуру. Кажется, это соответствует вашей ситуации.
В качестве альтернативы вы можете использовать фрагментную программу (шейдер) для выполнения произвольных цветовых преобразований отдельных пикселей.
Еще несколько пояснений: что такое текстура? Текстура, концептуально, представляет собой своего рода функцию поиска с некоторой дополнительной логикой сверху.
Двумерная текстура — это то, что для любой пары координат (s, t) или (x, y) в диапазоне [0,0] — [1,1] дает определенный цвет (RGB, RGBA, L, что угодно). Кроме того, в нем есть некоторые настройки, такие как деформация или фильтрация.
Внизу текстура описывается дискретными данными заданной «плотности» — возможно, 16×16, возможно, 256×512. Процесс фильтрации позволяет указать цвет для любого действительного числа в диапазоне от [0,0] до [1,1] (путем смешивания / интерполяции соседних текселов или просто взятия ближайшего).
Одномерная текстура идентична, за исключением того, что она отображает только одно реальное значение цвета. Следовательно, его можно рассматривать как особый тип «таблицы подстановки». Вы можете считать это эквивалентным 2-мерной текстуре, основанной на изображении размером 1xN.
Если у вас есть градиент в оттенках серого, вы можете отобразить его напрямую, обработав значение градиента как цвет — или вы можете обработать его как координаты текстуры (= индексы в таблице поиска) и использовать одномерную текстуру для произвольного преобразования цветового пространства.
Вам просто нужно перевести значения градиента (из диапазона 0 .. 255) в диапазон индексов текстуры [0 ..1]. Я бы порекомендовал что-то вроде out = (in 0.5)/256.0
. Значение 0,5 соответствует смещению в половину текселя, поскольку мы хотим указать на середину текселя (значение внутри текстуры), а не на угол между двумя значениями.
Чтобы иметь только точные значения RGB из таблицы поиска (= одномерная текстура), также установите для текстурных фильтров значение GL_NEAREST
.
Кстати: Обратите внимание, что если вам уже нужна другая текстура для рисования градиента, тогда это становится немного сложнее, потому что вы захотите обрабатывать значения, полученные из одной текстуры, как координаты для другой текстуры — и я полагаю, что для этого вам понадобятся пиксельные шейдеры. Не то чтобы шейдеры были сложными или что-то в этом роде… они чрезвычайно удобны, когда вы изучаете основы.
Комментарии:
1. @Kos, не могли бы вы объяснить, что вы подразумеваете под первым утверждением об интерпретации в виде координат текстуры в 1-D формате?
2. @Jeff: В шейдере фрагмента используйте значение, считанное из градиентной текстуры, чтобы получить доступ ко второй текстуре с цветовой рампой.
3. @datenwolf, имеет ли значение, что форма градиента на самом деле не является текстурой, когда я ее рисую (т. Е. я не использовал GL_TEXTURE_2D для ее рисования)
4. @Jeff: Идея в том, чтобы использовать одномерную текстуру в качестве справочной таблицы. Допустим, v — это исходное значение оттенков серого в диапазоне от 0 до 1. И давайте предположим, что в примере texRamp есть одномерная текстура, содержащая желаемую цветовую гамму, тогда вы можете найти цвет с помощью ‘gl_FrontColor = texture1D(texRamp, v);’ в шейдере GLSL.
5. Понятно, спасибо. Я никогда раньше не работал с шейдерами (все еще немного новичок в OpenGL!). Я начал читать о них, и это имеет смысл, спасибо.