ready for pbr and tonemapping

pull/2/head
InkSoul 2023-05-22 11:21:13 +08:00
parent 39ba805802
commit 077d91916f
2 changed files with 175 additions and 82 deletions

View File

@ -21,27 +21,6 @@
#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
@ -206,46 +185,50 @@ VulkanglTFModel::~VulkanglTFModel()
{
skins.resize(input.skins.size());
for (size_t i = 0; i < input.skins.size(); i++)
if (skins.size() > 0)
{
tinygltf::Skin glTFSkin = input.skins[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)
for (size_t i = 0; i < input.skins.size(); i++)
{
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));
tinygltf::Skin glTFSkin = input.skins[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);
}
}
//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
@ -542,6 +525,7 @@ VulkanglTFModel::~VulkanglTFModel()
if (channel.path == "translation")
{
channel.node->translation = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], ratio);
channel.node->bAnimateNode = true;
}
if (channel.path == "rotation")
{
@ -596,7 +580,7 @@ VulkanglTFModel::~VulkanglTFModel()
}
// Pass the final matrix to the vertex shader using push constants
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);
}
@ -645,24 +629,7 @@ VulkanExample::VulkanExample():
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()
{
@ -747,6 +714,7 @@ void VulkanExample::getEnabledFeatures()
glTFModel.loadAnimations(glTFInput);
// update joint in nodes
for (auto node : glTFModel.nodes)
{
glTFModel.updateJoints(node);
@ -1014,7 +982,7 @@ void VulkanExample::getEnabledFeatures()
}
if (!paused)
{
glTFModel.updateAnimation(frameTimer,shaderData.buffer);
glTFModel.updateAnimation(frameTimer,shaderData.skinSSBO);
}
}

View File

@ -91,7 +91,7 @@ public:
}
glm::mat4 matrix;
bool bAnimateNode = false;
/*
~Node() {
for (auto& child : children) {
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
struct Material {
glm::vec4 baseColorFactor = glm::vec4(1.0f);
uint32_t baseColorTextureIndex;
uint32_t normalMapTextureIndex;
uint32_t matalicRoughTextureIndex;
int32_t emissiveTextureIndex = -1;
MaterialData materialData;
};
// Contains the texture for a single glTF image
@ -177,7 +190,27 @@ public:
//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 loadTextures(tinygltf::Model& input);
void loadMaterials(tinygltf::Model& input);
@ -198,6 +231,9 @@ class VulkanExample : public VulkanExampleBase
{
public:
bool wireframe = false;
bool normalMapping = true;
bool ToneMapping = true;
bool pbrEnabled = true;
VulkanglTFModel glTFModel;
@ -208,28 +244,117 @@ public:
glm::mat4 model;
glm::vec4 lightPos = glm::vec4(5.0f, 5.0f, 5.0f, 1.0f);
glm::vec4 viewPos;
glm::vec4 bFlagSet = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
} values;
vks::Buffer animationBuffer;
vks::Buffer skinSSBO;
} shaderData;
struct Pipelines {
VkPipeline solid;
VkPipeline wireframe = VK_NULL_HANDLE;
VkPipeline toneMapping = VK_NULL_HANDLE;
} pipelines;
struct PipelineLayouts
{
VkPipelineLayout pbrLayout;
VkPipelineLayout tonemappingLayout;
} pipelineLayouts;
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 {
VkDescriptorSetLayout matrices;
VkDescriptorSetLayout textures;
VkDescriptorSetLayout materialUniform;
VkDescriptorSetLayout ssbo;
VkDescriptorSetLayout jointMatrices;
} descriptorSetLayouts;
VkDescriptorSet descriptorSet;
struct IBLTextures
{
vks::TextureCubeMap skyboxCube;
vks::TextureCubeMap irradianceCube;
vks::TextureCubeMap prefilteredCube;
vks::Texture2D lutBrdf;
} ibltextures;
VulkanglTFModel skyboxModel;
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);
virtual void getEnabledFeatures();
void buildCommandBuffers();