diff --git a/projects/particle_simulation/shaders/comp1.spv b/projects/particle_simulation/shaders/comp1.spv new file mode 100644 index 0000000000000000000000000000000000000000..aa72785c8955dbb67fd1d1f5d37274e8789ddb40 Binary files /dev/null and b/projects/particle_simulation/shaders/comp1.spv differ diff --git a/projects/particle_simulation/shaders/compile.bat b/projects/particle_simulation/shaders/compile.bat index b4521235c40fe5fb163bab874560c2f219b7517f..001e1325df100d3341bc2cf1a8f761a3521752da 100644 --- a/projects/particle_simulation/shaders/compile.bat +++ b/projects/particle_simulation/shaders/compile.bat @@ -1,3 +1,4 @@ %VULKAN_SDK%\Bin32\glslc.exe shader.vert -o vert.spv %VULKAN_SDK%\Bin32\glslc.exe shader.frag -o frag.spv +%VULKAN_SDK%\Bin32\glslc.exe shader1.comp -o comp1.spv pause \ No newline at end of file diff --git a/projects/particle_simulation/shaders/shader.vert b/projects/particle_simulation/shaders/shader.vert index 7cce3a089413d16e1032bcf8d3e4d149c129d8e0..9e3a8249b113adad1563627aa8c16ffba5c2d0d0 100644 --- a/projects/particle_simulation/shaders/shader.vert +++ b/projects/particle_simulation/shaders/shader.vert @@ -3,6 +3,19 @@ layout(location = 0) in vec3 particle; +struct Particle +{ + vec3 position; + float lifeTime; + vec3 velocity; + float padding_2; +}; + +layout(std430, binding = 2) coherent buffer buffer_inParticle +{ + Particle inParticle[]; +}; + layout( push_constant ) uniform constants{ mat4 mvp; }; diff --git a/projects/particle_simulation/shaders/shader1.comp b/projects/particle_simulation/shaders/shader1.comp new file mode 100644 index 0000000000000000000000000000000000000000..ee84397b2d1efcd6cf4bcd6426234519fdc56d13 --- /dev/null +++ b/projects/particle_simulation/shaders/shader1.comp @@ -0,0 +1,22 @@ +#version 450 core +#extension GL_ARB_separate_shader_objects : enable + +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; + +struct Particle +{ + vec3 position; + float lifeTime; + vec3 velocity; + float padding_2; +}; + +layout(std430, binding = 0) coherent buffer buffer_inParticle +{ + Particle inParticle[]; +}; + +void main() { + uint id = gl_GlobalInvocationID.x; + inParticle[id].position = inParticle[id].position + vec3(0.f,0.01f,0.f); +} diff --git a/projects/particle_simulation/shaders/vert.spv b/projects/particle_simulation/shaders/vert.spv index e77272b23e4965f386db65c89cdb96aaa92b0964..841133cd5ef81d8fed6fdf94b598f82627eed2f5 100644 Binary files a/projects/particle_simulation/shaders/vert.spv and b/projects/particle_simulation/shaders/vert.spv differ diff --git a/projects/particle_simulation/src/ParticleSystem.hpp b/projects/particle_simulation/src/ParticleSystem.hpp index cec4df931e13b93e0263303439cdcbcf53db28e3..2afb825392dcb4fdc36b6e52096589f19ef0ecb6 100644 --- a/projects/particle_simulation/src/ParticleSystem.hpp +++ b/projects/particle_simulation/src/ParticleSystem.hpp @@ -3,6 +3,7 @@ #include <vector> #include "Particle.hpp" #include <random> +#include "vkcv/Buffer.hpp" class ParticleSystem { diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp index 0315d45eb4ba329bb0e435721196e572ba996418..0b244f02c25f3ab5fb916af5b9632ef24182fe15 100644 --- a/projects/particle_simulation/src/main.cpp +++ b/projects/particle_simulation/src/main.cpp @@ -47,12 +47,28 @@ int main(int argc, const char** argv) { vkcv::PassConfig particlePassDefinition({ present_color_attachment }); vkcv::PassHandle particlePass = core.createPass(particlePassDefinition); - if (!particlePass) + vkcv::PassConfig computePassDefinition({}); + vkcv::PassHandle computePass = core.createPass(computePassDefinition); + + if (!particlePass || !computePass) { std::cout << "Error. Could not create renderpass. Exiting." << std::endl; return EXIT_FAILURE; } + vkcv::ShaderProgram computeShaderProgram{}; + computeShaderProgram.addShader(vkcv::ShaderStage::COMPUTE, std::filesystem::path("shaders/comp1.spv")); + + vkcv::DescriptorSetHandle computeDescriptorSet = core.createDescriptorSet(computeShaderProgram.getReflectedDescriptors()[0]); + + const std::vector<vkcv::VertexAttachment> computeVertexAttachments = computeShaderProgram.getVertexAttachments(); + + std::vector<vkcv::VertexBinding> computeBindings; + for (size_t i = 0; i < computeVertexAttachments.size(); i++) { + computeBindings.push_back(vkcv::VertexBinding(i, { computeVertexAttachments[i] })); + } + const vkcv::VertexLayout computeLayout(computeBindings); + vkcv::ShaderProgram particleShaderProgram{}; particleShaderProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("shaders/vert.spv")); particleShaderProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("shaders/frag.spv")); @@ -65,6 +81,9 @@ int main(int argc, const char** argv) { ); const std::vector<vkcv::VertexAttachment> vertexAttachments = particleShaderProgram.getVertexAttachments(); + const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { + vkcv::VertexBufferBinding(0, vertexBuffer.getVulkanHandle())}; + std::vector<vkcv::VertexBinding> bindings; for (size_t i = 0; i < vertexAttachments.size(); i++) { bindings.push_back(vkcv::VertexBinding(i, { vertexAttachments[i] })); @@ -88,6 +107,9 @@ int main(int argc, const char** argv) { vertexBuffer.fill(vertices); vkcv::PipelineHandle particlePipeline = core.createGraphicsPipeline(particlePipelineDefinition); + + vkcv::PipelineHandle computePipeline = core.createComputePipeline(computeShaderProgram, {core.getDescriptorSet(computeDescriptorSet).layout} ); + vkcv::Buffer<glm::vec4> color = core.createBuffer<glm::vec4>( vkcv::BufferType::UNIFORM, 1 @@ -98,17 +120,29 @@ int main(int argc, const char** argv) { 1 ); - const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { - vkcv::VertexBufferBinding(0, vertexBuffer.getVulkanHandle()) - }; + glm::vec3 minVelocity = glm::vec3(-0.0f,-0.0f,0.f); + glm::vec3 maxVelocity = glm::vec3(0.0f,0.0f,0.f); + glm::vec2 lifeTime = glm::vec2(0.f,5.f); + ParticleSystem particleSystem = ParticleSystem( 100 , minVelocity, maxVelocity, lifeTime); + vkcv::Buffer<Particle> particleBuffer = core.createBuffer<Particle>( + vkcv::BufferType::STORAGE, + particleSystem.getParticles().size() + ); + + particleBuffer.fill(particleSystem.getParticles()); vkcv::DescriptorWrites setWrites; setWrites.uniformBufferWrites = {vkcv::UniformBufferDescriptorWrite(0,color.getHandle()), vkcv::UniformBufferDescriptorWrite(1,position.getHandle())}; + setWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(2,particleBuffer.getHandle())}; core.writeDescriptorSet(descriptorSet, setWrites); - if (!particlePipeline) + vkcv::DescriptorWrites computeWrites; + computeWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0,particleBuffer.getHandle())}; + core.writeDescriptorSet(computeDescriptorSet, computeWrites); + + if (!particlePipeline || !computePipeline) { std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; return EXIT_FAILURE; @@ -118,7 +152,6 @@ int main(int argc, const char** argv) { const vkcv::Mesh renderMesh({vertexBufferBindings}, particleIndexBuffer.getVulkanHandle(), particleIndexBuffer.getCount()); vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); - //vkcv::DrawcallInfo drawcalls(renderMesh, {vkcv::DescriptorSetUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle)}); glm::vec2 pos = glm::vec2(1.f); @@ -126,15 +159,9 @@ int main(int argc, const char** argv) { pos = glm::vec2(static_cast<float>(offsetX), static_cast<float>(offsetY)); }); - glm::vec3 minVelocity = glm::vec3(-0.5f,-0.5f,0.f); - glm::vec3 maxVelocity = glm::vec3(0.5f,0.5f,0.f); - glm::vec2 lifeTime = glm::vec2(0.f,5.f); - ParticleSystem particleSystem = ParticleSystem( 100 , minVelocity, maxVelocity, lifeTime); - std::vector<glm::mat4> modelMatrices; std::vector<vkcv::DrawcallInfo> drawcalls; for(auto particle : particleSystem.getParticles()) { - modelMatrices.push_back(glm::translate(glm::mat4(1.f), particle.getPosition())); drawcalls.push_back(vkcv::DrawcallInfo(renderMesh, {descriptorUsage})); } @@ -164,10 +191,7 @@ int main(int argc, const char** argv) { modelMatrices.push_back(glm::translate(glm::mat4(1.f), particle.getPosition())); } - //modelmatrix = glm::rotate(modelmatrix, angle, glm::vec3(0,0,1)); - cameraManager.getCamera().updateView(deltatime); - //const glm::mat4 mvp = modelmatrix * cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView(); std::vector<glm::mat4> mvp; mvp.clear(); for(const auto& m : modelMatrices){ @@ -177,6 +201,13 @@ int main(int argc, const char** argv) { vkcv::PushConstantData pushConstantData((void*)mvp.data(), sizeof(glm::mat4)); auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + uint32_t computeDispatchCount[3] = {static_cast<uint32_t> (std::ceil(particleSystem.getParticles().size()/64.f)),1,1}; + core.recordComputeDispatchToCmdStream(cmdStream, + computePipeline, + computeDispatchCount, + {vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet).vulkanHandle)}, + vkcv::PushConstantData(nullptr, 0)); + core.recordDrawcallsToCmdStream( cmdStream, particlePass,