ShaderEffect QML Type

カスタムシェーダを矩形に適用します。詳細...

Import Statement: import QtQuick
Inherits:

Item

プロパティ

詳細説明

ShaderEffect タイプは、カスタムvertex およびfragment (pixel) シェーダを矩形に適用します。これにより、ドロップシャドウ、ぼかし、カラーライズ、ページカールなどのエフェクトを QML シーンに追加することができます。

注: 使用するQt Quick scenegraph バックエンドによっては、ShaderEffect タイプがサポートされない場合があります。例えば、software のバックエンドでは、エフェクトは全くレンダリングされません。

シェーダー

Qt 5 では、エフェクトは GLSL (OpenGL Shading Language) のソースコードで提供されていました。Qt 5.8 から、ローカルまたは Qt リソースシステム内のファイルを参照できるようになりました。

Qt 6では、Qt Quick 、Vulkan、Metal、Direct3D 11などのグラフィックスAPIもサポートしています。そのため、GLSLソース・ストリングでの作業はもはや不可能です。むしろ、新しいシェーダー・パイプラインは、Vulkan互換のGLSLコードをSPIR-Vにコンパイルし、その後、リフレクション情報を収集し、HLSL、メタル・シェーディング言語、さまざまなGLSLバージョンなどの他のシェーディング言語に翻訳することに基づいています。出来上がったアセットは1つのパッケージにまとめられ、通常、.qsb の拡張子を持つファイルに保存されます。このプロセスはオフラインで行われるか、遅くともアプリケーションのビルド時に行われます。実行時に、シーングラフと基礎となるグラフィックス抽象化は、これらの.qsb ファイルを消費します。したがって、ShaderEffect は、インラインシェーダーコードの代わりに、Qt 6 のファイル(ローカルまたは qrc)参照を期待します。

vertexShaderfragmentShader プロパティは Qt 6 の URL であり、例えばImage.source とよく似た動作をします。ただし、ShaderEffect でサポートされているのはfileqrc のスキームのみです。file スキームを省略することも可能で、便利な方法で相対パスを指定できます。このようなパスは、コンポーネント(.qml ファイル)の場所からの相対パスとして解決されます。

シェーダーの入力とリソース

vertexShader への入力には、ユニフォーム入力と頂点入力の 2 種類があります。

以下の入力は定義済みです:

  • vec4 qt_Vertex (位置 0 - 頂点の位置)、左上の頂点の位置は (0, 0)、右下の頂点の位置は (width,height)。
  • vec2 qt_MultiTexCoord0 は位置 1 - テクスチャ座標で、左上の座標は (0, 0)、右下の座標は (1, 1) です。supportsAtlasTextures がtrueの場合、座標は代わりにアトラス内の位置に基づきます。

注意: 実際に重要なのは頂点の入力位置だけです。名前は自由に変更できますが、位置は常に、頂点位置は0 、テクスチャ座標は1 でなければなりません。ただし、これは頂点入力にのみ適用され、フラグメントシェーダの入力として使用される頂点シェーダからの出力変数(典型的には補間されたテクスチャ座標)には必ずしも当てはまらないことに注意してください。

以下のユニフォームが定義済みです:

  • mat4 qt_Matrix - 結合された変換行列で、ルート項目からこの ShaderEffect への行列の積、および直交投影。
  • float qt_Opacity - 結合された不透明度、ルート項目からこの ShaderEffect までの不透明度の積。

注意: VulkanスタイルのGLSLには、個別のユニフォーム変数がありません。代わりに、シェーダは常に0 のバインディングポイントを持つユニフォームブロックを使用する必要があります。

注意 : ユニフォームブロックレイアウト修飾子は常にstd140 でなければなりません。

注意 :頂点入力とは異なり、定義済みの名前(qt_Matrix、qt_Opacity)は変更してはいけません。

さらに、GLSL タイプにマッピングできるプロパティはすべて、シェーダで利用可能 にすることができます。以下のリストは、プロパティがどのようにマッピングされるかを示しています:

  • bool, int, qreal -> bool, int, float - シェーダの型が QML の型と異なる場合、値は自動的に変換されます。
  • QColor -> vec4 - シェーダに色が渡されるとき、最初に乗算されます。したがって、Qt.rgba(0.2, 0.6, 1.0, 0.5) はシェーダでは vec4(0.1, 0.3, 0.5, 0.5) になります。
  • QRect QRectF -> vec4 - Qt.rect(x, y, w, h) はシェーダでは vec4(x, y, w, h) になります。
  • QPoint QPointF, , -> vec2QSize QSizeF
  • QVector3D -> vec3
  • QVector4D -> vec4
  • QTransform -> mat3
  • QMatrix4x4 -> mat4
  • QQuaternion -> vec4、スカラー値は 。w
  • Image -> sampler2D - Originは左上隅にあり、カラー値は事前乗算されます。テクスチャは、Image アイテムの fillMode を除いて、そのまま提供されます。fillMode を含めるには、 または Image::layer::enabled を使用します。ShaderEffectSource
  • ShaderEffectSource -> sampler2D - 原点は左上隅にあり、色の値は事前乗算されます。

