ShaderEffect 是 QML 中用于實現自定義著色器效果的組件,允許開發者使用 GLSL 著色器語言創建圖形效果。
核心屬性
基本屬性
屬性 | 類型 | 默認值 | 說明 |
---|---|---|---|
fragmentShader | string | "" | 片段著色器代碼 |
vertexShader | string | "" | 頂點著色器代碼 |
blending | bool | true | 是否啟用混合 |
mesh | variant | Qt.size(1, 1) | 網格分辨率或自定義網格 |
cullMode | enumeration | ShaderEffect.NoCulling | 面剔除模式 |
log | string | "" | 只讀,著色器編譯日志 |
著色器參數屬性
屬性 | 類型 | 說明 |
---|---|---|
property var <name> | variant | 聲明著色器參數 |
property real <name> | real | 聲明實數參數 |
property vector2d <name> | vector2d | 聲明2D向量參數 |
property vector3d <name> | vector3d | 聲明3D向量參數 |
property vector4d <name> | vector4d | 聲明4D向量參數 |
property color <name> | color | 聲明顏色參數 |
property rect <name> | rect | 聲明矩形參數 |
property point <name> | point | 聲明點參數 |
property size <name> | size | 聲明尺寸參數 |
property matrix4x4 <name> | matrix4x4 | 聲明4x4矩陣參數 |
CullMode 枚舉值
值 | 說明 |
---|---|
ShaderEffect.NoCulling | 不剔除 |
ShaderEffect.BackFaceCulling | 剔除背面 |
ShaderEffect.FrontFaceCulling | 剔除正面 |
常用方法
方法 | 參數 | 返回值 | 說明 |
---|---|---|---|
setUniformValue(name, value) | name: string value: variant | - | 設置著色器參數值 |
update() | - | - | 強制更新效果 |
常用信號
信號 | 參數 | 說明 |
---|---|---|
logChanged() | - | 著色器日志改變時觸發 |
著色器特殊變量
頂點著色器可用變量
變量 | 類型 | 說明 |
---|---|---|
qt_Vertex | vec4 | 頂點位置 |
qt_MultiTexCoord0 | vec4 | 紋理坐標 |
qt_ModelViewProjectionMatrix | mat4 | 模型視圖投影矩陣 |
varying vec2 qt_TexCoord0 | vec2 | 傳遞給片段著色器的紋理坐標 |
片段著色器可用變量
變量 | 類型 | 說明 |
---|---|---|
varying vec2 qt_TexCoord0 | vec2 | 來自頂點著色器的紋理坐標 |
uniform sampler2D source | sampler2D | 源紋理 |
uniform float qt_Opacity | float | 不透明度 |
基本使用示例
1. 簡單著色器效果
qml
import QtQuick 2.15ShaderEffect {width: 200; height: 200property color uColor: "red"fragmentShader: "uniform lowp vec4 uColor;void main() {gl_FragColor = uColor;}"
}
2. 紋理處理
qml
ShaderEffect {width: 200; height: 200property variant sourceproperty real uAmount: 0.5fragmentShader: "uniform sampler2D source;uniform float uAmount;varying vec2 qt_TexCoord0;void main() {vec4 color = texture2D(source, qt_TexCoord0);gl_FragColor = vec4(color.rgb * uAmount, color.a);}"
}
高級用法
1. 自定義網格
qml
ShaderEffect {width: 200; height: 200mesh: GridMesh {resolution: Qt.size(10, 10)}// 著色器代碼...
}
2. 多紋理輸入
qml
ShaderEffect {width: 200; height: 200property variant source1property variant source2property real uMixFactor: 0.5fragmentShader: "uniform sampler2D source1;uniform sampler2D source2;uniform float uMixFactor;varying vec2 qt_TexCoord0;void main() {vec4 color1 = texture2D(source1, qt_TexCoord0);vec4 color2 = texture2D(source2, qt_TexCoord0);gl_FragColor = mix(color1, color2, uMixFactor);}"
}
3. 動畫效果
qml
ShaderEffect {width: 200; height: 200property variant sourceproperty real uTime: 0NumberAnimation on uTime {from: 0; to: 1duration: 1000loops: Animation.Infinite}fragmentShader: "uniform sampler2D source;uniform float uTime;varying vec2 qt_TexCoord0;void main() {vec2 uv = qt_TexCoord0;uv.x += sin(uTime * 10.0 + uv.y * 5.0) * 0.1;gl_FragColor = texture2D(source, uv);}"
}
性能優化技巧
-
減少uniform更新:避免頻繁更新著色器參數
-
簡化著色器:復雜著色器會影響性能
-
合理使用mesh:增加網格分辨率會降低性能
-
避免動態編譯:預編譯著色器
-
使用mipmap:對于縮小的紋理
常見著色器效果實現
1. 灰度效果
qml
fragmentShader: "uniform sampler2D source;varying vec2 qt_TexCoord0;void main() {vec4 color = texture2D(source, qt_TexCoord0);float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));gl_FragColor = vec4(vec3(gray), color.a);}
"
2. 邊緣檢測
qml
fragmentShader: "uniform sampler2D source;uniform float qt_Opacity;varying vec2 qt_TexCoord0;void main() {vec2 uv = qt_TexCoord0;vec2 step = vec2(1.0/width, 1.0/height);float gx = -1.0 * texture2D(source, uv + vec2(-step.x, -step.y)).r +-2.0 * texture2D(source, uv + vec2(-step.x, 0.0)).r +-1.0 * texture2D(source, uv + vec2(-step.x, step.y)).r +1.0 * texture2D(source, uv + vec2(step.x, -step.y)).r +2.0 * texture2D(source, uv + vec2(step.x, 0.0)).r +1.0 * texture2D(source, uv + vec2(step.x, step.y)).r;float gy = -1.0 * texture2D(source, uv + vec2(-step.x, -step.y)).r +-2.0 * texture2D(source, uv + vec2(0.0, -step.y)).r +-1.0 * texture2D(source, uv + vec2(step.x, -step.y)).r +1.0 * texture2D(source, uv + vec2(-step.x, step.y)).r +2.0 * texture2D(source, uv + vec2(0.0, step.y)).r +1.0 * texture2D(source, uv + vec2(step.x, step.y)).r;float edge = sqrt(gx*gx + gy*gy);gl_FragColor = vec4(vec3(edge), qt_Opacity);}
"
注意事項
-
著色器代碼必須符合目標平臺的GLSL版本
-
不同平臺可能有不同的著色器限制
-
復雜的著色器可能在某些設備上不工作
-
調試著色器可以使用log屬性查看編譯錯誤
-
確保所有uniform變量都有對應的property聲明