Примеры шейдеров OpenGL ES 2.0 для обработки изображений? - PullRequest
9 голосов
/ 02 июня 2011

Я изучаю программирование шейдеров и ищу примеры, специально для обработки изображений.Я хотел бы применить некоторые эффекты Photoshop к моим фотографиям, например, кривые, уровни, настройки оттенка / насыщенности и т. Д.

Ответы [ 2 ]

10 голосов
/ 02 июня 2011

Я предполагаю, что у вас есть простой не противоречивый вершинный шейдер, так как он на самом деле не имеет отношения к вопросу, такой как:

void main()
{
    gl_Position = modelviewProjectionMatrix * position;
    texCoordVarying = vec2(textureMatrix * vec4(texCoord0, 0.0, 1.0));
}

Так что это почти так же, как ES 1.x, если освещениебыл отключен, включая матрицу текстур, которую почти никто не использует.

Я не эксперт по Photoshop, поэтому, пожалуйста, прости мои высказывания о том, что, по моему мнению, делают различные инструменты, особенно если я ошибаюсь.

Я думаю, что правильно сказать, что инструмент уровней эффективно растягивает (и обрезает) гистограмму яркости?В этом случае примерным шейдером может быть:

varying mediump vec2 texCoordVarying;
uniform sampler2D tex2D;

const mediump mat4 rgbToYuv = mat4( 0.257,  0.439,  -0.148, 0.06, 
                                    0.504, -0.368,  -0.291, 0.5,
                                    0.098, -0.071,   0.439, 0.5, 
                                     0.0,     0.0,     0.0, 1.0);

const mediump mat4 yuvToRgb = mat4( 1.164,  1.164,  1.164,  -0.07884, 
                                    2.018, -0.391,    0.0,  1.153216,
                                      0.0, -0.813,  1.596,  0.53866, 
                                      0.0,    0.0,    0.0,  1.0);

uniform mediump float centre, range;    

void main()
{
    lowp vec4 srcPixel = texture2D(tex2D, texCoordVarying);
    lowp vec4 yuvPixel = rgbToYuv * srcPixel;

    yuvPixel.r = ((yuvPixel.r - centre) * range) + 0.5;

    gl_FragColor = yuvToRgb * yuvPixel;
}

Вы можете контролировать это, устанавливая центр диапазона, который вы хотите пропустить (который будет перемещен в центр диапазона вывода), иобщий диапазон, который вы хотите пропустить (1,0 для всего диапазона, 0,5 для половины диапазона и т. д.).

Одна вещь, представляющая интерес, состоит в том, что я переключаюсь с пространства ввода RGB на цветовое пространство YUV для промежуточногорегулировка.Я делаю это с помощью умножения матриц.Затем я настраиваю канал яркости и применяю другую матрицу, которая преобразует обратно из YUV в RGB.Для меня было наиболее разумно работать в цветовом пространстве яркости / цветности, и оттуда я выбрал YUV довольно произвольно, хотя он имеет большое преимущество для целей ES в виде простого линейного преобразования пространства RGB.

IЯ понимаю, что инструмент кривых также переназначает яркость, но в соответствии с некоторой функцией f (x) = y, которая монотонно увеличивается (то есть будет пересекать любую горизонталь или вертикаль только один раз) и устанавливается в интерфейсе какКак-то кривая снизу-слева-вверх-вправо.

Поскольку GL ES не фантастична со структурами данных, и по возможности следует избегать ветвления, я бы предложил лучший способ реализации, который заключается в загрузке яркости 256x1.текстура, где значение в «х» является f (х).Затем вы можете просто отобразить вторичную текстуру, например, с помощью:

... same as before down to ...
lowp vec4 yuvPixel = rgbToYuv * srcPixel;

yuvPixel.r = texture2D(lookupTexture, vec2(yuvPixel.r, 0.0));

... and as above to convert back to RGB, etc ...

Вы используете запасной текстурный блок для эффективного индексирования таблицы поиска.На устройствах iOS, которые поддерживают ES 2.0, вы получаете по крайней мере восемь текстурных блоков, поэтому, надеюсь, у вас будет один запасной.

Корректировка оттенка / насыщенности более болезненно показывать, поскольку отображение от RGB до HSV включает в себя множество условных выражений., но процесс в основном тот же - сопоставьте RGB с HSV, выполните необходимые изменения для H и S, сопоставьте с RGB и выведите.

На основе быстрого поиска Google, этого сайта предлагает некоторый загружаемый код, который включает в себя некоторые функции Photoshop (хотя это не кривые или уровни, которые я могу видеть) и, что существенно, предоставляет примеры реализации функций RGBToHSL и HSLToRGB.Это для настольного GLSL, который имеет более предопределенные переменные, типы и функции, но у вас не должно быть больших проблем, чтобы обойти это.Только не забудьте добавить прецизионные модификаторы и предоставить собственные замены отсутствующим функциям min и max.

6 голосов
/ 03 июня 2011

Для кривых фотошоп использует бикубическую сплайн-интерполяцию. Для заданного набора контрольных точек вы можете предварительно рассчитать все 256 значений для каждого канала и для мастер-кривой. Я обнаружил, что проще сохранить результаты в виде текстуры 256x1 и передать ее шейдеру, а затем изменить значения каждого компонента:

uniform sampler2D curvesTexture;

vec3 RGBCurvesAdjustment(vec3 color)
{
    return vec3(texture2D(curvesTexture, vec2(color.r, 1.0)).r,
                texture2D(curvesTexture, vec2(color.g, 1.0)).g,
                texture2D(curvesTexture, vec2(color.b, 1.0)).b);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...