サンプラーは、シェーダーコードの中で、別のユニフォーム変数として宣言されたままです。シェーダはこれらのバインディングポイントを自由に選択できます。ただし、0 はユニフォームブロックのために予約されています。

シェーディング言語や API の中には、画像オブジェクトとサンプラーオブジェクトを分離する概念を持つものがあります。Qt Quick は、SPIR-V でサポートされているように、シェーダーでは常に画像サンプラーオブジェクトを組み合わせて動作します。したがって、ShaderEffect用に提供されるシェーダーは、常にlayout(binding = 1) uniform sampler2D tex; スタイルのサンプラー宣言を使用する必要があります。基礎となる抽象化レイヤとシェーダーパイプラインは、アプリケーションに対して透過的に、サポートされるすべてのAPIとシェーディング言語に対して、この作業を行います。

QMLシーングラフバックエンドは、テクスチャアトラスにテクスチャを割り当てることができます。アトラスに割り当てられたテクスチャがShaderEffectに渡される場合、デフォルトではテクスチャ座標が0から1になるように、テクスチャアトラスからスタンドアロンテクスチャにコピーされ、期待されるラップモードが得られます。しかし、これはメモリ使用量を増加させます。テクスチャのコピーを避けるには、 qt_MultiTexCoord0 を使ってシンプルシェーダ用にsupportsAtlasTextures を設定するか、各 "uniform sampler2D <name>" に対して、テクスチャの正規化されたソース矩形が割り当てられる "uniform vec4 qt_SubRect_<name>" を宣言します。スタンドアロンテクスチャの場合、ソース矩形は [0, 1]x[0, 1] です。アトラス内のテクスチャの場合、ソース矩形はテクスチャが保存されているテクスチャアトラスの部分に対応します。テクスチャアトラス内の「ソース」と呼ばれるテクスチャのテクスチャ座標を計算する正しい方法は、「qt_SubRect_source.xy + qt_SubRect_source.zw * qt_MultiTexCoord0」です。

fragmentShader からの出力は事前に乗算されている必要があります。blending が有効な場合、ソースオーバーブレンディングが使用されます。ただし、アルファチャンネルにゼロを出力することで、加算ブレンドを実現できます。

import QtQuick 2.0

Rectangle {
    width: 200; height: 100
    Row {
        Image { id: img;
                sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
        ShaderEffect {
            width: 100; height: 100
            property variant src: img
            vertexShader: "myeffect.vert.qsb"
            fragmentShader: "myeffect.frag.qsb"
        }
    }
}

この例では、myeffect.vertmyeffect.frag に Vulkan スタイルの GLSL コードが含まれており、qsb ツールで処理されて.qsb ファイルが生成されると仮定しています。

#version 440
layout(location = 0) in vec4 qt_Vertex;
layout(location = 1) in vec2 qt_MultiTexCoord0;
layout(location = 0) out vec2 coord;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
void main() {
    coord = qt_MultiTexCoord0;
    gl_Position = qt_Matrix * qt_Vertex;
}
#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;
};
layout(binding = 1) uniform sampler2D src;
void main() {
    vec4 tex = texture(src, coord);
    fragColor = vec4(vec3(dot(tex.rgb, vec3(0.344, 0.5, 0.156))), tex.a) * qt_Opacity;
}

Note: Scene Graph テクスチャは、OpenGL で一般的な左下ではなく、左上に原点があります。

シェーダーを1つだけ持つ

vertexShaderfragmentShader の両方を指定することは必須ではありません。多くの ShaderEffect 実装は、デフォルトのビルトイン頂点シェーダに依存しながら、実際にはフラグメントシェーダのみを提供したいと思うでしょう。

デフォルトの頂点シェーダは、テクスチャ座標を0 の位置vec2 qt_TexCoord0 としてフラグメントシェーダに渡します。

デフォルトのフラグメントシェーダは、テクスチャ座標が頂点シェーダから0 の位置でvec2 qt_TexCoord0 として渡されることを期待し、バインディングポイント1source という名前のサンプラ 2D からサンプリングします。

