이 페이지에서

Qt 3D: 와이어프레임 QML 예제

단일 패스 와이어프레임 렌더링 방식을 구현한 ‘ Qt 3D ’ QML 애플리케이션입니다.

삼각형 메쉬로 구성된 빨간색 토러스 매듭의 3D 와이어프레임 렌더링

Qt 3D '와이어프레임 렌더링' 예제는 사용자 정의 셰이더 세트를 사용하여 단일 엔티티(트레포일 매듭)를 그리는 방법을 보여줌으로써, 단일 패스 와이어프레임 렌더링 방식을 구현하는 방법을 설명합니다.

예제 실행

다음 위치에서 예제를 실행할 수 있습니다:

엔티티 생성

렌더러 측면에서는 지오메트리, 머티리얼, 그리고 선택적으로 변환을 가진 엔티티를 찾습니다. 이 모든 것은 Mesh, Material, Transform 형태로 QML 엔진에 내보내진 QComponent의 서브클래스 형태로 지정됩니다. 우리는 이러한 컴포넌트를 사용하여 TrefoilKnot.qml에서 사용자 정의 QML 항목을 생성합니다.

먼저, Entity 유형과 Qt.vector3d()와 같은 값 유형 헬퍼를 제공하는 Qt3D 2.0 모듈을 임포트합니다. 또한 렌더러 어스펙트가 가져오는 컴포넌트 및 기타 유형을 제공하는 Qt3D.Renderer 모듈도 임포트합니다:

import Qt3D.Core 2.0
import Qt3D.Render 2.0

다른 어스펙트의 컴포넌트를 사용하려면 해당 QML 모듈도 함께 가져와야 합니다.

그런 다음 Entity 타입을 사용자 정의 QML 타입의 루트 요소로 사용하여, QML의 다른 타입과 마찬가지로 몇 가지 사용자 정의 속성을 노출시킵니다:

