Add configurable camera aperture/focus
This commit is contained in:
parent
42bbae3da8
commit
6d2fd5caaa
7 changed files with 20 additions and 27 deletions
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Reference in a new issue