Introducing Qt Quick 3D Particles

As you may have already seen or heard, Qt Quick 3D introduces support for 3D particles in Qt 6.1. Similarly to instanced rendering , also 3D particles module is a technology preview in Qt 6.1 and will be fully supported in Qt 6.2. In this blog post we'll go through things every developer & designer should know about the new 3D particles, so please continue reading. With the visual elements such as particles, it is always beneficial to actually see what you can do with them. The video below goes through some demos from our Testbed application, included as part of the Qt 6.1 examples.

Usage

If you are familiar with the Qt Quick particles module, you should feel comfortable also with the 3D particles. As a start, instead of "import QtQuick.Particles", you will use "import QtQuick3D.Particles3D" in the beginning of your QML files. Here is a QML code for a simple particle system with a single logical particle, an emitter and an affector:

ParticleSystem3D {
    SpriteParticle3D {
        id: starParticle
        sprite: Texture {
            source: "images/star.png"
        }
        maxAmount: 200
        color: "#ffff00"
        particleScale: 20.0
        fadeOutDuration: 500
        billboard: true
    }
    ParticleEmitter3D {
        particle: starParticle
        velocity: VectorDirection3D {
            direction: Qt.vector3d(100, 200, 0)
            directionVariation: Qt.vector3d(20, 20, 20)
        }
        particleScaleVariation: 0.4
        emitRate: 50
        lifeSpan: 4000
    }
    Gravity3D {
        magnitude: 100
    }
}

When you run the example above, you will see something like this:

particles_example1_output

Or, if you replace the SpriteParticle3D with a ModelParticle3D to get 3D particles and add some color & rotation variation, the output would look like this:

particles_example2_output

So let's go through some aspects of our simple example:

  • ParticleSystem3D is the root of the particle system. It handles the system timing and groups all the other related elements like particles, emitters, and affectors together. Compared to Qt Quick ParticleSystem , one neat feature of the ParticleSystem3D is that you can freely animate the time, which allows for example to synchronize particles with other animations. Another feature which especially designers enjoy, is that particles system can be randomized with a specific seed to get identical pixel-perfect particles effect on every run.

  • Two different logical particle types are supported: SpriteParticle3D for 2D texture particles and ModelParticle3D for 3D model particles. Model particles actually use instanced rendering to allow rendering thousands of particles, with full Quick 3D materials and lights support. Logical particle will define the common appearance of the particles. One important property is maxAmount , which is used for allocating the data for particles. Qt Quick particles don't have this feature, but instead they automatically grow the data based on emitRate, lifeSpan and bursts. Requiring it to be defined allows us to optimize the memory usage and to modify the emitRate and lifeSpan without reallocations

  • ParticleEmitter3D handles the actual emitting of the particles. There are many properties to define what the individual particles will look like and how they are emitted. Many of the properties have Variation counterparts, for adding disparity among the particles. To emit particles from another particles, you can use TrailEmitter3D.

  • There are currently 4 different affectors for controlling how the particles animate during their lifetime, and more will be likely added in the future. Here we use the Gravity3D affector, with a magnitude to drag the particles down.

To learn more, please check the Particles3D API documentation and documentation of the Testbed example

Performance Notes

As with all Qt modules, performance has been one of the key aspects of the new 3D particles module. After all, we want the particles to be usable on a variety of hardware, on desktops, mobile and embedded devices. That said, it is not just about rendering the maximum amount of particle elements on the screen. Easy to use API, extensibilty to different use-cases, rendering quality, integration with the other UI elements etc. are also important for us.

Currently, the rendering runs on GPU, while the particle system logic runs on CPU. We are using a so-called stateless particle system, which allows moving also system logic on GPU, if that seems beneficial. The intial measurements indicate that we are quite well balanced between CPU & GPU. Our stateless system also allows for better tooling integration in the future, as particles can be animated on a timeline (as an example of this, see the Testbed "Qt Cube Burst"). And as already mentioned, the model particles utilize instanced rendering to boost the performance. That means OpenGL ES 2.0 unfortunately isn't enough, at least OpenGL ES 3.0, Vulkan etc. modern backend is required so that we can make the rendering performant.

To get a more concrete view on the actual performance, the video below shows the particles Testbed application running on 4 different Android devices. These devices and their chipsets & GPUs could be considered to be lower-end / mid-range, confirming that the particles can perform well also on more affordable hardware.

What about Qt Quick (2D) particles?

The 2D Qt Quick particles module is still fully supported in Qt 6, so no need to worry about that. Laszlo Agocs has ported the particles module to QRhi so it works on all the Qt 6 supported rendering backends (OpenGL, Vulkan, Metal, and D3D11). Myself and other community members have also made different cleanups, bug fixes and optimizations. So actually Qt Quick particles on Qt 6 are better than ever, just continue using them with your 2D Qt Quick particle UIs.

What's next?

If you are reading this, and haven't yet downloaded the latest Qt 6.1 release, please do it now. You can run the particles Testbed example to get an idea what it currently offers and look into the source code. Then you can experiment with the 3D particles yourself, create wild effects with your own designs. And the most important request: Please provide us feedback with Jira tickets , so we can improve the 3D particles module to suit your needs in the future Qt releases. Thanks!


Blog Topics:

Comments

Commenting for this post has ended.

K
Kelteseth
0 points
48 months ago

