Qt 3D からQt Quick 3D への移植:移行ガイド

このガイドは、現在 Qt 3Dへの移行を希望する開発者を対象としています。 Qt Quick 3D.

スコープの違い

3Dと Qt 3DQt Quick 3Dはどちらも3D APIを提供しているため似ているように見えるかもしれないが、根本的に異なるアプローチで設計されている。

Qt 3D は、カスタム3Dレンダラーを実装するための柔軟なAPIで、レンダリングプロセスのさまざまな側面を低レベルで抽象化します。その結果、Qt 3DC++QML の両方の API を提供している。

対照的に、Qt Quick 3D は、3D コンテンツのレンダリングに特化した高水準 API であり、Qt Quick の拡張として設計されています。そのため、API の大部分はQML ベースです。したがって、現在のQt 3D アプリケーションが C++ に大きく依存している場合、Qt Quick 3D に移行するには QML に移行する必要があります。

アーキテクチャの違い

Qt 3D 3DとQt Quick 3Dのアーキテクチャは大きく異なります。 Qt Quick 3D は、Qt Quick と同じデザイン・パターンを踏襲し、3D レンダリングをサポートするために機能を拡張しています。

Qt 3D では、ECSEntity-Component System)パターンを採用しています。このシステムでは、汎用的なエンティティ・クラスが使用され、コンポジション・パターンに従って、エンティティにさまざまなコンポーネントを追加することで特殊化できます。対照的に、Qt Quick 3D は、より広範な Qt フレームワークに沿った継承ベースの API を使用しており、特殊化されたノードは共通の基本クラスのサブクラスとなります。このような基本的な違いがあるため、2つのAPIの間に直接1:1のマッピングはありません。

もう1つの大きな違いは、スレッド・モデルにある。Qt 3Dアスペクトの概念が導入され、エンティティに接続されたさまざまなタイプのコンポーネントに異なるエントリ・ポイントが提供される。各アスペクトは、スレッドプールで処理されるタスクを作成することができ、プロバイダと依存関係のツリーに従って、フレームのレンダリングに必要なすべての作業を完了します。一方、Qt Quick 3D は、Qt Quick と同じスレッドモデルを使用している。シーンの状態を管理するためのメインGUIスレッドからアクセス可能なフロントエンドAPIと、レンダリングスレッド上のバックエンドAPIがある。レンダリング スレッドは、特定のタスクに追加のスレッドを使用することができますが、ユーザーから見た概念モデルには、2つのスレッドのみが含まれます。Qt 3D のアスペクトが提供する機能の多くはまだ利用可能ですが、Qt Quick 3D にはアスペクトの明確な概念はありません。

レンダリングの観点からは、Qt 3D は高度にカスタマイズ可能なアプローチを提供し、特注のレンダリングパイプラインを作成できる。しかし、この柔軟性には複雑さが伴う。デフォルトでは、Qt 3D は設定済みのレンダリングパイプラインを提供しない。対照的に、Qt Quick 3Dは、シーンのニーズに自動的に適応するすぐに使えるレンダリングパイプラインを備えており、よりユーザーフレンドリーに設計されています。たとえば、Qt Quick 3Dの指向性ライトが影を落とすように設定されている場合、レンダリングパイプラインにはシャドウマップ生成パスが自動的に含まれ、シーン内のマテリアルで使用されます。Qt 3D では、このような機能は、フレームグラフの手動設定と、シャドウマッピングパスをサポートするためのマテリアルの拡張を必要とします。さらに、ポイントライトやスポットライトのような異なるライトタイプの場合、フレームグラフとマテリアル定義にさらなる修正が必要になります。Qt 3D 、シャドウマッピング技術に強力なカスタマイズオプションが用意されていますが、シャドウを有効にするのがライトのプロパティを1つ設定するだけで済むQt Quick 3Dと比べると、かなりのオーバーヘッドになる可能性があります。

モジュールごとの詳細

Qt 3D コア

Qt 3D Core モジュールは、他のQt 3D モジュールを構築するための基本的なプリミティブを提供します。Qt 3D Core のほとんどのクラスは、ECS(Entity-Component-System)アーキテクチャを特別にサポートするクラスを除き、Qt Quick 3D で同等のコンポーネントを持っています。 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
    ]
}

この例では、エンティティはNode コンポーネントのサブクラスであるModel に置き換えられており、Qt 3D からTransform コンポーネントと同等のものを継承しています。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 があります。クリックが検出されると、pick メソッドがクリックの x 座標と y 座標で呼び出されます。ピック操作の結果は、球体モデルがヒットしたかどうかを判断するために使用されます。ヒットした場合は、球体モデルのマテリアルが赤と青の間で切り替わります。

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 を画面中央に配置したシンプルなシーンを作成しています。ボタンは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"
                            }
                        }
                    }
                }
            ]
        }
    }
}