Entity {
    id: root

    property real x: 0.0
    property real y: 0.0
    property real z: 0.0
    property real scale: 1.0
    property real theta: 0.0
    property real phi: 0.0
    property Material material

Entity 유형은 컴포넌트를 집계하는 것 외에도 자식 객체들을 그룹화하는 데 사용할 수 있습니다. 이는 Qt Quick 2에서 Item 유형이 사용되는 방식과 유사합니다.

변환 지정

Transform 컴포넌트와 Mesh 컴포넌스를 인스턴스화합니다. Transform 컴포넌트는 OpenGL 파이프라인을 통해 지오메트리가 그려질 때 렌더러가 지오메트리를 어떻게 변환해야 하는지 지정합니다. 순서가 정해진 변환 집합을 단일 Transform 컴포넌트로 결합합니다. 이 정보는 표준 명명된 유니폼 변수를 통해 셰이더에서 자동으로 사용할 수 있게 됩니다:

    Transform {
        id: transform
        translation: Qt.vector3d(root.x, root.y, root.z)
        rotation: fromEulerAngles(theta, phi, 0)
        scale: root.scale
    }

동적 정점별 데이터 불러오기

Mesh 컴포넌트는 매우 간단합니다. 이 컴포넌트의 source 속성을 사용하여 Wavefront Obj 형식의 파일에서 정적 지오메트리 집합(버텍스 위치, 법선 벡터, 텍스처 좌표 등)을 불러옵니다. 이 데이터는 Blender 애플리케이션에서 내보낸 것입니다.

    Mesh {
        id: mesh
        source: "qrc:/assets/obj/trefoil.obj"
    }

Mesh 요소 외에도, Qt 3D 는 태스크 기반 엔진에 의해 호출되는 C++ 후크를 통해 정점별 속성 데이터를 동적으로 생성할 수 있도록 지원합니다.

컴포넌트 통합

그러나 단순히 컴포넌트를 인스턴스화하는 것만으로는 충분하지 않습니다. 컴포넌트가 엔티티에 특수한 동작을 부여하려면, 엔티티가 components 속성을 통해 컴포넌트를 통합해야 합니다:

    components: [ transform, mesh, root.material ]

이를 통해 여러 엔티티 간에 컴포넌트를 매우 쉽게 공유할 수 있습니다. 이 예제에서는 TrefoilKnot 사용자 정의 유형 내에 포함된 트랜스폼 및 메시용 컴포넌트가 있습니다. 마지막 컴포넌트인 ` Material` 유형은 TrefoilKnot 사용자 정의 유형의 속성을 통해 제공됩니다. 나중에 이 엔티티의 외관을 사용자 정의할 것입니다.

카메라를 통한 렌더링

main. qml에서 TrefoilKnot 사용자 정의 타입을 사용하여 화면에 트레포일 매듭을 그립니다.

TrefoilKnot.qml에서와 동일한 임포트 문장을 사용하며, 애니메이션에 필요한 Qt Quick 모듈에 대한 네임스페이스 임포트를 추가합니다:

import QtQuick 2.1 as QQ2
import Qt3D.Core 2.0
import Qt3D.Render 2.0

Entity 타입을 루트 타입으로 사용하는 이유는 단순히 자식 요소들의 부모 역할을 하기 위함입니다. 이러한 의미에서 Entity 타입은 Item 타입과 매우 유사합니다:

import Qt3D.Input 2.0
import Qt3D.Extras 2.0

Entity {
    id: root

RendererSettings 컴포넌트는 C++ 코드를 전혀 건드리지 않고 렌더러를 완전히 구성하기 위해 ForwardRenderer 타입을 사용합니다:

    // Render from the mainCamera
    components: [
        RenderSettings {
            activeFrameGraph: ForwardRenderer {
                id: renderer
                camera: mainCamera
            }
        },
        // Event Source will be set by the Qt3DQuickWindow
        InputSettings { }
    ]

BasicCamera 타입은 가상 카메라를 나타내는 내장 Camera 타입을 감싸는 간단한 래퍼입니다. 이 타입에는 근점 및 원점 평면, 시야각, 종횡비, 투영 유형, 위치, 방향 등과 같은 속성이 있습니다:

    BasicCamera {
        id: mainCamera
        position: Qt.vector3d( 0.0, 0.0, 15.0 )
    }

Configuration 타입은 어스펙트와 컴포넌트를 사용하는 적절한 구현이 완료될 때까지 카메라를 마우스로 제어할 수 있도록 하는 임시 해결책입니다:

    FirstPersonCameraController { camera: mainCamera }

여러 대의 카메라를 사용하고, 장면 렌더링의 전체 또는 일부에 대해 프레임그래프를 통해 카메라를 선택하는 것은 매우 간단합니다.

매터리얼 매핑

Qt 3D 는 여러 단계의 사용자 지정이 가능한 견고하고 매우 유연한 머티리얼 시스템을 갖추고 있습니다. 우리는 `WireframeMaterial` 사용자 정의 타입을 사용하여 ` Material ` 타입을 래핑합니다:

    WireframeMaterial {
        id: wireframeMaterial
        effect: WireframeEffect {}
        ambient: Qt.rgba( 0.2, 0.0, 0.0, 1.0 )
        diffuse: Qt.rgba( 0.8, 0.0, 0.0, 1.0 )

그런 다음 TrefoilKnot 타입을 인스턴스화하고 해당 타입에 머티리얼을 설정합니다:

    TrefoilKnot {
        id: trefoilKnot
        material: wireframeMaterial
    }

Qt 3D 엔진은 렌더러 어스펙트와 연동되어, 이제 우리가 지정한 머티리얼을 사용하여 메쉬를 최종적으로 렌더링하는 데 필요한 충분한 정보를 확보하게 되었습니다.

애니메이션 요소 사용

Qt Quick 2에서 제공하는 애니메이션 요소를 사용하여 TrefoilKnot 및 WireframeMaterial 타입의 속성을 애니메이션화합니다. 타입의 구성 요소 속성은 QML 속성 바인딩 메커니즘을 사용하여 업데이트됩니다:

        QQ2.SequentialAnimation {
            loops: QQ2.Animation.Infinite
            running: true

            QQ2.NumberAnimation {
                target: wireframeMaterial;
                property: "lineWidth";
                duration: 1000;
                from: 0.8
                to: 1.8
            }

            QQ2.NumberAnimation {
                target: wireframeMaterial;
                property: "lineWidth";
                duration: 1000;
                from: 1.8
                to: 0.8
            }

            QQ2.PauseAnimation { duration: 1500 }
        }

속성 업데이트는 QNode 기본 클래스에 의해 감지되어 렌더러 측면의 해당 객체들로 자동으로 전달됩니다. 그런 다음 렌더러는 속성 업데이트를 GLSL 셰이더 프로그램 내의 균일 변수(uniform variables)에 대한 새로운 값으로 변환하는 작업을 처리합니다.

예제를 실행하면 와이어프레임 선의 너비가 맥동하는 트레포일 매듭을 볼 수 있습니다. 모든 중량 작업은 GPU에서 처리됩니다. CPU는 속성 애니메이션을 실행하고, 씬그래프와 프레임그래프를 원시 OpenGL 호출로 변환하는 역할만 수행하면 됩니다.

사용자 정의 셰이더 프로그램과 머티리얼을 통해 GPU에서 애니메이션을 구현하는 것도 가능합니다.

예제 프로젝트 @ code.qt.io

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