Qt QML 2D shader

---------------------------------------------------
Qt quick 2d shader effect
---------------------------------------------------
概念
    着色器和普通的图像处理程序不同,它只针对一个点做运算,它包括:
        vertext shader: 顶点着色器,主要用于处理位置,要求输出当前点的新位置。
        fragment shader(pixel shader):片段着色器(像素着色器),主要用于处理色彩。要求输出当前点的新色彩。
    系统会自动处理循环,并行运算多个点,自动处理图像边界
    主要有两类Shader程序: GLSL(OpenGL提供), HLSL(DirectX提供)
    注:好像时 5.6 版本后才支持directx,所以事情复杂了。现在Qt3D的shader就复杂无比.

GLSL(OpenGL Shader Language)
    参数修饰词
        uniform : 表示每次运算时参数值不变的
        varying : 表示每次运算时参数值时变动的。如当前点的纹理坐标
        lowp    : 表示低精度
        highp   : 表示高精度
    预定义参数
        uniform mat4 qt_Matrix           : 变形矩阵- combined transformation matrix, the product of the matrices from the root item to this ShaderEffect, and an orthogonal projection.
        uniform float qt_Opacity         : 透明度- combined opacity, the product of the opacities from the root item to this ShaderEffect.
        attribute vec4 qt_Vertex         : 当前计算点的坐标
        attribute vec2 qt_MultiTexCoord0 : 纹理坐标(输入的图片/item等)
    输入参数类型映射
        在ShaderEffect中定义的参数会自动映射到Shader里面去
        bool, int, qreal -> bool, int, float
        QColor -> vec4         : 注意色彩输入shader时会先做半透明预处理,如Qt.rgba(0.2, 0.6, 1.0, 0.5) 会转化为 vec4(0.1, 0.3, 0.5, 0.5)
        QRect, QRectF -> vec4(x, y, w, h)
        QPoint, QPointF, QSize, QSizeF -> vec2(x, y)
        QVector3D -> vec3(x, y, z)
        QVector4D -> vec4(x, y, w, w)
        QTransform -> mat3
        QMatrix4x4 -> mat4
        QQuaternion -> vec4, scalar value is w.
        Image -> sampler2D
        ShaderEffectSource -> sampler2D
    输出
        vertext shader: 顶点着色器,主要用于处理位置,要求输出gl_Position参数。
        fragment shader(pixel shader):片段着色器(像素着色器),主要用于处理色彩。要求输出gl_FragColor参数。
    常用方法
        lowp vect4 text = texture2D(src, qt_TexCoord0);  // 取纹理色彩
        abs/min/max/....
    示例
        ShaderEffect {
          width: 200
          height: 200
          mesh: GridMesh { resolution: Qt.size(20, 20) }
          property var source: Image {
              source: "qt-logo.png"
              sourceSize { width: 200; height: 200 }
          }
          vertexShader: "
              uniform highp mat4 qt_Matrix;
              attribute highp vec4 qt_Vertex;
              attribute highp vec2 qt_MultiTexCoord0;
              varying highp vec2 qt_TexCoord0;
              uniform highp float width;
              void main() {
                  highp vec4 pos = qt_Vertex;
                  highp float d = .5 * smoothstep(0., 1., qt_MultiTexCoord0.y);
                  pos.x = width * mix(d, 1.0 - d, qt_MultiTexCoord0.x);
                  gl_Position = qt_Matrix * pos;
                  qt_TexCoord0 = qt_MultiTexCoord0;
              }"
        }

