diff --git a/README.md b/README.md
index 3a713055..277aad92 100644
--- a/README.md
+++ b/README.md
@@ -84,7 +84,8 @@ Distance field font textures can be generated with tools like [Hiero](https://gi
## [Pipelines](pipelines/)
-Pipelines replace the huge (and cumbersome) state machine of OpenGL. This example creates different pipelines with different states and shader setups.
+[Pipeline state objects](https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#pipelines) replace the biggest part of the dynamic state machine from OpenGL, baking state information for culling, blending, rasterization, etc. and shaders into a fixed stat that can be optimized much easier by the implementation.
+This example uses three different PSOs for rendering the same scene with different visuals and shaders and also demonstrates the use [pipeline derivatives](https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#pipelines-pipeline-derivatives).
## [Gears](gears/)
@@ -220,7 +221,7 @@ Implements a simple ray tracer using a compute shader. No primitives are rendere
## [(Compute shader) Image processing](computeshader/)
-
+
Demonstrates the use of a separate compute queue (and command buffer) to apply different convolution kernels on an input image in realtime.
@@ -255,6 +256,7 @@ Please note that (some) models and textures use separate licenses. Please comply
- Voyager model by [NASA](http://nasa3d.arc.nasa.gov/models)
- Astroboy COLLADA model copyright 2008 Sony Computer Entertainment Inc.
- Old deer model used in tessellation example by [Čestmír Dammer](http://opengameart.org/users/cdmir)
+- Hidden treasure scene used in pipeline and debug marker examples by [Laurynas Jurgila](http://www.blendswap.com/user/PigArt)
- Textures used in some examples by [Hugues Muller](http://www.yughues-folio.com)
- Updated compute particle system shader by [Lukas Bergdoll](https://github.com/Voultapher)
- Vulkan scene model (and derived models) by [Dominic Agoro-Ombaka](http://www.agorodesign.com/) and [Sascha Willems](http://www.saschawillems.de)
diff --git a/data/shaders/pipelines/base.vert b/data/shaders/pipelines/base.vert
deleted file mode 100644
index 6adc1349..00000000
--- a/data/shaders/pipelines/base.vert
+++ /dev/null
@@ -1,28 +0,0 @@
-#version 450
-
-#extension GL_ARB_separate_shader_objects : enable
-#extension GL_ARB_shading_language_420pack : enable
-
-layout (location = 0) in vec3 inPos;
-layout (location = 1) in vec3 inColor;
-layout (location = 2) in vec2 inUV;
-layout (location = 3) in vec3 inNormal;
-
-layout (binding = 0) uniform UBO
-{
- mat4 projectionMatrix;
- mat4 modelMatrix;
- mat4 viewMatrix;
-} ubo;
-
-layout (location = 0) out vec3 outColor;
-layout (location = 1) out vec2 outUV;
-layout (location = 2) out vec3 outNormal;
-
-void main()
-{
- outColor = inColor;
- outUV = inUV;
- outNormal = inNormal;
- gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(inPos.xyz, 1.0);
-}
diff --git a/data/shaders/pipelines/base.vert.spv b/data/shaders/pipelines/base.vert.spv
deleted file mode 100644
index 22cd95b9..00000000
Binary files a/data/shaders/pipelines/base.vert.spv and /dev/null differ
diff --git a/data/shaders/pipelines/color.frag b/data/shaders/pipelines/color.frag
deleted file mode 100644
index e5abb03d..00000000
--- a/data/shaders/pipelines/color.frag
+++ /dev/null
@@ -1,10 +0,0 @@
-#version 450
-
-layout (location = 0 ) in vec3 inColor;
-
-layout (location = 0) out vec4 outFragColor;
-
-void main()
-{
- outFragColor = vec4(inColor, 1.0);
-}
\ No newline at end of file
diff --git a/data/shaders/pipelines/color.frag.spv b/data/shaders/pipelines/color.frag.spv
deleted file mode 100644
index 1a102443..00000000
Binary files a/data/shaders/pipelines/color.frag.spv and /dev/null differ
diff --git a/data/shaders/pipelines/generate-spriv.bat b/data/shaders/pipelines/generate-spriv.bat
index 175c2508..17806643 100644
--- a/data/shaders/pipelines/generate-spriv.bat
+++ b/data/shaders/pipelines/generate-spriv.bat
@@ -1,6 +1,7 @@
-glslangvalidator -V base.vert -o base.vert.spv
-glslangvalidator -V base.frag -o base.frag.spv
-glslangvalidator -V color.frag -o color.frag.spv
-glslangvalidator -V texture.frag -o texture.frag.spv
+glslangvalidator -V phong.vert -o phong.vert.spv
+glslangvalidator -V phong.frag -o phong.frag.spv
+glslangvalidator -V wireframe.vert -o wireframe.vert.spv
glslangvalidator -V wireframe.frag -o wireframe.frag.spv
+glslangvalidator -V toon.vert -o toon.vert.spv
+glslangvalidator -V toon.frag -o toon.frag.spv
diff --git a/data/shaders/pipelines/phong.frag b/data/shaders/pipelines/phong.frag
new file mode 100644
index 00000000..4eabd4da
--- /dev/null
+++ b/data/shaders/pipelines/phong.frag
@@ -0,0 +1,30 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (binding = 1) uniform sampler2D samplerColorMap;
+
+layout (location = 0) in vec3 inNormal;
+layout (location = 1) in vec3 inColor;
+layout (location = 2) in vec2 inUV;
+layout (location = 3) in vec3 inViewVec;
+layout (location = 4) in vec3 inLightVec;
+
+layout (location = 0) out vec4 outFragColor;
+
+void main()
+{
+ // Desaturate color
+ vec3 color = vec3(mix(inColor, vec3(dot(vec3(0.2126,0.7152,0.0722), inColor)), 0.65));
+
+ // High ambient colors because mesh materials are pretty dark
+ vec3 ambient = color * vec3(1.0);
+ vec3 N = normalize(inNormal);
+ vec3 L = normalize(inLightVec);
+ vec3 V = normalize(inViewVec);
+ vec3 R = reflect(-L, N);
+ vec3 diffuse = max(dot(N, L), 0.0) * color;
+ vec3 specular = pow(max(dot(R, V), 0.0), 32.0) * vec3(0.35);
+ outFragColor = vec4(ambient + diffuse * 1.75 + specular, 1.0);
+}
\ No newline at end of file
diff --git a/data/shaders/pipelines/phong.frag.spv b/data/shaders/pipelines/phong.frag.spv
new file mode 100644
index 00000000..1e547c40
Binary files /dev/null and b/data/shaders/pipelines/phong.frag.spv differ
diff --git a/data/shaders/pipelines/phong.vert b/data/shaders/pipelines/phong.vert
new file mode 100644
index 00000000..293173bf
--- /dev/null
+++ b/data/shaders/pipelines/phong.vert
@@ -0,0 +1,41 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inPos;
+layout (location = 1) in vec3 inNormal;
+layout (location = 2) in vec2 inUV;
+layout (location = 3) in vec3 inColor;
+
+layout (binding = 0) uniform UBO
+{
+ mat4 projection;
+ mat4 model;
+ vec4 lightPos;
+} ubo;
+
+layout (location = 0) out vec3 outNormal;
+layout (location = 1) out vec3 outColor;
+layout (location = 2) out vec2 outUV;
+layout (location = 3) out vec3 outViewVec;
+layout (location = 4) out vec3 outLightVec;
+
+out gl_PerVertex
+{
+ vec4 gl_Position;
+};
+
+void main()
+{
+ outNormal = inNormal;
+ outColor = inColor;
+ outUV = inUV;
+ gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0);
+
+ vec4 pos = ubo.model * vec4(inPos, 1.0);
+ outNormal = mat3(ubo.model) * inNormal;
+ vec3 lPos = mat3(ubo.model) * ubo.lightPos.xyz;
+ outLightVec = lPos - pos.xyz;
+ outViewVec = -pos.xyz;
+}
\ No newline at end of file
diff --git a/data/shaders/pipelines/phong.vert.spv b/data/shaders/pipelines/phong.vert.spv
new file mode 100644
index 00000000..d6215eb5
Binary files /dev/null and b/data/shaders/pipelines/phong.vert.spv differ
diff --git a/data/shaders/pipelines/texture.frag b/data/shaders/pipelines/texture.frag
deleted file mode 100644
index 0d174f4c..00000000
--- a/data/shaders/pipelines/texture.frag
+++ /dev/null
@@ -1,21 +0,0 @@
-#version 450
-
-layout (binding = 1) uniform sampler2D colorMap;
-
-layout (location = 1) in vec2 inUV;
-layout (location = 2) in vec3 inNormal;
-
-layout (location = 0) out vec4 outFragColor;
-
-void main()
-{
- outFragColor = texture(colorMap, inUV);
- outFragColor.rgb = inNormal;
-
- vec3 N = normalize(inNormal);
- vec3 L = normalize(vec3(2.0, 2.0, 2.0));
-
- vec3 color = texture(colorMap, inUV).rgb;
- outFragColor.rgb = vec3(clamp(max(dot(N,L), 0.0), 0.15, 1.0)) * color;
-}
-
\ No newline at end of file
diff --git a/data/shaders/pipelines/texture.frag.spv b/data/shaders/pipelines/texture.frag.spv
deleted file mode 100644
index 76c3ce74..00000000
Binary files a/data/shaders/pipelines/texture.frag.spv and /dev/null differ
diff --git a/data/shaders/pipelines/toon.frag b/data/shaders/pipelines/toon.frag
new file mode 100644
index 00000000..0f98b5e3
--- /dev/null
+++ b/data/shaders/pipelines/toon.frag
@@ -0,0 +1,39 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (binding = 1) uniform sampler2D samplerColorMap;
+
+layout (location = 0) in vec3 inNormal;
+layout (location = 1) in vec3 inColor;
+layout (location = 2) in vec2 inUV;
+layout (location = 3) in vec3 inViewVec;
+layout (location = 4) in vec3 inLightVec;
+
+layout (location = 0) out vec4 outFragColor;
+
+void main()
+{
+ // Desaturate color
+ vec3 color = vec3(mix(inColor, vec3(dot(vec3(0.2126,0.7152,0.0722), inColor)), 0.65));
+
+ // High ambient colors because mesh materials are pretty dark
+ vec3 ambient = color * vec3(1.0);
+ vec3 N = normalize(inNormal);
+ vec3 L = normalize(inLightVec);
+ vec3 V = normalize(inViewVec);
+ vec3 R = reflect(-L, N);
+ vec3 diffuse = max(dot(N, L), 0.0) * color;
+ vec3 specular = pow(max(dot(R, V), 0.0), 16.0) * vec3(0.75);
+ outFragColor = vec4(ambient + diffuse * 1.75 + specular, 1.0);
+
+ float intensity = dot(N,L);
+ float shade = 1.0;
+ shade = intensity < 0.5 ? 0.75 : shade;
+ shade = intensity < 0.35 ? 0.6 : shade;
+ shade = intensity < 0.25 ? 0.5 : shade;
+ shade = intensity < 0.1 ? 0.25 : shade;
+
+ outFragColor.rgb = inColor * 3.0 * shade;
+}
\ No newline at end of file
diff --git a/data/shaders/pipelines/toon.frag.spv b/data/shaders/pipelines/toon.frag.spv
new file mode 100644
index 00000000..0e3518d9
Binary files /dev/null and b/data/shaders/pipelines/toon.frag.spv differ
diff --git a/data/shaders/pipelines/toon.vert b/data/shaders/pipelines/toon.vert
new file mode 100644
index 00000000..293173bf
--- /dev/null
+++ b/data/shaders/pipelines/toon.vert
@@ -0,0 +1,41 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inPos;
+layout (location = 1) in vec3 inNormal;
+layout (location = 2) in vec2 inUV;
+layout (location = 3) in vec3 inColor;
+
+layout (binding = 0) uniform UBO
+{
+ mat4 projection;
+ mat4 model;
+ vec4 lightPos;
+} ubo;
+
+layout (location = 0) out vec3 outNormal;
+layout (location = 1) out vec3 outColor;
+layout (location = 2) out vec2 outUV;
+layout (location = 3) out vec3 outViewVec;
+layout (location = 4) out vec3 outLightVec;
+
+out gl_PerVertex
+{
+ vec4 gl_Position;
+};
+
+void main()
+{
+ outNormal = inNormal;
+ outColor = inColor;
+ outUV = inUV;
+ gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0);
+
+ vec4 pos = ubo.model * vec4(inPos, 1.0);
+ outNormal = mat3(ubo.model) * inNormal;
+ vec3 lPos = mat3(ubo.model) * ubo.lightPos.xyz;
+ outLightVec = lPos - pos.xyz;
+ outViewVec = -pos.xyz;
+}
\ No newline at end of file
diff --git a/data/shaders/pipelines/toon.vert.spv b/data/shaders/pipelines/toon.vert.spv
new file mode 100644
index 00000000..d6215eb5
Binary files /dev/null and b/data/shaders/pipelines/toon.vert.spv differ
diff --git a/data/shaders/pipelines/wireframe.frag b/data/shaders/pipelines/wireframe.frag
index 1625fb1f..ecfa03c2 100644
--- a/data/shaders/pipelines/wireframe.frag
+++ b/data/shaders/pipelines/wireframe.frag
@@ -1,10 +1,13 @@
#version 450
-layout (location = 0 ) in vec3 inColor;
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inColor;
layout (location = 0) out vec4 outFragColor;
void main()
{
- outFragColor = vec4(1.0);
+ outFragColor.rgb = inColor * 1.5;
}
\ No newline at end of file
diff --git a/data/shaders/pipelines/wireframe.frag.spv b/data/shaders/pipelines/wireframe.frag.spv
index 80d0acdd..987c629d 100644
Binary files a/data/shaders/pipelines/wireframe.frag.spv and b/data/shaders/pipelines/wireframe.frag.spv differ
diff --git a/data/shaders/pipelines/wireframe.vert b/data/shaders/pipelines/wireframe.vert
new file mode 100644
index 00000000..f842fec1
--- /dev/null
+++ b/data/shaders/pipelines/wireframe.vert
@@ -0,0 +1,28 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec4 inPos;
+layout (location = 3) in vec3 inColor;
+
+layout (binding = 0) uniform UBO
+{
+ mat4 projection;
+ mat4 model;
+} ubo;
+
+layout (location = 0) out vec3 outColor;
+
+out gl_PerVertex
+{
+ vec4 gl_Position;
+};
+
+void main()
+{
+ {
+ outColor = inColor;
+ }
+ gl_Position = ubo.projection * ubo.model * inPos;
+}
diff --git a/data/shaders/pipelines/wireframe.vert.spv b/data/shaders/pipelines/wireframe.vert.spv
new file mode 100644
index 00000000..9e254ace
Binary files /dev/null and b/data/shaders/pipelines/wireframe.vert.spv differ
diff --git a/pipelines/pipelines.cpp b/pipelines/pipelines.cpp
index 684f68af..56b57e6e 100644
--- a/pipelines/pipelines.cpp
+++ b/pipelines/pipelines.cpp
@@ -16,21 +16,20 @@
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include
#include
-#include
#include
-
#include "vulkanexamplebase.h"
#define VERTEX_BUFFER_BIND_ID 0
#define ENABLE_VALIDATION false
// Vertex layout for this example
-struct Vertex {
- float pos[3];
- float col[3];
- float uv[2];
- float normal[3];
+std::vector vertexLayout =
+{
+ vkMeshLoader::VERTEX_LAYOUT_POSITION,
+ vkMeshLoader::VERTEX_LAYOUT_NORMAL,
+ vkMeshLoader::VERTEX_LAYOUT_UV,
+ vkMeshLoader::VERTEX_LAYOUT_COLOR
};
class VulkanExample: public VulkanExampleBase
@@ -39,7 +38,6 @@ private:
vkTools::VulkanTexture textureColorMap;
public:
struct {
- int count;
VkPipelineVertexInputStateCreateInfo inputState;
std::vector bindingDescriptions;
std::vector attributeDescriptions;
@@ -53,9 +51,9 @@ public:
// Same uniform buffer layout as shader
struct {
- glm::mat4 projectionMatrix;
- glm::mat4 modelMatrix;
- glm::mat4 viewMatrix;
+ glm::mat4 projection;
+ glm::mat4 modelView;
+ glm::vec4 lightPos = glm::vec4(0.0f, 2.0f, 1.0f, 0.0f);
} uboVS;
VkPipelineLayout pipelineLayout;
@@ -63,29 +61,29 @@ public:
VkDescriptorSetLayout descriptorSetLayout;
struct {
- VkPipeline solidColor;
- VkPipeline wireFrame;
- VkPipeline texture;
+ VkPipeline phong;
+ VkPipeline wireframe;
+ VkPipeline toon;
} pipelines;
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
{
- zoom = -5.0f;
- rotation = glm::vec3(-32.5f, 45.0f, 0.0f);
+ zoom = -10.5f;
+ rotation = glm::vec3(-25.0f, 15.0f, 0.0f);
enableTextOverlay = true;
- title = "Vulkan Example - Using pipelines";
+ title = "Vulkan Example - Pipeline state objects";
}
~VulkanExample()
{
// Clean up used Vulkan resources
// Note : Inherited destructor cleans up resources stored in base class
- vkDestroyPipeline(device, pipelines.solidColor, nullptr);
+ vkDestroyPipeline(device, pipelines.phong, nullptr);
if (deviceFeatures.fillModeNonSolid)
{
- vkDestroyPipeline(device, pipelines.wireFrame, nullptr);
+ vkDestroyPipeline(device, pipelines.wireframe, nullptr);
}
- vkDestroyPipeline(device, pipelines.texture, nullptr);
+ vkDestroyPipeline(device, pipelines.toon, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
@@ -142,30 +140,29 @@ public:
VkDeviceSize offsets[1] = { 0 };
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &meshes.cube.vertices.buf, offsets);
-
- vkCmdSetLineWidth(drawCmdBuffers[i], 2.0f);
+ vkCmdBindIndexBuffer(drawCmdBuffers[i], meshes.cube.indices.buf, 0, VK_INDEX_TYPE_UINT32);
// Left : Solid colored
viewport.width = (float)width / 3.0;
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
- vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.solidColor);
+ vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.phong);
- vkCmdDraw(drawCmdBuffers[i], vertices.count, 1, 0, 0);
+ vkCmdDrawIndexed(drawCmdBuffers[i], meshes.cube.indexCount, 1, 0, 0, 0);
- // Center : Textured
+ // Center : Toon
viewport.x = (float)width / 3.0;
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
- vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.texture);
+ vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.toon);
vkCmdSetLineWidth(drawCmdBuffers[i], 2.0f);
- vkCmdDraw(drawCmdBuffers[i], vertices.count, 1, 0, 0);
+ vkCmdDrawIndexed(drawCmdBuffers[i], meshes.cube.indexCount, 1, 0, 0, 0);
if (deviceFeatures.fillModeNonSolid)
{
// Right : Wireframe
viewport.x = (float)width / 3.0 + (float)width / 3.0;
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
- vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireFrame);
- vkCmdDraw(drawCmdBuffers[i], vertices.count, 1, 0, 0);
+ vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireframe);
+ vkCmdDrawIndexed(drawCmdBuffers[i], meshes.cube.indexCount, 1, 0, 0, 0);
}
vkCmdEndRenderPass(drawCmdBuffers[i]);
@@ -174,72 +171,9 @@ public:
}
}
- // Create vertices and buffers for uv mapped cube
- void generateCube()
+ void loadMeshes()
{
-
- // Setup vertices
-#define colred { 1.0f, 0.0f, 0.0f }
-#define colgreen { 0.0f, 1.0f, 0.0f }
-#define colblue { 0.0f, 0.0f, 1.0f }
-#define d 1.0f
-
- std::vector vertexBuffer = {
-
- // -Y
- { { d,-d, d }, colred,{ 1.0, 1.0 }, { 0.0f, 1.0f, 0.0f } },
- { { -d,-d,-d }, colred,{ 0.0, 0.0 },{ 0.0f, 1.0f, 0.0f } },
- { { d,-d,-d }, colred,{ 1.0, 0.0 },{ 0.0f, 1.0f, 0.0f } },
- { { d,-d, d }, colred,{ 1.0, 1.0 },{ 0.0f, 1.0f, 0.0f } },
- { { -d,-d, d }, colred,{ 0.0, 1.0 },{ 0.0f, 1.0f, 0.0f } },
- { { -d,-d,-d }, colred,{ 0.0, 0.0 },{ 0.0f, 1.0f, 0.0f } },
- // +Y
- { { d, d, d }, colred,{ 1.0, 1.0 },{ 0.0f, -1.0f, 0.0f } },
- { { d, d,-d }, colred,{ 1.0, 0.0 },{ 0.0f, -1.0f, 0.0f } },
- { { -d, d,-d }, colred,{ 0.0, 0.0 },{ 0.0f, -1.0f, 0.0f } },
- { { d, d, d }, colred,{ 1.0, 1.0 },{ 0.0f, -1.0f, 0.0f } },
- { { -d, d,-d }, colred,{ 0.0, 0.0 },{ 0.0f, -1.0f, 0.0f } },
- { { -d, d, d }, colred,{ 0.0, 1.0 },{ 0.0f, -1.0f, 0.0f } },
- // -X
- { { -d,-d,-d }, colblue,{ 0.0, 0.0 },{ -1.0f, 0.0f, 0.0f } },
- { { -d,-d, d }, colblue,{ 0.0, 1.0 },{ -1.0f, 0.0f, 0.0f } },
- { { -d, d, d }, colblue,{ 1.0, 1.0 },{ -1.0f, 0.0f, 0.0f } },
- { { -d,-d,-d }, colblue,{ 0.0, 0.0 },{ -1.0f, 0.0f, 0.0f } },
- { { -d, d, d }, colblue,{ 1.0, 1.0 },{ -1.0f, 0.0f, 0.0f } },
- { { -d, d,-d }, colblue,{ 1.0, 0.0 },{ -1.0f, 0.0f, 0.0f } },
- // +X
- { { d, d, d }, colblue,{ 1.0, 1.0 },{ 1.0f, 0.0f, 0.0f } },
- { { d,-d,-d }, colblue,{ 0.0, 0.0 },{ 1.0f, 0.0f, 0.0f } },
- { { d, d,-d }, colblue,{ 1.0, 0.0 },{ 1.0f, 0.0f, 0.0f } },
- { { d,-d,-d }, colblue,{ 0.0, 0.0 },{ 1.0f, 0.0f, 0.0f } },
- { { d, d, d }, colblue,{ 1.0, 1.0 },{ 1.0f, 0.0f, 0.0f } },
- { { d,-d, d }, colblue,{ 0.0, 1.0 },{ 1.0f, 0.0f, 0.0f } },
- // -Z
- { { d, d,-d }, colgreen,{ 1.0, 1.0 },{ 0.0f, 0.0f, -1.0f } },
- { { -d,-d,-d }, colgreen,{ 0.0, 0.0 },{ 0.0f, 0.0f, -1.0f } },
- { { -d, d,-d }, colgreen,{ 0.0, 1.0 },{ 0.0f, 0.0f, -1.0f } },
- { { d, d,-d }, colgreen,{ 1.0, 1.0 },{ 0.0f, 0.0f, -1.0f } },
- { { d,-d,-d }, colgreen,{ 1.0, 0.0 },{ 0.0f, 0.0f, -1.0f } },
- { { -d,-d,-d }, colgreen,{ 0.0, 0.0 },{ 0.0f, 0.0f, -1.0f } },
- // +Z
- { { -d, d, d }, colgreen,{ 0.0, 1.0 },{ 0.0f, 0.0f, 1.0f } },
- { { -d,-d, d }, colgreen,{ 0.0, 0.0 },{ 0.0f, 0.0f, 1.0f } },
- { { d,-d, d }, colgreen,{ 1.0, 0.0 },{ 0.0f, 0.0f, 1.0f } },
- { { d, d, d }, colgreen,{ 1.0, 1.0 },{ 0.0f, 0.0f, 1.0f } },
- { { -d, d, d }, colgreen,{ 0.0, 1.0 },{ 0.0f, 0.0f, 1.0f } },
- { { d,-d, d }, colgreen,{ 1.0, 0.0 },{ 0.0f, 0.0f, 1.0f } }
-
- };
-#undef d
-
- vertices.count = vertexBuffer.size();
-
- createBuffer(
- VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
- vertexBuffer.size() * sizeof(Vertex),
- vertexBuffer.data(),
- &meshes.cube.vertices.buf,
- &meshes.cube.vertices.mem);
+ loadMesh(getAssetPath() + "models/treasure_smooth.dae", &meshes.cube, vertexLayout, 1.0f);
}
void setupVertexDescriptions()
@@ -249,7 +183,7 @@ public:
vertices.bindingDescriptions[0] =
vkTools::initializers::vertexInputBindingDescription(
VERTEX_BUFFER_BIND_ID,
- sizeof(Vertex),
+ vkMeshLoader::vertexSize(vertexLayout),
VK_VERTEX_INPUT_RATE_VERTEX);
// Attribute descriptions
@@ -387,7 +321,7 @@ public:
VkPipelineRasterizationStateCreateInfo rasterizationState =
vkTools::initializers::pipelineRasterizationStateCreateInfo(
VK_POLYGON_MODE_FILL,
- VK_CULL_MODE_FRONT_BIT,
+ VK_CULL_MODE_BACK_BIT,
VK_FRONT_FACE_CLOCKWISE,
0);
@@ -417,8 +351,7 @@ public:
std::vector dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT,
- VK_DYNAMIC_STATE_SCISSOR,
- VK_DYNAMIC_STATE_LINE_WIDTH
+ VK_DYNAMIC_STATE_SCISSOR
};
VkPipelineDynamicStateCreateInfo dynamicState =
vkTools::initializers::pipelineDynamicStateCreateInfo(
@@ -426,12 +359,11 @@ public:
dynamicStateEnables.size(),
0);
- // Color pipeline
- // Load shaders
std::array shaderStages;
- shaderStages[0] = loadShader(getAssetPath() + "shaders/pipelines/base.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
- shaderStages[1] = loadShader(getAssetPath() + "shaders/pipelines/color.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
+ // Phong shading pipeline
+ shaderStages[0] = loadShader(getAssetPath() + "shaders/pipelines/phong.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
+ shaderStages[1] = loadShader(getAssetPath() + "shaders/pipelines/phong.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
VkGraphicsPipelineCreateInfo pipelineCreateInfo =
vkTools::initializers::pipelineCreateInfo(
@@ -450,27 +382,37 @@ public:
pipelineCreateInfo.stageCount = shaderStages.size();
pipelineCreateInfo.pStages = shaderStages.data();
+ // We are using this pipeline as the base for the other pipelines (derivatives)
+ // Pipeline derivatives can be used for pipelines that share most of their state
+ // Depending on the implementation this may result in better performance for pipeline
+ // switchting and faster creation time
+ pipelineCreateInfo.flags = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;
+
// Textured pipeline
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solidColor));
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.phong));
- // Reuse most of the initial pipeline for the next pipelines and only change affected parameters
- // Cull back faces
- rasterizationState.cullMode = VK_CULL_MODE_BACK_BIT;
+ // All pipelines created after the base pipeline will be derivatives
+ pipelineCreateInfo.flags = VK_PIPELINE_CREATE_DERIVATIVE_BIT;
+ // Base pipeline will be our first created pipeline
+ pipelineCreateInfo.basePipelineHandle = pipelines.phong;
+ // It's only allowed to either use a handle or index for the base pipeline
+ // As we use the handle, we must set the index to -1 (see section 9.5 of the specification)
+ pipelineCreateInfo.basePipelineIndex = -1;
- // Pipeline for textured rendering
- // Use different fragment shader
- shaderStages[1] = loadShader(getAssetPath() + "shaders/pipelines/texture.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.texture));
+ // Toon shading pipeline
+ shaderStages[0] = loadShader(getAssetPath() + "shaders/pipelines/toon.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
+ shaderStages[1] = loadShader(getAssetPath() + "shaders/pipelines/toon.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
+
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.toon));
// Non solid rendering is not a mandatory Vulkan feature
if (deviceFeatures.fillModeNonSolid)
{
// Pipeline for wire frame rendering
- // Solid polygon fill
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
- // Use different fragment shader
+ shaderStages[0] = loadShader(getAssetPath() + "shaders/pipelines/wireframe.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderStages[1] = loadShader(getAssetPath() + "shaders/pipelines/wireframe.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wireFrame));
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wireframe));
}
}
@@ -492,14 +434,14 @@ public:
void updateUniformBuffers()
{
- uboVS.projectionMatrix = glm::perspective(glm::radians(60.0f), (float)(width / 3.0f) / (float)height, 0.1f, 256.0f);
+ uboVS.projection = glm::perspective(glm::radians(60.0f), (float)(width / 3.0f) / (float)height, 0.1f, 256.0f);
- uboVS.viewMatrix = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, zoom));
+ glm::mat4 viewMatrix = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, zoom));
- uboVS.modelMatrix = glm::mat4();
- uboVS.modelMatrix = glm::rotate(uboVS.modelMatrix, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
- uboVS.modelMatrix = glm::rotate(uboVS.modelMatrix, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
- uboVS.modelMatrix = glm::rotate(uboVS.modelMatrix, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
+ uboVS.modelView = viewMatrix * glm::translate(glm::mat4(), cameraPos);
+ uboVS.modelView = glm::rotate(uboVS.modelView, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
+ uboVS.modelView = glm::rotate(uboVS.modelView, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
+ uboVS.modelView = glm::rotate(uboVS.modelView, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
uint8_t *pData;
VK_CHECK_RESULT(vkMapMemory(device, uniformDataVS.memory, 0, sizeof(uboVS), 0, (void **)&pData));
@@ -522,10 +464,10 @@ public:
{
VulkanExampleBase::prepare();
loadTextures();
+ loadMeshes();
setupVertexDescriptions();
prepareUniformBuffers();
setupDescriptorSetLayout();
- generateCube();
preparePipelines();
setupDescriptorPool();
setupDescriptorSet();
@@ -545,6 +487,12 @@ public:
updateUniformBuffers();
}
+ virtual void getOverlayText(VulkanTextOverlay *textOverlay)
+ {
+ textOverlay->addText("Phong shading pipeline",(float)width / 6.0f, height - 35.0f, VulkanTextOverlay::alignCenter);
+ textOverlay->addText("Toon shading pipeline", (float)width / 2.0f, height - 35.0f, VulkanTextOverlay::alignCenter);
+ textOverlay->addText("Wireframe pipeline", width - (float)width / 6.5f, height - 35.0f, VulkanTextOverlay::alignCenter);
+ }
};
VulkanExample *vulkanExample;
diff --git a/screenshots/basic_pipelines.png b/screenshots/basic_pipelines.png
index 515980d9..18b75fdb 100644
Binary files a/screenshots/basic_pipelines.png and b/screenshots/basic_pipelines.png differ
diff --git a/screenshots/compute_imageprocessing.jpg b/screenshots/compute_imageprocessing.jpg
new file mode 100644
index 00000000..0b6edadd
Binary files /dev/null and b/screenshots/compute_imageprocessing.jpg differ
diff --git a/screenshots/compute_imageprocessing.png b/screenshots/compute_imageprocessing.png
deleted file mode 100644
index 7c8c9a2e..00000000
Binary files a/screenshots/compute_imageprocessing.png and /dev/null differ
diff --git a/screenshots/compute_particles.jpg b/screenshots/compute_particles.jpg
index 7a814388..666b1601 100644
Binary files a/screenshots/compute_particles.jpg and b/screenshots/compute_particles.jpg differ
diff --git a/screenshots/spherical_env_mapping.png b/screenshots/spherical_env_mapping.png
index e29d7cae..0b0f5366 100644
Binary files a/screenshots/spherical_env_mapping.png and b/screenshots/spherical_env_mapping.png differ