警告 警告:シェーダが1つだけ指定されている場合、シェーダのライタはデフォルトのシェーダが期待するユニフォームブロックレイアウトを認識している必要があります:qt_Matrix は常にオフセット 0 にあり、qt_Opacity がオフセット 64 に続いていなければなりません。qt_Matrixは常にオフセット0に、qt_Opacityはオフセット64に置かなければなりません。これは、アプリケーションが提供するシェーダが行列や不透明度を使用しない場合でも必須です。なぜなら、実行時に頂点シェーダとフラグメントシェーダの両方に公開される単一のユニフォームバッファが存在するからです。

警告 頂点入力の場合とは異なり、頂点シェーダとフラグメントシェーダの 間でデータを渡す場合、基礎となるグラフィックス API によっては、 同じ名前を使用する必要があるかもしれません。最も顕著なのは、デフォルトのビルトイン頂点シェーダに依存しなが らフラグメントシェーダを指定する場合、テクスチャ座標は0 の位置qt_TexCoord0 として渡されるため、フラグメントシェーダは同じ名前(qt_TexCoord0)で入力を宣言することを強く推奨します。たとえば、基礎となる GLSL シェーダソースコードにロケーション修飾子がなく、シェーダリンク処理中の変数名に基づいてマッチングが行われる非コアプロファイルの OpenGL コンテキストで実行する場合などです。

ShaderEffectとアイテムレイヤー

ShaderEffect タイプはlayered items と組み合わせることができます。

エフェクト無効のレイヤー エフェクトが有効なレイヤー
Item {
    id: layerRoot
    layer.enabled: true
    layer.effect: ShaderEffect {
       fragmentShader: "effect.frag.qsb"
    }
}
#version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
layout(binding = 1) uniform sampler2D source;
void main() {
    vec4 p = texture(source, qt_TexCoord0);
    float g = dot(p.xyz, vec3(0.344, 0.5, 0.156));
    fragColor = vec4(g, g, g, p.a) * qt_Opacity;
}

複数のレイヤーアイテムを組み合わせることも可能です:

Rectangle {
    id: gradientRect;
    width: 10
    height: 10
    gradient: Gradient {
        GradientStop { position: 0; color: "white" }
        GradientStop { position: 1; color: "steelblue" }
    }
    visible: false; // should not be visible on screen.
    layer.enabled: true;
    layer.smooth: true
 }
 Text {
    id: textItem
    font.pixelSize: 48
    text: "Gradient Text"
    anchors.centerIn: parent
    layer.enabled: true
    // This item should be used as the 'mask'
    layer.samplerName: "maskSource"
    layer.effect: ShaderEffect {
        property var colorSource: gradientRect;
        fragmentShader: "mask.frag.qsb"
    }
}
#version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
layout(binding = 1) uniform sampler2D colorSource;
layout(binding = 2) uniform sampler2D maskSource;
void main() {
    fragColor = texture(colorSource, qt_TexCoord0)
                    * texture(maskSource, qt_TexCoord0).a
                    * qt_Opacity;
}

その他の注意事項

デフォルトでは、ShaderEffectは4つの頂点で構成され、各コーナーに1つずつ配置されます。ページカールのような非線形の頂点変換では、mesh の解像度を指定することで、頂点の細かいグリッドを指定できます。

Qt 5 からの移行

ShaderEffect アイテムを使用した Qt 5 アプリケーションでは、Qt 6 への移行が必要です:

  • シェーダーコードを.vert.frag の別々のファイルに移動する、
  • シェーダーを Vulkan 互換の GLSL に更新します、
  • qsb ツールを実行する、
  • 結果の.qsb ファイルを Qt リソースシステムで実行ファイルに含める、
  • そして、vertexShaderfragmentShader のプロパティでファイルを参照します。

QtShader Toolsモジュールで説明されているように、CMake がビルド時にqsb ツールを起動することで、これらのステップの一部を自動化することができます。QtShader Tools Build System Integrationを参照してください。

シェーダーコードの更新に関しては、一般的に必要な変更の概要を以下に示します。

Qt 5 の頂点シェーダQt 6 の頂点シェーダ
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
varying highp vec2 coord;
uniform highp mat4 qt_Matrix;
void main() {
    coord = qt_MultiTexCoord0;
    gl_Position = qt_Matrix * qt_Vertex;
}
#version 440
layout(location = 0) in vec4 qt_Vertex;
layout(location = 1) in vec2 qt_MultiTexCoord0;
layout(location = 0) out vec2 coord;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
void main() {
    coord = qt_MultiTexCoord0;
    gl_Position = qt_Matrix * qt_Vertex;
}

