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