Qt シェーダツールビルドシステムの統合
シェーダーをコンパイルして Qt リソースに追加する
はじめに
Qt Shader Toolsモジュールは、アプリケーションがCMakeLists.txt
で使用できる便利な関数を提供する CMake マクロファイルを提供します。
qt6_add_shaders
関数を使用すると、qsbツールがビルドシステムによって自動的に呼び出され、その結果.qsb
ファイルが暗黙のうちにリソースシステムに追加されます。
最初の例
簡単な例を見てみよう。Qt Quick アプリケーションがあり、ShaderEffect を使って独自のウォブル効果を提供したいとします。フラグメントシェーダはwobble.frag
に実装されています。ShaderEffect アイテムの fragmentShader プロパティはwobble.frag.qsb
を参照しています。 この .qsb ファイルがビルド時に生成されるようにするにはどうすればよいでしょうか?
... project(exampleapp LANGUAGES CXX) ... find_package(Qt6 COMPONENTS ShaderTools) ... qt6_add_executable(exampleapp main.cpp ) ... qt6_add_resources(exampleapp "exampleapp" PREFIX "/" FILES "main.qml" ) qt6_add_shaders(exampleapp "exampleapp_shaders" PREFIX "/" FILES "wobble.frag" )
アプリケーションが実行時に:/wobble.frag.qsb
にアクセスできるようにするには、上記で十分です。オリジナルの Vulkan スタイルの GLSL ソースコード(wobble.frag)はアプリケーションの実行ファイルに含まれないため、出荷する必要はありません。シェーダーコードにエラーがある場合、ビルド時にglslang
コンパイラーメッセージが出力され、ビルドは失敗します。シェーダー・ソース・ファイルを変更すると、C++ や他のソース・ファイルと同様に、次回のビルドで変更が自動的に反映されます。
キーとなるのはqt6_add_shaders
関数で、qt6_add_resources
と共通点があります。さらなるパラメータを指定することなく、この関数は、Vulkan、Metal、Direct 3D、および OpenGL または OpenGL ES をターゲットとするフラグメントシェーダに適した合理的なデフォルト引数のセットで qsb を実行するように導きます。
注: find_package
の行に注意してください。ShaderTools
にfind_package
を含めることが重要で、そうしないとqt6_add_shaders
が利用できなくなります。
注意 :qt6_add_shaders
関数の最初の引数として渡されるターゲットは、関数が呼び出される前に存在していなければなりません。
注: 複数のqt6_add_shaders
呼び出しがサポートされている。複雑なアプリケーションでは、異なるシェーダーセットが異なる設定を必要とすることはまずありません。プロジェクトの後の名前(上記の例では"exampleapp_shaders"
)は、呼び出しごとに一意でなければなりません。
設定
デフォルトではqt6_add_shaders
はqsb を次のように呼び出します:
qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o <output>.qsb <input>
これは、生成されるパッケージにSPIR-V(Vulkan 1.0用)、GLSL ES 100(OpenGL ES 2.0以降用)、GLSL 120(ノンコアプロファイルOpenGLコンテキスト用)、GLSL 150(コアプロファイルOpenGLコンテキスト用)、Shader Model 5.0用HLSLソース(Direct3D 11.1用)、およびMetal Shading Language 1.2ソース(Metal用)が含まれることを意味します。
これはQt Quickのための良いデフォルトセットであり、さまざまなシステムに対して移植性の高いアプリケーションを作成します。しかし、これらのデフォルトは常に適しているわけではありません。シェーダが、これらのターゲットに相当するものがない関数やコンストラクトを使用する場合、処理、つまりビルドは失敗します。その場合、ターゲットを調整する必要があり、これはアプリケーションの最小システム要件が暗黙のうちに調整されることも意味します。例として、OpenGL ES 3.0以上(つまりGLSL ES 300以上)でしか利用できないtextureLod
GLSL関数を考えてみましょう。100 es
の代わりに GLSL300 es
を要求した場合、ビルドは成功しますが、生成されるアプリケーションは OpenGL ES 3.0 以上を必要とし、OpenGL ES 2.0 ベースのシステムとは互換性がありません。
シェーダタイプ
シェーダーのタイプは、ファイルの拡張子から推測されます。したがって、拡張子は以下のいずれかでなければなりません:
.vert
- 頂点シェーダー.tesc
- テッセレーション制御シェーダー.tese
- テッセレーション評価シェーダー.frag
- フラグメント(ピクセル)シェーダ用.comp
- コンピュート・シェーダー用
注: テッセレーション・コントロール・シェーダーと評価シェーダーは、現在Direct 3D (HLSL)ではサポートされていません。これを回避するには、ハルとドメインのシェーダーを手動で作成し、FILES
セクションのファイル置換構文を使って注入します。
ターゲット
次のキーワードが使用できます:
GLSL
- 指定されたGLSLバージョンのリストに対してソースコードの生成を要求します。リストがカンマ区切りの 構文に従っていることに注意してください。例えば、コンピュートシェーダは、デフォルトでは適さないので、 をここで指定したいでしょう。qsb
"310 es,430"
NOGLSL
- この引数なしキーワードは、GLSLソースの生成を無効にします。OpenGLをまったく使いたくないアプリケーションに適しています。HLSL
- 指定されたHLSL(シェーダーモデル)バージョンのリストのソースコードの生成を要求します。 ツールは GLSL スタイルのバージョン番号に従うので、 はシェーダーモデル 5.0、 は 5.1 に対応する。qsb
50
51
NOHLSL
- この引数なしキーワードは、HLSLソースの生成を無効にします。Direct 3Dをまったく使いたくないアプリケーションに適しています。MSL
- 指定されたバージョンのメタルシェーディング言語のソースコード生成を要求する。 は 1.2、 は 2.0 に対応する。12
20
NOMSL
- この引数なしのキーワードは、MSL ソースの生成を無効にします。Metalをまったく使いたくないアプリケーションに適しています。
最も一般的にオーバーライドされる設定はGLSL
です。たとえば、アプリケーションのシェーダーが OpenGL 3.x の機能を使用する場合、100 es
または120
よりも高い値を指定したいと思うでしょう:
qt_add_shaders(exampleapp "res_gl3shaders" GLSL "300es,330" PREFIX "/shaders" FILES shaders/ssao.vert shaders/ssao.frag shaders/skybox.vert shaders/skybox.frag )
注意: 接尾辞es
の前のスペースはオプションです。
テセレーション
TESSELLATION
- この引数なしのキーワードは、シェーダがテッセレーションを使用するパイプラインで使用されることを示します。これは、頂点シェーダがリストされ、メタルシェーダ生成が無効になっていない場合にのみ関係します。例としてこのスニペットを参照してください。このオプションは Qt 6.5 で導入されました。
TESSELLATION_VERTEX_COUNT
- このオプションは、テッセレーション制御ステージからの出力頂点数を示す数値を取ります。これを指定することは、Metalで使用されるテッセレーション評価シェーダーでは必須です。デフォルト値は3です。この値がテッセレーション制御ステージと一致しない場合、生成されたMSLコードは期待通りに機能しません。このオプションはQt 6.5で導入されました。
TESSELLATION_MODE
- このオプションはテッセレーションモードを指定します。デフォルト値は です。このオプションは、テッセレーション・コントロール・シェーダーが リストにあるときに指定する必要があります。このオプションは、テッセレーション評価ステージと一致しなければなりません。"triangles"
"quads"
triangles
FILES
このオプションは Qt 6.5 で導入されました。
マルチビュー
VIEW_COUNT
- このオプションは、頂点シェーダが使用するビューの数を指定します。マルチビュー(GL_OVR_multiview2、VK_KHR_multiview、D3D12 ビューインスタンシングなど)を使用する場合は、正しい GLSL シェーダーコードを生成できるようにするため、関連するシェーダーには常に正しい VIEW_COUNT を指定し、値 >= 2 とします。ただし、マルチビューに依存しない頂点シェーダでは、VIEW_COUNT の設定は避けるべきで、この値を設定すると、生成される GLSL コードが事実上マルチビュー依存になるからです。これを解決するには、頂点シェーダーを複数の qt_add_shaders() 呼び出しにグループ化します。 を設定すると、同じ値を持つプリプロセッサ定義 がシェーダソースコードに自動的に注入されます。さらに、 行は、ビューカウントが 2 以上設定されると、頂点シェーダに自動的に注入されます。マルチビューの場合、GLSL の最小バージョンは と です。HLSL の場合、最小バージョンは です。アプリケーションは、それに応じて(または新しいバージョンに)言語ターゲットを設定することをお勧めします。VIEW_COUNT
QSHADER_VIEW_COUNT
#extension GL_EXT_multiview : require
330
300 es
61
このオプションは Qt 6.7 で導入されました。
MULTIVIEW
- このオプションは Qt 6.7 で導入されました。これは事実上、適切な GLSL/HLSL/MSL/VIEW_COUNT 引数を持つ 2 つの qt_add_shaders() 呼び出しを手動で作成するための便利な機能です。このオプションは主にQt自身が使用するためのものですが、アプリケーションのシェーダーにとってマルチビューバリアントの暗黙の設定が十分である限り、アプリケーションも使用できます:GLSL 330,300es HLSL 61 MSL 12.VIEW_COUNT はマルチビューバリアントのために 2 に設定されます。マルチビューバリアントは、 に加えて、 が追加されたファイルに保存されます。.qsb
.mv2qsb
このオプションは Qt 6.8 で導入されました。
Qt Quick の仕様
BATCHABLE
- この引数なしの単一キーワードを指定することは、Qt Quick で使用されるバーテックスシェーダ( または のいずれか)には必須です。フラグメントシェーダやコンピュートシェーダには影響せず、このキーワードは ファイルでのみ考慮されるため、異なるタイプを同じリストに安全に含めることができます。ShaderEffect QSGMaterialShader.vert
qsb の 引数に相当します。-b
ZORDER_LOC
- が指定された場合、追加の頂点入力はデフォルトで の位置に注入されます。このキーワードは、この位置を別の値に変更するために使用します。これは、頂点シェーダに多くの入力があり、7 が使用中で衝突する場合に関連します。BATCHABLE
7
外部ツールの起動
PRECOMPILE
- プラットフォームによって異なりますが、qsb の または オプションに相当します。Windows 上でビルドする場合、これは Windows SDK から を起動し、コンパイルの第 1 フェーズ(HLSL ソースから DXBC バイトコードへ)を実行時ではなくビルド時に実行します。その結果、 ファイルにはコンパイル結果(中間シェーダーフォーマット)のみが含まれ、元のシェーダーソースコードは含まれません。-c
-t
fxc
.qsb
OPTIMIZED
- (Vulkan SDK またはその他の場所から利用可能である必要があります)を呼び出して、SPIR-V バイトコードの最適化を実行します。spirv-opt
qsb の 引数に相当します。-O
その他の設定
DEFINES
- シェーダーのコンパイル時に有効なマクロを定義します。qsb の 引数に相当する。リストは の形式をとりますが、 のように改行で区切ることもできます。-D
"name1=value1;name2=value2"
FILES
OUTPUTS
- 生成される .qsb ファイルの名前をソースと異なるものにする必要がある場合、たとえば を介して区別することにより、1 つのシェーダーファイルが複数の .qsb ファイルのソースとして機能するため、このリストには の各項目のエントリを含めることができ、通常は で終わるファイル名を指定します。指定された名前は、単にソースファイル名に を付加するのではなく、qsb の 引数に渡される。DEFINES
FILES
.qsb
.qsb
-o
DEBUGINFO
- SPIR-V の完全なデバッグ情報を生成できるようになり、RenderDoc のようなツールが、パイプラインを検査するときや、頂点やフラグメントのデバッグを実行するときに、完全なソースを表示できるようになります。qsb の 引数に相当します。また、 キーワードが指定されている場合、生成される中間バイトコードにデバッグ情報を含めるように に指示されるため、Direct 3D にも効果があります。-g
PRECOMPILE
fxc
QUIET
- qsb からのデバッグ出力と警告出力を抑制する。致命的なエラーだけが出力されます。OUTPUT_TARGETS
- qt_add_shadersをスタティックライブラリで使用する場合、1つ以上の特別なターゲットが生成されます。これらのターゲットに対して追加処理を行いたい場合は、OUTPUT_TARGETS パラメータに値を渡します。
手作りシェーダーの代用
CMake の統合は、結果として生成される .qsb ファイルで、指定されたバージョンのシェーダの置換を指定することもサポートしています。これは事実上、-r
コマンドラインオプションでqsb を実行するのと同じです。
これは、FILES リストの以下の特別な構文によって有効になります:
FILES "shaders/externalsampler.frag@glsl,100es,shaders/externalsampler_gles.frag"
ファイル名の後には、@で区切られた置換指定をいくつでも続けることができます。これらのそれぞれは、シェーディング言語、バージョン、データを読み込むファイルをカンマで区切って指定する。詳細はQSBマニュアルを参照。
テセレーションの例
vertex.vert
の頂点ステージ、tess.tesc
のテッセレーション制御ステージ、tess.tese
のテッセレーション評価ステージ、fragment.frag
のフラグメントステージの4つのステージからなるグラフィックスパイプラインを考えてみましょう。
Vulkan、OpenGL、Metal、およびDirect 3Dのいずれでも機能する、完全に移植可能なアプリケーションを構築するには、主に2つのことに注意する必要があります:テッセレーション・シェーダーのHLSLバージョンは、手動で作成し、注入する必要があります。一方、Metalでは、適切なキーワードを指定しなければならない。
まず、頂点シェーダーとフラグメント・シェーダーを列挙する。Metalをサポートするために、TESSELLATION
キーワードが追加されています。これにより、Metal シェーダーコードを生成するときに、vertex.vert
の特別な処理と変換が可能になります。OpenGLについては、テッセレーション・サポートは新しいOpenGLバージョンでのみ利用可能であるため、GLSL言語バージョンを制限しています。
qt6_add_shaders(project "shaders_tessellation_part1" PREFIX "/shaders" GLSL "410,320es" TESSELLATION FILES "vertex.vert" "fragment.frag" )
第二に、テッセレーションシェーダーは、別のqt6_add_shaders()コールでリストされます。これは、NOHLSL
キーワードによるものです。頂点シェーダーとフラグメントシェーダーは、通常通りHLSLに変換されるべきです。そのため、4つのシェーダーすべてを1つのqt6_add_shaders()呼び出しで保持することは、実現不可能です。Metalの場合、いくつかのテッセレーション設定(出力頂点数、モード)は、VulkanやOpenGLとは異なり、前もって知っておく必要があるため、指定されます。
qt6_add_shaders(project "shaders_tessellation_part2" PREFIX "/shaders" NOHLSL GLSL "410,320es" TESSELLATION_VERTEX_COUNT 3 TESSELLATION_MODE "triangles" FILES "tess.tesc@hlsl,50,tess_hull.hlsl" "tess.tese@hlsl,50,tess_domain.hlsl" )
注: ハルとドメインのHLSLシェーダーを手動で記述することは、上級ユーザーのみに推奨されます。定数バッファのような特定の構成要素は、すべてのリソースインターフェイスとレイアウトが SPIR-V/GLSL/MSL シェーダと互換性を保つように、特別な注意が必要です。
©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。