All things Qt are progressing quite well at the moment and here is the one of the directions that Qt Scene graph is going in:
The ShaderEffectItem is simply a rectangle with a custom vertex and fragment shader. The vertices passed to the vertex shader are the corners of the rectangle defined by the “width” and “height” properties of the item. (There is a property you can set to divide the rectangle into multiple rows and columns, but by default, you get four vertices.) The nifty thing about the ShaderEffectItem, though, is that you can define your own properties on the QML item, and they will be available to you as uniform variables in the shaders. For instance, you can define a property called “tint” of type “color” and animate it in QML, and you can read it in the shaders as “uniform vec4 tint”. Several types are supported: real, point, size, color, vector3d, and a new type, ShaderEffectSource, which maps to a “sampler2D” in the shader code. The ShaderEffectSource allows you to render a QML item into a texture and pass it to the ShaderEffectItem. The ShaderEffectSource has properties like wrap mode and mipmapping, and a reference to the QML item to render into the texture. ShaderEffectItems can be strung together by letting one ShaderEffectItem be the source of another. The ShaderEffectItem is powerful, and as with anything powerful, you need to use it with caution. A poorly written shader or too many effects active at once can easily ruin the performance, well, on devices at least.
The code below shows how the wobble effect can be implemented.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
import QtQuick 2.0 Image { width: 180 height: 180 source: "winter.jpg" Text { id: theItem anchors.fill: parent horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pixelSize: 120 font.family: "Times" color: "blue" text: "Qt" } ShaderEffectItem { anchors.fill: parent property variant source: ShaderEffectSource { sourceItem: theItem smooth: true hideSource: true } property real amplitude: 0.02 property real frequency: 20 property real time: 0 NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 } fragmentShader: " uniform highp float amplitude; uniform highp float frequency; uniform highp float time; uniform sampler2D source; uniform lowp float qt_Opacity; varying highp vec2 qt_TexCoord0; void main() { highp vec2 p = sin(time + frequency * qt_TexCoord0); gl_FragColor = qt_Opacity * texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)); }" } } |
The source code can be found in the qml-team/qtquick2 branch of http://qt.gitorious.org/+qt-developers/qt/staging/.
source