Updated pipelines demo with new scene, shaders and pipeline derivatives

This commit is contained in:
saschawillems 2016-05-26 19:43:27 +02:00
parent 6ad7e5e9ba
commit aa9f2405dd
26 changed files with 261 additions and 187 deletions

View file

@ -84,7 +84,8 @@ Distance field font textures can be generated with tools like [Hiero](https://gi
## [Pipelines](pipelines/)
<img src="./screenshots/basic_pipelines.png" height="96px" align="right">
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).
<br><br>
## [Gears](gears/)
@ -220,7 +221,7 @@ Implements a simple ray tracer using a compute shader. No primitives are rendere
<br><br>
## [(Compute shader) Image processing](computeshader/)
<img src="./screenshots/compute_imageprocessing.png" height="96px" align="right">
<img src="./screenshots/compute_imageprocessing.jpg" height="96px" align="right">
Demonstrates the use of a separate compute queue (and command buffer) to apply different convolution kernels on an input image in realtime.
<br><br>
@ -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)

View file

@ -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);
}

Binary file not shown.

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

Binary file not shown.

View file

@ -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;
}

Binary file not shown.

View file

@ -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;
}

View file

@ -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;
}

Binary file not shown.

View file

@ -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;
}

Binary file not shown.

View file

@ -1,10 +1,13 @@
#version 450
#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;
}

View file

@ -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;
}

Binary file not shown.

View file

@ -16,21 +16,20 @@
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <gli/gli.hpp>
#include <vulkan/vulkan.h>
#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<vkMeshLoader::VertexLayout> 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<VkVertexInputBindingDescription> bindingDescriptions;
std::vector<VkVertexInputAttributeDescription> 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<Vertex> 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<VkDynamicState> 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<VkPipelineShaderStageCreateInfo, 2> 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;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 KiB

After

Width:  |  Height:  |  Size: 226 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 KiB

After

Width:  |  Height:  |  Size: 498 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 KiB

After

Width:  |  Height:  |  Size: 449 KiB

Before After
Before After