summaryrefslogtreecommitdiffstats
path: root/tests/manual/compute-particles
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/compute-particles')
-rw-r--r--tests/manual/compute-particles/CMakeLists.txt50
-rw-r--r--tests/manual/compute-particles/ComputeFrameGraph.qml41
-rw-r--r--tests/manual/compute-particles/ComputeMaterial.qml108
-rw-r--r--tests/manual/compute-particles/ParticlesScene.qml200
-rw-r--r--tests/manual/compute-particles/compute-particles.qrc14
-rw-r--r--tests/manual/compute-particles/main.cpp24
-rw-r--r--tests/manual/compute-particles/main.qml100
-rw-r--r--tests/manual/compute-particles/shaders/gl43/particles.comp41
-rw-r--r--tests/manual/compute-particles/shaders/gl43/particles.frag33
-rw-r--r--tests/manual/compute-particles/shaders/gl43/particles.vert27
-rw-r--r--tests/manual/compute-particles/shaders/gl45/particles.comp43
-rw-r--r--tests/manual/compute-particles/shaders/gl45/particles.frag33
-rw-r--r--tests/manual/compute-particles/shaders/gl45/particles.vert33
13 files changed, 747 insertions, 0 deletions
diff --git a/tests/manual/compute-particles/CMakeLists.txt b/tests/manual/compute-particles/CMakeLists.txt
new file mode 100644
index 000000000..e46594fc2
--- /dev/null
+++ b/tests/manual/compute-particles/CMakeLists.txt
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(compute-particles LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+
+find_package(Qt6 REQUIRED COMPONENTS 3DCore 3DInput 3DQuick 3DRender Core Gui Qml Quick)
+
+qt_add_executable(compute-particles
+ main.cpp
+)
+
+set_target_properties(compute-particles PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(compute-particles PUBLIC
+ Qt::3DCore
+ Qt::3DInput
+ Qt::3DQuick
+ Qt::3DRender
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::Quick
+)
+
+# Resources:
+set(compute-particles_resource_files
+ "ComputeFrameGraph.qml"
+ "ComputeMaterial.qml"
+ "ParticlesScene.qml"
+ "main.qml"
+ "shaders/gl43/particles.comp"
+ "shaders/gl43/particles.frag"
+ "shaders/gl43/particles.vert"
+ "shaders/gl45/particles.comp"
+ "shaders/gl45/particles.frag"
+ "shaders/gl45/particles.vert"
+)
+
+qt6_add_resources(compute-particles "compute-particles"
+ PREFIX
+ "/"
+ FILES
+ ${compute-particles_resource_files}
+)
diff --git a/tests/manual/compute-particles/ComputeFrameGraph.qml b/tests/manual/compute-particles/ComputeFrameGraph.qml
new file mode 100644
index 000000000..4ceca993c
--- /dev/null
+++ b/tests/manual/compute-particles/ComputeFrameGraph.qml
@@ -0,0 +1,41 @@
+// Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.9
+
+Viewport {
+ property alias camera: selector.camera
+
+ RenderSurfaceSelector {
+ id: surfaceSelector
+
+ // Clear Buffer
+ ClearBuffers {
+ buffers: ClearBuffers.ColorDepthBuffer
+ NoDraw {}
+ }
+
+ // Compute Pass
+ DispatchCompute {
+ workGroupX: 50; workGroupY: 1; workGroupZ: 1
+ TechniqueFilter {
+ matchAll: [
+ FilterKey { name: "type"; value: "compute"}
+ ]
+ }
+ }
+
+ // Draw particles from buffer computed in the Compute Pass
+ CameraSelector {
+ id: selector
+ TechniqueFilter {
+ MemoryBarrier { waitFor: MemoryBarrier.VertexAttributeArray }
+ matchAll: [
+ FilterKey { name: "type"; value: "draw"}
+ ]
+ }
+ }
+ }
+}
+
diff --git a/tests/manual/compute-particles/ComputeMaterial.qml b/tests/manual/compute-particles/ComputeMaterial.qml
new file mode 100644
index 000000000..90f9a7c2e
--- /dev/null
+++ b/tests/manual/compute-particles/ComputeMaterial.qml
@@ -0,0 +1,108 @@
+// Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+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 }
+ ]
+
+ effect: Effect {
+ techniques: [
+ Technique {
+ renderPasses: [
+ RenderPass {
+ shaderProgram: ShaderProgram {
+ computeShaderCode: loadSource("qrc:/shaders/gl43/particles.comp")
+ }
+ // We set the buffer as the parameter data
+ parameters: [
+ Parameter { name: "Particles"; value: dataBuffer }
+ ]
+ }
+ ]
+ filterKeys: [
+ FilterKey { name: "type"; value: "compute" }
+ ]
+ graphicsApiFilter {
+ api: GraphicsApiFilter.OpenGL
+ profile: GraphicsApiFilter.CoreProfile
+ majorVersion: 4
+ minorVersion: 3
+ }
+ },
+ Technique {
+ renderPasses: [
+ RenderPass {
+ shaderProgram: ShaderProgram {
+ vertexShaderCode: loadSource("qrc:/shaders/gl43/particles.vert")
+ fragmentShaderCode: loadSource("qrc:/shaders/gl43/particles.frag")
+ }
+ // We assume the mesh to be drawn will also receive
+ // Vertex buffers attributes that will be used to position and color
+ }
+ ]
+ filterKeys: [
+ FilterKey { name: "type"; value: "draw" }
+ ]
+ graphicsApiFilter {
+ api: GraphicsApiFilter.OpenGL
+ profile: GraphicsApiFilter.CoreProfile
+ majorVersion: 4
+ minorVersion: 3
+ }
+ },
+ Technique {
+ renderPasses: [
+ RenderPass {
+ shaderProgram: ShaderProgram {
+ computeShaderCode: loadSource("qrc:/shaders/gl45/particles.comp")
+ }
+ // We set the buffer as the parameter data
+ parameters: [
+ Parameter { name: "Particles"; value: dataBuffer }
+ ]
+ }
+ ]
+ filterKeys: [
+ FilterKey { name: "type"; value: "compute" }
+ ]
+ graphicsApiFilter {
+ api: GraphicsApiFilter.RHI
+ profile: GraphicsApiFilter.NoProfile
+ majorVersion: 1
+ minorVersion: 0
+ }
+ },
+ Technique {
+ renderPasses: [
+ RenderPass {
+ shaderProgram: ShaderProgram {
+ vertexShaderCode: loadSource("qrc:/shaders/gl45/particles.vert")
+ fragmentShaderCode: loadSource("qrc:/shaders/gl45/particles.frag")
+ }
+ // We assume the mesh to be drawn will also receive
+ // Vertex buffers attributes that will be used to position and color
+ }
+ ]
+ filterKeys: [
+ FilterKey { name: "type"; value: "draw" }
+ ]
+ graphicsApiFilter {
+ api: GraphicsApiFilter.RHI
+ profile: GraphicsApiFilter.NoProfile
+ majorVersion: 1
+ minorVersion: 0
+ }
+ }
+ ] // techniques
+ }
+}
+
diff --git a/tests/manual/compute-particles/ParticlesScene.qml b/tests/manual/compute-particles/ParticlesScene.qml
new file mode 100644
index 000000000..c3b6fa4ae
--- /dev/null
+++ b/tests/manual/compute-particles/ParticlesScene.qml
@@ -0,0 +1,200 @@
+// Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+import Qt3D.Extras 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: [
+ RenderSettings {
+ ComputeFrameGraph {
+ camera: sceneCamera
+ }
+ // explicitly set RenderingPolicy to AlwaysRender, as changes in the
+ // scene won't be reflected in actual Qt scene-graph changes (due to
+ // GPU compute calls)
+ renderPolicy: RenderSettings.Always
+ }
+ ]
+
+ FirstPersonCameraController { camera: 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 byteSizeOfParticleData = 12;
+ var bufferData = new Float32Array(particlesCount * byteSizeOfParticleData);
+ var factor = 500.0;
+ for (var i = 0; i < particlesCount; ++i) {
+ var positionIdx = i * byteSizeOfParticleData;
+ var velocityIdx = i * byteSizeOfParticleData + 4;
+ var colorIdx = i * byteSizeOfParticleData + 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
+ // 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
+ vertexBaseType: Attribute.Float
+ vertexSize: 3
+ divisor: 1
+ byteStride: 12 * floatSize
+ buffer: particleBuffer
+ }
+
+ Attribute {
+ id: particleColorDataAttribute
+ name: "particleColor"
+ attributeType: Attribute.VertexAttribute
+ vertexBaseType: Attribute.Float
+ vertexSize: 3
+ divisor: 1
+ byteOffset: 8 * floatSize
+ byteStride: 12 * floatSize
+ buffer: particleBuffer
+ }
+
+ ComputeMaterial {
+ id: computeMaterial
+ dataBuffer: particleBuffer
+ }
+
+ Entity {
+ id: particleComputeEntity
+ readonly property ComputeCommand particlesComputeJob: ComputeCommand {}
+ 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
+ indexOffset: 0
+ firstInstance: 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/tests/manual/compute-particles/compute-particles.qrc b/tests/manual/compute-particles/compute-particles.qrc
new file mode 100644
index 000000000..b9d41c875
--- /dev/null
+++ b/tests/manual/compute-particles/compute-particles.qrc
@@ -0,0 +1,14 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>ComputeFrameGraph.qml</file>
+ <file>ComputeMaterial.qml</file>
+ <file>ParticlesScene.qml</file>
+ <file>shaders/gl43/particles.frag</file>
+ <file>shaders/gl43/particles.vert</file>
+ <file>shaders/gl43/particles.comp</file>
+ <file>shaders/gl45/particles.frag</file>
+ <file>shaders/gl45/particles.vert</file>
+ <file>shaders/gl45/particles.comp</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/compute-particles/main.cpp b/tests/manual/compute-particles/main.cpp
new file mode 100644
index 000000000..035ae2129
--- /dev/null
+++ b/tests/manual/compute-particles/main.cpp
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QGuiApplication>
+#include <QQuickView>
+#include <Qt3DRender/qt3drender-config.h>
+
+int main(int argc, char* argv[])
+{
+ QGuiApplication app(argc, argv);
+
+#if !QT_CONFIG(qt3d_rhi_renderer)
+ qputenv("QSG_RHI_BACKEND", "opengl");
+#endif
+
+ QQuickView view;
+
+ view.resize(500, 500);
+ view.setResizeMode(QQuickView::SizeRootObjectToView);
+ view.setSource(QUrl("qrc:/main.qml"));
+ view.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/compute-particles/main.qml b/tests/manual/compute-particles/main.qml
new file mode 100644
index 000000000..380b54ed3
--- /dev/null
+++ b/tests/manual/compute-particles/main.qml
@@ -0,0 +1,100 @@
+// Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick 2.0
+import QtQuick.Scene3D 2.0
+import QtQuick.Controls 2.0
+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
+ from: 0.0
+ to: 2
+ value: 0.4
+ }
+ }
+ RowLayout {
+ Text {
+ text: "Particles Collision:"
+ color: "white"
+ }
+ Slider {
+ height: 35
+ id: collisionSlider
+ Layout.fillWidth: true
+ from: 0.0
+ to: 2
+ value: 0.2
+ }
+ }
+ RowLayout {
+ Button {
+ text: "Reset Particles"
+ onClicked: scene.reset()
+ }
+ }
+ RowLayout {
+ Text {
+ text: "Particles Shape:"
+ color: "white"
+ }
+ ButtonGroup {
+ exclusive: true
+ id: particlesTypeGroup
+ }
+ CheckBox {
+ text: "Sphere"
+ checked: true
+ ButtonGroup.group: particlesTypeGroup
+ onClicked: scene.particlesShape = scene._SPHERE
+ }
+ CheckBox
+ { text: "Cube"
+ checked: false
+ ButtonGroup.group: particlesTypeGroup
+ onClicked: scene.particlesShape = scene._CUBE
+ }
+ CheckBox {
+ text: "Cylinder"
+ checked: false
+ ButtonGroup.group: particlesTypeGroup
+ onClicked: scene.particlesShape = scene._CYLINDER
+ }
+ CheckBox {
+ text: "Torus"
+ checked: false
+ ButtonGroup.group: particlesTypeGroup
+ onClicked: scene.particlesShape = scene._TORUS
+ }
+ }
+ }
+}
diff --git a/tests/manual/compute-particles/shaders/gl43/particles.comp b/tests/manual/compute-particles/shaders/gl43/particles.comp
new file mode 100644
index 000000000..af993bbe2
--- /dev/null
+++ b/tests/manual/compute-particles/shaders/gl43/particles.comp
@@ -0,0 +1,41 @@
+#version 430 core
+
+uniform float particleStep;
+uniform float finalCollisionFactor;
+
+layout (local_size_x = 1024) in;
+
+struct ParticleData
+{
+ vec4 position;
+ vec4 direction;
+ vec4 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
+ vec4 acceleration = normalize(vec4(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/tests/manual/compute-particles/shaders/gl43/particles.frag b/tests/manual/compute-particles/shaders/gl43/particles.frag
new file mode 100644
index 000000000..3f11b9868
--- /dev/null
+++ b/tests/manual/compute-particles/shaders/gl43/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/tests/manual/compute-particles/shaders/gl43/particles.vert b/tests/manual/compute-particles/shaders/gl43/particles.vert
new file mode 100644
index 000000000..5f2da2a00
--- /dev/null
+++ b/tests/manual/compute-particles/shaders/gl43/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/tests/manual/compute-particles/shaders/gl45/particles.comp b/tests/manual/compute-particles/shaders/gl45/particles.comp
new file mode 100644
index 000000000..9a6f74cfc
--- /dev/null
+++ b/tests/manual/compute-particles/shaders/gl45/particles.comp
@@ -0,0 +1,43 @@
+#version 450 core
+
+layout(std140, binding=3) uniform particle_uniforms {
+ float particleStep;
+ float finalCollisionFactor;
+};
+
+layout (local_size_x = 1024) in;
+
+struct ParticleData
+{
+ vec4 position;
+ vec4 direction;
+ vec4 color;
+};
+
+// Particles from previouse frame
+layout (std430, binding = 5) 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
+ vec4 acceleration = normalize(vec4(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/tests/manual/compute-particles/shaders/gl45/particles.frag b/tests/manual/compute-particles/shaders/gl45/particles.frag
new file mode 100644
index 000000000..42fb12b40
--- /dev/null
+++ b/tests/manual/compute-particles/shaders/gl45/particles.frag
@@ -0,0 +1,33 @@
+#version 450 core
+
+layout(location = 0) out vec4 color;
+
+layout(location = 0) 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/tests/manual/compute-particles/shaders/gl45/particles.vert b/tests/manual/compute-particles/shaders/gl45/particles.vert
new file mode 100644
index 000000000..b5815f6fb
--- /dev/null
+++ b/tests/manual/compute-particles/shaders/gl45/particles.vert
@@ -0,0 +1,33 @@
+#version 450 core
+
+layout(location = 0) in vec3 vertexPosition;
+layout(location = 1) in vec3 vertexNormal;
+
+layout(location = 2) in vec3 particlePosition;
+layout(location = 3) in vec3 particleColor;
+
+layout (location = 0) out VertexBlock
+{
+ flat vec3 color;
+ vec3 pos;
+ vec3 normal;
+} v_out;
+
+layout(std140, binding = 1) uniform qt3d_command_uniforms {
+ mat4 modelMatrix;
+ mat4 inverseModelMatrix;
+ mat4 modelViewMatrix;
+ mat3 modelNormalMatrix;
+ mat4 inverseModelViewMatrix;
+ mat4 modelViewProjection;
+ mat4 inverseModelViewProjectionMatrix;
+};
+
+void main(void)
+{
+ vec4 pos = vec4(vertexPosition.xyz, 1.0) + vec4(particlePosition, 0.0);
+ gl_Position = modelViewProjection * pos;
+ v_out.pos = vec4(modelViewMatrix * pos).xyz;
+ v_out.normal = normalize(modelNormalMatrix * vertexNormal);
+ v_out.color = mix(particleColor * 0.2, particleColor, smoothstep(0.5, 0.8, abs(v_out.normal).z));
+}