summaryrefslogtreecommitdiffstats
path: root/examples/qt3d
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2015-12-08 09:01:15 +0100
committerSean Harmer <sean.harmer@kdab.com>2016-01-14 21:36:00 +0000
commit4a44b6520ff8add3dd65be6224fd7410e5405939 (patch)
tree13a5a4a3df1cc3f7059afc7f8f55286f434f26e6 /examples/qt3d
parent08ad89dde168476c8e7045b84785f26eb8c8bc7a (diff)
Add a compute shader example
Change-Id: I956b647e2218ad3e604bd9e8260b3ea0a90dc84e Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'examples/qt3d')
-rw-r--r--examples/qt3d/compute-particles/ComputeFrameGraph.qml69
-rw-r--r--examples/qt3d/compute-particles/ComputeMaterial.qml108
-rw-r--r--examples/qt3d/compute-particles/ParticlesScene.qml230
-rw-r--r--examples/qt3d/compute-particles/compute-particles.pro14
-rw-r--r--examples/qt3d/compute-particles/compute-particles.qrc11
-rw-r--r--examples/qt3d/compute-particles/main.cpp52
-rw-r--r--examples/qt3d/compute-particles/main.qml132
-rw-r--r--examples/qt3d/compute-particles/particles.comp41
-rw-r--r--examples/qt3d/compute-particles/particles.frag33
-rw-r--r--examples/qt3d/compute-particles/particles.vert27
-rw-r--r--examples/qt3d/qt3d.pro3
11 files changed, 719 insertions, 1 deletions
diff --git a/examples/qt3d/compute-particles/ComputeFrameGraph.qml b/examples/qt3d/compute-particles/ComputeFrameGraph.qml
new file mode 100644
index 000000000..08782d93f
--- /dev/null
+++ b/examples/qt3d/compute-particles/ComputeFrameGraph.qml
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+
+Viewport {
+ property alias camera: selector.camera
+
+ // Clear Buffer
+ ClearBuffer {
+ buffers: ClearBuffer.ColorDepthBuffer
+ NoDraw {}
+ }
+
+ // Compute Pass
+ DispatchCompute {
+ workGroupX: 1024; workGroupY: 1; workGroupZ: 1
+ TechniqueFilter {
+ requires: [
+ Annotation { name: "type"; value: "compute"}
+ ]
+ }
+ }
+
+ // Draw particles from buffer computed in the Compute Pass
+ CameraSelector {
+ id: selector
+ TechniqueFilter {
+ requires: [
+ Annotation { name: "type"; value: "draw"}
+ ]
+ }
+ }
+}
+
diff --git a/examples/qt3d/compute-particles/ComputeMaterial.qml b/examples/qt3d/compute-particles/ComputeMaterial.qml
new file mode 100644
index 000000000..d91d15b3c
--- /dev/null
+++ b/examples/qt3d/compute-particles/ComputeMaterial.qml
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+
+Material {
+ property Buffer dataBuffer;
+ property real particleStep: 0.4
+ property real finalCollisionFactor: 0.2
+
+ parameters: [
+ Parameter { name: "particleStep"; value: particleStep },
+ Parameter { name: "finalCollisionFactor"; value: finalCollisionFactor }
+ ]
+
+ ShaderProgram {
+ id: computeShader
+ computeShaderCode: loadSource("qrc:/particles.comp")
+ }
+
+ ShaderProgram {
+ id: drawShader
+ vertexShaderCode: loadSource("qrc:/particles.vert")
+ fragmentShaderCode: loadSource("qrc:/particles.frag")
+ }
+
+ effect: Effect {
+ techniques: [
+ Technique {
+ renderPasses: [
+ RenderPass {
+ shaderProgram: computeShader
+ // We set the buffer as the parameter data
+ parameters: [
+ Parameter { name: "Particles"; value: dataBuffer }
+ ]
+ }
+ ]
+ annotations: [
+ Annotation { name: "type"; value: "compute" }
+ ]
+ graphicsApiFilter {
+ api: GraphicsApiFilter.OpenGL
+ profile: GraphicsApiFilter.CoreProfile
+ majorVersion: 4
+ minorVersion: 3
+ }
+ },
+ Technique {
+ renderPasses: [
+ RenderPass {
+ shaderProgram: drawShader
+ // We assume the mesh to be drawn will also receive
+ // Vertex buffers attributes that will be used to position and color
+ bindings: [
+ ParameterMapping { parameterName: "particlePosition"; shaderVariableName: "particlePosition"; bindingType: ParameterMapping.Attribute },
+ ParameterMapping { parameterName: "particleColor"; shaderVariableName: "particleColor"; bindingType: ParameterMapping.Attribute }
+ ]
+ }
+ ]
+ annotations: [
+ Annotation { name: "type"; value: "draw" }
+ ]
+ graphicsApiFilter {
+ api: GraphicsApiFilter.OpenGL
+ profile: GraphicsApiFilter.CoreProfile
+ majorVersion: 4
+ minorVersion: 3
+ }
+ }
+ ] // techniques
+ }
+}
+
diff --git a/examples/qt3d/compute-particles/ParticlesScene.qml b/examples/qt3d/compute-particles/ParticlesScene.qml
new file mode 100644
index 000000000..f1472e178
--- /dev/null
+++ b/examples/qt3d/compute-particles/ParticlesScene.qml
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+
+Entity {
+ property alias particleStep: computeMaterial.particleStep
+ property alias finalCollisionFactor: computeMaterial.finalCollisionFactor
+
+ readonly property int _SPHERE: 0
+ readonly property int _CUBE: 1
+ readonly property int _CYLINDER: 2
+ readonly property int _TORUS: 3
+
+ property int particlesShape: _SPHERE
+
+ signal reset()
+
+ components: [
+ FrameGraph {
+ ComputeFrameGraph {
+ camera: sceneCamera
+ }
+ }
+ ]
+
+ Configuration {
+ controlledCamera: sceneCamera
+ }
+
+ Camera {
+ id: sceneCamera
+ projectionType: CameraLens.PerspectiveProjection
+ viewCenter: Qt.vector3d(0, 0, 0)
+ position: Qt.vector3d(0, 0, -800)
+ nearPlane: 0.1
+ farPlane: 1000
+ fieldOfView: 25
+ aspectRatio: 1.33
+ }
+
+ property int particlesCount: 50 * 1024
+ readonly property int floatSize: 4
+
+ function buildParticlesBuffer() {
+ var bufferData = new Float32Array(particlesCount * 4 * 3);
+ var factor = 500.0;
+ for (var i = 0; i < particlesCount; ++i) {
+ var positionIdx = i * 12;
+ var velocityIdx = i * 12 + 4;
+ var colorIdx = i * 12 + 8;
+
+ for (var j = 0; j < 3; ++j) {
+ bufferData[positionIdx + j] = (Math.random() - 0.5) * factor;
+ bufferData[velocityIdx + j] = Math.random() * 2.0;
+ bufferData[colorIdx + j] = 0.75 + Math.sin(((i / 1024.0) + j * 0.333) * 6.0) * 0.25;
+ }
+
+ bufferData[positionIdx + 3] = 1.0;
+ bufferData[velocityIdx + 3] = 0.0;
+ bufferData[colorIdx + 3] = 1.0;
+ }
+ return bufferData
+ }
+
+ Buffer {
+ id: particleBuffer
+ type: Buffer.VertexBuffer
+ // struct ParticleData
+ // {
+ // vec3 position; // Aligned to 4 floats
+ // vec3 velocity; // Aligned to 4 floats
+ // vec3 color; // Aligned to 4 floats
+ // };
+ data: buildParticlesBuffer()
+ }
+
+ onReset : {
+ particleBuffer.data = buildParticlesBuffer()
+ }
+
+ Attribute {
+ id: particlePositionDataAttribute
+ name: "particlePosition"
+ attributeType: Attribute.VertexAttribute
+ dataType: Attribute.Float
+ dataSize: 3
+ divisor: 1
+ byteStride: 12 * floatSize
+ buffer: particleBuffer
+ }
+
+ Attribute {
+ id: particleColorDataAttribute
+ name: "particleColor"
+ attributeType: Attribute.VertexAttribute
+ dataType: Attribute.Float
+ dataSize: 3
+ divisor: 1
+ byteOffset: 8 * floatSize
+ byteStride: 12 * floatSize
+ buffer: particleBuffer
+ }
+
+ ComputeMaterial {
+ id: computeMaterial
+ dataBuffer: particleBuffer
+ }
+
+ Entity {
+ id: particleComputeEntity
+ readonly property ComputeJob particlesComputeJob: ComputeJob {}
+ components: [
+ particlesComputeJob,
+ computeMaterial
+ ]
+ }
+
+ SphereGeometry {
+ id: sphereGeometry
+ rings: 10
+ slices: 10
+ radius: 1
+ // Additional Attributes
+ attributes: [
+ particlePositionDataAttribute,
+ particleColorDataAttribute
+ ]
+ }
+
+ CuboidGeometry {
+ id: cubeGeometry
+ yzMeshResolution: Qt.size(2, 2)
+ xzMeshResolution: Qt.size(2, 2)
+ xyMeshResolution: Qt.size(2, 2)
+ // Additional Attributes
+ attributes: [
+ particlePositionDataAttribute,
+ particleColorDataAttribute
+ ]
+ }
+
+ CylinderGeometry {
+ id: cylinderGeometry
+ rings: 10
+ slices: 10
+ radius: 1
+ length: 1.5
+ // Additional Attributes
+ attributes: [
+ particlePositionDataAttribute,
+ particleColorDataAttribute
+ ]
+ }
+
+ TorusGeometry {
+ id: torusGeometry
+ rings: 10
+ slices: 10
+ radius: 1
+ minorRadius: 0.5
+ // Additional Attributes
+ attributes: [
+ particlePositionDataAttribute,
+ particleColorDataAttribute
+ ]
+ }
+
+ Entity {
+ id: particleRenderEntity
+ readonly property GeometryRenderer particlesRenderer: GeometryRenderer {
+ instanceCount: particlesCount
+ baseVertex: 0
+ baseInstance: 0
+ primitiveType: GeometryRenderer.Triangles
+ geometry: {
+ switch (particlesShape) {
+ case _SPHERE:
+ return sphereGeometry;
+ case _CUBE:
+ return cubeGeometry;
+ case _CYLINDER:
+ return cylinderGeometry;
+ case _TORUS:
+ return torusGeometry;
+ }
+ }
+ }
+
+ components: [
+ particlesRenderer,
+ computeMaterial
+ ]
+ }
+}
+
diff --git a/examples/qt3d/compute-particles/compute-particles.pro b/examples/qt3d/compute-particles/compute-particles.pro
new file mode 100644
index 000000000..c25cc0c30
--- /dev/null
+++ b/examples/qt3d/compute-particles/compute-particles.pro
@@ -0,0 +1,14 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+QT += 3dcore 3drender 3dquick 3dinput quick qml
+
+HEADERS += \
+
+
+RESOURCES += \
+ compute-particles.qrc
+
+SOURCES += \
+ main.cpp
diff --git a/examples/qt3d/compute-particles/compute-particles.qrc b/examples/qt3d/compute-particles/compute-particles.qrc
new file mode 100644
index 000000000..0f94fddd5
--- /dev/null
+++ b/examples/qt3d/compute-particles/compute-particles.qrc
@@ -0,0 +1,11 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>ComputeFrameGraph.qml</file>
+ <file>ComputeMaterial.qml</file>
+ <file>particles.frag</file>
+ <file>particles.vert</file>
+ <file>ParticlesScene.qml</file>
+ <file>particles.comp</file>
+ </qresource>
+</RCC>
diff --git a/examples/qt3d/compute-particles/main.cpp b/examples/qt3d/compute-particles/main.cpp
new file mode 100644
index 000000000..1095df57b
--- /dev/null
+++ b/examples/qt3d/compute-particles/main.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QQuickView>
+
+int main(int argc, char* argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QQuickView view;
+
+ view.resize(500, 500);
+ view.setResizeMode(QQuickView::SizeRootObjectToView);
+ view.setSource(QUrl("qrc:/main.qml"));
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/qt3d/compute-particles/main.qml b/examples/qt3d/compute-particles/main.qml
new file mode 100644
index 000000000..a0b43590e
--- /dev/null
+++ b/examples/qt3d/compute-particles/main.qml
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Scene3D 2.0
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.1
+
+Item {
+
+ Scene3D {
+ anchors.fill: parent
+ aspects: "input"
+ ParticlesScene {
+ id: scene
+ particleStep: stepSlider.value
+ finalCollisionFactor: collisionSlider.value
+ }
+ }
+
+ ColumnLayout {
+ id: colorLayout
+ anchors.left: parent.left
+ anchors.leftMargin: 35
+ anchors.right: parent.right
+ anchors.rightMargin: 35
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 35
+ spacing: 15
+
+ RowLayout {
+ Text {
+ text: "Particles Step:"
+ color: "white"
+ }
+ Slider {
+ height: 35
+ id: stepSlider
+ Layout.fillWidth: true
+ minimumValue: 0.0
+ maximumValue: 2
+ value: 0.4
+ }
+ }
+ RowLayout {
+ Text {
+ text: "Particles Collision:"
+ color: "white"
+ }
+ Slider {
+ height: 35
+ id: collisionSlider
+ Layout.fillWidth: true
+ minimumValue: 0.0
+ maximumValue: 2
+ value: 0.2
+ }
+ }
+ RowLayout {
+ Button {
+ text: "Reset Particles"
+ onClicked: scene.reset()
+ }
+ }
+ RowLayout {
+ Text {
+ text: "Particles Shape:"
+ color: "white"
+ }
+ ExclusiveGroup {
+ id: particlesTypeGroup
+ }
+ CheckBox {
+ text: "Sphere"
+ checked: true
+ exclusiveGroup: particlesTypeGroup
+ onClicked: scene.particlesShape = scene._SPHERE
+ }
+ CheckBox
+ { text: "Cube"
+ checked: false
+ exclusiveGroup: particlesTypeGroup
+ onClicked: scene.particlesShape = scene._CUBE
+ }
+ CheckBox {
+ text: "Cylinder"
+ checked: false
+ exclusiveGroup: particlesTypeGroup
+ onClicked: scene.particlesShape = scene._CYLINDER
+ }
+ CheckBox {
+ text: "Torus"
+ checked: false
+ exclusiveGroup: particlesTypeGroup
+ onClicked: scene.particlesShape = scene._TORUS
+ }
+ }
+ }
+}
diff --git a/examples/qt3d/compute-particles/particles.comp b/examples/qt3d/compute-particles/particles.comp
new file mode 100644
index 000000000..7feaf5fdd
--- /dev/null
+++ b/examples/qt3d/compute-particles/particles.comp
@@ -0,0 +1,41 @@
+#version 430 core
+
+uniform float particleStep;
+uniform float finalCollisionFactor;
+
+layout (local_size_x = 1024) in;
+
+struct ParticleData
+{
+ vec3 position;
+ vec3 direction;
+ vec3 color;
+};
+
+// Particles from previouse frame
+layout (std430, binding = 0) coherent buffer Particles
+{
+ ParticleData particles[];
+} data;
+
+void main(void)
+{
+ uint globalId = gl_GlobalInvocationID.x;
+
+ // Retrieve current particle from previous frame
+ ParticleData currentParticle = data.particles[globalId];
+
+ // New position = old position + distance traveled over step duration
+ currentParticle.position = currentParticle.position + currentParticle.direction * particleStep;
+
+ // Make acceleration more or less point toward the center of the scene
+ vec3 acceleration = normalize(vec3(0.0) - currentParticle.position) * finalCollisionFactor;
+
+ // New velocity = old velocity + acceleration over step duration
+ currentParticle.direction = currentParticle.direction + acceleration * particleStep;
+
+
+
+ // Save updated particle
+ data.particles[globalId] = currentParticle;
+}
diff --git a/examples/qt3d/compute-particles/particles.frag b/examples/qt3d/compute-particles/particles.frag
new file mode 100644
index 000000000..3f11b9868
--- /dev/null
+++ b/examples/qt3d/compute-particles/particles.frag
@@ -0,0 +1,33 @@
+#version 430 core
+
+out vec4 color;
+
+in VertexBlock
+{
+ flat vec3 color;
+ vec3 pos;
+ vec3 normal;
+} frag_in;
+
+const vec4 lightPosition = vec4(0.0, 0.0, 0.0, 0.0);
+const vec3 lightIntensity = vec3(1.0, 1.0, 1.0);
+const vec3 ka = vec3(0.1, 0.1, 0.1);
+const vec3 ks = vec3(0.8, 0.8, 0.8);
+const float shininess = 50.0;
+
+vec3 ads()
+{
+ vec3 n = normalize( frag_in.normal);
+ vec3 s = normalize( vec3(lightPosition) - frag_in.pos );
+ vec3 v = normalize( -frag_in.pos );
+ vec3 h = normalize( v + s );
+ return lightIntensity * (ka +
+ frag_in.color * max( dot(s, frag_in.normal ), 0.0 ) +
+ ks * pow( max( dot( h, n ), 0.0 ), shininess ) );
+}
+
+
+void main(void)
+{
+ color = vec4(ads(), 1.0);
+}
diff --git a/examples/qt3d/compute-particles/particles.vert b/examples/qt3d/compute-particles/particles.vert
new file mode 100644
index 000000000..5f2da2a00
--- /dev/null
+++ b/examples/qt3d/compute-particles/particles.vert
@@ -0,0 +1,27 @@
+#version 430 core
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+
+in vec3 particlePosition;
+in vec3 particleColor;
+
+out VertexBlock
+{
+ flat vec3 color;
+ vec3 pos;
+ vec3 normal;
+} v_out;
+
+uniform mat4 mvp;
+uniform mat3 modelViewNormal;
+uniform mat4 modelView;
+
+void main(void)
+{
+ vec4 pos = vec4(vertexPosition.xyz, 1.0) + vec4(particlePosition, 0.0);
+ gl_Position = mvp * pos;
+ v_out.pos = vec4(modelView * pos).xyz;
+ v_out.normal = normalize(modelViewNormal * vertexNormal);
+ v_out.color = mix(particleColor * 0.2, particleColor, smoothstep(0.5, 0.8, abs(v_out.normal).z));
+}
diff --git a/examples/qt3d/qt3d.pro b/examples/qt3d/qt3d.pro
index 829eb2789..afba0a352 100644
--- a/examples/qt3d/qt3d.pro
+++ b/examples/qt3d/qt3d.pro
@@ -44,7 +44,8 @@ SUBDIRS += \
instanced-arrays-qml \
picking-qml \
transforms-qml \
- lights
+ lights \
+ compute-particles
# qmake seems to break in some CI configurations, disable this for now
#SUBDIRS += qgltf