Qt 3D からQt Quick 3Dへの移植:移行ガイド
このガイドは、現在 Qt 3D からxml-ph-0001@deepl.internal 3Dへの移行を希望する Qt Quick 3Dへの移行を希望する開発者を対象としています。適用範囲の違い
適用範囲の違い
一方、 Qt 3D と Qt Quick 3D はどちらも3D APIを提供しているため一見似ているように見えますが、その設計思想は根本的に異なります。
Qt 3D は、カスタム3Dレンダラーを実装するための柔軟なAPIであり、レンダリングプロセスのさまざまな側面に対して低レベルの抽象化を提供します。その結果、Qt 3D はC++ とQMLの両方に対応したAPIを提供しています。
対照的に、Qt Quick 3Dは3Dコンテンツのレンダリングに焦点を当てた高レベルなAPIであり、Qt Quick の拡張として設計されています。そのため、そのAPIの大部分はQMLベースとなっています。したがって、現在のQt 3D アプリケーションがC++に大きく依存している場合、Qt Quick 3Dへの移行にはQMLへの移行が必要となります。
アーキテクチャの違い
Qt 3D とQt Quick 3Dは、アーキテクチャにおいて大きく異なります。Qt Quick 3Dは、Qt Quick と同じ設計パターンを踏襲し、3Dレンダリングをサポートするようにその機能を拡張しています。
最初の大きな違いは、デザインパターンの使用方法にあります。Qt 3D は、エンティティ・コンポーネント・システム(ECS)パターンを採用しています。このシステムでは、汎用的なエンティティクラスが使用され、コンポジションのパターンに従って、エンティティにさまざまなコンポーネントを追加することで特化させることができます。 対照的に、Qt Quick 3D は、より広範なQtフレームワークと整合する継承ベースのAPIを採用しており、特殊化されたノードは共通の基底クラスのサブクラスとなります。これらの根本的な違いにより、2つのAPI間には1対1の直接的な対応関係はありません。
もう一つの重要な違いは、スレッドモデルにあります。Qt 3D では「アスペクト(Aspects)」という概念が導入されており、エンティティにアタッチされたさまざまな種類のコンポーネントに対して異なるエントリポイントを提供します。各アスペクトはタスクを作成でき、それらはスレッドプールによって処理され、プロバイダと依存関係のツリーに従って、フレームのレンダリングに必要なすべての処理を完了させます。 一方、Qt Quick 3D はQt Quick と同じスレッドモデルを採用しています。シーン状態を管理するためのメインGUIスレッドからアクセス可能なフロントエンドAPIと、レンダリングスレッド上のバックエンドAPIを備えています。レンダリングスレッドは特定のタスクのために追加のスレッドを利用する場合もありますが、ユーザーの視点から見た概念モデルでは、スレッドは2つしか存在しません。Qt Quick 3D には「アスペクト」という明確な概念は存在しませんが、Qt 3D のアスペクトが提供する機能の多くは引き続き利用可能です。
レンダリングの観点から見ると、Qt 3D は高度にカスタマイズ可能なアプローチを提供しており、独自のレンダリングパイプラインを作成することが可能です。しかし、この柔軟性には複雑さが伴います。デフォルトでは、Qt 3D はあらかじめ設定されたレンダリングパイプラインを提供していません。 対照的に、Qt Quick 3Dは、シーンのニーズに自動的に適応する、すぐに使えるレンダリングパイプラインを備え、よりユーザーフレンドリーになるように設計されています。 例えば、Qt Quick 3Dで指向性ライトが影を落とすように設定されている場合、レンダリングパイプラインには自動的にシャドウマップ生成パスが組み込まれ、それがシーン内のマテリアルによって使用されます。Qt 3D では、このような機能を実現するには、フレームグラフを手動で設定し、シャドウマッピングパスをサポートするようにマテリアルを拡張する必要があります。 さらに、ポイントライトやスポットライトといった異なる種類のライトについては、フレームグラフやマテリアルの定義をさらに変更する必要があります。Qt 3D ではシャドウマッピング技術に対して強力なカスタマイズオプションが用意されていますが、これはQt Quick 3Dと比較して大きなオーバーヘッドとなる可能性があります。 3Dでは、ライトのプロパティを1つ設定するだけで簡単に影を有効化できるからです。
モジュールごとの詳細
Qt 3D コア
Qt 3D のCoreモジュールは、他のQt 3D モジュールを構築するための基礎となるプリミティブを提供します。Qt 3D Coreのほとんどのクラスには、Qt Quick 3Dに同等のコンポーネントが存在しますが、Entity-Component-System(ECS)アーキテクチャを具体的にサポートするクラスは例外です。Qt Quick 3Dは、Qt 3D で使用される一般的なエンティティとコンポーネントの組み合わせに対応した、あらかじめ組み立てられたコンポーネントを提供しており、開発プロセスを簡素化します。
例として、Qt3Dにおけるレンダリング可能なエンティティの設定を以下に示します:
PhongMaterial {
id: material
}
TorusMesh {
id: torusMesh
radius: 5
minorRadius: 1
rings: 100
slices: 20
}
Transform {
id: torusTransform
scale3D: Qt.vector3d(1.5, 1, 0.5)
rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45)
}
Entity {
id: torusEntity
components: [ torusMesh, material, torusTransform ]
}上記のコードから、このエンティティがメッシュ、マテリアル、トランスフォームで構成されていることがわかります。Qt Quick 3D における同等のコードは、次のようになります:
Model {
id: torusModel
scale: Qt.vector3d(1.5, 1, 0.5)
eulerRotation.x: 45
geometry: TorusGeometry {
radius: 5
tubeRadius: 1
rings: 100
segments: 20
}
materials: [
PrincipledMaterial {
id: material
]
}この例では、エンティティはModel に置き換えられています。これはNode コンポーネントのサブクラスであり、Qt 3D のTransform コンポーネントに相当する機能を継承しています。さらに、Nodeのサブクラスはすべて、親子関係を持つシーングラフの一部となります。 Modelコンポーネントは、ジオメトリやマテリアルを持つことができるレンダリング可能なエンティティです。この例では、Qt 3D のコードで使用されている手続き型APIに合わせるためにgeometry プロパティを使用していますが、source プロパティを使用して静的ファイルからジオメトリを指定することも可能です。Modelコンポーネントのmaterials プロパティは、ジオメトリのシェーディングに使用されるマテリアルのリストです。 これがリストになっているのは、ジオメトリが複数のサブセットを含み、それぞれが個別のマテリアルを使用する可能性があるためです。PrincipledMaterial コンポーネントは、Metallic-Roughnessワークフローを使用するPBR(Physically Based Rendering)マテリアルであり、この例の場合、Qt 3D スニペットで使用されているPhongMaterial を置き換えます。
Qt 3D 入力
Qt 3D は、独自のカスタム入力システムを通じてさまざまな入力クラスを提供します。対照的に、Qt Quick 3Dは主にQt Quick の入力クラスを再利用しています。3Dシーンとのインタラクションのために、Qt Quick 3Dはレイキャスティングやオブジェクトのピッキングを実行するための追加APIを提供しています。
View3D は、Qt Quick 3Dにおけるピック操作を処理するための主要なクラスであり、明示的および暗黙的なピックメソッドの両方を提供します。明示的なピックAPIを使用すると、View3D 内のx座標とy座標を指定することで、2D空間から直接ピックを行うことができます。この操作は、ヒットしたオブジェクトおよびヒット位置に関する詳細を含むpickResult 値を返します。 このAPIは同期型であり、レイが投射された直後に結果が得られます。さらに、シーン内の任意の点からレイを投射することが可能です。明示的および暗黙的なピッキング手法のいずれも、最初のヒットだけでなく、すべてのヒットのリストを返すことができます。
import QtQuick
import QtQuick.Controls
import QtQuick3D
ApplicationWindow {
width: 640
height: 480
visible: true
View3D {
id: view
anchors.fill: parent
PerspectiveCamera {
z: 200
}
DirectionalLight {
}
PrincipledMaterial {
id: material
baseColor: "red"
}
PrincipledMaterial {
id: selectedMaterial
baseColor: "blue"
}
Model {
id: sphereModel
source: "#Sphere"
pickable: true
materials: [
material
]
}
}
MouseArea {
anchors.fill: parent
onClicked: (mouse) => {
let result = view.pick(mouse.x, mouse.y)
if (result.hitType == PickResult.Model) {
if (result.objectHit == sphereModel) {
// toggle selection
if (sphereModel.materials[0] == material)
sphereModel.materials[0] = selectedMaterial
else
sphereModel.materials[0] = material
}
} else {
// deselect
sphereModel.materials[0] = material
}
}
}
}このサンプルコードスニペットでは、球体モデルを含む単純なシーンが作成されています。球体モデルはpickable に設定されており、これはシーン内にレイが投射された際、このモデルがピッキングの対象として考慮されることを意味します。View3D の上には、クリックを監視するMouseArea が配置されています。 クリックが検出されると、クリックの x 座標と y 座標を引数として、pick メソッドが呼び出されます。その後、ピック操作の結果を用いて、球体モデルがヒットしたかどうかを判定します。ヒットした場合は、球体モデルのマテリアルを赤と青の間で切り替えます。
import QtQuick
import QtQuick.Controls
import QtQuick3D
ApplicationWindow {
width: 640
height: 480
visible: true
View3D {
id: view
anchors.fill: parent
Node {
eulerRotation.y: 45
PerspectiveCamera {
z: 200
}
}
DirectionalLight {
}
Node {
id: anchorItem
Item {
anchors.centerIn: parent
width: 250
height: 250
Button {
anchors.centerIn: parent
text: "Click Me"
}
}
}
}
}このサンプルコードスニペットでは、画面中央にButton を配置したシンプルなシーンが作成されています。 Buttonは2Dアイテムですが、その親がNode であるため、3D空間に投影されます。このようなコンポーネントは、2D空間と同じように操作できます。View3D は、シーンへのレイの投射や、シーンを構成する2Dアイテムへの入力イベントの転送を自動的に処理します。
import QtQuick
import QtQuick.Controls
import QtQuick3D
ApplicationWindow {
width: 640
height: 480
visible: true
View3D {
id: view
anchors.fill: parent
Node {
eulerRotation.y: 25
PerspectiveCamera {
z: 200
}
DirectionalLight {
}
}
Model {
source: "#Cube"
pickable: true
materials: [
PrincipledMaterial {
baseColorMap: Texture {
sourceItem: Pane {
width: 250
height: 250
Button {
anchors.centerIn: parent
text: "Click Me"
}
}
}
}
]
}
}
}同様に、上記のコードスニペットでは、`Pane `(内部に`Button`を含む)をテクスチャとして持つキューブ `Model ` が作成されています。この場合、`Button` を含む `Pane ` コンポーネントをレンダリングすることで、250×250ピクセルの `Texture ` が生成されます。 通常、このテクスチャは非インタラクティブですが、Model でpickable をtrueに設定することで、前の例で入力イベントをButton に転送していたのと同じ暗黙的なピッキングメカニズムが、この例では入力イベントをButton に転送するために使用されます。立方体Model の場合、立方体の各面がButton とインタラクティブになります。
Qt 3D の入力クラスのほとんどは、Qt Quick 3Dに直接変換できないため、ある程度の移植作業が必要ですが、Qt Quick 3Dの暗黙的なピッキング機構により、3Dシーン内の2Dアイテムとのインタラクションが容易になります。
Qt 3D ロジック
Qt 3D のLogicモジュールには、レンダリングされる各フレームごとにコールバックを提供する単一のコンポーネントが含まれています。Qt Quick 3Dでは、これに相当するアプローチとして、FrameAnimation コンポーネントを使用します。これは、Qt Quick の汎用コンポーネントであり、レンダリングされる各フレームのタイミング情報とコールバックメカニズムを提供します。
FrameAnimation {
running: true
onTriggered: {
console.log(`currentFrame: ${currentFrame}, frameTime: ${frameTime}`)
}
}このコンポーネントは、シーン内のどこでも使用でき、各フレームで何らかのアクションを実行したいオブジェクトの子として配置することも可能です。
ただし、このパターンは、各フレームで何らかのアクションを実行したい場合にのみ必要となる点に留意してください。FrameAnimation を使用すると、一部のゲームエンジンでポーリング動作を再現できますが、Qt Quick 3D でも、Qt Quick と同様にイベント駆動型のパターンを使用することも可能です。
Qt 3D レンダリング
Qt 3D のRenderモジュールには、レンダリングに必要な主要なクラスのほとんどが含まれています。Qt Quick 3Dでは、同等の機能の大部分は、ユーザーに直接公開されない内部実装の詳細として提供されています。ただし、Qt Quick 3Dの機能を拡張・カスタマイズするために使用できるAPIとして、ユーザーに公開されているクラスもいくつかあります。
ジオメトリ
Qt 3D におけるジオメトリまたはメッシュデータは、QGeometryRenderer クラスまたはGeometryRenderer コンポーネントによって表現されます。Qt Quick 3D では、これらに相当するのはQQuick3DGeometry クラスとProceduralMesh コンポーネントです。Qt 3D では、QGeometryRenderer クラスはより低レベルであり、ユーザーがジオメトリデータの一部として頂点属性のレイアウトを指定することが求められます。Qt Quick 3D では、使用する組み込みの頂点属性を制御できますが、バッファのレイアウトは実装上の詳細として内部で処理されます。
この仕組みの詳細については、「Qt Quick 」の3D カスタムジオメトリの例をご覧ください。
テクスチャ
Qt 3D におけるテクスチャは、QAbstractTexture のサブクラスによって表現されます。Qt Quick 3D では、これに相当するのがTexture コンポーネントであり、これはテクスチャとサンプラのフロントエンド表現です。ただし、テクスチャコンポーネントが使用するデータは、さまざまなソースから取得できます。最も簡単な方法は、source プロパティに画像ファイルを設定するだけであり、それによってテクスチャデータとして GPU にアップロードされます。 また、2D QMLコンテンツをソースとして使用するか、QQuick3DTextureData をサブクラス化するか、あるいはProceduralTextureData コンポーネントを使用することで、実行時にテクスチャデータを手続き的に生成することも可能です。これらのタイプでは、サイズ、フォーマット、および生の画像データを指定することでテクスチャデータを定義できます。さらに、render extensions を使用することで、GPU上でテクスチャを作成することも可能です。
具体的な方法の詳細については、「Qt Quick 」の「3D Procedural Texture Example」を参照してください。
マテリアル
Qt 3D では、いくつかの組み込みマテリアルを使用することは可能でしたが、その場合は、それらと連携可能な組み込みのframegraphs に制限されていました。Qt Quick 3D も同様の状況にあり、内部レンダリング戦略と連携する組み込みマテリアルがいくつか提供されています。しかし、Qt 3D とQt Quick 3D のどちらにおいても、カスタムマテリアルを作成することが可能です。
Qt 3D では、これはQMaterial 、QEffect 、QTechnique 、QRenderPass 、およびQShaderProgram を階層的に組み合わせる、かなり複雑なプロセスでした。Qt Quick 3D では、マテリアルに関してこのプロセスが単一のCustomMaterial コンポーネントに簡略化されています。このコンポーネントを使用すると、マテリアル用のカスタムシェーダーコードを指定でき、残りの設定はレンダラーによって行われます。CustomMaterial には、「シェーディングモード」と「非シェーディングモード」の 2 つのモードがあります。 シェーデッドモードでは、カスタムシェーダーコードAPIを使用して組み込みのPrincipledMaterial シェーダーをカスタマイズでき、アンシェーデッドモードでは独自のシェーダーコードをゼロから記述できます。どちらの場合もシェーダー言語はGLSLですが、Qt Quick 3D APIの他の部分との統合を容易にするために、Qt固有のキーワード拡張がいくつか用意されています。
具体的な実装方法の詳細については、「シェーディングモード」および「非シェーディングモード」のサンプル、ならびにQt Quick 3DのカスタムGLSLシェーダー言語の使用に関するこの概要を参照してください。
エフェクト
Qt3Dの観点からは、3Dシーンのレンダリングとポストプロセッシングエフェクトのレンダリングに違いはなく、低レベルな観点からもこれは正しいです。しかし、Qt Quick 3Dでは区別が設けられています。Models 3Dシーンの一部にはmaterials のリストが含まれており、これらはメインパス中にレンダリングされます。 これらのメインパスの結果は、ウィンドウ表面またはテクスチャに直接レンダリングされた3Dコンテンツとなります。Effects は、Qt Quick 3Dにおいて、各pass が最終的にレンダリングターゲット全体を覆う単一のクワッドとなるポストプロセッシングエフェクトを指すという点で異なります。 メインカラーパスの結果として得られるテクスチャは、テクスチャとして最初のエフェクトパスに渡され、そのパスの結果はテクスチャとして次のEffect パスに渡され、以下同様です。 最後のパスは、通常はウィンドウ表面である出力レンダリングターゲットにレンダリングされます。Effects によっては、深度テクスチャのようにメインパスで作成されたbuffers を必要とするものもあれば、中間ステップを必要とするものもありますが、これらはすべてQt Quick 3DのEffects APIを使用して定義することができます。
Qt Quick 3Dでは、このポストプロセッシングエフェクトチェーンを専門化しており、APIを通じて、目的のエフェクトを実現するために必要な数のレンダリングパスを定義できるようになっています。
その詳細については、「Qt Quick 3D ポストプロセッシングの例」をご覧ください。
インスタンスバッファ
Qt 3D では、インスタンス化やインスタンスバッファの使用はかなり低レベルであるため、その使用方法は具体的なユースケースによって異なります。Qt Quick 3Dでは、組み込みのマテリアルには設定可能な固定のインスタンス化プロパティがいくつかありますが、これを行うにはインスタンスデータをバッファとして指定する必要があります。このデータを指定する方法はいくつかあり、一度指定すれば、Model コンポーネントのinstancing プロパティを設定するだけで、インスタンスバッファのデータをインスタンス化したい対象に関連付けることができます。
詳細については、Qt Quick 3D のインスタンス化に特化したこちらの記事をご覧ください。
レンダラー拡張機能
Qt 3D の目的は、アプリケーション向けにカスタムレンダリングソリューションを定義するための強力な手段を提供することです。Qt Quick 3Dは、カスタマイズしやすさよりも使いやすさを重視しているため、このレベルのカスタマイズ機能は提供していませんが、上記で挙げたすべての方法に加えて、レンダリングパイプラインを拡張するいくつかの方法を提供しています。 これは、render extensions を実装することで実現されます。これにより、レンダラーと同じデータを使用して、レンダラーにカスタムレンダーパスを追加できます。これは低レベルのAPIであり、Qt Quick 3Dのレンダリングパイプラインおよび Qt Rendering Hardware Interface (RHI)APIについて十分な理解が必要です。
具体的な実装例については、「Stencil Outline Extension Example」を参照してください。
Qt 3D エクストラ
「Qt 3D Extras」モジュールには、マテリアル、ジオメトリジェネレータ、カメラコントローラなど、「すぐに使える」環境を実現するためのさまざまなユーティリティが用意されています。また、フォワードレンダラーのフレームグラフも含まれています。Qt Quick 3D では、フレームグラフを明示的に定義する必要はなく、シーンの要件に基づいてフレームグラフが自動的に生成されます。
組み込みマテリアル
Qt Quick 3Dでは、マテリアルはPrincipledMaterial やSpecularGlossyMaterial を使用するか、カスタムシェーダーコードを含むCustomMaterial を定義することで提供されます。PrincipledMaterial は、Metallic-Roughnessワークフローを使用するPBR(Physically Based Rendering)シェーダーです。生成されるシェーダーの複雑さは、ユーザーが設定したプロパティやシーンの内容に基づいて増加します。 たとえば、ライトが影を落とす場合、生成されるシェーダーには影の受容に関するコードが含まれます。また、ライトプローブやリフレクションプローブが存在する場合、シェーダーはその照明情報を組み込みます。この動的な適応は、シェーディングモードの「CustomMaterial 」にも適用されます。ただし、シェーディングされていない「CustomMaterial 」シェーダーでは、照明などのシーン情報は自動的に考慮されません。
ジオメトリヘルパー
Qt 3D と同様に、Qt Quick 3Dも多くの組み込みジオメトリプリミティブに加え、多数のプロシージャルジオメトリジェネレータを提供しています。
以下の表は、Qt 3D のジオメトリクラスと、Qt Quick 3Dにおけるそれに対応するクラスの対応関係を示しています:
| Qt 3D | Qt Quick 3D |
|---|---|
| ConeMesh | ConeGeometry |
| CuboidMesh | CuboidGeometry |
| CylinderMesh | CylinderGeometry |
| ExtrudedTextMesh | ExtrudedTextGeometry |
| PlaneMesh | PlaneGeometry |
| 球メッシュ | SphereGeometry |
| トーラスメッシュ | TorusGeometry |
カメラコントローラー
カメラの制御に関しては、Qt Quick 3D は、OrbitCameraController およびWasdController と同等のオプションを提供しています。WasdController は、Qt3D のFirstPersonCameraController に似ていますが、カメラだけでなく、シーン内のあらゆるアイテムを制御することができます。
| Qt 3D | Qt Quick 3D |
|---|---|
| FirstPersonCameraController | WasdController |
| OrbitCameraController | OrbitCameraController |
Qt 3D アニメーション
Qt 3D のAnimationモジュールは、3D環境における各種アニメーションの処理方法を定義しています。Qt Quick 3Dでは、同等の機能が複数のモジュールに分散しており、可能な限りQt Quick の既存のクラスを活用しています。例えば、QtQuick インポートに含まれる各種アニメーションクラスを使用して、3Dノードのプロパティにアニメーションを適用することができます。
3Dコンテンツ作成ツールからアニメーションをインポートする場合、それらは通常、タイムラインを使用して定義されます。Qt Quick のタイムラインモジュールは、そのようなアニメーションを定義するために必要なクラスを提供しており、アニメーションを含むインポートされたコンテンツが機能するには、このモジュールが必要となります。
シーン内のアイテムに対する基本的な変形(平行移動、回転、拡大縮小など)に加え、Qt Quick 3Dはアーマチュアベースのアニメーションをサポートしています。これは、スケルトンのボーンをアニメーション化し、各関節やボーンに関連付けられた頂点に影響を与えるものです。これは、シーン内のボーンを表すNode オブジェクトを、Model's ジオメトリ内の対応するボーンウェイトと結びつける「Skin 」コンポーネントによって実現されます。 この場合、スケルトンのアニメーションは、トランスフォーメーションを使用してボーンをアニメーション化することで行われます。
Qt Quick 3Dでは、モデルのジオメトリの変化を直接アニメーション化できるモーフターゲットアニメーションもサポートされています。モーフターゲットはモデルのジオメトリの事前定義されたスナップショットであり、「MorphTarget 」コンポーネントを使用して、それらの間をアニメーション化することができます。
複数のアニメーションを組み合わせたり、ブレンドしたりするには、「Qt Quick 」の「Timeline Blend Trees」モジュール内のコンポーネントが使用されます。このモジュールでは、異なるアニメーションの相互作用を管理するための複雑なツリーを定義できます。これらの汎用アニメーションクラスのほとんどは、Qt Quick 3Dに固有のものではなく、より広範なQt Quick フレームワークの一部であり、新しいメソッドを導入するのではなく、既存の機能を活用しています。
Qt 3D Scene2D
Qt 3D では、Scene2Dコンポーネントを使用して、2DのQt Quick シーンを、3Dシーン内で使用可能なテクスチャとしてレンダリングします。Qt Quick 3D では、これはTexture コンポーネントのsourceItem プロパティを使用して実現されます。sourceItemプロパティは、既存のItem を参照することも、インラインアイテムを定義することもできます。最上位のアイテムがテクスチャのサイズを決定し、Qt Quick シーンは、Texture コンポーネントにマッピングされるレイヤーにレンダリングされます。
さらに、Item-based コンポーネントを3Dシーン内で直接使用することも可能です。この場合、テクスチャを必要とせずに3D空間に投影されます。
© 2026 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.