Model Pane Buttonこの場合、Button を含むPane コンポーネントをレンダリングすることで、250x250 ピクセルのTexture が作成されます。通常、このテクスチャは非インタラクティブですが、Modelpickable を true に設定することで、前の例でButton に入力イベントを転送したのと同じ暗黙のピッキング メカニズムが、この例ではButton に入力イベントを転送するために使用されます。立方体Model の場合、立方体の各面はButton と対話的になります。

Qt 3D の入力クラスのほとんどは、Qt Quick 3Dに直接変換できないので、多少の移植作業が必要ですが、Qt Quick 3Dの暗黙のピッキング・メカニズムにより、3Dシーンで2Dアイテムを簡単に操作できます。

Qt 3D ロジック

Qt 3D Logicモジュールには、レンダリングされた各フレームのコールバックを提供するコンポーネントが1つ含まれています。Qt Quick 3Dでは、タイミング情報とレンダリングされた各フレームのコールバック・メカニズムを提供する一般的なQt Quick コンポーネントであるFrameAnimation コンポーネントを使用するのが同等のアプローチです。

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 Custom Geometry Example を参照してください。

テクスチャ

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 3DQt Quick 3D の両方で、カスタムマテリアルを作成することが可能です。

Qt 3D では、QMaterialQEffectQTechniqueQRenderPassQShaderProgram のツリーを含むかなり複雑なプロセスでした。Qt Quick 3D では、マテリアルに関して、このプロセスは単一のCustomMaterial コンポーネントに簡素化されています。このコンポーネントでは、マテリアルのカスタムシェーダコードを指定でき、残りのセットアップはレンダラーが行います。CustomMaterial にはシェーディングモードと非シェーディングモードがあります。シェー ドモードでは、カスタムシェーダコード API を使用して、ビルトインされたPrincipledMaterial シェーダをカスタマイズできます。どちらの場合もシェーダ言語は GLSL で、Qt Quick 3D API の他の部分との統合を容易にするために Qt 固有のキーワード拡張がいくつかあります。

この方法の詳細については、シェーディングモードと アンシェーディングモードの例、およびQt Quick 3D のカスタムGLSL シェーダ言語の使用に関する概要を参照してください。

エフェクト

Qt3Dの観点では、3Dシーンのレンダリングとポスト処理エフェクトのレンダリングに違いはありません。Qt Quick 3DシーンのModels 部分にはmaterials のリストが含まれ、これらはメインパスの間にレンダリングされます。これらのメインパスの結果は、ウィンドウサーフェスまたはテクスチャに直接レンダリングされた3Dコンテンツです。Effects は、Qt Quick 3Dでは、各pass がレンダーターゲット全体をカバーする単一のクワッドで終わる後処理エフェクトを指す点で異なります。メインカラーパスの結果のテクスチャは、テクスチャとして最初のエフェクトパスに渡され、そのパスの結果は、テクスチャとして次のEffect パスに渡されます。最終パスは、出力レンダーターゲット(通常はウィンドウサーフェス)にレンダリングされます。いくつかのEffects 、深度テクスチャのようにメインパス中に作成されたbuffers 、他の中間ステップが必要になります。これらはすべて、Qt Quick 3DのエフェクトAPIを使用して定義できます。

Qt Quick 3Dは、希望する効果を得るために必要な数のレンダーパスを定義できるAPIを使用して、このポスト処理エフェクトチェーンを特殊化します。

この方法の詳細については、Qt Quick 3D Post Processing Exampleをご覧ください。

インスタンスバッファ

Qt 3D では、インスタンス化およびインスタンスバッファの使用は非常に低レベルであ るため、どのように使用するかは特定のユースケースに依存します。Qt Quick 3Dでは、ビルトインされたマテリアルは、設定可能ないくつかの固定インスタンスプロパティを持っていますが、これを行うには、インスタンスデータをバッファとして提供する必要があります。このデータを提供する方法はいくつかあり、一度提供したら、Model コンポーネントのinstancing プロパティを設定するだけで、インスタンス・バッファ・データをインスタンス化したいものに関連付けることができます。

詳しくは、Qt Quick 3Dのインスタンス化に関する記事をご覧ください。

レンダラー拡張

Qt 3D の目的は、アプリケーションのカスタムレンダリングソリューションを定義する強力な方法を提供することです。 Qt Quick 3Dは、カスタマイズしやすいのではなく、使いやすいことを目的としているため、このレベルのカスタマイズは提供しませんが、上記のすべての方法に加えて、レンダリングパイプラインを拡張するいくつかの方法を提供します。これは、render extensions を実装することで、レンダラーと同じデータを使用してレンダラーにカスタム レンダー パスを追加できます。これは、Qt Quick 3Dレンダリングパイプラインと Qt Rendering Hardware Interface (RHI) APIをよく理解している必要がある低レベルのAPIです。

