Изменение цвета фрагмента текстуры с помощью шейдеров - PullRequest
4 голосов
/ 05 декабря 2011

Декларативный язык программирования QML позволяет связывать элементы, их свойства с универсальными переменными в описании шейдерных программ.Для этих целей есть такие элементы, как ShaderEffectItem , например.Здесь, например, мы определяем определенное изображение image.jpg.А в свойстве source мы устанавливаем только то, что это изображение любое изменится в изображении, и далее это свойство уже задано в описании программы фрагмента шейдера fragShader как единый источник sampler2D.qt_TexCoord0 определяет начальную координату текстуры.Мы получаем там серый цвет на всех текстурах скалярного произведения lowp float grey = dot (textureColor, vec4 (0.299, 0.587, 0.114, 0.0));и устанавливаем цвет фрагмента в выходную переменную gl_FragColor.

....
Item {
    id: main
    Image {
         id: img
         source: "images/image.jpg"
      }

    ShaderEffectItem {
       id: effect
       property real ratio: 1.0
        property variant source: ShaderEffectSource {            
             sourceItem: img;
             hideSource: true
        }

        fragmentShader:
          "
          varying highp vec2 qt_TexCoord0;
          uniform sampler2D source;
          uniform highp float ratio;
          void main(void)
          {
            lowp vec4 textureColor = texture2D(source, qt_TexCoord0.st);
            lowp float gray = dot(textureColor, vec4(0.299, 0.587, 0.114, 0.0));
            gl_FragColor = vec4(gray * ratio + textureColor.r * (1.0 - ratio), gray * ratio + textureColor.g * (1.0 - ratio), gray * ratio + textureColor.b * (1.0 - ratio), textureColor.a);
         }
         "
    }

        SequentialAnimation on ratio {
            id: ratioAnimation
            running: true
            loops: Animation.Infinite
            NumberAnimation {
                easing.type: Easing.Linear
                to: 0.0
                duration: 500
            }
            PauseAnimation {
                duration: 500
            }
            NumberAnimation {
                easing.type: Easing.Linear
                to: 1.0
                duration: 500
            }
            PauseAnimation {
                duration: 500
            }
        }
    }

После выполнения цвет текстуры (картинки) постепенно полностью переходит в серый, а затем все наоборот и выполняется в бесконечном цикле,Теперь:

enter image description here

Вопрос собственно вот в чем: а я могу как-то изменить цвет любой определенности части текстуры (моя картинка images / image.jpg), т.е.какие-то определенные разделы.Например, я определю в QML две переменные xColor, yColor, мы передадим его аналогичным образом в соотношении с описанием шейдера, а затем, например, текстура изменится только в квадрат с координатами левого верхнего угла [xColor - 10, yColor - 10] и [xColor + 10, yColor + 10] - нижний правый угол.Я хочу:

enter image description here

Я знаю, что это может быть реализовано.Как это более оптимально сделать?В каком направлении мне думать?Есть ли какие-нибудь похожие примеры?Было бы неплохо добавить смешение цветов (от красного к серому в этом разделе).

1 Ответ

3 голосов
/ 05 декабря 2011

Для прямоугольника необходимо проверить координаты текстуры:

  1. Преобразовать координаты входной текстуры в пиксели:

    highp vec2 pix_coords = qt_TexCoord0.st * image_size;// вам нужно передать переменную image_size в шейдер

  2. Проверить границы вашего прямоугольника:

    if ((pix_coords.x> rect_bottom_left.x) && (pix_coords.y> rect_bottom_left.y) && (pix_coords.x

    {// сделать градацию серого}

    остальное

    {// стандартный поиск цвета}

Что касается оптимизации, было бы лучше преобразовать прямоугольник в текстурное пространство и проверить не преобразованные координаты текстуры.

...