変換プロセスでは、ほとんどの場合、GL_KHR_vulkan_glsl と互換性があるようにコードを更新します。Qt Quick は GLSL と Vulkan が提供する機能のサブセットを使用しているため、典型的な ShaderEffect シェーダの変換プロセスは通常簡単です。

  • GL_KHR_vulkan_glsl拡張はGLSL 140以上のために書かれているため、version ディレクティブは、440 または450 を指定する必要がありますが、他のGLSLバージョンを指定しても動作します。
  • 入力と出力には最新の GLSLinout キーワードを使用しなければなりません。さらに、場所の指定が必要です。入力と出力のロケーション名前空間は別々なので、両方に0から始まるロケーションを割り当てても安全です。
  • 頂点シェーダ入力に関しては、ShaderEffect で指定できるのは、頂点位置の位置0 (従来はqt_Vertex という名前)とテクスチャ座標の位置1 (従来はqt_MultiTexCoord0 という名前)だけです。
  • 頂点シェーダ出力とフラグメントシェーダ入力は、シェーダコードに よって定義されます。フラグメントシェーダは、vec4 出力が位置 0 になければなりません(通常、fragColor と呼ばれます)。移植性を最大にするために、頂点出力とフラグメント入力は同じ位置番号と同じ名前の両方を使うべきです。フラグメントシェーダのみを指定する場合、テクスチャ座標は、上記のスニペット例に示すように、ビルトイン頂点シェーダから0 の位置にvec2 qt_TexCoord0 として渡されます。
  • ユニフォームブロック外のユニフォーム変数は、合法ではありません。むしろ、ユニフォーム・データは、バインディング・ポイント0 を持つユニフォーム・ブロックで宣言されなければなりません。
  • 一様ブロックは、 std140 修飾子を使用することが期待されます。
  • 実行時、頂点シェーダとフラグメントシェーダは、バインディングポイント0にバインドされた同じユニフォームバッファを取得します。したがって、一般的なルールとして、ユニフォームブロックの宣言は、シェーダ間で同一でなければなりません。これには、どちらかのシェーダで使用されていないメンバも含まれます。いくつかのグラフィックスAPIでは、ユニフォームブロックは、アプリケーションに対して透過的に、従来の構造体ユニフォームに変換されるため、メンバ名は一致する必要があります。
  • シェーダーの1つだけを提供する場合は、組み込みシェーダーがユニフォームブロックの先頭でqt_Matrixqt_Opacity 。(より正確には、それぞれオフセット0と64)一般的なルールとして、常にブロックの最初と2番目のメンバとしてこれらを含めます。
  • この例では、ユニフォーム・ブロックはブロック名buf を指定しています。この名前は自由に変更できますが、シェーダ間で一致する必要があります。layout(...) uniform buf { ... } instance_name; のようなインスタンス名の使用はオプションです。指定した場合、メンバへのアクセスはすべて instance_name で修飾する必要があります。
Qt 5 のフラグメントシェーダQt 6 のフラグメントシェーダ
varying highp vec2 coord;
uniform lowp float qt_Opacity;
uniform sampler2D src;
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;
}
#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;
};
layout(binding = 1) uniform sampler2D src;
void main() {
    vec4 tex = texture(src, coord);
    fragColor = vec4(vec3(dot(tex.rgb,
                     vec3(0.344, 0.5, 0.156))),
                          tex.a) * qt_Opacity;
}
  • 精度修飾子 (lowp,mediump,highp) は現在使用されていません。
  • 組み込み GLSL 関数の呼び出しは、最新の GLSL 名に従わなければなりません。特に、texture2D() の代わりにtexture() を使用します。
  • サンプラーは1から始まるバインディングポイントを使用しなければなりません。
  • Qt Quickmultiview を有効にしてレンダリングされる場合、たとえば、VR/AR 環境でレンダリングされる 3D シーンの一部で、左目と右目のコンテンツがシングルパスで生成されるため、ShaderEffect のシェーダはこれを考慮して記述する必要があります。たとえばビュー数が 2 の場合、2 の行列が存在します(qt_Matrix は 2 つの要素を持つ mat4 の配列です)。頂点シェーダはgl_ViewIndex を考慮する必要があります。マルチビュー対応シェーダの作成に関する一般的な情報については、QSB マニュアルの Multiview のセクションを参照してください。

Item LayersQSB マニュアルQtShader Tools Build System Integrationも参照してください

プロパティ ドキュメント

blending : bool

このプロパティが true の場合、fragmentShader からの出力は、ソースオーバーブレンドモードを使用して背景とブレンドされます。false の場合、背景は無視されます。ブレンドはパフォーマンスを低下させるため、ブレンドが不要な場合はこのプロパティをfalseに設定する必要があります。デフォルト値はtrueです。


