Merge glTF branch (#747)

* Added helper function for easy pipeline vertex input state create info structure setup from glTF model vertex class

* Split glTF loader into header and implementation

* Updated sample to use glTF

* Removed collada files

Replaced assets are now part of the asset pack

* Return value for glTF model vertex input state create info helper

* Removed unused assets

* Use glTF assets

* Added default material for glTF node's without materials

* Use glTF assets

* Apply pre-transforms to normals

* Use glTF assets

* Use glTF assets

* Use vertex input state from glTF model class

* Scene setup

* Use glTF assets

* Use glTF assets

* Display error message and exit if glTF file could not be loaded

* Use glTF assets

* Use glTF assets

* Use glTF assets

* Remove unused buffer binds

* Use glTF assets

* Remove no longer used model files

* Remove no longer used model files

* Added support for rendering glTF models with images

* glTF model normal pre-transform ignores translation

* Use glTF assets

* Use glTF assets

* Use glTF assets

* Use glTF assets

* Use glTF assets

* Only add combined image samplers to pool if actually used in the scene

* Use global descriptor set layouts

* Use global descriptor set layouts

* Use glTF assets

* Use glTF assets

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders

* Use glTF assets

Code cleanup

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders

* Remove no-longer used model

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders
Removed no-longer used model

* Use glTF assets

Code cleanup
Use RGBA texture instead of different compressed formats
Removed no-longer used assets

* Adnrdoid build file

* Use glTF assets

Code cleanup and refactoring
Updated GLSL and HLSL shaders

* Added vertex count and way of passing additional memory property type flags to glTF loader

* Use glTF assets

Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Updated GLSL and HLSL shaders

* Remove unfinished sample

* Completely reworked push constants sample

Use glTF assets
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Android CMake build files

* Removed un-used asset

* Explicit buffer binding function

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders

* Use glTF assets

Code cleanup

* Use glTF assets

Code cleanup
Removed no-longer used assets

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Remove no-longer used asset

* Use glTF assets

Code cleanup and refactoring
Performance optimizations
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring

* Use glTF assets

Code cleanup and refactoring

* Use glTF assets

Code cleanup and refactoring
Removed no-longer used assets

* Pass vertex size and calculate multiplier in shaders instead of hard-coding

With this, changes to the glTF vertex structure won't break the ray tracing samples

* Load tangents (if present)

* Use glTF assets

Code cleanup and heavy refactoring
Reworked debug display code

* Android build

* Normal mapping fixes

Udpated HLSL shaders

* Use glTF assets

Code cleanup and heavy refactoring
Reworked debug display code
Updated GLSL and HLSL shaders

* Code cleanup, comments

* Use glTF assets

Code cleanup and heavy refactoring
Reworked debug display code
Updated GLSL and HLSL shaders

* Added sample count to framebuffer create info

* Removed no-longer used assets

* Android build

Removed no-longer used assets

* Code cleanup and heavy refactoring

Updated GLSL and HLSL shaders
Use tangents stored in GLSL instead of calculating them in the fragment shader

* Renamed textured PBR sample main cpp file

* Use glTF assets

Code cleanup and refactoring
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Removed no-longer used assets

* Android build files

* Android build files

* Use glTF assets

Removed no-longer used assets

* Fixed HLSL shaders

* Android build files

* Use glTF assets

Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Updated GLSL and HLSL shaders
Removed no-longer used assets

* Added flag to disable glTF image loading

Useful for samples that use their own textures or don't use textures at all to speed up loading

* Use glTF assets

Code cleanup
Use Sponza scene instead of Sibenik to better highlight the effect
Updated GLSL and HLSL shaders

* Updated Android build files

* Removed left-over comment

* Use Sponza scene for the SSAO sample

* Removed unused code

* Removed ASSIMP

No longer required as all samples now use the glTF file format

* Added missing vertex shader stage

* Removed old ASSIMP-based model loader

* Added support for loading external glTF images from ktx

Android fixes for loading external buffer files

* Scene setup

* Added missing shader stages

* Removed ASSIMP from build files

* Fixed compiler warning

* Removed ASSIMP from readmes

* Android build files cleanup

* Replaced ktx submodule with only the files required for this repo

The ktx submodule was a tad too big and contained lots of files not required for this repo

* Moved ktx build files into base project

* Use glTF assets

* Use glTF assets

* Removed license files, will be moved to asset pack

* Use RGBA textures

* Use RGBA cubemp texture with face assignment based on original images

Refs #679

* Android build files

* Removed textures

All textures will be moved to the asset pack

* Ignore asset folders

* Removed font

Fonts will be moved to the asset pack

* Link to gltf asset pack

* Updated gitignore

* Android build file
This commit is contained in:
Sascha Willems 2020-07-28 20:20:38 +02:00 committed by GitHub
parent 8526c204e7
commit feb939096f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
726 changed files with 21935 additions and 132751 deletions

View file

@ -22,7 +22,7 @@
#include <vulkan/vulkan.h>
#include "vulkanexamplebase.h"
#include "VulkanBuffer.hpp"
#include "VulkanModel.hpp"
#include "VulkanglTFModel.h"
#include "VulkanTexture.hpp"
#define ENABLE_VALIDATION false
@ -33,20 +33,13 @@ public:
bool bloom = true;
bool displaySkybox = true;
// Vertex layout for the models
vks::VertexLayout vertexLayout = vks::VertexLayout({
vks::VERTEX_COMPONENT_POSITION,
vks::VERTEX_COMPONENT_NORMAL,
vks::VERTEX_COMPONENT_UV,
});
struct {
vks::TextureCubeMap envmap;
} textures;
struct Models {
vks::Model skybox;
std::vector<vks::Model> objects;
vkglTF::Model skybox;
std::vector<vkglTF::Model> objects;
int32_t objectIndex = 1;
} models;
@ -127,8 +120,8 @@ public:
{
title = "High dynamic range rendering";
camera.type = Camera::CameraType::lookat;
camera.setPosition(glm::vec3(0.0f, 0.0f, -4.0f));
camera.setRotation(glm::vec3(0.0f, 180.0f, 0.0f));
camera.setPosition(glm::vec3(0.0f, 0.0f, -6.0f));
camera.setRotation(glm::vec3(0.0f, 0.0f, 0.0f));
camera.setPerspective(60.0f, (float)width / (float)height, 0.1f, 256.0f);
settings.overlay = true;
}
@ -164,10 +157,6 @@ public:
filterPass.color[0].destroy(device);
for (auto& model : models.objects) {
model.destroy();
}
models.skybox.destroy();
uniformBuffers.matrices.destroy();
uniformBuffers.params.destroy();
textures.envmap.destroy();
@ -230,7 +219,7 @@ public:
vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &models.skybox.vertices.buffer, offsets);
vkCmdBindIndexBuffer(drawCmdBuffers[i], models.skybox.indices.buffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.skybox);
vkCmdDrawIndexed(drawCmdBuffers[i], models.skybox.indexCount, 1, 0, 0, 0);
models.skybox.draw(drawCmdBuffers[i]);
}
// 3D object
@ -238,7 +227,7 @@ public:
vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &models.objects[models.objectIndex].vertices.buffer, offsets);
vkCmdBindIndexBuffer(drawCmdBuffers[i], models.objects[models.objectIndex].indices.buffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.reflect);
vkCmdDrawIndexed(drawCmdBuffers[i], models.objects[models.objectIndex].indexCount, 1, 0, 0, 0);
models.objects[models.objectIndex].draw(drawCmdBuffers[i]);
vkCmdEndRenderPass(drawCmdBuffers[i]);
}
@ -594,14 +583,14 @@ public:
void loadAssets()
{
// Models
models.skybox.loadFromFile(getAssetPath() + "models/cube.obj", vertexLayout, 0.05f, vulkanDevice, queue);
std::vector<std::string> filenames = { "geosphere.obj", "teapot.dae", "torusknot.obj", "venus.fbx" };
// Load glTF models
const uint32_t glTFLoadingFlags = vkglTF::FileLoadingFlags::PreTransformVertices | vkglTF::FileLoadingFlags::FlipY;
models.skybox.loadFromFile(getAssetPath() + "models/cube.gltf", vulkanDevice, queue, glTFLoadingFlags);
std::vector<std::string> filenames = { "sphere.gltf", "teapot.gltf", "torusknot.gltf", "venus.gltf" };
objectNames = { "Sphere", "Teapot", "Torusknot", "Venus" };
for (auto file : filenames) {
vks::Model model;
model.loadFromFile(getAssetPath() + "models/" + file, vertexLayout, 0.05f * (file == "venus.fbx" ? 3.0f : 1.0f), vulkanDevice, queue);
models.objects.push_back(model);
models.objects.resize(filenames.size());
for (size_t i = 0; i < filenames.size(); i++) {
models.objects[i].loadFromFile(getAssetPath() + "models/" + filenames[i], vulkanDevice, queue, glTFLoadingFlags);
}
// Load HDR cube map
textures.envmap.loadFromFile(getAssetPath() + "textures/hdr/uffizi_cube.ktx", VK_FORMAT_R16G16B16A16_SFLOAT, vulkanDevice, queue);
@ -725,75 +714,27 @@ public:
void preparePipelines()
{
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
vks::initializers::pipelineInputAssemblyStateCreateInfo(
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
0,
VK_FALSE);
VkPipelineRasterizationStateCreateInfo rasterizationState =
vks::initializers::pipelineRasterizationStateCreateInfo(
VK_POLYGON_MODE_FILL,
VK_CULL_MODE_BACK_BIT,
VK_FRONT_FACE_COUNTER_CLOCKWISE,
0);
VkPipelineColorBlendAttachmentState blendAttachmentState =
vks::initializers::pipelineColorBlendAttachmentState(
0xf,
VK_FALSE);
VkPipelineColorBlendStateCreateInfo colorBlendState =
vks::initializers::pipelineColorBlendStateCreateInfo(
1,
&blendAttachmentState);
VkPipelineDepthStencilStateCreateInfo depthStencilState =
vks::initializers::pipelineDepthStencilStateCreateInfo(
VK_FALSE,
VK_FALSE,
VK_COMPARE_OP_LESS_OR_EQUAL);
VkPipelineViewportStateCreateInfo viewportState =
vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
VkPipelineMultisampleStateCreateInfo multisampleState =
vks::initializers::pipelineMultisampleStateCreateInfo(
VK_SAMPLE_COUNT_1_BIT,
0);
std::vector<VkDynamicState> dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
};
VkPipelineDynamicStateCreateInfo dynamicState =
vks::initializers::pipelineDynamicStateCreateInfo(
dynamicStateEnables.data(),
static_cast<uint32_t>(dynamicStateEnables.size()),
0);
VkGraphicsPipelineCreateInfo pipelineCreateInfo =
vks::initializers::pipelineCreateInfo(
pipelineLayouts.models,
renderPass,
0);
std::vector<VkPipelineColorBlendAttachmentState> blendAttachmentStates = {
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE),
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE),
};
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
pipelineCreateInfo.pRasterizationState = &rasterizationState;
pipelineCreateInfo.pColorBlendState = &colorBlendState;
pipelineCreateInfo.pMultisampleState = &multisampleState;
pipelineCreateInfo.pViewportState = &viewportState;
pipelineCreateInfo.pDepthStencilState = &depthStencilState;
pipelineCreateInfo.pDynamicState = &dynamicState;
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE);
VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0);
VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState);
VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_FALSE, VK_FALSE, VK_COMPARE_OP_LESS_OR_EQUAL);
VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0);
std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables);
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
pipelineCreateInfo.pStages = shaderStages.data();
VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayouts.models, renderPass, 0);
pipelineCI.pInputAssemblyState = &inputAssemblyState;
pipelineCI.pRasterizationState = &rasterizationState;
pipelineCI.pColorBlendState = &colorBlendState;
pipelineCI.pMultisampleState = &multisampleState;
pipelineCI.pViewportState = &viewportState;
pipelineCI.pDepthStencilState = &depthStencilState;
pipelineCI.pDynamicState = &dynamicState;
pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size());
pipelineCI.pStages = shaderStages.data();
VkSpecializationInfo specializationInfo;
std::array<VkSpecializationMapEntry, 1> specializationMapEntries;
@ -802,17 +743,21 @@ public:
// Empty vertex input state, full screen triangles are generated by the vertex shader
VkPipelineVertexInputStateCreateInfo emptyInputState = vks::initializers::pipelineVertexInputStateCreateInfo();
pipelineCreateInfo.pVertexInputState = &emptyInputState;
pipelineCI.pVertexInputState = &emptyInputState;
// Final fullscreen composition pass pipeline
shaderStages[0] = loadShader(getShadersPath() + "hdr/composition.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderStages[1] = loadShader(getShadersPath() + "hdr/composition.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
pipelineCreateInfo.layout = pipelineLayouts.composition;
pipelineCreateInfo.renderPass = renderPass;
rasterizationState.cullMode = VK_CULL_MODE_FRONT_BIT;
std::vector<VkPipelineColorBlendAttachmentState> blendAttachmentStates = {
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE),
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE),
};
pipelineCI.layout = pipelineLayouts.composition;
pipelineCI.renderPass = renderPass;
rasterizationState.cullMode = VK_CULL_MODE_NONE;
colorBlendState.attachmentCount = 1;
colorBlendState.pAttachments = blendAttachmentStates.data();
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.composition));
shaderStages[0] = loadShader(getShadersPath() + "hdr/composition.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderStages[1] = loadShader(getShadersPath() + "hdr/composition.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.composition));
// Bloom pass
shaderStages[0] = loadShader(getShadersPath() + "hdr/bloom.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
@ -832,66 +777,42 @@ public:
uint32_t dir = 1;
specializationInfo = vks::initializers::specializationInfo(1, specializationMapEntries.data(), sizeof(dir), &dir);
shaderStages[1].pSpecializationInfo = &specializationInfo;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.bloom[0]));
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.bloom[0]));
// Second blur pass (into separate framebuffer)
pipelineCreateInfo.renderPass = filterPass.renderPass;
pipelineCI.renderPass = filterPass.renderPass;
dir = 0;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.bloom[1]));
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.bloom[1]));
// Object rendering pipelines
rasterizationState.cullMode = VK_CULL_MODE_BACK_BIT;
// Use vertex input state from glTF model setup
pipelineCI.pVertexInputState = vkglTF::Vertex::getPipelineVertexInputState({ vkglTF::VertexComponent::Position, vkglTF::VertexComponent::Normal });
// Vertex bindings an attributes for model rendering
// Binding description
std::vector<VkVertexInputBindingDescription> vertexInputBindings = {
vks::initializers::vertexInputBindingDescription(0, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX),
};
// Attribute descriptions
std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = {
vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Position
vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3), // Normal
vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 6), // UV
};
VkPipelineVertexInputStateCreateInfo vertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo();
vertexInputState.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size());
vertexInputState.pVertexBindingDescriptions = vertexInputBindings.data();
vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size());
vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data();
pipelineCreateInfo.pVertexInputState = &vertexInputState;
// Skybox pipeline (background cube)
blendAttachmentState.blendEnable = VK_FALSE;
pipelineCreateInfo.layout = pipelineLayouts.models;
pipelineCreateInfo.renderPass = offscreen.renderPass;
pipelineCI.layout = pipelineLayouts.models;
pipelineCI.renderPass = offscreen.renderPass;
colorBlendState.attachmentCount = 2;
colorBlendState.pAttachments = blendAttachmentStates.data();
shaderStages[0] = loadShader(getShadersPath() + "hdr/gbuffer.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderStages[1] = loadShader(getShadersPath() + "hdr/gbuffer.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
// Set constant parameters via specialization constants
specializationMapEntries[0] = vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t));
uint32_t shadertype = 0;
specializationInfo = vks::initializers::specializationInfo(1, specializationMapEntries.data(), sizeof(shadertype), &shadertype);
shaderStages[0].pSpecializationInfo = &specializationInfo;
shaderStages[1].pSpecializationInfo = &specializationInfo;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.skybox));
// Skybox pipeline (background cube)
rasterizationState.cullMode = VK_CULL_MODE_FRONT_BIT;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.skybox));
// Object rendering pipeline
shadertype = 1;
// Enable depth test and write
depthStencilState.depthWriteEnable = VK_TRUE;
depthStencilState.depthTestEnable = VK_TRUE;
// Flip cull mode
rasterizationState.cullMode = VK_CULL_MODE_FRONT_BIT;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.reflect));
rasterizationState.cullMode = VK_CULL_MODE_BACK_BIT;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.reflect));
}
// Prepare and initialize uniform buffer containing shader uniforms