QML Fragment shader acting strangely with Gradient background



  • Hello. This is my first time posting a thread on Qt's forum, I'm also a beginner with shaders.

    I have the following shader:

        @fragmentShader: "
            uniform highp sampler2D sourceTexture;
            varying highp vec2 qt_TexCoord;
    
            void main (void)
            {
                vec4 c = texture2D(sourceTexture, qt_TexCoord);
                gl_FragColor = vec4(c.rgb, c.a);
            }
        "@
    

    Basically, it does nothing, it was just in order to test... The image is rendered correctly, pixel by pixel.

    This simple line:

    @gl_FragColor = vec4(1.0f, 0.f, 0.f, 0.f);@

    Should give me invisible colors, right? because it gives me half transparent red as long as I don't have uniform white as the background...

    Minimal code in "this post":http://developer.qt.nokia.com/forums/viewreply/56175/



  • Transparency also depends of parent QML item transparency. I don't know if this is related to QML fragment shader.

    And transparency also depends of order of the rendering.



  • You seem to be right -- a minimal code doesn't reproduce the problem. I'll try using the same background as in my app, and when i have a minimal code reproducing the problem, i'll post it.

    Edit: alright, here is the minimal code:

    @import QtQuick 1.0
    import Qt.labs.shaders 1.0

    Rectangle {
    width: 360
    height: 360

    gradient: Gradient {
        GradientStop {
            position: 0
            color: "#8f9da8"
        }
    
        GradientStop {
            position: 0.190
            color: "#80b5ca"
        }
    
        GradientStop {
            position: 0.480
            color: "#db9b40"
        }
    
        GradientStop {
            position: 1
            color: "#91772f"
        }
    }
    
    id: root;
    
    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
    
    Image {
        id: image
        source: "../images/qtlogo.png"
        width: 80;
        height: 80;
        x: 40;
        y: 40;
    }
    
    ShaderEffectItem {
        property real alpha: 0.5
    
        ShaderEffectSource {
            id: sourceImage
            hideSource: true
            sourceItem: image
            live: true
        }
    
        function grab() {
            sourceImage.grab();
        }
    
        x: image.x
        y: image.y
        width: image.width
        height: image.height
    
        property variant sourceTexture: sourceImage
    
        property color blendColor: "red"
    
        vertexShader: "
            uniform highp mat4 qt_ModelViewProjectionMatrix;
            attribute highp vec4 qt_Vertex;
            attribute highp vec2 qt_MultiTexCoord0;
    
            varying highp vec2 qt_TexCoord;
    
            void main(void)
            {
                qt_TexCoord = qt_MultiTexCoord0;
                gl_Position =  qt_ModelViewProjectionMatrix * qt_Vertex;
            }
        "
    
        fragmentShader: "
            uniform highp sampler2D sourceTexture;
            uniform lowp float alpha;
            uniform lowp vec4 blendColor;
            varying highp vec2 qt_TexCoord;
    
            void main (void)
            {
                vec4 c = texture2D(sourceTexture, qt_TexCoord);
    
                gl_FragColor = vec4(c.rgb*(1-alpha) + blendColor.rgb*alpha, c.a);
            }
        "
    }
    

    }@

    The problem only happens when the background is not pure white. Normally, by running the code above, you'll see a red rectangle even where it's supposed to be transparent. If you use "black" as blendcolor, however, no problems. I tested with an image as a background, same problem.

    I've also uploaded a zip with the project (8 kB): http://www.mediafire.com/?htjwebacpuzaem8

    Please let me know what I'm doing wrong?



  • Alright I think I figured it out.

    It seems that when I specify an alpha of 0, it adds the color components to the background. That's why when the background is white, there's no problems, as the color components are already maxed out.

    So a hack I found is doing :

    @gl_FragColor = vec4((c.rgb*(1-alpha) + blendColor.rgb*alpha)*c.a, c.a);@

    I multiply the color component by the alpha component, that way when alpha = 0, the rgb is 0 and nothing is added to the color components of the background, thus they stay the same.

    I'm relatively new to shaders so I can't tell if this is something to be expected or a weird behavior - definitely seems the latter, so please tell me if this is not a bug before I post a bug report tomorrow.



  • I don't how QML fragment shader works with alpha blending (maybe they are using some strange blend equation) so I don't know if it's weird behaviour.

    Anyway, just report the bug. Definitely it's strange thing.




Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.