HLSL(Direct3D)
    blablabla,有很多不同,
    示例
        Image { id: img; sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
        ShaderEffect {
            width: 100; height: 100
            property variant src: img
            fragmentShader: "qrc:/effect_ps.cso"
        }
        cbuffer ConstantBuffer : register(b0)
        {
            float4x4 qt_Matrix;
            float qt_Opacity;
        };
        Texture2D src : register(t0);
        SamplerState srcSampler : register(s0);
        float4 ExamplePixelShader(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
        {
            float4 tex = src.Sample(srcSampler, coord);
            float3 col = dot(tex.rgb, float3(0.344, 0.5, 0.156));
            return float4(col, tex.a) * qt_Opacity;
        }

跨平台的Shader写法
    方法1(根据 GraphicsInfo.shaderType 判断):
          Image { id: img; sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
          ShaderEffect {
              width: 100; height: 100
              property variant src: img
              property variant color: Qt.vector3d(0.344, 0.5, 0.156)
              fragmentShader:
                GraphicsInfo.shaderType === GraphicsInfo.GLSL ?
                  "varying highp vec2 coord;
                  uniform sampler2D src;
                  uniform lowp float qt_Opacity;
                  void main() {
                      lowp vec4 tex = texture2D(src, coord);
                      gl_FragColor = vec4(vec3(dot(tex.rgb, vec3(0.344, 0.5, 0.156))), tex.a) * qt_Opacity;
                  }"
                : GraphicsInfo.shaderType === GraphicsInfo.HLSL ?
                  "cbuffer ConstantBuffer : register(b0)
                  {
                      float4x4 qt_Matrix;
                      float qt_Opacity;
                  };
                  Texture2D src : register(t0);
                  SamplerState srcSampler : register(s0);
                  float4 ExamplePixelShader(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
                  {
                      float4 tex = src.Sample(srcSampler, coord);
                      float3 col = dot(tex.rgb, float3(0.344, 0.5, 0.156));
                      return float4(col, tex.a) * qt_Opacity;
                  }"
              : ""
          }
     方法2(自动选择):
          Image { id: img; sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
          ShaderEffect {
              width: 100; height: 100
              property variant src: img
              property variant color: Qt.vector3d(0.344, 0.5, 0.156)
              fragmentShader: "qrc:shaders/effect.frag" // 系统会自动选择 shaders/effect.frag 或 shaders/+hlsl/effect.frag
          }

示例
    // 去色
    ShaderEffect {
      fragmentShader: "
          uniform lowp sampler2D source; // this item
          uniform lowp float qt_Opacity; // inherited opacity of this item
          varying highp vec2 qt_TexCoord0;
          void main() {
              lowp vec4 p = texture2D(source, qt_TexCoord0);
              lowp float g = dot(p.xyz, vec3(0.344, 0.5, 0.156));
              gl_FragColor = vec4(g, g, g, p.a) * qt_Opacity;
          }"
    }

    // 图层混合
    ShaderEffect {
        property var colorSource: gradientRect;
        fragmentShader: "
          uniform lowp sampler2D colorSource;
          uniform lowp sampler2D maskSource;
          uniform lowp float qt_Opacity;
          varying highp vec2 qt_TexCoord0;
          void main() {
              gl_FragColor =
                  texture2D(colorSource, qt_TexCoord0)
                  * texture2D(maskSource, qt_TexCoord0).a
                  * qt_Opacity;
          }
      "
    }

    // 上下两边虚化
    Flickable{
       ....
    }
    ShaderEffectSource {
        id: flickableAreaSource
        sourceItem: flickableArea
        hideSource: true
        visible: false
    }
    ShaderEffect {
        property variant src: flickableAreaSource
        anchors.fill: flickableArea
        fragmentShader: "
            varying highp vec2 qt_TexCoord0;
            uniform lowp float qt_Opacity;
            uniform sampler2D src;
            void main() {
                lowp vec4 tex = texture2D(src, qt_TexCoord0);
                lowp float dist = abs(qt_TexCoord0.y-0.5)*4.0;
                tex*= min(1.0, (2.0 - dist));
                gl_FragColor = tex * qt_Opacity;
            }"
    }    
时间: 2024-09-30 04:16:26

Qt QML 2D shader的相关文章

Qt QML referenceexamples attached Demo hacking

/********************************************************************************************* * Qt QML referenceexamples attached Demo hacking * 说明: * 1. 本源代码来自Qt自带的Example,而本文也仅仅是代码解读,需要有点基础: * 2. 由于是Qt自带Demo,分为几个文件,文件存在联系,而本人把所有代码放在这个文件里,会照成阅读困难:

Qt官方教程翻译——Qt QML

Pull 解析器简介 Pull 解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如: 开始元素和结束元素事件,使用xmlPullParser.next() 可以进入下一个元素并触发相应事件.跟 SAX 不同的 是, Pull 解析器产生的事件是一个数字,而非方法,因此可以使用一个 switch 对事件进行处理.当元素开始解析时,调用 parser.nextText() 方法可以获取下一个 Text 类型节点的值. Pull解析器的源码及文档下载网址:http://www.xmlpul

qt qml中PropertyAnimation的几种使用方法

qml文章 qt qml中PropertyAnimation的几种使用方法 动画应用场景有以下几种: 首先如果一个Rectangle.动画是要改变它的x和y值 1,Rectangle一旦被创建,就要移动到一个特定的位置 2,动画仅仅有在某一个特定的外部行为触发时候才会被触发,比如,鼠标单击某一个控件时候,产生动画.使目标移动到指定的位置 3,仅仅有在某一个特定的信号后才触发 4,做为一个独立的动画,尽管没有绑定rectangle的运动,可是能够在脚本中载入,開始和停止 5.仅仅有在状态改变时候才

Qt qml listview 下拉刷新上拉分页控件

Qt qml listview下拉刷新和上拉分页主要根据contentY来判断.但要加上顶部下拉指示器.滚动条,并封装成可简单调用的组件,着实花了我不少精力:) [先看效果]    [功能] 1 下拉刷新和上拉分页逻辑 2 /下拉刷新 3 /上拉更多 4 /滚动栏 5 /工具栏半拉显隐 6 Author: surfsky.cnblogs.com 7 Lisence: MIT 请保留此文档声明 8 History: 9 init. surfsky.cnblogs.com, 2015-01 10 a

QT QML Keys 处理注意事项

今天在学习 QT QML 最基本的东东,在下面的代码中响应按键处理无效.代码如下: 1 import QtQuick 2.2 2 import QtQuick.Window 2.1 3 import QtQuick.Controls 1.2 4 5 Window { 6 visible: true 7 width: 360 8 height: 360 9 10 MouseArea { 11 anchors.fill: parent 12 onClicked: { 13 Qt.quit(); 14

Qt qml中listview 列表视图控件(下拉刷新、上拉分页、滚动轴)

Qt qml中listview 列表视图控件(下拉刷新.上拉分页.滚动轴) 来源 https://www.cnblogs.com/surfsky/p/4352898.html 设置ListView涉及到将contentsY,即视图的可见部分的顶部,设置y为委托的值.另一个更改是interactive将视图设置为false.这样可以防止视图移动.用户不能再滚动列表或更改当前Item. contentY为列表上拉后列表左上角点距显示框左上解点的高度listView1.height为可显示部分的高度,

qt qml

Qt 和  QML 的互用 题目比较大, 先列个提纲, 周末写. Qt 和  QML 的互用1. 在 QML中使用 Qt 定义的非控件类2. 在 QML中使用 Qt 定义的 控件类3. 在 QML中使用 lib 中的类4. 在 Qt 中使用 QML 对象5. 在 Qt 和 QML 中使用 javascript   

qt qml 利用xmlhttprequest 调用有赞api

最近朋友在有赞商城上面开了一个店铺,因为有实体店,一般卖商品后送货上门,但是打票时候老是人工用world文档人工复制黏贴订单打印小票, 所以就找我帮忙做一个软件专门打印小票的,就研究起来调用有赞第三方api来着,本篇主要介绍如何用qml中的xmlhttprequest来实现http请求协议,就以调用有赞商城api的查询订单接口为例:kdt.trades.sold.get: function searchTrades(startDate,endDate){ tradesModel.clear();

qt qml 刮刮卡效果

用canvas+mouseArea实现的刮刮卡效果. 表层是一层色彩,用手指划开,可看到下面的文字Lisence: MIT, 请保留本文档说明Author: surfsky.cnblogs.com 2015-02 [先看效果] [下载] http://download.csdn.net/detail/surfsky/8445011 [核心代码] 1 Canvas { 2 id: canvas 3 anchors.fill: parent 4 5 // 6 property bool isFirs