# 波纹特效

在这个更复杂的示例中,将使用片段着色器创建波浪效果。 波形基于正弦曲线,它会影响用于颜色的纹理坐标。

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值的影响,其结果是一个移动的波浪。

image

在此示例中,使用片段着色器,这意味着在矩形项的纹理内移动像素。 如果希望整个项像波浪一样移动,将不得不使用顶点着色器。

最后更新: 1/9/2022, 5:58:27 PM