ready for pbr and tonemapping
							parent
							
								
									39ba805802
								
							
						
					
					
						commit
						077d91916f
					
				| 
						 | 
				
			
			@ -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,44 +185,48 @@ 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());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
	VkPipelineLayout pipelineLayout;
 | 
			
		||||
	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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue