diff --git a/dl/base/dl_type_user.h b/dl/base/dl_type_user.h index 80ae1a98..67fd9a34 100644 --- a/dl/base/dl_type_user.h +++ b/dl/base/dl_type_user.h @@ -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 { diff --git a/dl/dl_type.h b/dl/dl_type.h index 8252d8e1..59760bd6 100644 --- a/dl/dl_type.h +++ b/dl/dl_type.h @@ -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" diff --git a/dl/render/dl_factory.cpp b/dl/render/dl_factory.cpp index 2bd62cf9..e1f7e4cc 100644 --- a/dl/render/dl_factory.cpp +++ b/dl/render/dl_factory.cpp @@ -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*/) diff --git a/dl/render/dl_factory.h b/dl/render/dl_factory.h index af222694..d222dad4 100644 --- a/dl/render/dl_factory.h +++ b/dl/render/dl_factory.h @@ -175,8 +175,9 @@ public: Camera* GetCamera(); //! 设置调试绘图(3d) - void SetDebugViewTexture(int texture); - void SetDebugViewPbr(int pbr); + void SetDebugView3D(DebugView3D type); + + void UpdateDebugView(); //-----------------------------Sprite------------------------------ /** * @brief 创建默认精灵 diff --git a/dl/vk/dl_vertex.h b/dl/vk/dl_vertex.h index 96af3e91..55dadba6 100644 --- a/dl/vk/dl_vertex.h +++ b/dl/vk/dl_vertex.h @@ -267,8 +267,8 @@ struct alignas(16) UbPass float _prefilteredCubeMipLevels; // 预过滤的立方体贴图级数 float _scaleIBLAmbient; // ibl环境光系数 std::array _sh; // 球谐函数系数(环境光漫反射) + Position4 _cascadeSplits; float _debugView; - float _debugPbr; std::array _light; }; diff --git a/dl/vk/dl_vk.cpp b/dl/vk/dl_vk.cpp index a4e447a1..b2405d88 100644 --- a/dl/vk/dl_vk.cpp +++ b/dl/vk/dl_vk.cpp @@ -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 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 bindings = { - uboLayoutBinding, uboLayoutBinding1, uboLayoutBinding2, - texLayoutBinding3, texLayoutBinding4 + std::array 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 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 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 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 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; diff --git a/dl/vk/dl_vk.h b/dl/vk/dl_vk.h index 8b1777c1..d50aa6b4 100644 --- a/dl/vk/dl_vk.h +++ b/dl/vk/dl_vk.h @@ -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 _uniformBuffers; //统一缓冲 std::vector _uniformBuffersMemory; //统一缓冲内存 VkDescriptorPool _descriptorPool; //描述符池 - std::vector _descriptorSets; // 描述符集(ubo、matrial、pass、ibl) + std::vector _descriptorSets; // 描述符集(ubo、matrial、pass、cascade、ibl、brdf) std::vector _descriptorSetsTex; // 描述符集(纹理) std::vector _descriptorSetsBone; // 描述符集(带骨骼动画) VkSampler _standardSampler; // 纹理采样器(标准) @@ -950,11 +945,12 @@ private: Pipeline _pipelineBone; std::vector _ubCsmBuffer; std::vector _ubCsmMemory; - UbCSM _ubCsm; + UbCSM _ubCsm; + Texture _tex; struct Cascade { - Texture _tex; + VkImageView _imageView; VkFramebuffer _frameBuffer; }; std::vector _cascade; diff --git a/project/dl_test/ui_actor.h b/project/dl_test/ui_actor.h index f950de2d..b75d47d8 100644 --- a/project/dl_test/ui_actor.h +++ b/project/dl_test/ui_actor.h @@ -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) diff --git a/res/dl/shader/3d_bone_frag.spv b/res/dl/shader/3d_bone_frag.spv index 98333bca..d4f7ad34 100644 Binary files a/res/dl/shader/3d_bone_frag.spv and b/res/dl/shader/3d_bone_frag.spv differ diff --git a/res/dl/shader/3d_bone_vert.spv b/res/dl/shader/3d_bone_vert.spv index 560c2042..bc54b61c 100644 Binary files a/res/dl/shader/3d_bone_vert.spv and b/res/dl/shader/3d_bone_vert.spv differ diff --git a/res/dl/shader/3d_frag.spv b/res/dl/shader/3d_frag.spv index 98333bca..d4f7ad34 100644 Binary files a/res/dl/shader/3d_frag.spv and b/res/dl/shader/3d_frag.spv differ diff --git a/res/dl/shader/3d_vert.spv b/res/dl/shader/3d_vert.spv index b8bb95cc..646bad0c 100644 Binary files a/res/dl/shader/3d_vert.spv and b/res/dl/shader/3d_vert.spv differ diff --git a/shader/3d.frag b/shader/3d.frag index c5ece1fe..75cb2ce1 100644 --- a/shader/3d.frag +++ b/shader/3d.frag @@ -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; + } } } diff --git a/shader/3d.vert b/shader/3d.vert index e947c914..bd1ef874 100644 --- a/shader/3d.vert +++ b/shader/3d.vert @@ -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; }