normal compute

feature/softbody-runtime-control
Benjamin Kraft 4 months ago
parent c84fe3e3b9
commit 705d6fa119
  1. 3
      include/soft_body.hpp
  2. 2
      shaders/compile.sh
  3. 8
      shaders/normal.comp
  4. 31
      src/simulation.cpp
  5. 6
      src/soft_body.cpp
  6. 13
      src/vulkan/instance.cpp

@ -3,6 +3,7 @@
#include <cstdint>
#include <string>
#include <vector>
#include <glm/vec3.hpp>
using std::vector;
@ -29,6 +30,8 @@ public:
vector<Face> faces;
vector<Tetrahedron> tetrahedra;
void applyOffset(const glm::vec3& offset);
SoftBody& operator =(const SoftBody& other) = delete;
private:
};

@ -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
glslc normal.comp -o normal.spv

@ -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;
};

@ -11,8 +11,13 @@ Simulation::Simulation() {
Mesh sphere("models/sphere_high.ply");
Mesh bunny("models/bunny_high.ply");
softBodies.push_back(std::make_unique<SoftBody>(&sphere, 0.3f));
// softBodies.push_back(std::make_unique<SoftBody>(&bunny, 0.3f));
auto body = std::make_unique<SoftBody>(&sphere, 0.3f);
for (size_t i = 0; i < 500; i++){
auto copy = std::make_unique<SoftBody>(*body.get());
copy->applyOffset({i / 2.f, 0, 0});
softBodies.push_back(std::move(copy));
}
vector<Vertex> vertices;
vector<Edge> 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);

@ -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;
}
}

@ -7,8 +7,7 @@
#include <cstring>
const std::vector<const char*> 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

Loading…
Cancel
Save