Added debug display for light source depth maps and shadow toggle
This commit is contained in:
parent
1e4e233f81
commit
7f687570d4
9 changed files with 59 additions and 87 deletions
|
|
@ -14,30 +14,16 @@ layout (location = 0) out vec4 outFragColor;
|
||||||
|
|
||||||
float LinearizeDepth(float depth)
|
float LinearizeDepth(float depth)
|
||||||
{
|
{
|
||||||
float n = 1.0; // camera z near
|
float n = 0.1; // camera z near
|
||||||
float f = 96.0; // camera z far
|
float f = 64.0; // camera z far
|
||||||
float z = depth;
|
float z = depth;
|
||||||
return (2.0 * n) / (f + n - z * (f - n));
|
return (2.0 * n) / (f + n - z * (f - n));
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 components[3];
|
// Display depth from light's point-of-view
|
||||||
components[0] = texture(samplerPosition, inUV.st).rgb;
|
// inUV.w = number of light source
|
||||||
components[1] = texture(samplerNormal, inUV.st).rgb;
|
float depth = texture(samplerDepth, vec3(inUV)).r;
|
||||||
//components[2] = texture(samplerDepth, inUV.st).rgb;
|
outFragColor = vec4(vec3(1.0 - LinearizeDepth(depth)), 0.0);
|
||||||
// Uncomment to display specular component
|
|
||||||
//components[2] = vec3(texture(samplerAlbedo, inUV.st).a);
|
|
||||||
|
|
||||||
// Select component depending on z coordinate of quad
|
|
||||||
highp int index = int(inUV.z);
|
|
||||||
if (index == 2)
|
|
||||||
{
|
|
||||||
float depth = texture(samplerDepth, vec3(inUV.st, 2.0)).r;
|
|
||||||
outFragColor = vec4(vec3(1.0-LinearizeDepth(depth)), 1.0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
outFragColor.rgb = components[index];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
|
@ -5,12 +5,11 @@
|
||||||
|
|
||||||
layout (location = 0) in vec3 inPos;
|
layout (location = 0) in vec3 inPos;
|
||||||
layout (location = 1) in vec2 inUV;
|
layout (location = 1) in vec2 inUV;
|
||||||
layout (location = 3) in vec3 inNormal;
|
|
||||||
|
|
||||||
layout (binding = 0) uniform UBO
|
layout (binding = 0) uniform UBO
|
||||||
{
|
{
|
||||||
mat4 projection;
|
mat4 projection;
|
||||||
mat4 model;
|
mat4 modelview;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
layout (location = 0) out vec3 outUV;
|
layout (location = 0) out vec3 outUV;
|
||||||
|
|
@ -22,6 +21,9 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outUV = vec3(inUV.st, inNormal.z);
|
outUV = vec3(inUV.st, gl_InstanceIndex);
|
||||||
gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0);
|
vec4 tmpPos = vec4(inPos, 1.0);
|
||||||
|
tmpPos.y += gl_InstanceIndex;
|
||||||
|
tmpPos.xy *= vec2(1.0/4.0, 1.0/3.0);
|
||||||
|
gl_Position = ubo.projection * ubo.modelview * tmpPos;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -31,6 +31,7 @@ layout (binding = 4) uniform UBO
|
||||||
{
|
{
|
||||||
vec4 viewPos;
|
vec4 viewPos;
|
||||||
Light lights[LIGHT_COUNT];
|
Light lights[LIGHT_COUNT];
|
||||||
|
int useShadows;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
float textureProj(vec4 P, float layer, vec2 offset)
|
float textureProj(vec4 P, float layer, vec2 offset)
|
||||||
|
|
@ -124,18 +125,21 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shadow calculations in a separate pass
|
// Shadow calculations in a separate pass
|
||||||
for(int i = 0; i < LIGHT_COUNT; ++i)
|
if (ubo.useShadows > 0)
|
||||||
{
|
{
|
||||||
vec4 shadowClip = ubo.lights[i].viewMatrix * vec4(fragPos, 1.0);
|
for(int i = 0; i < LIGHT_COUNT; ++i)
|
||||||
|
{
|
||||||
|
vec4 shadowClip = ubo.lights[i].viewMatrix * vec4(fragPos, 1.0);
|
||||||
|
|
||||||
float shadowFactor;
|
float shadowFactor;
|
||||||
#ifdef USE_PCF
|
#ifdef USE_PCF
|
||||||
shadowFactor= filterPCF(shadowClip, i);
|
shadowFactor= filterPCF(shadowClip, i);
|
||||||
#else
|
#else
|
||||||
shadowFactor = textureProj(shadowClip, i, vec2(0.0));
|
shadowFactor = textureProj(shadowClip, i, vec2(0.0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fragcolor *= shadowFactor;
|
fragcolor *= shadowFactor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outFragColor.rgb = fragcolor;
|
outFragColor.rgb = fragcolor;
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -10,7 +10,6 @@ layout (binding = 0) uniform UBO
|
||||||
{
|
{
|
||||||
mat4 projection;
|
mat4 projection;
|
||||||
mat4 modelview;
|
mat4 modelview;
|
||||||
mat4 lightMVP;
|
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
layout (location = 0) out vec2 outUV;
|
layout (location = 0) out vec2 outUV;
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -26,7 +26,7 @@
|
||||||
#define ENABLE_VALIDATION false
|
#define ENABLE_VALIDATION false
|
||||||
|
|
||||||
// Shadowmap properties
|
// Shadowmap properties
|
||||||
#define SHADOWMAP_DIM 2048
|
#define SHADOWMAP_DIM 1024
|
||||||
// 16 bits of depth is enough for such a small scene
|
// 16 bits of depth is enough for such a small scene
|
||||||
#define SHADOWMAP_FORMAT VK_FORMAT_D32_SFLOAT_S8_UINT
|
#define SHADOWMAP_FORMAT VK_FORMAT_D32_SFLOAT_S8_UINT
|
||||||
|
|
||||||
|
|
@ -50,12 +50,13 @@ class VulkanExample : public VulkanExampleBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool debugDisplay = false;
|
bool debugDisplay = false;
|
||||||
|
bool enableShadows = true;
|
||||||
|
|
||||||
// Keep depth range as small as possible
|
// Keep depth range as small as possible
|
||||||
// for better shadow map precision
|
// for better shadow map precision
|
||||||
float zNear = 0.1f;
|
float zNear = 0.1f;
|
||||||
float zFar = 64.0f;
|
float zFar = 64.0f;
|
||||||
float lightFOV = 120.0f;
|
float lightFOV = 100.0f;
|
||||||
|
|
||||||
// Depth bias (and slope) are used to avoid shadowing artefacts
|
// Depth bias (and slope) are used to avoid shadowing artefacts
|
||||||
float depthBiasConstant = 1.25f;
|
float depthBiasConstant = 1.25f;
|
||||||
|
|
@ -110,6 +111,7 @@ public:
|
||||||
struct {
|
struct {
|
||||||
glm::vec4 viewPos;
|
glm::vec4 viewPos;
|
||||||
Light lights[LIGHT_COUNT];
|
Light lights[LIGHT_COUNT];
|
||||||
|
uint32_t useShadows = 1;
|
||||||
} uboFragmentLights;
|
} uboFragmentLights;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -170,7 +172,7 @@ public:
|
||||||
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION, getEnabledFeatures)
|
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION, getEnabledFeatures)
|
||||||
{
|
{
|
||||||
enableTextOverlay = true;
|
enableTextOverlay = true;
|
||||||
title = "Vulkan Example - Deferred shading with shadow mapping";
|
title = "Vulkan Example - Deferred shading with shadows (2016 by Sascha Willems)";
|
||||||
camera.type = Camera::CameraType::firstperson;
|
camera.type = Camera::CameraType::firstperson;
|
||||||
camera.movementSpeed = 5.0f;
|
camera.movementSpeed = 5.0f;
|
||||||
camera.rotationSpeed = 0.25f;
|
camera.rotationSpeed = 0.25f;
|
||||||
|
|
@ -510,23 +512,18 @@ public:
|
||||||
VkDeviceSize offsets[1] = { 0 };
|
VkDeviceSize offsets[1] = { 0 };
|
||||||
vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.deferred, 0, 1, &descriptorSet, 0, NULL);
|
vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.deferred, 0, 1, &descriptorSet, 0, NULL);
|
||||||
|
|
||||||
if (debugDisplay)
|
|
||||||
{
|
|
||||||
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.debug);
|
|
||||||
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &meshes.quad.vertices.buf, offsets);
|
|
||||||
vkCmdBindIndexBuffer(drawCmdBuffers[i], meshes.quad.indices.buf, 0, VK_INDEX_TYPE_UINT32);
|
|
||||||
vkCmdDrawIndexed(drawCmdBuffers[i], meshes.quad.indexCount, 1, 0, 0, 1);
|
|
||||||
// Move viewport to display final composition in lower right corner
|
|
||||||
viewport.x = viewport.width * 0.5f;
|
|
||||||
viewport.y = viewport.height * 0.5f;
|
|
||||||
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Final composition as full screen quad
|
// Final composition as full screen quad
|
||||||
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.deferred);
|
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.deferred);
|
||||||
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &meshes.quad.vertices.buf, offsets);
|
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &meshes.quad.vertices.buf, offsets);
|
||||||
vkCmdBindIndexBuffer(drawCmdBuffers[i], meshes.quad.indices.buf, 0, VK_INDEX_TYPE_UINT32);
|
vkCmdBindIndexBuffer(drawCmdBuffers[i], meshes.quad.indices.buf, 0, VK_INDEX_TYPE_UINT32);
|
||||||
vkCmdDrawIndexed(drawCmdBuffers[i], 6, 1, 0, 0, 1);
|
vkCmdDrawIndexed(drawCmdBuffers[i], 6, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
if (debugDisplay)
|
||||||
|
{
|
||||||
|
// Visualize depth maps
|
||||||
|
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.debug);
|
||||||
|
vkCmdDrawIndexed(drawCmdBuffers[i], 6, LIGHT_COUNT, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
||||||
|
|
||||||
|
|
@ -545,10 +542,9 @@ public:
|
||||||
loadMesh(getAssetPath() + "models/openbox.dae", &meshes.background, vertexLayout, &meshCreateInfo);
|
loadMesh(getAssetPath() + "models/openbox.dae", &meshes.background, vertexLayout, &meshCreateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Create a single quad for fullscreen deferred pass and debug passes (debug pass uses instancing for light visualization) */
|
||||||
void generateQuads()
|
void generateQuads()
|
||||||
{
|
{
|
||||||
// Setup vertices for multiple screen aligned quads
|
|
||||||
// Used for displaying final result and debug
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
float pos[3];
|
float pos[3];
|
||||||
float uv[2];
|
float uv[2];
|
||||||
|
|
@ -559,22 +555,10 @@ public:
|
||||||
|
|
||||||
std::vector<Vertex> vertexBuffer;
|
std::vector<Vertex> vertexBuffer;
|
||||||
|
|
||||||
float x = 0.0f;
|
vertexBuffer.push_back({ { 1.0f, 1.0f, 0.0f },{ 1.0f, 1.0f },{ 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, 0.0f } });
|
||||||
float y = 0.0f;
|
vertexBuffer.push_back({ { 0.0f, 1.0f, 0.0f },{ 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, 0.0f } });
|
||||||
for (uint32_t i = 0; i < 3; i++)
|
vertexBuffer.push_back({ { 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f },{ 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, 0.0f } });
|
||||||
{
|
vertexBuffer.push_back({ { 1.0f, 0.0f, 0.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, 0.0f } });
|
||||||
// Last component of normal is used for debug display sampler index
|
|
||||||
vertexBuffer.push_back({ { x + 1.0f, y + 1.0f, 0.0f },{ 1.0f, 1.0f },{ 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, (float)i } });
|
|
||||||
vertexBuffer.push_back({ { x, y + 1.0f, 0.0f },{ 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, (float)i } });
|
|
||||||
vertexBuffer.push_back({ { x, y, 0.0f },{ 0.0f, 0.0f },{ 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, (float)i } });
|
|
||||||
vertexBuffer.push_back({ { x + 1.0f, y, 0.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, (float)i } });
|
|
||||||
x += 1.0f;
|
|
||||||
if (x > 1.0f)
|
|
||||||
{
|
|
||||||
x = 0.0f;
|
|
||||||
y += 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createBuffer(
|
createBuffer(
|
||||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||||
|
|
@ -1040,14 +1024,7 @@ public:
|
||||||
|
|
||||||
void updateUniformBuffersScreen()
|
void updateUniformBuffersScreen()
|
||||||
{
|
{
|
||||||
if (debugDisplay)
|
uboVS.projection = glm::ortho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
|
||||||
{
|
|
||||||
uboVS.projection = glm::ortho(0.0f, 2.0f, 0.0f, 2.0f, -1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uboVS.projection = glm::ortho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
uboVS.model = glm::mat4();
|
uboVS.model = glm::mat4();
|
||||||
|
|
||||||
uint8_t *pData;
|
uint8_t *pData;
|
||||||
|
|
@ -1079,7 +1056,6 @@ public:
|
||||||
};
|
};
|
||||||
std::vector<glm::vec4> lightColors =
|
std::vector<glm::vec4> lightColors =
|
||||||
{
|
{
|
||||||
// glm::vec4(1.0f),
|
|
||||||
glm::vec4(1.0f, 0.5f, 0.5f, 0.0f),
|
glm::vec4(1.0f, 0.5f, 0.5f, 0.0f),
|
||||||
glm::vec4(0.0f, 0.0f, 1.0f, 0.0f),
|
glm::vec4(0.0f, 0.0f, 1.0f, 0.0f),
|
||||||
glm::vec4(1.0f, 1.0f, 1.0f, 0.0f),
|
glm::vec4(1.0f, 1.0f, 1.0f, 0.0f),
|
||||||
|
|
@ -1209,6 +1185,12 @@ public:
|
||||||
updateUniformBuffersScreen();
|
updateUniformBuffersScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toggleShadows()
|
||||||
|
{
|
||||||
|
uboFragmentLights.useShadows = !uboFragmentLights.useShadows;
|
||||||
|
updateUniformBufferDeferredLights();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void keyPressed(uint32_t keyCode)
|
virtual void keyPressed(uint32_t keyCode)
|
||||||
{
|
{
|
||||||
switch (keyCode)
|
switch (keyCode)
|
||||||
|
|
@ -1218,24 +1200,23 @@ public:
|
||||||
toggleDebugDisplay();
|
toggleDebugDisplay();
|
||||||
updateTextOverlay();
|
updateTextOverlay();
|
||||||
break;
|
break;
|
||||||
|
case 0x71:
|
||||||
|
case GAMEPAD_BUTTON_B:
|
||||||
|
toggleShadows();
|
||||||
|
updateTextOverlay();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void getOverlayText(VulkanTextOverlay *textOverlay)
|
virtual void getOverlayText(VulkanTextOverlay *textOverlay)
|
||||||
{
|
{
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
textOverlay->addText("Press \"Button A\" to toggle debug display", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
textOverlay->addText("Press \"Button A\" to toggle debug view", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
||||||
|
textOverlay->addText("Press \"Button A\" to toggle shadows", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
|
||||||
#else
|
#else
|
||||||
textOverlay->addText("Press \"F1\" to toggle debug display", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
textOverlay->addText("Press \"F1\" to toggle debug view", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
||||||
|
textOverlay->addText("Press \"F2\" to toggle shadows", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
|
||||||
#endif
|
#endif
|
||||||
// Render targets
|
|
||||||
if (debugDisplay)
|
|
||||||
{
|
|
||||||
textOverlay->addText("World space position", (float)width * 0.25f, (float)height * 0.5f - 25.0f, VulkanTextOverlay::alignCenter);
|
|
||||||
textOverlay->addText("World space normals", (float)width * 0.75f, (float)height * 0.5f - 25.0f, VulkanTextOverlay::alignCenter);
|
|
||||||
textOverlay->addText("Albedo", (float)width * 0.25f, (float)height - 25.0f, VulkanTextOverlay::alignCenter);
|
|
||||||
textOverlay->addText("Final image", (float)width * 0.75f, (float)height - 25.0f, VulkanTextOverlay::alignCenter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue