Qt Quick 3D - Particles 3D Testbed Example
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick3D
import QtQuick3D.Particles3D
import QtQuick.Controls
Item {
anchors.fill: parent
Timer {
id: lightsUpdateTimer
interval: 0
triggeredOnStart: true
onTriggered: updateLightsArray();
}
// Update the lights array of the particles
function updateLightsArray() {
var newLights = [];
if (checkBoxDirectionalLightUse.checked)
newLights.push(lightDirectional);
if (checkBoxPointLightUse.checked)
newLights.push(lightPoint);
if (checkBoxSpotLightUse.checked)
newLights.push(lightSpot);
// Particles to use the enabled lights
spriteParticle.lights = newLights;
}
View3D {
anchors.fill: parent
environment: SceneEnvironment {
clearColor: "#000000"
backgroundMode: SceneEnvironment.Color
antialiasingMode: SceneEnvironment.MSAA
antialiasingQuality: SceneEnvironment.High
}
PerspectiveCamera {
position: Qt.vector3d(0, 100, 700)
eulerRotation.x: -10
}
DirectionalLight {
id: lightDirectional
color: Qt.rgba(1.0, 0.1, 0.1, 1.0)
position: Qt.vector3d(0, 200, 0)
rotation: Quaternion.fromEulerAngles(-70, 0, 0)
visible: checkBoxDirectionalLight.checked
brightness: sliderDirectionalLight.sliderValue
}
PointLight {
id: lightPoint
color: Qt.rgba(0.1, 1.0, 0.1, 1.0)
position: Qt.vector3d(0, 300, 0)
visible: checkBoxPointLight.checked
brightness: sliderPointLight.sliderValue
constantFade: sliderPointLightConstantFade.sliderValue
linearFade: sliderPointLightLinearFade.sliderValue
quadraticFade: sliderPointLightQuadraticFade.sliderValue
SequentialAnimation on x {
loops: Animation.Infinite
NumberAnimation {
to: 400
duration: 2000
easing.type: Easing.InOutQuad
}
NumberAnimation {
to: -400
duration: 2000
easing.type: Easing.InOutQuad
}
}
}
SpotLight {
id: lightSpot
color: Qt.rgba(0.0, 0.0, 1.0, 1.0)
position: Qt.vector3d(0, 250, 0)
eulerRotation.x: -45
visible: checkBoxSpotLight.checked
brightness: sliderSpotLight.sliderValue
coneAngle: 50
innerConeAngle: 20
constantFade: sliderSpotLightConstantFade.sliderValue
linearFade: sliderSpotLightLinearFade.sliderValue
quadraticFade: sliderSpotLightQuadraticFade.sliderValue
PropertyAnimation on eulerRotation.y {
loops: Animation.Infinite
from: 0
to: 360
duration: 10000
}
}
Model {
source: "#Rectangle"
y: -200
scale: Qt.vector3d(15, 15, 15)
eulerRotation.x: -90
materials: [
DefaultMaterial {
diffuseColor: Qt.rgba(0.4, 0.4, 0.4, 1.0)
}
]
}
Model {
source: "#Rectangle"
z: -400
scale: Qt.vector3d(15, 15, 15)
materials: [
DefaultMaterial {
diffuseColor: Qt.rgba(0.4, 0.4, 0.4, 1.0)
}
]
}
ParticleSystem3D {
id: psystem
startTime: 5000
SpriteParticle3D {
id: spriteParticle
sprite: Texture {
source: "images/sphere.png"
}
maxAmount: 10000
color: "#ffffff"
colorVariation: Qt.vector4d(0.0, 0.0, 0.0, 0.5);
fadeInDuration: 1000
fadeOutDuration: 1000
billboard: true
// Disable this to see the unlit particles
blendMode: SpriteParticle3D.Screen
}
ParticleEmitter3D {
id: emitter
particle: spriteParticle
position: Qt.vector3d(0, 350, 0)
depthBias: -100
scale: Qt.vector3d(8.0, 0.0, 8.0)
shape: ParticleShape3D {
type: ParticleShape3D.Sphere
}
particleScale: 2.0
particleScaleVariation: 1.0;
velocity: VectorDirection3D {
direction: Qt.vector3d(0, -100, 0)
directionVariation: Qt.vector3d(20, 50, 20)
}
emitRate: 2000
lifeSpan: 5000
}
PointRotator3D {
pivotPoint: Qt.vector3d(0, 0, 0)
direction: Qt.vector3d(0, 1, 0)
magnitude: 20
}
}
}
SettingsView {
CustomCheckBox {
id: checkBoxDirectionalLight
text: qsTr("Directional Light")
checked: true
}
CustomSlider {
id: sliderDirectionalLight
sliderValue: 0.4
fromValue: 0.0
toValue: 1
}
CustomCheckBox {
id: checkBoxDirectionalLightUse
text: qsTr("Use also for particles")
checked: true
onCheckedChanged: lightsUpdateTimer.restart();
}
Item { width: 1; height: 40 }
CustomCheckBox {
id: checkBoxPointLight
text: qsTr("Point Light")
checked: true
}
CustomSlider {
id: sliderPointLight
sliderValue: 6
fromValue: 0.0
toValue: 10
}
CustomCheckBox {
id: checkBoxPointLightUse
text: qsTr("Use also for particles")
checked: true
onCheckedChanged: lightsUpdateTimer.restart();
}
CustomLabel {
text: qsTr("constantFade")
}
CustomSlider {
id: sliderPointLightConstantFade
sliderValue: 1.0
fromValue: 0.1
toValue: 20.0
}
CustomLabel {
text: qsTr("linearFade")
}
CustomSlider {
id: sliderPointLightLinearFade
sliderValue: 0.0
fromValue: 0.0
toValue: 20.0
}
CustomLabel {
text: qsTr("quadraticFade")
}
CustomSlider {
id: sliderPointLightQuadraticFade
sliderValue: 1.0
fromValue: 0.1
toValue: 20.0
}
Item { width: 1; height: 40 }
CustomCheckBox {
id: checkBoxSpotLight
text: qsTr("Spot Light")
checked: true
}
CustomSlider {
id: sliderSpotLight
sliderValue: 40
fromValue: 0.0
toValue: 100
}
CustomCheckBox {
id: checkBoxSpotLightUse
text: qsTr("Use also for particles")
checked: true
onCheckedChanged: lightsUpdateTimer.restart();
}
CustomLabel {
text: qsTr("constantFade")
}
CustomSlider {
id: sliderSpotLightConstantFade
sliderValue: 1.0
fromValue: 0.1
toValue: 20.0
}
CustomLabel {
text: qsTr("linearFade")
}
CustomSlider {
id: sliderSpotLightLinearFade
sliderValue: 0.0
fromValue: 0.0
toValue: 20.0
}
CustomLabel {
text: qsTr("quadraticFade")
}
CustomSlider {
id: sliderSpotLightQuadraticFade
sliderValue: 1.0
fromValue: 0.1
toValue: 20.0
}
}
LoggingView {
anchors.bottom: parent.bottom
particleSystems: [psystem]
}
}