diff --git a/data/shaders/deferredshadows/debug.frag b/data/shaders/deferredshadows/debug.frag index 06a2e090..8ec60922 100644 --- a/data/shaders/deferredshadows/debug.frag +++ b/data/shaders/deferredshadows/debug.frag @@ -14,30 +14,16 @@ layout (location = 0) out vec4 outFragColor; float LinearizeDepth(float depth) { - float n = 1.0; // camera z near - float f = 96.0; // camera z far + float n = 0.1; // camera z near + float f = 64.0; // camera z far float z = depth; return (2.0 * n) / (f + n - z * (f - n)); } void main() { - vec3 components[3]; - components[0] = texture(samplerPosition, inUV.st).rgb; - components[1] = texture(samplerNormal, inUV.st).rgb; - //components[2] = texture(samplerDepth, inUV.st).rgb; - // 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]; - } + // Display depth from light's point-of-view + // inUV.w = number of light source + float depth = texture(samplerDepth, vec3(inUV)).r; + outFragColor = vec4(vec3(1.0 - LinearizeDepth(depth)), 0.0); } \ No newline at end of file diff --git a/data/shaders/deferredshadows/debug.frag.spv b/data/shaders/deferredshadows/debug.frag.spv index af44ecc2..39a88b28 100644 Binary files a/data/shaders/deferredshadows/debug.frag.spv and b/data/shaders/deferredshadows/debug.frag.spv differ diff --git a/data/shaders/deferredshadows/debug.vert b/data/shaders/deferredshadows/debug.vert index af5ced49..40833b18 100644 --- a/data/shaders/deferredshadows/debug.vert +++ b/data/shaders/deferredshadows/debug.vert @@ -5,12 +5,11 @@ layout (location = 0) in vec3 inPos; layout (location = 1) in vec2 inUV; -layout (location = 3) in vec3 inNormal; layout (binding = 0) uniform UBO { mat4 projection; - mat4 model; + mat4 modelview; } ubo; layout (location = 0) out vec3 outUV; @@ -22,6 +21,9 @@ out gl_PerVertex void main() { - outUV = vec3(inUV.st, inNormal.z); - gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0); + outUV = vec3(inUV.st, gl_InstanceIndex); + 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; } diff --git a/data/shaders/deferredshadows/debug.vert.spv b/data/shaders/deferredshadows/debug.vert.spv index 4300cf84..f7b69969 100644 Binary files a/data/shaders/deferredshadows/debug.vert.spv and b/data/shaders/deferredshadows/debug.vert.spv differ diff --git a/data/shaders/deferredshadows/deferred.frag b/data/shaders/deferredshadows/deferred.frag index 263a66e3..4562a767 100644 --- a/data/shaders/deferredshadows/deferred.frag +++ b/data/shaders/deferredshadows/deferred.frag @@ -31,6 +31,7 @@ layout (binding = 4) uniform UBO { vec4 viewPos; Light lights[LIGHT_COUNT]; + int useShadows; } ubo; float textureProj(vec4 P, float layer, vec2 offset) @@ -124,18 +125,21 @@ void main() } // 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; - #ifdef USE_PCF - shadowFactor= filterPCF(shadowClip, i); - #else - shadowFactor = textureProj(shadowClip, i, vec2(0.0)); - #endif + float shadowFactor; + #ifdef USE_PCF + shadowFactor= filterPCF(shadowClip, i); + #else + shadowFactor = textureProj(shadowClip, i, vec2(0.0)); + #endif - fragcolor *= shadowFactor; + fragcolor *= shadowFactor; + } } outFragColor.rgb = fragcolor; diff --git a/data/shaders/deferredshadows/deferred.frag.spv b/data/shaders/deferredshadows/deferred.frag.spv index d0f517a6..77359095 100644 Binary files a/data/shaders/deferredshadows/deferred.frag.spv and b/data/shaders/deferredshadows/deferred.frag.spv differ diff --git a/data/shaders/deferredshadows/deferred.vert b/data/shaders/deferredshadows/deferred.vert index 48e1365c..e13d0aff 100644 --- a/data/shaders/deferredshadows/deferred.vert +++ b/data/shaders/deferredshadows/deferred.vert @@ -10,7 +10,6 @@ layout (binding = 0) uniform UBO { mat4 projection; mat4 modelview; - mat4 lightMVP; } ubo; layout (location = 0) out vec2 outUV; diff --git a/data/shaders/deferredshadows/deferred.vert.spv b/data/shaders/deferredshadows/deferred.vert.spv index bc47c34a..5f41a5ed 100644 Binary files a/data/shaders/deferredshadows/deferred.vert.spv and b/data/shaders/deferredshadows/deferred.vert.spv differ diff --git a/deferredshadows/deferredshadows.cpp b/deferredshadows/deferredshadows.cpp index e18eb570..83a2c4ab 100644 --- a/deferredshadows/deferredshadows.cpp +++ b/deferredshadows/deferredshadows.cpp @@ -26,7 +26,7 @@ #define ENABLE_VALIDATION false // Shadowmap properties -#define SHADOWMAP_DIM 2048 +#define SHADOWMAP_DIM 1024 // 16 bits of depth is enough for such a small scene #define SHADOWMAP_FORMAT VK_FORMAT_D32_SFLOAT_S8_UINT @@ -50,12 +50,13 @@ class VulkanExample : public VulkanExampleBase { public: bool debugDisplay = false; + bool enableShadows = true; // Keep depth range as small as possible // for better shadow map precision float zNear = 0.1f; float zFar = 64.0f; - float lightFOV = 120.0f; + float lightFOV = 100.0f; // Depth bias (and slope) are used to avoid shadowing artefacts float depthBiasConstant = 1.25f; @@ -110,6 +111,7 @@ public: struct { glm::vec4 viewPos; Light lights[LIGHT_COUNT]; + uint32_t useShadows = 1; } uboFragmentLights; struct { @@ -170,7 +172,7 @@ public: VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION, getEnabledFeatures) { 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.movementSpeed = 5.0f; camera.rotationSpeed = 0.25f; @@ -510,23 +512,18 @@ public: VkDeviceSize offsets[1] = { 0 }; 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 vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.deferred); 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], 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]); @@ -545,10 +542,9 @@ public: 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() { - // Setup vertices for multiple screen aligned quads - // Used for displaying final result and debug struct Vertex { float pos[3]; float uv[2]; @@ -559,22 +555,10 @@ public: std::vector vertexBuffer; - float x = 0.0f; - float y = 0.0f; - for (uint32_t i = 0; i < 3; i++) - { - // 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; - } - } + 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 } }); + 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 } }); + 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 } }); createBuffer( VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, @@ -1040,14 +1024,7 @@ public: void updateUniformBuffersScreen() { - if (debugDisplay) - { - 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.projection = glm::ortho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); uboVS.model = glm::mat4(); uint8_t *pData; @@ -1079,7 +1056,6 @@ public: }; std::vector lightColors = { -// glm::vec4(1.0f), 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), @@ -1209,6 +1185,12 @@ public: updateUniformBuffersScreen(); } + void toggleShadows() + { + uboFragmentLights.useShadows = !uboFragmentLights.useShadows; + updateUniformBufferDeferredLights(); + } + virtual void keyPressed(uint32_t keyCode) { switch (keyCode) @@ -1218,24 +1200,23 @@ public: toggleDebugDisplay(); updateTextOverlay(); break; + case 0x71: + case GAMEPAD_BUTTON_B: + toggleShadows(); + updateTextOverlay(); + break; } } virtual void getOverlayText(VulkanTextOverlay *textOverlay) { #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 - 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 - // 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); - } } };