Image layouts, light positions, use std::abs

This commit is contained in:
saschawillems 2016-09-03 11:21:06 +02:00
parent 0261fc27ba
commit ba4ac1d83e

View file

@ -11,6 +11,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <vector> #include <vector>
#include <algorithm>
#define GLM_FORCE_RADIANS #define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE #define GLM_FORCE_DEPTH_ZERO_TO_ONE
@ -254,13 +255,13 @@ public:
// Each layer corresponds to one of the lights // Each layer corresponds to one of the lights
// The actual output to the separate layers is done in the geometry shader using shader instancing // The actual output to the separate layers is done in the geometry shader using shader instancing
// We will pass the matrices of the lights to the GS that selects the layer by the current invocation // We will pass the matrices of the lights to the GS that selects the layer by the current invocation
vk::AttachmentCreateInfo framebufferInfo = {}; vk::AttachmentCreateInfo attachmentInfo = {};
framebufferInfo.format = SHADOWMAP_FORMAT; attachmentInfo.format = SHADOWMAP_FORMAT;
framebufferInfo.width = SHADOWMAP_DIM; attachmentInfo.width = SHADOWMAP_DIM;
framebufferInfo.height = SHADOWMAP_DIM; attachmentInfo.height = SHADOWMAP_DIM;
framebufferInfo.layerCount = LIGHT_COUNT; attachmentInfo.layerCount = LIGHT_COUNT;
framebufferInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; attachmentInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
frameBuffers.shadow->addAttachment(framebufferInfo); frameBuffers.shadow->addAttachment(attachmentInfo);
// Create sampler to sample from to depth attachment // Create sampler to sample from to depth attachment
// Used to sample in the fragment shader for shadowed rendering // Used to sample in the fragment shader for shadowed rendering
@ -268,6 +269,16 @@ public:
// Create default renderpass for the framebuffer // Create default renderpass for the framebuffer
VK_CHECK_RESULT(frameBuffers.shadow->createRenderPass()); VK_CHECK_RESULT(frameBuffers.shadow->createRenderPass());
VkCommandBuffer cmdBuf = vulkanDevice->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
vkTools::setImageLayout(
cmdBuf,
frameBuffers.shadow->attachments[0].image,
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
frameBuffers.shadow->attachments[0].subresourceRange);
vulkanDevice->flushCommandBuffer(cmdBuf, queue);
} }
// Prepare the framebuffer for offscreen rendering with multiple attachments used as render targets inside the fragment shaders // Prepare the framebuffer for offscreen rendering with multiple attachments used as render targets inside the fragment shaders
@ -279,24 +290,24 @@ public:
frameBuffers.deferred->height = FB_DIM; frameBuffers.deferred->height = FB_DIM;
// Four attachments (3 color, 1 depth) // Four attachments (3 color, 1 depth)
vk::AttachmentCreateInfo framebufferInfo = {}; vk::AttachmentCreateInfo attachmentInfo = {};
framebufferInfo.width = FB_DIM; attachmentInfo.width = FB_DIM;
framebufferInfo.height = FB_DIM; attachmentInfo.height = FB_DIM;
framebufferInfo.layerCount = 1; attachmentInfo.layerCount = 1;
framebufferInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; attachmentInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
// Color attachments // Color attachments
// Attachment 0: (World space) Positions // Attachment 0: (World space) Positions
framebufferInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT; attachmentInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
frameBuffers.deferred->addAttachment(framebufferInfo); frameBuffers.deferred->addAttachment(attachmentInfo);
// Attachment 1: (World space) Normals // Attachment 1: (World space) Normals
framebufferInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT; attachmentInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
frameBuffers.deferred->addAttachment(framebufferInfo); frameBuffers.deferred->addAttachment(attachmentInfo);
// Attachment 2: Albedo (color) // Attachment 2: Albedo (color)
framebufferInfo.format = VK_FORMAT_R8G8B8A8_UNORM; attachmentInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
frameBuffers.deferred->addAttachment(framebufferInfo); frameBuffers.deferred->addAttachment(attachmentInfo);
// Depth attachment // Depth attachment
// Find a suitable depth format // Find a suitable depth format
@ -304,9 +315,9 @@ public:
VkBool32 validDepthFormat = vkTools::getSupportedDepthFormat(physicalDevice, &attDepthFormat); VkBool32 validDepthFormat = vkTools::getSupportedDepthFormat(physicalDevice, &attDepthFormat);
assert(validDepthFormat); assert(validDepthFormat);
framebufferInfo.format = attDepthFormat; attachmentInfo.format = attDepthFormat;
framebufferInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; attachmentInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
frameBuffers.deferred->addAttachment(framebufferInfo); frameBuffers.deferred->addAttachment(attachmentInfo);
// Create sampler to sample from the color attachments // Create sampler to sample from the color attachments
VK_CHECK_RESULT(frameBuffers.deferred->createSampler(VK_FILTER_LINEAR, VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)); VK_CHECK_RESULT(frameBuffers.deferred->createSampler(VK_FILTER_LINEAR, VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE));
@ -1001,56 +1012,47 @@ public:
vkUnmapMemory(device, uniformData.vsOffscreen.memory); vkUnmapMemory(device, uniformData.vsOffscreen.memory);
} }
Light initLight(glm::vec3 pos, glm::vec3 target, glm::vec3 color)
{
Light light;
light.position = glm::vec4(pos, 1.0f);
light.target = glm::vec4(target, 0.0f);
light.color = glm::vec4(color, 0.0f);
return light;
}
void initLights()
{
uboFragmentLights.lights[0] = initLight(glm::vec3(-14.0f, -0.5f, 15.0f), glm::vec3(-2.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.5f, 0.5f));
uboFragmentLights.lights[1] = initLight(glm::vec3(14.0f, -4.0f, 12.0f), glm::vec3(2.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
uboFragmentLights.lights[2] = initLight(glm::vec3(0.0f, -10.0f, 4.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f));
}
// Update fragment shader light position uniform block // Update fragment shader light position uniform block
void updateUniformBufferDeferredLights() void updateUniformBufferDeferredLights()
{ {
std::vector<glm::vec4> lightPositions =
{
glm::vec4(-14.0f, -0.5f, 15.0f, 0.0f),
glm::vec4(14.0f, -4.0f, 12.0f, 0.0f),
glm::vec4(0.0f, -10.0f, 4.0f, 0.0f)
};
std::vector<glm::vec4> lightColors =
{
glm::vec4(1.0f, 0.5f, 0.5f, 0.0f),
glm::vec4(0.0f, 0.0f, 1.0f, 0.0f),
glm::vec4(1.0f, 1.0f, 1.0f, 0.0f),
};
std::vector<glm::vec4> lightTargets =
{
glm::vec4(-2.0f, 0.0f, 0.0f, 0.0f),
glm::vec4(2.0f, 0.0f, 0.0f, 0.0f),
glm::vec4(0.0f, 0.0f, 0.0f, 0.0f),
};
// Animate // Animate
if (!paused) //if (!paused)
{ {
lightPositions[0].x = -14.0f + abs(sin(glm::radians(timer * 360.0f)) * 20.0f); uboFragmentLights.lights[0].position.x = -14.0f + std::abs(sin(glm::radians(timer * 360.0f)) * 20.0f);
lightPositions[0].z = 15.0f + cos(glm::radians(timer *360.0f)) * 1.0f; uboFragmentLights.lights[0].position.z = 15.0f + cos(glm::radians(timer *360.0f)) * 1.0f;
lightPositions[1].x = 14.0f - abs(sin(glm::radians(timer * 360.0f)) * 2.5f); uboFragmentLights.lights[1].position.x = 14.0f - std::abs(sin(glm::radians(timer * 360.0f)) * 2.5f);
lightPositions[1].z = 13.0f + cos(glm::radians(timer *360.0f)) * 4.0f; uboFragmentLights.lights[1].position.z = 13.0f + cos(glm::radians(timer *360.0f)) * 4.0f;
lightPositions[2].x = 0.0f + sin(glm::radians(timer *360.0f)) * 4.0f; uboFragmentLights.lights[2].position.x = 0.0f + sin(glm::radians(timer *360.0f)) * 4.0f;
lightPositions[2].z = 4.0f + cos(glm::radians(timer *360.0f)) * 2.0f; uboFragmentLights.lights[2].position.z = 4.0f + cos(glm::radians(timer *360.0f)) * 2.0f;
} }
for (uint32_t i = 0; i < static_cast<uint32_t>(lightPositions.size()); i++) for (uint32_t i = 0; i < LIGHT_COUNT; i++)
{ {
Light *light = &uboFragmentLights.lights[i];
light->position = lightPositions[i];
light->color = lightColors[i];
light->target = lightTargets[i];
// mvp from light's pov (for shadows) // mvp from light's pov (for shadows)
glm::mat4 shadowProj = glm::perspective(glm::radians(lightFOV), 1.0f, zNear, zFar); glm::mat4 shadowProj = glm::perspective(glm::radians(lightFOV), 1.0f, zNear, zFar);
glm::mat4 shadowView = glm::lookAt(glm::vec3(light->position), glm::vec3(light->target), glm::vec3(0.0f, 1.0f, 0.0f)); glm::mat4 shadowView = glm::lookAt(glm::vec3(uboFragmentLights.lights[i].position), glm::vec3(uboFragmentLights.lights[i].target), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 shadowModel = glm::mat4(); glm::mat4 shadowModel = glm::mat4();
uboShadowGS.mvp[i] = shadowProj * shadowView * shadowModel; uboShadowGS.mvp[i] = shadowProj * shadowView * shadowModel;
light->viewMatrix = uboShadowGS.mvp[i]; uboFragmentLights.lights[i].viewMatrix = uboShadowGS.mvp[i];
} }
uint8_t *pData; uint8_t *pData;
@ -1061,7 +1063,6 @@ public:
memcpy(pData, &uboShadowGS, sizeof(uboShadowGS)); memcpy(pData, &uboShadowGS, sizeof(uboShadowGS));
vkUnmapMemory(device, uniformData.uboShadowGS.memory); vkUnmapMemory(device, uniformData.uboShadowGS.memory);
uboFragmentLights.viewPos = glm::vec4(uboOffscreenVS.view[3]);
uboFragmentLights.viewPos = glm::vec4(camera.position, 0.0f) * glm::vec4(-1.0f, 1.0f, -1.0f, 1.0f);; uboFragmentLights.viewPos = glm::vec4(camera.position, 0.0f) * glm::vec4(-1.0f, 1.0f, -1.0f, 1.0f);;
VK_CHECK_RESULT(vkMapMemory(device, uniformData.fsLights.memory, 0, sizeof(uboFragmentLights), 0, (void **)&pData)); VK_CHECK_RESULT(vkMapMemory(device, uniformData.fsLights.memory, 0, sizeof(uboFragmentLights), 0, (void **)&pData));
@ -1110,6 +1111,7 @@ public:
setupVertexDescriptions(); setupVertexDescriptions();
deferredSetup(); deferredSetup();
shadowSetup(); shadowSetup();
initLights();
prepareUniformBuffers(); prepareUniformBuffers();
setupDescriptorSetLayout(); setupDescriptorSetLayout();
preparePipelines(); preparePipelines();
@ -1125,8 +1127,7 @@ public:
if (!prepared) if (!prepared)
return; return;
draw(); draw();
//if (!paused) updateUniformBufferDeferredLights();
updateUniformBufferDeferredLights();
} }
virtual void viewChanged() virtual void viewChanged()