Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing the color of some fragment of a texture using shaders

Declarative programming language QML allows to connect the elements, their properties with universal variables in shader programs description. For these purposes there is such elements as ShaderEffectItem, for instance. Here, for example, we define a certain image image.jpg. And in the source property we set just that this image any will change in the image and further this property is set already in the fragment shader program description fragmentShader as uniform sampler2D source. qt_TexCoord0 defines initial coordinate a texture. We receive there gray color on all texture scalar product lowp float gray = dot (textureColor, vec4 (0.299, 0.587, 0.114, 0.0)); also we install color of a fragment in an output variable 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
            }
        }
    }

After performance color of a texture (picture) gradually completely passes in gray, and all is then reverse also it is fulfilled in an infinite loop. Now:

enter image description here

A question actually here in what: and I can change somehow color of any definiteness of a part of a texture (my picture images/image.jpg), i.e. any certain sections. For example I will define in QML two variables xColor, yColor, we transfer it similarly ratio the shader description and then for example the texture will change only in a square with coordinates the left top corner [xColor - 10, yColor - 10] and [xColor + 10, yColor + 10] - bottom right corner. I want:

enter image description here

I know that it can be implemented. How it more optimally to make? In what direction to me to think? Whether there are any similar examples? It would be nice to add blending color (red to gray in this section).

like image 503
G-71 Avatar asked Dec 05 '11 06:12

G-71


1 Answers

For rectangle you need to check texture coordinates:

  1. Convert input texture coordinates to pixels:

    highp vec2 pix_coords = qt_TexCoord0.st * image_size; // you need to pass image_size variable to shader

  2. Check bounds of your rect:

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

    { // make grayscale }

    else

    { // standard color lookup }

As for optimization, it would be better to transform rectangle into texture space and check non-converted texture coordinates.

like image 133
brigadir Avatar answered Sep 20 '22 12:09

brigadir