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
#extension GL_EXT_shader_atomic_float : enable
layout (local_size_x = 256) in;
layout (local_size_x = 16) in;
struct Vertex {
vec3 position;

@ -1,6 +1,6 @@
#version 450
layout (local_size_x = 256) in;
layout (local_size_x = 16) in;
struct Vertex {
vec3 position;
@ -12,6 +12,11 @@ layout (std430, set = 0, binding = 0) buffer VertexBuffer {
Vertex vertices[];
};
layout (std140, set = 0, binding = 5) uniform Sizes {
uint vertexCount;
uint faceCount;
};
layout (std140, set = 1, binding = 0) uniform UBO {
float dt;
vec3 gravity;
@ -19,8 +24,29 @@ layout (std140, set = 1, binding = 0) uniform UBO {
layout (push_constant) uniform PushConstants {
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);
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)
inputManager->keyPressed(key);
if (action == GLFW_RELEASE)
@ -18,13 +18,13 @@ Input::Input(GLFWwindow *window) : window(window) {
});
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);
});
glfwGetCursorPos(window, &oldX, &oldY);
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)
inputManager->mouseButtonPressed(button);
if (action == GLFW_RELEASE)

@ -7,6 +7,7 @@
#include "mesh.hpp"
#include "constraints.hpp"
#include "vulkan/descriptor_pool.hpp"
#include "timer.hpp"
Simulation::Simulation() {
createMeshBuffers();
@ -49,14 +50,17 @@ void Simulation::recordDrawCommands() {
VkBuffer buffers[] = {vertexBuffer->handle};
VkDeviceSize offsets[] = {0};
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);
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) {
#define BlOCK_SIZE 256
#define BlOCK_SIZE 16
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){
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 faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE);
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle);
VkMemoryBarrier barrier {};
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
barrier.srcAccessMask = 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);
size_t subSteps = 1;
uint32_t state;
size_t subSteps = 10;
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);
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;
for (uint32_t partition = 0; partition < partitionCount; partition++){
uint32_t partitionSize = 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);
}
*/
state = 2;
vkCmdPushConstants(cmdBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
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);
}
@ -94,7 +104,8 @@ 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, &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);
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);
@ -120,9 +131,16 @@ void Simulation::createMeshBuffers() {
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());
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));
}
@ -168,7 +186,12 @@ void Simulation::createComputePipelines() {
{
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();

@ -7,5 +7,5 @@ Timer::Timer() {
Timer::~Timer() {
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