Различные статьи по Qt и c++

Qt6 и модуль Qt Quick 3D: что нового для 3D-интерфейсов

Qt Quick 3D — это декларативный модуль для построения 3D-сцен на QML, появившийся ещё в Qt 5.15 в техническом превью и получивший полноценную поддержку в Qt6. В отличие от прямой работы с OpenGL/Vulkan API, Qt Quick 3D позволяет описывать 3D-объекты, материалы, камеры и свет так же, как обычный QML-интерфейс — декларативно, с привязками свойств (property bindings) и анимациями.

Зачем нужен Qt Quick 3D

Раньше для встраивания 3D-контента в Qt-приложение приходилось либо писать собственный рендерер на OpenGL через QOpenGLWidget, либо интегрировать сторонние движки. Qt Quick 3D даёт готовый набор примитивов (куб, сфера, плоскость), систему материалов на основе PBR (Physically Based Rendering), поддержку импорта моделей через balsam (конвертер glTF/FBX в формат Qt Quick 3D) и интеграцию с обычным 2D QML-интерфейсом.

Минимальный пример: вращающийся куб

// main.qml
import QtQuick
import QtQuick.Window
import QtQuick3D

Window {
    id: window
    visible: true
    width: 800
    height: 600
    title: "Qt Quick 3D Demo"

    View3D {
        anchors.fill: parent

        environment: SceneEnvironment {
            clearColor: "#202020"
            backgroundMode: SceneEnvironment.Color
        }

        // Камера
        PerspectiveCamera {
            id: camera
            position: Qt.vector3d(0, 200, 400)
            eulerRotation.x: -20
        }

        // Источник света
        DirectionalLight {
            eulerRotation.x: -30
            brightness: 1.2
        }

        // 3D-объект
        Model {
            id: cube
            source: "#Cube"
            scale: Qt.vector3d(1.5, 1.5, 1.5)

            materials: PrincipledMaterial {
                baseColor: "orange"
                roughness: 0.3
                metalness: 0.1
            }

            // Бесконечное вращение через стандартную QML-анимацию
            NumberAnimation on eulerRotation.y {
                from: 0; to: 360
                duration: 4000
                loops: Animation.Infinite
            }
        }
    }
}

Пояснения к коду

  • View3D — корневой элемент, который встраивает 3D-сцену в обычное 2D-окно QML; его можно располагать рядом с другими QML-компонентами (кнопками, текстом) как обычный Item.
  • SceneEnvironment задаёт фон сцены и параметры постобработки (тонмаппинг, сглаживание, AO).
  • PerspectiveCamera — камера с перспективной проекцией; есть также OrthographicCamera.
  • Model с source: "#Cube" использует встроенный примитив — доступны также #Sphere, #Cone, #Cylinder, #Plane.
  • PrincipledMaterial — современный PBR-материал, аналог материалов в Blender/Unreal Engine: задаются базовый цвет, шероховатость (roughness) и металличность (metalness).
  • Анимация eulerRotation.y использует стандартный QML NumberAnimation — это показывает, как тесно 3D-объекты интегрированы с обычной системой анимации QtQuick.

Импорт собственных 3D-моделей

Для использования моделей, созданных в Blender или другом 3D-редакторе, используется инструмент balsam, который конвертирует glTF2/FBX в формат .qml + .mesh:

balsam -o assets/ model.gltf

После конвертации модель подключается так:

import QtQuick3D

// assets/Model.qml сгенерирован balsam
Model {
    source: "assets/meshes/model.mesh"
    materials: [ /* материалы из сгенерированного файла */ ]
}

Интеграция 2D и 3D интерфейса

Типичный сценарий — наложение обычного UI (кнопки, HUD) над 3D-сценой:

Window {
    visible: true
    width: 800; height: 600

    View3D {
        id: scene3d
        anchors.fill: parent
        // ... содержимое сцены
    }

    // 2D-интерфейс поверх 3D-вида
    Column {
        anchors.top: parent.top
        anchors.right: parent.right
        anchors.margins: 16
        spacing: 8

        Button {
            text: "Сбросить камеру"
            onClicked: camera.position = Qt.vector3d(0, 200, 400)
        }
    }
}

Подводные камни

  • Производительность на встраиваемых системах. Qt Quick 3D опирается на RHI и требует GPU с поддержкой шейдеров уровня OpenGL ES 3.0/Direct3D 11 — на слабом встроенном железе сцены с большим количеством материалов могут заметно проседать по FPS.
  • Антиалиасинг по умолчанию выключен — для качественной картинки нужно явно включать antialiasingMode в SceneEnvironment.
  • Тени включаются на каждом источнике света отдельно (castsShadow: true) и заметно нагружают рендер — используйте их избирательно.
  • balsam не всегда идеально конвертирует сложные материалы — анимированные текстуры и сложные node-материалы из Blender могут потребовать ручной донастройки.
  • Модуль QtQuick3D.Helpers содержит полезные debug-инструменты (DebugView, WasdController), которые удобны на этапе разработки, но их не стоит оставлять в продакшен-сборке.

Совет

Если 3D-контент нужен только для отдельных элементов интерфейса (например, превью 3D-модели товара), не обязательно превращать всё приложение в 3D-сцену: View3D можно использовать локально, как обычный QML-компонент, ограниченный конкретной областью экрана.

================================================================================