使用ShaderEffectItem进行奇怪的alpha混合结果

lee*_*mes 3 qt alphablending glsl qml

我正在尝试使用QML项目应用简单的alpha蒙版ShaderEffectItem.

这是一个最小的(非)工作示例:我有一个红色到白色的渐变作为背景,并希望在它上面绘制一个绿色的200x200平方.此方块的alpha蒙版应该在左侧为0.0,在右边框为1.0,因此在左边框应该是透明的.

import QtQuick 1.1
import Qt.labs.shaders 1.0

Rectangle {
    width: 300
    height: 300

    id: wrapper

    gradient: Gradient {
        GradientStop { position: 0.0; color: "red" }
        GradientStop { position: 1.0; color: "white" }
    }

    Rectangle {
        id: square
        anchors.centerIn: parent
        width: 200
        height: 200
        color: "green"
    }

    ShaderEffectItem {
        anchors.centerIn: parent
        width: 200
        height: 200

        property variant source: ShaderEffectSource {
            sourceItem: square
            hideSource: true
        }

        fragmentShader: "
        varying vec2 qt_TexCoord0;
        uniform sampler2D source;
        void main(void)
        {
            vec4 sourceColor = texture2D(source, qt_TexCoord0);
            float alpha = qt_TexCoord0.x; // = 0.0 at left, 1.0 at right border
            sourceColor.a *= alpha;       // apply alpha mask
            gl_FragColor = sourceColor;
        }
        "
    }
}
Run Code Online (Sandbox Code Playgroud)

我期望以下输出(使用GIMP绘制):

预期结果

但这实际上显示了:

实际结果

我究竟做错了什么?

我正在使用qmlviewer(Qt 4.8.2)显示带有-opengl选项的QML文件,以启用着色器效果.

也许这与我在几周前发现的QGLFramebufferObjects上的alpha混合这种奇怪的行为有关 ...

小智 7

尝试将片段着色器的主要功能修改为:

    void main(void)
    {
        gl_FragColor = texture2D(source, qt_TexCoord0).rgba*qt_TexCoord0.x;
    }
Run Code Online (Sandbox Code Playgroud)

  • 是的,谢谢.刚刚意识到Qt正在使用预乘的颜色.您可以将此添加到您的答案中,作为我们必须乘以所有颜色分量而不仅仅是alpha值的原因,如果我们想要应用alpha蒙版. (4认同)