feat(render): 重构离屏渲染资源管理并优化光照计算

- 移除对 gli 库的引用,后续不再使用该第三方库,补充stb_image作为替代
- 引入 RenderOffScreen、RenderLightSource 等封装类统一管理离屏渲染资源
- 使用成员变量替代局部变量,通过 getter 方法访问 Vulkan 资源句柄
- 将 push constant 数据封装到专用结构体中,并提供设置方法
- 更新光照方向计算逻辑,使用封装后的光源旋转数据
- 清理冗余代码,提升 generateCubemaps 函数可读性与维护性
reconstruct-gltfLoader
InkSoul 2025-11-29 15:28:27 +08:00
parent 1c207b7fab
commit 98335c7edc
5 changed files with 43 additions and 56 deletions

BIN
3rdparty/stb/stb_image.h vendored 100644

Binary file not shown.

View File

@ -12,7 +12,7 @@ project(${RenderName})
set(3rdPARTY_PATH "${CMAKE_SOURCE_DIR}/3rdparty") set(3rdPARTY_PATH "${CMAKE_SOURCE_DIR}/3rdparty")
set(3rdParty_imgui_path "${3rdPARTY_PATH}/imgui") 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_glm_path "${3rdPARTY_PATH}/glm")
set(3rdParty_stb_path "${3rdPARTY_PATH}/stb") set(3rdParty_stb_path "${3rdPARTY_PATH}/stb")
set(3rdParty_tinygltf_path "${3rdPARTY_PATH}/tinygltf") set(3rdParty_tinygltf_path "${3rdPARTY_PATH}/tinygltf")

View File

@ -42,7 +42,7 @@ set(GLTF_MODEL_LOADER
aux_source_directory(${PROJECT_SOURCE_DIR}/src/render VULKAN_BASE) 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_glm_path})
include_directories(${3rdParty_imgui_path}) include_directories(${3rdParty_imgui_path})
include_directories(${3rdParty_stb_path}) include_directories(${3rdParty_stb_path})

View File

