Режим наложения цветов Opengl ES

У меня есть система частиц, отображаемая поверх фоновой текстуры. Каждая частица представляет собой квадрат, к ней не применяется текстура, и все они одного цвета. Фон представляет собой текстуру в оттенках серого. Я пытаюсь добиться того же типа смешивания, известного в таких приложениях, как Gimp, как режим смешивания цветов.

По сути, область фона, покрытая частицей, должна сохранять свою яркость, но принимать цвет частицы. Я пробовал несколько комбинаций параметра glBlendFunc() и пытался возиться с glTexEnv, но у меня много проблем с пониманием этого. В настоящее время, если две частицы перекрываются, они становятся либо ярче, либо темнее (в зависимости от параметров glBlendFunc).

Я использую OpenGL ES 1.1 на Android. Есть ли способ добиться этого эффекта без использования OpenGL ES 2.0? Если так, то, что это?


person Davide    schedule 06.03.2014    source источник


Ответы (1)


glBlendFunc поддерживает только раздельные режимы наложения. Смешивание только оттенка не является разделимым, поэтому его нельзя выразить в стандартном OpenGL. См. эту презентацию Марка Килгарда из Nvidia, слайд 41.

Nvidia предоставляет расширение для своих новых графических процессоров (включая Tegra), которое называется NV_blend_equation_advanced который добавляет токены GL_HSL_HUE_NV и GL_HSL_COLOR_NV для выполнения операции, которую вы описываете. Учитывая, что вы хотите сохранить поддержку OpenGL ES 1.1, на самом деле это не вариант для вас.

Однако может быть способ добиться эффекта, который вы описываете, учитывая, что ваш фон имеет оттенки серого:

  1. преобразовать цвет частиц из RGB в цветовое пространство HSL
  2. максимизировать яркость в HSL (т.е. установить 1.0 0.5)
  3. преобразовать обратно в RGB. Это будет ваш фактический цвет частиц
  4. нарисуйте свою частицу с помощью операции многократного смешивания: glBlendFunc(GL_DST_COLOR, GL_ZERO)

Это должно поддерживать яркость при рисовании фона цветом частицы.

Редактировать: glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR) даст 2 * цвет источника * назначения, что может помочь.

Изменить 2: попробуйте glTexEnvf следующим образом.

  1. Рендеринг фона с помощью glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)
  2. Рендерим частицу с помощью glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)

Прошло более десяти лет с тех пор, как я в последний раз использовал glTexEnv, но может быть комбинация параметров, которая может достичь того, что вы пытаетесь сделать.

person The Fiddler    schedule 07.03.2014
comment
На втором этапе, если я максимизирую яркость в HSL, разве я не получу чистый белый цвет? Преобразовывая обратно в RGB, я получаю (255 255 255). Поэтому я попытался использовать цветовое пространство HSV и максимизировать значение, но фон становится темнее, когда частицы перекрываются. - person Davide; 07.03.2014
comment
Вы правы, в HSL яркость должна быть 0,5, а не 1,0 (чисто белый цвет). HSV со значением 1.0 должен дать тот же результат. Идея состоит в том, что умножение на чистый цвет не должно приводить к изменению яркости. Это работает только для чистых цветов (это можно легко проверить, например, с помощью RGB = (255,0,0).) - person The Fiddler; 07.03.2014
comment
Я получаю желаемый эффект, но только с цветами (255,0,0), (0,255,0) и (0,0,255). Если я использую что-то вроде (204,0,255), что соответствует (288º, 100%, 50%) в HSL, перекрытие становится темнее. - person Davide; 07.03.2014
comment
Поиграв еще немного, кажется, что единственные цвета, где перекрытие не становится темнее, это те, где канал установлен либо на 255, либо на 0 (т.е. 255,0,0; 255,255,0; 255,0,255 и т. д.). .) Есть еще идеи, которые я мог бы попробовать? - person Davide; 07.03.2014
comment
А, я только что понял, что glTexEnv доступен в OpenGL ЕС 1.1. Я думал, что это доступно только в десктопном OpenGL. См. мое редактирование в сообщении выше для другого потенциального решения. - person The Fiddler; 08.03.2014
comment
Я уже использовал GL_REPLACE для рендеринга фона, поэтому на него не повлиял gl_color. Что касается GL_MODULATE или любого другого текстурного окружения для рендеринга частиц, кажется, что оно действительно ничего не меняет, поскольку у частиц нет текстуры... Возможно, мне следует использовать белую текстуру и использовать GL_TEXTURE_ENV_COLOR для установки их цвета. Я попробую это сейчас. - person Davide; 11.03.2014
comment
Не повезло. Вся среда текстуры определяет, как текстуры применяются, а не как они смешиваются, поэтому все, что я могу сделать с glTexEnv, это определить цвет частиц... - person Davide; 12.03.2014