ready for pbr and tonemapping
parent
39ba805802
commit
077d91916f
|
@ -21,27 +21,6 @@
|
||||||
#include "homework1.h"
|
#include "homework1.h"
|
||||||
|
|
||||||
|
|
||||||
VulkanglTFModel::~VulkanglTFModel()
|
|
||||||
{
|
|
||||||
for (auto node : nodes) {
|
|
||||||
delete node;
|
|
||||||
}
|
|
||||||
// Release all Vulkan resources allocated for the model
|
|
||||||
vkDestroyBuffer(vulkanDevice->logicalDevice, vertices.buffer, nullptr);
|
|
||||||
vkFreeMemory(vulkanDevice->logicalDevice, vertices.memory, nullptr);
|
|
||||||
vkDestroyBuffer(vulkanDevice->logicalDevice, indices.buffer, nullptr);
|
|
||||||
vkFreeMemory(vulkanDevice->logicalDevice, indices.memory, nullptr);
|
|
||||||
for (Image image : images) {
|
|
||||||
vkDestroyImageView(vulkanDevice->logicalDevice, image.texture.view, nullptr);
|
|
||||||
vkDestroyImage(vulkanDevice->logicalDevice, image.texture.image, nullptr);
|
|
||||||
vkDestroySampler(vulkanDevice->logicalDevice, image.texture.sampler, nullptr);
|
|
||||||
vkFreeMemory(vulkanDevice->logicalDevice, image.texture.deviceMemory, nullptr);
|
|
||||||
}
|
|
||||||
for (Skin skin : skins)
|
|
||||||
{
|
|
||||||
skin.ssbo.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
glTF loading functions
|
glTF loading functions
|
||||||
|
@ -206,46 +185,50 @@ VulkanglTFModel::~VulkanglTFModel()
|
||||||
{
|
{
|
||||||
|
|
||||||
skins.resize(input.skins.size());
|
skins.resize(input.skins.size());
|
||||||
|
if (skins.size() > 0)
|
||||||
for (size_t i = 0; i < input.skins.size(); i++)
|
|
||||||
{
|
{
|
||||||
tinygltf::Skin glTFSkin = input.skins[i];
|
for (size_t i = 0; i < input.skins.size(); i++)
|
||||||
|
|
||||||
skins[i].name = glTFSkin.name;
|
|
||||||
//follow the tree structure,find the root node of skeleton by index
|
|
||||||
skins[i].skeletonRoot = nodeFromIndex(glTFSkin.skeleton);
|
|
||||||
|
|
||||||
//join nodes
|
|
||||||
for (int jointIndex : glTFSkin.joints)
|
|
||||||
{
|
|
||||||
Node* node = nodeFromIndex(jointIndex);
|
|
||||||
if (node)
|
|
||||||
{
|
{
|
||||||
skins[i].joints.push_back(node);
|
tinygltf::Skin glTFSkin = input.skins[i];
|
||||||
}
|
|
||||||
}
|
skins[i].name = glTFSkin.name;
|
||||||
//get the inverse bind matrices
|
//follow the tree structure,find the root node of skeleton by index
|
||||||
if (glTFSkin.inverseBindMatrices > -1)
|
skins[i].skeletonRoot = nodeFromIndex(glTFSkin.skeleton);
|
||||||
{
|
|
||||||
const tinygltf::Accessor& accessor = input.accessors[glTFSkin.inverseBindMatrices];
|
//join nodes
|
||||||
const tinygltf::BufferView& bufferview = input.bufferViews[accessor.bufferView];
|
for (int jointIndex : glTFSkin.joints)
|
||||||
const tinygltf::Buffer& buffer = input.buffers[bufferview.buffer];
|
{
|
||||||
skins[i].inverseBindMatrices.resize(accessor.count);
|
Node* node = nodeFromIndex(jointIndex);
|
||||||
memcpy(skins[i].inverseBindMatrices.data(), &buffer.data[accessor.byteOffset + bufferview.byteOffset], accessor.count * sizeof(glm::mat4));
|
if (node)
|
||||||
|
{
|
||||||
|
skins[i].joints.push_back(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//get the inverse bind matrices
|
||||||
|
if (glTFSkin.inverseBindMatrices > -1)
|
||||||
|
{
|
||||||
|
const tinygltf::Accessor& accessor = input.accessors[glTFSkin.inverseBindMatrices];
|
||||||
|
const tinygltf::BufferView& bufferview = input.bufferViews[accessor.bufferView];
|
||||||
|
const tinygltf::Buffer& buffer = input.buffers[bufferview.buffer];
|
||||||
|
skins[i].inverseBindMatrices.resize(accessor.count);
|
||||||
|
memcpy(skins[i].inverseBindMatrices.data(), &buffer.data[accessor.byteOffset + bufferview.byteOffset], accessor.count * sizeof(glm::mat4));
|
||||||
|
|
||||||
|
//create a host visible shader buffer to store inverse bind matrices for this skin
|
||||||
|
VK_CHECK_RESULT(
|
||||||
|
vulkanDevice->createBuffer(
|
||||||
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||||
|
&skins[i].ssbo,
|
||||||
|
sizeof(glm::mat4) * skins[i].inverseBindMatrices.size(),
|
||||||
|
skins[i].inverseBindMatrices.data()));
|
||||||
|
VK_CHECK_RESULT(skins[i].ssbo.map());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//create a host visible shader buffer to store inverse bind matrices for this skin
|
|
||||||
VK_CHECK_RESULT(
|
|
||||||
vulkanDevice->createBuffer(
|
|
||||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
&skins[i].ssbo,
|
|
||||||
sizeof(glm::mat4) * skins[i].inverseBindMatrices.size(),
|
|
||||||
skins[i].inverseBindMatrices.data()));
|
|
||||||
VK_CHECK_RESULT(skins[i].ssbo.map());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//glTF nodes loading helper function
|
//glTF nodes loading helper function
|
||||||
|
@ -542,6 +525,7 @@ VulkanglTFModel::~VulkanglTFModel()
|
||||||
if (channel.path == "translation")
|
if (channel.path == "translation")
|
||||||
{
|
{
|
||||||
channel.node->translation = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], ratio);
|
channel.node->translation = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], ratio);
|
||||||
|
channel.node->bAnimateNode = true;
|
||||||
}
|
}
|
||||||
if (channel.path == "rotation")
|
if (channel.path == "rotation")
|
||||||
{
|
{
|
||||||
|
@ -596,7 +580,7 @@ VulkanglTFModel::~VulkanglTFModel()
|
||||||
}
|
}
|
||||||
// Pass the final matrix to the vertex shader using push constants
|
// Pass the final matrix to the vertex shader using push constants
|
||||||
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &nodeMatrix);
|
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &nodeMatrix);
|
||||||
if (skins.size() != 0)
|
if (skins.size() > 0)
|
||||||
{
|
{
|
||||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &skins[node.skin].descriptorSet, 0, nullptr);
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &skins[node.skin].descriptorSet, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
@ -645,24 +629,7 @@ VulkanExample::VulkanExample():
|
||||||
camera.setPerspective(60.0f, (float)width / (float)height, 0.1f, 256.0f);
|
camera.setPerspective(60.0f, (float)width / (float)height, 0.1f, 256.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanExample::~VulkanExample()
|
|
||||||
{
|
|
||||||
// Clean up used Vulkan resources
|
|
||||||
// Note : Inherited destructor cleans up resources stored in base class
|
|
||||||
vkDestroyPipeline(device, pipelines.solid, nullptr);
|
|
||||||
if (pipelines.wireframe != VK_NULL_HANDLE) {
|
|
||||||
vkDestroyPipeline(device, pipelines.wireframe, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.matrices, nullptr);
|
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.textures, nullptr);
|
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.jointMatrices, nullptr);
|
|
||||||
|
|
||||||
|
|
||||||
shaderData.buffer.destroy();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VulkanExample::getEnabledFeatures()
|
void VulkanExample::getEnabledFeatures()
|
||||||
{
|
{
|
||||||
|
@ -747,6 +714,7 @@ void VulkanExample::getEnabledFeatures()
|
||||||
|
|
||||||
glTFModel.loadAnimations(glTFInput);
|
glTFModel.loadAnimations(glTFInput);
|
||||||
// update joint in nodes
|
// update joint in nodes
|
||||||
|
|
||||||
for (auto node : glTFModel.nodes)
|
for (auto node : glTFModel.nodes)
|
||||||
{
|
{
|
||||||
glTFModel.updateJoints(node);
|
glTFModel.updateJoints(node);
|
||||||
|
@ -1014,7 +982,7 @@ void VulkanExample::getEnabledFeatures()
|
||||||
}
|
}
|
||||||
if (!paused)
|
if (!paused)
|
||||||
{
|
{
|
||||||
glTFModel.updateAnimation(frameTimer,shaderData.buffer);
|
glTFModel.updateAnimation(frameTimer,shaderData.skinSSBO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ public:
|
||||||
}
|
}
|
||||||
glm::mat4 matrix;
|
glm::mat4 matrix;
|
||||||
bool bAnimateNode = false;
|
bool bAnimateNode = false;
|
||||||
/*
|
|
||||||
~Node() {
|
~Node() {
|
||||||
for (auto& child : children) {
|
for (auto& child : children) {
|
||||||
delete child;
|
delete child;
|
||||||
|
@ -99,15 +99,28 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
// material data for pbr
|
||||||
|
struct MaterialData
|
||||||
|
{
|
||||||
|
vks::Buffer buffer;
|
||||||
|
VkDescriptorSet descriptorSet;
|
||||||
|
struct Values
|
||||||
|
{
|
||||||
|
glm::vec3 emissiveFactor;
|
||||||
|
glm::vec4 baseColorFactor;
|
||||||
|
}values;
|
||||||
|
|
||||||
|
};
|
||||||
// A glTF material stores information in e.g. the texture that is attached to it and colors
|
// A glTF material stores information in e.g. the texture that is attached to it and colors
|
||||||
struct Material {
|
struct Material {
|
||||||
glm::vec4 baseColorFactor = glm::vec4(1.0f);
|
glm::vec4 baseColorFactor = glm::vec4(1.0f);
|
||||||
uint32_t baseColorTextureIndex;
|
uint32_t baseColorTextureIndex;
|
||||||
|
uint32_t normalMapTextureIndex;
|
||||||
|
uint32_t matalicRoughTextureIndex;
|
||||||
|
int32_t emissiveTextureIndex = -1;
|
||||||
|
MaterialData materialData;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Contains the texture for a single glTF image
|
// Contains the texture for a single glTF image
|
||||||
|
@ -177,7 +190,27 @@ public:
|
||||||
|
|
||||||
|
|
||||||
//VulkanglTFModel();
|
//VulkanglTFModel();
|
||||||
~VulkanglTFModel();
|
~VulkanglTFModel()
|
||||||
|
{
|
||||||
|
for (auto node : nodes) {
|
||||||
|
delete node;
|
||||||
|
}
|
||||||
|
// Release all Vulkan resources allocated for the model
|
||||||
|
vkDestroyBuffer(vulkanDevice->logicalDevice, vertices.buffer, nullptr);
|
||||||
|
vkFreeMemory(vulkanDevice->logicalDevice, vertices.memory, nullptr);
|
||||||
|
vkDestroyBuffer(vulkanDevice->logicalDevice, indices.buffer, nullptr);
|
||||||
|
vkFreeMemory(vulkanDevice->logicalDevice, indices.memory, nullptr);
|
||||||
|
for (auto& material : materials)
|
||||||
|
{
|
||||||
|
material.materialData.buffer.destroy();
|
||||||
|
}
|
||||||
|
for (Image image : images) {
|
||||||
|
vkDestroyImageView(vulkanDevice->logicalDevice, image.texture.view, nullptr);
|
||||||
|
vkDestroyImage(vulkanDevice->logicalDevice, image.texture.image, nullptr);
|
||||||
|
vkDestroySampler(vulkanDevice->logicalDevice, image.texture.sampler, nullptr);
|
||||||
|
vkFreeMemory(vulkanDevice->logicalDevice, image.texture.deviceMemory, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
void loadImages(tinygltf::Model& input);
|
void loadImages(tinygltf::Model& input);
|
||||||
void loadTextures(tinygltf::Model& input);
|
void loadTextures(tinygltf::Model& input);
|
||||||
void loadMaterials(tinygltf::Model& input);
|
void loadMaterials(tinygltf::Model& input);
|
||||||
|
@ -198,6 +231,9 @@ class VulkanExample : public VulkanExampleBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool wireframe = false;
|
bool wireframe = false;
|
||||||
|
bool normalMapping = true;
|
||||||
|
bool ToneMapping = true;
|
||||||
|
bool pbrEnabled = true;
|
||||||
|
|
||||||
VulkanglTFModel glTFModel;
|
VulkanglTFModel glTFModel;
|
||||||
|
|
||||||
|
@ -208,28 +244,117 @@ public:
|
||||||
glm::mat4 model;
|
glm::mat4 model;
|
||||||
glm::vec4 lightPos = glm::vec4(5.0f, 5.0f, 5.0f, 1.0f);
|
glm::vec4 lightPos = glm::vec4(5.0f, 5.0f, 5.0f, 1.0f);
|
||||||
glm::vec4 viewPos;
|
glm::vec4 viewPos;
|
||||||
|
glm::vec4 bFlagSet = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
} values;
|
} values;
|
||||||
vks::Buffer animationBuffer;
|
vks::Buffer skinSSBO;
|
||||||
} shaderData;
|
} shaderData;
|
||||||
|
|
||||||
struct Pipelines {
|
struct Pipelines {
|
||||||
VkPipeline solid;
|
VkPipeline solid;
|
||||||
VkPipeline wireframe = VK_NULL_HANDLE;
|
VkPipeline wireframe = VK_NULL_HANDLE;
|
||||||
|
VkPipeline toneMapping = VK_NULL_HANDLE;
|
||||||
} pipelines;
|
} pipelines;
|
||||||
|
|
||||||
|
struct PipelineLayouts
|
||||||
|
{
|
||||||
|
VkPipelineLayout pbrLayout;
|
||||||
|
VkPipelineLayout tonemappingLayout;
|
||||||
|
} pipelineLayouts;
|
||||||
|
|
||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout;
|
||||||
|
|
||||||
|
VkDescriptorSet descriptorSet;
|
||||||
|
VkDescriptorSet skinDescriptorSet;
|
||||||
|
VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
struct FrameBufferAttachment
|
||||||
|
{
|
||||||
|
VkImage image;
|
||||||
|
VkDeviceMemory deviceMemory;
|
||||||
|
VkImageView imageView;
|
||||||
|
VkFormat format;
|
||||||
|
|
||||||
|
void destroy(VkDevice device)
|
||||||
|
{
|
||||||
|
vkDestroyImage(device, image, nullptr);
|
||||||
|
vkDestroyImageView(device, imageView,nullptr);
|
||||||
|
vkFreeMemory(device, deviceMemory, nullptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FrameBuffer
|
||||||
|
{
|
||||||
|
int32_t width, height;
|
||||||
|
VkFramebuffer frameBuffer;
|
||||||
|
VkRenderPass renderPass;
|
||||||
|
void setSize(int32_t w, int32_t h)
|
||||||
|
{
|
||||||
|
this->width = w;
|
||||||
|
this->height = h;
|
||||||
|
}
|
||||||
|
void destroy(VkDevice device)
|
||||||
|
{
|
||||||
|
vkDestroyFramebuffer(device, frameBuffer, nullptr);
|
||||||
|
vkDestroyRenderPass(device, renderPass, nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PBRFrameBuffer {
|
||||||
|
FrameBufferAttachment color, depth;
|
||||||
|
FrameBuffer fbo;
|
||||||
|
bool bCreate = false;
|
||||||
|
} pbrFrameBuffer;
|
||||||
|
|
||||||
|
VkSampler colorSampler;
|
||||||
|
|
||||||
struct DescriptorSetLayouts {
|
struct DescriptorSetLayouts {
|
||||||
VkDescriptorSetLayout matrices;
|
VkDescriptorSetLayout matrices;
|
||||||
VkDescriptorSetLayout textures;
|
VkDescriptorSetLayout textures;
|
||||||
|
VkDescriptorSetLayout materialUniform;
|
||||||
|
VkDescriptorSetLayout ssbo;
|
||||||
VkDescriptorSetLayout jointMatrices;
|
VkDescriptorSetLayout jointMatrices;
|
||||||
} descriptorSetLayouts;
|
} descriptorSetLayouts;
|
||||||
|
|
||||||
VkDescriptorSet descriptorSet;
|
struct IBLTextures
|
||||||
|
{
|
||||||
|
vks::TextureCubeMap skyboxCube;
|
||||||
|
vks::TextureCubeMap irradianceCube;
|
||||||
|
vks::TextureCubeMap prefilteredCube;
|
||||||
|
vks::Texture2D lutBrdf;
|
||||||
|
} ibltextures;
|
||||||
|
|
||||||
|
VulkanglTFModel skyboxModel;
|
||||||
|
|
||||||
VulkanExample();
|
VulkanExample();
|
||||||
~VulkanExample();
|
~VulkanExample()
|
||||||
|
{
|
||||||
|
// Clean up used Vulkan resources
|
||||||
|
// Note : Inherited destructor cleans up resources stored in base class
|
||||||
|
vkDestroyPipeline(device, pipelines.solid, nullptr);
|
||||||
|
vkDestroyPipeline(device, pipelines.toneMapping, nullptr);
|
||||||
|
if (pipelines.wireframe != VK_NULL_HANDLE) {
|
||||||
|
vkDestroyPipeline(device, pipelines.wireframe, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroyPipelineLayout(device, pipelineLayouts.pbrLayout, nullptr);
|
||||||
|
vkDestroyPipelineLayout(device, pipelineLayouts.tonemappingLayout, nullptr);
|
||||||
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.matrices, nullptr);
|
||||||
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.textures, nullptr);
|
||||||
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.materialUniform, nullptr);
|
||||||
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.ssbo, nullptr);
|
||||||
|
ibltextures.irradianceCube.destroy();
|
||||||
|
ibltextures.skyboxCube.destroy();
|
||||||
|
ibltextures.prefilteredCube.destroy();
|
||||||
|
ibltextures.lutBrdf.destroy();
|
||||||
|
pbrFrameBuffer.color.destroy(device);
|
||||||
|
pbrFrameBuffer.depth.destroy(device);
|
||||||
|
pbrFrameBuffer.fbo.destroy(device);
|
||||||
|
vkDestroySampler(device, colorSampler, nullptr);
|
||||||
|
|
||||||
|
shaderData.buffer.destroy();
|
||||||
|
shaderData.skinSSBO.destroy();
|
||||||
|
}
|
||||||
void loadglTFFile(std::string filename);
|
void loadglTFFile(std::string filename);
|
||||||
virtual void getEnabledFeatures();
|
virtual void getEnabledFeatures();
|
||||||
void buildCommandBuffers();
|
void buildCommandBuffers();
|
||||||
|
|
Loading…
Reference in New Issue