この方法の例については、ステンシルアウトラインエクステンションの例を参照してください。

Qt 3D エクストラ

Qt 3D Extras モジュールは、マテリアル、ジオメトリ ジェネレータ、カメラ コントローラなど、「すぐに使える」エクスペリエンスを促進するさまざまなユーティリティを提供します。また、フォワードレンダラフレームグラフも含まれています。Qt Quick 3Dでは、フレームグラフを明示的に定義する必要はありません。代わりに、シーンの要件に基づいてフレームグラフが自動的に生成されます。

組み込みマテリアル

Qt Quick 3D では、マテリアルはPrincipledMaterial またはSpecularGlossyMaterial を使用するか、カスタム・シェーダー・コードでCustomMaterial を定義することで提供されます。PrincipledMaterial は PBR(Physically Based Rendering)シェーダで、Metallic-Roughness ワークフローを使用します。生成されるシェーダの複雑さは、ユーザによって設定されたプロパティとシーンの内容に基づいて増加します。たとえば、ライト が影を落とす場合、生成されるシェーダは影を受け取るためのコードを含 みます。ライトプローブや反射プローブが存在する場合、シェーダはそのライティ ング情報を取り込みます。このダイナミックアダプテーションは、シェー ディングモードのCustomMaterial にも適用されます。しかし、シェー ドされていないCustomMaterial シェーダは、照明などのシーン情報を自動的 には考慮しません。

ジオメトリ・ヘルパー

Qt 3D と同様に、Qt Quick 3D にも、多くの組み込みジオメトリ プリミティブと、多くの手続き型ジオメトリ ジェネレータが用意されています。

次の表は、Qt 3D のジオメトリクラスと、Qt Quick 3D の同等クラスとの対応表です:

カメラコントローラ

カメラ制御については、Qt Quick 3D は、OrbitCameraController およびWasdController と同等のオプションを提供します。WasdController は Qt3D のFirstPersonCameraController に似ていますが、カメラだけでなく、シーン内のあらゆるアイテムを制御できます。

Qt 3D アニメーション

Qt 3D Animation モジュールは、さまざまなタイプのアニメーションを 3D でどのように扱うかを定義します。Qt Quick 3D では、同等の機能が複数のモジュールにまたがっており、可能な限りQt Quick の既存のクラスを利用しています。たとえば、QtQuick インポートからさまざまなアニメーション・クラスを使用して、3D ノードのプロパティをアニメーション化できます。

3Dコンテンツ作成ツールからアニメーションをインポートする場合、通常はタイムラインを使用して定義します。この Qt Quick Timelineモジュールは、このようなアニメーションを定義するために必要なクラスを提供し、アニメーションを使用してインポートされたコンテンツは、機能するためにこのモジュールが必要になります。

シーン内のアイテムの基本的なトランスフォーム(平行移動、回転、拡大縮小など)に加えて、Qt Quick 3Dはアーマチュアベースのアニメーションをサポートしています。ここでは、スケルトンのボーンをアニメーションさせ、各関節やボーンに関連する頂点に影響を与えます。これは、Skin コンポーネントによって実現されます。このコンポーネントは、シーン内のボーンを表すNode オブジェクトを、Model's ジオメトリ内の対応するボーンウェイトに接続します。この場合、スケルトンのアニメーションは、トランスフォームを使用してボーンをアニメーション化することによって行われます。

Qt Quick 3Dはモーフターゲットアニメーションもサポートしており、モデルのジオメトリの変化を直接アニメートすることができます。モーフターゲットは、モデルのジオメトリの定義済みのスナップショットで、MorphTarget コンポーネントを使用して、それらの間でアニメーションを行うことができます。

複数のアニメーションを組み合わせたり、ブレンドしたりするには、Qt Quick Timeline Blend Trees モジュールのコンポーネントを使用します。このモジュールでは、異なるアニメーションの相互作用を管理するための複雑なツリーを定義できます。これらの汎用アニメーションクラスのほとんどは、Qt Quick 3Dに特化したものではなく、より広範なQt Quick フレームワークの一部であり、新しいメソッドを導入する代わりに既存の機能を活用しています。

Qt 3D Scene2D

Qt 3D では、Scene2D コンポーネントは、2DQt Quick シーンを、3D シーン内で使用できるテクスチャにレンダリングするために使用されます。Qt Quick 3D では、これはTexture コンポーネントのsourceItem プロパティを使用して実現されます。sourceItem プロパティは、既存のItem を参照するか、インライン アイテムを定義できます。トップレベル アイテムはテクスチャ サイズを決定し、Qt Quick シーンは、Texture コンポーネントにマップされるレイヤにレンダリングされます。

さらに、Item-based コンポーネントを 3D シーン内で直接使用することも可能です。この場合、テクスチャは必要なく、3D 空間に投影されます。

© 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.