Qt Quick 3D 2D 콘텐츠가 포함된 장면
3D 세계 속의 2D 아이템
Qt Quick 3D 3D 및 2D 요소를 결합한 씬을 효율적으로 생성하고 렌더링할 수 있습니다.
3D-2D 결합 장면이란 무엇을 의미할까요?
본질적으로, 2D 장면에서 3D 뷰포트를 나타내는 View3D 객체는 View3D 객체(이 객체 자체는 Qt Quick Item 입니다)의 주변, 아래 또는 위에 Rectangle, Image, Text와 같은 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 장면은 회색 배경의 영역입니다. 창의 나머지 부분은 2D Qt Quick 항목들로 구성되어 있습니다. 이 항목들은 View3D 와 겹칠 수 있지만, 3D 세계의 일부가 아니며, 3D 좌표계를 사용하지 않고, 3D 장면의 변환에 참여하지도 않습니다.
만약 2D 항목을 3D 세계 내에 배치하여, 모든 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 메시에 텍스처를 적용하려는 경우, 대신 the sourceItem property 또는 Texture 를 사용하십시오.
| 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 ’가 자동으로 생성되어, ‘Rectangle’이 ‘ parent ’을 참조하고 고정(anchoring)을 수행할 수 있게 합니다. 노드(Node)의 3D 변환이 전체 2D 하위 트리에 적용됩니다. 예제에서 이는 회전이 큐브의 회전과 일치함을 의미합니다.
Node {
y: 150
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter2D 및 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 항목으로 전달됩니다. 포인팅 장치로부터의 입력은 선언된 항목(Items)의 childrenRect 내에서 발생해야 합니다.
- 3D 씬에 2D 항목 트리를 추가하는 것은 비교적 부담이 적지만, 3D 씬 내에 과도한 수의(수백 개 이상) 2D 서브트리가 포함되는 것은 피해야 합니다. 이는 대량으로 존재할 경우 메모리 및 그래픽 리소스 사용량이 증가할 수 있기 때문입니다. 이는 3D 노드 아래에 있는 개별 Item 서브트리의 수를 의미하며, 해당 서브트리 내의 2D 아이템 총 개수를 의미하는 것이 아님을 유의하십시오. 예를 들어, 위의 QML 스니펫에는 2D 서브트리가 단 하나만 포함되어 있습니다.
Qt Quick 3D - Quick Items 예제 및 QQuickItem::mapFromGlobal()도 참조하십시오 .
© 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.

