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использует стандартный QMLNumberAnimation— это показывает, как тесно 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-компонент, ограниченный конкретной областью экрана.
================================================================================