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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
..
---------------------------------------------------------------------------
Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
All rights reserved.
This work, unless otherwise expressly stated, is licensed under a
Creative Commons Attribution-ShareAlike 2.5.
The full license document is available from
http://creativecommons.org/licenses/by-sa/2.5/legalcode .
---------------------------------------------------------------------------
Shader Effects
==============
Overview
--------
In order to perform advanced graphical effects, Qt Quick 2 enables you to use vertex and fragment shader programs with your QML local properties via the :qt5:`ShaderEffect <qtquick/qml-qtquick2-shadereffect.html>` QML type.
This type enables you to combine your GLSL program with your QML code to control the graphics at a much lower level using custom shaders. `ShaderEffect` enables you to implement a vertex or fragment shader program in your QML code via the :qt5:`vertexShader <qml-qtquick2-shadereffect.html#vertexShader-prop>` and :qt5:`fragmentShader <qtquick/qml-qtquick2-shadereffect.html#fragmentShader-prop>` properties. When you specify a QML item as variant property in your `ShaderEffect`, the item is provided to your vertex or fragment shader as `Sampler2D`.
Consider the following example:
.. code-block:: js
import QtQuick 2.0
Rectangle {
id: root
color: "white"
width: 600
height: 300
Image {
id: background
width: parent.width/2
height: parent.height
source: "resources/Qt.png"
anchors {
right: parent.right
top: parent.top
}
}
ShaderEffect {
id: shaderEffect
width: parent.width/2
height: parent.height
anchors {
left: parent.left
top: parent.top
}
property variant source: background
}
}
The `ShaderEffect` type takes the background QML item, provides it as a `Sampler2D` to the fragment shader and paints the result on the screen (at the position of the `ShaderEffect`). In the above example, we did not specify any fragment or vertex shader. So the default shaders that apply no special effects are used.
.. image:: images/shader_1.png
:scale: 60%
:align: center
You can then add your vertex or fragment shader program using `fragmentVertex` or `fragmentShader`. For example, we can add an effect using a fragment shader as follows
.. code-block:: js
import QtQuick 2.0
Rectangle {
id: root
color: "white"
width: 600
height: 300
Image {
id: background
width: parent.width/2
height: parent.height
source: "resources/Qt.png"
anchors {
right: parent.right
top: parent.top
}
}
ShaderEffect {
id: shaderEffect
width: parent.width/2
height: parent.height
anchors {
left: parent.left
top: parent.top
}
property variant source: background
property real frequency: 20
property real amplitude: 0.05
property real time
NumberAnimation on time {
from: 0; to: Math.PI * 2
duration: 1000
loops: Animation.Infinite
}
fragmentShader:
"varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
uniform lowp float qt_Opacity;
uniform highp float frequency;
uniform highp float amplitude;
uniform highp float time;
void main(){
vec2 p= sin(time + frequency * qt_TexCoord0);
gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude *vec2(p.y, -p.x))* qt_Opacity;
}";
}
}
Again the background QML item is provided as `Sampler2D` in the fragment shader. Another very important feature that is introduced in the code above is the automatic property binding between QML and GLSL code.
If an `uniform` variable in the vertex or fragment shader program has the same name as a property defined in the `ShaderEffect`, the value of this property is bound to the uniform.
In the above code snippet we are using this feature in conjunction with a `NumberAnimation` to produce a animated wobbling effect. The effect is shown in the screenshot below:
.. image:: images/shader_2.png
:scale: 60%
:align: center
For more details concerning GLSL and the use of Shaders in QML, refer to the related links listed at the end of this tutorial.
What's next?
------------
Next, we will be implementing a demo application that illustrates the use of the ``Particles`` module and ``ShaderEffect`` type in QML.
|