2023-05-26 16:19:12 +08:00
|
|
|
#pragma once
|
2023-05-26 15:20:44 +08:00
|
|
|
|
2023-05-26 16:19:12 +08:00
|
|
|
|
2023-05-26 15:20:44 +08:00
|
|
|
#include "vulkanexamplebase.h"
|
|
|
|
#include "glTFModel.h"
|
|
|
|
|
2023-06-01 00:05:36 +08:00
|
|
|
|
2023-05-26 15:20:44 +08:00
|
|
|
#define ENABLE_VALIDATION false
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-06-02 09:56:49 +08:00
|
|
|
class PlumageRender : public VulkanExampleBase
|
2023-05-26 15:20:44 +08:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool wireframe = false;
|
|
|
|
bool normalMapping = true;
|
|
|
|
bool ToneMapping = true;
|
|
|
|
bool pbrEnabled = true;
|
|
|
|
|
|
|
|
VulkanglTFModel glTFModel;
|
|
|
|
|
|
|
|
struct ShaderData {
|
|
|
|
vks::Buffer buffer;
|
|
|
|
struct Values {
|
|
|
|
glm::mat4 projection;
|
|
|
|
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 skinSSBO;
|
|
|
|
} shaderData;
|
|
|
|
|
2023-06-01 15:32:08 +08:00
|
|
|
struct FilePath
|
|
|
|
{
|
|
|
|
std::string glTFModelFilePath = getAssetPath() + "buster_drone/busterDrone.gltf";
|
|
|
|
std::string skyboxModleFilePath = getAssetPath() + "models/cube.gltf";
|
|
|
|
std::string iblTexturesFilePath = getAssetPath() + "textures/hdr/pisa_cube.ktx";
|
|
|
|
std::string modelVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.vert.spv";
|
|
|
|
std::string modelFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.frag.spv";
|
|
|
|
std::string tonemappingVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/genbrdflut.vert.spv";
|
|
|
|
std::string tonemappingEnableFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/tonemapping_enable.frag.spv";
|
|
|
|
std::string tonemappingDisableFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/tonemapping_disable.frag.spv";
|
|
|
|
std::string irradianceVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/filtercube.vert.spv";
|
|
|
|
std::string irradianceFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/irradiancecube.frag.spv";
|
|
|
|
std::string prefilterVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/filtercube.vert.spv";
|
|
|
|
std::string prefilterFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/prefilterenvmap.frag.spv";
|
|
|
|
std::string brdfVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/genbrdflut.vert.spv";
|
|
|
|
std::string brdfFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/genbrdflut.frag.spv";
|
|
|
|
|
|
|
|
|
|
|
|
} filePath;
|
|
|
|
|
2023-05-26 15:20:44 +08:00
|
|
|
struct StagingBuffer {
|
|
|
|
VkBuffer buffer;
|
|
|
|
VkDeviceMemory memory;
|
|
|
|
} vertexStaging, indexStaging;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
struct IBLTextures
|
|
|
|
{
|
|
|
|
vks::TextureCubeMap skyboxCube;
|
|
|
|
vks::TextureCubeMap irradianceCube;
|
|
|
|
vks::TextureCubeMap prefilteredCube;
|
|
|
|
vks::Texture2D lutBrdf;
|
|
|
|
} ibltextures;
|
|
|
|
|
|
|
|
struct OffScreen
|
|
|
|
{
|
|
|
|
VkImage image;
|
|
|
|
VkImageView view;
|
|
|
|
VkDeviceMemory memory;
|
|
|
|
VkFramebuffer framebuffer;
|
|
|
|
} offscreen;
|
|
|
|
|
|
|
|
struct IrradiancePushBlock
|
|
|
|
{
|
|
|
|
glm::mat4 mvp;
|
|
|
|
// Sampling deltas
|
|
|
|
float deltaPhi = (2.0f * float(M_PI)) / 180.0f;
|
|
|
|
float deltaTheta = (0.5f * float(M_PI)) / 64.0f;
|
|
|
|
} irradiancePushBlock;
|
|
|
|
|
|
|
|
struct PrefilterPushBlock {
|
|
|
|
glm::mat4 mvp;
|
|
|
|
float roughness;
|
|
|
|
uint32_t numSamples = 32u;
|
|
|
|
} prefilterPushBlock;
|
|
|
|
|
|
|
|
VulkanglTFModel skyboxModel;
|
|
|
|
|
2023-06-02 09:56:49 +08:00
|
|
|
PlumageRender();
|
|
|
|
~PlumageRender()
|
2023-05-26 15:20:44 +08:00
|
|
|
{
|
|
|
|
// 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, VulkanglTFModel& model, bool bSkyboxFlag);
|
|
|
|
virtual void getEnabledFeatures();
|
|
|
|
void createAttachment(VkFormat format, VkImageUsageFlagBits usage, FrameBufferAttachment* attachment, uint32_t width, uint32_t height);
|
|
|
|
virtual void setupFrameBuffer();
|
|
|
|
void buildCommandBuffers();
|
|
|
|
void loadAssets();
|
|
|
|
void setupDescriptors();
|
|
|
|
void preparePipelines();
|
|
|
|
void CreateToneMappingPipeline();
|
|
|
|
void GenerateIrradianceCubemap();
|
|
|
|
void GeneratePrefilteredCubemap();
|
|
|
|
void GenerateBRDFLUT();
|
|
|
|
void prepareUniformBuffers();
|
|
|
|
void updateUniformBuffers();
|
|
|
|
void prepare();
|
|
|
|
virtual void render();
|
|
|
|
virtual void viewChanged();
|
|
|
|
virtual void OnUpdateUIOverlay(vks::UIOverlay* overlay);
|
|
|
|
};
|