Introducing Qt 3D
One of the major new features in Qt 5.7.0 is the fully supported release of a stable Qt 3D module! Although Qt has long offered facilities for taking advantage of accelerated graphics and integrating custom OpenGL rendering in Qt-based applications, it has not provided a high-level facility for 3D graphics. Qt 3D now provides this and paves the way for making 3D content a first class citizen in Qt applications.
Qt 3D allows you to quickly and easily build, render and interact with 3D scenes using either C++ or QML APIs. We also provide a custom Qt Quick 2 element called Scene3D that allows you to trivially embed Qt 3D content into a Qt Quick 2 based UI. This allows for the composition of 2D and 3D content to create visually stunning user interfaces for a wide range of domains including automotive IVI, medical, and other visualisations.
Features of Qt 3D
Based on the experience and lessons learned at KDAB helping many of our customers integrate 3D content into their applications Qt 3D has been architected to be more than just a 3D renderer. Qt 3D is a framework for soft realtime simulations – although rendering is still a very important part of this. What does this mean in practice? Well, it means that if Qt 3D doesn’t quite fit your needs, then you can freely extend it to support your use cases. Unlike traditional OOP, Qt 3D is built upon an Entity Component System (ECS) which favours aggregation over deep and wide inheritance hierarchies (see this Overview of Qt 3D for more information).
The ECS architecture also provides a way for us to continue to develop Qt 3D in the future without having to make restrictive assumptions now. As an example, support for collision detection and rigid-body physics simulations can be added in without impacting the renderer at all. We have taken care to ensure that the core architecture of Qt 3D as well as the renderer are as generic as possible.
The Qt3DCore library provides the basic infrastructure that the rest of Qt 3D builds upon. It is a lightweight library but provides a very scalable framework that takes advantage of today’s and tomorrow’s many core hardware. If you create your own aspects for Qt 3D, the core provides you with a very nice task-based threading framework to allow your jobs to be distributed across a thread pool with dependencies between jobs taken care of. Qt 3D’s architecture keeps the main thread as free of heavy work as possible by shifting such work to the thread pool. The Qt3DCore library makes it easy to communicate between the frontend and backend objects.
The Qt3DRender module is a high-level interface to hardware accelerated graphics. At present Qt 3D uses an OpenGL backend but we have left the door open to be able to support more modern APIs such as Vulkan, Metal and DirectX 12 in the future. Qt 3D already supports the vast majority of the OpenGL feature set including compressed textures, instanced rendering, and all shader stages – yes, you can now use OpenGL compute shaders with Qt 3D!
One of the key features of Qt 3D’s renderer is the frame graph concept. The frame graph is a way to specify how a 3D scene is rendered. Traditionally this would be hard-coded in low-level C++ code that implements logic around which groups objects are rendered, in what order, using which specific cameras, what the current render target is etc. We wanted to avoid users having to provide such low level code in order to control the rendering algorithm. The frame graph does this by allowing the developer to specify data that describes the rendering algorithm which Qt 3D then translates into the low level code. The approach is data driven which means that the complete rendering approach can be dynamically changed at run-time and without touching any C++ code at all. For more information on the frame graph concept please take a look at this KDAB blog post.
The Qt3DInput module adds support to Qt 3D for reacting to inputs from the traditional mouse and keyboard devices and also allows extension to support other custom input devices such as 3D mice, gamepads, joysticks and anything supported by the QtGamepad module. Qt3DInput also allows you to map multiple physical devices into logical devices and to get analog axis values out of them for use in property bindings or your own custom C++ code.
One thing you will not find in the above libraries is high-level utilities. This is for two reasons. The first is that we want to keep the renderer and other core facilities as generic as possible. Providing a collection of materials based on the traditional Phong lighting model there would bake in some assumptions that we would then need to live with until Qt 6. The second reason is that some of these higher level facilities depend upon more than one Qt 3D library. For example, the camera controllers depend upon multiple Qt 3D libraries libraries for their implementation.
Whilst the above libraries are all stable, we do still have one Qt 3D library marked as unstable for now. The Qt3DExtras library provides a collection of basic geometries, materials and other utilities and integration points. Whilst we do not expect the facilities provided by Qt3DExtras to change much, we did not yet feel comfortable with freezing the API of these higher level helpers. This compromise makes Qt 3D useable out of the box but on the understanding that the API of these classes may evolve a little in the future. Of course you are also free to write your own specialised set of geometries and materials for your own use cases. We will also continue to develop such higher level primitives and package them up into coherent libraries. For example, we may well decide to provide a set of Physics Based Rendering (PBR) materials as seen in the Qt Automotive Suite, or perhaps a set of classes for generating and manipulating geometric shapes.
The Future of Qt 3D
Qt 3D as released with Qt 5.7.0 is just the beginning. KDAB and The Qt Company recently held a Qt 3D planning session in Oulu. Some of the prominent features that we have planned for future releases include:
- Collision detection
- Key-frame and morph target animation system
- Rigid-body physics simulation
- Qt Quick 2 within Qt 3D
- Use QPainter to paint on textures
- PBR materials
- Dynamic materials
- Support for more input devices
- Build time/design time tooling for asset conditioning
- Profiling and debugging tooling – stand alone and as part of GammaRay
In addition to the above features, there is a proof of concept Qt 3D Scene Editor available for you to try. This editor allows you to graphically compose a 3D scene and export it to QML.
We are also working on a Qt 3d profiler and debugging tool that allows you to see details of the jobs executed on the Qt 3D thread pool along with their timings and to issue commands to introspect the internal Qt 3D engine state.
With this initial release of Qt 3D, we now have a powerful framework and foundation on which to build UIs of the future. Please do take Qt 3D for a spin and let us know what you think. If you are interested in getting involved with writing code or shaders, documentation, examples, producing assets, helping with JIRA, then please do get in touch via the development mailing lists or on IRC at #qt-3d.