* 级联阴影初步完成

This commit is contained in:
2026-05-12 19:48:32 +08:00
parent e263237057
commit ca3490e728
14 changed files with 367 additions and 126 deletions
+19
View File
@@ -51,6 +51,25 @@ struct RenderInfo3D
{}
};
//! 调试绘图3d
enum class DebugView3D
{
NONE,
DIFFUSE = 1, // 漫反射
NORMAL, // 法线
AO, // 几何遮蔽
EMISSIVE, // 自发光
METALLIC, // 金属度
ROUGHNESS, // 粗糙度
PBR_DIFFUSE = 10, // pbr漫反射
PBR_F, // pbr 菲涅尔
PBR_G, // pbr 几何遮蔽
PBR_D, // pbr 微表面分布
PBR_SPEC, // pbr 高光
REFLECTION, // 反射向量
CASCADE = 20, // 级联阴影
};
//! 设备属性
struct DeviceInfo
{
+1
View File
@@ -16,3 +16,4 @@
#include "base/dl_type_create.h"
#include "base/dl_type_convert.h"
#include "base/dl_string_n.h"
#include "base/dl_type_user.h"
+76 -4
View File
@@ -181,14 +181,86 @@ Camera* Factory::GetCamera()
}
void Factory::SetDebugViewTexture(int texture)
void Factory::SetDebugView3D(DebugView3D type)
{
g_vk->SetDebugViewTexture(texture);
g_vk->SetDebugView(type);
}
void Factory::SetDebugViewPbr(int pbr)
void Factory::UpdateDebugView()
{
g_vk->SetDebugViewPbr(pbr);
//
bool ctrl = g_input->KeyState(KeyCode::LEFT_CONTROL);
bool alt = g_input->KeyState(KeyCode::LEFT_ALT);
if (!ctrl && !alt)
{
if (g_input->KeyDown(KeyCode::KP_0))
SetDebugView3D((DebugView3D)0);
else if (g_input->KeyDown(KeyCode::KP_1))
SetDebugView3D((DebugView3D)1);
else if (g_input->KeyDown(KeyCode::KP_2))
SetDebugView3D((DebugView3D)2);
else if (g_input->KeyDown(KeyCode::KP_3))
SetDebugView3D((DebugView3D)3);
else if (g_input->KeyDown(KeyCode::KP_4))
SetDebugView3D((DebugView3D)4);
else if (g_input->KeyDown(KeyCode::KP_5))
SetDebugView3D((DebugView3D)5);
else if (g_input->KeyDown(KeyCode::KP_6))
SetDebugView3D((DebugView3D)6);
else if (g_input->KeyDown(KeyCode::KP_7))
SetDebugView3D((DebugView3D)7);
else if (g_input->KeyDown(KeyCode::KP_8))
SetDebugView3D((DebugView3D)8);
else if (g_input->KeyDown(KeyCode::KP_9))
SetDebugView3D((DebugView3D)9);
}
else if (ctrl)
{
if (g_input->KeyDown(KeyCode::KP_0))
SetDebugView3D((DebugView3D)10);
else if (g_input->KeyDown(KeyCode::KP_1))
SetDebugView3D((DebugView3D)11);
else if (g_input->KeyDown(KeyCode::KP_2))
SetDebugView3D((DebugView3D)12);
else if (g_input->KeyDown(KeyCode::KP_3))
SetDebugView3D((DebugView3D)13);
else if (g_input->KeyDown(KeyCode::KP_4))
SetDebugView3D((DebugView3D)14);
else if (g_input->KeyDown(KeyCode::KP_5))
SetDebugView3D((DebugView3D)15);
else if (g_input->KeyDown(KeyCode::KP_6))
SetDebugView3D((DebugView3D)16);
else if (g_input->KeyDown(KeyCode::KP_7))
SetDebugView3D((DebugView3D)17);
else if (g_input->KeyDown(KeyCode::KP_8))
SetDebugView3D((DebugView3D)18);
else if (g_input->KeyDown(KeyCode::KP_9))
SetDebugView3D((DebugView3D)19);
}
else if (alt)
{
if (g_input->KeyDown(KeyCode::KP_0))
SetDebugView3D((DebugView3D)20);
else if (g_input->KeyDown(KeyCode::KP_1))
SetDebugView3D((DebugView3D)21);
else if (g_input->KeyDown(KeyCode::KP_2))
SetDebugView3D((DebugView3D)22);
else if (g_input->KeyDown(KeyCode::KP_3))
SetDebugView3D((DebugView3D)23);
else if (g_input->KeyDown(KeyCode::KP_4))
SetDebugView3D((DebugView3D)24);
else if (g_input->KeyDown(KeyCode::KP_5))
SetDebugView3D((DebugView3D)25);
else if (g_input->KeyDown(KeyCode::KP_6))
SetDebugView3D((DebugView3D)26);
else if (g_input->KeyDown(KeyCode::KP_7))
SetDebugView3D((DebugView3D)27);
else if (g_input->KeyDown(KeyCode::KP_8))
SetDebugView3D((DebugView3D)28);
else if (g_input->KeyDown(KeyCode::KP_9))
SetDebugView3D((DebugView3D)29);
}
}
gcSprite Factory::CreateSpriteDefault(const Color& col /*= ColorDef::WHITE*/)
+3 -2
View File
@@ -175,8 +175,9 @@ public:
Camera* GetCamera();
//! 设置调试绘图(3d)
void SetDebugViewTexture(int texture);
void SetDebugViewPbr(int pbr);
void SetDebugView3D(DebugView3D type);
void UpdateDebugView();
//-----------------------------Sprite------------------------------
/**
* @brief 创建默认精灵
+1 -1
View File
@@ -267,8 +267,8 @@ struct alignas(16) UbPass
float _prefilteredCubeMipLevels; // 预过滤的立方体贴图级数
float _scaleIBLAmbient; // ibl环境光系数
std::array<Position4, 9> _sh; // 球谐函数系数(环境光漫反射)
Position4 _cascadeSplits;
float _debugView;
float _debugPbr;
std::array<Light, 16> _light;
};
+123 -39
View File
@@ -14,6 +14,14 @@ namespace dl
{
VK* g_vk = nullptr;
constexpr uint32_t BINDING_INDEX_UBO = 0;
constexpr uint32_t BINDING_INDEX_MATERIAL = 1;
constexpr uint32_t BINDING_INDEX_PASS = 2;
constexpr uint32_t BINDING_INDEX_CASCADE = 3;
constexpr uint32_t BINDING_INDEX_IBL = 4;
constexpr uint32_t BINDING_INDEX_BRDF = 5;
constexpr uint32_t BINDING_INDEX_SHADOW = 6;
void VK::_init(GLFWwindow* window)
{
_curPushConstant = 0;
@@ -856,7 +864,7 @@ void VK::_create_graphics_pipeline()
return;
}
//深度模板状态
// 深度模板状态
VkPipelineDepthStencilStateCreateInfo depthStencil{};
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencil.depthTestEnable = VK_TRUE;
@@ -869,7 +877,7 @@ void VK::_create_graphics_pipeline()
depthStencil.front = {}; // Optional
depthStencil.back = {}; // Optional
//图形管线
// 图形管线
VkGraphicsPipelineCreateInfo pipelineInfo{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = 2;
@@ -1379,7 +1387,7 @@ void VK::_create_descriptor_set_layout_shadow()
std::array<VkWriteDescriptorSet, 1> descriptorWrites{};
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = _shadow._descriptorSets[i];
descriptorWrites[0].dstBinding = 0;
descriptorWrites[0].dstBinding = BINDING_INDEX_UBO;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrites[0].descriptorCount = 1;
@@ -2234,7 +2242,7 @@ void VK::CopyBufferToImageMulti(
void VK::CreateImage(uint32_t w, uint32_t h, uint32_t mip_level, VkSampleCountFlagBits numSamples,
VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage,
VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory)
VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory, uint32_t layers)
{
VkImageCreateInfo imageInfo{};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@@ -2243,7 +2251,7 @@ void VK::CreateImage(uint32_t w, uint32_t h, uint32_t mip_level, VkSampleCountFl
imageInfo.extent.height = h;
imageInfo.extent.depth = 1;
imageInfo.mipLevels = mip_level;
imageInfo.arrayLayers = 1;
imageInfo.arrayLayers = layers;
imageInfo.format = format;
imageInfo.tiling = tiling;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -2274,6 +2282,7 @@ void VK::CreateImage(uint32_t w, uint32_t h, uint32_t mip_level, VkSampleCountFl
vkBindImageMemory(_device, image, imageMemory, 0);
}
size_t VK::CreateTextureReal(Image* image, bool srgb, bool delete_image)
{
assert(image);
@@ -2518,43 +2527,57 @@ void VK::_create_descriptor_set_layout()
{
// ubo
VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = 0;
uboLayoutBinding.binding = BINDING_INDEX_UBO;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
uboLayoutBinding.pImmutableSamplers = nullptr; // Optional
// ubo material
VkDescriptorSetLayoutBinding uboLayoutBinding1{};
uboLayoutBinding1.binding = 1;
uboLayoutBinding1.binding = BINDING_INDEX_MATERIAL;
uboLayoutBinding1.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding1.descriptorCount = 1;
uboLayoutBinding1.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;//像素着色器可见
uboLayoutBinding1.pImmutableSamplers = nullptr; // Optional
// ubo pass
VkDescriptorSetLayoutBinding uboLayoutBinding2{};
uboLayoutBinding2.binding = 2;
uboLayoutBinding2.binding = BINDING_INDEX_PASS;
uboLayoutBinding2.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding2.descriptorCount = 1;
uboLayoutBinding2.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;//像素着色器可见
uboLayoutBinding2.pImmutableSamplers = nullptr; // Optional
// ubo cascade
VkDescriptorSetLayoutBinding uboLayoutBinding3{};
uboLayoutBinding3.binding = BINDING_INDEX_CASCADE;
uboLayoutBinding3.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding3.descriptorCount = 1;
uboLayoutBinding3.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;//像素着色器可见
uboLayoutBinding3.pImmutableSamplers = nullptr; // Optional
// ibl贴图
VkDescriptorSetLayoutBinding texLayoutBinding3{};
texLayoutBinding3.binding = 3;
texLayoutBinding3.descriptorCount = 1;
texLayoutBinding3.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
texLayoutBinding3.pImmutableSamplers = nullptr;
texLayoutBinding3.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
VkDescriptorSetLayoutBinding texLayoutBinding{};
texLayoutBinding.binding = BINDING_INDEX_IBL;
texLayoutBinding.descriptorCount = 1;
texLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
texLayoutBinding.pImmutableSamplers = nullptr;
texLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
// brdf贴图
VkDescriptorSetLayoutBinding texLayoutBinding4{};
texLayoutBinding4.binding = 4;
texLayoutBinding4.descriptorCount = 1;
texLayoutBinding4.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
texLayoutBinding4.pImmutableSamplers = nullptr;
texLayoutBinding4.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
VkDescriptorSetLayoutBinding texLayoutBinding1{};
texLayoutBinding1.binding = BINDING_INDEX_BRDF;
texLayoutBinding1.descriptorCount = 1;
texLayoutBinding1.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
texLayoutBinding1.pImmutableSamplers = nullptr;
texLayoutBinding1.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
// 阴影贴图
VkDescriptorSetLayoutBinding texLayoutBinding2{};
texLayoutBinding2.binding = BINDING_INDEX_SHADOW;
texLayoutBinding2.descriptorCount = 1;
texLayoutBinding2.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
texLayoutBinding2.pImmutableSamplers = nullptr;
texLayoutBinding2.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
std::array<VkDescriptorSetLayoutBinding, 5> bindings = {
uboLayoutBinding, uboLayoutBinding1, uboLayoutBinding2,
texLayoutBinding3, texLayoutBinding4
std::array<VkDescriptorSetLayoutBinding, 7> bindings = {
uboLayoutBinding, uboLayoutBinding1, uboLayoutBinding2, uboLayoutBinding3,
texLayoutBinding, texLayoutBinding1, texLayoutBinding2
};
VkDescriptorSetLayoutCreateInfo layoutInfo{};
@@ -2745,7 +2768,6 @@ void VK::_create_uniform_buffers()
_pass._scaleIBLAmbient = 1.0f;
_pass._sh = {};
_pass._debugView = 0;
_pass._debugPbr = 0;
}
void VK::_create_uniform_bone()
@@ -2879,7 +2901,7 @@ void VK::_create_ibl()
std::array<VkWriteDescriptorSet, 1> descriptorWrites{};
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = _descriptorSets[i];
descriptorWrites[0].dstBinding = 4;
descriptorWrites[0].dstBinding = BINDING_INDEX_BRDF;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[0].descriptorCount = 1;
@@ -3611,7 +3633,7 @@ size_t VK::CreatePrimitive(ModelMaterial& m)
std::array<VkWriteDescriptorSet, 3> descriptorWrites{};
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = _descriptorSets[index];
descriptorWrites[0].dstBinding = 0;
descriptorWrites[0].dstBinding = BINDING_INDEX_UBO;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrites[0].descriptorCount = 1;
@@ -3619,7 +3641,7 @@ size_t VK::CreatePrimitive(ModelMaterial& m)
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[1].dstSet = _descriptorSets[index];
descriptorWrites[1].dstBinding = 1;
descriptorWrites[1].dstBinding = BINDING_INDEX_MATERIAL;
descriptorWrites[1].dstArrayElement = 0;
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrites[1].descriptorCount = 1;
@@ -3627,7 +3649,7 @@ size_t VK::CreatePrimitive(ModelMaterial& m)
descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[2].dstSet = _descriptorSets[index];
descriptorWrites[2].dstBinding = 2;
descriptorWrites[2].dstBinding = BINDING_INDEX_PASS;
descriptorWrites[2].dstArrayElement = 0;
descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrites[2].descriptorCount = 1;
@@ -4773,28 +4795,90 @@ void VK::_create_shadow()
_shadow._cascade.resize(NUM_SHADOW_CASCADE);
Texture& tex = _shadow._tex;
CreateImage(SIZE_SHADOW_IMAGE, SIZE_SHADOW_IMAGE, 1,
VK_SAMPLE_COUNT_1_BIT, FORMAT_SHADOW_IMAGE, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, // 深度附件,着色器采样
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, tex._image, tex._memory, NUM_SHADOW_CASCADE);
// 整个View
{
VkImageViewCreateInfo viewInfo{};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = tex._image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
viewInfo.format = FORMAT_SHADOW_IMAGE;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = NUM_SHADOW_CASCADE;
if (vkCreateImageView(_device, &viewInfo, nullptr, &tex._imageView) != VK_SUCCESS)
{
log_err0("创建图像视图失败!");
return;
}
}
for (size_t i = 0; i < NUM_SHADOW_CASCADE; ++i)
{
Texture& tex = _shadow._cascade[i]._tex;
CreateImage(SIZE_SHADOW_IMAGE, SIZE_SHADOW_IMAGE, 1,
VK_SAMPLE_COUNT_1_BIT, FORMAT_SHADOW_IMAGE, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, // 深度附件,着色器采样
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, tex._image, tex._memory);
tex._imageView = CreateImageView(tex._image, FORMAT_SHADOW_IMAGE, VK_IMAGE_ASPECT_DEPTH_BIT, 1);
// 切片View
VkImageViewCreateInfo viewInfo{};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = tex._image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
viewInfo.format = FORMAT_SHADOW_IMAGE;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = (uint32_t)i;
viewInfo.subresourceRange.layerCount = 1;
if (vkCreateImageView(_device, &viewInfo, nullptr, &_shadow._cascade[i]._imageView) != VK_SUCCESS)
{
log_err0("创建图像视图1失败!");
return;
}
// 帧缓冲
VkFramebufferCreateInfo fbCI{};
fbCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
fbCI.renderPass = _shadow._renderPass;
fbCI.attachmentCount = 1;
// 只绑定一个深度附件
fbCI.pAttachments = &tex._imageView;
fbCI.pAttachments = &_shadow._cascade[i]._imageView;
fbCI.width = SIZE_SHADOW_IMAGE;
fbCI.height = SIZE_SHADOW_IMAGE;
fbCI.layers = 1;
vkCreateFramebuffer(_device, &fbCI, nullptr, &_shadow._cascade[i]._frameBuffer);
}
// 更新描述符
{
// shadow
VkDescriptorImageInfo imageInfo{};
imageInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
imageInfo.imageView = _shadow._tex._imageView;
imageInfo.sampler = _skybox._brdfSampler;// todo
for (size_t i = 0; i < _descriptorSets.size(); ++i)
{
std::array<VkWriteDescriptorSet, 1> descriptorWrites{};
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = _descriptorSets[i];
descriptorWrites[0].dstBinding = BINDING_INDEX_SHADOW;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[0].descriptorCount = 1;
descriptorWrites[0].pImageInfo = &imageInfo;
vkUpdateDescriptorSets(_device,
(uint32_t)descriptorWrites.size(), descriptorWrites.data(),
0, nullptr);
}
}
}
void VK::_delete_shadow()
@@ -4802,9 +4886,9 @@ void VK::_delete_shadow()
for (auto& iter : _shadow._cascade)
{
vkDestroyFramebuffer(_device, iter._frameBuffer, nullptr);
iter._tex.Delete(_device);
vkDestroyImageView(_device, iter._imageView, nullptr);
}
_shadow._tex.Delete(_device);
for (auto& iter : _shadow._ubCsmBuffer)
vkDestroyBuffer(_device, iter, nullptr);
for (auto& iter : _shadow._ubCsmMemory)
@@ -5190,7 +5274,7 @@ void VK::LoadSkybox(std::string_view path)
std::array<VkWriteDescriptorSet, 1> descriptorWrites{};
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = _descriptorSets[i];
descriptorWrites[0].dstBinding = 3;
descriptorWrites[0].dstBinding = BINDING_INDEX_IBL;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[0].descriptorCount = 1;
+7 -11
View File
@@ -610,7 +610,7 @@ public:
*/
void CreateImage(uint32_t w, uint32_t h, uint32_t mip_level, VkSampleCountFlagBits numSamples,
VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties,
VkImage& image, VkDeviceMemory& imageMemory);
VkImage& image, VkDeviceMemory& imageMemory, uint32_t layers = 1);
/**
* @brief 创建图像视图
@@ -745,15 +745,10 @@ public:
_mapBoneUse[id] = true;
}
void SetDebugViewTexture(int texture)
void SetDebugView(DebugView3D type)
{
_pass._debugView = (float)texture;
_pass._debugView = (float)type;
}
void SetDebugViewPbr(int pbr)
{
_pass._debugPbr = (float)pbr;
}
//! 真正的创建一个纹理,失败返回0
size_t CreateTextureReal(Image* image, bool srgb, bool delete_image);
@@ -878,7 +873,7 @@ private:
std::vector<VkBuffer> _uniformBuffers; //统一缓冲
std::vector<VkDeviceMemory> _uniformBuffersMemory; //统一缓冲内存
VkDescriptorPool _descriptorPool; //描述符池
std::vector<VkDescriptorSet> _descriptorSets; // 描述符集(ubo、matrial、pass、ibl)
std::vector<VkDescriptorSet> _descriptorSets; // 描述符集(ubo、matrial、pass、cascade、ibl、brdf)
std::vector<VkDescriptorSet> _descriptorSetsTex; // 描述符集(纹理)
std::vector<VkDescriptorSet> _descriptorSetsBone; // 描述符集(带骨骼动画)
VkSampler _standardSampler; // 纹理采样器(标准)
@@ -950,11 +945,12 @@ private:
Pipeline _pipelineBone;
std::vector<VkBuffer> _ubCsmBuffer;
std::vector<VkDeviceMemory> _ubCsmMemory;
UbCSM _ubCsm;
UbCSM _ubCsm;
Texture _tex;
struct Cascade
{
Texture _tex;
VkImageView _imageView;
VkFramebuffer _frameBuffer;
};
std::vector<Cascade> _cascade;
+1 -31
View File
@@ -61,37 +61,7 @@ public:
else
g_system->SetCursorMode(System::CursorMode::NORMAL);
//
if (g_input->KeyDown(KeyCode::F1))
g_factory->SetDebugViewTexture(0);
else if (g_input->KeyDown(KeyCode::F2))
g_factory->SetDebugViewTexture(1);
else if (g_input->KeyDown(KeyCode::F3))
g_factory->SetDebugViewTexture(2);
else if (g_input->KeyDown(KeyCode::F4))
g_factory->SetDebugViewTexture(3);
else if (g_input->KeyDown(KeyCode::F5))
g_factory->SetDebugViewTexture(4);
else if (g_input->KeyDown(KeyCode::F6))
g_factory->SetDebugViewTexture(5);
else if (g_input->KeyDown(KeyCode::F7))
g_factory->SetDebugViewTexture(6);
if (g_input->KeyDown(KeyCode::KP_0))
g_factory->SetDebugViewPbr(0);
else if (g_input->KeyDown(KeyCode::KP_1))
g_factory->SetDebugViewPbr(1);
else if (g_input->KeyDown(KeyCode::KP_2))
g_factory->SetDebugViewPbr(2);
else if (g_input->KeyDown(KeyCode::KP_3))
g_factory->SetDebugViewPbr(3);
else if (g_input->KeyDown(KeyCode::KP_4))
g_factory->SetDebugViewPbr(4);
else if (g_input->KeyDown(KeyCode::KP_5))
g_factory->SetDebugViewPbr(5);
else if (g_input->KeyDown(KeyCode::KP_6))
g_factory->SetDebugViewPbr(6);
g_factory->UpdateDebugView();
Value v = _lst->GetSelectClickDouble();
if (v)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+130 -35
View File
@@ -6,6 +6,10 @@
const float M_PI = 3.141592653589793;
const float c_MinRoughness = 0.04;
layout (constant_id = 0) const int SHADOW_MAP_CASCADE_COUNT = 4;
layout (constant_id = 1) const int enablePCF = 0;
layout (set = 0, binding = 0) uniform UniformBufferObject
{
mat4 proj;
@@ -40,18 +44,25 @@ layout(set = 0, binding = 2) uniform UniformBufferPass
float prefilteredCubeMipLevels; // 预过滤的立方体贴图级数
float scaleIBLAmbient; // ibl环境光系数
vec4 sh[9]; // 球谐漫反射
vec4 cascadeSplits; // 级联分割
float debugViewInputs;
float debugViewEquation;
Light light[NUM_LIGHT];
} pass;
layout (set = 0, binding = 3) uniform UniformBufferCascade
{
mat4 viewProj[SHADOW_MAP_CASCADE_COUNT];
} cascade;
// 依赖pass
#include "include/tonemap.glsl"
// 预过滤镜面环境贴图(ibl)
layout (set = 0, binding = 3) uniform samplerCube prefilteredMap;
layout (set = 0, binding = 4) uniform samplerCube prefilteredMap;
// BRDF 积分查找表
layout (set = 0, binding = 4) uniform sampler2D samplerBRDFLUT;
layout (set = 0, binding = 5) uniform sampler2D samplerBRDFLUT;
// 阴影贴图
layout (set = 0, binding = 6) uniform sampler2DArray shadowMap;
layout(set = 1, binding = 0) uniform sampler2D diffuseMap; // 漫反射
layout(set = 1, binding = 1) uniform sampler2D physicalMap; // 物理
@@ -64,6 +75,7 @@ layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec2 inUV0;
layout (location = 3) in vec2 inUV1;
layout (location = 4) in vec4 inColor;
layout (location = 5) in vec3 inViewPos;
layout(location = 0) out vec4 outColor;
@@ -209,6 +221,55 @@ vec3 getIBLContribution(PbrInfo pbrInputs, vec3 n, vec3 reflection)
return diffuse + specular;
}
// 阴影偏移
const mat4 biasMat = mat4(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.0
);
#define ambient 0.3
float textureProj(vec4 shadowCoord, vec2 offset, uint cascadeIndex)
{
float shadow = 1.0;
float bias = 0.005;
if ( shadowCoord.z > -1.0 && shadowCoord.z < 1.0 )
{
float dist = texture(shadowMap, vec3(shadowCoord.st + offset, cascadeIndex)).r;
if (shadowCoord.w > 0 && dist < shadowCoord.z - bias)
{
shadow = ambient;
}
}
return shadow;
}
// 百分比渐进过滤
float filterPCF(vec4 sc, uint cascadeIndex)
{
ivec2 texDim = textureSize(shadowMap, 0).xy;
float scale = 0.75;
float dx = scale * 1.0 / float(texDim.x);
float dy = scale * 1.0 / float(texDim.y);
float shadowFactor = 0.0;
int count = 0;
int range = 1;
for (int x = -range; x <= range; x++)
{
for (int y = -range; y <= range; y++)
{
shadowFactor += textureProj(sc, vec2(dx*x, dy*y), cascadeIndex);
count++;
}
}
return shadowFactor / count;
}
void main()
{
float perceptualRoughness;
@@ -340,6 +401,34 @@ void main()
vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
// 最终光照 = 漫反射 + 高光,受法线与灯光夹角影响
vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib);
//----------------------------------阴影计算
// 返回所在级联
uint cascadeIndex = 0;
for(uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; ++i)
{
if(inViewPos.z < pass.cascadeSplits[i])
{
cascadeIndex = i + 1;
}
}
// 所在贴图位置
vec4 shadowCoord = (biasMat * cascade.viewProj[cascadeIndex]) * vec4(inPosition, 1.0);
float shadow = 0;
if (enablePCF == 1)
{
shadow = filterPCF(shadowCoord / shadowCoord.w, cascadeIndex);
}
else
{
shadow = textureProj(shadowCoord / shadowCoord.w, vec2(0.0), cascadeIndex);
}
// 只影响直射光
color *= shadow;
// 计算ibl光照
color += getIBLContribution(pbrInputs, n, reflection);
@@ -385,42 +474,48 @@ void main()
case 6: // 粗糙度
outColor.rgb = texture(physicalMap, inUV0).ggg;
break;
}
outColor = SRGBtoLINEAR(outColor);
}
// PBR 光照方程 调试可视化
// 可选显示内容:
// "none" 关闭调试(显示最终颜色)
// "Diff (l,n)" 只显示漫反射项
// "F (l,h)" 只显示菲涅尔项
// "G (l,v,h)" 只显示几何遮蔽项
// "D (h)" 只显示微表面分布项
// "Specular" 只显示高光项
// "reflection" 反射向量
if (pass.debugViewEquation > 0.0)
{
int index = int(pass.debugViewEquation);
switch (index)
{
case 1:
outColor.rgb = diffuseContrib;
// PBR 光照方程 调试可视化
case 10:
outColor.rgb = diffuseContrib; // 漫反射
break;
case 2:
outColor.rgb = F;
case 11:
outColor.rgb = F; // 菲涅尔
break;
case 3:
outColor.rgb = vec3(G);
case 12:
outColor.rgb = vec3(G); // 几何遮蔽
break;
case 4:
outColor.rgb = vec3(D);
case 13:
outColor.rgb = vec3(D); // 微表面分布
break;
case 5:
outColor.rgb = specContrib;
case 14:
outColor.rgb = specContrib; // 高光
break;
case 6:// 点 -> 光
outColor.rgb = reflection;
break;
}
case 15:// 点 -> 光
outColor.rgb = reflection; // 反射向量
break;
// 级联阴影
case 20:
{
switch(cascadeIndex)
{
case 0 :
outColor.rgb *= vec3(1.0f, 0.25f, 0.25f);
break;
case 1 :
outColor.rgb *= vec3(0.25f, 1.0f, 0.25f);
break;
case 2 :
outColor.rgb *= vec3(0.25f, 0.25f, 1.0f);
break;
case 3 :
outColor.rgb *= vec3(1.0f, 1.0f, 0.25f);
break;
}
}
break;
case 21:
outColor.rgb = vec3(shadow); // 阴影贴图
break;
}
}
}
+6 -3
View File
@@ -45,6 +45,7 @@ layout (location = 1) out vec3 outNormal;
layout (location = 2) out vec2 outUV0;
layout (location = 3) out vec2 outUV1;
layout (location = 4) out vec4 outColor;
layout (location = 5) out vec3 outViewPos;
void main()
{
@@ -70,15 +71,17 @@ void main()
vec3 posL = inPosition;
vec3 normalL = inNormal;
#endif
vec3 worldPos = (constant.model * vec4(posL, 1.0)).xyz;
vec4 worldPos = constant.model * vec4(posL, 1.0);
mat3 normalMat = transpose(inverse(mat3(constant.model)));
vec3 worldNormal = normalize(normalMat * normalL);
vec4 viewPos = ubo.view * worldPos; // 相机空间位置
outPosition = worldPos;
outPosition = worldPos.xyz;
outNormal = worldNormal;
outUV0 = inUV0;
outUV1 = inUV1;
outColor = inColor * constant.color;
outViewPos = viewPos.xyz;
gl_Position = ubo.proj * ubo.view * vec4(worldPos, 1.0);
gl_Position = ubo.proj * ubo.view * worldPos;
}