Qt Quick 3D - 3D粒子测试平台示例
// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick import QtQuick3D import QtQuick3D.Particles3D Item { id: mainWindow anchors.fill: parent View3D { anchors.fill: parent environment: SceneEnvironment { clearColor: "#202020" backgroundMode: SceneEnvironment.Color antialiasingMode: AppSettings.antialiasingMode antialiasingQuality: AppSettings.antialiasingQuality } PerspectiveCamera { id: camera position: Qt.vector3d(0, 100, 600) } ParticleSystem3D { id: psystem // Particles SpriteParticle3D { id: animated sprite: Texture { source: "images/bear_black.png" } spriteSequence: SpriteSequence3D { frameCount: 13 interpolate: false duration: 2000 durationVariation: 1500 } maxAmount: 4 billboard: true blendMode: SpriteParticle3D.Screen } SpriteParticle3D { id: blended sprite: Texture { source: "images/explosion_01_strip13.png" } spriteSequence: SpriteSequence3D { frameCount: 13 interpolate: true } maxAmount: 26 billboard: true blendMode: SpriteParticle3D.Screen } SpriteParticle3D { id: numberParticle sprite: Texture { source: "images/sprite_09.png" } spriteSequence: SpriteSequence3D { id: numberParticleSequence frameCount: 10 frameIndex: sliderFrameIndex.sliderValue animationDirection: sliderAnimationDirection.sliderValue interpolate: checkBoxInterpolate.checked randomStart: checkBoxRandom.checked duration: sliderDuration.sliderValue durationVariation: sliderDurationVariation.sliderValue } maxAmount: 10 billboard: true blendMode: SpriteParticle3D.Screen } // Emitters, one per particle ParticleEmitter3D { id: emitter1 particle: animated particleScale: 10 position: Qt.vector3d(-300, 0, 0) emitRate: 1 lifeSpan: 4000 shape: ParticleShape3D { fill: true } Node { y: -140 x: -100 Text { anchors.verticalCenter: parent.verticalCenter text: "Animated + durationVariation" font.pointSize: AppSettings.fontSizeLarge color: "#ffffff" } } } ParticleEmitter3D { id: emitter2 particle: blended position: Qt.vector3d(300, -100, 0) particleScale: 20 velocity: VectorDirection3D { direction: Qt.vector3d(0, 100, 0) directionVariation: Qt.vector3d(50, 50, 50) } emitRate: 12 lifeSpan: 2000 lifeSpanVariation: 200 Node { y: -40 x: -100 Text { anchors.verticalCenter: parent.verticalCenter text: "Animated + interpolated" font.pointSize: AppSettings.fontSizeLarge color: "#ffffff" } } } ParticleEmitter3D { id: emitter3 particle: numberParticle particleScale: 8 position: Qt.vector3d(0, 350, 0) emitRate: 2 lifeSpan: 5000 velocity: VectorDirection3D { direction: Qt.vector3d(0, -100, 0) } Node { y: 40 x: -50 Text { anchors.verticalCenter: parent.verticalCenter text: "Controlled" font.pointSize: AppSettings.fontSizeLarge color: "#ffffff" } } } } } SettingsView { CustomLabel { property var enumStrings: ["Normal", "Reverse", "Alternate", "AlternateReverse", "SingleFrame"] text: "Animation Direction: " + enumStrings[numberParticleSequence.animationDirection] } CustomSlider { id: sliderAnimationDirection sliderValue: 0 fromValue: 0 toValue: 4 sliderStepSize: 1 } CustomLabel { text: "Duration" } CustomSlider { id: sliderDuration sliderValue: -1 fromValue: -1 toValue: 8000 } CustomLabel { text: "Duration Variation" } CustomSlider { id: sliderDurationVariation sliderValue: 0 fromValue: 0 toValue: 2000 } CustomCheckBox { id: checkBoxInterpolate text: "Interpolate" checked: false } CustomCheckBox { id: checkBoxRandom text: "Random Start" checked: false } CustomLabel { text: "Frame Index" opacity: checkBoxRandom.checked ? 0.4 : 1.0 } CustomSlider { id: sliderFrameIndex sliderValue: 0 fromValue: 0 toValue: 9 sliderEnabled: !checkBoxRandom.checked sliderStepSize: 1 } } LoggingView { anchors.bottom: parent.bottom particleSystems: [psystem] } }