首页 > 代码库 > Qt QML 2D shader

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;            }"    }    

 

Qt QML 2D shader