• Qml-ShaderEffect的使用


    Qml-ShaderEffect的使用

    ShaderEffect的概述

    1. ShaderEffect使用自定义的顶点和片段着色器用于渲染一个矩形。用于在qml场景中添加阴影、模糊、着色和页面卷曲等效果。

    2. Qt5和Qt6中ShaderEffect有一定区别,在Qt6中由于支持不同的渲染API,ShaderEffect是用统一的qsb文件来满足对不同的渲染API支持。使用Qt6提供的qsb.exe工具来将顶点着色器和片段着色器生成qsb文件。

    3. 在Shader的编写中,顶点着色器默认输入有两个顶点:
      vec4 qt_Vertex 在location = 0,顶点坐标;
      vec2 qt_MultiTexCoord0 在 location = 1;纹理坐标。
      两个uniform变量:
      mat4 qt_Matrix:组合变换矩阵,从根项到该ShaderEffect的矩阵的乘积,以及正交投影.
      float qt_Opacity:组合不透明度,从根项到此ShaderEffect的不透明度的乘积
      注意 unoform变量的名字不能改变;ubo的布局是std140布局格式;具体可查阅openGL的全局缓冲对象(uniform buffer object)相关使用

    4. 在ShaderEffect 中声明的属性可以映射到Shader中,qml中类和Shader中类型映射关系如下:
      bool, int, qreal -> bool, int, float
      QColor -> vec4
      QPoint, QPointF, QSize, QSizeF -> vec2
      QVector3D -> vec3
      QVector4D -> vec4
      QTransform -> mat3
      QMatrix4x4 -> mat4
      QQuaternion -> vec4
      Image -> sampler2D
      ShaderEffectSource-> sampler2D

    5. 注意本实例代码在Qt6.5版本中测试验证的。Qt6和Qt5有差异

    ShaderEffect的实例代码

    1.qml代码如下

    import QtQuick
    
    Rectangle {
        width: 240;
        height: 100
        Row {
            spacing: 20
            Image {
                id: img;
                sourceSize { width: 100; height: 100 }
                source: "qrc:/qt/qml/text/qmlDemo/Resource/qtlogo.png"                     //图片路径,根据需要可做调整
            }
            ShaderEffect {
                width: 100; height: 100
                property variant src: img                                               //定义一个属性,属性名 src,值为Image,映射到Shader中是sampler2D;
                vertexShader: "qrc:/qt/qml/text/qmlDemo/myeffect.vert.qsb"
                fragmentShader: "qrc:/qt/qml/text/qmlDemo/myeffect.frag.qsb"
            }
        }
    }
    
    1. 顶点着色器代码如下:
    #version 440
    //location 顶点位置
    layout(location = 0) in vec4 qt_Vertex;
    layout(location = 1) in vec2 qt_MultiTexCoord0;
    layout(location = 0) out vec2 coord;
    //std140 使用std140内存布局,std140有一套对齐规则 binding = 0 将ubo 绑定到绑定点0
    layout(std140, binding = 0) uniform buf {
        mat4 qt_Matrix;
        float qt_Opacity;
    };
    void main() {
        coord = qt_MultiTexCoord0;
        //gl_Position 是glsl 顶点着色器中内置变量
        gl_Position = qt_Matrix * qt_Vertex;
    }
    
    1. 片段着色器代码如下:
    #version 440
    //片段着色器
    layout(location = 0) in vec2 coord;
    layout(location = 0) out vec4 fragColor;
    layout(std140, binding = 0) uniform buf {
        mat4 qt_Matrix;
        float qt_Opacity;
    };
    //src 是 qml中ShaderEffect 中映射进来Image对象,当作纹理
    layout(binding = 1) uniform sampler2D src;
    void main() {
       
        vec4 tex = texture(src, coord);			//对纹理采样
        //dot 是点剩,即对采样出来的r*0.344 g*0.5 b*0.146;灰度化。
        fragColor = vec4(vec3(dot(tex.rgb, vec3(0.344, 0.5, 0.156))), tex.a) * qt_Opacity;
    }
    
    

    4.qsb命令:
    –glsl: OpenGL和OpenGLES --hlsl: DX11 -o :输出文件名

    	qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o myeffect.frag.qsb myeffect.frag
    

    ShaderEffect实例代码运行结果如下:

    1.个人理解:ShaderEffect是用户自己写Shader对渲染进行控制,可用于一些特效处理或者后期处理。
    2.ShaderEffect可以和layer.effect结合做一些特殊处理。
    3.在ShaderEffect中,还可以使用单个Shader,比如只编写片段着色器,对片段进行特殊处理。
    4.ShaderEffect中涉及到很多OpenGL相关的知识和概念,可以通过学习 learnOpengl 去了解更多OpenGL相关的知识和概率。
    5.在Qt帮助文档中,有用ShaderEffect 类处理渐变文本实例,感兴趣小伙伴可以多研究下原理。
    在这里插入图片描述

  • 相关阅读:
    软件工程:阿姆达尔定律,性能设计和优化的指导原则
    在达梦数据库上使用密码设备上的国密算法详细操作指南
    springboot基于Android的校园综合服务App平台的设计毕业设计源码181040
    数码管的静态显示(二)
    SpringMVC和实际案例
    利用面向对象方法,处理数据文件【Python】
    js去除字符串空格的几种方式
    Go :验证编译器是否强制执行了复制参数要求(附完整源码)
    腾讯云2核4G服务器5M带宽 218元一年 优惠价格明细表
    250. 统计同值子树(二叉树)
  • 原文地址:https://blog.csdn.net/u013125105/article/details/143349342