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.0Rectangle {
width: 360
height: 360gradient: 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.
-
Alright, bug report posted "here":https://bugreports.qt.nokia.com/browse/QTCOMPONENTS-1074