From 6d2fd5caaa6fdf8c6f32e16d4539f1cec7680637 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 5 Nov 2018 21:06:12 -0500 Subject: [PATCH] Add configurable camera aperture/focus --- include/camera.h | 2 ++ include/dofpass.h | 3 ++- shaders/gfield.frag | 9 ++------- shaders/gfield.vert | 12 +++--------- src/dofpass.cpp | 13 ++++++------- src/main.cpp | 6 ++++-- src/renderer.cpp | 2 +- 7 files changed, 20 insertions(+), 27 deletions(-) diff --git a/include/camera.h b/include/camera.h index 27fc1d6..ae4391a 100644 --- a/include/camera.h +++ b/include/camera.h @@ -5,4 +5,6 @@ class Camera { public: glm::vec3 position = glm::vec3(0), target = glm::vec3(0); + float focusDistance = 0.0f; + float aperture = 0.0f; }; diff --git a/include/dofpass.h b/include/dofpass.h index 4274c38..e7b97f9 100644 --- a/include/dofpass.h +++ b/include/dofpass.h @@ -4,13 +4,14 @@ class Renderer; struct RenderTarget; +class Camera; class DoFPass { public: DoFPass(Renderer& renderer); ~DoFPass(); - void render(VkCommandBuffer commandBuffer, RenderTarget* target); + void render(VkCommandBuffer commandBuffer, Camera& camera, RenderTarget* target); void createDescriptorSet(RenderTarget* target); diff --git a/shaders/gfield.frag b/shaders/gfield.frag index b5f8850..3e927ee 100644 --- a/shaders/gfield.frag +++ b/shaders/gfield.frag @@ -20,12 +20,7 @@ void main() { outColor = texture(sceneSampler, vec2(inPos.x / res.x, inPos.y / res.y)) * texture(bokehSampler, inUV); outColor.a = (cocRadius / 9000.0); - if(pushConstants.dpack[0] == 0) { - if(texture(depthSampler, gl_FragCoord.xy / res).r < pushConstants.dpack[1]) - discard; - } else { - if(texture(depthSampler, gl_FragCoord.xy / res).r > pushConstants.dpack[1]) - discard; - } + if(texture(depthSampler, gl_FragCoord.xy / res).r < pushConstants.dpack[1]) + discard; } diff --git a/shaders/gfield.vert b/shaders/gfield.vert index 84d5e5c..dc9c037 100644 --- a/shaders/gfield.vert +++ b/shaders/gfield.vert @@ -19,15 +19,9 @@ void main() { const float depth = texture(depthSampler, vec2(loc.x / res.x, loc.y / res.y)).r; float size = 0.0; - // dpack[0] is the field we are drawing (far = 0, near = 1) - if(pushConstants.dpack[0] == 0) { - if(depth > pushConstants.dpack[1]) - size = (depth - pushConstants.dpack[1]) * 500.0; - } else { - if(depth < pushConstants.dpack[1]) - size = (pushConstants.dpack[1] - depth) * 500.0; - } - + if(depth > pushConstants.dpack[1]) + size = (depth - pushConstants.dpack[1]) * 500.0 * pushConstants.dpack[0]; + cocRadius = size; outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); diff --git a/src/dofpass.cpp b/src/dofpass.cpp index 839735f..70e920b 100644 --- a/src/dofpass.cpp +++ b/src/dofpass.cpp @@ -5,6 +5,7 @@ #include #include "renderer.h" +#include "camera.h" DoFPass::DoFPass(Renderer& renderer) : renderer_(renderer) { createRenderPass(); @@ -27,7 +28,7 @@ DoFPass::~DoFPass() { vkDestroyRenderPass(renderer_.getDevice(), renderPass_, nullptr); } -void DoFPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) { +void DoFPass::render(VkCommandBuffer commandBuffer, Camera& camera, RenderTarget* target) { VkViewport viewport = {}; viewport.width = target->extent.width / 2; viewport.height = target->extent.height / 2; @@ -56,8 +57,8 @@ void DoFPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) { vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); glm::vec4 dpack; - dpack[0] = 0; - dpack[1] = 0.9581; + dpack[0] = camera.aperture; + dpack[1] = (100 - camera.focusDistance) / 100.0f; dpack[2] = target->extent.width / 2; dpack[3] = target->extent.height / 2; @@ -66,7 +67,8 @@ void DoFPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) { vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(glm::vec4), &dpack); - vkCmdDraw(commandBuffer, 3, (target->extent.width / 2) * (target->extent.height / 2), 0, 0); + if(camera.aperture > 0.0f) + vkCmdDraw(commandBuffer, 3, (target->extent.width / 2) * (target->extent.height / 2), 0, 0); vkCmdEndRenderPass(commandBuffer); @@ -78,9 +80,6 @@ void DoFPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) { vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_); vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &target->dofSets[target->currentImage], 0, nullptr); - dpack[0] = 1; - dpack[1] = 0.9581; - vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(glm::vec4), &dpack); //FIXME: near field is bugged diff --git a/src/main.cpp b/src/main.cpp index 13b70b8..688257b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -349,8 +349,10 @@ int main(int argc, char* argv[]) { if(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) io.MousePos = ImVec2(static_cast(mouseX), static_cast(mouseY)); - - ImGui::ShowDemoWindow(); + + ImGui::DragFloat("Aperture", &camera.aperture, 0.01f, 0.0f, 1.0f); + ImGui::DragFloat("Focus Distance", &camera.focusDistance); + ImGui::Text("dpack[2] = %f", (100 - camera.focusDistance) / 100.0f); ImGui::Render(); renderer->render(world, camera, target); diff --git a/src/renderer.cpp b/src/renderer.cpp index 12ced69..8b6162a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -78,7 +78,7 @@ void Renderer::render(World& world, Camera& camera, RenderTarget* target) { vkCmdSetScissor(commandBuffer, 0, 1, &scissor); worldPass_->render(commandBuffer, world, camera, target); - dofPass_->render(commandBuffer, target); + dofPass_->render(commandBuffer, camera, target); // reset after dof pass vkCmdSetViewport(commandBuffer, 0, 1, &viewport);