Подтвердить что ты не робот

Как изменить оттенок текстуры с помощью GLSL?

Есть ли способ эффективно изменить оттенок 2D-текстуры OpenGL с использованием GLSL (шейдер фрагмента)?

У кого-то есть код для этого?

UPDATE: Это код, полученный в результате запроса user1118321:

uniform sampler2DRect texture;
const mat3 rgb2yiq = mat3(0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135);
const mat3 yiq2rgb = mat3(1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.1070, 1.7046);
uniform float hue;

void main() {

vec3 yColor = rgb2yiq * texture2DRect(texture, gl_TexCoord[0].st).rgb; 

float originalHue = atan(yColor.b, yColor.g);
float finalHue = originalHue + hue;

float chroma = sqrt(yColor.b*yColor.b+yColor.g*yColor.g);

vec3 yFinalColor = vec3(yColor.r, chroma * cos(finalHue), chroma * sin(finalHue));
gl_FragColor    = vec4(yiq2rgb*yFinalColor, 1.0);
}

И это результат по сравнению со ссылкой:

enter image description here

Я попытался переключить я с Q внутри atan, но результат неправильный даже около 0 °

Есть ли у вас какой-нибудь намек?

Если это необходимо для сравнения, это оригинальное немодифицированное изображение: enter image description here

4b9b3361

Ответ 1

Хотя то, что говорит @awoodland, верно, этот метод может вызвать проблемы с изменениями яркости, я считаю.

Системы цвета HSV и HLS являются проблематичными по ряду причин. Я недавно общался с цветным ученым, и его рекомендация заключалась в том, чтобы преобразовать в пространство YIQ или YCbCr и соответствующим образом настроить каналы цветности (I & Q, или Cb & Cr). (Вы можете узнать, как это сделать здесь и здесь. )

В одном из этих пространств вы можете получить оттенок от угла, образованного каналами цветности, выполнив hue = atan(cr/cb) (наблюдая за cb == 0). Это дает вам ценность в радианах. Просто поверните его, добавив количество вращения оттенка. Как только вы это сделаете, вы можете рассчитать величину цветности с помощью chroma = sqrt(cr*cr+cb*cb). Чтобы вернуться в RGB, вычислите новые Cb и Cr (или я и Q) с помощью Cr = chroma * sin (hue), Cb = chroma * cos (hue). Затем конвертируйте обратно в RGB, как описано на приведенных выше веб-страницах.

EDIT: Здесь решение, которое я тестировал, и, похоже, дает мне те же результаты, что и ваша ссылка. Вероятно, вы можете свернуть некоторые из точечных продуктов на матрицу:

uniform sampler2DRect inputTexture;
uniform float   hueAdjust;
void main ()
{
    const vec4  kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);
    const vec4  kRGBToI     = vec4 (0.596, -0.275, -0.321, 0.0);
    const vec4  kRGBToQ     = vec4 (0.212, -0.523, 0.311, 0.0);

    const vec4  kYIQToR   = vec4 (1.0, 0.956, 0.621, 0.0);
    const vec4  kYIQToG   = vec4 (1.0, -0.272, -0.647, 0.0);
    const vec4  kYIQToB   = vec4 (1.0, -1.107, 1.704, 0.0);

    // Sample the input pixel
    vec4    color   = texture2DRect (inputTexture, gl_TexCoord [ 0 ].xy);

    // Convert to YIQ
    float   YPrime  = dot (color, kRGBToYPrime);
    float   I      = dot (color, kRGBToI);
    float   Q      = dot (color, kRGBToQ);

    // Calculate the hue and chroma
    float   hue     = atan (Q, I);
    float   chroma  = sqrt (I * I + Q * Q);

    // Make the user adjustments
    hue += hueAdjust;

    // Convert back to YIQ
    Q = chroma * sin (hue);
    I = chroma * cos (hue);

    // Convert back to RGB
    vec4    yIQ   = vec4 (YPrime, I, Q, 0.0);
    color.r = dot (yIQ, kYIQToR);
    color.g = dot (yIQ, kYIQToG);
    color.b = dot (yIQ, kYIQToB);

    // Save the result
    gl_FragColor    = color;
}

Ответ 2

Andrea3000, сравнивая примеры YIQ в сети, я столкнулся с вашей публикацией, но я думаю, что есть проблема с "обновленной" версией вашего кода.... я уверен, что ваши определения "mat3" - это флип /flopped по порядку столбца/строки... (может быть, почему у вас все еще были проблемы)...

FYI: упорядочение матрицы OpenGL: "Для большего количества значений матрицы заполняются в основном порядке столбца. То есть первые значения X являются первым столбцом, а вторыми значениями X являются следующий столбец и т.д.". См.: http://www.opengl.org/wiki/GLSL_Types

mat2(
float, float,   //first column
float, float);  //second column