Qt Quick 3D 2D 콘텐츠가 포함된 씬

3D 월드의 2D 아이템

Qt Quick 3D 은 3D와 2D 요소를 결합한 씬을 효율적으로 제작하고 렌더링할 수 있는 기능을 제공합니다.

3D-2D 결합 장면이란 무엇을 의미할까요?

기본적으로 2D 장면에서 3D 뷰포트를 나타내는 View3D 개체는 그 자체가 Qt Quick ItemView3D 항목의 주변, 아래 또는 위에 직사각형, 이미지, 텍스트와 같은 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 변환에 실제로 참여하는 방식으로 포함하려면 어떻게 해야 할까요? 예를 들어 RectangleText 항목을 3D 월드 내에 큐브의 회전을 따라 항상 그 위에 배치하는 방식으로 배치할 수 있을까요?

다음 섹션에서는 이를 달성하는 방법을 살펴보겠습니다. 이 예에서는 RectangleText 을 사용했지만 Qt Quick Controls, Shape, ShaderEffect, ParticleSystem 을 포함한 모든 Qt Quick 콘텐츠는 이러한 방식으로 사용할 수 있습니다.

참고: 2D 콘텐츠를 3D 오브젝트와 통합하는 다른 방법도 있습니다. 2D 항목을 3D 노드에 추가하면 3D 월드에서 2D와 3D 오브젝트를 자유롭게 결합할 수 있지만, 3D 오브젝트의 표면에 2D 콘텐츠를 렌더링할 수는 없습니다. Qt Quick 에서 생성된 콘텐츠로 3D 메시를 텍스처링하는 것이 목표인 경우 Texturethe sourceItem property 을 대신 사용하세요.

Qt Quick 텍스처 맵으로 사용되는 콘텐츠Qt Quick 3D 씬의 항목

3D 노드에 2D 항목 추가

핵심 기능은 Item 자식 객체를 받아들이고 특별한 방식으로 처리하는 Object3D 의 기능입니다. Object3DNode 유형의 기본 클래스입니다. 즉, Node 는 물론 Model 과 같은 유형도 Item 자식을 받아들입니다.

Qt 6.0부터는 2D 항목을 3D 노드에 추가해도 더 이상 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 노드 아래의 최상위 수준 Itemlayer.enabled: true 을 추가하면 됩니다.
  • Qt 6.2부터는 필요에 따라 2D 항목에 입력이 전달됩니다. 포인팅 디바이스로부터의 입력은 선언된 아이템의 childrenRect 내에서 이루어져야 합니다.
  • 3D 씬에 2D 아이템 트리를 추가하는 것은 상당히 저렴하지만, 3D 씬 내에 과도한 양의 2D 서브트리(수백 개 이상)를 추가하면 메모리 및 그래픽 리소스 사용량이 증가할 수 있으므로 피해야 합니다. 이는 3D 노드 아래에 있는 별도의 Item 서브트리 수를 의미하며, 해당 서브트리에 있는 2D 항목의 총 개수를 의미하지 않는다는 점에 유의하세요. 예를 들어 위의 QML 스니펫에는 2D 하위 트리가 하나만 포함되어 있습니다.

Qt Quick 3D - 빠른 항목 예제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.