@ -931,6 +931,8 @@ void PlumageRender::generateCubemaps()
// Create offscreen framebuffer // Create offscreen framebuffer
{ {
VkImage offscreenImage = m_offScreen.getImage();
VkDeviceMemory offscreenMemory = m_offScreen.getMemory();
// Image // Image
VkImageCreateInfo imageCI{}; VkImageCreateInfo imageCI{};
imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@ -946,17 +948,19 @@ void PlumageRender::generateCubemaps()
imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageCI.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; imageCI.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 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; VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(device, offscreen.image, &memReqs); vkGetImageMemoryRequirements(device, offscreenImage, &memReqs);
VkMemoryAllocateInfo memAllocInfo{}; VkMemoryAllocateInfo memAllocInfo{};
memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memAllocInfo.allocationSize = memReqs.size; memAllocInfo.allocationSize = memReqs.size;
memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &offscreen.memory)); VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &offscreenMemory));
VK_CHECK_RESULT(vkBindImageMemory(device, offscreen.image, offscreen.memory, 0)); VK_CHECK_RESULT(vkBindImageMemory(device, offscreenImage, offscreenMemory, 0));
// View // View
VkImageView offscreenImageView = m_offScreen.getView();
VkImageViewCreateInfo viewCI{}; VkImageViewCreateInfo viewCI{};
viewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewCI.viewType = VK_IMAGE_VIEW_TYPE_2D; viewCI.viewType = VK_IMAGE_VIEW_TYPE_2D;
@ -968,24 +972,25 @@ void PlumageRender::generateCubemaps()
viewCI.subresourceRange.levelCount = 1; viewCI.subresourceRange.levelCount = 1;
viewCI.subresourceRange.baseArrayLayer = 0; viewCI.subresourceRange.baseArrayLayer = 0;
viewCI.subresourceRange.layerCount = 1; viewCI.subresourceRange.layerCount = 1;
viewCI.image = offscreen.image; viewCI.image = offscreenImage;
VK_CHECK_RESULT(vkCreateImageView(device, &viewCI, nullptr, &offscreen.view)); VK_CHECK_RESULT(vkCreateImageView(device, &viewCI, nullptr, &offscreenImageView));
// Framebuffer // Framebuffer
VkFramebufferCreateInfo framebufferCI{}; VkFramebufferCreateInfo framebufferCI{};
framebufferCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferCI.renderPass = renderpass; framebufferCI.renderPass = renderpass;
framebufferCI.attachmentCount = 1; framebufferCI.attachmentCount = 1;
framebufferCI.pAttachments = &offscreen.view; framebufferCI.pAttachments = &offscreenImageView;
framebufferCI.width = dim; framebufferCI.width = dim;
framebufferCI.height = dim; framebufferCI.height = dim;
framebufferCI.layers = 1; 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); VkCommandBuffer layoutCmd = vulkanDevice->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
VkImageMemoryBarrier imageMemoryBarrier{}; VkImageMemoryBarrier imageMemoryBarrier{};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.image = offscreen.image; imageMemoryBarrier.image = offscreenImage;
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
imageMemoryBarrier.srcAccessMask = 0; imageMemoryBarrier.srcAccessMask = 0;
@ -1151,7 +1156,7 @@ void PlumageRender::generateCubemaps()
VkRenderPassBeginInfo renderPassBeginInfo{}; VkRenderPassBeginInfo renderPassBeginInfo{};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.renderPass = renderpass; renderPassBeginInfo.renderPass = renderpass;
renderPassBeginInfo.framebuffer = offscreen.framebuffer; renderPassBeginInfo.framebuffer = m_offScreen.getFramebuffer();
renderPassBeginInfo.renderArea.extent.width = dim; renderPassBeginInfo.renderArea.extent.width = dim;
renderPassBeginInfo.renderArea.extent.height = dim; renderPassBeginInfo.renderArea.extent.height = dim;
renderPassBeginInfo.clearValueCount = 1; renderPassBeginInfo.clearValueCount = 1;
@ -1222,13 +1227,13 @@ void PlumageRender::generateCubemaps()
switch (target) switch (target)
{ {
case IRRADIANCE: case IRRADIANCE:
irradiancePushBlock.mvp = glm::perspective((float)(M_PI / 2.0), 1.0f, 0.1f, 512.0f) * matrices[f]; 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), &irradiancePushBlock); vkCmdPushConstants(cmdBuf, pipelinelayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(IrradiancePushBlock), &m_irradiancePushBlock);
break; break;
case PREFILTEREDENV: case PREFILTEREDENV:
prefilterPushBlock.mvp = glm::perspective((float)(M_PI / 2.0), 1.0f, 0.1f, 512.0f) * matrices[f]; m_prefilterPushBlock.setMvp(glm::perspective((float)(M_PI / 2.0), 1.0f, 0.1f, 512.0f) * matrices[f]);
prefilterPushBlock.roughness = 0.0; //(float)m / (float)(numMips - 1); 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), &prefilterPushBlock); vkCmdPushConstants(cmdBuf, pipelinelayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PrefilterPushBlock), &m_prefilterPushBlock);
break; break;
}; };
@ -1250,7 +1255,7 @@ void PlumageRender::generateCubemaps()
{ {
VkImageMemoryBarrier imageMemoryBarrier{}; VkImageMemoryBarrier imageMemoryBarrier{};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 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.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
@ -1280,7 +1285,7 @@ void PlumageRender::generateCubemaps()
vkCmdCopyImage( vkCmdCopyImage(
cmdBuf, cmdBuf,
offscreen.image, m_offScreen.getImage(),
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
cubemap.image, cubemap.image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
@ -1290,7 +1295,7 @@ void PlumageRender::generateCubemaps()
{ {
VkImageMemoryBarrier imageMemoryBarrier{}; VkImageMemoryBarrier imageMemoryBarrier{};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 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.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
@ -1318,10 +1323,10 @@ void PlumageRender::generateCubemaps()
} }
vkDestroyRenderPass(device, renderpass, nullptr); vkDestroyRenderPass(device, renderpass, nullptr);
vkDestroyFramebuffer(device, offscreen.framebuffer, nullptr); vkDestroyFramebuffer(device, m_offScreen.getFramebuffer(), nullptr);
vkFreeMemory(device, offscreen.memory, nullptr); vkFreeMemory(device, m_offScreen.getMemory(), nullptr);
vkDestroyImageView(device, offscreen.view, nullptr); vkDestroyImageView(device, m_offScreen.getView(), nullptr);
vkDestroyImage(device, offscreen.image, nullptr); vkDestroyImage(device, m_offScreen.getImage(), nullptr);
vkDestroyDescriptorPool(device, descriptorpool, nullptr); vkDestroyDescriptorPool(device, descriptorpool, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorsetlayout, nullptr); vkDestroyDescriptorSetLayout(device, descriptorsetlayout, nullptr);
vkDestroyPipeline(device, pipeline, nullptr); vkDestroyPipeline(device, pipeline, nullptr);
@ -1661,9 +1666,9 @@ void PlumageRender::updateUniformBuffers()
void PlumageRender::updateShaderData() void PlumageRender::updateShaderData()
{ {
glm::vec4 currentLightDir = glm::vec4( glm::vec4 currentLightDir = glm::vec4(
sin(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(lightSource.rotation.y)), sin(glm::radians(m_lightSource.getRotation().y)),
cos(glm::radians(lightSource.rotation.x)) * cos(glm::radians(lightSource.rotation.y)), cos(glm::radians(m_lightSource.getRotation().x)) * cos(glm::radians(m_lightSource.getRotation().y)),
0.0f); 0.0f);
m_shaderData.setLightDir(currentLightDir); m_shaderData.setLightDir(currentLightDir);
} }

View File

@ -2,6 +2,7 @@
#include "ConfigFilePath.h" #include "ConfigFilePath.h"
#include "RenderDescriptorSetLayoutList.h" #include "RenderDescriptorSetLayoutList.h"
#include "RenderOffScreen.h"
#include "RenderPipelineList.h" #include "RenderPipelineList.h"
#include "RenderSceneTextures.h" #include "RenderSceneTextures.h"
#include "renderShaderData.h" #include "renderShaderData.h"
@ -44,8 +45,12 @@
#include "ConfigFilePath.h" #include "ConfigFilePath.h"
#include "IndexStagingBuffer.h" #include "IndexStagingBuffer.h"
#include "IrradiancePushBlock.h"
#include "PrefilterPushBlock.h"
#include "RenderDescriptorSetLayoutList.h" #include "RenderDescriptorSetLayoutList.h"
#include "RenderDescriptorSetList.h" #include "RenderDescriptorSetList.h"
#include "RenderLightSource.h"
#include "RenderOffScreen.h"
#include "RenderPipelineLayoutList.h" #include "RenderPipelineLayoutList.h"
#include "RenderPipelineList.h" #include "RenderPipelineList.h"
#include "RenderSceneTextures.h" #include "RenderSceneTextures.h"
@ -79,6 +84,12 @@ private:
RenderPipelineLayoutList m_pipelineLayoutList; RenderPipelineLayoutList m_pipelineLayoutList;
RenderDescriptorSetLayoutList m_descriptorSetLayoutList; RenderDescriptorSetLayoutList m_descriptorSetLayoutList;
RenderLightSource m_lightSource;
RenderOffScreen m_offScreen;
IrradiancePushBlock m_irradiancePushBlock;
PrefilterPushBlock m_prefilterPushBlock;
public: public:
float modelrot = 0.0f; float modelrot = 0.0f;
@ -122,37 +133,8 @@ public:
bool displayBackground = true; 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 // 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; UI *gui;
uint64_t savedFrameCounter = settings.startFrameCount; uint64_t savedFrameCounter = settings.startFrameCount;