# 波纹特效
在这个更复杂的示例中,将使用片段着色器创建波浪效果。 波形基于正弦曲线,它会影响用于颜色的纹理坐标。
qml 文件定义属性和动画。
import QtQuick 2.5
Rectangle {
width: 480; height: 240
color: '#1e1e1e'
Row {
anchors.centerIn: parent
spacing: 20
Image {
id: sourceImage
width: 160; height: width
source: "../assets/coastline.jpg"
}
ShaderEffect {
width: 160; height: width
property variant source: sourceImage
property real frequency: 8
property real amplitude: 0.1
property real time: 0.0
NumberAnimation on time {
from: 0; to: Math.PI*2; duration: 1000; loops: Animation.Infinite
}
fragmentShader: "wave.frag.qsb"
}
}
}
片段着色器获取属性并根据属性计算每个像素的颜色。
#version 440
layout(location=0) in vec2 qt_TexCoord0;
layout(location=0) out vec4 fragColor;
layout(std140, binding=0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
float frequency;
float amplitude;
float time;
} ubuf;
layout(binding=1) uniform sampler2D source;
void main() {
vec2 pulse = sin(ubuf.time - ubuf.frequency * qt_TexCoord0);
vec2 coord = qt_TexCoord0 + ubuf.amplitude * vec2(pulse.x, -pulse.x);
fragColor = texture(source, coord) * ubuf.qt_Opacity;
}
波的计算是基于脉冲和纹理坐标的变化的。 脉冲方程根据当前时间和使用的纹理坐标提供了一个正弦波:
vec2 pulse = sin(ubuf.time - ubuf.frequency * qt_TexCoord0);
如果没有时间因素,只会有扭曲,但不会出现像波浪那样的扭曲波动。
对于颜色,使用不同纹理坐标处的颜色:
vec2 coord = qt_TexCoord0 + ubuf.amplitude * vec2(pulse.x, -pulse.x);
纹理坐标受脉冲x值的影响,其结果是一个移动的波浪。
在此示例中,使用片段着色器,这意味着在矩形项的纹理内移动像素。 如果希望整个项像波浪一样移动,将不得不使用顶点着色器。