diff --git a/include/soft_body.hpp b/include/soft_body.hpp index 8b17c6f..08bb7f9 100644 --- a/include/soft_body.hpp +++ b/include/soft_body.hpp @@ -3,6 +3,7 @@ #include #include #include +#include using std::vector; @@ -29,6 +30,8 @@ public: vector faces; vector tetrahedra; + void applyOffset(const glm::vec3& offset); + SoftBody& operator =(const SoftBody& other) = delete; private: }; \ No newline at end of file diff --git a/shaders/compile.sh b/shaders/compile.sh index e80db5d..8acbf25 100755 --- a/shaders/compile.sh +++ b/shaders/compile.sh @@ -2,4 +2,4 @@ glslc shader.vert -o vert.spv glslc shader.frag -o frag.spv glslc pbd.comp -o pbd.spv -glslc --target-env=vulkan1.3 normal.comp -o normal.spv \ No newline at end of file +glslc normal.comp -o normal.spv \ No newline at end of file diff --git a/shaders/normal.comp b/shaders/normal.comp index 890645e..f6d21e6 100644 --- a/shaders/normal.comp +++ b/shaders/normal.comp @@ -3,7 +3,7 @@ -layout (local_size_x = 1) in; +layout (local_size_x = 256) in; struct Vertex { vec3 position; @@ -23,8 +23,12 @@ layout (std430, set = 0, binding = 0) buffer VertexBuffer { layout (std430, set = 0, binding = 1) buffer FaceBuffer { Face faces[]; }; +layout (std140, set = 0, binding = 2) uniform UniformBuffer { + uint vertexCount; + uint faceCount; +}; -layout (push_constant) uniform StateConstant { +layout (push_constant) uniform PushConstants { uint state; }; diff --git a/src/simulation.cpp b/src/simulation.cpp index 6538f85..62de945 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -11,8 +11,13 @@ Simulation::Simulation() { Mesh sphere("models/sphere_high.ply"); Mesh bunny("models/bunny_high.ply"); - softBodies.push_back(std::make_unique(&sphere, 0.3f)); - // softBodies.push_back(std::make_unique(&bunny, 0.3f)); + auto body = std::make_unique(&sphere, 0.3f); + + for (size_t i = 0; i < 500; i++){ + auto copy = std::make_unique(*body.get()); + copy->applyOffset({i / 2.f, 0, 0}); + softBodies.push_back(std::move(copy)); + } vector vertices; vector edges; @@ -29,6 +34,12 @@ Simulation::Simulation() { triangles.insert(triangles.end(), softBody->triangles.begin(), softBody->triangles.end()); faces.insert(faces.end(), softBody->faces.begin(), softBody->faces.end()); tetrahedra.insert(tetrahedra.end(), softBody->tetrahedra.begin(), softBody->tetrahedra.end()); + + for (auto iter = faces.begin() + softBody->firstIndex / 3; iter != faces.end(); iter++){ + iter->a += softBody->vertexOffset; + iter->b += softBody->vertexOffset; + iter->c += softBody->vertexOffset; + } } class SimulationBuffer : public Buffer { @@ -60,16 +71,12 @@ void Simulation::recordDrawCommands() { vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &graphicsPipeline->descriptorSet, 0, nullptr); - for (const auto& softBody : softBodies){ - vkCmdDrawIndexed(cmdBuffer, softBody->faces.size() * 3, 1, softBody->firstIndex, softBody->vertexOffset, 0); - } + vkCmdDrawIndexed(cmdBuffer, faceBuffer->size / sizeof(Face) * 3, 1, 0, 0, 0); } void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle); - SoftBody& body = *softBodies[0]; - VkMemoryBarrier barrier {}; barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; @@ -97,8 +104,14 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1, &normalPipeline->descriptorSet, 0, nullptr); - uint32_t vertexGroupCount = vertexBuffer->size / sizeof(Vertex); - uint32_t faceGroupCount = faceBuffer->size / sizeof(Face); +#define BlOCK_SIZE 256 + + auto getGroupCount = [](uint32_t threads, uint32_t blockSize){ + return (threads - 1) / blockSize + 1; + }; + + uint32_t vertexGroupCount = getGroupCount(vertexBuffer->size / sizeof(Vertex), BlOCK_SIZE); + uint32_t faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE); uint32_t state = 0; vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); diff --git a/src/soft_body.cpp b/src/soft_body.cpp index b62f692..7a41922 100644 --- a/src/soft_body.cpp +++ b/src/soft_body.cpp @@ -71,3 +71,9 @@ SoftBody::SoftBody(Mesh* mesh, float compliance) : compliance(compliance) { faces.shrink_to_fit(); } + +void SoftBody::applyOffset(const glm::vec3 &offset) { + for (Vertex& vertex : vertices){ + vertex.position += offset; + } +} diff --git a/src/vulkan/instance.cpp b/src/vulkan/instance.cpp index 7a9d56d..988f4fd 100644 --- a/src/vulkan/instance.cpp +++ b/src/vulkan/instance.cpp @@ -7,8 +7,7 @@ #include const std::vector deviceExtensions = { - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME, + VK_KHR_SWAPCHAIN_EXTENSION_NAME }; #ifndef NDEBUG @@ -83,7 +82,7 @@ void Instance::createInstance() { applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); applicationInfo.pEngineName = "No Engine"; applicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); - applicationInfo.apiVersion = VK_API_VERSION_1_3; + applicationInfo.apiVersion = VK_API_VERSION_1_0; uint32_t glfwExtensionCount = 0; const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); @@ -147,17 +146,13 @@ void Instance::createLogicalDevice() { queueCreateInfos.push_back(queueCreateInfo); } - VkPhysicalDeviceFeatures deviceFeaturesCore {}; - VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomicFeatures {}; - atomicFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT; - atomicFeatures.shaderBufferFloat32Atomics = VK_TRUE; + VkPhysicalDeviceFeatures deviceFeatures {}; VkDeviceCreateInfo createInfo {}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.pQueueCreateInfos = queueCreateInfos.data(); createInfo.queueCreateInfoCount = queueCreateInfos.size(); - createInfo.pEnabledFeatures = &deviceFeaturesCore; - createInfo.pNext = &atomicFeatures; + createInfo.pEnabledFeatures = &deviceFeatures; createInfo.enabledExtensionCount = deviceExtensions.size(); createInfo.ppEnabledExtensionNames = deviceExtensions.data(); #ifdef ENABLE_VALIDATION_LAYERS