Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtquick3d-2d.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2020 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\page qtquick3d-2d.html
6
\title Qt Quick 3D Scenes with 2D Content
7
\brief Embedding Qt Quick items in a 3D scene
8
9
\section1 2D Items in a 3D World
10
11
Qt Quick 3D offers efficient creation and rendering of scenes that combine 3D and 2D
12
elements.
13
14
What do we mean by a combined 3D-2D scene?
15
16
By nature, a \l View3D object, representing a 3D viewport in the 2D scene, can be easily
17
combined with Qt Quick items, such as, Rectangle, Image, Text, around, below, or above the
18
View3D item, which itself is a Qt Quick \l Item.
19
20
Consider the following example:
21
22
\qml
23
import QtQuick
24
import QtQuick3D
25
26
Rectangle {
27
gradient: Gradient {
28
GradientStop { position: 0; color: "steelblue" }
29
GradientStop { position: 1; color: "black" }
30
}
31
Text {
32
text: "Hello 2D World"
33
font.pointSize: 32
34
color: "red"
35
anchors.top: parent.top
36
anchors.horizontalCenter: parent.horizontalCenter
37
}
38
Item {
39
width: 400; height: 400
40
anchors.centerIn: parent
41
View3D {
42
anchors.fill: parent
43
environment: SceneEnvironment { backgroundMode: SceneEnvironment.Color; clearColor: "lightGray" }
44
PerspectiveCamera { z: 600 }
45
DirectionalLight { }
46
Model {
47
source: "#Cube"
48
materials: PrincipledMaterial { baseColor: "green"; metalness: 0.0; roughness: 0.0 }
49
eulerRotation: Qt.vector3d(30, 45, 0)
50
}
51
}
52
}
53
}
54
\endqml
55
56
\image quick2d-3d-1.jpg
57
58
Here the 3D scene is the area with gray background. The rest of the window consists of 2D
59
Qt Quick items. These can overlap with the View3D but are not part of the 3D world, are
60
not using the 3D coordinate system, and do not take part in the 3D scene's
61
transformations.
62
63
What if we want to have 2D items within the 3D world, in a way that they truly participate
64
in all 3D transforms? For example, can we have \l Rectangle and \l Text items placed
65
within the 3D world, in a way that they follow the cube's rotation and are always placed
66
above it?
67
68
\image quick2d-3d-3.jpg
69
70
In the following sections we will take a look at how this can be achieved. While the
71
example uses \l Rectangle and \l Text, any Qt Quick content, including Qt Quick Controls,
72
\l Shape, \l ShaderEffect, \l ParticleSystem, can be used this way.
73
74
\note There are also other approaches available to integrate 2D content with the 3D
75
objects. Adding 2D items to 3D nodes allows freely combining the 2D and 3D objects in the
76
3D world, but it does not allow rendering the 2D content on the surface of a 3D object. If
77
the goal is to texture a 3D mesh with content generated by Qt Quick, use
78
\l{Texture::sourceItem}{the sourceItem property} of \l Texture instead.
79
80
\table
81
\header
82
\li Qt Quick content used as a texture map
83
\li Qt Quick items in the 3D scene
84
\row
85
\li \image quick2d-3d-4.jpg
86
\li \image quick2d-3d-5.jpg
87
\endtable
88
89
\section1 Adding 2D Items to 3D Nodes
90
91
The key enabler is \l{Object3D}'s ability to accept \l Item child objects, and treat them
92
in a special way. \l Object3D is the base class for the \l Node type. This means that any
93
\l Node, and also types like \l Model, accept \l Item children.
94
95
Starting with Qt 6.0, adding a 2D item to a 3D node no longer triggers rendering the 2D
96
content into a OpenGL texture, Vulkan image, or similar. Rather, the default mode is to
97
render the 2D items in-line with the rest of the 3D scene, in the same render pass. The 2D
98
items have all 3D transformations applied. The transformations are inherited from the
99
wrapping \l Node.
100
101
\qml
102
import QtQuick
103
import QtQuick3D
104
105
Rectangle {
106
gradient: Gradient {
107
GradientStop { position: 0; color: "steelblue" }
108
GradientStop { position: 1; color: "black" }
109
}
110
Text {
111
text: "Hello 2D World"
112
font.pointSize: 32
113
color: "red"
114
anchors.top: parent.top
115
anchors.horizontalCenter: parent.horizontalCenter
116
}
117
Item {
118
width: 400; height: 400
119
anchors.centerIn: parent
120
View3D {
121
anchors.fill: parent
122
environment: SceneEnvironment { backgroundMode: SceneEnvironment.Color; clearColor: "lightGray" }
123
PerspectiveCamera { z: 600 }
124
DirectionalLight { }
125
Model {
126
Node {
127
y: 150
128
Rectangle {
129
anchors.horizontalCenter: parent.horizontalCenter
130
color: "white"
131
width: text3d.width
132
height: text3d.height
133
Text {
134
id: text3d
135
text: "Hello 3D World"
136
font.pointSize: 32
137
}
138
}
139
}
140
source: "#Cube"
141
materials: PrincipledMaterial { baseColor: "green"; metalness: 0.0; roughness: 0.0 }
142
eulerRotation: Qt.vector3d(30, 45, 0)
143
}
144
}
145
}
146
}
147
\endqml
148
149
\image quick2d-3d-2.jpg
150
151
Compared to the first snippet, the \l Model node now has a child node, with a transform
152
that places it somewhat above the cube's position. \c 150 is relative to the cube's
153
center, in the 3D coordinate space.
154
155
\qml
156
Model {
157
Node {
158
y: 150
159
\endqml
160
161
Then there is the \l Rectangle item. When adding it under a \l Node, the boundaries of the
162
3D and 2D world are crossed internally, but this remains transparent to the application
163
designer. An invisible \c{content item} is generated automatically, allowing the Rectangle
164
to refer to \c parent and perform anchoring. The 3D transform from the Node is applied to
165
the entire 2D subtree. In the example this means that the rotation will match the cube's
166
rotation.
167
168
\qml
169
Node {
170
y: 150
171
Rectangle {
172
anchors.horizontalCenter: parent.horizontalCenter
173
\endqml
174
175
\section2 Coordinate Spaces in 2D and 3D
176
177
The 2D items continue to use Qt Quick's coordinate system: Y axis runs from top to bottom,
178
and the units correspond to pixels. 3D nodes on the other hand use the 3D coordinate
179
system: the Y axis points up, and the units correspond to centimeters, affected by the
180
\l{Camera}'s perspective projection.
181
182
The top item's top-left corner is placed at the Node's origin by default. This means that
183
the top-level item in a 2D subtree will often want to specify an anchor, for example
184
\c{anchors.centerIn: parent}, or, like in the example, anchoring the horizontal center to
185
the parent' horizontal center, thus centering the 2D content horizontally over the 3D
186
node.
187
188
\section2 Further Considerations
189
190
\list
191
192
\li While the 2D items are rended in-line with 3D objects, they do not participate in
193
lighting, and will not be casting shadows.
194
195
\li \l{Item::clip}{Clipping} may not perform as expected and should be avoided. If
196
clipping is essential to the design of 2D items, the application should make an explicit
197
fall back to rendering to a texture. This can be achieved by adding \c{layer.enabled:
198
true} to the top-level \c Item under the 3D node.
199
200
\li As of Qt 6.2, input is passed to the 2D items as necessary. Input from pointing devices
201
must occur within the \l{Item::childrenRect.x}{childrenRect} of the declared Items.
202
203
\li While adding a 2D item tree into the 3D scene is fairly cheap, excess amounts
204
(hundreds or more) of 2D subtrees within the 3D scene should be avoided, because in large
205
amounts this may lead to increased memory and graphics resource usage. Note that this
206
refers to the number of separate \l Item subtrees under 3D nodes, not the total number of
207
2D items in those subtrees. For example, the QML snippet above contains only one 2D
208
subtree.
209
210
\endlist
211
212
\sa {Qt Quick 3D - Quick Items Example}, QQuickItem::mapFromGlobal()
213
214
*/
qtquick3d
src
quick3d
doc
src
qtquick3d-2d.qdoc
Generated on
for Qt by
1.14.0