Archived
1
Fork 0

Add configurable camera aperture/focus

This commit is contained in:
Joshua Goins 2018-11-05 21:06:12 -05:00
parent 42bbae3da8
commit 6d2fd5caaa
7 changed files with 20 additions and 27 deletions

View file

@ -5,4 +5,6 @@
class Camera { class Camera {
public: public:
glm::vec3 position = glm::vec3(0), target = glm::vec3(0); glm::vec3 position = glm::vec3(0), target = glm::vec3(0);
float focusDistance = 0.0f;
float aperture = 0.0f;
}; };

View file

@ -4,13 +4,14 @@
class Renderer; class Renderer;
struct RenderTarget; struct RenderTarget;
class Camera;
class DoFPass { class DoFPass {
public: public:
DoFPass(Renderer& renderer); DoFPass(Renderer& renderer);
~DoFPass(); ~DoFPass();
void render(VkCommandBuffer commandBuffer, RenderTarget* target); void render(VkCommandBuffer commandBuffer, Camera& camera, RenderTarget* target);
void createDescriptorSet(RenderTarget* target); void createDescriptorSet(RenderTarget* target);

View file

@ -20,12 +20,7 @@ void main() {
outColor = texture(sceneSampler, vec2(inPos.x / res.x, inPos.y / res.y)) * texture(bokehSampler, inUV); outColor = texture(sceneSampler, vec2(inPos.x / res.x, inPos.y / res.y)) * texture(bokehSampler, inUV);
outColor.a = (cocRadius / 9000.0); outColor.a = (cocRadius / 9000.0);
if(pushConstants.dpack[0] == 0) { if(texture(depthSampler, gl_FragCoord.xy / res).r < pushConstants.dpack[1])
if(texture(depthSampler, gl_FragCoord.xy / res).r < pushConstants.dpack[1]) discard;
discard;
} else {
if(texture(depthSampler, gl_FragCoord.xy / res).r > pushConstants.dpack[1])
discard;
}
} }

View file

@ -19,15 +19,9 @@ void main() {
const float depth = texture(depthSampler, vec2(loc.x / res.x, loc.y / res.y)).r; const float depth = texture(depthSampler, vec2(loc.x / res.x, loc.y / res.y)).r;
float size = 0.0; float size = 0.0;
// dpack[0] is the field we are drawing (far = 0, near = 1) if(depth > pushConstants.dpack[1])
if(pushConstants.dpack[0] == 0) { size = (depth - pushConstants.dpack[1]) * 500.0 * pushConstants.dpack[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;
}
cocRadius = size; cocRadius = size;
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);

View file

@ -5,6 +5,7 @@
#include <stb_image.h> #include <stb_image.h>
#include "renderer.h" #include "renderer.h"
#include "camera.h"
DoFPass::DoFPass(Renderer& renderer) : renderer_(renderer) { DoFPass::DoFPass(Renderer& renderer) : renderer_(renderer) {
createRenderPass(); createRenderPass();
@ -27,7 +28,7 @@ DoFPass::~DoFPass() {
vkDestroyRenderPass(renderer_.getDevice(), renderPass_, nullptr); vkDestroyRenderPass(renderer_.getDevice(), renderPass_, nullptr);
} }
void DoFPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) { void DoFPass::render(VkCommandBuffer commandBuffer, Camera& camera, RenderTarget* target) {
VkViewport viewport = {}; VkViewport viewport = {};
viewport.width = target->extent.width / 2; viewport.width = target->extent.width / 2;
viewport.height = target->extent.height / 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); vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
glm::vec4 dpack; glm::vec4 dpack;
dpack[0] = 0; dpack[0] = camera.aperture;
dpack[1] = 0.9581; dpack[1] = (100 - camera.focusDistance) / 100.0f;
dpack[2] = target->extent.width / 2; dpack[2] = target->extent.width / 2;
dpack[3] = target->extent.height / 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); 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); vkCmdEndRenderPass(commandBuffer);
@ -78,9 +80,6 @@ void DoFPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) {
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &target->dofSets[target->currentImage], 0, nullptr); 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); vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(glm::vec4), &dpack);
//FIXME: near field is bugged //FIXME: near field is bugged

View file

@ -349,8 +349,10 @@ int main(int argc, char* argv[]) {
if(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) if(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)
io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY)); io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(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(); ImGui::Render();
renderer->render(world, camera, target); renderer->render(world, camera, target);

View file

@ -78,7 +78,7 @@ void Renderer::render(World& world, Camera& camera, RenderTarget* target) {
vkCmdSetScissor(commandBuffer, 0, 1, &scissor); vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
worldPass_->render(commandBuffer, world, camera, target); worldPass_->render(commandBuffer, world, camera, target);
dofPass_->render(commandBuffer, target); dofPass_->render(commandBuffer, camera, target);
// reset after dof pass // reset after dof pass
vkCmdSetViewport(commandBuffer, 0, 1, &viewport); vkCmdSetViewport(commandBuffer, 0, 1, &viewport);