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 1bb15e8..d4846e6 100644 Binary files a/assets/shaders/ray.frag.spv and b/assets/shaders/ray.frag.spv differ diff --git a/pléascach.cpp b/pléascach.cpp index e034535..3d02649 100644 --- a/pléascach.cpp +++ b/pléascach.cpp @@ -80,9 +80,10 @@ int main(int argc, char* argv[]) { ren.present(); const auto t = frame_timer.read(); ren.ui->info.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