feat(render): 重构离屏渲染资源管理并优化光照计算
- 移除对 gli 库的引用,后续不再使用该第三方库,补充stb_image作为替代 - 引入 RenderOffScreen、RenderLightSource 等封装类统一管理离屏渲染资源 - 使用成员变量替代局部变量,通过 getter 方法访问 Vulkan 资源句柄 - 将 push constant 数据封装到专用结构体中,并提供设置方法 - 更新光照方向计算逻辑,使用封装后的光源旋转数据 - 清理冗余代码,提升 generateCubemaps 函数可读性与维护性reconstruct-gltfLoader
parent
1c207b7fab
commit
98335c7edc
Binary file not shown.
|
|
@ -12,7 +12,7 @@ project(${RenderName})
|
|||
set(3rdPARTY_PATH "${CMAKE_SOURCE_DIR}/3rdparty")
|
||||
|
||||
set(3rdParty_imgui_path "${3rdPARTY_PATH}/imgui")
|
||||
set(3rdParty_gli_path "${3rdPARTY_PATH}/gli")
|
||||
#set(3rdParty_gli_path "${3rdPARTY_PATH}/gli")
|
||||
set(3rdParty_glm_path "${3rdPARTY_PATH}/glm")
|
||||
set(3rdParty_stb_path "${3rdPARTY_PATH}/stb")
|
||||
set(3rdParty_tinygltf_path "${3rdPARTY_PATH}/tinygltf")
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ set(GLTF_MODEL_LOADER
|
|||
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/src/render VULKAN_BASE)
|
||||
|
||||
include_directories(${3rdParty_gli_path})
|
||||
#include_directories(${3rdParty_gli_path})
|
||||
include_directories(${3rdParty_glm_path})
|
||||
include_directories(${3rdParty_imgui_path})
|
||||
include_directories(${3rdParty_stb_path})
|
||||
|
|
|
|||
|
|
@ -931,6 +931,8 @@ void PlumageRender::generateCubemaps()
|
|||
|
||||
// Create offscreen framebuffer
|
||||
{
|
||||
VkImage offscreenImage = m_offScreen.getImage();
|
||||
VkDeviceMemory offscreenMemory = m_offScreen.getMemory();
|
||||
// Image
|
||||
VkImageCreateInfo imageCI{};
|
||||
imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
|
|
@ -946,17 +948,19 @@ void PlumageRender::generateCubemaps()
|
|||
imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageCI.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &offscreen.image));
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &offscreenImage));
|
||||
VkMemoryRequirements memReqs;
|
||||
vkGetImageMemoryRequirements(device, offscreen.image, &memReqs);
|
||||
vkGetImageMemoryRequirements(device, offscreenImage, &memReqs);
|
||||
VkMemoryAllocateInfo memAllocInfo{};
|
||||
memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
memAllocInfo.allocationSize = memReqs.size;
|
||||
memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &offscreen.memory));
|
||||
VK_CHECK_RESULT(vkBindImageMemory(device, offscreen.image, offscreen.memory, 0));
|
||||
VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &offscreenMemory));
|
||||
VK_CHECK_RESULT(vkBindImageMemory(device, offscreenImage, offscreenMemory, 0));
|
||||
|
||||
// View
|
||||
VkImageView offscreenImageView = m_offScreen.getView();
|
||||
VkImageViewCreateInfo viewCI{};
|
||||
viewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewCI.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
|
|
@ -968,24 +972,25 @@ void PlumageRender::generateCubemaps()
|
|||
viewCI.subresourceRange.levelCount = 1;
|
||||
viewCI.subresourceRange.baseArrayLayer = 0;
|
||||
viewCI.subresourceRange.layerCount = 1;
|
||||
viewCI.image = offscreen.image;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device, &viewCI, nullptr, &offscreen.view));
|
||||
viewCI.image = offscreenImage;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device, &viewCI, nullptr, &offscreenImageView));
|
||||
|
||||
// Framebuffer
|
||||
VkFramebufferCreateInfo framebufferCI{};
|
||||
framebufferCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
framebufferCI.renderPass = renderpass;
|
||||
framebufferCI.attachmentCount = 1;
|
||||
framebufferCI.pAttachments = &offscreen.view;
|
||||
framebufferCI.pAttachments = &offscreenImageView;
|
||||
framebufferCI.width = dim;
|
||||
framebufferCI.height = dim;
|
||||
framebufferCI.layers = 1;
|
||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCI, nullptr, &offscreen.framebuffer));
|
||||
VkFramebuffer offscreenFrameBuffer = m_offScreen.getFramebuffer();
|
||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCI, nullptr, &offscreenFrameBuffer));
|
||||
|
||||
VkCommandBuffer layoutCmd = vulkanDevice->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
|
||||
VkImageMemoryBarrier imageMemoryBarrier{};
|
||||
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
imageMemoryBarrier.image = offscreen.image;
|
||||
imageMemoryBarrier.image = offscreenImage;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
|
|
@ -1151,7 +1156,7 @@ void PlumageRender::generateCubemaps()
|
|||
VkRenderPassBeginInfo renderPassBeginInfo{};
|
||||
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassBeginInfo.renderPass = renderpass;
|
||||
renderPassBeginInfo.framebuffer = offscreen.framebuffer;
|
||||
renderPassBeginInfo.framebuffer = m_offScreen.getFramebuffer();
|
||||
renderPassBeginInfo.renderArea.extent.width = dim;
|
||||
renderPassBeginInfo.renderArea.extent.height = dim;
|
||||
renderPassBeginInfo.clearValueCount = 1;
|
||||
|
|
@ -1222,13 +1227,13 @@ void PlumageRender::generateCubemaps()
|
|||
switch (target)
|
||||
{
|
||||
case IRRADIANCE:
|
||||
irradiancePushBlock.mvp = glm::perspective((float)(M_PI / 2.0), 1.0f, 0.1f, 512.0f) * matrices[f];
|
||||
vkCmdPushConstants(cmdBuf, pipelinelayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(IrradiancePushBlock), &irradiancePushBlock);
|
||||
m_irradiancePushBlock.setMvp(glm::perspective((float)(M_PI / 2.0), 1.0f, 0.1f, 512.0f) * matrices[f]);
|
||||
vkCmdPushConstants(cmdBuf, pipelinelayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(IrradiancePushBlock), &m_irradiancePushBlock);
|
||||
break;
|
||||
case PREFILTEREDENV:
|
||||
prefilterPushBlock.mvp = glm::perspective((float)(M_PI / 2.0), 1.0f, 0.1f, 512.0f) * matrices[f];
|
||||
prefilterPushBlock.roughness = 0.0; //(float)m / (float)(numMips - 1);
|
||||
vkCmdPushConstants(cmdBuf, pipelinelayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PrefilterPushBlock), &prefilterPushBlock);
|
||||
m_prefilterPushBlock.setMvp(glm::perspective((float)(M_PI / 2.0), 1.0f, 0.1f, 512.0f) * matrices[f]);
|
||||
m_prefilterPushBlock.setRoughness(0.0); //(float)m / (float)(numMips - 1);
|
||||
vkCmdPushConstants(cmdBuf, pipelinelayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PrefilterPushBlock), &m_prefilterPushBlock);
|
||||
break;
|
||||
};
|
||||
|
||||
|
|
@ -1250,7 +1255,7 @@ void PlumageRender::generateCubemaps()
|
|||
{
|
||||
VkImageMemoryBarrier imageMemoryBarrier{};
|
||||
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
imageMemoryBarrier.image = offscreen.image;
|
||||
imageMemoryBarrier.image = m_offScreen.getImage();
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
|
@ -1280,7 +1285,7 @@ void PlumageRender::generateCubemaps()
|
|||
|
||||
vkCmdCopyImage(
|
||||
cmdBuf,
|
||||
offscreen.image,
|
||||
m_offScreen.getImage(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
cubemap.image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
|
|
@ -1290,7 +1295,7 @@ void PlumageRender::generateCubemaps()
|
|||
{
|
||||
VkImageMemoryBarrier imageMemoryBarrier{};
|
||||
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
imageMemoryBarrier.image = offscreen.image;
|
||||
imageMemoryBarrier.image = m_offScreen.getImage();
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
|
|
@ -1318,10 +1323,10 @@ void PlumageRender::generateCubemaps()
|
|||
}
|
||||
|
||||
vkDestroyRenderPass(device, renderpass, nullptr);
|
||||
vkDestroyFramebuffer(device, offscreen.framebuffer, nullptr);
|
||||
vkFreeMemory(device, offscreen.memory, nullptr);
|
||||
vkDestroyImageView(device, offscreen.view, nullptr);
|
||||
vkDestroyImage(device, offscreen.image, nullptr);
|
||||
vkDestroyFramebuffer(device, m_offScreen.getFramebuffer(), nullptr);
|
||||
vkFreeMemory(device, m_offScreen.getMemory(), nullptr);
|
||||
vkDestroyImageView(device, m_offScreen.getView(), nullptr);
|
||||
vkDestroyImage(device, m_offScreen.getImage(), nullptr);
|
||||
vkDestroyDescriptorPool(device, descriptorpool, nullptr);
|
||||
vkDestroyDescriptorSetLayout(device, descriptorsetlayout, nullptr);
|
||||
vkDestroyPipeline(device, pipeline, nullptr);
|
||||
|
|
@ -1661,9 +1666,9 @@ void PlumageRender::updateUniformBuffers()
|
|||
void PlumageRender::updateShaderData()
|
||||
{
|
||||
glm::vec4 currentLightDir = glm::vec4(
|
||||
sin(glm::radians(lightSource.rotation.x)) * cos(glm::radians(lightSource.rotation.y)),
|
||||
sin(glm::radians(lightSource.rotation.y)),
|
||||
cos(glm::radians(lightSource.rotation.x)) * cos(glm::radians(lightSource.rotation.y)),
|
||||
sin(glm::radians(m_lightSource.getRotation().x)) * cos(glm::radians(m_lightSource.getRotation().y)),
|
||||
sin(glm::radians(m_lightSource.getRotation().y)),
|
||||
cos(glm::radians(m_lightSource.getRotation().x)) * cos(glm::radians(m_lightSource.getRotation().y)),
|
||||
0.0f);
|
||||
m_shaderData.setLightDir(currentLightDir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "ConfigFilePath.h"
|
||||
#include "RenderDescriptorSetLayoutList.h"
|
||||
#include "RenderOffScreen.h"
|
||||
#include "RenderPipelineList.h"
|
||||
#include "RenderSceneTextures.h"
|
||||
#include "renderShaderData.h"
|
||||
|
|
@ -44,8 +45,12 @@
|
|||
|
||||
#include "ConfigFilePath.h"
|
||||
#include "IndexStagingBuffer.h"
|
||||
#include "IrradiancePushBlock.h"
|
||||
#include "PrefilterPushBlock.h"
|
||||
#include "RenderDescriptorSetLayoutList.h"
|
||||
#include "RenderDescriptorSetList.h"
|
||||
#include "RenderLightSource.h"
|
||||
#include "RenderOffScreen.h"
|
||||
#include "RenderPipelineLayoutList.h"
|
||||
#include "RenderPipelineList.h"
|
||||
#include "RenderSceneTextures.h"
|
||||
|
|
@ -79,6 +84,12 @@ private:
|
|||
RenderPipelineLayoutList m_pipelineLayoutList;
|
||||
|
||||
RenderDescriptorSetLayoutList m_descriptorSetLayoutList;
|
||||
RenderLightSource m_lightSource;
|
||||
|
||||
RenderOffScreen m_offScreen;
|
||||
|
||||
IrradiancePushBlock m_irradiancePushBlock;
|
||||
PrefilterPushBlock m_prefilterPushBlock;
|
||||
|
||||
public:
|
||||
float modelrot = 0.0f;
|
||||
|
|
@ -122,37 +133,8 @@ public:
|
|||
|
||||
bool displayBackground = true;
|
||||
|
||||
struct LightSource
|
||||
{
|
||||
glm::vec3 color = glm::vec3(1.0f);
|
||||
glm::vec3 rotation = glm::vec3(75.0f, 40.0f, 0.0f);
|
||||
} lightSource;
|
||||
|
||||
// cube map generation
|
||||
|
||||
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;
|
||||
|
||||
UI *gui;
|
||||
|
||||
uint64_t savedFrameCounter = settings.startFrameCount;
|
||||
|
|
|
|||
Loading…
Reference in New Issue