nit
nit

Reputation: 97

qt qml: fade image horizontally (i.e from left to right ... not whole image)

enter image description herei m showing 3 images horizontally at a time using PathLine. The left and right image need to be shown as 50% faded from left & 50% faded from right. Here i cannot use a black rectangle gradient to show the fade effect as my parent is 20% transparent & it floats on a background video.

So is there any ways to apply the opacity property as a horizontal fade animation?

Upvotes: 1

Views: 3560

Answers (1)

leemes
leemes

Reputation: 45705

With the QML ShaderEffectItem element you can add post-effects to a QML item using a shader program. This enables you to do some graphics effects on the GPU.

As you see in the documentation I've linked above, this can for example be a wave effect. In general, you apply a small "program" to every output pixel. This is the so-called fragment shader in GLSL.

To give you an idea of how you could implement a alpha mask on an item (this might be your scene which contains the images on the path which you are animating), I'll give an example in which I implement a simple linear gradient as the alpha mask, where on the left we have zero opacity and on the right full opacity.

import QtQuick 1.0
import Qt.labs.shaders 1.0

Item {
    width: 300
    height: 300

    id: wrapper

    Item {
        id: scene
        anchors.fill: parent
        // Here is your scene with the images ...
    }

    ShaderEffectItem {
        anchors.fill: wrapper

        // Any property you add to the ShaderEffectItem is accessible as a
        // "uniform" value in the shader program. See GLSL doc for details.
        // Essentially, this is a value you pass to the fragment shader,
        // which is the same for every pixel, thus its name.

        // Here we add a source item (the scene) as a uniform value. Within the
        // shader, we can access it as a sampler2D which is the type used to
        // access pixels in a texture. So the source item becomes a texture.
        property variant source: ShaderEffectSource
        {
            sourceItem: scene // The item you want to apply the effect to
            hideSource: true  // Only show the modified item, not the original
        }

        // This is the fragment shader code in GLSL (GL Shading Language)
        fragmentShader: "
        varying highp vec2 qt_TexCoord0;  // The coords within the source item
        uniform sampler2D source;         // The source item texture
        void main(void)
        {
            // Read the source color of the pixel
            vec4 sourceColor = texture2D(source, qt_TexCoord0);

            // The alpha value of the mask
            float alpha = qt_TexCoord0.x; // = 0.0 at left, 1.0 at right border

            // Multiply the alpha mask on the color to be drawn:
            sourceColor *= alpha;

            // Write the pixel to the output image
            gl_FragColor = sourceColor;
        }
        "
    }
}

The most important line in the shader program is the value of the alpha variable. In this small example I just set the X component of the texture coordinate as the alpha value, thus at the left border it is 0, at the right border it is 1. Note that the texture coordinates are not measured in pixels but in a [0..1] range. If you want to access pixel coordinates, you can use gl_FragCoord.x/y. Note that y is measured from bottom to top, so 0 is the bottom border and height is the top border. Per default you can't access the height of the whole resulting image, but therefore we can use uniforms. Just assign a new property int h: height and access it using uniform float h in the shader.

Upvotes: 4

Related Questions