We have moved to a new Sailfish OS Forum. Please start new discussions there.
0

ShaderEffect messes up with opacity [answered]

asked 2015-10-27 02:04:31 +0300

kimmoli gravatar image

Just asking, am i doing something wrong...?

My fragmentShader to invert colors

// Invert colors

uniform sampler2D source;
uniform sampler2D mask;
varying highp vec2 qt_TexCoord0;
uniform lowp float qt_Opacity;

void main(void)
{
    highp vec4 color = texture2D(source, qt_TexCoord0);
    color.rgb = 1.0 - color.rgb;
    gl_FragColor = color * texture2D(mask, qt_TexCoord0).a;
}

where source contains the photo and the line-arts, and mask contains the white area

(i can write this in a few different ways, all resulting the same behaviour)

Results in this 20151027005718.jpg which changes to this 20151027005749.jpg if there is any activity on screen (e.g. rotating device is enough)

Another fragment shader to swap RGB channels (interesting part shown)

    gl_FragColor = texture2D(source, qt_TexCoord0).brga * texture2D(mask, qt_TexCoord0).a;

Results this: 20151027005635.jpg which is looking fine.

I know that the empty canvas is all black with alpha 0.0. I tried to replace clearRect() with filled rectangle of color Qt.rgba(1.0, 1.0, 1.0, 0.0) but it went even more haywire with that.

I tried to change the 1.0 - color.rgb to e.g. color.rgb + 0.1 and it fails in similar way. I see the transparent areas to get light white color.

edit retag flag offensive reopen delete

The question has been closed for the following reason "the question is answered, an answer was accepted" by kimmoli
close date 2015-10-29 09:47:42.679997

Comments

FYI @sletta

kimmoli ( 2015-10-27 12:24:38 +0300 )edit

1 Answer

Sort by » oldest newest most voted
1

answered 2015-10-27 13:01:31 +0300

sletta gravatar image

When you implement a fragment shader, you need to take the inherited scene opacity into account in your output pixel (gl_FragColor). If you don't, then the resulting pixels will in all likelyhood come out opaque or with some other artifact.

What you want in both cases is to multiply the result color with qt_Opacity, like the examples in the ShaderEffect documentation does.

edit flag offensive delete publish link more

Comments

Thanks for pointing this out, but it has no effect on this issue.

Relevant code is now as below, but result is the same.

gl_FragColor = color * texture2D(mask, qt_TexCoord0).a * qt_Opacity;
kimmoli ( 2015-10-27 14:24:17 +0300 )edit

The source color there is also premultiplied is it not? So to do the 1.0 - rgb correctly, you should do:

color.rgb = (1.0 - color.rgb/color.a) * color.a;

or something along those lines..

sletta ( 2015-10-27 15:33:13 +0300 )edit

Learning curve.

Yes, the color is premultiplied alpha.

From the docs http://doc.qt.io/qt-5/qml-qtquick-shadereffect.html

QColor -> vec4 - When colors are passed to the shader, they are first premultiplied. Thus Qt.rgba(0.2, 0.6, 1.0, 0.5) becomes vec4(0.1, 0.3, 0.5, 0.5) in the shader, for example.
kimmoli ( 2015-10-27 16:57:12 +0300 )edit

Question tools

Follow
1 follower

Stats

Asked: 2015-10-27 02:04:31 +0300

Seen: 433 times

Last updated: Oct 27 '15