prepare graph color

feature/softbody-runtime-control
Benjamin Kraft 4 months ago
parent 4309dae5a0
commit 1c322260c4
  1. 5
      shaders/normal.comp
  2. 30
      shaders/pbd.comp
  3. 6
      src/input.cpp
  4. 45
      src/simulation.cpp
  5. 2
      src/timer.cpp

@ -1,9 +1,6 @@
#version 450 #version 450
#extension GL_EXT_shader_atomic_float : enable
layout (local_size_x = 16) in;
layout (local_size_x = 256) in;
struct Vertex { struct Vertex {
vec3 position; vec3 position;

@ -1,6 +1,6 @@
#version 450 #version 450
layout (local_size_x = 256) in; layout (local_size_x = 16) in;
struct Vertex { struct Vertex {
vec3 position; vec3 position;
@ -12,6 +12,11 @@ layout (std430, set = 0, binding = 0) buffer VertexBuffer {
Vertex vertices[]; Vertex vertices[];
}; };
layout (std140, set = 0, binding = 5) uniform Sizes {
uint vertexCount;
uint faceCount;
};
layout (std140, set = 1, binding = 0) uniform UBO { layout (std140, set = 1, binding = 0) uniform UBO {
float dt; float dt;
vec3 gravity; vec3 gravity;
@ -19,8 +24,29 @@ layout (std140, set = 1, binding = 0) uniform UBO {
layout (push_constant) uniform PushConstants { layout (push_constant) uniform PushConstants {
uint state; uint state;
int vertexOffset;
}; };
void main() { void preSolve(uint vID){
vertices[vID].position += vec3(0.0001, 0, 0);
}
void postSolve(uint vID){
vertices[vID].position += vec3(0, 0.0001, 0);
}
void main() {
uint id = gl_GlobalInvocationID.x;
switch (state){
case 0:
if (id < vertexCount){
preSolve(id);
}
break;
case 2:
if (id < vertexCount){
postSolve(id);
}
break;
}
} }

@ -10,7 +10,7 @@ Input::Input(GLFWwindow *window) : window(window) {
glfwSetWindowUserPointer(window, this); glfwSetWindowUserPointer(window, this);
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods){ glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods){
auto inputManager = reinterpret_cast<Input*>(glfwGetWindowUserPointer(window)); auto inputManager = static_cast<Input*>(glfwGetWindowUserPointer(window));
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
inputManager->keyPressed(key); inputManager->keyPressed(key);
if (action == GLFW_RELEASE) if (action == GLFW_RELEASE)
@ -18,13 +18,13 @@ Input::Input(GLFWwindow *window) : window(window) {
}); });
glfwSetCursorPosCallback(window, [](GLFWwindow* window, double xpos, double ypos){ glfwSetCursorPosCallback(window, [](GLFWwindow* window, double xpos, double ypos){
auto inputManager = reinterpret_cast<Input*>(glfwGetWindowUserPointer(window)); auto inputManager = static_cast<Input*>(glfwGetWindowUserPointer(window));
inputManager->mouseMoved(xpos, ypos); inputManager->mouseMoved(xpos, ypos);
}); });
glfwGetCursorPos(window, &oldX, &oldY); glfwGetCursorPos(window, &oldX, &oldY);
glfwSetMouseButtonCallback(window, [](GLFWwindow* window, int button, int action, int mods){ glfwSetMouseButtonCallback(window, [](GLFWwindow* window, int button, int action, int mods){
auto inputManager = reinterpret_cast<Input*>(glfwGetWindowUserPointer(window)); auto inputManager = static_cast<Input*>(glfwGetWindowUserPointer(window));
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
inputManager->mouseButtonPressed(button); inputManager->mouseButtonPressed(button);
if (action == GLFW_RELEASE) if (action == GLFW_RELEASE)

@ -7,6 +7,7 @@
#include "mesh.hpp" #include "mesh.hpp"
#include "constraints.hpp" #include "constraints.hpp"
#include "vulkan/descriptor_pool.hpp" #include "vulkan/descriptor_pool.hpp"
#include "timer.hpp"
Simulation::Simulation() { Simulation::Simulation() {
createMeshBuffers(); createMeshBuffers();
@ -49,14 +50,17 @@ void Simulation::recordDrawCommands() {
VkBuffer buffers[] = {vertexBuffer->handle}; VkBuffer buffers[] = {vertexBuffer->handle};
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets); vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets);
vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr);
vkCmdDrawIndexed(cmdBuffer, faceBuffer->size / sizeof(Face) * 3, 1, 0, 0, 0); for (const auto &softBody : softBodies){
vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, sizeof(uint32_t) * softBody->firstIndex, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(cmdBuffer, softBody->faces.size() * 3, 1, 0, 0, 0);
}
// vkCmdDrawIndexed(cmdBuffer, faceBuffer->size / sizeof(Face) * 3, 1, 0, 0, 0);
} }
void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
#define BlOCK_SIZE 256 #define BlOCK_SIZE 16
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){ auto getGroupCount = [](uint32_t threads, uint32_t blockSize){
return (threads - 1) / blockSize + 1; return (threads - 1) / blockSize + 1;
@ -65,28 +69,34 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
uint32_t vertexGroupCount = getGroupCount(vertexBuffer->size / sizeof(Vertex), BlOCK_SIZE); uint32_t vertexGroupCount = getGroupCount(vertexBuffer->size / sizeof(Vertex), BlOCK_SIZE);
uint32_t faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE); uint32_t faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE);
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle);
VkMemoryBarrier barrier {}; VkMemoryBarrier barrier {};
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle);
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr);
size_t subSteps = 1; uint32_t state;
size_t subSteps = 10;
for (size_t i = 0; i < subSteps; i++){ for (size_t i = 0; i < subSteps; i++){
state = 0;
vkCmdPushConstants(cmdBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
/*
uint32_t partitionCount = 1; uint32_t partitionCount = 1;
for (uint32_t partition = 0; partition < partitionCount; partition++){ for (uint32_t partition = 0; partition < partitionCount; partition++){
uint32_t partitionSize = 1; uint32_t partitionSize = 1;
vkCmdDispatch(cmdBuffer, partitionSize, 1, 1); vkCmdDispatch(cmdBuffer, partitionSize, 1, 1);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
} }
*/
state = 2;
vkCmdPushConstants(cmdBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
} }
@ -94,7 +104,8 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle); vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle);
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr);
uint32_t state = 0;
state = 0;
vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
@ -120,9 +131,16 @@ void Simulation::createMeshBuffers() {
auto body = std::make_unique<SoftBody>(&sphere, 0.3f); auto body = std::make_unique<SoftBody>(&sphere, 0.3f);
for (size_t i = 0; i < 500; i++){ for (size_t i = 0; i < 5; i++){
auto copy = std::make_unique<SoftBody>(*body.get()); auto copy = std::make_unique<SoftBody>(*body.get());
copy->applyOffset({i / 2.f, 0, 0}); copy->applyOffset({i * 2, 0, 0});
softBodies.push_back(std::move(copy));
}
body = std::make_unique<SoftBody>(&bunny, 0.3f);
for (size_t i = 0; i < 5; i++){
auto copy = std::make_unique<SoftBody>(*body.get());
copy->applyOffset({i * 2, 2, 0});
softBodies.push_back(std::move(copy)); softBodies.push_back(std::move(copy));
} }
@ -168,7 +186,12 @@ void Simulation::createComputePipelines() {
{ {
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]); layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
pbdPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/pbd.spv", layouts)); pushRanges.push_back({
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0,
.size = 2 * sizeof(uint32_t)
});
pbdPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/pbd.spv", layouts, pushRanges));
} }
layouts.clear(); layouts.clear();

@ -7,5 +7,5 @@ Timer::Timer() {
Timer::~Timer() { Timer::~Timer() {
size_t nanoseconds = (system_clock::now() - start).count(); size_t nanoseconds = (system_clock::now() - start).count();
printf("Timer: %zu mus\n", nanoseconds / 1000); printf("Timer: %zu μs\n", nanoseconds / 1000);
} }

Loading…
Cancel
Save