From 1afb74e07cd82df4bf6c5f9d93275fc0253f9b12 Mon Sep 17 00:00:00 2001
From: TheJackiMonster <thejackimonster@gmail.com>
Date: Mon, 25 Jul 2022 19:15:37 +0200
Subject: [PATCH] Write basic voxel compute shader (WIP)

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
---
 projects/fire_works/shaders/smoke.inc         |  8 ++
 projects/fire_works/shaders/smoke.vert        |  8 +-
 projects/fire_works/shaders/voxel.inc         |  9 +++
 .../fire_works/shaders/voxel_particle.comp    | 53 ++++++++++++
 projects/fire_works/shaders/voxel_smoke.comp  | 54 +++++++++++++
 projects/fire_works/shaders/voxel_trail.comp  | 81 +++++++++++++++++++
 6 files changed, 206 insertions(+), 7 deletions(-)
 create mode 100644 projects/fire_works/shaders/voxel.inc
 create mode 100644 projects/fire_works/shaders/voxel_particle.comp
 create mode 100644 projects/fire_works/shaders/voxel_smoke.comp
 create mode 100644 projects/fire_works/shaders/voxel_trail.comp

diff --git a/projects/fire_works/shaders/smoke.inc b/projects/fire_works/shaders/smoke.inc
index b01a707b..6b1bbbb5 100644
--- a/projects/fire_works/shaders/smoke.inc
+++ b/projects/fire_works/shaders/smoke.inc
@@ -10,4 +10,12 @@ struct smoke_t {
 	uint eventID;
 };
 
+float smokeDensity(float size) {
+	if (size > 0.0f) {
+		return 0.025f / size;
+	} else {
+		return 0.0f;
+	}
+}
+
 #endif // SMOKE_INC
