diff --git a/shaders/vulkan/ComputeShader.comp b/shaders/vulkan/ComputeShader.comp new file mode 100644 index 0000000..f199347 --- /dev/null +++ b/shaders/vulkan/ComputeShader.comp @@ -0,0 +1,96 @@ +#version 460 + +#define FLOAT_MAX 4294967296.0f +#define FLOAT_FACTOR 0.00000000023283064365386962890625f + +struct particle +{ + float px, py, pz; + float vx, vy, vz; + float cx, cy, cz; + float age; +}; + +layout(std430, binding = 0) buffer particles +{ + particle p[]; +}; + +layout(binding = 1) uniform dtIn +{ + float dt; +}; + +layout(binding = 2) uniform staticIn +{ + vec3 resetPos; + uint maxParticles; +}; + +layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in; + +uint hash(uvec3 seed) +{ + uint hash; + hash = (seed.x ^ 61u) ^ (seed.y >> 16u); + hash *= 9u; + hash = seed.z ^ (seed.x >> 4u); + hash *= 0x27d4eb2du; + hash = seed.y ^ (seed.z >> 15u); + return hash; +} + +uint rand(uint seed) +{ + // Xorshift algorithm from George Marsaglia's paper + seed ^= (seed << 13u); + seed ^= (seed >> 17u); + seed ^= (seed << 5u); + return seed; +} + +int foreSign(uint seed) +{ + return rand(seed) % 2 == 0 ? 1 : -1; +} + +void main() +{ + uint gid = gl_GlobalInvocationID.x; + + if (gid <= maxParticles) + { + particle part = p[gid]; + + uint hash1 = hash(uvec3(uint(part.px * FLOAT_MAX), uint(part.cy * FLOAT_MAX), uint(part.vz * FLOAT_MAX))); + uint hash2 = hash(uvec3(uint(part.vx * FLOAT_MAX), uint(part.py * FLOAT_MAX), uint(part.cz * FLOAT_MAX))); + uint hash3 = hash(uvec3(uint(part.cx * FLOAT_MAX), uint(part.vy * FLOAT_MAX), uint(part.pz * FLOAT_MAX))); + + if (part.age < 0 || part.px > 1 || part.py > 1 || part.pz > 1 || part.px < -1 || part.py < -1 || part.pz < -1) + { + part.px = resetPos.x; + part.py = resetPos.y; + part.pz = resetPos.z; + + part.age = rand(hash(uvec3(hash1, hash2, hash3))) % (250 - 60 + 1) + 60; + + part.vx = foreSign(hash1) * float(rand(hash2)) * FLOAT_FACTOR; + part.vy = foreSign(hash3) * float(rand(hash1)) * FLOAT_FACTOR; + part.vz = foreSign(hash2) * float(rand(hash3)) * FLOAT_FACTOR; + + part.cx = float(rand(hash1 ^ hash2)) * FLOAT_FACTOR; + part.cy = float(rand(hash2 ^ hash3)) * FLOAT_FACTOR; + part.cz = float(rand(hash3 ^ hash1)) * FLOAT_FACTOR; + } + else + { + part.px += part.vx * dt; + part.py += part.vy * dt; + part.pz += part.vz * dt; + + part.age -= 0.01f; + } + + p[gid] = part; + } +} diff --git a/shaders/vulkan/VertexShader.vert b/shaders/vulkan/VertexShader.vert new file mode 100644 index 0000000..2c66e6a --- /dev/null +++ b/shaders/vulkan/VertexShader.vert @@ -0,0 +1,12 @@ +#version 460 + +layout(location = 0) in vec3 pos; +layout(location = 1) in vec3 colIn; + +layout(location = 0) out vec3 colV; + +void main(void) +{ + colV = colIn; + gl_Position = vec4(pos, 1); +} \ No newline at end of file diff --git a/shaders/vulkan/runCompiler.bat b/shaders/vulkan/runCompiler.bat new file mode 100644 index 0000000..a01d804 --- /dev/null +++ b/shaders/vulkan/runCompiler.bat @@ -0,0 +1,3 @@ +D:\Programme\VulkanSDK\1.1.106.0\Bin\glslangValidator.exe -V ComputeShader.comp +D:\Programme\VulkanSDK\1.1.106.0\Bin\glslangValidator.exe -V VertexShader.vert +D:\Programme\VulkanSDK\1.1.106.0\Bin\glslangValidator.exe -V FragmentShader.frag \ No newline at end of file