From efd2d33dd28ef21bd0d57711ba9d476df572878c Mon Sep 17 00:00:00 2001 From: Hinageshi <69386319+Hinageshi01@users.noreply.github.com> Date: Tue, 24 Oct 2023 20:44:51 +0800 Subject: [PATCH] Shader lazy load (#382) --- .gitignore | 10 +- Engine/BuiltInShaders/atm/varying.def.sc | 21 - Engine/BuiltInShaders/common/Envirnoment.sh | 2 +- .../{atm => common}/atm_definitions.sh | 0 .../{atm => common}/atm_functions.sh | 0 .../cs_ComputeDirectIrradiance.sc | 2 +- .../cs_ComputeIndirectIrradiance.sc | 2 +- .../cs_ComputeMultipleScattering.sc | 2 +- .../cs_ComputeScatteringDensity.sc | 2 +- .../cs_ComputeSingleScattering.sc | 2 +- .../cs_ComputeTransmittance.sc | 2 +- ...fs_PrecomputedAtmosphericScattering_LUT.sc | 2 +- .../fs_SingleScattering_RayMarching.sc | 0 .../{atm => shaders}/vs_atmSkyBox.sc | 0 Engine/EditorResources/Text.csv | 4 +- .../Source/Editor/ECWorld/ECWorldConsumer.cpp | 148 ++---- .../Source/Editor/ECWorld/ECWorldConsumer.h | 1 + Engine/Source/Editor/EditorApp.cpp | 118 +++-- Engine/Source/Editor/EditorApp.h | 14 +- Engine/Source/Editor/Main.cpp | 3 +- .../Editor/Resources/ResourceBuilder.cpp | 40 +- .../Source/Editor/Resources/ResourceBuilder.h | 11 +- .../Source/Editor/Resources/ShaderBuilder.cpp | 128 +++-- .../Source/Editor/Resources/ShaderBuilder.h | 17 +- .../Source/Editor/UILayers/AssetBrowser.cpp | 8 +- Engine/Source/Editor/UILayers/EntityList.cpp | 4 +- Engine/Source/Editor/UILayers/Inspector.cpp | 57 +-- Engine/Source/Editor/UILayers/MainMenu.cpp | 14 +- .../Source/Runtime/Application/IApplication.h | 1 + .../Runtime/ECWorld/AllComponentsHeader.h | 1 - .../Runtime/ECWorld/MaterialComponent.cpp | 78 ++- .../Runtime/ECWorld/MaterialComponent.h | 21 +- Engine/Source/Runtime/ECWorld/SceneWorld.cpp | 11 +- Engine/Source/Runtime/ECWorld/SceneWorld.h | 7 - .../ShaderVariantCollectionsComponent.cpp | 8 - .../ShaderVariantCollectionsComponent.h | 29 -- .../Source/Runtime/ECWorld/SkyComponent.cpp | 13 +- Engine/Source/Runtime/ECWorld/SkyComponent.h | 19 +- .../Source/Runtime/ECWorld/TerrainComponent.h | 16 +- .../Source/Runtime/ImGui/ImGuiBaseLayer.cpp | 1 + .../Source/Runtime/Material/MaterialType.cpp | 6 - Engine/Source/Runtime/Material/MaterialType.h | 4 - .../Source/Runtime/Material/ShaderSchema.cpp | 116 +---- Engine/Source/Runtime/Material/ShaderSchema.h | 66 +-- Engine/Source/Runtime/Path/Path.cpp | 16 +- Engine/Source/Runtime/Path/Path.h | 10 +- .../Source/Runtime/Rendering/AABBRenderer.cpp | 14 +- .../Source/Runtime/Rendering/AABBRenderer.h | 1 + .../Runtime/Rendering/AnimationRenderer.cpp | 19 +- .../Runtime/Rendering/AnimationRenderer.h | 1 + .../Runtime/Rendering/BlendShapeRenderer.cpp | 53 +- .../Runtime/Rendering/BlendShapeRenderer.h | 1 + .../Rendering/BlitRenderTargetPass.cpp | 6 +- .../Runtime/Rendering/BlitRenderTargetPass.h | 1 + .../Runtime/Rendering/BloomRenderer.cpp | 483 ++++++++++-------- .../Source/Runtime/Rendering/BloomRenderer.h | 18 +- .../Runtime/Rendering/ImGuiRenderer.cpp | 20 +- .../Source/Runtime/Rendering/ImGuiRenderer.h | 2 +- .../Runtime/Rendering/PBRSkyRenderer.cpp | 68 ++- .../Source/Runtime/Rendering/PBRSkyRenderer.h | 1 + .../Runtime/Rendering/ParticleRenderer.cpp | 7 +- .../Runtime/Rendering/ParticleRenderer.h | 1 + .../Runtime/Rendering/PostProcessRenderer.cpp | 23 +- .../Runtime/Rendering/PostProcessRenderer.h | 2 +- .../Runtime/Rendering/RenderContext.cpp | 362 +++++++++---- .../Source/Runtime/Rendering/RenderContext.h | 73 ++- Engine/Source/Runtime/Rendering/Renderer.cpp | 5 +- Engine/Source/Runtime/Rendering/Renderer.h | 3 + .../Runtime/Rendering/ShaderCollections.cpp | 68 +++ .../Runtime/Rendering/ShaderCollections.h | 57 +++ .../Runtime/Rendering/ShaderCompileInfo.h | 31 ++ .../Source/Runtime/Rendering/ShaderFeature.h | 53 ++ Engine/Source/Runtime/Rendering/ShaderType.h | 38 ++ .../Runtime/Rendering/SkeletonRenderer.cpp | 15 +- .../Runtime/Rendering/SkeletonRenderer.h | 1 + Engine/Source/Runtime/Rendering/SkyType.h | 30 ++ .../Runtime/Rendering/SkyboxRenderer.cpp | 19 +- .../Source/Runtime/Rendering/SkyboxRenderer.h | 1 + .../Runtime/Rendering/TerrainRenderer.cpp | 23 +- .../Runtime/Rendering/TerrainRenderer.h | 1 + .../Runtime/Rendering/WhiteModelRenderer.cpp | 14 +- .../Runtime/Rendering/WhiteModelRenderer.h | 1 + .../Runtime/Rendering/WireframeRenderer.cpp | 16 +- .../Runtime/Rendering/WireframeRenderer.h | 1 + .../Runtime/Rendering/WorldRenderer.cpp | 18 +- .../Source/Runtime/Rendering/WorldRenderer.h | 1 + .../Source/Runtime/Resources/ShaderLoader.cpp | 46 -- .../Source/Runtime/Resources/ShaderLoader.h | 17 - .../BuiltInShaders/Direct3D11/fs_imgui.bin | Bin 0 -> 434 bytes .../BuiltInShaders/Direct3D11/vs_imgui.bin | Bin 0 -> 621 bytes 90 files changed, 1549 insertions(+), 1103 deletions(-) delete mode 100644 Engine/BuiltInShaders/atm/varying.def.sc rename Engine/BuiltInShaders/{atm => common}/atm_definitions.sh (100%) rename Engine/BuiltInShaders/{atm => common}/atm_functions.sh (100%) rename Engine/BuiltInShaders/{atm => shaders}/cs_ComputeDirectIrradiance.sc (92%) rename Engine/BuiltInShaders/{atm => shaders}/cs_ComputeIndirectIrradiance.sc (93%) rename Engine/BuiltInShaders/{atm => shaders}/cs_ComputeMultipleScattering.sc (94%) rename Engine/BuiltInShaders/{atm => shaders}/cs_ComputeScatteringDensity.sc (91%) rename Engine/BuiltInShaders/{atm => shaders}/cs_ComputeSingleScattering.sc (94%) rename Engine/BuiltInShaders/{atm => shaders}/cs_ComputeTransmittance.sc (89%) rename Engine/BuiltInShaders/{atm => shaders}/fs_PrecomputedAtmosphericScattering_LUT.sc (94%) rename Engine/BuiltInShaders/{atm => shaders}/fs_SingleScattering_RayMarching.sc (100%) rename Engine/BuiltInShaders/{atm => shaders}/vs_atmSkyBox.sc (100%) delete mode 100644 Engine/Source/Runtime/ECWorld/ShaderVariantCollectionsComponent.cpp delete mode 100644 Engine/Source/Runtime/ECWorld/ShaderVariantCollectionsComponent.h create mode 100644 Engine/Source/Runtime/Rendering/ShaderCollections.cpp create mode 100644 Engine/Source/Runtime/Rendering/ShaderCollections.h create mode 100644 Engine/Source/Runtime/Rendering/ShaderCompileInfo.h create mode 100644 Engine/Source/Runtime/Rendering/ShaderFeature.h create mode 100644 Engine/Source/Runtime/Rendering/ShaderType.h create mode 100644 Engine/Source/Runtime/Rendering/SkyType.h delete mode 100644 Engine/Source/Runtime/Resources/ShaderLoader.cpp delete mode 100644 Engine/Source/Runtime/Resources/ShaderLoader.h create mode 100644 Projects/Shared/BuiltInShaders/Direct3D11/fs_imgui.bin create mode 100644 Projects/Shared/BuiltInShaders/Direct3D11/vs_imgui.bin diff --git a/.gitignore b/.gitignore index 72910185..88fcad05 100644 --- a/.gitignore +++ b/.gitignore @@ -9,11 +9,19 @@ Engine/ThirdPartyProjects ARM64 # tmp -Projects/Shared +Projects/Shared/* Projects/Test/* !Projects/Test/*/ Projects/Test/Textures/* !Projects/Test/Textures/*/ +# Precompiled Shader +!Projects/Shared/BuiltInShaders +Projects/Shared/BuiltInShaders/* +!Projects/Shared/BuiltInShaders/Direct3D11 +Projects/Shared/BuiltInShaders/Direct3D11/* +!Projects/Shared/BuiltInShaders/Direct3D11/vs_imgui.bin +!Projects/Shared/BuiltInShaders/Direct3D11/fs_imgui.bin + # Commercial SKD Engine/Auto/commercial_sdk_locations.bat diff --git a/Engine/BuiltInShaders/atm/varying.def.sc b/Engine/BuiltInShaders/atm/varying.def.sc deleted file mode 100644 index 1eb126e5..00000000 --- a/Engine/BuiltInShaders/atm/varying.def.sc +++ /dev/null @@ -1,21 +0,0 @@ -vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0); -vec3 v_worldPos : TEXCOORD1 = vec3(0.0, 0.0, 0.0); -vec3 v_skyboxDir : TEXCOORD2 = vec3(0.0, 0.0, 0.0); -vec3 v_bc : TEXCOORD3 = vec3(0.0, 0.0, 0.0); -vec3 v_normal : NORMAL = vec3(0.0, 0.0, 1.0); -mat3 v_TBN : TEXCOORD4; -vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0); -vec4 v_color1 : COLOR1 = vec4(1.0, 0.0, 0.0, 1.0); -flat ivec4 v_indices : BLENDINDICES = vec4(0, 0, 0, 0); -vec4 v_weight : BLENDWEIGHT = vec4(1.0, 1.0, 1.0, 1.0); -vec2 v_alphaMapTexCoord : TEXCOORD5 = vec2(0.0, 0.0); - -vec3 a_position : POSITION; -vec3 a_normal : NORMAL; -vec3 a_tangent : TANGENT; -vec3 a_bitangent : BITANGENT; -vec2 a_texcoord0 : TEXCOORD0; -vec3 a_color0 : COLOR0; -vec3 a_color1 : COLOR1; -ivec4 a_indices : BLENDINDICES; -vec4 a_weight : BLENDWEIGHT; \ No newline at end of file diff --git a/Engine/BuiltInShaders/common/Envirnoment.sh b/Engine/BuiltInShaders/common/Envirnoment.sh index 398b89b7..b6e02f6e 100644 --- a/Engine/BuiltInShaders/common/Envirnoment.sh +++ b/Engine/BuiltInShaders/common/Envirnoment.sh @@ -10,7 +10,7 @@ #if defined(ATM) -#include "../atm/atm_functions.sh" +#include "atm_functions.sh" uniform vec4 u_LightDir; uniform vec4 u_HeightOffsetAndshadowLength; diff --git a/Engine/BuiltInShaders/atm/atm_definitions.sh b/Engine/BuiltInShaders/common/atm_definitions.sh similarity index 100% rename from Engine/BuiltInShaders/atm/atm_definitions.sh rename to Engine/BuiltInShaders/common/atm_definitions.sh diff --git a/Engine/BuiltInShaders/atm/atm_functions.sh b/Engine/BuiltInShaders/common/atm_functions.sh similarity index 100% rename from Engine/BuiltInShaders/atm/atm_functions.sh rename to Engine/BuiltInShaders/common/atm_functions.sh diff --git a/Engine/BuiltInShaders/atm/cs_ComputeDirectIrradiance.sc b/Engine/BuiltInShaders/shaders/cs_ComputeDirectIrradiance.sc similarity index 92% rename from Engine/BuiltInShaders/atm/cs_ComputeDirectIrradiance.sc rename to Engine/BuiltInShaders/shaders/cs_ComputeDirectIrradiance.sc index 2ca4e6d6..75e58605 100644 --- a/Engine/BuiltInShaders/atm/cs_ComputeDirectIrradiance.sc +++ b/Engine/BuiltInShaders/shaders/cs_ComputeDirectIrradiance.sc @@ -1,7 +1,7 @@ #include "../common/bgfx_compute.sh" #define COMPUTE -#include "atm_functions.sh" +#include "../common/atm_functions.sh" IMAGE2D_WR(s_delta_irradiance, rgba32f, 0); IMAGE2D_WR(s_irradiance, rgba32f, 1); diff --git a/Engine/BuiltInShaders/atm/cs_ComputeIndirectIrradiance.sc b/Engine/BuiltInShaders/shaders/cs_ComputeIndirectIrradiance.sc similarity index 93% rename from Engine/BuiltInShaders/atm/cs_ComputeIndirectIrradiance.sc rename to Engine/BuiltInShaders/shaders/cs_ComputeIndirectIrradiance.sc index 0b98f359..aa3423d9 100644 --- a/Engine/BuiltInShaders/atm/cs_ComputeIndirectIrradiance.sc +++ b/Engine/BuiltInShaders/shaders/cs_ComputeIndirectIrradiance.sc @@ -1,7 +1,7 @@ #include "../common/bgfx_compute.sh" #define COMPUTE -#include "atm_functions.sh" +#include "../common/atm_functions.sh" uniform vec4 u_numScatteringOrders; diff --git a/Engine/BuiltInShaders/atm/cs_ComputeMultipleScattering.sc b/Engine/BuiltInShaders/shaders/cs_ComputeMultipleScattering.sc similarity index 94% rename from Engine/BuiltInShaders/atm/cs_ComputeMultipleScattering.sc rename to Engine/BuiltInShaders/shaders/cs_ComputeMultipleScattering.sc index 821347fd..8a527b07 100644 --- a/Engine/BuiltInShaders/atm/cs_ComputeMultipleScattering.sc +++ b/Engine/BuiltInShaders/shaders/cs_ComputeMultipleScattering.sc @@ -1,7 +1,7 @@ #include "../common/bgfx_compute.sh" #define COMPUTE -#include "atm_functions.sh" +#include "../common/atm_functions.sh" IMAGE3D_WR(s_delta_multiple_scattering, rgba32f, 0); IMAGE3D_RW(s_scattering, rgba32f, 1); diff --git a/Engine/BuiltInShaders/atm/cs_ComputeScatteringDensity.sc b/Engine/BuiltInShaders/shaders/cs_ComputeScatteringDensity.sc similarity index 91% rename from Engine/BuiltInShaders/atm/cs_ComputeScatteringDensity.sc rename to Engine/BuiltInShaders/shaders/cs_ComputeScatteringDensity.sc index dc04df0b..105b7ef3 100644 --- a/Engine/BuiltInShaders/atm/cs_ComputeScatteringDensity.sc +++ b/Engine/BuiltInShaders/shaders/cs_ComputeScatteringDensity.sc @@ -1,7 +1,7 @@ #include "../common/bgfx_compute.sh" #define COMPUTE -#include "atm_functions.sh" +#include "../common/atm_functions.sh" uniform vec4 u_numScatteringOrders; diff --git a/Engine/BuiltInShaders/atm/cs_ComputeSingleScattering.sc b/Engine/BuiltInShaders/shaders/cs_ComputeSingleScattering.sc similarity index 94% rename from Engine/BuiltInShaders/atm/cs_ComputeSingleScattering.sc rename to Engine/BuiltInShaders/shaders/cs_ComputeSingleScattering.sc index 3d3a5b36..18fd3003 100644 --- a/Engine/BuiltInShaders/atm/cs_ComputeSingleScattering.sc +++ b/Engine/BuiltInShaders/shaders/cs_ComputeSingleScattering.sc @@ -1,7 +1,7 @@ #include "../common/bgfx_compute.sh" #define COMPUTE -#include "atm_functions.sh" +#include "../common/atm_functions.sh" IMAGE3D_WR(s_delta_rayleigh_scattering, rgba32f, 0); IMAGE3D_WR(s_delta_mie_scattering, rgba32f, 1); diff --git a/Engine/BuiltInShaders/atm/cs_ComputeTransmittance.sc b/Engine/BuiltInShaders/shaders/cs_ComputeTransmittance.sc similarity index 89% rename from Engine/BuiltInShaders/atm/cs_ComputeTransmittance.sc rename to Engine/BuiltInShaders/shaders/cs_ComputeTransmittance.sc index 5fcc1104..9259a6b1 100644 --- a/Engine/BuiltInShaders/atm/cs_ComputeTransmittance.sc +++ b/Engine/BuiltInShaders/shaders/cs_ComputeTransmittance.sc @@ -1,7 +1,7 @@ #include "../common/bgfx_compute.sh" #define COMPUTE -#include "atm_functions.sh" +#include "../common/atm_functions.sh" IMAGE2D_WR(s_transmittance, rgba32f, 0); diff --git a/Engine/BuiltInShaders/atm/fs_PrecomputedAtmosphericScattering_LUT.sc b/Engine/BuiltInShaders/shaders/fs_PrecomputedAtmosphericScattering_LUT.sc similarity index 94% rename from Engine/BuiltInShaders/atm/fs_PrecomputedAtmosphericScattering_LUT.sc rename to Engine/BuiltInShaders/shaders/fs_PrecomputedAtmosphericScattering_LUT.sc index fcc0688d..c0a991f6 100644 --- a/Engine/BuiltInShaders/atm/fs_PrecomputedAtmosphericScattering_LUT.sc +++ b/Engine/BuiltInShaders/shaders/fs_PrecomputedAtmosphericScattering_LUT.sc @@ -2,7 +2,7 @@ $input v_worldPos #include "../common/common.sh" #include "../common/Camera.sh" -#include "atm_functions.sh" +#include "../common/atm_functions.sh" uniform vec4 u_LightDir; uniform vec4 u_HeightOffset; diff --git a/Engine/BuiltInShaders/atm/fs_SingleScattering_RayMarching.sc b/Engine/BuiltInShaders/shaders/fs_SingleScattering_RayMarching.sc similarity index 100% rename from Engine/BuiltInShaders/atm/fs_SingleScattering_RayMarching.sc rename to Engine/BuiltInShaders/shaders/fs_SingleScattering_RayMarching.sc diff --git a/Engine/BuiltInShaders/atm/vs_atmSkyBox.sc b/Engine/BuiltInShaders/shaders/vs_atmSkyBox.sc similarity index 100% rename from Engine/BuiltInShaders/atm/vs_atmSkyBox.sc rename to Engine/BuiltInShaders/shaders/vs_atmSkyBox.sc diff --git a/Engine/EditorResources/Text.csv b/Engine/EditorResources/Text.csv index 10c2b2d9..afea8250 100644 --- a/Engine/EditorResources/Text.csv +++ b/Engine/EditorResources/Text.csv @@ -10,8 +10,6 @@ TEXT_SAVE,保存,Save TEXT_SAVE_AS,另存为,Save AS TEXT_WINDOW,窗口,Window TEXT_BUILD,编译,Build -TEXT_REBUILD_NONUBER_SHADERS,重新生成着色器,Rebuild Non-Uber shaders -TEXT_REBUILD_PBR_SHADERS,重新生成PBR着色器,Rebuild PBR shaders -TEXT_REBUILD_ANIMATION_SHADERS,重新生成动画着色器,Rebuild Animation shaders +TEXT_BUILD_PBR_VARIANT,编译所有PBR着色器变体,Build All PBR Shader Variant TEXT_ABOUT,关于,About TEXT_DOCUMENTS,文档,Documents diff --git a/Engine/Source/Editor/ECWorld/ECWorldConsumer.cpp b/Engine/Source/Editor/ECWorld/ECWorldConsumer.cpp index 22c998ab..c69075dd 100644 --- a/Engine/Source/Editor/ECWorld/ECWorldConsumer.cpp +++ b/Engine/Source/Editor/ECWorld/ECWorldConsumer.cpp @@ -40,7 +40,7 @@ CD_FORCEINLINE bool IsMaterialTextureTypeValid(cd::MaterialTextureType type) } // namespace Detail ECWorldConsumer::ECWorldConsumer(engine::SceneWorld* pSceneWorld, engine::RenderContext* pRenderContext) : - m_pSceneWorld(pSceneWorld) + m_pSceneWorld(pSceneWorld), m_pRenderContext(pRenderContext) { } @@ -261,129 +261,84 @@ void ECWorldConsumer::AddMaterial(engine::Entity entity, const cd::Material* pMa std::set compiledTextureSlot; std::map outputTexturePathToData; - bool missRequiredTextures = false; - bool unknownTextureSlot = false; + engine::MaterialComponent& materialComponent = m_pSceneWorld->GetWorld()->CreateComponent(entity); + materialComponent.Init(); + materialComponent.SetMaterialType(pMaterialType); + materialComponent.SetMaterialData(pMaterial); + materialComponent.ActivateShaderFeature(engine::GetSkyTypeShaderFeature(m_pSceneWorld->GetSkyComponent(m_pSceneWorld->GetSkyEntity())->GetSkyType())); + + cd::Vec3f albedoColor(1.0f); + engine::ShaderSchema& shaderSchema = pMaterialType->GetShaderSchema(); if (pMaterial) { - for (cd::MaterialTextureType requiredTextureType : pMaterialType->GetRequiredTextureTypes()) + // Expected textures are ready to build. Add more optional texture data. + for (cd::MaterialTextureType optionalTextureType : pMaterialType->GetOptionalTextureTypes()) { - cd::TextureID textureID = pMaterial->GetTextureID(requiredTextureType); + cd::TextureID textureID = pMaterial->GetTextureID(optionalTextureType); if (!textureID.IsValid()) { - missRequiredTextures = true; - CD_ENGINE_ERROR("Material {0} massing required texture {1}!", pMaterial->GetName(), - nameof::nameof_enum(requiredTextureType)); - break; + // TODO : Its ok to have a material factor instead of texture, remove factor case warning. + CD_WARN("Material {0} does not have optional texture type {1}!", pMaterial->GetName(), + nameof::nameof_enum(optionalTextureType)); + continue; } - std::optional optTextureSlot = pMaterialType->GetTextureSlot(requiredTextureType); + std::optional optTextureSlot = pMaterialType->GetTextureSlot(optionalTextureType); if (!optTextureSlot.has_value()) { - unknownTextureSlot = true; - CD_ENGINE_ERROR("Material {0} unknown texture slot of textuere type {1}!", pMaterial->GetName(), - nameof::nameof_enum(requiredTextureType)); + CD_ERROR("Unknow texture {0} slot!", nameof::nameof_enum(optionalTextureType)); break; } + if (Detail::IsMaterialTextureTypeValid(optionalTextureType)) + { + materialComponent.ActivateShaderFeature(Detail::materialTextureTypeToShaderFeature.at(optionalTextureType)); + } + uint8_t textureSlot = optTextureSlot.value(); - const cd::Texture& requiredTexture = pSceneDatabase->GetTexture(textureID.Data()); - std::string outputTexturePath = engine::Path::GetTextureOutputFilePath(requiredTexture.GetPath(), ".dds"); + const cd::Texture& optionalTexture = pSceneDatabase->GetTexture(textureID.Data()); + std::string outputTexturePath = engine::Path::GetTextureOutputFilePath(optionalTexture.GetPath(), ".dds"); if (compiledTextureSlot.find(textureSlot) == compiledTextureSlot.end()) { - // When multiple textures have the same texture slot, it implies that these textures are packed in one file. - // For example, AO + Metalness + Roughness are packed so they have same slots which mean we only need to build it once. - // Note that these texture types can only have same setting to build texture. compiledTextureSlot.insert(textureSlot); - ResourceBuilder::Get().AddTextureBuildTask(requiredTexture.GetType(), requiredTexture.GetPath(), outputTexturePath.c_str()); - outputTexturePathToData[cd::MoveTemp(outputTexturePath)] = &requiredTexture; + ResourceBuilder::Get().AddTextureBuildTask(optionalTexture.GetType(), optionalTexture.GetPath(), outputTexturePath.c_str()); + outputTexturePathToData[cd::MoveTemp(outputTexturePath)] = &optionalTexture; } } - } - // In any bad case, we should have a material component. - engine::MaterialComponent& materialComponent = m_pSceneWorld->GetWorld()->CreateComponent(entity); - materialComponent.Init(); + if (auto optMetallic = pMaterial->GetFloatProperty(cd::MaterialPropertyGroup::Metallic, cd::MaterialProperty::Factor); optMetallic.has_value()) + { + materialComponent.SetMetallicFactor(optMetallic.value()); + } - cd::Vec3f albedoColor(1.0f); - engine::ShaderSchema& shaderSchema = pMaterialType->GetShaderSchema(); - if (missRequiredTextures || unknownTextureSlot) - { - // Give a special red color to notify. - albedoColor = cd::Vec3f(1.0f, 0.0f, 0.0f); - } - else - { - if (pMaterial) + if (auto optRoughness = pMaterial->GetFloatProperty(cd::MaterialPropertyGroup::Roughness, cd::MaterialProperty::Factor); optRoughness.has_value()) { - // Expected textures are ready to build. Add more optional texture data. - for (cd::MaterialTextureType optionalTextureType : pMaterialType->GetOptionalTextureTypes()) - { - cd::TextureID textureID = pMaterial->GetTextureID(optionalTextureType); - if (!textureID.IsValid()) - { - // TODO : Its ok to have a material factor instead of texture, remove factor case warning. - CD_WARN("Material {0} does not have optional texture type {1}!", pMaterial->GetName(), - nameof::nameof_enum(optionalTextureType)); - continue; - } - - std::optional optTextureSlot = pMaterialType->GetTextureSlot(optionalTextureType); - if (!optTextureSlot.has_value()) - { - CD_ERROR("Unknow texture {0} slot!", nameof::nameof_enum(optionalTextureType)); - break; - } - - if (Detail::IsMaterialTextureTypeValid(optionalTextureType)) - { - materialComponent.ActiveShaderFeature(Detail::materialTextureTypeToShaderFeature.at(optionalTextureType)); - } - - uint8_t textureSlot = optTextureSlot.value(); - const cd::Texture& optionalTexture = pSceneDatabase->GetTexture(textureID.Data()); - std::string outputTexturePath = engine::Path::GetTextureOutputFilePath(optionalTexture.GetPath(), ".dds"); - if (compiledTextureSlot.find(textureSlot) == compiledTextureSlot.end()) - { - compiledTextureSlot.insert(textureSlot); - ResourceBuilder::Get().AddTextureBuildTask(optionalTexture.GetType(), optionalTexture.GetPath(), outputTexturePath.c_str()); - outputTexturePathToData[cd::MoveTemp(outputTexturePath)] = &optionalTexture; - } - } + materialComponent.SetRoughnessFactor(optRoughness.value()); + } - if (auto optMetallic = pMaterial->GetFloatProperty(cd::MaterialPropertyGroup::Metallic, cd::MaterialProperty::Factor); optMetallic.has_value()) - { - materialComponent.SetMetallicFactor(optMetallic.value()); - } + if (auto optTwoSided = pMaterial->GetBoolProperty(cd::MaterialPropertyGroup::General, cd::MaterialProperty::TwoSided); optTwoSided.has_value()) + { + materialComponent.SetTwoSided(optTwoSided.value()); + } - if (auto optRoughness = pMaterial->GetFloatProperty(cd::MaterialPropertyGroup::Roughness, cd::MaterialProperty::Factor); optRoughness.has_value()) + if (auto optBlendMode = pMaterial->GetI32Property(cd::MaterialPropertyGroup::General, cd::MaterialProperty::BlendMode); optBlendMode.has_value()) + { + cd::BlendMode blendMode = static_cast(optBlendMode.value()); + if (cd::BlendMode::Mask == blendMode) { - materialComponent.SetRoughnessFactor(optRoughness.value()); - } + auto optAlphaTestValue = pMaterial->GetFloatProperty(cd::MaterialPropertyGroup::General, cd::MaterialProperty::OpacityMaskClipValue); + assert(optAlphaTestValue.has_value()); - if (auto optTwoSided = pMaterial->GetBoolProperty(cd::MaterialPropertyGroup::General, cd::MaterialProperty::TwoSided); optTwoSided.has_value()) - { - materialComponent.SetTwoSided(optTwoSided.value()); + materialComponent.SetAlphaCutOff(optAlphaTestValue.value()); } - if (auto optBlendMode = pMaterial->GetI32Property(cd::MaterialPropertyGroup::General, cd::MaterialProperty::BlendMode); optBlendMode.has_value()) - { - cd::BlendMode blendMode = static_cast(optBlendMode.value()); - if (cd::BlendMode::Mask == blendMode) - { - auto optAlphaTestValue = pMaterial->GetFloatProperty(cd::MaterialPropertyGroup::General, cd::MaterialProperty::OpacityMaskClipValue); - assert(optAlphaTestValue.has_value()); - - materialComponent.SetAlphaCutOff(optAlphaTestValue.value()); - } - - materialComponent.SetBlendMode(blendMode); - } - } - else - { - albedoColor = cd::Vec3f(0.2f); + materialComponent.SetBlendMode(blendMode); } } + else + { + albedoColor = cd::Vec3f(0.2f); + } // TODO : ResourceBuilder will move to EditorApp::Update in the future. // Now let's wait all resource build tasks done here. @@ -391,10 +346,7 @@ void ECWorldConsumer::AddMaterial(engine::Entity entity, const cd::Material* pMa // TODO : create material component before ResourceBuilder done. // Assign a special color for loading resource status. - materialComponent.SetMaterialType(pMaterialType); - materialComponent.SetMaterialData(pMaterial); materialComponent.SetAlbedoColor(cd::MoveTemp(albedoColor)); - materialComponent.SetSkyType(m_pSceneWorld->GetSkyComponent(m_pSceneWorld->GetSkyEntity())->GetSkyType()); // Textures. for (const auto& [outputTextureFilePath, pTextureData] : outputTexturePathToData) diff --git a/Engine/Source/Editor/ECWorld/ECWorldConsumer.h b/Engine/Source/Editor/ECWorld/ECWorldConsumer.h index bd0ec9a0..04878995 100644 --- a/Engine/Source/Editor/ECWorld/ECWorldConsumer.h +++ b/Engine/Source/Editor/ECWorld/ECWorldConsumer.h @@ -71,6 +71,7 @@ class ECWorldConsumer final : public cdtools::IConsumer private: engine::MaterialType* m_pDefaultMaterialType = nullptr; engine::SceneWorld* m_pSceneWorld = nullptr; + engine::RenderContext* m_pRenderContext = nullptr; uint32_t m_nodeMinID; uint32_t m_meshMinID; diff --git a/Engine/Source/Editor/EditorApp.cpp b/Engine/Source/Editor/EditorApp.cpp index bbea935c..e49ebe5e 100644 --- a/Engine/Source/Editor/EditorApp.cpp +++ b/Engine/Source/Editor/EditorApp.cpp @@ -27,13 +27,13 @@ #include "Rendering/RenderContext.h" #include "Rendering/SkeletonRenderer.h" #include "Rendering/SkyboxRenderer.h" +#include "Rendering/ShaderCollections.h" #include "Rendering/TerrainRenderer.h" #include "Rendering/WorldRenderer.h" #include "Rendering/ParticleRenderer.h" #include "Resources/FileWatcher.h" #include "Resources/ResourceBuilder.h" #include "Resources/ShaderBuilder.h" -#include "Resources/ShaderLoader.h" #include "Scene/SceneDatabase.h" #include "UILayers/AssetBrowser.h" #include "UILayers/EntityList.h" @@ -90,17 +90,21 @@ void EditorApp::Init(engine::EngineInitArgs initArgs) // Init graphics backend InitRenderContext(m_initArgs.backend, pSplashWindow->GetNativeHandle()); + pSplashWindow->OnResize.Bind(m_pRenderContext.get()); AddWindow(cd::MoveTemp(pSplashWindow)); InitEditorRenderers(); + EditorRenderersWarmup(); InitEditorImGuiContext(m_initArgs.language); InitECWorld(); m_pEditorImGuiContext->SetSceneWorld(m_pSceneWorld.get()); + InitEngineRenderers(); + // Add shader build tasks and create a thread to update tasks. - InitShaderPrograms(); + InitShaderPrograms(initArgs.compileAllShaders); m_pEditorImGuiContext->AddStaticLayer(std::make_unique("Splash")); std::thread resourceThread([]() @@ -109,7 +113,9 @@ void EditorApp::Init(engine::EngineInitArgs initArgs) }); resourceThread.detach(); + // TODO : Shader hot compile and load. m_pFileWatcher = std::make_unique(CDENGINE_BUILTIN_SHADER_PATH); + m_pFileWatcher->EnableWatchSubTree(); } void EditorApp::Shutdown() @@ -246,7 +252,6 @@ void EditorApp::InitECWorld() InitEditorCameraEntity(); InitSkyEntity(); - InitShaderVariantCollectionEntity(); #ifdef ENABLE_DDGI m_pSceneWorld->InitDDGISDK(); @@ -327,19 +332,6 @@ void EditorApp::InitSkyEntity() meshComponent.Submit(); } -void EditorApp::InitShaderVariantCollectionEntity() -{ - engine::World* pWorld = m_pSceneWorld->GetWorld(); - - engine::Entity shaderVariantCollectionEntity = pWorld->CreateEntity(); - m_pSceneWorld->SetShaderVariantCollectionEntity(shaderVariantCollectionEntity); - - auto& nameComponent = pWorld->CreateComponent(shaderVariantCollectionEntity); - nameComponent.SetName("ShaderVariantCollection"); - - auto& shaderVariantCollectionsComponent = pWorld->CreateComponent(shaderVariantCollectionEntity); -} - #ifdef ENABLE_DDGI void EditorApp::InitDDGIEntity() { @@ -355,6 +347,43 @@ void EditorApp::InitDDGIEntity() } #endif +void EditorApp::UpdateMaterials() +{ + for (engine::Entity entity : m_pSceneWorld->GetMaterialEntities()) + { + engine::MaterialComponent* pMaterialComponent = m_pSceneWorld->GetMaterialComponent(entity); + if (!pMaterialComponent) + { + continue; + } + + m_pRenderContext->CheckShaderProgram(pMaterialComponent->GetProgramName(), pMaterialComponent->GetFeaturesCombine()); + } +} + +void EditorApp::LazyCompileAndLoadShaders() +{ + bool doCompile = false; + + for (const auto& task : m_pRenderContext->GetShaderCompileTasks()) + { + ShaderBuilder::BuildShader(m_pRenderContext.get(), task); + doCompile = true; + } + + if (doCompile) + { + ResourceBuilder::Get().Update(true); + + for (auto& info : m_pRenderContext->GetShaderCompileTasks()) + { + m_pRenderContext->UploadShaderProgram(info.m_programName, info.m_featuresCombine); + } + + m_pRenderContext->ClearShaderCompileTasks(); + } +} + void EditorApp::InitRenderContext(engine::GraphicsBackend backend, void* hwnd) { CD_INFO("Init graphics backend : {}", nameof::nameof_enum(backend)); @@ -363,6 +392,9 @@ void EditorApp::InitRenderContext(engine::GraphicsBackend backend, void* hwnd) m_pRenderContext = std::make_unique(); m_pRenderContext->Init(backend, hwnd); engine::Renderer::SetRenderContext(m_pRenderContext.get()); + + m_pShaderCollections = std::make_unique(); + m_pRenderContext->SetShaderCollections(m_pShaderCollections.get()); } void EditorApp::InitEditorRenderers() @@ -461,6 +493,22 @@ void EditorApp::InitEngineRenderers() AddEngineRenderer(std::make_unique(m_pRenderContext->CreateView(), pSceneRenderTarget)); } +void EditorApp::EditorRenderersWarmup() +{ + for (std::unique_ptr& pRenderer : m_pEditorRenderers) + { + pRenderer->Warmup(); + } +} + +void EditorApp::EngineRenderersWarmup() +{ + for (std::unique_ptr& pRenderer : m_pEngineRenderers) + { + pRenderer->Warmup(); + } +} + bool EditorApp::IsAtmosphericScatteringEnable() const { engine::GraphicsBackend backend = engine::Path::GetGraphicsBackend(); @@ -470,21 +518,26 @@ bool EditorApp::IsAtmosphericScatteringEnable() const && engine::GraphicsBackend::OpenGLES != backend; } -void EditorApp::InitShaderPrograms() const +void EditorApp::InitShaderPrograms(bool compileAllShaders) const { - std::string nonUberBuildPath = CDENGINE_BUILTIN_SHADER_PATH; - ShaderBuilder::BuildNonUberShader(nonUberBuildPath + "shaders"); - if (IsAtmosphericScatteringEnable()) + ShaderBuilder::CompileRegisteredNonUberShader(m_pRenderContext.get()); + + if (compileAllShaders) { - std::string atmBuildPath = CDENGINE_BUILTIN_SHADER_PATH; - ShaderBuilder::BuildNonUberShader(atmBuildPath + "atm"); + ShaderBuilder::CompileUberShaderAllVariants(m_pRenderContext.get(), m_pSceneWorld->GetPBRMaterialType()); + +#ifdef ENABLE_DDGI + ShaderBuilder::CompileUberShaderAllVariants(m_pRenderContext.get(), m_pSceneWorld->GetDDGIMaterialType()); +#endif } + else + { + ShaderBuilder::CompileRegisteredUberShader(m_pRenderContext.get(), m_pSceneWorld->GetPBRMaterialType()); - ShaderBuilder::BuildUberShader(m_pSceneWorld->GetPBRMaterialType()); - ShaderBuilder::BuildUberShader(m_pSceneWorld->GetAnimationMaterialType()); #ifdef ENABLE_DDGI - ShaderBuilder::BuildUberShader(m_pSceneWorld->GetDDGIMaterialType()); + ShaderBuilder::CompileRegisteredUberShader(m_pRenderContext.get(), m_pSceneWorld->GetDDGIMaterialType()); #endif + } } void EditorApp::InitEditorController() @@ -516,11 +569,8 @@ bool EditorApp::Update(float deltaTime) if (!m_bInitEditor && ResourceBuilder::Get().IsIdle()) { m_bInitEditor = true; - engine::ShaderLoader::UploadUberShader(m_pSceneWorld->GetPBRMaterialType()); - engine::ShaderLoader::UploadUberShader(m_pSceneWorld->GetAnimationMaterialType()); -#ifdef ENABLE_DDGI - engine::ShaderLoader::UploadUberShader(m_pSceneWorld->GetDDGIMaterialType()); -#endif + + EngineRenderersWarmup(); // Phase 2 - Project Manager // * TODO : Show project selector @@ -539,7 +589,6 @@ bool EditorApp::Update(float deltaTime) GetMainWindow()->SetBordedLess(false); GetMainWindow()->SetResizeable(true); - InitEngineRenderers(); m_pEditorImGuiContext->ClearUILayers(); InitEditorUILayers(); @@ -550,8 +599,8 @@ bool EditorApp::Update(float deltaTime) } GetMainWindow()->Update(); - m_pSceneWorld->Update(); m_pEditorImGuiContext->Update(deltaTime); + m_pSceneWorld->Update(); engine::CameraComponent* pMainCameraComponent = m_pSceneWorld->GetCameraComponent(m_pSceneWorld->GetMainCameraEntity()); engine::TerrainComponent* pTerrainComponent = m_pSceneWorld->GetTerrainComponent(m_pSceneWorld->GetSelectedEntity()); @@ -577,7 +626,7 @@ bool EditorApp::Update(float deltaTime) { m_pViewportCameraController->Update(deltaTime); } - //Do Screen Space Smoothing + // Do Screen Space Smoothing if (pTerrainComponent && m_pSceneView->IsTerrainEditMode() && engine::Input::Get().IsMouseLBPressed()) { float screenSpaceX = 2.0f * static_cast(engine::Input::Get().GetMousePositionX() - m_pSceneView->GetWindowPosX()) / @@ -595,6 +644,9 @@ bool EditorApp::Update(float deltaTime) m_pEngineImGuiContext->SetWindowPosOffset(m_pSceneView->GetWindowPosX(), m_pSceneView->GetWindowPosY()); m_pEngineImGuiContext->Update(deltaTime); + UpdateMaterials(); + LazyCompileAndLoadShaders(); + for (std::unique_ptr& pRenderer : m_pEngineRenderers) { if (pRenderer->IsEnable()) diff --git a/Engine/Source/Editor/EditorApp.h b/Engine/Source/Editor/EditorApp.h index cb71de73..a3907f64 100644 --- a/Engine/Source/Editor/EditorApp.h +++ b/Engine/Source/Editor/EditorApp.h @@ -18,6 +18,7 @@ class Renderer; class AABBRenderer; class RenderTarget; class SceneWorld; +class ShaderCollections; } @@ -50,9 +51,14 @@ class EditorApp final : public engine::IApplication void RemoveWindow(size_t index); void InitRenderContext(engine::GraphicsBackend backend, void* hwnd = nullptr); + void InitEditorRenderers(); void InitEngineRenderers(); - void InitShaderPrograms() const; + + void EditorRenderersWarmup(); + void EngineRenderersWarmup(); + + void InitShaderPrograms(bool compileAllShaders = false) const; void AddEditorRenderer(std::unique_ptr pRenderer); void AddEngineRenderer(std::unique_ptr pRenderer); @@ -71,12 +77,14 @@ class EditorApp final : public engine::IApplication private: void InitEditorCameraEntity(); void InitSkyEntity(); - void InitShaderVariantCollectionEntity(); #ifdef ENABLE_DDGI void InitDDGIEntity(); #endif + void UpdateMaterials(); + void LazyCompileAndLoadShaders(); + bool m_bInitEditor = false; engine::EngineInitArgs m_initArgs; @@ -101,6 +109,8 @@ class EditorApp final : public engine::IApplication // Rendering std::unique_ptr m_pRenderContext; + std::unique_ptr m_pShaderCollections; + std::vector> m_pEditorRenderers; std::vector> m_pEngineRenderers; diff --git a/Engine/Source/Editor/Main.cpp b/Engine/Source/Editor/Main.cpp index 4f1838be..d463f541 100644 --- a/Engine/Source/Editor/Main.cpp +++ b/Engine/Source/Editor/Main.cpp @@ -8,7 +8,8 @@ int main() pEngine->Init({ .pTitle = "CatDogEditor", .pIconFilePath = "editor_icon.png", .width = 1280, .height = 720, .useFullScreen = false, - .language = Language::ChineseSimplied, .backend = GraphicsBackend::Direct3D11 }); + .language = Language::ChineseSimplied, + .backend = GraphicsBackend::Direct3D11, .compileAllShaders = false }); pEngine->Run(); diff --git a/Engine/Source/Editor/Resources/ResourceBuilder.cpp b/Engine/Source/Editor/Resources/ResourceBuilder.cpp index 0099406a..a7a3633b 100644 --- a/Engine/Source/Editor/Resources/ResourceBuilder.cpp +++ b/Engine/Source/Editor/Resources/ResourceBuilder.cpp @@ -13,15 +13,10 @@ namespace editor ResourceBuilder::ResourceBuilder() { std::string modifyCachePath = GetModifyCacheFilePath(); - if (std::filesystem::exists(modifyCachePath)) + if (std::filesystem::exists(cd::MoveTemp(modifyCachePath))) { ReadModifyCacheFile(); } - else - { - CD_INFO("Modify time cache {0} does not exist.", modifyCachePath); - CD_WARN("Everything will be compiled at the begining."); - } } ResourceBuilder::~ResourceBuilder() @@ -68,6 +63,7 @@ void ResourceBuilder::WriteModifyCacheFile() if (!std::filesystem::exists(modifyCachePath)) { + CD_INFO("Creating modify cache file at : {0}", modifyCachePath); std::filesystem::create_directories(std::filesystem::path(modifyCachePath).parent_path()); } @@ -83,7 +79,7 @@ void ResourceBuilder::WriteModifyCacheFile() UpdateModifyTimeCache(); outFile.clear(); - for (const auto& [filePath, timeStamp] : m_modifyTimeCache) + for (auto& [filePath, timeStamp] : m_modifyTimeCache) { outFile << filePath << "=" << timeStamp << std::endl; } @@ -105,6 +101,16 @@ std::string ResourceBuilder::GetModifyCacheFilePath() ProcessStatus ResourceBuilder::CheckFileStatus(const char* pInputFilePath, const char* pOutputFilePath) { + // Use output file path as map key to store time cache. + // + // For normal resources, the input and output files are one-to-one, + // so the output file path is sufficient to represent the input file. + // + // And for uber shader, a single source file can generate multiple output files, + // so the input file path is no longer sufficient to represent the modified state of a particular variant. + + const char* key = pOutputFilePath; + if (!std::filesystem::exists(pInputFilePath)) { CD_ERROR("Input file path {0} does not exist!", pInputFilePath); @@ -113,17 +119,17 @@ ProcessStatus ResourceBuilder::CheckFileStatus(const char* pInputFilePath, const auto crtTimeStamp = engine::Clock::FileTimePointToTimeStamp(std::filesystem::last_write_time(pInputFilePath)); - if (m_modifyTimeCache.find(pInputFilePath) == m_modifyTimeCache.end()) + if (m_modifyTimeCache.find(key) == m_modifyTimeCache.end()) { CD_INFO("New input file {0} detected.", pInputFilePath); - m_newModifyTimeCache[pInputFilePath] = crtTimeStamp; + m_newModifyTimeCache[key] = crtTimeStamp; return ProcessStatus::InputAdded; } - if (m_modifyTimeCache[pInputFilePath] != crtTimeStamp) + if (m_modifyTimeCache[key] != crtTimeStamp) { CD_INFO("Input file path {0} has been modified.", pInputFilePath); - m_newModifyTimeCache[pInputFilePath] = crtTimeStamp; + m_newModifyTimeCache[key] = crtTimeStamp; return ProcessStatus::InputModified; } @@ -150,7 +156,7 @@ bool ResourceBuilder::AddTask(Process process) return true; } -bool ResourceBuilder::AddShaderBuildTask(ShaderType shaderType, const char* pInputFilePath, const char* pOutputFilePath, const char* pShaderFeatures) +bool ResourceBuilder::AddShaderBuildTask(engine::ShaderType shaderType, const char* pInputFilePath, const char* pOutputFilePath, const char* pShaderFeatures) { if (s_SkipStatus & static_cast(CheckFileStatus(pInputFilePath, pOutputFilePath))) { @@ -183,15 +189,15 @@ bool ResourceBuilder::AddShaderBuildTask(ShaderType shaderType, const char* pInp #endif commandArguments.push_back("--type"); - if (ShaderType::Compute == shaderType) + if (engine::ShaderType::Compute == shaderType) { commandArguments.push_back("c"); } - else if (ShaderType::Fragment == shaderType) + else if (engine::ShaderType::Fragment == shaderType) { commandArguments.push_back("f"); } - else if (ShaderType::Vertex == shaderType) + else if (engine::ShaderType::Vertex == shaderType) { commandArguments.push_back("v"); } @@ -225,7 +231,7 @@ bool ResourceBuilder::AddShaderBuildTask(ShaderType shaderType, const char* pInp assert("Unknown shader compile profile."); } - if (pShaderFeatures && *pShaderFeatures != '\0') + if (std::strlen(pShaderFeatures) != 0 && std::strlen(pShaderFeatures)) { commandArguments.push_back("--define"); commandArguments.push_back(shaderLanguageDefine + ";" + pShaderFeatures); @@ -340,7 +346,7 @@ void ResourceBuilder::UpdateModifyTimeCache() { for (auto& [filePath, fileTime] : m_newModifyTimeCache) { - m_modifyTimeCache[filePath] = cd::MoveTemp(fileTime); + m_modifyTimeCache[cd::MoveTemp(filePath)] = cd::MoveTemp(fileTime); } m_newModifyTimeCache.clear(); diff --git a/Engine/Source/Editor/Resources/ResourceBuilder.h b/Engine/Source/Editor/Resources/ResourceBuilder.h index 1aaeae1d..de08ae12 100644 --- a/Engine/Source/Editor/Resources/ResourceBuilder.h +++ b/Engine/Source/Editor/Resources/ResourceBuilder.h @@ -1,6 +1,7 @@ #pragma once #include "Process/Process.h" +#include "Rendering/ShaderType.h" #include "Scene/MaterialTextureType.h" #include @@ -13,14 +14,6 @@ namespace editor { -enum class ShaderType -{ - None, - Compute, - Vertex, - Fragment -}; - enum class ProcessStatus : uint8_t { None = 1 << 0, @@ -59,7 +52,7 @@ class ResourceBuilder final bool AddTask(Process process); bool AddIrradianceCubeMapBuildTask(const char* pInputFilePath, const char* pOutputFilePath); bool AddRadianceCubeMapBuildTask(const char* pInputFilePath, const char* pOutputFilePath); - bool AddShaderBuildTask(ShaderType shaderType, const char* pInputFilePath, const char* pOutputFilePath, const char* pShaderFeatures = nullptr); + bool AddShaderBuildTask(engine::ShaderType shaderType, const char* pInputFilePath, const char* pOutputFilePath, const char* pShaderFeatures = ""); bool AddTextureBuildTask(cd::MaterialTextureType textureType, const char* pInputFilePath, const char* pOutputFilePath); void Update(bool doPrintLog = true); diff --git a/Engine/Source/Editor/Resources/ShaderBuilder.cpp b/Engine/Source/Editor/Resources/ShaderBuilder.cpp index 5c7a8c25..02cb9c65 100644 --- a/Engine/Source/Editor/Resources/ShaderBuilder.cpp +++ b/Engine/Source/Editor/Resources/ShaderBuilder.cpp @@ -1,71 +1,121 @@ #include "ShaderBuilder.h" +#include "ECWorld/SceneWorld.h" #include "Log/Log.h" #include "Path/Path.h" #include "Rendering/RenderContext.h" -#include "Resources/ResourceLoader.h" +#include "Rendering/ShaderCollections.h" namespace editor { -void ShaderBuilder::BuildUberShader(engine::MaterialType* pMaterialType) +namespace { - engine::ShaderSchema& shaderSchema = pMaterialType->GetShaderSchema(); - // No shader feature support for VS now. - std::string outputVSFilePath = engine::Path::GetShaderOutputPath(shaderSchema.GetVertexShaderPath()); - ResourceBuilder::Get().AddShaderBuildTask(ShaderType::Vertex, - shaderSchema.GetVertexShaderPath(), outputVSFilePath.c_str()); - - // Compile fragment shaders with shader features. - for (const auto& combine : shaderSchema.GetFeatureCombines()) +void CompileShaderVariants(const std::set& shaders, const std::set& combines) +{ + for (const std::string& shader : shaders) { - std::string outputFSFilePath = engine::Path::GetShaderOutputPath(shaderSchema.GetFragmentShaderPath(), combine); - ResourceBuilder::Get().AddShaderBuildTask(ShaderType::Fragment, - shaderSchema.GetFragmentShaderPath(), outputFSFilePath.c_str(), combine.c_str()); + engine::ShaderType shaderType = engine::GetShaderType(shader); + if (engine::ShaderType::Vertex == shaderType) + { + std::string inputVSFilePath = engine::Path::GetBuiltinShaderInputPath(shader.c_str()); + std::string outputVSFilePath = engine::Path::GetShaderOutputPath(shader.c_str()); + ResourceBuilder::Get().AddShaderBuildTask(engine::ShaderType::Vertex, inputVSFilePath.c_str(), outputVSFilePath.c_str()); + } + else if (engine::ShaderType::Fragment == shaderType) + { + for (const auto& combine : combines) + { + std::string inputFSFilePath = engine::Path::GetBuiltinShaderInputPath(shader.c_str()); + std::string outputFSFilePath = engine::Path::GetShaderOutputPath(shader.c_str(), combine); + ResourceBuilder::Get().AddShaderBuildTask(engine::ShaderType::Fragment, inputFSFilePath.c_str(), outputFSFilePath.c_str(), combine.c_str()); + } + } + else + { + // No shader feature support for Vertex and Compute shader. + continue; + } } +} - CD_ENGINE_INFO("Shader variant count of material type {0} : {1}", pMaterialType->GetMaterialName(), shaderSchema.GetFeatureCombines().size()); } -void ShaderBuilder::BuildNonUberShader(std::string folderPath) +void ShaderBuilder::CompileRegisteredNonUberShader(engine::RenderContext* pRenderContext) { - for (const auto& entry : std::filesystem::recursive_directory_iterator(folderPath)) + for (const auto& shaders : pRenderContext->GetShaderCollections()->GetShaderPrograms()) { - const auto& inputFilePath = entry.path(); - if (".sc" != inputFilePath.extension()) + for (const auto& shader : shaders.second) { - continue; - } + engine::ShaderType shaderType = engine::GetShaderType(shader); + if (engine::ShaderType::None == shaderType) + { + CD_WARN("Known shader type of {0} in ShaderBuilder!", shader); + continue; + } - ShaderType shaderType = GetShaderType(inputFilePath.stem().string()); - if (shaderType == ShaderType::None) - { - continue; + std::string inputShaderPath = engine::Path::GetBuiltinShaderInputPath(shader.c_str()); + std::string outputShaderPath = engine::Path::GetShaderOutputPath(shader.c_str()); + ResourceBuilder::Get().AddShaderBuildTask(shaderType, inputShaderPath.c_str(), outputShaderPath.c_str()); } - - std::string outputShaderPath = engine::Path::GetShaderOutputPath(inputFilePath.string().c_str()); - ResourceBuilder::Get().AddShaderBuildTask(shaderType, - inputFilePath.string().c_str(), outputShaderPath.c_str()); } } -const ShaderType ShaderBuilder::GetShaderType(const std::string& fileName) +void ShaderBuilder::CompileRegisteredUberShader(engine::RenderContext* pRenderContext, engine::MaterialType* pMaterialType) { - if (fileName._Starts_with("vs_") || fileName._Starts_with("VS_")) - { - return ShaderType::Vertex; - } - else if (fileName._Starts_with("fs_") || fileName._Starts_with("FS_")) + const std::string& programName = pMaterialType->GetShaderSchema().GetProgramName(); + engine::StringCrc programNameCrc = engine::StringCrc(programName); + + if (!pRenderContext->GetShaderCollections()->HasFeatureCombine(programNameCrc)) { - return ShaderType::Fragment; + return; } - else if (fileName._Starts_with("cs_") || fileName._Starts_with("CS_")) + + const std::set& shaders = pRenderContext->GetShaderCollections()->GetShaders(programNameCrc); + const std::set& combines = pRenderContext->GetShaderCollections()->GetFeatureCombines(programNameCrc); + CD_ENGINE_INFO("Compiling program {0} variant count : {1}", programName, combines.size()); + + CompileShaderVariants(shaders, combines); +} + +void ShaderBuilder::CompileUberShaderAllVariants(engine::RenderContext* pRenderContext, engine::MaterialType* pMaterialType) +{ + const std::string& programName = pMaterialType->GetShaderSchema().GetProgramName(); + + const std::set& shaders = pRenderContext->GetShaderCollections()->GetShaders(engine::StringCrc(programName)); + const std::set& combines = pMaterialType->GetShaderSchema().GetAllFeatureCombines(); + CD_ENGINE_INFO("Compiling program {0} variant count : {1}", programName, combines.size()); + + CompileShaderVariants(shaders, combines); + + ResourceBuilder::Get().Update(); +} + +void ShaderBuilder::BuildShader(engine::RenderContext* pRenderContext, const engine::ShaderCompileInfo& info) +{ + const std::set& shaders = pRenderContext->GetShaderCollections()->GetShaders(engine::StringCrc(info.m_programName)); + + for (const auto& shader : shaders) { - return ShaderType::Compute; + engine::ShaderType shaderType = engine::GetShaderType(shader); + if (engine::ShaderType::Vertex == shaderType || engine::ShaderType::Compute == shaderType) + { + std::string inputVSFilePath = engine::Path::GetBuiltinShaderInputPath(shader.c_str()); + std::string outputVSFilePath = engine::Path::GetShaderOutputPath(shader.c_str()); + ResourceBuilder::Get().AddShaderBuildTask(shaderType, inputVSFilePath.c_str(), outputVSFilePath.c_str()); + } + else if (engine::ShaderType::Fragment == shaderType) + { + std::string inputFSFilePath = engine::Path::GetBuiltinShaderInputPath(shader.c_str()); + std::string outputFSFilePath = engine::Path::GetShaderOutputPath(shader.c_str(), info.m_featuresCombine); + ResourceBuilder::Get().AddShaderBuildTask(engine::ShaderType::Fragment, inputFSFilePath.c_str(), outputFSFilePath.c_str(), info.m_featuresCombine.c_str()); + } + else + { + continue; + } } - - return ShaderType::None; } } // namespace editor diff --git a/Engine/Source/Editor/Resources/ShaderBuilder.h b/Engine/Source/Editor/Resources/ShaderBuilder.h index 25ca0249..34522229 100644 --- a/Engine/Source/Editor/Resources/ShaderBuilder.h +++ b/Engine/Source/Editor/Resources/ShaderBuilder.h @@ -2,21 +2,30 @@ #include "Material/MaterialType.h" #include "Resources/ResourceBuilder.h" +#include "Rendering/ShaderCompileInfo.h" #include #include +namespace engine +{ + +class RenderContext; + +} + namespace editor { class ShaderBuilder { public: - static void BuildNonUberShader(std::string folderPath); - static void BuildUberShader(engine::MaterialType* pMaterialType); + static void CompileRegisteredNonUberShader(engine::RenderContext* pRenderContext); + static void CompileRegisteredUberShader(engine::RenderContext* pRenderContext, engine::MaterialType* pMaterialType); + static void CompileUberShaderAllVariants(engine::RenderContext* pRenderContext, engine::MaterialType* pMaterialType); -private: - static const ShaderType GetShaderType(const std::string& fileName); + // Compile specified shader program/program variant. + static void BuildShader(engine::RenderContext* pRenderContext, const engine::ShaderCompileInfo& info); }; } // namespace editor diff --git a/Engine/Source/Editor/UILayers/AssetBrowser.cpp b/Engine/Source/Editor/UILayers/AssetBrowser.cpp index 0c17ca7e..69a51095 100644 --- a/Engine/Source/Editor/UILayers/AssetBrowser.cpp +++ b/Engine/Source/Editor/UILayers/AssetBrowser.cpp @@ -824,18 +824,18 @@ void AssetBrowser::ImportAssetFile(const char* pFilePath) std::filesystem::path inputFilePath(pFilePath); std::string inputFileName = inputFilePath.stem().generic_string(); - ShaderType shaderType; + engine::ShaderType shaderType; if (inputFileName.find("vs_") != std::string::npos) { - shaderType = ShaderType::Vertex; + shaderType = engine::ShaderType::Vertex; } else if (inputFileName.find("fs_") != std::string::npos) { - shaderType = ShaderType::Fragment; + shaderType = engine::ShaderType::Fragment; } else if (inputFileName.find("cs_") != std::string::npos) { - shaderType = ShaderType::Compute; + shaderType = engine::ShaderType::Compute; } else { diff --git a/Engine/Source/Editor/UILayers/EntityList.cpp b/Engine/Source/Editor/UILayers/EntityList.cpp index c8e49a24..8c6151c8 100644 --- a/Engine/Source/Editor/UILayers/EntityList.cpp +++ b/Engine/Source/Editor/UILayers/EntityList.cpp @@ -64,7 +64,7 @@ void EntityList::AddEntity(engine::SceneWorld* pSceneWorld) materialComponent.Init(); materialComponent.SetMaterialType(pMaterialType); materialComponent.SetAlbedoColor(cd::Vec3f(0.2f)); - materialComponent.SetSkyType(pSceneWorld->GetSkyComponent(pSceneWorld->GetSkyEntity())->GetSkyType()); + materialComponent.ActivateShaderFeature(engine::GetSkyTypeShaderFeature(pSceneWorld->GetSkyComponent(pSceneWorld->GetSkyEntity())->GetSkyType())); materialComponent.Build(); auto& transformComponent = pWorld->CreateComponent(entity); @@ -127,8 +127,8 @@ void EntityList::AddEntity(engine::SceneWorld* pSceneWorld) materialComponent.Init(); materialComponent.SetMaterialType(pTerrainMaterialType); materialComponent.SetAlbedoColor(cd::Vec3f(0.2f)); - materialComponent.SetSkyType(pSceneWorld->GetSkyComponent(pSceneWorld->GetSkyEntity())->GetSkyType()); materialComponent.SetTwoSided(true); + materialComponent.ActivateShaderFeature(engine::GetSkyTypeShaderFeature(pSceneWorld->GetSkyComponent(pSceneWorld->GetSkyEntity())->GetSkyType())); materialComponent.Build(); auto& transformComponent = pWorld->CreateComponent(entity); diff --git a/Engine/Source/Editor/UILayers/Inspector.cpp b/Engine/Source/Editor/UILayers/Inspector.cpp index 862c5ef6..64535630 100644 --- a/Engine/Source/Editor/UILayers/Inspector.cpp +++ b/Engine/Source/Editor/UILayers/Inspector.cpp @@ -318,7 +318,7 @@ void UpdateComponentWidget(engine::SceneWorld* pScene if (!activeShaderFeatures.empty()) { - if (ImGui::BeginCombo("##combo", "Active shader features")) + if (ImGui::BeginCombo("##shaderFeatureCombo", "Active shader features")) { for (size_t index = 0; index < activeShaderFeatures.size(); ++index) { @@ -577,22 +577,28 @@ void UpdateComponentWidget(engine::SceneWorld* pSceneWorld if (isOpen) { - std::vector skyTypes; - for (size_t type = 0; type < static_cast(engine::SkyType::Count); ++type) + auto currentSkyType = pSkyComponent->GetSkyType(); + if (ImGuiUtils::ImGuiEnumProperty("SkyType", currentSkyType)) { - if (!pSkyComponent->GetAtmophericScatteringEnable() && engine::SkyType::AtmosphericScattering == static_cast(type)) - { - continue; - } - skyTypes.emplace_back(nameof::nameof_enum(static_cast(type)).data()); - } + pSkyComponent->SetSkyType(currentSkyType); - if (!skyTypes.empty()) - { - auto currentSkyType = pSkyComponent->GetSkyType(); - if (ImGuiUtils::ImGuiEnumProperty("SkyType", currentSkyType)) + for (engine::Entity entity : pSceneWorld->GetMaterialEntities()) { - pSkyComponent->SetSkyType(currentSkyType); + engine::MaterialComponent* pMaterialComponent = pSceneWorld->GetMaterialComponent(entity); + if (!pMaterialComponent) + { + continue; + } + + if (engine::SkyType::None == currentSkyType) + { + pMaterialComponent->DeactiveShaderFeature(engine::GetSkyTypeShaderFeature(engine::SkyType::AtmosphericScattering)); + pMaterialComponent->DeactiveShaderFeature(engine::GetSkyTypeShaderFeature(engine::SkyType::SkyBox)); + } + else + { + pMaterialComponent->ActivateShaderFeature(engine::GetSkyTypeShaderFeature(currentSkyType)); + } } } @@ -631,28 +637,6 @@ void UpdateComponentWidget(engine::SceneWorld* pScene ImGui::PopStyleVar(); } -template<> -void UpdateComponentWidget(engine::SceneWorld* pSceneWorld, engine::Entity entity) -{ - auto* pShaderVariantCollectionsComponent = pSceneWorld->GetShaderVariantCollectionsComponent(entity); - if (!pShaderVariantCollectionsComponent) - { - return; - } - - bool isOpen = ImGui::CollapsingHeader("Shader Variant Collections Component", ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_DefaultOpen); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); - ImGui::Separator(); - - if (isOpen) - { - - } - - ImGui::Separator(); - ImGui::PopStyleVar(); -} - } namespace editor @@ -702,7 +686,6 @@ void Inspector::Update() details::UpdateComponentWidget(pSceneWorld, m_lastSelectedEntity); details::UpdateComponentWidget(pSceneWorld, m_lastSelectedEntity); details::UpdateComponentWidget(pSceneWorld, m_lastSelectedEntity); - details::UpdateComponentWidget(pSceneWorld, m_lastSelectedEntity); #ifdef ENABLE_DDGI details::UpdateComponentWidget(pSceneWorld, m_lastSelectedEntity); diff --git a/Engine/Source/Editor/UILayers/MainMenu.cpp b/Engine/Source/Editor/UILayers/MainMenu.cpp index 6a241d1a..f21c2ac2 100644 --- a/Engine/Source/Editor/UILayers/MainMenu.cpp +++ b/Engine/Source/Editor/UILayers/MainMenu.cpp @@ -222,20 +222,10 @@ void MainMenu::BuildMenu() { engine::SceneWorld* pSceneWorld = GetSceneWorld(); - if (ImGui::MenuItem(CD_TEXT("TEXT_REBUILD_NONUBER_SHADERS"))) + if (ImGui::MenuItem(CD_TEXT("TEXT_BUILD_PBR_VARIANT"))) { - std::string nonUberPath = CDENGINE_BUILTIN_SHADER_PATH; - ShaderBuilder::BuildNonUberShader(nonUberPath + "shaders"); + ShaderBuilder::CompileUberShaderAllVariants(GetRenderContext(), pSceneWorld->GetPBRMaterialType()); } - if (ImGui::MenuItem(CD_TEXT("TEXT_REBUILD_PBR_SHADERS"))) - { - ShaderBuilder::BuildUberShader(pSceneWorld->GetPBRMaterialType()); - } - if (ImGui::MenuItem(CD_TEXT("TEXT_REBUILD_ANIMATION_SHADERS"))) - { - ShaderBuilder::BuildUberShader(pSceneWorld->GetAnimationMaterialType()); - } - ResourceBuilder::Get().Update(); ImGui::EndMenu(); } diff --git a/Engine/Source/Runtime/Application/IApplication.h b/Engine/Source/Runtime/Application/IApplication.h index 45cfdf82..fcd3e615 100644 --- a/Engine/Source/Runtime/Application/IApplication.h +++ b/Engine/Source/Runtime/Application/IApplication.h @@ -19,6 +19,7 @@ struct EngineInitArgs bool useFullScreen = false; Language language = Language::English; GraphicsBackend backend = GraphicsBackend::Direct3D11; + bool compileAllShaders = false; }; class IApplication diff --git a/Engine/Source/Runtime/ECWorld/AllComponentsHeader.h b/Engine/Source/Runtime/ECWorld/AllComponentsHeader.h index 912175e2..53f38877 100644 --- a/Engine/Source/Runtime/ECWorld/AllComponentsHeader.h +++ b/Engine/Source/Runtime/ECWorld/AllComponentsHeader.h @@ -11,7 +11,6 @@ #include "ECWorld/LightComponent.h" #include "ECWorld/MaterialComponent.h" #include "ECWorld/NameComponent.h" -#include "ECWorld/ShaderVariantCollectionsComponent.h" #include "ECWorld/SkyComponent.h" #include "ECWorld/StaticMeshComponent.h" #include "ECWorld/TerrainComponent.h" diff --git a/Engine/Source/Runtime/ECWorld/MaterialComponent.cpp b/Engine/Source/Runtime/ECWorld/MaterialComponent.cpp index 065dfea7..da478a59 100644 --- a/Engine/Source/Runtime/ECWorld/MaterialComponent.cpp +++ b/Engine/Source/Runtime/ECWorld/MaterialComponent.cpp @@ -95,17 +95,6 @@ uint64_t GetBGFXTextureFlag(cd::MaterialTextureType textureType, cd::TextureMapM return textureFlag; } -const std::unordered_map skyTypeToShaderFeature -{ - { engine::SkyType::SkyBox, engine::ShaderFeature::IBL}, - { engine::SkyType::AtmosphericScattering, engine::ShaderFeature::ATM }, -}; - -CD_FORCEINLINE bool IsSkyTypeValid(engine::SkyType type) -{ - return skyTypeToShaderFeature.find(type) != skyTypeToShaderFeature.end(); -} - } namespace engine @@ -138,24 +127,48 @@ const MaterialComponent::TextureInfo* MaterialComponent::GetTextureInfo(cd::Mate return &itTextureInfo->second; } -void MaterialComponent::ActiveShaderFeature(engine::ShaderFeature feature) +void MaterialComponent::ActivateShaderFeature(ShaderFeature feature) { - m_shaderFeatures.insert(feature); + if (ShaderFeature::DEFAULT == feature) + { + return; + } + + const auto& optConflict = m_pMaterialType->GetShaderSchema().GetConflictFeatureSet(feature); + assert(optConflict.has_value()); + + for (const auto& conflict : optConflict.value()) + { + m_shaderFeatures.erase(conflict); + } + + m_shaderFeatures.insert(cd::MoveTemp(feature)); + + m_isShaderFeatureDirty = true; } -void MaterialComponent::DeactiveShaderFeature(engine::ShaderFeature feature) +void MaterialComponent::DeactiveShaderFeature(ShaderFeature feature) { m_shaderFeatures.erase(feature); + + m_isShaderFeatureDirty = true; } -void MaterialComponent::MatchUberShaderCrc() +const std::string& MaterialComponent::GetFeaturesCombine() { - m_uberShaderCrc = m_pMaterialType->GetShaderSchema().GetFeaturesCrc(m_shaderFeatures); + if (false == m_isShaderFeatureDirty) + { + return m_featureCombine; + } + + m_featureCombine = m_pMaterialType->GetShaderSchema().GetFeaturesCombine(m_shaderFeatures); + m_isShaderFeatureDirty = false; + return m_featureCombine; } -uint16_t MaterialComponent::GetShadreProgram() const +const std::string& MaterialComponent::GetProgramName() const { - return m_pMaterialType->GetShaderSchema().GetCompiledProgram(m_uberShaderCrc); + return m_pMaterialType->GetShaderSchema().GetProgramName(); } void MaterialComponent::Reset() @@ -163,7 +176,6 @@ void MaterialComponent::Reset() m_pMaterialData = nullptr; m_pMaterialType = nullptr; m_shaderFeatures.clear(); - m_uberShaderCrc = ShaderSchema::DefaultUberShaderCrc; m_name.clear(); m_albedoColor = cd::Vec3f::One(); m_emissiveColor = cd::Vec3f::One(); @@ -172,8 +184,11 @@ void MaterialComponent::Reset() m_twoSided = false; m_blendMode = cd::BlendMode::Opaque; m_alphaCutOff = 1.0f; + m_isShaderFeatureDirty = false; + m_shaderFeatures.clear(); + m_featureCombine.clear(); + m_cacheTextureBlobs.clear(); m_textureResources.clear(); - m_skyType = SkyType::None; } std::string MaterialComponent::GetVertexShaderName() const @@ -262,27 +277,4 @@ void MaterialComponent::Build() } } -void MaterialComponent::SetSkyType(SkyType crtType) -{ - // SkyType::None is a special case which is not a shader feature but means deactive ShaderFeature::IBL and ShaderFeature::ATM. - - if (SkyType::Count == crtType || m_skyType == crtType) - { - return; - } - - if (IsSkyTypeValid(m_skyType)) - { - m_shaderFeatures.erase(skyTypeToShaderFeature.at(m_skyType)); - } - - if (IsSkyTypeValid(crtType)) - { - m_shaderFeatures.insert(skyTypeToShaderFeature.at(crtType)); - } - - m_uberShaderCrc = m_pMaterialType->GetShaderSchema().GetFeaturesCrc(m_shaderFeatures); - m_skyType = crtType; -} - } diff --git a/Engine/Source/Runtime/ECWorld/MaterialComponent.h b/Engine/Source/Runtime/ECWorld/MaterialComponent.h index 0d63690f..4d911c0c 100644 --- a/Engine/Source/Runtime/ECWorld/MaterialComponent.h +++ b/Engine/Source/Runtime/ECWorld/MaterialComponent.h @@ -3,7 +3,6 @@ #include "Core/StringCrc.h" #include "ECWorld/SkyComponent.h" #include "Material/ShaderSchema.h" -#include "Scene/Material.h" #include "Scene/MaterialTextureType.h" #include "Scene/Texture.h" @@ -31,6 +30,7 @@ namespace engine { class MaterialType; +class RenderContext; class MaterialComponent final { @@ -93,15 +93,14 @@ class MaterialComponent final const std::string& GetName() const { return m_name; } // Uber shader data. - void ActiveShaderFeature(ShaderFeature feature); + void ActivateShaderFeature(ShaderFeature feature); void DeactiveShaderFeature(ShaderFeature feature); - void MatchUberShaderCrc(); - uint16_t GetShadreProgram() const; - void SetShaderFeatures(std::set options) { m_shaderFeatures = cd::MoveTemp(m_shaderFeatures); } std::set& GetShaderFeatures() { return m_shaderFeatures; } const std::set& GetShaderFeatures() const { return m_shaderFeatures; } + const std::string& GetFeaturesCombine(); + const std::string& GetProgramName() const; std::string GetVertexShaderName() const; std::string GetFragmentShaderName() const; @@ -143,17 +142,10 @@ class MaterialComponent final float& GetAlphaCutOff() { return m_alphaCutOff; } float GetAlphaCutOff() const { return m_alphaCutOff; } - // Different sky types provide different environment lighting. - void SetSkyType(SkyType type); - const SkyType GetSkyType() const { return m_skyType; } - SkyType GetSkyType() { return m_skyType; } - private: // Input const cd::Material* m_pMaterialData = nullptr; const engine::MaterialType* m_pMaterialType = nullptr; - std::set m_shaderFeatures; - StringCrc m_uberShaderCrc; std::string m_name; cd::Vec3f m_albedoColor; @@ -164,7 +156,10 @@ class MaterialComponent final cd::BlendMode m_blendMode; float m_alphaCutOff; - SkyType m_skyType; + bool m_isShaderFeatureDirty = false; + std::set m_shaderFeatures; + std::string m_featureCombine; + std::vector m_cacheTextureBlobs; // Output diff --git a/Engine/Source/Runtime/ECWorld/SceneWorld.cpp b/Engine/Source/Runtime/ECWorld/SceneWorld.cpp index de096523..532275db 100644 --- a/Engine/Source/Runtime/ECWorld/SceneWorld.cpp +++ b/Engine/Source/Runtime/ECWorld/SceneWorld.cpp @@ -33,7 +33,6 @@ SceneWorld::SceneWorld() m_pLightComponentStorage = m_pWorld->Register(); m_pMaterialComponentStorage = m_pWorld->Register(); m_pNameComponentStorage = m_pWorld->Register(); - m_pShaderVariantCollectionsComponentStorage = m_pWorld->Register(); m_pSkyComponentStorage = m_pWorld->Register(); m_pStaticMeshComponentStorage = m_pWorld->Register(); m_pParticleComponentStorage = m_pWorld->Register(); @@ -51,7 +50,7 @@ void SceneWorld::CreatePBRMaterialType(bool isAtmosphericScatteringEnable) m_pPBRMaterialType = std::make_unique(); m_pPBRMaterialType->SetMaterialName("CD_PBR"); - ShaderSchema shaderSchema(Path::GetBuiltinShaderInputPath("shaders/vs_PBR"), Path::GetBuiltinShaderInputPath("shaders/fs_PBR")); + ShaderSchema shaderSchema("WorldProgram", Path::GetBuiltinShaderInputPath("vs_PBR"), Path::GetBuiltinShaderInputPath("fs_PBR")); shaderSchema.AddFeatureSet({ ShaderFeature::ALBEDO_MAP }); shaderSchema.AddFeatureSet({ ShaderFeature::NORMAL_MAP }); shaderSchema.AddFeatureSet({ ShaderFeature::ORM_MAP }); @@ -88,7 +87,7 @@ void SceneWorld::CreateAnimationMaterialType() m_pAnimationMaterialType = std::make_unique(); m_pAnimationMaterialType->SetMaterialName("CD_Animation"); - ShaderSchema shaderSchema(Path::GetBuiltinShaderInputPath("shaders/vs_animation"), Path::GetBuiltinShaderInputPath("shaders/fs_animation")); + ShaderSchema shaderSchema("AnimationProgram", Path::GetBuiltinShaderInputPath("vs_animation"), Path::GetBuiltinShaderInputPath("fs_animation")); m_pAnimationMaterialType->SetShaderSchema(cd::MoveTemp(shaderSchema)); cd::VertexFormat animationVertexFormat; @@ -172,12 +171,6 @@ void SceneWorld::SetSkyEntity(engine::Entity entity) m_skyEntity = entity; } -void SceneWorld::SetShaderVariantCollectionEntity(engine::Entity entity) -{ - CD_TRACE("Setup Shader Variant Collection entity : {0}", entity); - m_shaderVariantCollectionEntity = entity; -} - void SceneWorld::AddCameraToSceneDatabase(engine::Entity entity) { engine::CameraComponent* pCameraComponent = GetCameraComponent(entity); diff --git a/Engine/Source/Runtime/ECWorld/SceneWorld.h b/Engine/Source/Runtime/ECWorld/SceneWorld.h index 074b69a7..cdcbbca4 100644 --- a/Engine/Source/Runtime/ECWorld/SceneWorld.h +++ b/Engine/Source/Runtime/ECWorld/SceneWorld.h @@ -38,7 +38,6 @@ class SceneWorld DEFINE_COMPONENT_STORAGE_WITH_APIS(Light); DEFINE_COMPONENT_STORAGE_WITH_APIS(Material); DEFINE_COMPONENT_STORAGE_WITH_APIS(Name); - DEFINE_COMPONENT_STORAGE_WITH_APIS(ShaderVariantCollections); DEFINE_COMPONENT_STORAGE_WITH_APIS(Sky); DEFINE_COMPONENT_STORAGE_WITH_APIS(StaticMesh); DEFINE_COMPONENT_STORAGE_WITH_APIS(Particle); @@ -72,9 +71,6 @@ class SceneWorld void SetSkyEntity(engine::Entity entity); CD_FORCEINLINE engine::Entity GetSkyEntity() const { return m_skyEntity; } - void SetShaderVariantCollectionEntity(engine::Entity entity); - CD_FORCEINLINE engine::Entity GetShaderVariantCollectionEntity() const { return m_shaderVariantCollectionEntity; } - void DeleteEntity(engine::Entity entity) { if (entity == m_mainCameraEntity) @@ -100,7 +96,6 @@ class SceneWorld DeleteLightComponent(entity); DeleteMaterialComponent(entity); DeleteNameComponent(entity); - DeleteShaderVariantCollectionsComponent(entity); DeleteSkyComponent(entity); DeleteStaticMeshComponent(entity); DeleteParticleComponent(entity); @@ -146,9 +141,7 @@ class SceneWorld engine::Entity m_selectedEntity = engine::INVALID_ENTITY; engine::Entity m_mainCameraEntity = engine::INVALID_ENTITY; - // TODO : wrap them to project data. engine::Entity m_skyEntity = engine::INVALID_ENTITY; - engine::Entity m_shaderVariantCollectionEntity = engine::INVALID_ENTITY; #ifdef ENABLE_DDGI engine::Entity m_ddgiEntity = engine::INVALID_ENTITY; diff --git a/Engine/Source/Runtime/ECWorld/ShaderVariantCollectionsComponent.cpp b/Engine/Source/Runtime/ECWorld/ShaderVariantCollectionsComponent.cpp deleted file mode 100644 index c5c90905..00000000 --- a/Engine/Source/Runtime/ECWorld/ShaderVariantCollectionsComponent.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "ShaderVariantCollectionsComponent.h" - -namespace engine -{ - - - -} \ No newline at end of file diff --git a/Engine/Source/Runtime/ECWorld/ShaderVariantCollectionsComponent.h b/Engine/Source/Runtime/ECWorld/ShaderVariantCollectionsComponent.h deleted file mode 100644 index c90cdc4e..00000000 --- a/Engine/Source/Runtime/ECWorld/ShaderVariantCollectionsComponent.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "Base/Template.h" -#include "Core/StringCrc.h" - -namespace engine -{ - -class ShaderVariantCollectionsComponent final -{ -public: - static constexpr StringCrc GetClassName() - { - constexpr StringCrc className("ShaderVariantCollectionsComponent"); - return className; - } - - ShaderVariantCollectionsComponent() = default; - ShaderVariantCollectionsComponent(const ShaderVariantCollectionsComponent&) = default; - ShaderVariantCollectionsComponent& operator=(const ShaderVariantCollectionsComponent&) = default; - ShaderVariantCollectionsComponent(ShaderVariantCollectionsComponent&&) = default; - ShaderVariantCollectionsComponent& operator=(ShaderVariantCollectionsComponent&&) = default; - ~ShaderVariantCollectionsComponent() = default; - -private: - -}; - -} \ No newline at end of file diff --git a/Engine/Source/Runtime/ECWorld/SkyComponent.cpp b/Engine/Source/Runtime/ECWorld/SkyComponent.cpp index a1707b1e..e6f68aa1 100644 --- a/Engine/Source/Runtime/ECWorld/SkyComponent.cpp +++ b/Engine/Source/Runtime/ECWorld/SkyComponent.cpp @@ -3,19 +3,19 @@ namespace engine { -void SkyComponent::SetSkyType(SkyType crtType) +void SkyComponent::SetSkyType(SkyType type) { - if (m_type == crtType) + if (m_type == type) { return; } - m_type = crtType; + m_type = type; static std::string preRadPath = m_radianceTexturePath; if (SkyType::None == m_type) { preRadPath = cd::MoveTemp(m_radianceTexturePath); - m_radianceTexturePath = SkyComponent::PureGrayTexturePath; + m_radianceTexturePath = m_pureGrayTexturePath; } else if(preRadPath != m_radianceTexturePath) { @@ -38,4 +38,9 @@ void SkyComponent::SetRadianceTexturePath(std::string path) m_radianceTexturePath = cd::MoveTemp(path); } +void SkyComponent::SetPureGrayTexturePath(std::string path) +{ + m_pureGrayTexturePath = cd::MoveTemp(path); +} + } \ No newline at end of file diff --git a/Engine/Source/Runtime/ECWorld/SkyComponent.h b/Engine/Source/Runtime/ECWorld/SkyComponent.h index a8abc34e..41862bd7 100644 --- a/Engine/Source/Runtime/ECWorld/SkyComponent.h +++ b/Engine/Source/Runtime/ECWorld/SkyComponent.h @@ -3,27 +3,19 @@ #include "Base/Template.h" #include "Core/StringCrc.h" #include "Math/Vector.hpp" +#include "Rendering/SkyType.h" #include namespace engine { -enum class SkyType -{ - None = 0, - SkyBox, - AtmosphericScattering, - - Count, -}; - class SkyComponent final { public: static constexpr const char* DefaultIrradainceTexturePath = "Textures/skybox/defaultSkybox_irr.dds"; static constexpr const char* DefaultRadianceTexturePath = "Textures/skybox/defaultSkybox_rad.dds"; - static constexpr const char* PureGrayTexturePath = "Textures/skybox/PureGray.dds"; + static constexpr const char* DefaultPureGrayTexturePath = "Textures/skybox/PureGray.dds"; public: static constexpr StringCrc GetClassName() @@ -39,7 +31,7 @@ class SkyComponent final SkyComponent& operator=(SkyComponent&&) = default; ~SkyComponent() = default; - void SetSkyType(SkyType crtType); + void SetSkyType(SkyType type); SkyType& GetSkyType() { return m_type; } const SkyType& GetSkyType() const { return m_type; } @@ -79,6 +71,10 @@ class SkyComponent final std::string& GetRadianceTexturePath() { return m_radianceTexturePath; } const std::string& GetRadianceTexturePath() const { return m_radianceTexturePath; } + void SetPureGrayTexturePath(std::string path); + std::string& GetPureGrayTexturePath() { return m_pureGrayTexturePath; } + const std::string& GetPureGrayTexturePath() const { return m_pureGrayTexturePath; } + private: SkyType m_type = SkyType::SkyBox; bool m_isAtmophericScatteringEnable = false; @@ -94,6 +90,7 @@ class SkyComponent final std::string m_irradianceTexturePath = DefaultIrradainceTexturePath; std::string m_radianceTexturePath = DefaultRadianceTexturePath; + std::string m_pureGrayTexturePath = DefaultPureGrayTexturePath; }; } \ No newline at end of file diff --git a/Engine/Source/Runtime/ECWorld/TerrainComponent.h b/Engine/Source/Runtime/ECWorld/TerrainComponent.h index ff4213fd..a2f3315b 100644 --- a/Engine/Source/Runtime/ECWorld/TerrainComponent.h +++ b/Engine/Source/Runtime/ECWorld/TerrainComponent.h @@ -57,21 +57,21 @@ class TerrainComponent final void ScreenSpaceSmooth(float screenSpaceX, float screenSpaceY, cd::Matrix4x4 invProjMtx, cd::Matrix4x4 invViewMtx, cd::Vec3f camPos); private: - //mesh - uint16_t m_meshWidth = 129U;//uint32_t is too big for width + // mesh + uint16_t m_meshWidth = 129U; // uint32_t is too big for width uint16_t m_meshDepth = 129U; - //height map input - uint16_t m_texWidth = 129U;//uint32_t is too big for width - uint16_t m_texDepth = 129U;// + // height map input + uint16_t m_texWidth = 129U; // uint32_t is too big for width + uint16_t m_texDepth = 129U; float m_roughness = 1.55f; float m_minHeight = 0.0f; float m_maxHeight = 30.0f; - //for patch wise generating - //uint32_t m_PatchSize; + // for patch wise generating + // uint32_t m_PatchSize; - //height map output + // height map output std::vector m_elevationRawData; }; diff --git a/Engine/Source/Runtime/ImGui/ImGuiBaseLayer.cpp b/Engine/Source/Runtime/ImGui/ImGuiBaseLayer.cpp index 8b2750e7..bf3e2545 100644 --- a/Engine/Source/Runtime/ImGui/ImGuiBaseLayer.cpp +++ b/Engine/Source/Runtime/ImGui/ImGuiBaseLayer.cpp @@ -2,6 +2,7 @@ #include "ECWorld/SceneWorld.h" #include "ImGui/ImGuiContextInstance.h" +#include "Rendering/RenderContext.h" #include diff --git a/Engine/Source/Runtime/Material/MaterialType.cpp b/Engine/Source/Runtime/Material/MaterialType.cpp index bb00b601..5cb08866 100644 --- a/Engine/Source/Runtime/Material/MaterialType.cpp +++ b/Engine/Source/Runtime/Material/MaterialType.cpp @@ -11,12 +11,6 @@ void MaterialType::AddOptionalTextureType(cd::MaterialTextureType textureType, u m_textureTypeSlots[textureType] = slot; } -void MaterialType::AddRequiredTextureType(cd::MaterialTextureType textureType, uint8_t slot) -{ - m_requiredTextureTypes.insert(textureType); - m_textureTypeSlots[textureType] = slot; -} - std::optional MaterialType::GetTextureSlot(cd::MaterialTextureType textureType) const { auto itTexture = m_textureTypeSlots.find(textureType); diff --git a/Engine/Source/Runtime/Material/MaterialType.h b/Engine/Source/Runtime/Material/MaterialType.h index fe151356..ab3bfcdf 100644 --- a/Engine/Source/Runtime/Material/MaterialType.h +++ b/Engine/Source/Runtime/Material/MaterialType.h @@ -38,9 +38,6 @@ class MaterialType void AddOptionalTextureType(cd::MaterialTextureType textureType, uint8_t slot); const std::set& GetOptionalTextureTypes() const { return m_optionalTextureTypes; } - void AddRequiredTextureType(cd::MaterialTextureType textureType, uint8_t slot); - const std::set& GetRequiredTextureTypes() const { return m_requiredTextureTypes; } - std::optional GetTextureSlot(cd::MaterialTextureType textureType) const; private: @@ -49,7 +46,6 @@ class MaterialType cd::VertexFormat m_requiredVertexFormat; std::set m_optionalTextureTypes; - std::set m_requiredTextureTypes; std::map m_textureTypeSlots; }; diff --git a/Engine/Source/Runtime/Material/ShaderSchema.cpp b/Engine/Source/Runtime/Material/ShaderSchema.cpp index 0cac35a1..9f497129 100644 --- a/Engine/Source/Runtime/Material/ShaderSchema.cpp +++ b/Engine/Source/Runtime/Material/ShaderSchema.cpp @@ -10,33 +10,9 @@ namespace engine { -namespace -{ - -constexpr const char* ShaderFeatureNames[] = -{ - "", // Use empty string to represent default shader option in the name so we can reuse non-uber built shader. - "ALBEDOMAP;", - "NORMALMAP;", - "ORMMAP;", - "EMISSIVEMAP;", - "IBL;", - "ATM;", - "AREALLIGHT;", -}; - -static_assert(static_cast(ShaderFeature::COUNT) == sizeof(ShaderFeatureNames) / sizeof(char*), - "Shader features and names mismatch."); - -CD_FORCEINLINE constexpr const char* GetFeatureName(ShaderFeature feature) -{ - return ShaderFeatureNames[static_cast(feature)]; -} - -} - -ShaderSchema::ShaderSchema(std::string vsPath, std::string fsPath) +ShaderSchema::ShaderSchema(std::string progeamName, std::string vsPath, std::string fsPath) { + m_programName = cd::MoveTemp(progeamName); m_vertexShaderPath = cd::MoveTemp(vsPath); m_fragmentShaderPath = cd::MoveTemp(fsPath); @@ -58,7 +34,7 @@ void ShaderSchema::AddFeatureSet(ShaderFeatureSet featureSet) } m_isDirty = true; - m_shaderFeatureSets.emplace_back(cd::MoveTemp(featureSet)); + m_shaderFeatureSets.insert(cd::MoveTemp(featureSet)); } void ShaderSchema::Build() @@ -77,9 +53,9 @@ void ShaderSchema::Build() for (const auto& feature : featureSet) { std::string newFeatureName = GetFeatureName(feature); - std::vector newFeatureCombines = { newFeatureName }; + std::set newFeatureCombines = { newFeatureName }; - for (const auto& combine : m_featureCombines) + for (const auto& combine : m_allFeatureCombines) { // Skip combination which has features in same set. bool skip = false; @@ -97,27 +73,20 @@ void ShaderSchema::Build() } if (!skip) { - newFeatureCombines.emplace_back(combine + newFeatureName); + newFeatureCombines.insert(combine + newFeatureName); } } - m_featureCombines.insert(m_featureCombines.end(), newFeatureCombines.begin(), newFeatureCombines.end()); - for (const auto& combine : newFeatureCombines) - { - assert(!IsFeaturesValid(StringCrc(combine))); - m_compiledProgramHandles[StringCrc(combine).Value()] = InvalidProgramHandle; - } + m_allFeatureCombines.insert(newFeatureCombines.begin(), newFeatureCombines.end()); } } - // ShaderSchema also handle non-uber case. - m_featureCombines.emplace_back(""); - m_compiledProgramHandles[DefaultUberShaderCrc.Value()] = InvalidProgramHandle; + // Should ShaderSchema handle uber shader without shader feature? + m_allFeatureCombines.insert(""); } void ShaderSchema::CleanBuild() { - m_featureCombines.clear(); - m_compiledProgramHandles.clear(); + m_allFeatureCombines.clear(); m_isDirty = true; } @@ -129,38 +98,26 @@ void ShaderSchema::CleanAll() m_shaderFeatureSets.clear(); } -void ShaderSchema::SetCompiledProgram(StringCrc shaderFeaturesCrc, uint16_t programHandle) +const std::optional ShaderSchema::GetConflictFeatureSet(ShaderFeature feature) const { - assert(IsFeaturesValid(shaderFeaturesCrc)); - m_compiledProgramHandles[shaderFeaturesCrc.Value()] = programHandle; -} + const auto& asd = m_shaderFeatureSets; -uint16_t ShaderSchema::GetCompiledProgram(StringCrc shaderFeaturesCrc) const -{ - auto itProgram = m_compiledProgramHandles.find(shaderFeaturesCrc.Value()); - - if (itProgram == m_compiledProgramHandles.end()) + for (const auto& shaderFeatureSet : m_shaderFeatureSets) { - CD_ENGINE_ERROR("Unregistered shader features!"); - return InvalidProgramHandle; - } - - uint16_t programHandle = itProgram->second; - - if (programHandle == InvalidProgramHandle) - { - CD_ENGINE_ERROR("Uncompiled shader features"); - return InvalidProgramHandle; + if (shaderFeatureSet.find(feature) != shaderFeatureSet.end()) + { + return shaderFeatureSet; + } } - return programHandle; + return std::nullopt; } -StringCrc ShaderSchema::GetFeaturesCrc(const ShaderFeatureSet& featureSet) const +std::string ShaderSchema::GetFeaturesCombine(const ShaderFeatureSet& featureSet) const { if (m_shaderFeatureSets.empty() || featureSet.empty()) { - return DefaultUberShaderCrc; + return ""; } std::stringstream ss; @@ -177,40 +134,17 @@ StringCrc ShaderSchema::GetFeaturesCrc(const ShaderFeatureSet& featureSet) const } } - return StringCrc(ss.str()); -} - -bool ShaderSchema::IsFeaturesValid(StringCrc shaderFeaturesCrc) const -{ - return m_compiledProgramHandles.find(shaderFeaturesCrc.Value()) != m_compiledProgramHandles.end(); -} - -void ShaderSchema::AddUberVSBlob(ShaderBlob shaderBlob) -{ - if (m_pVSBlob) - { - // TODO : process vertex uber shaders. - return; - } - - m_pVSBlob = std::make_unique(cd::MoveTemp(shaderBlob)); + return ss.str(); } -void ShaderSchema::AddUberFSBlob(StringCrc shaderFeaturesCrc, ShaderBlob shaderBlob) +StringCrc ShaderSchema::GetFeaturesCombineCrc(const ShaderFeatureSet& featureSet) const { - if (m_shaderFeaturesToFSBlobs.find(shaderFeaturesCrc.Value()) != m_shaderFeaturesToFSBlobs.end()) + if (m_shaderFeatureSets.empty() || featureSet.empty()) { - return; + return DefaultUberShaderCrc; } - m_shaderFeaturesToFSBlobs[shaderFeaturesCrc.Value()] = std::make_unique(cd::MoveTemp(shaderBlob)); -} - -const ShaderSchema::ShaderBlob& ShaderSchema::GetFSBlob(StringCrc shaderFeaturesCrc) const -{ - auto itBlob = m_shaderFeaturesToFSBlobs.find(shaderFeaturesCrc.Value()); - assert(itBlob != m_shaderFeaturesToFSBlobs.end()); - return *(itBlob->second.get()); + return StringCrc(GetFeaturesCombine(featureSet)); } } \ No newline at end of file diff --git a/Engine/Source/Runtime/Material/ShaderSchema.h b/Engine/Source/Runtime/Material/ShaderSchema.h index 0dd92f71..4883ee77 100644 --- a/Engine/Source/Runtime/Material/ShaderSchema.h +++ b/Engine/Source/Runtime/Material/ShaderSchema.h @@ -1,9 +1,11 @@ #pragma once #include "Core/StringCrc.h" +#include "Rendering/ShaderFeature.h" #include #include +#include #include #include #include @@ -13,24 +15,6 @@ namespace engine { -enum class ShaderFeature : uint32_t -{ - DEFAULT = 0, - - // PBR parameters - ALBEDO_MAP, - NORMAL_MAP, - ORM_MAP, - EMISSIVE_MAP, - - // Techniques - IBL, - ATM, - AREAL_LIGHT, - - COUNT, -}; - enum class LoadingStatus : uint8_t { MISSING_RESOURCES = 0, @@ -46,62 +30,48 @@ class ShaderSchema public: static constexpr uint16_t InvalidProgramHandle = UINT16_MAX; static constexpr StringCrc DefaultUberShaderCrc = StringCrc(""); - using ShaderBlob = std::vector; - using ShaderFeatureSet = std::set; public: ShaderSchema() = default; - explicit ShaderSchema(std::string vsPath, std::string fsPath); + explicit ShaderSchema(std::string progeamName, std::string vsPath, std::string fsPath); ShaderSchema(const ShaderSchema&) = delete; ShaderSchema& operator=(const ShaderSchema&) = delete; ShaderSchema(ShaderSchema&&) = default; ShaderSchema& operator=(ShaderSchema&&) = default; ~ShaderSchema() = default; - const char* GetVertexShaderPath() const { return m_vertexShaderPath.c_str(); } - const char* GetFragmentShaderPath() const { return m_fragmentShaderPath.c_str(); } + const std::string& GetProgramName() const { return m_programName; } + const std::string& GetVertexShaderPath() const { return m_vertexShaderPath; } + const std::string& GetFragmentShaderPath() const { return m_fragmentShaderPath; } void AddFeatureSet(ShaderFeatureSet featureSet); - // Calling "AddFeatureSet/SetConflictOptions and Build" after Build will cause unnecessary performance overhead. void Build(); void CleanBuild(); void CleanAll(); - void SetCompiledProgram(StringCrc shaderFeaturesCrc, uint16_t programHandle); - uint16_t GetCompiledProgram(StringCrc shaderFeaturesCrc) const; - - StringCrc GetFeaturesCrc(const ShaderFeatureSet& featureSet) const; - bool IsFeaturesValid(StringCrc shaderFeaturesCrc) const; + const std::optional GetConflictFeatureSet(ShaderFeature feature) const; - std::vector& GetFeatures() { return m_shaderFeatureSets; } - const std::vector& GetFeatures() const { return m_shaderFeatureSets; } + std::string GetFeaturesCombine(const ShaderFeatureSet& featureSet) const; + StringCrc GetFeaturesCombineCrc(const ShaderFeatureSet& featureSet) const; - std::vector& GetFeatureCombines() { return m_featureCombines; } - const std::vector& GetFeatureCombines() const { return m_featureCombines; } + std::set& GetFeatures() { return m_shaderFeatureSets; } + const std::set& GetFeatures() const { return m_shaderFeatureSets; } - // TODO : More generic. - void AddUberVSBlob(ShaderBlob shaderBlob); - void AddUberFSBlob(StringCrc shaderFeaturesCrc, ShaderBlob shaderBlob); - const ShaderBlob& GetVSBlob() const { return *m_pVSBlob.get(); } - const ShaderBlob& GetFSBlob(StringCrc shaderFeaturesCrc) const; + std::set& GetAllFeatureCombines() { return m_allFeatureCombines; } + const std::set& GetAllFeatureCombines() const { return m_allFeatureCombines; } private: + std::string m_programName; std::string m_vertexShaderPath; std::string m_fragmentShaderPath; bool m_isDirty = false; - // Adding order of shaer features. - std::vector m_shaderFeatureSets; - // Parameters to compile shaders. - std::vector m_featureCombines; - - // Key: StringCrc(feature combine), Value: shader handle. - std::map m_compiledProgramHandles; - - std::unique_ptr m_pVSBlob; - std::map> m_shaderFeaturesToFSBlobs; + // Registration order of shader features. + std::set m_shaderFeatureSets; + // All permutations matching the registered shader features. + std::set m_allFeatureCombines; }; } \ No newline at end of file diff --git a/Engine/Source/Runtime/Path/Path.cpp b/Engine/Source/Runtime/Path/Path.cpp index c8179c5f..dfb1536f 100644 --- a/Engine/Source/Runtime/Path/Path.cpp +++ b/Engine/Source/Runtime/Path/Path.cpp @@ -91,7 +91,7 @@ void Path::SetGraphicsBackend(engine::GraphicsBackend backend) std::string Path::GetBuiltinShaderInputPath(const char* pShaderName) { - return (GetEngineBuiltinShaderPath() / std::filesystem::path(pShaderName)).replace_extension(ShaderInputExtension).string(); + return (GetEngineBuiltinShaderPath() / "shaders" / pShaderName).replace_extension(ShaderInputExtension).generic_string(); } std::filesystem::path Path::GetShaderOutputDirectory() @@ -99,13 +99,13 @@ std::filesystem::path Path::GetShaderOutputDirectory() return GetProjectsSharedPath() / "BuiltInShaders" / nameof::nameof_enum(s_backend); } -std::string Path::GetShaderOutputPath(const char* pInputFilePath, const std::string& options) +std::string Path::GetShaderOutputPath(const char* pInputFilePath, const std::string& combine) { - std::string outputShaderFileName = std::filesystem::path(pInputFilePath).stem().string(); + std::string outputShaderFileName = std::filesystem::path(pInputFilePath).stem().generic_string(); - if (!options.empty()) + if (!combine.empty()) { - std::string appendName = "_" + options; + std::string appendName = "_" + combine; std::replace(appendName.begin(), appendName.end(), ';', '_'); outputShaderFileName += appendName; @@ -117,17 +117,17 @@ std::string Path::GetShaderOutputPath(const char* pInputFilePath, const std::str } } - return (GetShaderOutputDirectory() / cd::MoveTemp(outputShaderFileName)).replace_extension(ShaderOutputExtension).string(); + return (GetShaderOutputDirectory() / cd::MoveTemp(outputShaderFileName)).replace_extension(ShaderOutputExtension).generic_string(); } std::string Path::GetTextureOutputFilePath(const char* pInputFilePath, const char* extension) { - return ((GetEngineResourcesPath() / "Textures" / std::filesystem::path(pInputFilePath).stem()).replace_extension(extension)).string(); + return ((GetEngineResourcesPath() / "Textures" / std::filesystem::path(pInputFilePath).stem()).replace_extension(extension)).generic_string(); } std::string Path::GetTerrainTextureOutputFilePath(const char* pInputFilePath, const char* extension) { - return ((GetEngineResourcesPath() / "Textures" / "Terrain" / std::filesystem::path(pInputFilePath).stem()).replace_extension(extension)).string(); + return ((GetEngineResourcesPath() / "Textures" / "Terrain" / std::filesystem::path(pInputFilePath).stem()).replace_extension(extension)).generic_string(); } } \ No newline at end of file diff --git a/Engine/Source/Runtime/Path/Path.h b/Engine/Source/Runtime/Path/Path.h index 1f03abc6..b8f44d52 100644 --- a/Engine/Source/Runtime/Path/Path.h +++ b/Engine/Source/Runtime/Path/Path.h @@ -20,11 +20,6 @@ class Path static std::optional GetApplicationDataPath(); - static std::filesystem::path GetEngineBuiltinShaderPath(); - static std::filesystem::path GetEngineResourcesPath(); - static std::filesystem::path GetEditorResourcesPath(); - static std::filesystem::path GetProjectsSharedPath(); - static engine::GraphicsBackend GetGraphicsBackend(); static void SetGraphicsBackend(engine::GraphicsBackend backend); @@ -35,6 +30,11 @@ class Path static std::string GetTerrainTextureOutputFilePath(const char* pInputFilePath, const char* extension); private: + static std::filesystem::path GetEngineBuiltinShaderPath(); + static std::filesystem::path GetEngineResourcesPath(); + static std::filesystem::path GetEditorResourcesPath(); + static std::filesystem::path GetProjectsSharedPath(); + static const char* GetPlatformPathKey(); static std::filesystem::path GetPlatformAppDataPath(const char* pRootPath); diff --git a/Engine/Source/Runtime/Rendering/AABBRenderer.cpp b/Engine/Source/Runtime/Rendering/AABBRenderer.cpp index 58d79204..a5900005 100644 --- a/Engine/Source/Runtime/Rendering/AABBRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/AABBRenderer.cpp @@ -4,7 +4,7 @@ #include "ECWorld/SceneWorld.h" #include "ECWorld/StaticMeshComponent.h" #include "ECWorld/TransformComponent.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" #include "Scene/Texture.h" namespace engine @@ -12,10 +12,17 @@ namespace engine void AABBRenderer::Init() { - GetRenderContext()->CreateProgram("AABBProgram", "vs_AABB.bin", "fs_AABB.bin"); + constexpr StringCrc programCrc = StringCrc("AABBProgram"); + GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_AABB", "fs_AABB" }); + bgfx::setViewName(GetViewID(), "AABBRenderer"); } +void AABBRenderer::Warmup() +{ + GetRenderContext()->UploadShaderProgram("AABBProgram"); +} + void AABBRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { UpdateViewRenderTarget(); @@ -45,8 +52,7 @@ void AABBRenderer::Render(float deltaTime) BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) | BGFX_STATE_PT_LINES; bgfx::setState(state); - constexpr StringCrc AABBAllProgram("AABBProgram"); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(AABBAllProgram)); + GetRenderContext()->Submit(GetViewID(), "AABBProgram"); } } diff --git a/Engine/Source/Runtime/Rendering/AABBRenderer.h b/Engine/Source/Runtime/Rendering/AABBRenderer.h index 32145ce5..b707a658 100644 --- a/Engine/Source/Runtime/Rendering/AABBRenderer.h +++ b/Engine/Source/Runtime/Rendering/AABBRenderer.h @@ -15,6 +15,7 @@ class AABBRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Rendering/AnimationRenderer.cpp b/Engine/Source/Runtime/Rendering/AnimationRenderer.cpp index 8617c737..cfcf5632 100644 --- a/Engine/Source/Runtime/Rendering/AnimationRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/AnimationRenderer.cpp @@ -4,7 +4,7 @@ #include "ECWorld/SceneWorld.h" #include "ECWorld/StaticMeshComponent.h" #include "ECWorld/TransformComponent.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" #include "Scene/Texture.h" #include @@ -134,15 +134,21 @@ void CalculateBoneTransform(std::vector& boneMatrices, const cd:: } void AnimationRenderer::Init() +{ + constexpr StringCrc programCrc = StringCrc("AnimationProgram"); + GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_animation", "fs_animation" }); + + bgfx::setViewName(GetViewID(), "AnimationRenderer"); +} + +void AnimationRenderer::Warmup() { #ifdef VISUALIZE_BONE_WEIGHTS m_pRenderContext->CreateUniform("u_debugBoneIndex", bgfx::UniformType::Vec4, 1); - m_pRenderContext->CreateProgram("AnimationProgram", "vs_visualize_bone_weight.bin", "fs_visualize_bone_weight.bin"); + m_pRenderContext->CreateProgram("AnimationProgram", "vs_visualize_bone_weight", "fs_visualize_bone_weight"); #else - GetRenderContext()->CreateProgram("AnimationProgram", "vs_animation.bin", "fs_animation.bin"); + GetRenderContext()->UploadShaderProgram("AnimationProgram"); #endif - - bgfx::setViewName(GetViewID(), "AnimationRenderer"); } void AnimationRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -211,8 +217,7 @@ void AnimationRenderer::Render(float deltaTime) constexpr uint64_t state = BGFX_STATE_WRITE_MASK | BGFX_STATE_CULL_CCW | BGFX_STATE_MSAA | BGFX_STATE_DEPTH_TEST_LESS; bgfx::setState(state); - constexpr StringCrc animationProgram("AnimationProgram"); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(animationProgram)); + GetRenderContext()->Submit(GetViewID(), "AnimationProgram"); } } diff --git a/Engine/Source/Runtime/Rendering/AnimationRenderer.h b/Engine/Source/Runtime/Rendering/AnimationRenderer.h index 694c6827..aeb18f4f 100644 --- a/Engine/Source/Runtime/Rendering/AnimationRenderer.h +++ b/Engine/Source/Runtime/Rendering/AnimationRenderer.h @@ -15,6 +15,7 @@ class AnimationRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Rendering/BlendShapeRenderer.cpp b/Engine/Source/Runtime/Rendering/BlendShapeRenderer.cpp index 732788c6..7e1ffa95 100644 --- a/Engine/Source/Runtime/Rendering/BlendShapeRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/BlendShapeRenderer.cpp @@ -49,17 +49,32 @@ constexpr const char* changedWeight = "u_changedWeight"; constexpr uint64_t samplerFlags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_W_CLAMP; constexpr uint64_t defaultRenderingState = BGFX_STATE_WRITE_MASK | BGFX_STATE_MSAA | BGFX_STATE_DEPTH_TEST_LESS; +constexpr const char *BlendShapeWeightsProgram = "BlendShapeWeightsProgram"; +constexpr const char *BlendShapeWeightPosProgram = "BlendShapeWeightPosProgram"; +constexpr const char *BlendShapeFinalPosProgram = "BlendShapeFinalPosProgram"; +constexpr const char *BlendShapeUpdatePosProgram = "BlendShapeUpdatePosProgram"; + +constexpr StringCrc BlendShapeWeightsProgramCrc = StringCrc("BlendShapeWeightsProgram"); +constexpr StringCrc BlendShapeWeightPosProgramCrc = StringCrc("BlendShapeWeightPosProgram"); +constexpr StringCrc BlendShapeFinalPosProgramCrc = StringCrc("BlendShapeFinalPosProgram"); +constexpr StringCrc BlendShapeUpdatePosProgramCrc = StringCrc("BlendShapeUpdatePosProgram"); + } void BlendShapeRenderer::Init() +{ + GetRenderContext()->RegisterShaderProgram(BlendShapeWeightsProgramCrc, { "cs_blendshape_weights" }); + GetRenderContext()->RegisterShaderProgram(BlendShapeWeightPosProgramCrc, { "cs_blendshape_weight_pos" }); + GetRenderContext()->RegisterShaderProgram(BlendShapeFinalPosProgramCrc, { "cs_blendshape_final_pos" }); + GetRenderContext()->RegisterShaderProgram(BlendShapeUpdatePosProgramCrc, { "cs_blendshape_update_pos" }); + + bgfx::setViewName(GetViewID(), "BlendShapeRenderer"); +} + +void BlendShapeRenderer::Warmup() { SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); - GetRenderContext()->CreateProgram("BlendShapeWeightsProgram", "cs_blendshape_weights.bin"); - GetRenderContext()->CreateProgram("BlendShapeWeightPosProgram", "cs_blendshape_weight_pos.bin"); - GetRenderContext()->CreateProgram("BlendShapeFinalPosProgram", "cs_blendshape_final_pos.bin"); - GetRenderContext()->CreateProgram("BlendShapeUpdatePosProgram", "cs_blendshape_update_pos.bin"); - GetRenderContext()->CreateUniform(lutSampler, bgfx::UniformType::Sampler); GetRenderContext()->CreateUniform(cubeIrradianceSampler, bgfx::UniformType::Sampler); GetRenderContext()->CreateUniform(cubeRadianceSampler, bgfx::UniformType::Sampler); @@ -84,7 +99,10 @@ void BlendShapeRenderer::Init() GetRenderContext()->CreateUniform(morphCountVertexCount, bgfx::UniformType::Vec4, 1); GetRenderContext()->CreateUniform(changedWeight, bgfx::UniformType::Vec4, 1); - bgfx::setViewName(GetViewID(), "BlendShapeRenderer"); + GetRenderContext()->UploadShaderProgram(BlendShapeWeightsProgram); + GetRenderContext()->UploadShaderProgram(BlendShapeWeightPosProgram); + GetRenderContext()->UploadShaderProgram(BlendShapeFinalPosProgram); + GetRenderContext()->UploadShaderProgram(BlendShapeUpdatePosProgram); } void BlendShapeRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -136,10 +154,7 @@ void BlendShapeRenderer::Render(float deltaTime) bgfx::setTransform(pTransformComponent->GetWorldMatrix().Begin()); } - constexpr StringCrc blendShapeWeightsProgram("BlendShapeWeightsProgram"); - constexpr StringCrc blendShapeWeightPosProgram("BlendShapeWeightPosProgram"); - constexpr StringCrc blendShapeFinalPosProgram("BlendShapeFinalPosProgram"); - constexpr StringCrc blendShapeUpdatePosProgram("BlendShapeUpdatePosProgram"); + uint16_t viewId = GetViewID(); // Compute Blend Shape if (pBlendShapeComponent->IsDirty()) @@ -150,18 +165,19 @@ void BlendShapeRenderer::Render(float deltaTime) constexpr StringCrc morphCountVertexCountCrc(morphCountVertexCount); cd::Vec4f morphCount = cd::Vec4f{ static_cast(pBlendShapeComponent->GetActiveMorphCount()),static_cast(pBlendShapeComponent->GetMeshVertexCount()),0,0}; GetRenderContext()->FillUniform(morphCountVertexCountCrc, &morphCount, 1); - bgfx::dispatch(GetViewID(), GetRenderContext()->GetProgram(blendShapeWeightsProgram),1U,1U,1U); - + GetRenderContext()->Dispatch(viewId, BlendShapeWeightsProgram, 1U, 1U, 1U); + bgfx::setBuffer(BS_MORPH_AFFECTED_STAGE, bgfx::VertexBufferHandle{pBlendShapeComponent->GetMorphAffectedVB()}, bgfx::Access::Read); bgfx::setBuffer(BS_FINAL_MORPH_AFFECTED_STAGE, bgfx::DynamicVertexBufferHandle{pBlendShapeComponent->GetFinalMorphAffectedVB()}, bgfx::Access::ReadWrite); GetRenderContext()->FillUniform(morphCountVertexCountCrc, &morphCount, 1); - bgfx::dispatch(GetViewID(), GetRenderContext()->GetProgram(blendShapeWeightPosProgram),1U, 1U, 1U); - + GetRenderContext()->Dispatch(viewId, BlendShapeWeightPosProgram, 1U, 1U, 1U); + bgfx::setBuffer(BS_FINAL_MORPH_AFFECTED_STAGE, bgfx::DynamicVertexBufferHandle{pBlendShapeComponent->GetFinalMorphAffectedVB()}, bgfx::Access::ReadWrite); bgfx::setBuffer(BS_ALL_MORPH_VERTEX_ID_STAGE, bgfx::IndexBufferHandle{pBlendShapeComponent->GetAllMorphVertexIDIB()}, bgfx::Access::Read); bgfx::setBuffer(BS_ACTIVE_MORPH_DATA_STAGE, bgfx::DynamicIndexBufferHandle{pBlendShapeComponent->GetActiveMorphOffestLengthWeightIB()}, bgfx::Access::Read); GetRenderContext()->FillUniform(morphCountVertexCountCrc, &morphCount, 1); - bgfx::dispatch(GetViewID(), GetRenderContext()->GetProgram(blendShapeFinalPosProgram)); + GetRenderContext()->Dispatch(viewId, BlendShapeFinalPosProgram, 1U, 1U, 1U); + pBlendShapeComponent->SetDirty(false); } if(pBlendShapeComponent->NeedUpdate()) @@ -175,7 +191,8 @@ void BlendShapeRenderer::Render(float deltaTime) //constexpr StringCrc changedWeightCrc(changedWeight); //cd::Vec4f changedWeightData = cd::Vec4f{ static_cast(pBlendShapeComponent->GetUpdatedWeight()),0,0,0 }; //GetRenderContext()->FillUniform(changedWeightCrc, &changedWeightData, 1); - bgfx::dispatch(GetViewID(), GetRenderContext()->GetProgram(blendShapeUpdatePosProgram)); + GetRenderContext()->Dispatch(viewId, BlendShapeUpdatePosProgram, 1U, 1U, 1U); + pBlendShapeComponent->ClearNeedUpdate(); } @@ -202,8 +219,6 @@ void BlendShapeRenderer::Render(float deltaTime) // Sky SkyType crtSkyType = pSkyComponent->GetSkyType(); - pMaterialComponent->SetSkyType(crtSkyType); - if (SkyType::SkyBox == crtSkyType) { // Create a new TextureHandle each frame if the skybox texture path has been updated, @@ -283,7 +298,7 @@ void BlendShapeRenderer::Render(float deltaTime) bgfx::setState(state); - bgfx::submit(GetViewID(), bgfx::ProgramHandle{pMaterialComponent->GetShadreProgram()}); + GetRenderContext()->Submit(viewId, "WorldProgram", pMaterialComponent->GetFeaturesCombine()); } } diff --git a/Engine/Source/Runtime/Rendering/BlendShapeRenderer.h b/Engine/Source/Runtime/Rendering/BlendShapeRenderer.h index 3b7a258a..ec748963 100644 --- a/Engine/Source/Runtime/Rendering/BlendShapeRenderer.h +++ b/Engine/Source/Runtime/Rendering/BlendShapeRenderer.h @@ -13,6 +13,7 @@ class BlendShapeRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.cpp b/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.cpp index a7c67657..18d255a2 100644 --- a/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.cpp +++ b/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.cpp @@ -1,6 +1,6 @@ #include "BlitRenderTargetPass.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" namespace engine { @@ -14,6 +14,10 @@ BlitRenderTargetPass::~BlitRenderTargetPass() { } +void BlitRenderTargetPass::Warmup() +{ +} + void BlitRenderTargetPass::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { } diff --git a/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.h b/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.h index e74c4868..410ddd58 100644 --- a/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.h +++ b/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.h @@ -12,6 +12,7 @@ class BlitRenderTargetPass final : public Renderer virtual ~BlitRenderTargetPass(); virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Rendering/BloomRenderer.cpp b/Engine/Source/Runtime/Rendering/BloomRenderer.cpp index 66bd869d..519f2622 100644 --- a/Engine/Source/Runtime/Rendering/BloomRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/BloomRenderer.cpp @@ -1,289 +1,336 @@ #include "BloomRenderer.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" namespace engine { - void BloomRenderer::Init(){ - GetRenderContext()->CreateUniform("s_texture", bgfx::UniformType::Sampler); - GetRenderContext()->CreateUniform("s_bloom", bgfx::UniformType::Sampler); - GetRenderContext()->CreateUniform("s_lightingColor", bgfx::UniformType::Sampler); - GetRenderContext()->CreateUniform("u_textureSize", bgfx::UniformType::Vec4); - GetRenderContext()->CreateUniform("u_bloomIntensity", bgfx::UniformType::Vec4); - GetRenderContext()->CreateUniform("u_luminanceThreshold", bgfx::UniformType::Vec4); - GetRenderContext()->CreateProgram("CapTureBrightnessProgram", "vs_fullscreen.bin", "fs_captureBrightness.bin"); - GetRenderContext()->CreateProgram("DownSampleProgram", "vs_fullscreen.bin", "fs_dowmsample.bin"); - GetRenderContext()->CreateProgram("BlurVerticalProgram", "vs_fullscreen.bin", "fs_blurvertical.bin"); - GetRenderContext()->CreateProgram("BlurHorizontalProgram", "vs_fullscreen.bin", "fs_blurhorizontal.bin"); - GetRenderContext()->CreateProgram("UpSampleProgram", "vs_fullscreen.bin", "fs_upsample.bin"); - GetRenderContext()->CreateProgram("KawaseBlurProgram", "vs_fullscreen.bin", "fs_kawaseblur.bin"); - GetRenderContext()->CreateProgram("CombineProgram", "vs_fullscreen.bin", "fs_bloom.bin"); - - bgfx::setViewName(GetViewID(), "BloomRenderer"); - - for (int i = 0; i < TEX_CHAIN_LEN; i++) m_sampleChainFB[i] = BGFX_INVALID_HANDLE; - for (int i = 0; i < 2; i++) m_blurChainFB[i] = BGFX_INVALID_HANDLE; - m_combineFB = BGFX_INVALID_HANDLE; - - start_dowmSamplePassID = GetRenderContext()->CreateView(); - for (int i = 0; i < TEX_CHAIN_LEN - 2; i++) GetRenderContext()->CreateView(); - start_verticalBlurPassID = GetRenderContext()->CreateView(); - start_horizontalBlurPassID = GetRenderContext()->CreateView(); - for (int i = 0; i < 40 - 2; i++) GetRenderContext()->CreateView(); - start_upSamplePassID = GetRenderContext()->CreateView(); - for (int i = 0; i < TEX_CHAIN_LEN - 2; i++) GetRenderContext()->CreateView(); - combinePassID = GetRenderContext()->CreateView(); - blit_colorPassID = GetRenderContext()->CreateView(); - } - BloomRenderer::~BloomRenderer() +void BloomRenderer::Init() +{ + constexpr StringCrc CapTureBrightnessProgramCrc = StringCrc("CapTureBrightnessProgram"); + constexpr StringCrc DownSampleProgramCrc = StringCrc("DownSampleProgram"); + constexpr StringCrc BlurVerticalProgramCrc = StringCrc("BlurVerticalProgram"); + constexpr StringCrc BlurHorizontalProgramCrc = StringCrc("BlurHorizontalProgram"); + constexpr StringCrc UpSampleProgramCrc = StringCrc("UpSampleProgram"); + constexpr StringCrc KawaseBlurProgramCrc = StringCrc("KawaseBlurProgram"); + constexpr StringCrc CombineProgramCrc = StringCrc("CombineProgram"); + + GetRenderContext()->RegisterShaderProgram(CapTureBrightnessProgramCrc, { "vs_fullscreen", "fs_captureBrightness" }); + GetRenderContext()->RegisterShaderProgram(DownSampleProgramCrc, { "vs_fullscreen", "fs_dowmsample" }); + GetRenderContext()->RegisterShaderProgram(BlurVerticalProgramCrc, { "vs_fullscreen", "fs_blurvertical" }); + GetRenderContext()->RegisterShaderProgram(BlurHorizontalProgramCrc, { "vs_fullscreen", "fs_blurhorizontal" }); + GetRenderContext()->RegisterShaderProgram(UpSampleProgramCrc, { "vs_fullscreen", "fs_upsample" }); + GetRenderContext()->RegisterShaderProgram(KawaseBlurProgramCrc, { "vs_fullscreen", "fs_kawaseblur" }); + GetRenderContext()->RegisterShaderProgram(CombineProgramCrc, { "vs_fullscreen", "fs_bloom" }); + + bgfx::setViewName(GetViewID(), "BloomRenderer"); +} + +void BloomRenderer::Warmup() +{ + for (int i = 0; i < TEX_CHAIN_LEN; i++) { + m_sampleChainFB[i] = BGFX_INVALID_HANDLE; } - - void BloomRenderer::SetEnable(bool value) + for (int i = 0; i < 2; i++) { - Entity entity = m_pCurrentSceneWorld->GetMainCameraEntity(); - CameraComponent* pCameraComponent = m_pCurrentSceneWorld->GetCameraComponent(entity); - pCameraComponent->SetBloomEnable(value); + m_blurChainFB[i] = BGFX_INVALID_HANDLE; } - - bool BloomRenderer::IsEnable() const + m_combineFB = BGFX_INVALID_HANDLE; + m_startDowmSamplePassID = GetRenderContext()->CreateView(); + for (int i = 0; i < TEX_CHAIN_LEN - 2; i++) + { + GetRenderContext()->CreateView(); + } + m_startVerticalBlurPassID = GetRenderContext()->CreateView(); + m_startHorizontalBlurPassID = GetRenderContext()->CreateView(); + for (int i = 0; i < 40 - 2; i++) { - Entity entity = m_pCurrentSceneWorld->GetMainCameraEntity(); - CameraComponent* pCameraComponent = m_pCurrentSceneWorld->GetCameraComponent(entity); - return pCameraComponent->GetIsBloomEnable(); + GetRenderContext()->CreateView(); } + m_startUpSamplePassID = GetRenderContext()->CreateView(); + for (int i = 0; i < TEX_CHAIN_LEN - 2; i++) + { + GetRenderContext()->CreateView(); + } + m_combinePassID = GetRenderContext()->CreateView(); + m_blitColorPassID = GetRenderContext()->CreateView(); + + GetRenderContext()->CreateUniform("s_texture", bgfx::UniformType::Sampler); + GetRenderContext()->CreateUniform("s_bloom", bgfx::UniformType::Sampler); + GetRenderContext()->CreateUniform("s_lightingColor", bgfx::UniformType::Sampler); + GetRenderContext()->CreateUniform("u_textureSize", bgfx::UniformType::Vec4); + GetRenderContext()->CreateUniform("u_bloomIntensity", bgfx::UniformType::Vec4); + GetRenderContext()->CreateUniform("u_luminanceThreshold", bgfx::UniformType::Vec4); + + GetRenderContext()->UploadShaderProgram("CapTureBrightnessProgram"); + GetRenderContext()->UploadShaderProgram("DownSampleProgram"); + GetRenderContext()->UploadShaderProgram("BlurVerticalProgram"); + GetRenderContext()->UploadShaderProgram("BlurHorizontalProgram"); + GetRenderContext()->UploadShaderProgram("UpSampleProgram"); + GetRenderContext()->UploadShaderProgram("KawaseBlurProgram"); + GetRenderContext()->UploadShaderProgram("CombineProgram"); +} - void BloomRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) +void BloomRenderer::SetEnable(bool value) +{ + Entity entity = m_pCurrentSceneWorld->GetMainCameraEntity(); + CameraComponent* pCameraComponent = m_pCurrentSceneWorld->GetCameraComponent(entity); + pCameraComponent->SetBloomEnable(value); +} + +bool BloomRenderer::IsEnable() const +{ + Entity entity = m_pCurrentSceneWorld->GetMainCameraEntity(); + CameraComponent* pCameraComponent = m_pCurrentSceneWorld->GetCameraComponent(entity); + return pCameraComponent->GetIsBloomEnable(); +} + +void BloomRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) +{ + uint16_t tempW = 0; + uint16_t tempH = 0; + if (m_pRenderTarget) { - uint16_t tempW = 0; - uint16_t tempH = 0; - if (m_pRenderTarget) - { - tempW = GetRenderTarget()->GetWidth(); - tempH = GetRenderTarget()->GetHeight(); - } - else - { - assert(GetRenderContext()); - tempW = GetRenderContext()->GetBackBufferWidth(); - tempH = GetRenderContext()->GetBackBufferHeight(); - } + tempW = GetRenderTarget()->GetWidth(); + tempH = GetRenderTarget()->GetHeight(); + } + else + { + tempW = GetRenderContext()->GetBackBufferWidth(); + tempH = GetRenderContext()->GetBackBufferHeight(); + } - if (width != tempW || height != tempH) { - width = tempW; - height = tempH; + if (m_width != tempW || m_height != tempH) + { + m_width = tempW; + m_height = tempH; - const uint64_t tsFlags = 0 | BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP; - for (int ii = 0; ii < TEX_CHAIN_LEN; ++ii) + constexpr uint64_t tsFlags = 0 | BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP; + for (int ii = 0; ii < TEX_CHAIN_LEN; ++ii) + { + if (bgfx::isValid(m_sampleChainFB[ii])) { - if (bgfx::isValid(m_sampleChainFB[ii])) bgfx::destroy(m_sampleChainFB[ii]); - if ((height >> ii) < 2 || (width >> ii) < 2) break; - m_sampleChainFB[ii] = bgfx::createFrameBuffer(width >> ii, height >> ii, bgfx::TextureFormat::RGBA32F, tsFlags); + bgfx::destroy(m_sampleChainFB[ii]); } - - m_combineFB = bgfx::createFrameBuffer(width, height, bgfx::TextureFormat::RGBA32F, tsFlags); + if ((m_height >> ii) < 2 || (m_width >> ii) < 2) + { + break; + } + m_sampleChainFB[ii] = bgfx::createFrameBuffer(m_width >> ii, m_height >> ii, bgfx::TextureFormat::RGBA32F, tsFlags); } + + m_combineFB = bgfx::createFrameBuffer(m_width, m_height, bgfx::TextureFormat::RGBA32F, tsFlags); } +} + +void BloomRenderer::Render(float deltaTime) +{ + constexpr StringCrc sceneRenderTarget("SceneRenderTarget"); - void BloomRenderer::Render(float deltaTime) + const RenderTarget* pInputRT = GetRenderContext()->GetRenderTarget(sceneRenderTarget); + const RenderTarget* pOutputRT = GetRenderTarget(); + + bgfx::TextureHandle screenEmissColorTextureHandle; + bgfx::TextureHandle screenTextureHandle; + if (pInputRT == pOutputRT) { - constexpr StringCrc sceneRenderTarget("SceneRenderTarget"); + constexpr StringCrc sceneRenderTargetBlitSRV("SceneRenderTargetBlitSRV"); + screenTextureHandle = GetRenderContext()->GetTexture(sceneRenderTargetBlitSRV); - const RenderTarget* pInputRT = GetRenderContext()->GetRenderTarget(sceneRenderTarget); - const RenderTarget* pOutputRT = GetRenderTarget(); + constexpr StringCrc sceneRenderTargetBlitEmissColor("SceneRenderTargetBlitEmissColor"); + screenEmissColorTextureHandle = GetRenderContext()->GetTexture(sceneRenderTargetBlitEmissColor); + } + else + { + screenTextureHandle = pInputRT->GetTextureHandle(0); + screenEmissColorTextureHandle = pInputRT->GetTextureHandle(1); + } - bgfx::TextureHandle screenEmissColorTextureHandle; - bgfx::TextureHandle screenTextureHandle; - if (pInputRT == pOutputRT) - { - constexpr StringCrc sceneRenderTargetBlitSRV("SceneRenderTargetBlitSRV"); - screenTextureHandle = GetRenderContext()->GetTexture(sceneRenderTargetBlitSRV); + Entity entity = m_pCurrentSceneWorld->GetMainCameraEntity(); + CameraComponent* pCameraComponent = m_pCurrentSceneWorld->GetCameraComponent(entity); - constexpr StringCrc sceneRenderTargetBlitEmissColor("SceneRenderTargetBlitEmissColor"); - screenEmissColorTextureHandle = GetRenderContext()->GetTexture(sceneRenderTargetBlitEmissColor); - } - else - { - screenTextureHandle = pInputRT->GetTextureHandle(0); - screenEmissColorTextureHandle = pInputRT->GetTextureHandle(1); - } + cd::Matrix4x4 orthoMatrix = cd::Matrix4x4::Orthographic(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1000.0f, 0.0f, bgfx::getCaps()->homogeneousDepth); - Entity entity = m_pCurrentSceneWorld->GetMainCameraEntity(); - CameraComponent* pCameraComponent = m_pCurrentSceneWorld->GetCameraComponent(entity); + // capture + bgfx::setViewFrameBuffer(GetViewID(), m_sampleChainFB[0]); + bgfx::setViewRect(GetViewID(), 0, 0, m_width, m_height); + bgfx::setViewTransform(GetViewID(), nullptr, orthoMatrix.Begin()); - cd::Matrix4x4 orthoMatrix = cd::Matrix4x4::Orthographic(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1000.0f, 0.0f, bgfx::getCaps()->homogeneousDepth); + constexpr StringCrc luminanceThresholdUniformName("u_luminanceThreshold"); + bgfx::setUniform(GetRenderContext()->GetUniform(luminanceThresholdUniformName), &pCameraComponent->GetLuminanceThreshold()); - //capture - bgfx::setViewFrameBuffer(GetViewID(), m_sampleChainFB[0]); - bgfx::setViewRect(GetViewID(), 0, 0, width, height); - bgfx::setViewTransform(GetViewID(), nullptr, orthoMatrix.Begin()); + constexpr StringCrc textureSampler("s_texture"); + bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), screenEmissColorTextureHandle); - constexpr StringCrc luminanceThresholdUniformName("u_luminanceThreshold"); - bgfx::setUniform(GetRenderContext()->GetUniform(luminanceThresholdUniformName), &pCameraComponent->GetLuminanceThreshold()); + bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); + Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - constexpr StringCrc textureSampler("s_texture"); - bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), screenEmissColorTextureHandle); + GetRenderContext()->Submit(GetViewID(), "CapTureBrightnessProgram"); - bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); - Renderer::ScreenSpaceQuad(GetRenderTarget(), false); + // downsample + int sampleTimes = int(pCameraComponent->GetBloomDownSampleTimes()); + int tempshift = 0; + for (int i = 0; i < sampleTimes; ++i) + { + int shift = i + 1; + if ((m_width >> shift) < 2 || (m_height >> shift) < 2) + { + break; + } - constexpr StringCrc CaptureBrightnessprogramName("CapTureBrightnessProgram"); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(CaptureBrightnessprogramName)); - - // downsample - int sampleTimes = int(pCameraComponent->GetBloomDownSampleTimes()); - int tempshift = 0; - for (int i = 0; i < sampleTimes; ++i) { - int shift = i + 1; - if ((width >> shift) < 2 || (height >> shift) < 2) break; - tempshift = shift; - const float pixelSize[4] = - { - 1.0f / static_cast(width >> shift), - 1.0f / static_cast(height >> shift), - 0.0f, - 0.0f, - }; + tempshift = shift; + const float pixelSize[4] = + { + 1.0f / static_cast(m_width >> shift), + 1.0f / static_cast(m_height >> shift), + 0.0f, + 0.0f, + }; - bgfx::setViewFrameBuffer(start_dowmSamplePassID + i, m_sampleChainFB[shift]); - bgfx::setViewRect(start_dowmSamplePassID + i, 0, 0, width >> shift, height >> shift); - bgfx::setViewTransform(start_dowmSamplePassID + i, nullptr, orthoMatrix.Begin()); + bgfx::setViewFrameBuffer(m_startDowmSamplePassID + i, m_sampleChainFB[shift]); + bgfx::setViewRect(m_startDowmSamplePassID + i, 0, 0, m_width >> shift, m_height >> shift); + bgfx::setViewTransform(m_startDowmSamplePassID + i, nullptr, orthoMatrix.Begin()); - constexpr StringCrc textureSizeUniformName("u_textureSize"); - bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize); + constexpr StringCrc textureSizeUniformName("u_textureSize"); + bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize); - bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_sampleChainFB[shift - 1])); + bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_sampleChainFB[shift - 1])); - bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); - Renderer::ScreenSpaceQuad(GetRenderTarget(), false); + bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); + Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - constexpr StringCrc DownSampleprogramName("DownSampleProgram"); - bgfx::submit(start_dowmSamplePassID + i, GetRenderContext()->GetProgram(DownSampleprogramName)); - } + GetRenderContext()->Submit(m_startDowmSamplePassID + i, "DownSampleProgram"); + } + + if (pCameraComponent->GetIsBlurEnable() && pCameraComponent->GetBlurTimes() != 0) + { + Blur(m_width >> tempshift, m_height >> tempshift, pCameraComponent->GetBlurTimes(), pCameraComponent->GetBlurSize(), pCameraComponent->GetBlurScaling(), orthoMatrix, bgfx::getTexture(m_sampleChainFB[tempshift])); + } - if (pCameraComponent->GetIsBlurEnable() && pCameraComponent->GetBlurTimes() != 0) { - Blur(width >> tempshift, height >> tempshift, pCameraComponent->GetBlurTimes(), pCameraComponent->GetBlurSize(),pCameraComponent->GetBlurScaling(), orthoMatrix, bgfx::getTexture(m_sampleChainFB[tempshift])); + // upsample + for (int i = 0; i < sampleTimes; ++i) + { + int shift = sampleTimes - i - 1; + if ((m_width >> shift) < 2 || (m_height >> shift) < 2) + { + continue; } - // upsample - for (int i = 0; i < sampleTimes; ++i) { - int shift = sampleTimes - i - 1; - if ((width >> shift) < 2 || (height >> shift) < 2) continue; - const float pixelSize[4] = - { - 1.0f / static_cast(width >> shift), - 1.0f / static_cast(height >> shift), - 0.0f, - 0.0f, - }; + const float pixelSize[4] = + { + 1.0f / static_cast(m_width >> shift), + 1.0f / static_cast(m_height >> shift), + 0.0f, + 0.0f, + }; - bgfx::setViewFrameBuffer(start_upSamplePassID + i, m_sampleChainFB[shift]); - bgfx::setViewRect(start_upSamplePassID + i, 0, 0, width >> shift, height >> shift); - bgfx::setViewTransform(start_upSamplePassID + i, nullptr, orthoMatrix.Begin()); + bgfx::setViewFrameBuffer(m_startUpSamplePassID + i, m_sampleChainFB[shift]); + bgfx::setViewRect(m_startUpSamplePassID + i, 0, 0, m_width >> shift, m_height >> shift); + bgfx::setViewTransform(m_startUpSamplePassID + i, nullptr, orthoMatrix.Begin()); - constexpr StringCrc textureSizeUniformName("u_textureSize"); - bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize); + constexpr StringCrc textureSizeUniformName("u_textureSize"); + bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize); - constexpr StringCrc bloomIntensityUniformName("u_bloomIntensity"); - bgfx::setUniform(GetRenderContext()->GetUniform(bloomIntensityUniformName), &pCameraComponent->GetBloomIntensity()); + constexpr StringCrc bloomIntensityUniformName("u_bloomIntensity"); + bgfx::setUniform(GetRenderContext()->GetUniform(bloomIntensityUniformName), &pCameraComponent->GetBloomIntensity()); - if (pCameraComponent->GetIsBlurEnable() && pCameraComponent->GetBlurTimes() != 0 && 0 == i) - { - bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_blurChainFB[1])); - } - else - { - bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_sampleChainFB[shift + 1])); - } + if (pCameraComponent->GetIsBlurEnable() && pCameraComponent->GetBlurTimes() != 0 && 0 == i) + { + bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_blurChainFB[1])); + } + else + { + bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_sampleChainFB[shift + 1])); + } - bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_BLEND_ADD); - Renderer::ScreenSpaceQuad(GetRenderTarget(), false); + bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_BLEND_ADD); + Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - constexpr StringCrc UpSampleprogramName("UpSampleProgram"); - bgfx::submit(start_upSamplePassID + i, GetRenderContext()->GetProgram(UpSampleprogramName)); - } + GetRenderContext()->Submit(m_startUpSamplePassID + i, "UpSampleProgram"); + } - // combine - bgfx::setViewFrameBuffer(combinePassID, m_combineFB); - bgfx::setViewRect(combinePassID, 0, 0, width, height); - bgfx::setViewTransform(combinePassID, nullptr, orthoMatrix.Begin()); + // combine + bgfx::setViewFrameBuffer(m_combinePassID, m_combineFB); + bgfx::setViewRect(m_combinePassID, 0, 0, m_width, m_height); + bgfx::setViewTransform(m_combinePassID, nullptr, orthoMatrix.Begin()); - constexpr StringCrc lightColorSampler("s_lightingColor"); - bgfx::setTexture(0, GetRenderContext()->GetUniform(lightColorSampler), screenTextureHandle); + constexpr StringCrc lightColorSampler("s_lightingColor"); + bgfx::setTexture(0, GetRenderContext()->GetUniform(lightColorSampler), screenTextureHandle); - constexpr StringCrc bloomcolorSampler("s_bloom"); - bgfx::setTexture(1, GetRenderContext()->GetUniform(bloomcolorSampler), bgfx::getTexture(m_sampleChainFB[0])); + constexpr StringCrc bloomcolorSampler("s_bloom"); + bgfx::setTexture(1, GetRenderContext()->GetUniform(bloomcolorSampler), bgfx::getTexture(m_sampleChainFB[0])); - bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); - Renderer::ScreenSpaceQuad(GetRenderTarget(), false); + bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); + Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - constexpr StringCrc CombineprogramName("CombineProgram"); - bgfx::submit(combinePassID, GetRenderContext()->GetProgram(CombineprogramName)); + GetRenderContext()->Submit(m_combinePassID, "CombineProgram"); - bgfx::blit(blit_colorPassID, screenTextureHandle, 0, 0, bgfx::getTexture(m_combineFB)); - } + bgfx::blit(m_blitColorPassID, screenTextureHandle, 0, 0, bgfx::getTexture(m_combineFB)); +} - void BloomRenderer::Blur(uint16_t width, uint16_t height, int iteration,float blursize, int blurscaling,cd::Matrix4x4 ortho,bgfx::TextureHandle texture) +void BloomRenderer::Blur(uint16_t width, uint16_t height, int iteration, float blursize, int blurscaling, cd::Matrix4x4 ortho, bgfx::TextureHandle texture) +{ + width = static_cast(width / blurscaling); + height = static_cast(height / blurscaling); + + const uint64_t tsFlags = 0 | BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP; + for (int ii = 0; ii < 2; ++ii) { - width = static_cast(width / blurscaling); - height = static_cast(height / blurscaling); + if (bgfx::isValid(m_blurChainFB[ii])) bgfx::destroy(m_blurChainFB[ii]); + m_blurChainFB[ii] = bgfx::createFrameBuffer(width, height, bgfx::TextureFormat::RGBA32F, tsFlags); + } - const uint64_t tsFlags = 0 | BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP; - for (int ii = 0; ii < 2; ++ii) + uint16_t verticalViewID = m_startVerticalBlurPassID; + uint16_t horizontalViewID = m_startHorizontalBlurPassID; + for (int i = 0; i < iteration; i++) + { + float pixelSize[4] = { - if (bgfx::isValid(m_blurChainFB[ii])) bgfx::destroy(m_blurChainFB[ii]); - m_blurChainFB[ii] = bgfx::createFrameBuffer(width, height, bgfx::TextureFormat::RGBA32F, tsFlags); - } + 1.0f / static_cast(width), + 1.0f / static_cast(height), + static_cast(i / blurscaling) + blursize, /*i + blursize*/ + 1.0f, + }; - uint16_t vertical = start_verticalBlurPassID; - uint16_t horizontal = start_horizontalBlurPassID; - for (int i = 0; i < iteration; i++) { - float pixelSize[4] = - { - 1.0f / static_cast(width), - 1.0f / static_cast(height), - static_cast(i / blurscaling) + blursize, /*i + blursize*/ - 1.0f, - }; + bgfx::setViewFrameBuffer(verticalViewID, m_blurChainFB[0]); + bgfx::setViewRect(verticalViewID, 0, 0, width, height); + bgfx::setViewTransform(verticalViewID, nullptr, ortho.Begin()); - bgfx::setViewFrameBuffer(vertical, m_blurChainFB[0]); - bgfx::setViewRect(vertical, 0, 0, width, height); - bgfx::setViewTransform(vertical, nullptr, ortho.Begin()); + constexpr StringCrc textureSizeUniformName("u_textureSize"); + bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize); - constexpr StringCrc textureSizeUniformName("u_textureSize"); - bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize); + constexpr StringCrc textureSampler("s_texture"); + bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), i == 0 ? texture : bgfx::getTexture(m_blurChainFB[1])); - constexpr StringCrc textureSampler("s_texture"); - bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), i == 0 ? texture : bgfx::getTexture(m_blurChainFB[1])); + bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); + Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); - Renderer::ScreenSpaceQuad(GetRenderTarget(), false); + GetRenderContext()->Submit(verticalViewID, "KawaseBlurProgram"); - constexpr StringCrc kawaseBlurprogramName("KawaseBlurProgram"); - bgfx::submit(vertical, GetRenderContext()->GetProgram(kawaseBlurprogramName)); - //constexpr StringCrc BlurHorizontalprogramName("BlurVerticalProgram"); // use Gaussian Blur - //bgfx::submit(horizontal, GetRenderContext()->GetProgram(BlurHorizontalprogramName)); + //constexpr StringCrc BlurHorizontalprogramName("BlurVerticalProgram"); // use Gaussian Blur + //bgfx::submit(horizontal, GetRenderContext()->GetProgram(BlurHorizontalprogramName)); - // vertical - bgfx::setViewFrameBuffer(horizontal, m_blurChainFB[1]); - bgfx::setViewRect(horizontal, 0, 0, width, height); - bgfx::setViewTransform(horizontal, nullptr, ortho.Begin()); + // vertical + bgfx::setViewFrameBuffer(horizontalViewID, m_blurChainFB[1]); + bgfx::setViewRect(horizontalViewID, 0, 0, width, height); + bgfx::setViewTransform(horizontalViewID, nullptr, ortho.Begin()); - bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize); + bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize); - bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_blurChainFB[0])); + bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_blurChainFB[0])); - bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); - Renderer::ScreenSpaceQuad(GetRenderTarget(), false); + bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); + Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - bgfx::submit(horizontal, GetRenderContext()->GetProgram(kawaseBlurprogramName)); - //constexpr StringCrc BlurVerticalprogramName("BlurVerticalProgram"); // use Gaussian Blur - //bgfx::submit(horizontal, GetRenderContext()->GetProgram(BlurVerticalprogramName)); + GetRenderContext()->Submit(horizontalViewID, "KawaseBlurProgram"); - vertical += 2; - horizontal += 2; - } + //constexpr StringCrc BlurVerticalprogramName("BlurVerticalProgram"); // use Gaussian Blur + //bgfx::submit(horizontal, GetRenderContext()->GetProgram(BlurVerticalprogramName)); + + verticalViewID += 2; + horizontalViewID += 2; } +} } diff --git a/Engine/Source/Runtime/Rendering/BloomRenderer.h b/Engine/Source/Runtime/Rendering/BloomRenderer.h index 4caab85e..6180b504 100644 --- a/Engine/Source/Runtime/Rendering/BloomRenderer.h +++ b/Engine/Source/Runtime/Rendering/BloomRenderer.h @@ -14,9 +14,9 @@ namespace engine { public: using Renderer::Renderer; - virtual ~BloomRenderer(); virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; @@ -34,15 +34,15 @@ namespace engine bgfx::FrameBufferHandle m_sampleChainFB[TEX_CHAIN_LEN]; bgfx::FrameBufferHandle m_combineFB; - uint16_t width; - uint16_t height; + uint16_t m_width; + uint16_t m_height; - uint16_t start_dowmSamplePassID; - uint16_t start_verticalBlurPassID; - uint16_t start_horizontalBlurPassID; - uint16_t start_upSamplePassID; - uint16_t blit_colorPassID; - uint16_t combinePassID; + uint16_t m_startDowmSamplePassID; + uint16_t m_startVerticalBlurPassID; + uint16_t m_startHorizontalBlurPassID; + uint16_t m_startUpSamplePassID; + uint16_t m_blitColorPassID; + uint16_t m_combinePassID; }; } \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/ImGuiRenderer.cpp b/Engine/Source/Runtime/Rendering/ImGuiRenderer.cpp index a15ae350..d2c49258 100644 --- a/Engine/Source/Runtime/Rendering/ImGuiRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/ImGuiRenderer.cpp @@ -1,5 +1,6 @@ #include "ImGuiRenderer.h" +#include "Core/StringCrc.h" #include "Rendering/RenderContext.h" #include @@ -8,6 +9,14 @@ namespace engine { void ImGuiRenderer::Init() +{ + constexpr StringCrc programCrc = StringCrc("ImGuiProgram"); + GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_imgui", "fs_imgui" }); + + bgfx::setViewName(GetViewID(), "ImGuiRenderer"); +} + +void ImGuiRenderer::Warmup() { constexpr StringCrc imguiVertexLayoutName("imgui_vertex_layout"); if (0 == GetRenderContext()->GetVertexLayout(imguiVertexLayoutName).m_stride) @@ -22,13 +31,7 @@ void ImGuiRenderer::Init() } GetRenderContext()->CreateUniform("s_tex", bgfx::UniformType::Sampler); - GetRenderContext()->CreateProgram("ImGuiProgram", "vs_imgui.bin", "fs_imgui.bin"); - - bgfx::setViewName(GetViewID(), "ImGuiRenderer"); -} - -ImGuiRenderer::~ImGuiRenderer() -{ + GetRenderContext()->UploadShaderProgram("ImGuiProgram"); } void ImGuiRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -169,8 +172,7 @@ void ImGuiRenderer::Render(float deltaTime) pEncoder->setVertexBuffer(0, &vertexBuffer, cmd->VtxOffset, numVertices); pEncoder->setIndexBuffer(&indexBuffer, cmd->IdxOffset, cmd->ElemCount); - constexpr StringCrc imguiProgram("ImGuiProgram"); - pEncoder->submit(GetViewID(), GetRenderContext()->GetProgram(imguiProgram)); + pEncoder->submit(GetViewID(), GetRenderContext()->GetShaderProgramHandle("ImGuiProgram")); } } } diff --git a/Engine/Source/Runtime/Rendering/ImGuiRenderer.h b/Engine/Source/Runtime/Rendering/ImGuiRenderer.h index 047449b0..7ade340d 100644 --- a/Engine/Source/Runtime/Rendering/ImGuiRenderer.h +++ b/Engine/Source/Runtime/Rendering/ImGuiRenderer.h @@ -9,9 +9,9 @@ class ImGuiRenderer final : public engine::Renderer { public: using Renderer::Renderer; - virtual ~ImGuiRenderer(); virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; }; diff --git a/Engine/Source/Runtime/Rendering/PBRSkyRenderer.cpp b/Engine/Source/Runtime/Rendering/PBRSkyRenderer.cpp index 61e4dfb6..f0ad7558 100644 --- a/Engine/Source/Runtime/Rendering/PBRSkyRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/PBRSkyRenderer.cpp @@ -4,7 +4,7 @@ #include "ECWorld/SkyComponent.h" #include "Log/Log.h" #include "Math/Box.hpp" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" #include "Scene/Mesh.h" #include "Scene/VertexFormat.h" #include "U_AtmophericScattering.sh" @@ -49,18 +49,29 @@ constexpr uint16_t ScatteringOrders = 6; void PBRSkyRenderer::Init() { - SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); + constexpr StringCrc ProgramAtmosphericScatteringLUTCrc = StringCrc(ProgramAtmosphericScatteringLUT); + constexpr StringCrc ProgramSingleScatteringRayMarchingCrc = StringCrc(ProgramSingleScatteringRayMarching); + constexpr StringCrc ProgramComputeTransmittanceCrc = StringCrc(ProgramComputeTransmittance); + constexpr StringCrc ProgramComputeDirectIrradianceCrc = StringCrc(ProgramComputeDirectIrradiance); + constexpr StringCrc ProgramComputeSingleScatteringCrc = StringCrc(ProgramComputeSingleScattering); + constexpr StringCrc ProgramComputeScatteringDensityCrc = StringCrc(ProgramComputeScatteringDensity); + constexpr StringCrc ProgramComputeIndirectIrradianceCrc = StringCrc(ProgramComputeIndirectIrradiance); + constexpr StringCrc ProgramComputeMultipleScatteringCrc = StringCrc(ProgramComputeMultipleScattering); + + GetRenderContext()->RegisterShaderProgram(ProgramAtmosphericScatteringLUTCrc, { "vs_atmSkyBox", "fs_PrecomputedAtmosphericScattering_LUT" }); + GetRenderContext()->RegisterShaderProgram(ProgramSingleScatteringRayMarchingCrc, { "vs_atmSkyBox", "fs_SingleScattering_RayMarching" }); + GetRenderContext()->RegisterShaderProgram(ProgramComputeTransmittanceCrc, { "cs_ComputeTransmittance" }); + GetRenderContext()->RegisterShaderProgram(ProgramComputeDirectIrradianceCrc, { "cs_ComputeDirectIrradiance" }); + GetRenderContext()->RegisterShaderProgram(ProgramComputeSingleScatteringCrc, { "cs_ComputeSingleScattering" }); + GetRenderContext()->RegisterShaderProgram(ProgramComputeScatteringDensityCrc, { "cs_ComputeScatteringDensity" }); + GetRenderContext()->RegisterShaderProgram(ProgramComputeIndirectIrradianceCrc, { "cs_ComputeIndirectIrradiance" }); + GetRenderContext()->RegisterShaderProgram(ProgramComputeMultipleScatteringCrc, { "cs_ComputeMultipleScattering" }); - GetRenderContext()->CreateProgram(ProgramAtmosphericScatteringLUT, "vs_atmSkyBox.bin", "fs_PrecomputedAtmosphericScattering_LUT.bin"); - GetRenderContext()->CreateProgram(ProgramSingleScatteringRayMarching, "vs_atmSkyBox.bin", "fs_SingleScattering_RayMarching.bin"); - - GetRenderContext()->CreateProgram(ProgramComputeTransmittance, "cs_ComputeTransmittance.bin"); - GetRenderContext()->CreateProgram(ProgramComputeDirectIrradiance, "cs_ComputeDirectIrradiance.bin"); - GetRenderContext()->CreateProgram(ProgramComputeSingleScattering, "cs_ComputeSingleScattering.bin"); - GetRenderContext()->CreateProgram(ProgramComputeScatteringDensity, "cs_ComputeScatteringDensity.bin"); - GetRenderContext()->CreateProgram(ProgramComputeIndirectIrradiance, "cs_ComputeIndirectIrradiance.bin"); - GetRenderContext()->CreateProgram(ProgramComputeMultipleScattering, "cs_ComputeMultipleScattering.bin"); + bgfx::setViewName(GetViewID(), "PBRSkyRenderer"); +} +void PBRSkyRenderer::Warmup() +{ GetRenderContext()->CreateTexture(TextureTransmittance, TRANSMITTANCE_TEXTURE_WIDTH, TRANSMITTANCE_TEXTURE_HEIGHT, 1, bgfx::TextureFormat::RGBA32F, FlagTexture2D); GetRenderContext()->CreateTexture(TextureIrradiance, IRRADIANCE_TEXTURE_WIDTH, IRRADIANCE_TEXTURE_HEIGHT, 1, @@ -83,7 +94,15 @@ void PBRSkyRenderer::Init() GetRenderContext()->CreateUniform(HeightOffset, bgfx::UniformType::Enum::Vec4, 1); GetRenderContext()->CreateUniform(NumScatteringOrders, bgfx::UniformType::Enum::Vec4, 1); - bgfx::setViewName(GetViewID(), "PBRSkyRenderer"); + GetRenderContext()->UploadShaderProgram(ProgramAtmosphericScatteringLUT); + GetRenderContext()->UploadShaderProgram(ProgramSingleScatteringRayMarching); + + GetRenderContext()->UploadShaderProgram(ProgramComputeTransmittance); + GetRenderContext()->UploadShaderProgram(ProgramComputeDirectIrradiance); + GetRenderContext()->UploadShaderProgram(ProgramComputeSingleScattering); + GetRenderContext()->UploadShaderProgram(ProgramComputeScatteringDensity); + GetRenderContext()->UploadShaderProgram(ProgramComputeIndirectIrradiance); + GetRenderContext()->UploadShaderProgram(ProgramComputeMultipleScattering); } void PBRSkyRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -146,8 +165,7 @@ void PBRSkyRenderer::Render(float deltaTime) GetRenderContext()->FillUniform(HeightOffsetCrc, &(tmpHeightOffset.x()), 1); bgfx::setState(StateRendering); - constexpr StringCrc ProgramAtmosphericScatteringLUTCrc(ProgramAtmosphericScatteringLUT); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(ProgramAtmosphericScatteringLUTCrc)); + GetRenderContext()->Submit(GetViewID(), ProgramAtmosphericScatteringLUT); } bool PBRSkyRenderer::IsEnable() const @@ -180,20 +198,20 @@ void PBRSkyRenderer::Precompute() const // Compute Transmittance. bgfx::setImage(0, GetRenderContext()->GetTexture(TextureTransmittanceCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); - bgfx::dispatch(viewId, GetRenderContext()->GetProgram(ProgramComputeTransmittanceCrc), TRANSMITTANCE_TEXTURE_WIDTH / 8U, TRANSMITTANCE_TEXTURE_HEIGHT / 8U, 1U); + GetRenderContext()->Dispatch(viewId, ProgramComputeTransmittance, TRANSMITTANCE_TEXTURE_WIDTH / 8U, TRANSMITTANCE_TEXTURE_HEIGHT / 8U, 1U); // Compute direct Irradiance. bgfx::setImage(ATM_TRANSMITTANCE_SLOT, GetRenderContext()->GetTexture(TextureTransmittanceCrc), 0, bgfx::Access::Read, bgfx::TextureFormat::RGBA32F); bgfx::setImage(0, GetRenderContext()->GetTexture(TextureDeltaIrradianceCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); bgfx::setImage(1, GetRenderContext()->GetTexture(TextureIrradianceCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); - bgfx::dispatch(viewId, GetRenderContext()->GetProgram(ProgramComputeDirectIrradianceCrc), IRRADIANCE_TEXTURE_WIDTH / 8U, IRRADIANCE_TEXTURE_HEIGHT / 8U, 1U); + GetRenderContext()->Dispatch(viewId, ProgramComputeDirectIrradiance, IRRADIANCE_TEXTURE_WIDTH / 8U, IRRADIANCE_TEXTURE_HEIGHT / 8U, 1U); // Compute single Scattering. bgfx::setImage(ATM_TRANSMITTANCE_SLOT, GetRenderContext()->GetTexture(TextureTransmittanceCrc), 0, bgfx::Access::Read, bgfx::TextureFormat::RGBA32F); bgfx::setImage(0, GetRenderContext()->GetTexture(TextureDeltaRayleighScatteringCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); bgfx::setImage(1, GetRenderContext()->GetTexture(TextureDeltaMieScatteringCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); bgfx::setImage(2, GetRenderContext()->GetTexture(TextureScatteringCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); - bgfx::dispatch(viewId, GetRenderContext()->GetProgram(ProgramComputeSingleScatteringCrc), SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); + GetRenderContext()->Dispatch(viewId, ProgramComputeSingleScattering, SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); // Compute multiple Scattering. cd::Vec4f tmpOrder; @@ -209,7 +227,7 @@ void PBRSkyRenderer::Precompute() const bgfx::setImage(ATM_MULTIPLE_SCATTERING_SLOT, GetRenderContext()->GetTexture(TextureDeltaMultipleScatteringCrc), 0, bgfx::Access::Read, bgfx::TextureFormat::RGBA32F); bgfx::setImage(ATM_IRRADIANCE_SLOT, GetRenderContext()->GetTexture(TextureDeltaIrradianceCrc), 0, bgfx::Access::Read, bgfx::TextureFormat::RGBA32F); bgfx::setImage(0, GetRenderContext()->GetTexture(TextureDeltaScatteringDensityCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); - bgfx::dispatch(viewId, GetRenderContext()->GetProgram(ProgramComputeScatteringDensityCrc), SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); + GetRenderContext()->Dispatch(viewId, ProgramComputeScatteringDensity, SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); // 2. Compute indirect Irradiance. tmpOrder.x() = static_cast(order - 1); @@ -220,14 +238,14 @@ void PBRSkyRenderer::Precompute() const bgfx::setImage(ATM_MULTIPLE_SCATTERING_SLOT, GetRenderContext()->GetTexture(TextureDeltaMultipleScatteringCrc), 0, bgfx::Access::Read, bgfx::TextureFormat::RGBA32F); bgfx::setImage(0, GetRenderContext()->GetTexture(TextureDeltaIrradianceCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); bgfx::setImage(1, GetRenderContext()->GetTexture(TextureIrradianceCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); - bgfx::dispatch(viewId, GetRenderContext()->GetProgram(ProgramComputeIndirectIrradianceCrc), IRRADIANCE_TEXTURE_WIDTH / 8U, IRRADIANCE_TEXTURE_HEIGHT / 8U, 1U); + GetRenderContext()->Dispatch(viewId, ProgramComputeIndirectIrradiance, IRRADIANCE_TEXTURE_WIDTH / 8U, IRRADIANCE_TEXTURE_HEIGHT / 8U, 1U); // 3. Compute multiple Scattering. bgfx::setImage(ATM_TRANSMITTANCE_SLOT, GetRenderContext()->GetTexture(TextureTransmittanceCrc), 0, bgfx::Access::Read, bgfx::TextureFormat::RGBA32F); bgfx::setImage(ATM_SCATTERING_DENSITY, GetRenderContext()->GetTexture(TextureDeltaScatteringDensityCrc), 0, bgfx::Access::Read, bgfx::TextureFormat::RGBA32F); bgfx::setImage(0, GetRenderContext()->GetTexture(TextureDeltaMultipleScatteringCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); bgfx::setImage(1, GetRenderContext()->GetTexture(TextureScatteringCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); - bgfx::dispatch(viewId, GetRenderContext()->GetProgram(ProgramComputeMultipleScatteringCrc), SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); + GetRenderContext()->Dispatch(viewId, ProgramComputeMultipleScattering, SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); } CD_ENGINE_TRACE("All compute shaders for precomputing atmospheric scattering texture dispatched."); @@ -238,11 +256,11 @@ void PBRSkyRenderer::Precompute() const skyComponent->SetATMIrradianceCrc(TextureIrradianceCrc); skyComponent->SetATMScatteringCrc(TextureScatteringCrc); - GetRenderContext()->Destory(TextureDeltaIrradianceCrc); - GetRenderContext()->Destory(TextureDeltaRayleighScatteringCrc); - GetRenderContext()->Destory(TextureDeltaMieScatteringCrc); - GetRenderContext()->Destory(TextureDeltaScatteringDensityCrc); - GetRenderContext()->Destory(TextureDeltaMultipleScatteringCrc); + GetRenderContext()->DestoryTexture(TextureDeltaIrradianceCrc); + GetRenderContext()->DestoryTexture(TextureDeltaRayleighScatteringCrc); + GetRenderContext()->DestoryTexture(TextureDeltaMieScatteringCrc); + GetRenderContext()->DestoryTexture(TextureDeltaScatteringDensityCrc); + GetRenderContext()->DestoryTexture(TextureDeltaMultipleScatteringCrc); } } \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/PBRSkyRenderer.h b/Engine/Source/Runtime/Rendering/PBRSkyRenderer.h index 380e5620..f16870c5 100644 --- a/Engine/Source/Runtime/Rendering/PBRSkyRenderer.h +++ b/Engine/Source/Runtime/Rendering/PBRSkyRenderer.h @@ -15,6 +15,7 @@ class PBRSkyRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; virtual bool IsEnable() const override; diff --git a/Engine/Source/Runtime/Rendering/ParticleRenderer.cpp b/Engine/Source/Runtime/Rendering/ParticleRenderer.cpp index a9e14364..c0c42474 100644 --- a/Engine/Source/Runtime/Rendering/ParticleRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/ParticleRenderer.cpp @@ -3,7 +3,7 @@ #include "ECWorld/CameraComponent.h" #include "ECWorld/SceneWorld.h" #include "ECWorld/TransformComponent.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" namespace engine { @@ -12,6 +12,11 @@ void ParticleRenderer::Init() bgfx::setViewName(GetViewID(), "ParticleRenderer"); } +void ParticleRenderer::Warmup() +{ + +} + void ParticleRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { UpdateViewRenderTarget(); diff --git a/Engine/Source/Runtime/Rendering/ParticleRenderer.h b/Engine/Source/Runtime/Rendering/ParticleRenderer.h index 507604e0..36e8e277 100644 --- a/Engine/Source/Runtime/Rendering/ParticleRenderer.h +++ b/Engine/Source/Runtime/Rendering/ParticleRenderer.h @@ -13,6 +13,7 @@ class ParticleRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Rendering/PostProcessRenderer.cpp b/Engine/Source/Runtime/Rendering/PostProcessRenderer.cpp index aa68aa30..f5c4e949 100644 --- a/Engine/Source/Runtime/Rendering/PostProcessRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/PostProcessRenderer.cpp @@ -1,21 +1,31 @@ #include "PostProcessRenderer.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" namespace engine { +namespace +{ + +constexpr const char *PostProcessProgram = "PostProcessProgram"; +constexpr StringCrc PostProcessProgramCrc = StringCrc(PostProcessProgram); + +} + void PostProcessRenderer::Init() { - GetRenderContext()->CreateUniform("s_lightingColor", bgfx::UniformType::Sampler); - GetRenderContext()->CreateUniform("u_postProcessingParams", bgfx::UniformType::Vec4); - GetRenderContext()->CreateProgram("PostProcessProgram", "vs_fullscreen.bin", "fs_PBR_postProcessing.bin"); + GetRenderContext()->RegisterShaderProgram(PostProcessProgramCrc, { "vs_fullscreen", "fs_PBR_postProcessing" }); bgfx::setViewName(GetViewID(), "PostProcessRenderer"); } -PostProcessRenderer::~PostProcessRenderer() +void PostProcessRenderer::Warmup() { + GetRenderContext()->CreateUniform("s_lightingColor", bgfx::UniformType::Sampler); + GetRenderContext()->CreateUniform("u_postProcessingParams", bgfx::UniformType::Vec4); + + GetRenderContext()->UploadShaderProgram(PostProcessProgram); } void PostProcessRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -60,8 +70,7 @@ void PostProcessRenderer::Render(float deltaTime) bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - constexpr StringCrc programName("PostProcessProgram"); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(programName)); + GetRenderContext()->Submit(GetViewID(), PostProcessProgram); } } \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/PostProcessRenderer.h b/Engine/Source/Runtime/Rendering/PostProcessRenderer.h index 8a777491..9dffb805 100644 --- a/Engine/Source/Runtime/Rendering/PostProcessRenderer.h +++ b/Engine/Source/Runtime/Rendering/PostProcessRenderer.h @@ -10,9 +10,9 @@ class PostProcessRenderer final : public Renderer { public: using Renderer::Renderer; - virtual ~PostProcessRenderer(); virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Rendering/RenderContext.cpp b/Engine/Source/Runtime/Rendering/RenderContext.cpp index 586a2e42..590ba289 100644 --- a/Engine/Source/Runtime/Rendering/RenderContext.cpp +++ b/Engine/Source/Runtime/Rendering/RenderContext.cpp @@ -3,7 +3,10 @@ #include "Log/Log.h" #include "Path/Path.h" #include "Renderer.h" +#include "Rendering/ShaderCollections.h" +#include "Rendering/ShaderType.h" #include "Rendering/Utility/VertexLayoutUtility.h" +#include "Resources/ResourceLoader.h" #include #include @@ -31,17 +34,33 @@ static void imageReleaseCb(void* _ptr, void* _userData) bimg::imageFree(imageContainer); } -template -void DestoryImpl(engine::StringCrc resourceCrc, T& caches) +std::tuple IdentifyShaderTypes(const std::set& shaders) { - auto itResource = caches.find(resourceCrc.Value()); - if(itResource != caches.end()) + assert(shaders.size() <= 2); + std::tuple shadersTuple = { "", "", "" }; + for (const auto& name : shaders) { - assert(bgfx::isValid(itResource->second)); - bgfx::destroy(itResource->second); - caches.erase(itResource); + engine::ShaderType type = engine::GetShaderType(name); + if (engine::ShaderType::Vertex == type) + { + std::get<0>(shadersTuple) = name; + } + else if (engine::ShaderType::Fragment == type) + { + std::get<1>(shadersTuple) = name; + + } + else if (engine::ShaderType::Compute == type) + { + std::get<2>(shadersTuple) = name; + } + else + { + CD_ENGINE_WARN("Unknown shader type of {0}!", name); + } } -}; + return shadersTuple; +} } @@ -102,24 +121,24 @@ void RenderContext::Init(GraphicsBackend backend, void* hwnd) void RenderContext::Shutdown() { - for (auto it : m_programHandleCaches) + for (auto it : m_shaderHandles) { - bgfx::destroy(it.second); + bgfx::destroy(bgfx::ShaderHandle{ it.second }); } - for(auto it : m_shaderHandleCaches) + for (auto it : m_shaderProgramHandles) { - bgfx::destroy(it.second); + bgfx::destroy(bgfx::ProgramHandle{ it.second }); } - + for (auto it : m_textureHandleCaches) { - bgfx::destroy(it.second); + bgfx::destroy(bgfx::TextureHandle{ it.second }); } for (auto it : m_uniformHandleCaches) { - bgfx::destroy(it.second); + bgfx::destroy(bgfx::UniformHandle{ it.second }); } } @@ -127,6 +146,18 @@ void RenderContext::BeginFrame() { } +void RenderContext::Submit(uint16_t viewID, const std::string& programName, const std::string& featureCombine) +{ + assert(bgfx::isValid(GetShaderProgramHandle(programName, featureCombine))); + bgfx::submit(viewID, GetShaderProgramHandle(programName, featureCombine)); +} + +void RenderContext::Dispatch(uint16_t viewID, const std::string& programName, uint32_t numX, uint32_t numY, uint32_t numZ) +{ + assert(bgfx::isValid(GetShaderProgramHandle(programName))); + bgfx::dispatch(viewID, GetShaderProgramHandle(programName), numX, numY, numZ); +} + void RenderContext::EndFrame() { // Advance to next frame. Rendering thread will be kicked to @@ -147,6 +178,122 @@ uint16_t RenderContext::CreateView() return m_currentViewCount++; } +void RenderContext::RegisterShaderProgram(StringCrc programNameCrc, std::initializer_list names) +{ + m_pShaderCollections->RegisterShaderProgram(programNameCrc, cd::MoveTemp(names)); +} + +void RenderContext::AddShaderFeature(StringCrc programNameCrc, std::string combine) +{ + m_pShaderCollections->AddFeatureCombine(programNameCrc, cd::MoveTemp(combine)); +} + +bool RenderContext::CheckShaderProgram(const std::string& programName, const std::string& featuresCombine) +{ + assert(m_pShaderCollections->IsProgramValid(StringCrc(programName))); + + if (!bgfx::isValid(GetShaderProgramHandle(programName, featuresCombine))) + { + // Its only represents that we do not hold the shader program GPU handle, + // whether the shader is compiled or not is unknown. + // The Combile Task will still be added to the queue and ResourceBuilder ensures that + // there is no duplication of compilation behavior. + AddShaderCompileTask(ShaderCompileInfo(programName, featuresCombine)); + m_pShaderCollections->AddFeatureCombine(StringCrc(programName), featuresCombine); + return false; + } + return true; +} + +void RenderContext::UploadShaderProgram(const std::string& programName, const std::string& featuresCombine) +{ + assert(m_pShaderCollections->IsProgramValid(StringCrc(programName))); + + auto [vsName, fsName, csName] = IdentifyShaderTypes(m_pShaderCollections->GetShaders(StringCrc(programName))); + + if (featuresCombine.empty()) + { + // Non-uber shader case. + if (!vsName.empty() && !fsName.empty() && csName.empty()) + { + CreateProgram(programName, vsName.data(), fsName.data()); + } + else if (!csName.empty()) + { + CreateProgram(programName, csName.data()); + } + else + { + CD_ENGINE_WARN("Unknown non-uber shader program type of {0}!", programName); + } + } + else + { + // Uber shader case. + if (!vsName.empty() && !fsName.empty() && csName.empty()) + { + CreateProgram(programName, vsName.data(), fsName.data(), featuresCombine); + } + else + { + CD_ENGINE_WARN("Unknown uber shader program type of {0}!", programName); + } + } +} + +void RenderContext::AddShaderCompileTask(ShaderCompileInfo info) +{ + const auto& it = std::find(m_shaderCompileTasks.begin(), m_shaderCompileTasks.end(), info); + if (it == m_shaderCompileTasks.end()) + { + CD_ENGINE_INFO("Shader compile task added for {0} with shader features : [{1}]", info.m_programName, info.m_featuresCombine); + m_shaderCompileTasks.emplace_back(cd::MoveTemp(info)); + } +} + +void RenderContext::ClearShaderCompileTasks() +{ + m_shaderCompileTasks.clear(); +} + +void RenderContext::SetShaderCompileTasks(std::vector tasks) +{ + m_shaderCompileTasks = cd::MoveTemp(tasks); +} + +const RenderContext::ShaderBlob& RenderContext::AddShaderBlob(StringCrc shaderNameCrc, ShaderBlob blob) +{ + const auto& it = m_shaderBlobs.find(shaderNameCrc.Value()); + if (it != m_shaderBlobs.end()) + { + return *(it->second); + } + m_shaderBlobs[shaderNameCrc.Value()] = std::make_unique(cd::MoveTemp(blob)); + return *m_shaderBlobs.at(shaderNameCrc.Value()); +} + +const RenderContext::ShaderBlob& RenderContext::GetShaderBlob(StringCrc shaderNameCrc) const +{ + assert(m_shaderBlobs.find(shaderNameCrc.Value()) != m_shaderBlobs.end() && "Shader blob does not exist!"); + return *m_shaderBlobs.at(shaderNameCrc.Value()).get(); +} + +void RenderContext::SetShaderProgramHandle(const std::string& programName, bgfx::ProgramHandle handle, const std::string& featureCombine) +{ + m_shaderProgramHandles[StringCrc(programName + featureCombine).Value()] = handle.idx; +} + +bgfx::ProgramHandle RenderContext::GetShaderProgramHandle(const std::string& programName, const std::string& featureCombine) const +{ + const auto& it = m_shaderProgramHandles.find(StringCrc(programName + featureCombine).Value()); + if (it != m_shaderProgramHandles.end()) + { + return { it->second }; + } + + return { bgfx::kInvalidHandle }; +} + RenderTarget* RenderContext::CreateRenderTarget(StringCrc resourceCrc, uint16_t width, uint16_t height, std::vector attachmentDescs) { return CreateRenderTarget(resourceCrc, std::make_unique(width, height, std::move(attachmentDescs))); @@ -171,85 +318,69 @@ RenderTarget* RenderContext::CreateRenderTarget(StringCrc resourceCrc, std::uniq return m_renderTargetCaches[resourceCrc.Value()].get(); } -bgfx::ShaderHandle RenderContext::CreateShader(const char* pFilePath) +bgfx::ShaderHandle RenderContext::CreateShader(const char* pShaderName) { - StringCrc filePath(pFilePath); - auto itShaderCache = m_shaderHandleCaches.find(filePath.Value()); - if(itShaderCache != m_shaderHandleCaches.end()) - { - return itShaderCache->second; - } - - std::string shaderFileFullPath = Path::GetShaderOutputPath(pFilePath); - std::ifstream fin(shaderFileFullPath, std::ios::in | std::ios::binary); - if (!fin.is_open()) + StringCrc shaderNameCrc(pShaderName); + auto itShaderCache = m_shaderHandles.find(shaderNameCrc.Value()); + if(itShaderCache != m_shaderHandles.end()) { - return bgfx::ShaderHandle{bgfx::kInvalidHandle}; + return { itShaderCache->second }; } - fin.seekg(0L, std::ios::end); - size_t fileSize = fin.tellg(); - fin.seekg(0L, std::ios::beg); - uint8_t* pRawData = new uint8_t[fileSize]; - fin.read(reinterpret_cast(pRawData), fileSize); - fin.close(); - - const bgfx::Memory* pMemory = bgfx::makeRef(pRawData, static_cast(fileSize)); - bgfx::ShaderHandle handle = bgfx::createShader(pMemory); + std::string shaderFileFullPath = Path::GetShaderOutputPath(pShaderName); + const auto& shaderBlob = AddShaderBlob(shaderNameCrc, ResourceLoader::LoadFile(shaderFileFullPath.c_str())); + bgfx::ShaderHandle shaderHandle = bgfx::createShader(bgfx::makeRef(shaderBlob.data(), static_cast(shaderBlob.size()))); - if(bgfx::isValid(handle)) + if(bgfx::isValid(shaderHandle)) { - bgfx::setName(handle, pFilePath); - m_shaderHandleCaches[filePath.Value()] = handle; + bgfx::setName(shaderHandle, pShaderName); + m_shaderHandles[shaderNameCrc.Value()] = shaderHandle.idx; } - return handle; + return shaderHandle; } -bgfx::ProgramHandle RenderContext::CreateProgram(const char* pName, const char* pVSName, const char* pFSName) +bgfx::ProgramHandle RenderContext::CreateProgram(const std::string& programName, const std::string& csName) { - return CreateProgram(pName, CreateShader(pVSName), CreateShader(pFSName)); -} - -bgfx::ProgramHandle RenderContext::CreateProgram(const char* pName, bgfx::ShaderHandle vsh, bgfx::ShaderHandle fsh) -{ - StringCrc programName(pName); - auto itProgram = m_programHandleCaches.find(programName.Value()); - if (itProgram != m_programHandleCaches.end()) + StringCrc programNameCrc(programName); + auto itProgram = m_shaderProgramHandles.find(programNameCrc.Value()); + if (itProgram != m_shaderProgramHandles.end()) { - return itProgram->second; + return { itProgram->second }; } - bgfx::ProgramHandle program = bgfx::createProgram(vsh, fsh); - if(bgfx::isValid(program)) + bgfx::ProgramHandle programHandle = bgfx::createProgram(CreateShader(csName.c_str())); + if (bgfx::isValid(programHandle)) { - m_programHandleCaches[programName.Value()] = program; + m_shaderProgramHandles[programNameCrc.Value()] = programHandle.idx; } - return program; + return programHandle; } -bgfx::ProgramHandle RenderContext::CreateProgram(const char *pName, const char *pCSName) +bgfx::ProgramHandle RenderContext::CreateProgram(const std::string& programName, const std::string& vsName, const std::string& fsName, const std::string& featureCombine) { - return CreateProgram(pName, CreateShader(pCSName)); -} + StringCrc fullProgramNameCrc = StringCrc(programName + featureCombine); -bgfx::ProgramHandle RenderContext::CreateProgram(const char *pName, bgfx::ShaderHandle csh) -{ - StringCrc programName(pName); - auto itProgram = m_programHandleCaches.find(programName.Value()); - if (itProgram != m_programHandleCaches.end()) + const auto& it = m_shaderProgramHandles.find(fullProgramNameCrc.Value()); + if (it != m_shaderProgramHandles.end()) { - return itProgram->second; + return { it->second }; } - bgfx::ProgramHandle program = bgfx::createProgram(csh, true); - if (bgfx::isValid(program)) + std::string inputVSFilePath = engine::Path::GetBuiltinShaderInputPath(vsName.c_str()); + std::string outputFSFilePath = engine::Path::GetShaderOutputPath(fsName.c_str(), featureCombine); + + bgfx::ShaderHandle vsHandle = CreateShader(inputVSFilePath.c_str()); + bgfx::ShaderHandle fsHandle = CreateShader(outputFSFilePath.c_str()); + bgfx::ProgramHandle programHandle = bgfx::createProgram(vsHandle, fsHandle); + + if (bgfx::isValid(programHandle)) { - m_programHandleCaches[programName.Value()] = program; + m_shaderProgramHandles[fullProgramNameCrc.Value()] = programHandle.idx; } - return program; + return programHandle; } bgfx::TextureHandle RenderContext::CreateTexture(const char* pFilePath, uint64_t flags) @@ -258,10 +389,10 @@ bgfx::TextureHandle RenderContext::CreateTexture(const char* pFilePath, uint64_t auto itTextureCache = m_textureHandleCaches.find(filePath.Value()); if (itTextureCache != m_textureHandleCaches.end()) { - return itTextureCache->second; + return { itTextureCache->second }; } - //std::string textureFileFullPath = std::format("{}{}", CDPROJECT_RESOURCES_ROOT_PATH, pFilePath); + //std::string textureFileFullPath = std::format("{}{}", CDPROJECT_RESOURCES_ROOT_PATH, pShaderName); std::string textureFileFullPath = CDPROJECT_RESOURCES_ROOT_PATH; textureFileFullPath += pFilePath; std::ifstream fin(textureFileFullPath, std::ios::in | std::ios::binary); @@ -328,7 +459,7 @@ bgfx::TextureHandle RenderContext::CreateTexture(const char* pFilePath, uint64_t if (bgfx::isValid(handle)) { bgfx::setName(handle, pFilePath); - m_textureHandleCaches[filePath.Value()] = handle; + m_textureHandleCaches[filePath.Value()] = handle.idx; } return handle; @@ -340,7 +471,7 @@ bgfx::TextureHandle RenderContext::CreateTexture(const char* pName, uint16_t wid auto itTextureCache = m_textureHandleCaches.find(textureName.Value()); if(itTextureCache != m_textureHandleCaches.end()) { - return itTextureCache->second; + return { itTextureCache->second }; } const bgfx::Memory* mem = nullptr; @@ -363,7 +494,7 @@ bgfx::TextureHandle RenderContext::CreateTexture(const char* pName, uint16_t wid if(bgfx::isValid(texture)) { bgfx::setName(texture, pName); - m_textureHandleCaches[textureName.Value()] = texture; + m_textureHandleCaches[textureName.Value()] = texture.idx; } else { @@ -391,7 +522,7 @@ bgfx::TextureHandle RenderContext::UpdateTexture(const char* pName, uint16_t lay mem = bgfx::makeRef(data, size); } - handle = itTextureCache->second; + handle = { itTextureCache->second }; if (depth > 1) { bgfx::updateTexture3D(handle, mip, x, y, z, width, height, depth, mem); @@ -410,13 +541,13 @@ bgfx::UniformHandle RenderContext::CreateUniform(const char* pName, bgfx::Unifor auto itUniformCache = m_uniformHandleCaches.find(uniformName.Value()); if (itUniformCache != m_uniformHandleCaches.end()) { - return itUniformCache->second; + return { itUniformCache->second }; } bgfx::UniformHandle uniformHandle = bgfx::createUniform(pName, uniformType, number); if(bgfx::isValid(uniformHandle)) { - m_uniformHandleCaches[uniformName.Value()] = uniformHandle; + m_uniformHandleCaches[uniformName.Value()] = uniformHandle.idx; } return uniformHandle; @@ -457,12 +588,12 @@ void RenderContext::SetVertexLayout(StringCrc resourceCrc, bgfx::VertexLayout ve void RenderContext::SetTexture(StringCrc resourceCrc, bgfx::TextureHandle textureHandle) { - m_textureHandleCaches[resourceCrc.Value()] = std::move(textureHandle); + m_textureHandleCaches[resourceCrc.Value()] = textureHandle.idx; } void RenderContext::SetUniform(StringCrc resourceCrc, bgfx::UniformHandle uniformreHandle) { - m_uniformHandleCaches[resourceCrc.Value()] = std::move(uniformreHandle); + m_uniformHandleCaches[resourceCrc.Value()] = uniformreHandle.idx; } void RenderContext::FillUniform(StringCrc resourceCrc, const void *pData, uint16_t vec4Count) const @@ -495,24 +626,13 @@ const bgfx::VertexLayout& RenderContext::GetVertexLayout(StringCrc resourceCrc) bgfx::ShaderHandle RenderContext::GetShader(StringCrc resourceCrc) const { - auto itResource = m_shaderHandleCaches.find(resourceCrc.Value()); - if (itResource != m_shaderHandleCaches.end()) + auto itResource = m_shaderHandles.find(resourceCrc.Value()); + if (itResource != m_shaderHandles.end()) { - return itResource->second; + return { itResource->second }; } - return bgfx::ShaderHandle{bgfx::kInvalidHandle}; -} - -bgfx::ProgramHandle RenderContext::GetProgram(StringCrc resourceCrc) const -{ - auto itResource = m_programHandleCaches.find(resourceCrc.Value()); - if (itResource != m_programHandleCaches.end()) - { - return itResource->second; - } - - return bgfx::ProgramHandle{bgfx::kInvalidHandle}; + return bgfx::ShaderHandle{ bgfx::kInvalidHandle }; } bgfx::TextureHandle RenderContext::GetTexture(StringCrc resourceCrc) const @@ -520,10 +640,10 @@ bgfx::TextureHandle RenderContext::GetTexture(StringCrc resourceCrc) const auto itResource = m_textureHandleCaches.find(resourceCrc.Value()); if (itResource != m_textureHandleCaches.end()) { - return itResource->second; + return { itResource->second }; } - return bgfx::TextureHandle{bgfx::kInvalidHandle}; + return bgfx::TextureHandle{ bgfx::kInvalidHandle }; } bgfx::UniformHandle RenderContext::GetUniform(StringCrc resourceCrc) const @@ -531,23 +651,59 @@ bgfx::UniformHandle RenderContext::GetUniform(StringCrc resourceCrc) const auto itResource = m_uniformHandleCaches.find(resourceCrc.Value()); if (itResource != m_uniformHandleCaches.end()) { - return itResource->second; + return { itResource->second }; } - return bgfx::UniformHandle{bgfx::kInvalidHandle}; + return bgfx::UniformHandle{ bgfx::kInvalidHandle }; } -void RenderContext::Destory(StringCrc resourceCrc) +void RenderContext::DestoryRenderTarget(StringCrc resourceCrc) { - DestoryImpl(resourceCrc, m_shaderHandleCaches); - DestoryImpl(resourceCrc, m_programHandleCaches); - DestoryImpl(resourceCrc, m_textureHandleCaches); - DestoryImpl(resourceCrc, m_uniformHandleCaches); + m_renderTargetCaches.erase(resourceCrc.Value()); } -void RenderContext::DestoryRenderTarget(StringCrc resourceCrc) +void RenderContext::DestoryTexture(StringCrc resourceCrc) { - m_renderTargetCaches.erase(resourceCrc.Value()); + auto it = m_textureHandleCaches.find(resourceCrc.Value()); + if (it != m_textureHandleCaches.end()) + { + assert(bgfx::isValid(bgfx::TextureHandle{ it->second })); + bgfx::destroy(bgfx::TextureHandle{ it->second }); + m_textureHandleCaches.erase(it); + } +} + +void RenderContext::DestoryUniform(StringCrc resourceCrc) +{ + auto it = m_uniformHandleCaches.find(resourceCrc.Value()); + if (it != m_uniformHandleCaches.end()) + { + assert(bgfx::isValid(bgfx::UniformHandle{ it->second })); + bgfx::destroy(bgfx::UniformHandle{ it->second }); + m_uniformHandleCaches.erase(it); + } +} + +void RenderContext::DestoryShader(StringCrc resourceCrc) +{ + auto it = m_shaderHandles.find(resourceCrc.Value()); + if (it != m_shaderHandles.end()) + { + assert(bgfx::isValid(bgfx::ShaderHandle{ it->second })); + bgfx::destroy(bgfx::ShaderHandle{ it->second }); + m_shaderHandles.erase(it); + } +} + +void RenderContext::DestoryProgram(StringCrc resourceCrc) +{ + auto it = m_shaderProgramHandles.find(resourceCrc.Value()); + if (it != m_shaderProgramHandles.end()) + { + assert(bgfx::isValid(bgfx::ProgramHandle{ it->second })); + bgfx::destroy(bgfx::ProgramHandle{ it->second }); + m_shaderProgramHandles.erase(it); + } } } \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/RenderContext.h b/Engine/Source/Runtime/Rendering/RenderContext.h index 629ae74a..fe080d50 100644 --- a/Engine/Source/Runtime/Rendering/RenderContext.h +++ b/Engine/Source/Runtime/Rendering/RenderContext.h @@ -3,6 +3,7 @@ #include "Core/StringCrc.h" #include "Graphics/GraphicsBackend.h" #include "Math/Matrix.hpp" +#include "Rendering/ShaderCompileInfo.h" #include "RenderTarget.h" #include "Scene/VertexAttribute.h" #include "Scene/VertexFormat.h" @@ -10,7 +11,9 @@ #include #include +#include #include +#include #include namespace engine @@ -18,6 +21,7 @@ namespace engine class Camera; class Renderer; +class ShaderCollections; static constexpr uint8_t MaxViewCount = 255; static constexpr uint8_t MaxRenderTargetCount = 255; @@ -26,6 +30,9 @@ static constexpr uint8_t MaxRenderTargetCount = 255; // The reason is that it binds to bgfx graphics initialization which should only happen once. class RenderContext { +public: + using ShaderBlob = std::vector; + public: RenderContext() = default; RenderContext(const RenderContext&) = delete; @@ -37,6 +44,8 @@ class RenderContext void Init(GraphicsBackend backend, void* hwnd = nullptr); void OnResize(uint16_t width, uint16_t height); void BeginFrame(); + void Submit(uint16_t viewID, const std::string& programName, const std::string& featureCombine = ""); + void Dispatch(uint16_t viewID, const std::string& programName, uint32_t numX, uint32_t numY, uint32_t numZ); void EndFrame(); void Shutdown(); @@ -48,18 +57,44 @@ class RenderContext void ResetViewCount() { m_currentViewCount = 0; } uint16_t GetCurrentViewCount() const { return m_currentViewCount; } + ///////////////////////////////////////////////////////////////////// + // Shader collections apis + ///////////////////////////////////////////////////////////////////// + void SetShaderCollections(ShaderCollections* pShaderCollections) { m_pShaderCollections = pShaderCollections; } + const ShaderCollections* GetShaderCollections() const { return m_pShaderCollections; } + + void RegisterShaderProgram(StringCrc programNameCrc, std::initializer_list names); + void AddShaderFeature(StringCrc programNameCrc, std::string combine); + + bool CheckShaderProgram(const std::string& programName, const std::string& featuresCombine = ""); + void UploadShaderProgram(const std::string& programName, const std::string& featuresCombine = ""); + + void AddShaderCompileTask(ShaderCompileInfo info); + void ClearShaderCompileTasks(); + void SetShaderCompileTasks(std::vector tasks); + std::vector& GetShaderCompileTasks() { return m_shaderCompileTasks; } + const std::vector& GetShaderCompileTasks() const { return m_shaderCompileTasks; } + + ///////////////////////////////////////////////////////////////////// + // Shader blob apis + ///////////////////////////////////////////////////////////////////// + const RenderContext::ShaderBlob& AddShaderBlob(StringCrc shaderNameCrc, ShaderBlob blob); + const ShaderBlob& GetShaderBlob(StringCrc shaderNameCrc) const; + ///////////////////////////////////////////////////////////////////// // Resource related apis ///////////////////////////////////////////////////////////////////// + + void SetShaderProgramHandle(const std::string& programName, bgfx::ProgramHandle handle, const std::string& featureCombine = ""); + bgfx::ProgramHandle GetShaderProgramHandle(const std::string& programName, const std::string& featureCombine = "") const; + RenderTarget* CreateRenderTarget(StringCrc resourceCrc, uint16_t width, uint16_t height, std::vector attachmentDescs); RenderTarget* CreateRenderTarget(StringCrc resourceCrc, uint16_t width, uint16_t height, void* pWindowHandle); RenderTarget* CreateRenderTarget(StringCrc resourceCrc, std::unique_ptr pRenderTarget); bgfx::ShaderHandle CreateShader(const char* filePath); - bgfx::ProgramHandle CreateProgram(const char* pName, const char* pVSName, const char* pFSName); - bgfx::ProgramHandle CreateProgram(const char* pName, bgfx::ShaderHandle vsh, bgfx::ShaderHandle fsh); - bgfx::ProgramHandle CreateProgram(const char* pName, const char* pCSName); - bgfx::ProgramHandle CreateProgram(const char* pName, bgfx::ShaderHandle csh); + bgfx::ProgramHandle CreateProgram(const std::string& programName, const std::string& csName); + bgfx::ProgramHandle CreateProgram(const std::string& programName, const std::string& vsName, const std::string& fsName, const std::string& featureCombine = ""); bgfx::TextureHandle CreateTexture(const char* filePath, uint64_t flags = 0UL); bgfx::TextureHandle CreateTexture(const char* pName, uint16_t width, uint16_t height, uint16_t depth, bgfx::TextureFormat::Enum format, uint64_t flags = 0UL, const void* data = nullptr, uint32_t size = 0); @@ -77,24 +112,36 @@ class RenderContext RenderTarget* GetRenderTarget(StringCrc resourceCrc) const; const bgfx::VertexLayout& GetVertexLayout(StringCrc resourceCrc) const; bgfx::ShaderHandle GetShader(StringCrc resourceCrc) const; - bgfx::ProgramHandle GetProgram(StringCrc resourceCrc) const; bgfx::TextureHandle GetTexture(StringCrc resourceCrc) const; bgfx::UniformHandle GetUniform(StringCrc resourceCrc) const; - void Destory(StringCrc resourceCrc); void DestoryRenderTarget(StringCrc resourceCrc); + void DestoryTexture(StringCrc resourceCrc); + void DestoryUniform(StringCrc resourceCrc); + void DestoryShader(StringCrc resourceCrc); + void DestoryProgram(StringCrc resourceCrc); private: uint8_t m_currentViewCount = 0; - std::unordered_map> m_renderTargetCaches; - std::unordered_map m_vertexLayoutCaches; - std::unordered_map m_shaderHandleCaches; - std::unordered_map m_programHandleCaches; - std::unordered_map m_textureHandleCaches; - std::unordered_map m_uniformHandleCaches; - uint16_t m_backBufferWidth; uint16_t m_backBufferHeight; + + std::unordered_map> m_renderTargetCaches; + std::unordered_map m_vertexLayoutCaches; + std::unordered_map m_textureHandleCaches; + std::unordered_map m_uniformHandleCaches; + + ShaderCollections* m_pShaderCollections = nullptr; + + // Key : StringCrc(Program name), Value : Shader program handle + std::unordered_map m_shaderProgramHandles; + + // Key : StringCrc(Shader name), Value : Shader handle + std::unordered_map m_shaderHandles; + // Key : StringCrc(Shader name), Value : Shader binary data + std::unordered_map> m_shaderBlobs; + + std::vector m_shaderCompileTasks; }; } \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/Renderer.cpp b/Engine/Source/Runtime/Rendering/Renderer.cpp index 83edf1a2..89f232e9 100644 --- a/Engine/Source/Runtime/Rendering/Renderer.cpp +++ b/Engine/Source/Runtime/Rendering/Renderer.cpp @@ -1,8 +1,8 @@ #include "Renderer.h" #include "ECWorld/StaticMeshComponent.h" -#include "RenderContext.h" -#include "RenderTarget.h" +#include "Rendering/RenderContext.h" +#include "Rendering/RenderTarget.h" #include @@ -16,6 +16,7 @@ Renderer::Renderer(uint16_t viewID, RenderTarget* pRenderTarget) } static RenderContext* m_pRenderContext = nullptr; + void Renderer::SetRenderContext(RenderContext* pRenderContext) { m_pRenderContext = pRenderContext; diff --git a/Engine/Source/Runtime/Rendering/Renderer.h b/Engine/Source/Runtime/Rendering/Renderer.h index 2f3957c2..699503a6 100644 --- a/Engine/Source/Runtime/Rendering/Renderer.h +++ b/Engine/Source/Runtime/Rendering/Renderer.h @@ -8,6 +8,7 @@ namespace engine class Camera; class RenderContext; class RenderTarget; +class ShaderCollections; class StaticMeshComponent; class Renderer @@ -25,6 +26,8 @@ class Renderer static RenderContext* GetRenderContext(); virtual void Init() = 0; + // All registered shaders are compiled in the App::Init stage, simply create the GPU resource here. + virtual void Warmup() = 0; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) = 0; virtual void Render(float deltaTime) = 0; diff --git a/Engine/Source/Runtime/Rendering/ShaderCollections.cpp b/Engine/Source/Runtime/Rendering/ShaderCollections.cpp new file mode 100644 index 00000000..89fa5a9e --- /dev/null +++ b/Engine/Source/Runtime/Rendering/ShaderCollections.cpp @@ -0,0 +1,68 @@ +#include "ShaderCollections.h" + +#include "Log/Log.h" + +#include + +namespace engine +{ + +void ShaderCollections::RegisterShaderProgram(StringCrc programNameCrc, std::initializer_list names) +{ + if (IsProgramValid(programNameCrc) || HasFeatureCombine(programNameCrc)) + { + return; + } + + m_shaderPrograms[programNameCrc.Value()] = cd::MoveTemp(names); +} + +void ShaderCollections::AddFeatureCombine(StringCrc programNameCrc, std::string combine) +{ + assert(IsProgramValid(programNameCrc) && "Shader program does not exist!"); + + m_programFeatureCombines[programNameCrc.Value()].insert(cd::MoveTemp(combine)); +} + +void ShaderCollections::DeleteFeatureCombine(StringCrc programNameCrc, std::string combine) +{ + assert(HasFeatureCombine(programNameCrc) && "Feature combine does not exist!"); + + m_programFeatureCombines[programNameCrc.Value()].erase(cd::MoveTemp(combine)); +} + +void ShaderCollections::SetShaders(StringCrc programNameCrc, std::set shaders) +{ + assert(IsProgramValid(programNameCrc) && "Shader program does not exist!"); + + m_shaderPrograms[programNameCrc.Value()] = cd::MoveTemp(shaders); +} + +void ShaderCollections::SetFeatureCombines(StringCrc programNameCrc, std::set combine) +{ + assert(IsProgramValid(programNameCrc) && "Shader program does not exist!"); + + m_programFeatureCombines[programNameCrc.Value()] = cd::MoveTemp(combine); +} + +bool ShaderCollections::IsProgramValid(StringCrc programNameCrc) const +{ + return (m_shaderPrograms.find(programNameCrc.Value()) != m_shaderPrograms.end()); +} + +bool ShaderCollections::HasFeatureCombine(StringCrc programNameCrc) const +{ + return (m_programFeatureCombines.find(programNameCrc.Value()) != m_programFeatureCombines.end()); +} + +void ShaderCollections::SetShaderPrograms(std::map> shaders) +{ + m_shaderPrograms = cd::MoveTemp(shaders); +} + +void ShaderCollections::SetFeatureCombinePrograms(std::map> combines) +{ + m_programFeatureCombines = cd::MoveTemp(combines); +} + +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/ShaderCollections.h b/Engine/Source/Runtime/Rendering/ShaderCollections.h new file mode 100644 index 00000000..5452a682 --- /dev/null +++ b/Engine/Source/Runtime/Rendering/ShaderCollections.h @@ -0,0 +1,57 @@ +#pragma once + +#include "Base/Template.h" +#include "Core/StringCrc.h" + +#include +#include +#include + +namespace engine +{ + +class ShaderCollections final +{ +public: + static constexpr uint16_t InvalidProgramHandle = UINT16_MAX; + +public: + ShaderCollections() = default; + ShaderCollections(const ShaderCollections&) = default; + ShaderCollections& operator=(const ShaderCollections&) = default; + ShaderCollections(ShaderCollections&&) = default; + ShaderCollections& operator=(ShaderCollections&&) = default; + ~ShaderCollections() = default; + + void RegisterShaderProgram(StringCrc programNameCrc, std::initializer_list names); + + void AddFeatureCombine(StringCrc programNameCrc, std::string combine); + void DeleteFeatureCombine(StringCrc programNameCrc, std::string combine); + + void SetShaders(StringCrc programNameCrc, std::set shaders); + std::set& GetShaders(StringCrc programNameCrc) { return m_shaderPrograms[programNameCrc.Value()]; } + const std::set& GetShaders(StringCrc programNameCrc) const { return m_shaderPrograms.at(programNameCrc.Value()); } + + void SetFeatureCombines(StringCrc programNameCrc, std::set combine); + std::set& GetFeatureCombines(StringCrc programNameCrc) { return m_programFeatureCombines[programNameCrc.Value()]; } + const std::set& GetFeatureCombines(StringCrc programNameCrc) const { return m_programFeatureCombines.at(programNameCrc.Value()); } + + bool IsProgramValid(StringCrc programNameCrc) const; + bool HasFeatureCombine(StringCrc programNameCrc) const; + + void SetShaderPrograms(std::map> shaders); + std::map>& GetShaderPrograms() { return m_shaderPrograms; } + const std::map>& GetShaderPrograms() const { return m_shaderPrograms; } + + void SetFeatureCombinePrograms(std::map> combines); + std::map>& GetFeatureCombinePrograms() { return m_programFeatureCombines; } + const std::map>& GetFeatureCombinePrograms() const { return m_programFeatureCombines; } + +private: + // Key : StringCrc(Program name), Value : Shader names + std::map> m_shaderPrograms; + // Key : StringCrc(Program name), Value : Feature combines used as a parameter for compiling shaders + std::map> m_programFeatureCombines; +}; + +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/ShaderCompileInfo.h b/Engine/Source/Runtime/Rendering/ShaderCompileInfo.h new file mode 100644 index 00000000..b0a24fee --- /dev/null +++ b/Engine/Source/Runtime/Rendering/ShaderCompileInfo.h @@ -0,0 +1,31 @@ +#pragma once + +#include "Base/Template.h" + +#include + +namespace engine +{ + +class ShaderCompileInfo +{ +public: + ShaderCompileInfo(std::string name, std::string combine = "") : + m_programName(cd::MoveTemp(name)), m_featuresCombine(cd::MoveTemp(combine)) {} + ShaderCompileInfo() = default; + ShaderCompileInfo(const ShaderCompileInfo&) = default; + ShaderCompileInfo& operator=(const ShaderCompileInfo&) = default; + ShaderCompileInfo(ShaderCompileInfo&&) = default; + ShaderCompileInfo& operator=(ShaderCompileInfo&&) = default; + ~ShaderCompileInfo() = default; + + std::string m_programName; + std::string m_featuresCombine; + + bool operator==(const ShaderCompileInfo& other) const + { + return (m_programName == other.m_programName) && (m_featuresCombine == other.m_featuresCombine); + } +}; + +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/ShaderFeature.h b/Engine/Source/Runtime/Rendering/ShaderFeature.h new file mode 100644 index 00000000..ff0e6ff0 --- /dev/null +++ b/Engine/Source/Runtime/Rendering/ShaderFeature.h @@ -0,0 +1,53 @@ +#pragma once + +#include "Base/Platform.h" + +#include +#include +#include + +namespace engine +{ + +enum class ShaderFeature : uint32_t +{ + DEFAULT = 0, + + // PBR parameters + ALBEDO_MAP, + NORMAL_MAP, + ORM_MAP, + EMISSIVE_MAP, + + // Techniques + IBL, + ATM, + AREAL_LIGHT, + + COUNT, +}; + +// These names are used as macro definition symbols in shaders. +constexpr const char* ShaderFeatureNames[] = +{ + "", // Use empty string to represent default shader option in the name so we can reuse non-uber built shader. + "ALBEDOMAP;", + "NORMALMAP;", + "ORMMAP;", + "EMISSIVEMAP;", + "IBL;", + "ATM;", + "AREALLIGHT;", +}; + +static_assert(static_cast(ShaderFeature::COUNT) == sizeof(ShaderFeatureNames) / sizeof(char*), + "Shader features and names mismatch."); + +CD_FORCEINLINE constexpr const char* GetFeatureName(ShaderFeature feature) +{ + return ShaderFeatureNames[static_cast(feature)]; +} + +using ShaderFeatureSet = std::set; + +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/ShaderType.h b/Engine/Source/Runtime/Rendering/ShaderType.h new file mode 100644 index 00000000..a13f5a00 --- /dev/null +++ b/Engine/Source/Runtime/Rendering/ShaderType.h @@ -0,0 +1,38 @@ +#pragma once + +#include "base/Platform.h" + +#include + +namespace engine +{ + +enum class ShaderType +{ + None, + Compute, + Vertex, + Fragment +}; + +CD_FORCEINLINE static const ShaderType GetShaderType(const std::string& fileName) +{ + if (fileName._Starts_with("vs_") || fileName._Starts_with("VS_")) + { + return ShaderType::Vertex; + } + else if (fileName._Starts_with("fs_") || fileName._Starts_with("FS_")) + { + return ShaderType::Fragment; + } + else if (fileName._Starts_with("cs_") || fileName._Starts_with("CS_")) + { + return ShaderType::Compute; + } + else + { + return ShaderType::None; + } +} + +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/SkeletonRenderer.cpp b/Engine/Source/Runtime/Rendering/SkeletonRenderer.cpp index be0fb0af..502f81bb 100644 --- a/Engine/Source/Runtime/Rendering/SkeletonRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/SkeletonRenderer.cpp @@ -3,7 +3,7 @@ #include "Core/StringCrc.h" #include "ECWorld/SceneWorld.h" #include "ECWorld/TransformComponent.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" #include "Rendering/Utility/VertexLayoutUtility.h" namespace engine @@ -56,10 +56,17 @@ void TraverseBone(const cd::Bone& bone, const cd::SceneDatabase* pSceneDatabase, void SkeletonRenderer::Init() { - GetRenderContext()->CreateProgram("SkeletonProgram", "vs_AABB.bin", "fs_AABB.bin"); + constexpr StringCrc programCrc = StringCrc("SkeletonProgram"); + GetRenderContext()->RegisterShaderProgram(programCrc, {"vs_AABB", "fs_AABB"}); + bgfx::setViewName(GetViewID(), "SkeletonRenderer"); } +void SkeletonRenderer::Warmup() +{ + GetRenderContext()->UploadShaderProgram("SkeletonProgram"); +} + void SkeletonRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { UpdateViewRenderTarget(); @@ -127,8 +134,8 @@ void SkeletonRenderer::Render(float delataTime) BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) | BGFX_STATE_PT_LINES; bgfx::setState(state); - constexpr StringCrc SkeletonProgram("SkeletonProgram"); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(SkeletonProgram)); + + GetRenderContext()->Submit(GetViewID(), "SkeletonProgram"); } } diff --git a/Engine/Source/Runtime/Rendering/SkeletonRenderer.h b/Engine/Source/Runtime/Rendering/SkeletonRenderer.h index 81632f97..3ced1d57 100644 --- a/Engine/Source/Runtime/Rendering/SkeletonRenderer.h +++ b/Engine/Source/Runtime/Rendering/SkeletonRenderer.h @@ -14,6 +14,7 @@ class SkeletonRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; void Build(); diff --git a/Engine/Source/Runtime/Rendering/SkyType.h b/Engine/Source/Runtime/Rendering/SkyType.h new file mode 100644 index 00000000..5e6200ba --- /dev/null +++ b/Engine/Source/Runtime/Rendering/SkyType.h @@ -0,0 +1,30 @@ +#pragma once + +#include "Base/Platform.h" +#include "Rendering/ShaderFeature.h" + +#include + +namespace engine +{ + +enum class SkyType +{ + None, + SkyBox, + AtmosphericScattering, +}; + +static const std::map SkyTypeToShaderFeature +{ + { engine::SkyType::None, engine::ShaderFeature::DEFAULT}, + { engine::SkyType::SkyBox, engine::ShaderFeature::IBL}, + { engine::SkyType::AtmosphericScattering, engine::ShaderFeature::ATM }, +}; + +CD_FORCEINLINE engine::ShaderFeature GetSkyTypeShaderFeature(engine::SkyType type) +{ + return SkyTypeToShaderFeature.at(type); +} + +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/SkyboxRenderer.cpp b/Engine/Source/Runtime/Rendering/SkyboxRenderer.cpp index 390db88d..0c5fadb7 100644 --- a/Engine/Source/Runtime/Rendering/SkyboxRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/SkyboxRenderer.cpp @@ -3,7 +3,7 @@ #include "ECWorld/CameraComponent.h" #include "ECWorld/SceneWorld.h" #include "ECWorld/SkyComponent.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" namespace engine { @@ -12,7 +12,7 @@ namespace { constexpr const char* skyboxSampler = "s_texSkybox"; -constexpr const char* skyboxShader = "skyboxShader"; +constexpr const char* skyboxProgram = "skyboxProgram"; constexpr uint16_t sampleFalg = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_W_CLAMP; constexpr uint64_t renderState = BGFX_STATE_WRITE_MASK | BGFX_STATE_CULL_CCW | BGFX_STATE_MSAA | BGFX_STATE_DEPTH_TEST_LEQUAL; @@ -20,14 +20,21 @@ constexpr uint64_t renderState = BGFX_STATE_WRITE_MASK | BGFX_STATE_CULL_CCW | B } void SkyboxRenderer::Init() +{ + constexpr StringCrc programCrc = StringCrc(skyboxProgram); + GetRenderContext()->RegisterShaderProgram(programCrc, {"vs_skybox", "fs_skybox"}); + + bgfx::setViewName(GetViewID(), "SkyboxRenderer"); +} + +void SkyboxRenderer::Warmup() { SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); GetRenderContext()->CreateUniform(skyboxSampler, bgfx::UniformType::Sampler); GetRenderContext()->CreateTexture(pSkyComponent->GetRadianceTexturePath().c_str(), sampleFalg); - GetRenderContext()->CreateProgram(skyboxShader, "vs_skybox.bin", "fs_skybox.bin"); - bgfx::setViewName(GetViewID(), "SkyboxRenderer"); + GetRenderContext()->UploadShaderProgram(skyboxProgram); } void SkyboxRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -73,14 +80,14 @@ void SkyboxRenderer::Render(float deltaTime) GetRenderContext()->CreateTexture(pSkyComponent->GetRadianceTexturePath().c_str(), sampleFalg); constexpr StringCrc samplerCrc(skyboxSampler); - constexpr StringCrc programCrc(skyboxShader); bgfx::setTexture(0, GetRenderContext()->GetUniform(samplerCrc), GetRenderContext()->GetTexture(StringCrc(pSkyComponent->GetRadianceTexturePath()))); bgfx::setState(renderState); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(programCrc)); + + GetRenderContext()->Submit(GetViewID(), skyboxProgram); } bool SkyboxRenderer::IsEnable() const diff --git a/Engine/Source/Runtime/Rendering/SkyboxRenderer.h b/Engine/Source/Runtime/Rendering/SkyboxRenderer.h index 6cc9ec9a..d61cf64b 100644 --- a/Engine/Source/Runtime/Rendering/SkyboxRenderer.h +++ b/Engine/Source/Runtime/Rendering/SkyboxRenderer.h @@ -13,6 +13,7 @@ class SkyboxRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; virtual bool IsEnable() const override; diff --git a/Engine/Source/Runtime/Rendering/TerrainRenderer.cpp b/Engine/Source/Runtime/Rendering/TerrainRenderer.cpp index 42b68b2d..a61ee208 100644 --- a/Engine/Source/Runtime/Rendering/TerrainRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/TerrainRenderer.cpp @@ -9,7 +9,7 @@ #include "LightUniforms.h" #include "Material/ShaderSchema.h" #include "Math/Transform.hpp" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" #include "Scene/Texture.h" #include "U_IBL.sh" #include "U_Terrain.sh" @@ -53,10 +53,17 @@ constexpr uint64_t defaultRenderingState = BGFX_STATE_WRITE_MASK | BGFX_STATE_MS } void TerrainRenderer::Init() +{ + constexpr StringCrc programCrc = StringCrc("TerrainProgram"); + GetRenderContext()->RegisterShaderProgram(programCrc, {"vs_terrain", "fs_terrain"}); + + bgfx::setViewName(GetViewID(), "TerrainRenderer"); +} + +void TerrainRenderer::Warmup() { SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); - - GetRenderContext()->CreateProgram("TerrainProgram", "vs_terrain.bin", "fs_terrain.bin"); + GetRenderContext()->CreateUniform(snowSampler, bgfx::UniformType::Sampler); GetRenderContext()->CreateUniform(rockSampler, bgfx::UniformType::Sampler); GetRenderContext()->CreateUniform(grassSampler, bgfx::UniformType::Sampler); @@ -83,7 +90,7 @@ void TerrainRenderer::Init() GetRenderContext()->CreateTexture(elevationTexture, 129U, 129U, 1, bgfx::TextureFormat::Enum::R32F, samplerFlags, nullptr, 0); - bgfx::setViewName(GetViewID(), "TerrainRenderer"); + GetRenderContext()->UploadShaderProgram("TerrainProgram"); } void TerrainRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -148,7 +155,6 @@ void TerrainRenderer::Render(float deltaTime) // Sky SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); SkyType crtSkyType = pSkyComponent->GetSkyType(); - pMaterialComponent->SetSkyType(crtSkyType); if (crtSkyType == SkyType::SkyBox) { @@ -176,7 +182,7 @@ void TerrainRenderer::Render(float deltaTime) constexpr StringCrc cameraPosCrc(cameraPos); GetRenderContext()->FillUniform(cameraPosCrc, &cameraTransform.GetTranslation().x(), 1); - // Submit uniform values : material settings + // Submit uniform values : material settings constexpr StringCrc albedoColorCrc(albedoColor); GetRenderContext()->FillUniform(albedoColorCrc, pMaterialComponent->GetAlbedoColor().Begin(), 1); @@ -187,7 +193,7 @@ void TerrainRenderer::Render(float deltaTime) constexpr StringCrc emissiveColorCrc(emissiveColor); GetRenderContext()->FillUniform(emissiveColorCrc, pMaterialComponent->GetEmissiveColor().Begin(), 1); - // Submit uniform values : light settings + // Submit uniform values : light settings auto lightEntities = m_pCurrentSceneWorld->GetLightEntities(); size_t lightEntityCount = lightEntities.size(); constexpr engine::StringCrc lightCountAndStrideCrc(lightCountAndStride); @@ -210,8 +216,7 @@ void TerrainRenderer::Render(float deltaTime) bgfx::setState(state); - constexpr StringCrc terrainProgram("TerrainProgram"); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(terrainProgram)); + GetRenderContext()->Submit(GetViewID(), "TerrainProgram"); } } diff --git a/Engine/Source/Runtime/Rendering/TerrainRenderer.h b/Engine/Source/Runtime/Rendering/TerrainRenderer.h index 01915a3e..1e7d5342 100644 --- a/Engine/Source/Runtime/Rendering/TerrainRenderer.h +++ b/Engine/Source/Runtime/Rendering/TerrainRenderer.h @@ -13,6 +13,7 @@ class TerrainRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Rendering/WhiteModelRenderer.cpp b/Engine/Source/Runtime/Rendering/WhiteModelRenderer.cpp index ba659799..79d6eb5e 100644 --- a/Engine/Source/Runtime/Rendering/WhiteModelRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/WhiteModelRenderer.cpp @@ -4,7 +4,7 @@ #include "ECWorld/SceneWorld.h" #include "ECWorld/StaticMeshComponent.h" #include "ECWorld/TransformComponent.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" #include "Scene/Texture.h" namespace engine @@ -12,10 +12,17 @@ namespace engine void WhiteModelRenderer::Init() { - GetRenderContext()->CreateProgram("WhiteModelProgram", "vs_whiteModel.bin", "fs_whiteModel.bin"); + constexpr StringCrc programCrc = StringCrc("WhiteModelProgram"); + GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_whiteModel", "fs_whiteModel" }); + bgfx::setViewName(GetViewID(), "WhiteModelRenderer"); } +void WhiteModelRenderer::Warmup() +{ + GetRenderContext()->UploadShaderProgram("WhiteModelProgram"); +} + void WhiteModelRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { UpdateViewRenderTarget(); @@ -55,8 +62,7 @@ void WhiteModelRenderer::Render(float deltaTime) BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA); bgfx::setState(state); - constexpr StringCrc whiteModelProgram("WhiteModelProgram"); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(whiteModelProgram)); + GetRenderContext()->Submit(GetViewID(), "WhiteModelProgram"); } } diff --git a/Engine/Source/Runtime/Rendering/WhiteModelRenderer.h b/Engine/Source/Runtime/Rendering/WhiteModelRenderer.h index 62325dec..c7a97f99 100644 --- a/Engine/Source/Runtime/Rendering/WhiteModelRenderer.h +++ b/Engine/Source/Runtime/Rendering/WhiteModelRenderer.h @@ -15,6 +15,7 @@ class WhiteModelRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Rendering/WireframeRenderer.cpp b/Engine/Source/Runtime/Rendering/WireframeRenderer.cpp index 27481582..ccd9ea49 100644 --- a/Engine/Source/Runtime/Rendering/WireframeRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/WireframeRenderer.cpp @@ -4,18 +4,27 @@ #include "ECWorld/SceneWorld.h" #include "ECWorld/StaticMeshComponent.h" #include "ECWorld/TransformComponent.h" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" #include "Scene/Texture.h" +#undef EDITOR_MODE + namespace engine { void WireframeRenderer::Init() { - GetRenderContext()->CreateProgram("WireframeLineProgram", "vs_wireframe_line.bin", "fs_wireframe_line.bin"); + constexpr StringCrc programCrc = StringCrc("WireframeLineProgram"); + GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_wireframe_line", "fs_wireframe_line" }); + bgfx::setViewName(GetViewID(), "WireframeRenderer"); } +void WireframeRenderer::Warmup() +{ + GetRenderContext()->UploadShaderProgram("WireframeLineProgram"); +} + void WireframeRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { UpdateViewRenderTarget(); @@ -60,8 +69,7 @@ void WireframeRenderer::Render(float deltaTime) BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) | BGFX_STATE_PT_LINES; bgfx::setState(state); - constexpr StringCrc whiteModelProgram("WireframeLineProgram"); - bgfx::submit(GetViewID(), GetRenderContext()->GetProgram(whiteModelProgram)); + GetRenderContext()->Submit(GetViewID(), "WireframeLineProgram"); } } diff --git a/Engine/Source/Runtime/Rendering/WireframeRenderer.h b/Engine/Source/Runtime/Rendering/WireframeRenderer.h index 209befd1..90d1b191 100644 --- a/Engine/Source/Runtime/Rendering/WireframeRenderer.h +++ b/Engine/Source/Runtime/Rendering/WireframeRenderer.h @@ -15,6 +15,7 @@ class WireframeRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Rendering/WorldRenderer.cpp b/Engine/Source/Runtime/Rendering/WorldRenderer.cpp index 3fb014db..83fc2a06 100644 --- a/Engine/Source/Runtime/Rendering/WorldRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/WorldRenderer.cpp @@ -9,7 +9,7 @@ #include "LightUniforms.h" #include "Material/ShaderSchema.h" #include "Math/Transform.hpp" -#include "RenderContext.h" +#include "Rendering/RenderContext.h" #include "Scene/Texture.h" #include "U_IBL.sh" #include "U_AtmophericScattering.sh" @@ -46,6 +46,14 @@ constexpr uint64_t defaultRenderingState = BGFX_STATE_WRITE_MASK | BGFX_STATE_MS } void WorldRenderer::Init() +{ + constexpr StringCrc programCrc = StringCrc("WorldProgram"); + GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_PBR", "fs_PBR" }); + + bgfx::setViewName(GetViewID(), "WorldRenderer"); +} + +void WorldRenderer::Warmup() { SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); @@ -69,8 +77,6 @@ void WorldRenderer::Init() GetRenderContext()->CreateUniform(LightDir, bgfx::UniformType::Vec4, 1); GetRenderContext()->CreateUniform(HeightOffsetAndshadowLength, bgfx::UniformType::Vec4, 1); - - bgfx::setViewName(GetViewID(), "WorldRenderer"); } void WorldRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -137,14 +143,12 @@ void WorldRenderer::Render(float deltaTime) GetRenderContext()->FillUniform(albedoUVOffsetAndScaleCrc, &uvOffsetAndScaleData, 1); } - bgfx::setTexture(pTextureInfo->slot, bgfx::UniformHandle{pTextureInfo->samplerHandle}, bgfx::TextureHandle{pTextureInfo->textureHandle}); + bgfx::setTexture(pTextureInfo->slot, bgfx::UniformHandle{ pTextureInfo->samplerHandle }, bgfx::TextureHandle{ pTextureInfo->textureHandle }); } } // Sky SkyType crtSkyType = pSkyComponent->GetSkyType(); - pMaterialComponent->SetSkyType(crtSkyType); - if (SkyType::SkyBox == crtSkyType) { // Create a new TextureHandle each frame if the skybox texture path has been updated, @@ -224,7 +228,7 @@ void WorldRenderer::Render(float deltaTime) bgfx::setState(state); - bgfx::submit(GetViewID(), bgfx::ProgramHandle{pMaterialComponent->GetShadreProgram()}); + GetRenderContext()->Submit(GetViewID(), "WorldProgram", pMaterialComponent->GetFeaturesCombine()); } } diff --git a/Engine/Source/Runtime/Rendering/WorldRenderer.h b/Engine/Source/Runtime/Rendering/WorldRenderer.h index 7ddc7357..19d79d93 100644 --- a/Engine/Source/Runtime/Rendering/WorldRenderer.h +++ b/Engine/Source/Runtime/Rendering/WorldRenderer.h @@ -13,6 +13,7 @@ class WorldRenderer final : public Renderer using Renderer::Renderer; virtual void Init() override; + virtual void Warmup() override; virtual void UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) override; virtual void Render(float deltaTime) override; diff --git a/Engine/Source/Runtime/Resources/ShaderLoader.cpp b/Engine/Source/Runtime/Resources/ShaderLoader.cpp deleted file mode 100644 index 5f265bfd..00000000 --- a/Engine/Source/Runtime/Resources/ShaderLoader.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "ShaderLoader.h" - -#include "Log/Log.h" -#include "Path/Path.h" -#include "Rendering/RenderContext.h" -#include "Resources/ResourceLoader.h" - -namespace engine -{ - -void ShaderLoader::UploadUberShader(engine::MaterialType* pMaterialType) -{ - std::map outputFSPathToShaderFeaturesCrc; - - engine::ShaderSchema& shaderSchema = pMaterialType->GetShaderSchema(); - std::string outputVSFilePath = engine::Path::GetShaderOutputPath(shaderSchema.GetVertexShaderPath()); - for (const auto& combine : shaderSchema.GetFeatureCombines()) - { - std::string outputFSFilePath = engine::Path::GetShaderOutputPath(shaderSchema.GetFragmentShaderPath(), combine); - outputFSPathToShaderFeaturesCrc[cd::MoveTemp(outputFSFilePath)] = engine::StringCrc(combine); - } - - // Vertex shader. - shaderSchema.AddUberVSBlob(engine::ResourceLoader::LoadFile(outputVSFilePath.c_str())); - const auto& VSBlob = shaderSchema.GetVSBlob(); - bgfx::ShaderHandle vsHandle = bgfx::createShader(bgfx::makeRef(VSBlob.data(), static_cast(VSBlob.size()))); - bgfx::setName(vsHandle, outputVSFilePath.c_str()); - - // Fragment shader. - for (const auto& [outputFSFilePath, ShaderFeaturesCrc] : outputFSPathToShaderFeaturesCrc) - { - shaderSchema.AddUberFSBlob(ShaderFeaturesCrc, engine::ResourceLoader::LoadFile(outputFSFilePath.c_str())); - - const auto& FSBlob = shaderSchema.GetFSBlob(ShaderFeaturesCrc); - bgfx::ShaderHandle fsHandle = bgfx::createShader(bgfx::makeRef(FSBlob.data(), static_cast(FSBlob.size()))); - bgfx::setName(fsHandle, outputFSFilePath.c_str()); - assert(bgfx::isValid(fsHandle)); - - // Program. - bgfx::ProgramHandle uberProgramHandle = bgfx::createProgram(vsHandle, fsHandle); - assert(bgfx::isValid(uberProgramHandle)); - shaderSchema.SetCompiledProgram(ShaderFeaturesCrc, uberProgramHandle.idx); - } -} - -} // namespace editor diff --git a/Engine/Source/Runtime/Resources/ShaderLoader.h b/Engine/Source/Runtime/Resources/ShaderLoader.h deleted file mode 100644 index 84f30bf7..00000000 --- a/Engine/Source/Runtime/Resources/ShaderLoader.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "Material/MaterialType.h" - -#include -#include - -namespace engine -{ - -class ShaderLoader -{ -public: - static void UploadUberShader(engine::MaterialType* pMaterialType); -}; - -} // namespace editor diff --git a/Projects/Shared/BuiltInShaders/Direct3D11/fs_imgui.bin b/Projects/Shared/BuiltInShaders/Direct3D11/fs_imgui.bin new file mode 100644 index 0000000000000000000000000000000000000000..e14e7aa70a9f534afabbd94331b355c992d1fe07 GIT binary patch literal 434 zcmZ<@_TXl0{`8Om2$&dHi{ndDD-0MJ7=Q=}(D^k$VV4Le=lO^4zPtZmL&&PYH(Rv6 z^*Mu7gXEZjv>2Ftmjk3h;v7I60K^~wQV$XX0e&Ek0ka?kNE{^350pqk z6K4YQnSly|!{P({gFQn${rwo6{eAp{7(!eloc;ZSTo_jS1MLL40b~ZqP6Z%_0c1OY zW`sBfxx0oitX>`L;To|3s0idf4Is|qU|@^_IWa*1$YWrLkYHe8D1fj-LxJuRU|{|v zAON-l#5Mx5L2gS0>iMJqQI`P>P>>s385p_`F)%bZhl(5Er7wwy^=}grnW8>;lb7#*^ZuDh;{JjltjFThlIC4@f0;i-w>RTCK&Hs9Ez(U7 zI$x)&(~tc1eW^ZO|6aM;vMSBNcN6)HbOFQoaBzW|yn&36Cde4AmPn$@awX@yc@)_{ z4tsIHJL*UcB~o!X3e`YHy|km$uqz6F*X%+5_TxM<2JGadtn@-oo%~FrawRYQ7DeJD zo0)0vndM8|@1+|U5MfG)J>!O0$9S;d$t&mZQFP@1WWX)ZlD}VWyvNunqmK((N|D epP1}JubFcOYkCfuId1?zo_mkSa%xyyY0D1{;XBy? literal 0 HcmV?d00001