Updated pipelines demo with new scene, shaders and pipeline derivatives
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
30
data/shaders/pipelines/phong.frag
Normal 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);
|
||||
}
|
||||
BIN
data/shaders/pipelines/phong.frag.spv
Normal file
41
data/shaders/pipelines/phong.vert
Normal 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;
|
||||
}
|
||||
BIN
data/shaders/pipelines/phong.vert.spv
Normal 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;
|
||||
}
|
||||
|
||||
39
data/shaders/pipelines/toon.frag
Normal 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;
|
||||
}
|
||||
BIN
data/shaders/pipelines/toon.frag.spv
Normal file
41
data/shaders/pipelines/toon.vert
Normal 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;
|
||||
}
|
||||
BIN
data/shaders/pipelines/toon.vert.spv
Normal file
|
|
@ -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;
|
||||
}
|
||||
28
data/shaders/pipelines/wireframe.vert
Normal 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;
|
||||
}
|
||||
BIN
data/shaders/pipelines/wireframe.vert.spv
Normal 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;
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 226 KiB |
BIN
screenshots/compute_imageprocessing.jpg
Normal file
|
After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 441 KiB After Width: | Height: | Size: 498 KiB |
|
Before Width: | Height: | Size: 496 KiB After Width: | Height: | Size: 449 KiB |