Qt quick 2d shader effect

版权声明:如果对您有帮助,跪求点赞!本文为博主原创作品,转载请声明出处! https://blog.csdn.net/u011086209/article/details/90764408
---------------------------------------------------
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;
            }"
    }    

猜你喜欢

转载自blog.csdn.net/u011086209/article/details/90764408