From 13fff8cfad4891df7278fa6815128ec00e173a63 Mon Sep 17 00:00:00 2001 From: connellpaxton Date: Sat, 10 Feb 2024 17:40:56 -0500 Subject: [PATCH] Added object system using SSBOs --- Renderer/Pipeline.cpp | 16 ++++++++++ Renderer/Pipeline.hpp | 2 ++ Renderer/Renderer.cpp | 18 ++++++++--- Renderer/Renderer.hpp | 2 ++ Renderer/ShaderBuffer.cpp | 3 ++ Renderer/ShaderBuffer.hpp | 52 +++++++++++++++++++++++++++++++ Renderer/UniformBuffer.hpp | 12 ++++++-- Scene/Object.hpp | 20 ++++++++++++ assets/shaders/ray.frag | 59 +++++++++++++++++++++++++++++++++--- assets/shaders/ray.frag.spv | Bin 5052 -> 6624 bytes pléascach.cpp | 5 +-- util/glsl_types.hpp | 11 +++++++ 12 files changed, 185 insertions(+), 15 deletions(-) create mode 100644 Renderer/ShaderBuffer.cpp create mode 100644 Renderer/ShaderBuffer.hpp create mode 100644 Scene/Object.hpp create mode 100644 util/glsl_types.hpp diff --git a/Renderer/Pipeline.cpp b/Renderer/Pipeline.cpp index 4cecbf9..e1418da 100644 --- a/Renderer/Pipeline.cpp +++ b/Renderer/Pipeline.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -191,6 +192,21 @@ void GraphicsPipeline::update(uint32_t binding, const UniformBuffer& uni) { }, nullptr); } +void GraphicsPipeline::update(uint32_t binding, const ShaderBuffer& ssbo) { + auto buff_info = vk::DescriptorBufferInfo{ + .buffer = ssbo, + .offset = 0, + .range = vk::WholeSize, + }; + dev.updateDescriptorSets(vk::WriteDescriptorSet { + .dstSet = desc_set, + .dstBinding = binding, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .pBufferInfo = &buff_info, + }, nullptr); +} + void GraphicsPipeline::update(uint32_t binding, const Texture& tex) { auto tex_info = vk::DescriptorImageInfo { .sampler = tex.sampler, diff --git a/Renderer/Pipeline.hpp b/Renderer/Pipeline.hpp index 735b5eb..b347109 100644 --- a/Renderer/Pipeline.hpp +++ b/Renderer/Pipeline.hpp @@ -4,6 +4,7 @@ #include struct Shader; +struct ShaderBuffer; struct UniformBuffer; struct VertexBuffer; struct RenderPass; @@ -27,6 +28,7 @@ struct GraphicsPipeline { /* create overload for every type of object we need to update */ void update(uint32_t binding, const UniformBuffer& uni); + void update(uint32_t binding, const ShaderBuffer& ssbo); void update(uint32_t binding, const Texture& tex); ~GraphicsPipeline(); diff --git a/Renderer/Renderer.cpp b/Renderer/Renderer.cpp index 7974317..77fd9f9 100644 --- a/Renderer/Renderer.cpp +++ b/Renderer/Renderer.cpp @@ -191,9 +191,9 @@ Renderer::Renderer(Window& win) : win(win) { command_buffer = std::make_unique(dev, queue_family); uniform_buffer = std::make_unique(phys_dev, dev); + shader_buffer = std::make_unique(phys_dev, dev); textures = createResources({ - "assets/textures/oil.jpg", "assets/textures/eire.png", }); @@ -205,13 +205,14 @@ Renderer::Renderer(Window& win) : win(win) { std::vector bindings = { uniform_buffer->binding(0), textures[0].binding(1), + shader_buffer->binding(2), }; vertex_buffer = std::make_unique(phys_dev, dev, 6); /* simple quad */ vertex_buffer->upload(std::vector { - { { -1.0,-1.0 } }, + { { -1.0, -1.0 } }, { { -1.0, 1.0 } }, { { 1.0, 1.0 } }, { { 1.0, 1.0 } }, @@ -219,10 +220,16 @@ Renderer::Renderer(Window& win) : win(win) { { { -1.0,-1.0 } }, }); + shader_buffer->upload(std::vector { + { { 0.0, -10.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0, 0.0 }, 0, Shape::SPHERE }, + { { 0.0, -12.0, 0.0, 0.0 }, { 10.0, 1.0, 10.0, 0.0 }, 1, Shape::BOX }, + }); + pipeline = std::make_unique(dev, shaders, swapchain->extent, *render_pass, bindings, *vertex_buffer); pipeline->update(0, *uniform_buffer); - pipeline->update(1, textures[1]); + pipeline->update(1, textures[0]); + pipeline->update(2, *shader_buffer); for (auto& shader : shaders) shader.cleanup(); @@ -328,6 +335,7 @@ void Renderer::draw() { .time = time, .viewport = glm::vec4(viewport.width, viewport.y, 0.0, 0.0), .cam_dir = cam.dir(), + .n_objects = 2, }); command_buffer->bind(*pipeline); @@ -335,6 +343,7 @@ void Renderer::draw() { command_buffer->command_buffer.setScissor(0, scissor); command_buffer->bind(pipeline->layout, pipeline->desc_set); command_buffer->bind(*vertex_buffer); + shader_buffer->objects[0].center.y += glm::sin(time)/10.0; command_buffer->command_buffer.draw(6, 1, 0, 0); /* draw User Interface stuff */ @@ -346,7 +355,6 @@ void Renderer::draw() { command_buffer->end(); - vk::PipelineStageFlags stage_flags = vk::PipelineStageFlagBits::eColorAttachmentOutput; /* submit our command buffer to the queue */ @@ -386,7 +394,6 @@ void Renderer::present() { } frame++; - time += 0.0167f * speed * static_cast(running); } Renderer::~Renderer() { @@ -395,6 +402,7 @@ Renderer::~Renderer() { ui.reset(); uniform_buffer.reset(); + shader_buffer.reset(); vertex_buffer.reset(); pipeline.reset(); diff --git a/Renderer/Renderer.hpp b/Renderer/Renderer.hpp index e53ae31..561f0d2 100644 --- a/Renderer/Renderer.hpp +++ b/Renderer/Renderer.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -48,6 +49,7 @@ struct Renderer { std::unique_ptr pipeline; /* just holds single quad */ + std::unique_ptr shader_buffer; std::unique_ptr vertex_buffer; std::unique_ptr uniform_buffer; diff --git a/Renderer/ShaderBuffer.cpp b/Renderer/ShaderBuffer.cpp new file mode 100644 index 0000000..c19475a --- /dev/null +++ b/Renderer/ShaderBuffer.cpp @@ -0,0 +1,3 @@ +#include + + diff --git a/Renderer/ShaderBuffer.hpp b/Renderer/ShaderBuffer.hpp new file mode 100644 index 0000000..0f4e54e --- /dev/null +++ b/Renderer/ShaderBuffer.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include + +#include + +#include + +using namespace glsl; + +/* Wrapper for SSBO */ +struct ShaderBuffer { + + ShaderBuffer(vk::PhysicalDevice phys_dev, vk::Device dev, const size_t n_objects = 0x1000) : phys_dev(phys_dev), dev(dev), n_objects(n_objects) { + buffer = std::make_unique( + phys_dev, dev, n_objects * sizeof(Object), + vk::BufferUsageFlagBits::eStorageBuffer, + vk::MemoryPropertyFlagBits::eHostCoherent + | vk::MemoryPropertyFlagBits::eHostVisible + ); + objects = reinterpret_cast(buffer->p); + } + + vk::PhysicalDevice phys_dev; + vk::Device dev; + size_t n_objects; + Object* objects; + + std::unique_ptr buffer; + + operator vk::Buffer&() const { + return *buffer; + } + + inline vk::DescriptorSetLayoutBinding binding(uint32_t binding, vk::ShaderStageFlags stages = vk::ShaderStageFlagBits::eFragment) { + return vk::DescriptorSetLayoutBinding { + .binding = binding, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .descriptorCount = 1, + .stageFlags = stages, + .pImmutableSamplers = nullptr, + }; + } + + inline void upload(const std::vector& scene) { + buffer->upload(reinterpret_cast(scene.data())); + } + + ~ShaderBuffer() { + buffer.reset(); + } +}; \ No newline at end of file diff --git a/Renderer/UniformBuffer.hpp b/Renderer/UniformBuffer.hpp index 61b39c7..97119df 100644 --- a/Renderer/UniformBuffer.hpp +++ b/Renderer/UniformBuffer.hpp @@ -9,6 +9,10 @@ #include +#include + +using namespace glsl; + /* Uniform: * layout (set = 0, binding = 0) uniform Matrices { @@ -16,14 +20,16 @@ layout (set = 0, binding = 0) uniform Matrices { float time; vec4 viewport; vec3 cam_dir; + uint n_objects; }; */ struct UniformData { - glm::vec3 cam_pos; + vec3 cam_pos; float time; - glm::vec4 viewport; - glm::vec3 cam_dir; + vec4 viewport; + vec3 cam_dir; + uint n_objects; }; struct UniformBuffer { diff --git a/Scene/Object.hpp b/Scene/Object.hpp new file mode 100644 index 0000000..1846bcd --- /dev/null +++ b/Scene/Object.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include + +using namespace glsl; + + +enum Shape { + SPHERE, + BOX, +}; + +struct Object { + vec4 center; + vec4 dimensions; + uint id; + Shape shape; + float pad0; + float pad1; +}; diff --git a/assets/shaders/ray.frag b/assets/shaders/ray.frag index bc106b5..d52413e 100644 --- a/assets/shaders/ray.frag +++ b/assets/shaders/ray.frag @@ -5,15 +5,43 @@ layout (set = 0, binding = 0) uniform Matrices { float time; vec4 viewport; vec3 cam_dir; + uint n_objects; }; +/* +enum Shape { + SPHERE, + BOX, +}; +*/ + +#define SPHERE 0 +#define BOX 1 + +struct Object { + vec4 center; + vec4 dimensions; + uint id; + uint shape; +}; + +layout (set = 0, binding = 2) readonly buffer Objects { + Object objects[]; +}; + layout (location = 0) in vec2 pos; layout (location = 0) out vec4 fragColor; -float opUnion(float v1, float v2) { +/* joins two parts of a scene */ +float op_union(float v1, float v2) { return min(v1, v2); } +/* subtracts sdf from scene */ +float op_subtract(float v1, float v2) { + return max(v1, -v2); +} + float box(vec3 p, vec3 c, vec3 r) { p -= c; vec3 q = abs(p) - r; @@ -24,9 +52,28 @@ float sphere(vec3 p, vec3 c, float r) { return length(p-c) - r; } +float obj_to_sdf(vec3 p, uint n) { + switch(objects[n].shape) { + case SPHERE: + return sphere(p, objects[n].center.xyz, objects[n].dimensions.x); + break; + case BOX: + return box(p, objects[n].center.xyz, objects[n].dimensions.xyz); + break; + } +} + float sdf(vec3 pos) { - float d = sphere(pos, vec3(0.0, 0.0, 0.0), 3.0); - d = opUnion(d, box(pos, vec3(0.0, -10.0, 0.0), vec3(10.0, 1.0, 10.0))); + float d = 100000000.0; + for(uint i = 0; i < n_objects; i++) { + d = op_union(d, obj_to_sdf(pos, i)); + } + + /*float dsphere = sphere(pos, vec3(0.0, 3.0*sin(time)-10.0, 0.0), 1.0); + float dbox = box(pos, vec3(0.0, -10.0, 0.0), vec3(10.0, 1.0, 10.0)); + float dpellet = sphere(pos, vec3(0.0, 10.0*sin(time) - 10.0, 0.0), 0.1); + float d = op_union(op_subtract(dbox, dsphere), dpellet);*/ + return d; } @@ -57,8 +104,10 @@ void main() { float d = raycast(dir); vec3 point = cam_pos + dir * d; + float c = 1.0-(length(point)*0.075); + if(d < 0.0) - fragColor = vec4(0.0); + fragColor = vec4(0.1); else - fragColor = vec4(mod(point.y, 1.0)); + fragColor = vec4(c); } \ No newline at end of file diff --git a/assets/shaders/ray.frag.spv b/assets/shaders/ray.frag.spv index 1bb15e837f4c2998507999f4c571cedfa54c2e16..d4846e6429ebd849205f2143e9640e7b9528146d 100644 GIT binary patch literal 6624 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 Uinfo.fps = 1000.0f / t; + ren.time += t / 1000.0 * ren.speed * static_cast(ren.running); - while (frame_timer.read() < 16.60) - ; + /*while (frame_timer.read() < 16.60) + ;*/ } } catch (const std::string& e) { diff --git a/util/glsl_types.hpp b/util/glsl_types.hpp new file mode 100644 index 0000000..ff069c8 --- /dev/null +++ b/util/glsl_types.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include + +namespace glsl { + typedef uint32_t uint; + typedef glm::vec1 vec1; + typedef glm::vec2 vec2; + typedef glm::vec3 vec3; + typedef glm::vec4 vec4; +} \ No newline at end of file