So QtQuick3d now becomes a full 3d engine. That is cool but can you guys tell me what of the multiple 3d engines should we use? We now have a very active QtQuick3d, a not very active Qt3d (at least according to the latest commits), Qt 3d Studio engine. Is this blog post still valid: https://www.qt.io/blog/the-future-of-qt-3d ? To me, it looks like the Qt company wants to establish QtQuick3d as the de facto standard for 3d, but it still looks strange from the outside having multiple 3d engines that have a different feature set, do the same in some regards and are completely different in others.

Thanks!

Andy Nichols
1 point
48 months ago

Qt Quick 3D along with Qt Design Studio does replace Qt 3D Studio in Qt 6. Qt Quick 3D and Qt3D is more of an apples to oranges comparison. Yes they both involve 3D, but Qt Quick 3D is a higher level solution, where as Qt3D is a more of a bespoke solution for creating 3D runtimes. The Qt Company has a large development team focused on Qt Quick 3D, and Qt3D is done by KDAB to serve different use cases. Both of these projects live under the Qt Project umbrella. Yes I see that is a bit messy from a product standpoint, but from the Qt Company perspective Qt Quick 3D is the solution for high level 3D content we will actively continue to develop going forward.

G
Gil Hagi
1 point
48 months ago

Since the two 3D modules don't share anything in common, it's a really costly decision for someone to adopt one and then want to switch to the other. For example, Qt Quick 3D seemed like a great choice a year ago, until we ran into it being absent from iOS. Or was missing support for loading models at runtime in an editor-type experience like 3D Studio itself. These issues have recently been solved, but can you imagine being a developer a year ago having to redo everything in Qt3D because of some missing capability, then being faced with the prospect of porting back to QQuick3D? What if some other missing piece of functionality is discovered? The problem, I think, is that the architecture of Qt3D was fundamentally broken, and at the time when QQuick3D started, the decision must have been made to have nothing in common. Qt3D seems better now, but this historical decision now splintered the two, making the cost of switching high. If the difference was merely one being powerful and flexible, and the other being high level, then the latter would be an abstraction built on top of the former, and they would at least have a common data representation. Do you think a common scene representation is a worthwhile goal, in order to reduce the risk for clients adopting one or the other?

K
Kelteseth
0 points
48 months ago

Alright thanks for the info! Do you know if Qt Quick3d be available one day on the Qt Marketplace as a separate purchase?

Alex G
0 points
48 months ago

The big problem i see with quick3d is it's not possible to use it in a widgets app?

Andy Nichols
0 points
48 months ago

It's possible to embedded Qt Quick content in Widget content via QQuickWidget. There isn't any direct widget support because Qt Quick 3D depends on the runtime components of Qt Quick (rendering, animation, etc) . If the issue is just the lack of C++ API's in Qt Quick then that is something that is being worked on as part of Qt Quick as a whole currently, but even then Qt Quick and Qt Widgets work in fundamentally different ways and that won't really change if we support doing more Qt Quick stuff from C++.

Malek Khlif
0 points
48 months ago

Can we integrate Unreal Engine in Qt Quick ? Or can we integrate Qt Quick in Unreal engine ?

Homero Javier Oria Aguilera
0 points
48 months ago

Good question! Unreal Engine lacks good UI components like Qt Quick has.

T
Tuukka Turunen
0 points
48 months ago

@Malek: It is possible to use an external 3D engine with Qt. There are some drawbacks compared to using the built-in Qt Quick 3D engine (syncing, overhead, ...)

Malek Khlif
0 points
48 months ago

@Tuukka: Thank you for your reply. Can you please give me some guide how we integrate it ? I am not able to find in the internet any tuto to do that.

T
Tuukka Turunen
0 points
48 months ago

@Malek: Hooking up with an external 3D engine is not trivial. I do not think there is any tutorial available on that - and it is not something that users in general need to do as there are already 3D engine(s) available within Qt.

Homero Javier Oria Aguilera
0 points
48 months ago

It would be nice to read a detailed article in this blog about the differences between Qt Quick 3D and Qt 3D. Qt3D has a strong learning curve. I think if you do not have good programming graphics background or a paid course with KDAB it is a dead end. Yes, Andy Nichols has good answers but I mean: 1. What are the main uses of each technology? 2. Consider the following use case: I want to represent a heavy point cloud (10 million to 20 million points), and do some operations in it (cut, crop, represent meshes, manipulate vertex dynamically ...), what should I use: Qt Quick 3D or Qt3D? 2. And please, it would be nice a proper Qt Quick 3D's doc, unlike Qt3D docs.

T
Tuukka Turunen
0 points
48 months ago

@Homero: Documentation is never perfect and more tutorials would certainly be valuable. You can check the basics of Qt Quick 3D from https://doc.qt.io/qt-6/qtquick3d-index.html.

Homero Javier Oria Aguilera
0 points
48 months ago

@Tukka Turunen I think I expressed wrong. The current Qt Quick 3D doc is pretty good, with a lot of examples. Keep coming!

Kaj Grönholm
0 points
48 months ago

Good discussion and questions here, thanks!

Regarding the Qt Quick 3D and Qt 3D differences, Andy did a good summary already in the Quick 3D introduction post ( https://www.qt.io/blog/2019/08/14/introducing-qt-quick-3d-high-level-3d-api-qt-quick ) and KDAB has continued improving the Qt 3D on Qt 6 ( https://www.kdab.com/qt3d-renderer-qt6/ ). If you ask my personal opinion, I would refer the beloved 80-20 rule: Qt Quick 3D is a better first choice for 80% of common users. But being on a higher level may mean that its QML API (there isn't a public C++ API available at least yet) doesn't tick all the boxes. For those use-cases, lower level Qt 3D would be the next logical option. Having more choices isn't always a bad thing.. ;-)