\ No newline at end of file
diff --git a/projects/fire_works/shaders/smoke.vert b/projects/fire_works/shaders/smoke.vert
index 0392deca..634117f7 100644
--- a/projects/fire_works/shaders/smoke.vert
+++ b/projects/fire_works/shaders/smoke.vert
@@ -30,13 +30,7 @@ void main()	{
     passPos = vertexPos;
     passDir = pos - camera;
     passColor = color;
-
-    if (size > 0.0f) {
-        passDensity = 0.025f / size;
-    } else {
-        passDensity = 0.0f;
-    }
-
+    passDensity = smokeDensity(size);
     passSmokeIndex = gl_InstanceIndex;
 
     // transform position into projected view space
diff --git a/projects/fire_works/shaders/voxel.inc b/projects/fire_works/shaders/voxel.inc
new file mode 100644
index 00000000..bbeb3446
--- /dev/null
+++ b/projects/fire_works/shaders/voxel.inc
@@ -0,0 +1,9 @@
+#ifndef VOXEL_INC
+#define VOXEL_INC
+
+struct voxel_t {
+    vec3 color;
+    float density;
+};
+
+#endif // VOXEL_INC
\ No newline at end of file
diff --git a/projects/fire_works/shaders/voxel_particle.comp b/projects/fire_works/shaders/voxel_particle.comp
new file mode 100644
index 00000000..8489e960
--- /dev/null
+++ b/projects/fire_works/shaders/voxel_particle.comp
@@ -0,0 +1,53 @@
+#version 450 core
+#extension GL_GOOGLE_include_directive : enable
+#extension GL_ARB_separate_shader_objects : enable
+
+layout(local_size_x = 256) in;
+
+#include "physics.inc"
+#include "particle.inc"
+
+layout(set=0, binding=0, std430) readonly buffer particleBuffer {
+    particle_t particles [];
+};
+
+#include "voxel.inc"
+
+layout(set=1, binding=0, std430) buffer voxelBuffer {
+    voxel_t voxel [];
+};
+
+layout( push_constant ) uniform constants{
+    mat4 mvp;
+};
+
+void main() {
+    uint id = gl_GlobalInvocationID.x;
+
+    if (id >= particles.length()) {
+        return;
+    }
+
+    vec3 position = particles[id].position;
+    float lifetime = particles[id].lifetime;
+
+    if (lifetime <= 0.0f) {
+        return;
+    }
+
+    vec4 cs_pos = mvp * vec4(position, 1);
+
+    if (abs(cs_pos.w) <= 0.0f) {
+        return;
+    }
+
+    vec3 ndc_pos = cs_pos.xyz / cs_pos.w;
+    vec3 pos = (ndc_pos + vec3(1, 1, 0)) * vec3(0.5f, 0.5f, 1.0f);
+
+    // clipping!
+
+    float size = particles[id].size;
+    vec3 color = particles[id].color;
+
+    // write color into voxel at `pos * (resolution-1)` atomically!
+}
diff --git a/projects/fire_works/shaders/voxel_smoke.comp b/projects/fire_works/shaders/voxel_smoke.comp
new file mode 100644
index 00000000..da33a8ea
--- /dev/null
+++ b/projects/fire_works/shaders/voxel_smoke.comp
@@ -0,0 +1,54 @@
+#version 450 core
+#extension GL_GOOGLE_include_directive : enable
+#extension GL_ARB_separate_shader_objects : enable
+
+layout(local_size_x = 256) in;
+
+#include "physics.inc"
+#include "smoke.inc"
+
+layout(set=0, binding=0, std430) readonly buffer smokeBuffer {
+    smoke_t smokes [];
+};
+
+#include "voxel.inc"
+
+layout(set=1, binding=0, std430) buffer voxelBuffer {
+    voxel_t voxel [];
+};
+
+layout( push_constant ) uniform constants{
+    mat4 mvp;
+};
+
+void main() {
+    uint id = gl_GlobalInvocationID.x;
+
+    if (id >= smokes.length()) {
+        return;
+    }
+
+    vec3 position = smokes[id].position;
+    float size = smokes[id].size;
+
+    const float density = smokeDensity(size);
+
+    if (density <= mediumDensity) {
+        return;
+    }
+
+    vec4 cs_pos = mvp * vec4(position, 1);
+
+    if (abs(cs_pos.w) <= 0.0f) {
+        return;
+    }
+
+    vec3 ndc_pos = cs_pos.xyz / cs_pos.w;
+    vec3 pos = (ndc_pos + vec3(1, 1, 0)) * vec3(0.5f, 0.5f, 1.0f);
+
+    // clipping!
+
+    vec3 color = smokes[id].color;
+
+    // write (color, density) into voxel at `pos * (resolution-1)` atomically!
+}
diff --git a/projects/fire_works/shaders/voxel_trail.comp b/projects/fire_works/shaders/voxel_trail.comp
new file mode 100644
index 00000000..6419cf72
--- /dev/null
+++ b/projects/fire_works/shaders/voxel_trail.comp
@@ -0,0 +1,81 @@
+#version 450 core
+#extension GL_GOOGLE_include_directive : enable
+#extension GL_ARB_separate_shader_objects : enable
+
+layout(local_size_x = 256) in;
+
+#include "physics.inc"
+
+#include "trail.inc"
+
+layout(set=0, binding=0, std430) coherent buffer trailBuffer {
+    trail_t trails [];
+};
+
+#include "point.inc"
+
+layout(set=0, binding=1, std430) buffer pointBuffer {
+    point_t points [];
+};
+
+#include "voxel.inc"
+
+layout(set=1, binding=0, std430) buffer voxelBuffer {
+    voxel_t voxel [];
+};
+
+#include "smoke.inc"
+
+layout( push_constant ) uniform constants{
+    mat4 mvp;
+};
+
+void main() {
+    uint id = gl_GlobalInvocationID.x;
+
+    if (id >= trails.length()) {
+        return;
+    }
+
+    const uint particleIndex = trails[id].particleIndex;
+    const uint startIndex = trails[id].startIndex;
+
+    uint useCount = trails[id].useCount;
+
+    if (useCount <= 0) {
+        return;
+    }
+
+    vec3 color = trails[id].color;
+    float lifetime = trails[id].lifetime;
+
+    if (lifetime <= 0.0f) {
+        return;
+    }
+
+    for (uint i = 0; i < useCount; i++) {
+        const uint x = (startIndex + i) % points.length();
+
+        vec3 position = points[x].position;
+        float size = points[x].size;
+
+        const float density = smokeDensity(size);
+
+        if (density <= mediumDensity) {
+            break;
+        }
+
+        vec4 cs_pos = mvp * vec4(position, 1);
+
+        if (abs(cs_pos.w) <= 0.0f) {
+            return;
+        }
+
+        vec3 ndc_pos = cs_pos.xyz / cs_pos.w;
+        vec3 pos = (ndc_pos + vec3(1, 1, 0)) * vec3(0.5f, 0.5f, 1.0f);
+
+        // clipping!
+
+        // write (color, density) into voxel at `pos * (resolution-1)` atomically!
+    }
+}
-- 
GitLab