Qt Quick 2Dコンテンツによる3Dシーン
3D世界の2Dアイテム
Qt Quick 3Dは、3Dと2Dの要素を組み合わせたシーンの効率的な作成とレンダリングを提供します。
3Dと2Dを組み合わせたシーンとはどういう意味でしょうか?
本来、2Dシーン内の3Dビューポートを表すView3D オブジェクトは、View3D アイテムの周り、下、上、Qt Quick Item 、矩形、イメージ、テキストなどのQt Quick アイテムと簡単に組み合わせることができます。
次の例を考えてみよう:
import QtQuick import QtQuick3D Rectangle { gradient: Gradient { GradientStop { position: 0; color: "steelblue" } GradientStop { position: 1; color: "black" } } Text { text: "Hello 2D World" font.pointSize: 32 color: "red" anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter } Item { width: 400; height: 400 anchors.centerIn: parent View3D { anchors.fill: parent environment: SceneEnvironment { backgroundMode: SceneEnvironment.Color; clearColor: "lightGray" } PerspectiveCamera { z: 600 } DirectionalLight { } Model { source: "#Cube" materials: PrincipledMaterial { baseColor: "green"; metalness: 0.0; roughness: 0.0 } eulerRotation: Qt.vector3d(30, 45, 0) } } } }
ここでは、3Dシーンはグレーの背景のエリアです。ウィンドウの残りの部分は、2DQt Quick アイテムで構成されています。これらのアイテムは、View3D と重なることができますが、3D世界の一部ではなく、3D座標系を使用しておらず、3Dシーンの変換に関与しません。
3D世界の中に2Dアイテムを持ち、3D変換に参加させたい場合はどうすればいいでしょうか?例えば、Rectangle やText のアイテムが、立方体の回転に従い、常に立方体の上に配置されるように、3Dワールド内に配置することはできるでしょうか?
以下のセクションでは、これを実現する方法を見ていきます。この例では、Rectangle とText を使用していますが、Qt Quick Controls 、Shape 、ShaderEffect 、ParticleSystem など、Qt Quick のコンテンツはすべてこの方法で使用できます。
注: 2Dコンテンツを3Dオブジェクトと統合するには、他のアプローチもあります。3Dノードに2Dアイテムを追加することで、3D世界の2Dオブジェクトと3Dオブジェクトを自由に組み合わせることができますが、3Dオブジェクトの表面に2Dコンテンツをレンダリングすることはできません。Qt Quick によって生成されたコンテンツで 3D メッシュにテクスチャを貼ることが目的であれば、代わりにTexture のthe sourceItem property を使用してください。
Qt Quick テクスチャマップとして使用されるコンテンツ | Qt Quick 3Dシーン内のアイテム |
---|---|
3D ノードに 2D アイテムを追加する
Object3D Item Object3D は タイプの基本クラスです。これは、 や、 のような型が、 の子を受け入れることを意味します。Node Node Model Item
Qt 6.0 から、3D ノードに 2D アイテムを追加しても、2D コンテンツを OpenGL テクスチャや Vulkan イメージなどにレンダリングすることはなくなりました。むしろ、デフォルトのモードは、同じレンダーパスで、2Dアイテムを3Dシーンの残りの部分とインラインでレンダリングすることです。2Dアイテムには、すべての3Dトランスフォームが適用されます。トランスフォームは、ラッピングNode から継承されます。
import QtQuick import QtQuick3D Rectangle { gradient: Gradient { GradientStop { position: 0; color: "steelblue" } GradientStop { position: 1; color: "black" } } Text { text: "Hello 2D World" font.pointSize: 32 color: "red" anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter } Item { width: 400; height: 400 anchors.centerIn: parent View3D { anchors.fill: parent environment: SceneEnvironment { backgroundMode: SceneEnvironment.Color; clearColor: "lightGray" } PerspectiveCamera { z: 600 } DirectionalLight { } Model { Node { y: 150 Rectangle { anchors.horizontalCenter: parent.horizontalCenter color: "white" width: text3d.width height: text3d.height Text { id: text3d text: "Hello 3D World" font.pointSize: 32 } } } source: "#Cube" materials: PrincipledMaterial { baseColor: "green"; metalness: 0.0; roughness: 0.0 } eulerRotation: Qt.vector3d(30, 45, 0) } } } }
最初のスニペットと比較すると、Model ノードには子ノードが追加され、キューブの位置よりやや上に配置されるようにトランスフォームされています。150
は、3D座標空間において、キューブの中心からの相対的な位置です。
Model { Node { y: 150
次に、Rectangle アイテムがあります。Node の下に追加すると、3D ワールドと 2D ワールドの境界が内部的に交差しますが、アプリケーション・デザイナには透過的です。不可視のcontent item
が自動的に生成され、矩形がparent
を参照し、アンカーを実行できるようになります。ノードからの3D変換は、2Dサブツリー全体に適用されます。この例では、回転が立方体の回転と一致することを意味します。
Node { y: 150 Rectangle { anchors.horizontalCenter: parent.horizontalCenter
2Dと3Dの座標空間
2D アイテムは、引き続きQt Quick の座標系を使用します:Y軸は上から下へ、単位はピクセルです。一方、3D ノードは 3D 座標系を使用します。Y 軸は上を向き、単位はセンチメートルに対応し、Camera の透視投影の影響を受けます。
トップアイテムの左上隅は、デフォルトでノードの原点に配置されます。つまり、2Dサブツリーのトップレベル・アイテムは、anchors.centerIn: parent
などのアンカーを指定したり、例のように水平方向の中心を親の水平方向の中心に固定することで、2Dコンテンツを3Dノードの水平方向の中心に配置したい場合がよくあります。
さらなる考慮事項
- 2Dアイテムは3Dオブジェクトとインラインでレンダリングされますが、ライティングには参加せず、影を落とすこともありません。
- Clipping が期待通りに動作しない可能性があるため、避けるべきです。2Dアイテムのデザインにクリッピングが不可欠な場合、アプリケーションは明示的にテクスチャへのレンダリングにフォールバックする必要があります。これは、3D ノードの下のトップレベル に を追加することで実現できます。
Item
layer.enabled: true
- Qt 6.2では、入力は必要に応じて2Dアイテムに渡されます。ポインティングデバイスからの入力は、宣言されたItemのchildrenRect 。
- 3Dシーンに2Dアイテム・ツリーを追加するのは非常に簡単ですが、3Dシーン内に2Dサブツリーを大量に(数百以上)追加するのは避けるべきです。これは、3Dノードの下にあるItem サブツリーの数であり、サブツリー内の2Dアイテムの総数ではないことに注意してください。例えば、上のQMLスニペットには2Dサブツリーが1つしか含まれていません。
Qt Quick 3D - Quick Items ExampleおよびQQuickItem::mapFromGlobal()も参照して ください。
© 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.