cullMode : enumeration

このプロパティは、アイテムのどの面を表示するかを定義します。

定数説明
ShaderEffect.NoCulling両側が見える
ShaderEffect.BackFaceCulling表側のみ表示
ShaderEffect.FrontFaceCulling裏側のみ表示

デフォルトは NoCulling です。


fragmentShader : url

このプロパティには、前処理されたフラグメントシェーダーパッケージのファイルへの参照が含まれます。通常、拡張子は.qsb です。この値は、Image などの他の QML タイプと同様に、URL として扱われます。ローカルファイルであるか、Qtリソースシステム経由で埋め込まれたファイルにアクセスするためにqrcスキームを使用する必要があります。URLは絶対URLでも、コンポーネントのURLからの相対URLでもかまいません。

vertexShaderも参照してください


log : string [read-only]

このプロパティは、シェーダーをコンパイルしようとした最新の試行からの警告とエラーのログを保持します。このプロパティは、status が Compiled または Error に設定されると同時に更新されます。

注意: Qt 6 では、シェーダパイプラインは、Vulkan スタイルの GLSL シェーダのコンパイルと変換をオフラインで、または遅くともビルド時に行います。これは、必ずしも実行時にシェーダーのコンパイルが行われないことを意味するわけではありませんが、仮にコンパイルが行われたとしても、ShaderEffect 、その段階で構文エラーや同様のエラーが発生することはありません。したがって、このプロパティの値は通常空です。

statusも参照のこと


mesh : variant

このプロパティは、ShaderEffect の描画に使用されるメッシュを定義します。GridMesh オブジェクトを保持することができます。このプロパティにサイズ値が割り当てられている場合、ShaderEffect は暗黙的に、その値を持つGridMeshmesh resolution として使用します。デフォルトでは、このプロパティのサイズは 1x1 です。

GridMeshも参照


status : enumeration [read-only]

このプロパティは、シェーダの現在の状態を示します。

定数説明
ShaderEffect.Compiledシェーダプログラムは正常にコンパイルおよびリンクされました。
ShaderEffect.Uncompiledシェーダプログラムはまだコンパイルされていません。
ShaderEffect.Errorシェーダプログラムのコンパイルまたはリンクに失敗しました。

フラグメントシェーダまたは頂点シェーダのソースコードを設定すると、ステータスはUncompiledになります。新しいシェーダソースコードでShaderEffect が初めてレンダリングされると、シェーダはコンパイルおよびリンクされ、ステータスは Compiled または Error に更新されます。

ランタイムコンパイルが使用されておらず、シェーダプロパティがバイト コードファイルを参照している場合、ステータスは常に Compiled になります。シェーダの内容は、レンダリングパイプラインの後半になるまで(頂点入力 要素と定数バッファデータを発見するための基本的なリフレクションを除 いて)検査されないので、潜在的なエラー(レイアウトやルートシグネチャの不一致な ど)は後の時点で初めて検出されます。

logも参照してください


supportsAtlasTextures : bool [since QtQuick 2.4]

シェーダコードが qt_MultiTexCoord0 がメッシュに対して (0,0) から (1,1) までの範囲に依存しないことを確認するには、このプロパティを true に設定します。この場合、qt_MultiTexCoord0 の範囲はむしろアトラス内のテクスチャの位置に基づきます。このプロパティは、シェーダへの入力として使用されるサンプラーユニフォームが1つより少なくても多くても、今のところ何の効果もありません。

これは qt_SubRect_<name> ユニフォームを提供することとは異なり、後者はアトラスから1つ以上のテクスチャを1つのShaderEffect アイテムで描画することを可能にする一方、supportsAtlasTextures はアトラスから異なるソースイメージを使用するShaderEffect コンポーネントの複数のインスタンスを1つの描画でバッチ処理することを可能にします。どちらも、ShaderEffect によって参照されるとき、テクスチャがアトラスからコピーされるのを防ぎます。

デフォルト値は false です。

このプロパティは QtQuick 2.4 で導入されました。


vertexShader : url

このプロパティには、前処理された頂点シェーダーパッケージのファイルへの参照が含まれます。通常、拡張子は.qsb です。この値は、Image などの他の QML タイプと同様に、URL として扱われます。この値はローカルファイルであるか、Qtリソースシステム経由で埋め込まれたファイルにアクセスするためにqrcスキームを使用しなければなりません。URLは絶対URLでも、コンポーネントのURLからの相対URLでもかまいません。

fragmentShaderも参照して ください。


© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.