diff --git a/Engine/Source/Editor/EditorApp.cpp b/Engine/Source/Editor/EditorApp.cpp index 213a64f7..f508423b 100644 --- a/Engine/Source/Editor/EditorApp.cpp +++ b/Engine/Source/Editor/EditorApp.cpp @@ -28,9 +28,9 @@ #include "Rendering/RenderContext.h" #include "Rendering/Resources/MeshResource.h" #include "Rendering/Resources/ResourceContext.h" +#include "Rendering/Resources/ShaderResource.h" #include "Rendering/SkeletonRenderer.h" #include "Rendering/SkyboxRenderer.h" -#include "Rendering/ShaderCollections.h" #include "Rendering/ShadowMapRenderer.h" #include "Rendering/TerrainRenderer.h" #include "Rendering/WorldRenderer.h" @@ -99,7 +99,6 @@ void EditorApp::Init(engine::EngineInitArgs initArgs) AddWindow(cd::MoveTemp(pSplashWindow)); InitEditorRenderers(); - EditorRenderersWarmup(); InitEditorImGuiContext(m_initArgs.language); InitECWorld(); @@ -260,30 +259,18 @@ void EditorApp::InitECWorld() void EditorApp::InitMaterialType() { - constexpr const char* WorldProgram = "WorldProgram"; - constexpr const char* AnimationProgram = "AnimationProgram"; - constexpr const char* TerrainProgram = "TerrainProgram"; - constexpr const char* ParticleProgram = "ParticleProgram"; - constexpr const char* CelluloidProgram = "CelluloidProgram"; - - constexpr engine::StringCrc WorldProgramCrc{ WorldProgram }; - constexpr engine::StringCrc AnimationProgramCrc{ AnimationProgram }; - constexpr engine::StringCrc TerrainProgramCrc{ TerrainProgram }; - constexpr engine::StringCrc ParticleProgramCrc{ ParticleProgram}; - constexpr engine::StringCrc CelluloidProgramCrc{ CelluloidProgram }; - - m_pRenderContext->RegisterShaderProgram(WorldProgramCrc, { "vs_PBR", "fs_PBR" }); - m_pRenderContext->RegisterShaderProgram(AnimationProgramCrc, { "vs_animation", "fs_animation" }); - m_pRenderContext->RegisterShaderProgram(TerrainProgramCrc, { "vs_terrain", "fs_terrain" }); - m_pRenderContext->RegisterShaderProgram(ParticleProgramCrc, { "vs_particle","fs_particle" }); - m_pRenderContext->RegisterShaderProgram(CelluloidProgramCrc, { "vs_celluloid", "fs_celluloid" }); + m_pRenderContext->RegisterShaderProgram("WorldProgram", "vs_PBR", "fs_PBR"); + m_pRenderContext->RegisterShaderProgram("AnimationProgram", "vs_animation", "fs_animation"); + m_pRenderContext->RegisterShaderProgram("TerrainProgram", "vs_terrain", "fs_terrain"); + m_pRenderContext->RegisterShaderProgram("ParticleProgram", "vs_particle", "fs_particle"); + m_pRenderContext->RegisterShaderProgram("CelluloidProgram", "vs_celluloid", "fs_celluloid"); m_pSceneWorld = std::make_unique(); - m_pSceneWorld->CreatePBRMaterialType(WorldProgram, IsAtmosphericScatteringEnable()); - m_pSceneWorld->CreateAnimationMaterialType(AnimationProgram); - m_pSceneWorld->CreateTerrainMaterialType(TerrainProgram); - m_pSceneWorld->CreateParticleMaterialType(ParticleProgram); - m_pSceneWorld->CreateCelluloidMaterialType(CelluloidProgram); + m_pSceneWorld->CreatePBRMaterialType("WorldProgram", IsAtmosphericScatteringEnable()); + m_pSceneWorld->CreateAnimationMaterialType("AnimationProgram"); + m_pSceneWorld->CreateTerrainMaterialType("TerrainProgram"); + m_pSceneWorld->CreateParticleMaterialType("ParticleProgram"); + m_pSceneWorld->CreateCelluloidMaterialType("CelluloidProgram"); } void EditorApp::InitEditorCameraEntity() @@ -395,7 +382,7 @@ void EditorApp::OnShaderHotModifiedCallback(const char* rootDir, const char* fil // Do nothing when a non-shader file is detected. return; } - m_pRenderContext->CheckModifiedProgram(engine::Path::GetFileNameWithoutExtension(filePath)); + m_pRenderContext->OnShaderHotModified(engine::StringCrc{ engine::Path::GetFileNameWithoutExtension(filePath) }); } void EditorApp::UpdateMaterials() @@ -408,77 +395,52 @@ void EditorApp::UpdateMaterials() continue; } - const std::string& programName = pMaterialComponent->GetShaderProgramName(); - const std::string& featuresCombine = pMaterialComponent->GetFeaturesCombine(); - - // New shader feature added, need to compile new variants. - m_pRenderContext->CheckShaderProgram(entity, programName, featuresCombine); - - // Shader source files have been modified, need to re-compile existing variants. - if (m_crtInputFocus && !m_preInputFocus) + if (pMaterialComponent->IsShaderResourceDirty()) { - m_pRenderContext->OnShaderHotModified(entity, programName, featuresCombine); - } - } - - if (m_crtInputFocus && !m_preInputFocus) - { - m_pRenderContext->ClearModifiedProgramNameCrcs(); - } -} - -void EditorApp::CompileAndLoadShaders() -{ - // 1. Compile - TaskOutputCallbacks cb; - cb.onErrorOutput.Bind(this); - ShaderBuilder::BuildShaderInfos(m_pRenderContext.get(), cd::MoveTemp(cb)); + // 1. Create a new ShaderResource / Or find an exists one + // 2. Update it to MaterialComponent - // 2. Load - if (!m_pRenderContext->GetShaderCompileInfos().empty()) - { - ResourceBuilder::Get().Update(false, true); + const std::string& programName = pMaterialComponent->GetShaderProgramName(); + const std::string& featuresCombine = pMaterialComponent->GetFeaturesCombine(); - for (const auto& info : m_pRenderContext->GetShaderCompileInfos()) - { - // Info still in RenderContext::m_shaderCompileInfos means compiling is successful. - const uint32_t entity = info.m_entity; - auto& failedEntities = m_pRenderContext->GetCompileFailedEntities(); - if (failedEntities.find(entity) != failedEntities.end()) + engine::ShaderResource* pShaderResource = m_pResourceContext->GetShaderResource(engine::StringCrc{ programName + featuresCombine }); + if (!pShaderResource) { - engine::MaterialComponent* pMaterialComponent = m_pSceneWorld->GetMaterialComponent(entity); - pMaterialComponent->SetFactor(cd::MaterialPropertyGroup::BaseColor, cd::Vec3f{ 1.0f, 1.0f, 1.0f }); - failedEntities.erase(entity); + // We assume here that the ResourceContext hold informations about an + // original ShaderProgram that does not contain any ShaderFeature. + engine::ShaderResource* pOriginShaderResource = m_pResourceContext->GetShaderResource(engine::StringCrc{ programName }); + assert(pOriginShaderResource); + + engine::ShaderProgramType programtype = pOriginShaderResource->GetType(); + if (engine::ShaderProgramType::Standard == programtype) + { + pShaderResource = m_pRenderContext->RegisterShaderProgram(pOriginShaderResource->GetName(), + pOriginShaderResource->GetShaderInfo(0).name, + pOriginShaderResource->GetShaderInfo(1).name, + featuresCombine); + } + else + { + pShaderResource = m_pRenderContext->RegisterShaderProgram(pOriginShaderResource->GetName(), + pOriginShaderResource->GetShaderInfo(0).name, + programtype, + featuresCombine); + } + + m_pRenderContext->AddRecompileShaderResource(pShaderResource); } - m_pRenderContext->DestroyShaderProgram(info.m_programName, info.m_featuresCombine); - m_pRenderContext->UploadShaderProgram(info.m_programName, info.m_featuresCombine); + assert(pShaderResource); + pMaterialComponent->SetShaderResource(pShaderResource); } - - m_pRenderContext->ClearShaderCompileInfos(); + assert(!pMaterialComponent->IsShaderResourceDirty()); } -} -void EditorApp::OnShaderCompileFailed(uint32_t handle, std::span str) -{ - auto& infos = m_pRenderContext->GetShaderCompileInfos(); - auto it = infos.begin(); - - while (it != infos.end()) + // When the window gains focus, check if the shader for each program has been modified. + if (m_crtInputFocus) { - const auto& handles = it->m_taskHandles; - if (handles.find(handle) != handles.end()) - { - const uint32_t entity = it->m_entity; - m_pRenderContext->AddCompileFailedEntity(entity); - engine::MaterialComponent* pMaterialComponent = m_pSceneWorld->GetMaterialComponent(entity); - pMaterialComponent->SetFactor(cd::MaterialPropertyGroup::BaseColor, cd::Vec3f{ 1.0f, 0.0f, 1.0f }); - it = infos.erase(it); - } - else - { - ++it; - } + m_pRenderContext->OnShaderRecompile(); + ShaderBuilder::BuildRecompileShaderResources(m_pRenderContext.get()); } } @@ -493,9 +455,6 @@ void EditorApp::InitRenderContext(engine::GraphicsBackend backend, void* hwnd) m_pResourceContext = std::make_unique(); m_pRenderContext->SetResourceContext(m_pResourceContext.get()); - - m_pShaderCollections = std::make_unique(); - m_pRenderContext->SetShaderCollections(m_pShaderCollections.get()); } void EditorApp::InitEditorRenderers() @@ -613,22 +572,6 @@ 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(); @@ -640,24 +583,16 @@ bool EditorApp::IsAtmosphericScatteringEnable() const void EditorApp::InitShaderPrograms(bool compileAllShaders) const { - ShaderBuilder::CompileRegisteredNonUberShader(m_pRenderContext.get()); - if (compileAllShaders) { - ShaderBuilder::CompileUberShaderAllVariants(m_pRenderContext.get(), m_pSceneWorld->GetPBRMaterialType()); + ShaderBuilder::RegisterUberShaderAllVariants(m_pRenderContext.get(), m_pSceneWorld->GetPBRMaterialType()); #ifdef ENABLE_DDGI - ShaderBuilder::CompileUberShaderAllVariants(m_pRenderContext.get(), m_pSceneWorld->GetDDGIMaterialType()); + ShaderBuilder::RegisterUberShaderAllVariants(m_pRenderContext.get(), m_pSceneWorld->GetDDGIMaterialType()); #endif } - else - { - ShaderBuilder::CompileRegisteredUberShader(m_pRenderContext.get(), m_pSceneWorld->GetPBRMaterialType()); -#ifdef ENABLE_DDGI - ShaderBuilder::CompileRegisteredUberShader(m_pRenderContext.get(), m_pSceneWorld->GetDDGIMaterialType()); -#endif - } + ShaderBuilder::BuildRegisteredShaderResources(m_pRenderContext.get()); } void EditorApp::InitEditorController() @@ -690,8 +625,6 @@ bool EditorApp::Update(float deltaTime) { m_bInitEditor = true; - EngineRenderersWarmup(); - // Phase 2 - Project Manager // * TODO : Show project selector //GetMainWindow()->SetTitle("Project Manager"); @@ -767,8 +700,6 @@ bool EditorApp::Update(float deltaTime) m_pEngineImGuiContext->Update(deltaTime); UpdateMaterials(); - CompileAndLoadShaders(); - 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 5751eead..ade13534 100644 --- a/Engine/Source/Editor/EditorApp.h +++ b/Engine/Source/Editor/EditorApp.h @@ -20,7 +20,6 @@ class ResourceContext; class AABBRenderer; class RenderTarget; class SceneWorld; -class ShaderCollections; } @@ -57,9 +56,6 @@ class EditorApp final : public engine::IApplication void InitEditorRenderers(); void InitEngineRenderers(); - void EditorRenderersWarmup(); - void EngineRenderersWarmup(); - void InitShaderPrograms(bool compileAllShaders = false) const; void AddEditorRenderer(std::unique_ptr pRenderer); void AddEngineRenderer(std::unique_ptr pRenderer); @@ -87,10 +83,7 @@ class EditorApp final : public engine::IApplication void InitFileWatcher(); void OnShaderHotModifiedCallback(const char* rootDir, const char* filePath); - void UpdateMaterials(); - void CompileAndLoadShaders(); - void OnShaderCompileFailed(uint32_t handle, std::span str); bool m_crtInputFocus = true; bool m_preInputFocus = true; @@ -123,7 +116,6 @@ class EditorApp final : public engine::IApplication // Rendering std::unique_ptr m_pRenderContext; std::unique_ptr m_pResourceContext; - std::unique_ptr m_pShaderCollections; std::vector> m_pEditorRenderers; std::vector> m_pEngineRenderers; diff --git a/Engine/Source/Editor/Resources/ShaderBuilder.cpp b/Engine/Source/Editor/Resources/ShaderBuilder.cpp index 9697b91a..93ec5e14 100644 --- a/Engine/Source/Editor/Resources/ShaderBuilder.cpp +++ b/Engine/Source/Editor/Resources/ShaderBuilder.cpp @@ -4,134 +4,78 @@ #include "Log/Log.h" #include "Path/Path.h" #include "Rendering/RenderContext.h" -#include "Rendering/ShaderCollections.h" +#include "Rendering/Resources/ResourceContext.h" namespace editor { -namespace +void ShaderBuilder::RegisterUberShaderAllVariants(engine::RenderContext *pRenderContext, engine::MaterialType *pMaterialType) { + const std::string &programName = pMaterialType->GetShaderSchema().GetShaderProgramName(); + const engine::ShaderResource *pOriginShaderResource = pRenderContext->GetResourceContext()->GetShaderResource(engine::StringCrc{ programName }); + const auto &combines = pMaterialType->GetShaderSchema().GetAllFeatureCombines(); + engine::ShaderProgramType programType = pOriginShaderResource->GetType(); -void CompileShaderVariants(const std::set& shaders, const std::set& combines) -{ - for (const std::string& shader : shaders) + for (const auto &combine : combines) { - 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) + if (engine::ShaderProgramType::Standard == programType) { - 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()); - } + pRenderContext->RegisterShaderProgram(programName.c_str(), + pOriginShaderResource->GetShaderInfo(0).name.c_str(), + pOriginShaderResource->GetShaderInfo(0).name.c_str(), + combine); } else { - // No shader feature support for Vertex and Compute shader. - continue; + pRenderContext->RegisterShaderProgram(programName.c_str(), + pOriginShaderResource->GetShaderInfo(0).name.c_str(), + programType, + combine); } } -} + CD_ENGINE_INFO("Compiling program {0} all variants with count : {1}", programName, combines.size()); } -void ShaderBuilder::CompileRegisteredNonUberShader(engine::RenderContext* pRenderContext) +void ShaderBuilder::BuildRegisteredShaderResources(engine::RenderContext* pRenderContext, TaskOutputCallbacks callbacks) { - for (const auto& shaders : pRenderContext->GetShaderCollections()->GetShaderPrograms()) + for (const auto& [_, pShaderResource] : pRenderContext->GetShaderResources()) { - for (const auto& shader : shaders.second) - { - engine::ShaderType shaderType = engine::GetShaderType(shader); - if (engine::ShaderType::None == shaderType) - { - CD_WARN("Known shader type of {0} in ShaderBuilder!", shader); - 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()); - } + BuildShaderResource(pRenderContext, pShaderResource, callbacks); } + + ResourceBuilder::Get().Update(); } -void ShaderBuilder::CompileRegisteredUberShader(engine::RenderContext* pRenderContext, engine::MaterialType* pMaterialType) +void ShaderBuilder::BuildRecompileShaderResources(engine::RenderContext* pRenderContext, TaskOutputCallbacks callbacks) { - const std::string& programName = pMaterialType->GetShaderSchema().GetShaderProgramName(); - engine::StringCrc programNameCrc = engine::StringCrc(programName); - - if (!pRenderContext->GetShaderCollections()->HasFeatureCombine(programNameCrc)) + for (auto pShaderResource : pRenderContext->GetRecompileShaderResources()) { - return; + BuildShaderResource(pRenderContext, pShaderResource, callbacks); } - 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().GetShaderProgramName(); - - 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(); + pRenderContext->ClearRecompileShaderResources(); } -void ShaderBuilder::BuildShaderInfos(engine::RenderContext* pRenderContext, TaskOutputCallbacks callbacks) +void ShaderBuilder::BuildShaderResource(engine::RenderContext* pRenderContext, engine::ShaderResource* pShaderResource, TaskOutputCallbacks callbacks) { - std::set newInfos; - - for (auto info : pRenderContext->GetShaderCompileInfos()) + if (engine::ShaderProgramType::Standard == pShaderResource->GetType()) { - engine::ShaderCompileInfo newInfo{ info.m_entity, cd::MoveTemp(info.m_programName), cd::MoveTemp(info.m_featuresCombine) }; - const std::set& shaders = pRenderContext->GetShaderCollections()->GetShaders(engine::StringCrc(newInfo.m_programName)); - - for (const auto& shader : shaders) - { - 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()); - // No uber shader support for VS and CS. - TaskHandle handle = ResourceBuilder::Get().AddShaderBuildTask(shaderType, - inputVSFilePath.c_str(), outputVSFilePath.c_str(), "", callbacks); - newInfo.m_taskHandles.insert(handle); - - } - else if (engine::ShaderType::Fragment == shaderType) - { - std::string inputFSFilePath = engine::Path::GetBuiltinShaderInputPath(shader.c_str()); - std::string outputFSFilePath = engine::Path::GetShaderOutputPath(shader.c_str(), newInfo.m_featuresCombine); - TaskHandle handle = ResourceBuilder::Get().AddShaderBuildTask(engine::ShaderType::Fragment, - inputFSFilePath.c_str(), outputFSFilePath.c_str(), newInfo.m_featuresCombine.c_str(), callbacks); - newInfo.m_taskHandles.insert(handle); - } - else - { - continue; - } - } + const auto& vs = pShaderResource->GetShaderInfo(0); + const auto& fs = pShaderResource->GetShaderInfo(1); - newInfos.emplace(cd::MoveTemp(newInfo)); + TaskHandle vsTaskHandle = ResourceBuilder::Get().AddShaderBuildTask(vs.type, + vs.scPath.c_str(), vs.binPath.c_str(), pShaderResource->GetFeaturesCombine().c_str(), callbacks); + TaskHandle fsTaskHandle = ResourceBuilder::Get().AddShaderBuildTask(fs.type, + fs.scPath.c_str(), fs.binPath.c_str(), pShaderResource->GetFeaturesCombine().c_str(), callbacks); + } + else + { + const auto& shader = pShaderResource->GetShaderInfo(0); + TaskHandle taskHandle = ResourceBuilder::Get().AddShaderBuildTask(shader.type, + shader.scPath.c_str(), shader.binPath.c_str(), pShaderResource->GetFeaturesCombine().c_str(), callbacks); } - - pRenderContext->SetShaderCompileInfos(cd::MoveTemp(newInfos)); } } // namespace editor diff --git a/Engine/Source/Editor/Resources/ShaderBuilder.h b/Engine/Source/Editor/Resources/ShaderBuilder.h index 31132f9b..868c22e1 100644 --- a/Engine/Source/Editor/Resources/ShaderBuilder.h +++ b/Engine/Source/Editor/Resources/ShaderBuilder.h @@ -1,8 +1,8 @@ #pragma once #include "Material/MaterialType.h" +#include "Rendering/Resources/ShaderResource.h" #include "Resources/ResourceBuilder.h" -#include "Rendering/ShaderCompileInfo.h" #include #include @@ -20,12 +20,11 @@ namespace editor class ShaderBuilder { public: - static void CompileRegisteredNonUberShader(engine::RenderContext* pRenderContext); - static void CompileRegisteredUberShader(engine::RenderContext* pRenderContext, engine::MaterialType* pMaterialType); - static void CompileUberShaderAllVariants(engine::RenderContext* pRenderContext, engine::MaterialType* pMaterialType); + static void RegisterUberShaderAllVariants(engine::RenderContext *pRenderContext, engine::MaterialType *pMaterialType); - // Compile specified shader program/program variant. - static void BuildShaderInfos(engine::RenderContext* pRenderContext, TaskOutputCallbacks callbacks = {}); + static void BuildRegisteredShaderResources(engine::RenderContext* pRenderContext, TaskOutputCallbacks callbacks = {}); + static void BuildRecompileShaderResources(engine::RenderContext* pRenderContext, TaskOutputCallbacks callbacks = {}); + static void BuildShaderResource(engine::RenderContext* pRenderContext, engine::ShaderResource* pShaderResource, TaskOutputCallbacks callbacks = {}); }; } // namespace editor diff --git a/Engine/Source/Editor/UILayers/Inspector.cpp b/Engine/Source/Editor/UILayers/Inspector.cpp index 72cf78ab..6d2e2955 100644 --- a/Engine/Source/Editor/UILayers/Inspector.cpp +++ b/Engine/Source/Editor/UILayers/Inspector.cpp @@ -1,14 +1,14 @@ #include "Inspector.h" -#include "Rendering/RenderContext.h" -#include "Rendering/ShaderCollections.h" -#include "Resources/ResourceBuilder.h" -#include "Resources/ResourceLoader.h" -#include "Rendering/Resources/ResourceContext.h" -#include "Rendering/Resources/TextureResource.h" #include "Graphics/GraphicsBackend.h" #include "ImGui/ImGuiUtils.hpp" #include "Path/Path.h" +#include "Rendering/RenderContext.h" +#include "Rendering/Resources/ResourceContext.h" +#include "Rendering/Resources/ShaderResource.h" +#include "Rendering/Resources/TextureResource.h" +#include "Resources/ResourceBuilder.h" +#include "Resources/ResourceLoader.h" #include "ImGui/imfilebrowser.h" @@ -228,7 +228,7 @@ void UpdateComponentWidget(engine::SceneWorld* pScene ImGui::SetCursorScreenPos(ImVec2{ currentPos.x, currentPos.y + 66}); } - ImGuiUtils::ImGuiBoolProperty("Use texture", pPropertyGroup->useTexture); + bool isPropertyGroupChanded = ImGuiUtils::ImGuiBoolProperty("Use texture", pPropertyGroup->useTexture); ImGui::SameLine(130.0f); if (ImGui::Button("Select...")) { @@ -239,15 +239,18 @@ void UpdateComponentWidget(engine::SceneWorld* pScene ImGuiUtils::ImGuiVectorProperty("UV Offset", textureInfo.GetUVOffset(), cd::Unit::None, cd::Vec2f::Zero(), cd::Vec2f::One(), false, 0.01f); ImGuiUtils::ImGuiVectorProperty("UV Scale", textureInfo.GetUVScale()); - if (pPropertyGroup->useTexture) + if (isPropertyGroupChanded) { - pMaterialComponent->ActivateShaderFeature(engine::MaterialTextureTypeToShaderFeature.at(textureType)); - } - else - { - pMaterialComponent->DeactivateShaderFeature(engine::MaterialTextureTypeToShaderFeature.at(textureType)); + if (pPropertyGroup->useTexture) + { + pMaterialComponent->ActivateShaderFeature(engine::MaterialTextureTypeToShaderFeature.at(textureType)); + } + else + { + pMaterialComponent->DeactivateShaderFeature(engine::MaterialTextureTypeToShaderFeature.at(textureType)); + } } - + if (cd::MaterialTextureType::BaseColor == textureType) { ImGuiUtils::ColorPickerProperty("Factor", *(pMaterialComponent->GetFactor(textureType))); @@ -328,13 +331,14 @@ void UpdateComponentWidget(engine::SceneWorld* pScene if (isOpen) { - const auto& shaderProgramName = pMaterialComponent->GetShaderProgramName(); - ImGuiUtils::ImGuiStringProperty("Shader Program", shaderProgramName); - engine::RenderContext* pRenderContext = static_cast(ImGui::GetIO().BackendRendererUserData); - for (const auto& shaderFileName : pRenderContext->GetShaderCollections()->GetShaders(engine::StringCrc{ shaderProgramName })) + const engine::ShaderResource* pShaderResource = pMaterialComponent->GetShaderResource(); + + ImGuiUtils::ImGuiStringProperty("Shader Program", pShaderResource->GetName()); + ImGuiUtils::ImGuiStringProperty("Shader", pShaderResource->GetShaderInfo(0).name); + if (engine::ShaderProgramType::Standard == pShaderResource->GetType()) { - ImGuiUtils::ImGuiStringProperty("Shader", shaderFileName); + ImGuiUtils::ImGuiStringProperty("Shader", pShaderResource->GetShaderInfo(1).name); } ImGui::Separator(); diff --git a/Engine/Source/Editor/UILayers/MainMenu.cpp b/Engine/Source/Editor/UILayers/MainMenu.cpp index f21c2ac2..9a5fb7bd 100644 --- a/Engine/Source/Editor/UILayers/MainMenu.cpp +++ b/Engine/Source/Editor/UILayers/MainMenu.cpp @@ -224,9 +224,18 @@ void MainMenu::BuildMenu() if (ImGui::MenuItem(CD_TEXT("TEXT_BUILD_PBR_VARIANT"))) { - ShaderBuilder::CompileUberShaderAllVariants(GetRenderContext(), pSceneWorld->GetPBRMaterialType()); + ShaderBuilder::RegisterUberShaderAllVariants(GetRenderContext(), pSceneWorld->GetPBRMaterialType()); + ResourceBuilder::Get().Update(); } +#ifdef ENABLE_DDGI + if (ImGui::MenuItem(CD_TEXT("TEXT_BUILD_PBR_VARIANT"))) + { + ShaderBuilder::RegisterUberShaderAllVariants(m_pRenderContext.get(), m_pSceneWorld->GetDDGIMaterialType()); + ResourceBuilder::Get().Update(); + } +#endif + ImGui::EndMenu(); } } diff --git a/Engine/Source/Runtime/ECWorld/MaterialComponent.cpp b/Engine/Source/Runtime/ECWorld/MaterialComponent.cpp index 40965fdc..bb2c1c5a 100644 --- a/Engine/Source/Runtime/ECWorld/MaterialComponent.cpp +++ b/Engine/Source/Runtime/ECWorld/MaterialComponent.cpp @@ -2,6 +2,8 @@ #include "Log/Log.h" #include "Material/MaterialType.h" +#include "Rendering/Resources/ShaderResource.h" +#include "Rendering/Resources/TextureResource.h" #include "Scene/Material.h" #include @@ -39,6 +41,22 @@ void MaterialComponent::Init() m_propertyGroups[cd::MaterialPropertyGroup::Emissive] = cd::MoveTemp(propertyGroup); } +void MaterialComponent::Reset() +{ + m_pMaterialData = nullptr; + m_pMaterialType = nullptr; + m_name.clear(); + m_twoSided = false; + m_blendMode = cd::BlendMode::Opaque; + m_alphaCutOff = 1.0f; + m_isShaderFeaturesDirty = true; + m_isShaderResourceDirty = true; + m_pShaderResource = nullptr; + m_shaderFeatures.clear(); + m_featureCombine.clear(); + m_propertyGroups.clear(); +} + void MaterialComponent::SetMaterialData(const cd::Material* pMaterialData) { m_pMaterialData = pMaterialData; @@ -82,48 +100,62 @@ void MaterialComponent::ActivateShaderFeature(ShaderFeature feature) return; } - for (const auto& conflict : m_pMaterialType->GetShaderSchema().GetConflictFeatureSet(feature)) + if (const auto& optConflictFeatureSet = m_pMaterialType->GetShaderSchema().GetConflictFeatureSet(feature); optConflictFeatureSet.has_value()) { - m_shaderFeatures.erase(conflict); + for (const auto& conflictFeature : optConflictFeatureSet.value()) + { + m_shaderFeatures.erase(conflictFeature); + } } m_shaderFeatures.insert(cd::MoveTemp(feature)); - - m_isShaderFeatureDirty = true; + m_isShaderFeaturesDirty = true; + m_isShaderResourceDirty = true; } void MaterialComponent::DeactivateShaderFeature(ShaderFeature feature) { m_shaderFeatures.erase(feature); - - m_isShaderFeatureDirty = true; + m_isShaderFeaturesDirty = true; + m_isShaderResourceDirty = true; } const std::string& MaterialComponent::GetFeaturesCombine() { - if (false == m_isShaderFeatureDirty) + if (false == m_isShaderFeaturesDirty) { return m_featureCombine; } + m_isShaderFeaturesDirty = false; m_featureCombine = m_pMaterialType->GetShaderSchema().GetFeaturesCombine(m_shaderFeatures); - m_isShaderFeatureDirty = false; return m_featureCombine; } -void MaterialComponent::Reset() +void MaterialComponent::SetShaderFeatures(std::set features) { - m_pMaterialData = nullptr; - m_pMaterialType = nullptr; - m_name.clear(); - m_twoSided = false; - m_blendMode = cd::BlendMode::Opaque; - m_alphaCutOff = 1.0f; - m_isShaderFeatureDirty = false; - m_shaderFeatures.clear(); - m_featureCombine.clear(); - m_propertyGroups.clear(); + m_shaderFeatures = cd::MoveTemp(features); + m_isShaderFeaturesDirty = true; + m_isShaderResourceDirty = true; +} + +void MaterialComponent::SetShaderResource(ShaderResource* pShaderResource) +{ + if (m_pShaderResource) + { + m_pShaderResource->SetActive(false); + } + m_pShaderResource = pShaderResource; + m_pShaderResource->SetActive(true); + + m_isShaderResourceDirty = false; +} + +ShaderResource* MaterialComponent::GetShaderResource() const +{ + assert(!m_isShaderResourceDirty); + return m_pShaderResource; } TextureResource* MaterialComponent::GetTextureResource(cd::MaterialTextureType textureType) const diff --git a/Engine/Source/Runtime/ECWorld/MaterialComponent.h b/Engine/Source/Runtime/ECWorld/MaterialComponent.h index 4ee1b302..0f7571f6 100644 --- a/Engine/Source/Runtime/ECWorld/MaterialComponent.h +++ b/Engine/Source/Runtime/ECWorld/MaterialComponent.h @@ -32,6 +32,7 @@ namespace engine class MaterialType; class RenderContext; +class ShaderResource; class TextureResource; class MaterialComponent final @@ -89,6 +90,7 @@ class MaterialComponent final ~MaterialComponent() = default; void Init(); + void Reset(); void SetMaterialData(const cd::Material* pMaterialData); cd::Material* GetMaterialData() { return const_cast(m_pMaterialData); } @@ -97,21 +99,25 @@ class MaterialComponent final void SetMaterialType(const engine::MaterialType* pMaterialType) { m_pMaterialType = pMaterialType; } const engine::MaterialType* GetMaterialType() const { return m_pMaterialType; } - void Reset(); - // Basic data. void SetName(std::string name) { m_name = cd::MoveTemp(name); } std::string& GetName() { return m_name; } const std::string& GetName() const { return m_name; } const std::string& GetShaderProgramName() const; - // Uber shader data. + // Uber shader + // Activa one Feature will erase all conflicting Features. void ActivateShaderFeature(ShaderFeature feature); void DeactivateShaderFeature(ShaderFeature feature); - void SetShaderFeatures(std::set options) { m_shaderFeatures = cd::MoveTemp(m_shaderFeatures); } + const std::string& GetFeaturesCombine(); + + void SetShaderFeatures(std::set features); std::set& GetShaderFeatures() { return m_shaderFeatures; } const std::set& GetShaderFeatures() const { return m_shaderFeatures; } - const std::string& GetFeaturesCombine(); + + bool IsShaderResourceDirty() const { return m_isShaderResourceDirty; } + void SetShaderResource(ShaderResource* pShaderResource); + ShaderResource* GetShaderResource() const; // Texture data. TextureResource* GetTextureResource(cd::MaterialTextureType textureType) const; @@ -174,30 +180,30 @@ class MaterialComponent final float& GetAlphaCutOff() { return m_alphaCutOff; } float GetAlphaCutOff() const { return m_alphaCutOff; } - void SetToonParameters(ToonParameters toonParameters) { m_toonParameters = toonParameters; } - ToonParameters& GetToonParameters() { return m_toonParameters; } - ToonParameters GetToonParameters() const { return m_toonParameters; } - void SetIblStrengeth(float strength) { m_iblStrength = strength; } float& GetIblStrengeth() { return m_iblStrength; } float GetIblStrengeth() const { return m_iblStrength; } + void SetToonParameters(ToonParameters toonParameters) { m_toonParameters = toonParameters; } + ToonParameters& GetToonParameters() { return m_toonParameters; } + ToonParameters GetToonParameters() const { return m_toonParameters; } + private: // Input std::string m_name; const cd::Material* m_pMaterialData = nullptr; const engine::MaterialType* m_pMaterialType = nullptr; - bool m_twoSided; - bool m_isOpenOutLine; - cd::BlendMode m_blendMode; - float m_alphaCutOff; - - bool m_isShaderFeatureDirty = false; - std::set m_shaderFeatures; + bool m_isShaderFeaturesDirty = true; + bool m_isShaderResourceDirty = true; std::string m_featureCombine; + std::set m_shaderFeatures; + ShaderResource* m_pShaderResource = nullptr; // Output + bool m_twoSided; + cd::BlendMode m_blendMode; + float m_alphaCutOff; float m_iblStrength = 0.5f; ToonParameters m_toonParameters; std::map m_propertyGroups; diff --git a/Engine/Source/Runtime/ECWorld/ParticleEmitterComponent.cpp b/Engine/Source/Runtime/ECWorld/ParticleEmitterComponent.cpp index 32dc1ac7..69093d6d 100644 --- a/Engine/Source/Runtime/ECWorld/ParticleEmitterComponent.cpp +++ b/Engine/Source/Runtime/ECWorld/ParticleEmitterComponent.cpp @@ -303,13 +303,16 @@ void ParticleEmitterComponent::ActivateShaderFeature(ShaderFeature feature) return; } - for (const auto& conflict : m_pParticleMaterialType->GetShaderSchema().GetConflictFeatureSet(feature)) + // TODO : Should remove uber shader stuff from ParticleEmitterComponent. + if (const auto& optConflictFeatureSet = m_pParticleMaterialType->GetShaderSchema().GetConflictFeatureSet(feature); optConflictFeatureSet.has_value()) { - m_shaderFeatures.erase(conflict); + for (const auto& conflictFeature : optConflictFeatureSet.value()) + { + m_shaderFeatures.erase(conflictFeature); + } } m_shaderFeatures.insert(cd::MoveTemp(feature)); - m_isShaderFeatureDirty = true; } diff --git a/Engine/Source/Runtime/Material/ShaderSchema.cpp b/Engine/Source/Runtime/Material/ShaderSchema.cpp index 27c169e9..210e4053 100644 --- a/Engine/Source/Runtime/Material/ShaderSchema.cpp +++ b/Engine/Source/Runtime/Material/ShaderSchema.cpp @@ -1,6 +1,5 @@ #include "ShaderSchema.h" -#include "Base/Template.h" #include "Log/Log.h" #include @@ -10,29 +9,6 @@ namespace engine { -void ShaderSchema::SetShaderProgramName(std::string name) -{ - m_shaderProgramName = cd::MoveTemp(name); -} - -void ShaderSchema::AddFeatureSet(ShaderFeatureSet featureSet) -{ - for (const auto& existingFeatureSet : m_shaderFeatureSets) - { - for (const auto& newFeature : featureSet) - { - if (existingFeatureSet.find(newFeature) != existingFeatureSet.end()) - { - CD_ENGINE_WARN("Shader feature {0} repetitive, skip current feature set adding!", GetFeatureName(newFeature)); - return; - } - } - } - - m_isDirty = true; - m_shaderFeatureSets.insert(cd::MoveTemp(featureSet)); -} - void ShaderSchema::Build() { if (!m_isDirty) @@ -42,7 +18,6 @@ void ShaderSchema::Build() } CleanBuild(); - m_isDirty = false; for (const auto& featureSet : m_shaderFeatureSets) { @@ -76,8 +51,9 @@ void ShaderSchema::Build() } } - // Should ShaderSchema handle uber shader without shader feature? + // ShaderScheme also handles case without ShaderFeature. m_allFeatureCombines.insert(""); + m_isDirty = false; } void ShaderSchema::CleanBuild() @@ -94,7 +70,26 @@ void ShaderSchema::CleanAll() m_shaderFeatureSets.clear(); } -const ShaderFeatureSet ShaderSchema::GetConflictFeatureSet(const ShaderFeature feature) const +void ShaderSchema::AddFeatureSet(ShaderFeatureSet featureSet) +{ + // We trate shader features as set to handel mutually exclusive keywords. + for (const auto& existingFeatureSet : m_shaderFeatureSets) + { + for (const auto& newFeature : featureSet) + { + if (existingFeatureSet.find(newFeature) != existingFeatureSet.end()) + { + CD_ENGINE_WARN("Shader feature {0} repetitive, skip current feature set adding!", GetFeatureName(newFeature)); + return; + } + } + } + + m_isDirty = true; + m_shaderFeatureSets.insert(cd::MoveTemp(featureSet)); +} + +std::optional ShaderSchema::GetConflictFeatureSet(const ShaderFeature feature) const { for (const auto& shaderFeatureSet : m_shaderFeatureSets) { @@ -104,7 +99,7 @@ const ShaderFeatureSet ShaderSchema::GetConflictFeatureSet(const ShaderFeature f } } - return ShaderFeatureSet{}; + return std::nullopt; } std::string ShaderSchema::GetFeaturesCombine(const ShaderFeatureSet& featureSet) const @@ -115,30 +110,34 @@ std::string ShaderSchema::GetFeaturesCombine(const ShaderFeatureSet& featureSet) } std::stringstream ss; - // Use the option order in m_shaderFeatureSets to ensure that inputs in different orders can get a same StringCrc. + // Use the Shader Feature order in m_shaderFeatureSets to ensure that inputs in different orders can get a same StringCrc. for (const auto& registeredSet : m_shaderFeatureSets) { - // Ignore option which contain in parameter but not contain in m_shaderFeatureSets. + // Ignore Shader Feature which contain in parameter but not contain in m_shaderFeatureSets. for (const auto& registeredFeature : registeredSet) { if (featureSet.find(registeredFeature) != featureSet.end()) { + // We assume that theres no conflicting Features in the incoming featureSet parameter. ss << GetFeatureName(registeredFeature); + continue; } } - } + return ss.str(); } -StringCrc ShaderSchema::GetFeaturesCombineCrc(const ShaderFeatureSet& featureSet) const +std::set& ShaderSchema::GetAllFeatureCombines() { - if (m_shaderFeatureSets.empty() || featureSet.empty()) - { - return DefaultUberShaderCrc; - } + assert(!m_isDirty); + return m_allFeatureCombines; +} - return StringCrc(GetFeaturesCombine(featureSet)); +const std::set& ShaderSchema::GetAllFeatureCombines() const +{ + assert(!m_isDirty); + return m_allFeatureCombines; } } \ No newline at end of file diff --git a/Engine/Source/Runtime/Material/ShaderSchema.h b/Engine/Source/Runtime/Material/ShaderSchema.h index d714778e..fc85d1e5 100644 --- a/Engine/Source/Runtime/Material/ShaderSchema.h +++ b/Engine/Source/Runtime/Material/ShaderSchema.h @@ -1,6 +1,7 @@ #pragma once #include "Core/StringCrc.h" +#include "Base/Template.h" #include "Rendering/ShaderFeature.h" #include @@ -40,32 +41,29 @@ class ShaderSchema ShaderSchema& operator=(ShaderSchema&&) = default; ~ShaderSchema() = default; - void SetShaderProgramName(std::string name); + void SetShaderProgramName(std::string name) { m_shaderProgramName = cd::MoveTemp(name); } std::string& GetShaderProgramName() { return m_shaderProgramName; } const std::string& GetShaderProgramName() const { return m_shaderProgramName; } - void AddFeatureSet(ShaderFeatureSet featureSet); - void Build(); void CleanBuild(); void CleanAll(); - const ShaderFeatureSet GetConflictFeatureSet(const ShaderFeature feature) const; - + void AddFeatureSet(ShaderFeatureSet featureSet); + std::optional GetConflictFeatureSet(const ShaderFeature feature) const; std::string GetFeaturesCombine(const ShaderFeatureSet& featureSet) const; - StringCrc GetFeaturesCombineCrc(const ShaderFeatureSet& featureSet) const; - std::set& GetFeatures() { return m_shaderFeatureSets; } - const std::set& GetFeatures() const { return m_shaderFeatureSets; } + std::set& GetFeatureSets() { return m_shaderFeatureSets; } + const std::set& GetFeatureSets() const { return m_shaderFeatureSets; } - std::set& GetAllFeatureCombines() { return m_allFeatureCombines; } - const std::set& GetAllFeatureCombines() const { return m_allFeatureCombines; } + std::set& GetAllFeatureCombines(); + const std::set& GetAllFeatureCombines() const; private: std::string m_shaderProgramName; bool m_isDirty = false; - // Registration order of shader features. + // Registration order of shader feature sets. std::set m_shaderFeatureSets; // All permutations matching the registered shader features. std::set m_allFeatureCombines; diff --git a/Engine/Source/Runtime/Rendering/AABBRenderer.cpp b/Engine/Source/Runtime/Rendering/AABBRenderer.cpp index 69ad57b8..13ac9803 100644 --- a/Engine/Source/Runtime/Rendering/AABBRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/AABBRenderer.cpp @@ -5,6 +5,7 @@ #include "ECWorld/StaticMeshComponent.h" #include "ECWorld/TransformComponent.h" #include "Rendering/RenderContext.h" +#include "Rendering/Resources/ShaderResource.h" #include "Scene/Texture.h" namespace engine @@ -12,17 +13,11 @@ namespace engine void AABBRenderer::Init() { - constexpr StringCrc programCrc = StringCrc("AABBProgram"); - GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_AABB", "fs_AABB" }); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("AABBProgram", "vs_AABB", "fs_AABB")); bgfx::setViewName(GetViewID(), "AABBRenderer"); } -void AABBRenderer::Warmup() -{ - GetRenderContext()->UploadShaderProgram("AABBProgram"); -} - void AABBRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { UpdateViewRenderTarget(); @@ -31,6 +26,15 @@ void AABBRenderer::UpdateView(const float* pViewMatrix, const float* pProjection void AABBRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + for (Entity entity : m_pCurrentSceneWorld->GetCollisionMeshEntities()) { auto* pCollisionMesh = m_pCurrentSceneWorld->GetCollisionMeshComponent(entity); @@ -52,7 +56,8 @@ 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); - GetRenderContext()->Submit(GetViewID(), "AABBProgram"); + constexpr StringCrc programHandleIndex{ "AABBProgram" }; + GetRenderContext()->Submit(GetViewID(), programHandleIndex); } } diff --git a/Engine/Source/Runtime/Rendering/AABBRenderer.h b/Engine/Source/Runtime/Rendering/AABBRenderer.h index b707a658..32145ce5 100644 --- a/Engine/Source/Runtime/Rendering/AABBRenderer.h +++ b/Engine/Source/Runtime/Rendering/AABBRenderer.h @@ -15,7 +15,6 @@ 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 8e805724..7642b701 100644 --- a/Engine/Source/Runtime/Rendering/AnimationRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/AnimationRenderer.cpp @@ -5,10 +5,10 @@ #include "ECWorld/StaticMeshComponent.h" #include "ECWorld/TransformComponent.h" #include "Rendering/RenderContext.h" +#include "Rendering/Resources/ShaderResource.h" #include "Scene/Texture.h" #include -//#include namespace engine { @@ -136,13 +136,9 @@ void CalculateBoneTransform(std::vector& boneMatrices, const cd:: void AnimationRenderer::Init() { 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", "fs_visualize_bone_weight"); #endif } @@ -187,8 +183,14 @@ void AnimationRenderer::Render(float deltaTime) MaterialComponent* pMaterialComponent = m_pCurrentSceneWorld->GetMaterialComponent(entity); if (!pMaterialComponent || - pMaterialComponent->GetMaterialType() != m_pCurrentSceneWorld->GetAnimationMaterialType() || - !GetRenderContext()->IsShaderProgramValid(pMaterialComponent->GetShaderProgramName(), pMaterialComponent->GetFeaturesCombine())) + pMaterialComponent->GetMaterialType() != m_pCurrentSceneWorld->GetAnimationMaterialType()) + { + continue; + } + + const ShaderResource* pShaderResource = pMaterialComponent->GetShaderResource(); + if (ResourceStatus::Ready != pShaderResource->GetStatus() && + ResourceStatus::Optimized != pShaderResource->GetStatus()) { continue; } @@ -218,7 +220,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); - GetRenderContext()->Submit(GetViewID(), pMaterialComponent->GetShaderProgramName()); + GetRenderContext()->Submit(GetViewID(), pShaderResource->GetHandle()); } } diff --git a/Engine/Source/Runtime/Rendering/AnimationRenderer.h b/Engine/Source/Runtime/Rendering/AnimationRenderer.h index aeb18f4f..694c6827 100644 --- a/Engine/Source/Runtime/Rendering/AnimationRenderer.h +++ b/Engine/Source/Runtime/Rendering/AnimationRenderer.h @@ -15,7 +15,6 @@ 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 659b0c23..2ade8034 100644 --- a/Engine/Source/Runtime/Rendering/BlendShapeRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/BlendShapeRenderer.cpp @@ -11,10 +11,11 @@ #include "Material/ShaderSchema.h" #include "Math/Transform.hpp" #include "RenderContext.h" +#include "Rendering/Resources/ShaderResource.h" #include "Scene/Texture.h" -#include "U_IBL.sh" #include "U_AtmophericScattering.sh" #include "U_BlendShape.sh" +#include "U_IBL.sh" namespace engine { @@ -30,32 +31,24 @@ 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"); +constexpr StringCrc BlendShapeWeightsProgramCrc{ BlendShapeWeightsProgram }; +constexpr StringCrc BlendShapeWeightPosProgramCrc{ BlendShapeWeightPosProgram }; +constexpr StringCrc BlendShapeFinalPosProgramCrc{ BlendShapeFinalPosProgram }; +constexpr StringCrc BlendShapeUpdatePosProgramCrc{ 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"); -} + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("BlendShapeWeightsProgram", "cs_blendshape_weights", ShaderProgramType::Compute)); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("BlendShapeWeightPosProgram", "cs_blendshape_weight_pos", ShaderProgramType::Compute)); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("BlendShapeFinalPosProgram", "cs_blendshape_final_pos", ShaderProgramType::Compute)); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("BlendShapeUpdatePosProgram", "cs_blendshape_update_pos", ShaderProgramType::Compute)); -void BlendShapeRenderer::Warmup() -{ GetRenderContext()->CreateUniform(morphCountVertexCount, bgfx::UniformType::Vec4, 1); GetRenderContext()->CreateUniform(changedWeight, bgfx::UniformType::Vec4, 1); - GetRenderContext()->UploadShaderProgram(BlendShapeWeightsProgram); - GetRenderContext()->UploadShaderProgram(BlendShapeWeightPosProgram); - GetRenderContext()->UploadShaderProgram(BlendShapeFinalPosProgram); - GetRenderContext()->UploadShaderProgram(BlendShapeUpdatePosProgram); + bgfx::setViewName(GetViewID(), "BlendShapeRenderer"); } void BlendShapeRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -66,6 +59,15 @@ void BlendShapeRenderer::UpdateView(const float* pViewMatrix, const float* pProj void BlendShapeRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + for (Entity entity : m_pCurrentSceneWorld->GetBlendShapeEntities()) { // No blend shape? @@ -86,18 +88,18 @@ void BlendShapeRenderer::Render(float deltaTime) constexpr StringCrc morphCountVertexCountCrc(morphCountVertexCount); cd::Vec4f morphCount{ static_cast(pBlendShapeComponent->GetActiveMorphCount()), static_cast(pBlendShapeComponent->GetMeshVertexCount()), 0, 0}; GetRenderContext()->FillUniform(morphCountVertexCountCrc, &morphCount, 1); - GetRenderContext()->Dispatch(viewId, BlendShapeWeightsProgram, 1U, 1U, 1U); + GetRenderContext()->Dispatch(viewId, BlendShapeWeightsProgramCrc, 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); - GetRenderContext()->Dispatch(viewId, BlendShapeWeightPosProgram, 1U, 1U, 1U); + GetRenderContext()->Dispatch(viewId, BlendShapeWeightPosProgramCrc, 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); - GetRenderContext()->Dispatch(viewId, BlendShapeFinalPosProgram, 1U, 1U, 1U); + GetRenderContext()->Dispatch(viewId, BlendShapeFinalPosProgramCrc, 1U, 1U, 1U); pBlendShapeComponent->SetDirty(false); } @@ -113,7 +115,7 @@ 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); - GetRenderContext()->Dispatch(viewId, BlendShapeUpdatePosProgram, 1U, 1U, 1U); + GetRenderContext()->Dispatch(viewId, BlendShapeUpdatePosProgramCrc, 1U, 1U, 1U); pBlendShapeComponent->ClearNeedUpdate(); } diff --git a/Engine/Source/Runtime/Rendering/BlendShapeRenderer.h b/Engine/Source/Runtime/Rendering/BlendShapeRenderer.h index ec748963..3b7a258a 100644 --- a/Engine/Source/Runtime/Rendering/BlendShapeRenderer.h +++ b/Engine/Source/Runtime/Rendering/BlendShapeRenderer.h @@ -13,7 +13,6 @@ 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 18d255a2..12ebbbdb 100644 --- a/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.cpp +++ b/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.cpp @@ -14,10 +14,6 @@ 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 410ddd58..e74c4868 100644 --- a/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.h +++ b/Engine/Source/Runtime/Rendering/BlitRenderTargetPass.h @@ -12,7 +12,6 @@ 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 7a3e1b5c..1006fd11 100644 --- a/Engine/Source/Runtime/Rendering/BloomRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/BloomRenderer.cpp @@ -1,29 +1,50 @@ #include "BloomRenderer.h" #include "Rendering/RenderContext.h" +#include "Rendering/Resources/ShaderResource.h" #include namespace engine { +namespace +{ + +constexpr const char* CapTureBrightnessProgram = "CapTureBrightnessProgram"; +constexpr const char* DownSampleProgram = "DownSampleProgram"; +constexpr const char* BlurVerticalProgram = "BlurVerticalProgram"; +constexpr const char* BlurHorizontalProgram = "BlurHorizontalProgram"; +constexpr const char* UpSampleProgram = "UpSampleProgram"; +constexpr const char* KawaseBlurProgram = "KawaseBlurProgram"; +constexpr const char* CombineProgram = "CombineProgram"; + +constexpr StringCrc CapTureBrightnessProgramCrc{ CapTureBrightnessProgram }; +constexpr StringCrc DownSampleProgramCrc{ DownSampleProgram }; +constexpr StringCrc BlurVerticalProgramCrc{ BlurVerticalProgram }; +constexpr StringCrc BlurHorizontalProgramCrc{ BlurHorizontalProgram }; +constexpr StringCrc UpSampleProgramCrc{ UpSampleProgram }; +constexpr StringCrc KawaseBlurProgramCrc{ KawaseBlurProgram }; +constexpr StringCrc CombineProgramCrc{ CombineProgram }; + +} + 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" }); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram(CapTureBrightnessProgram, "vs_fullscreen", "fs_captureBrightness")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram(DownSampleProgram, "vs_fullscreen", "fs_dowmsample")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram(BlurVerticalProgram, "vs_fullscreen", "fs_blurvertical")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram(BlurHorizontalProgram, "vs_fullscreen", "fs_blurhorizontal")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram(UpSampleProgram, "vs_fullscreen", "fs_upsample")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram(KawaseBlurProgram, "vs_fullscreen", "fs_kawaseblur")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram(CombineProgram, "vs_fullscreen", "fs_bloom")); + + 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); bgfx::setViewName(GetViewID(), "BloomRenderer"); @@ -68,24 +89,6 @@ void BloomRenderer::AllocateViewIDs() m_blitColorPassID = GetRenderContext()->CreateView(); } -void BloomRenderer::Warmup() -{ - 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::SetEnable(bool value) { Entity entity = m_pCurrentSceneWorld->GetMainCameraEntity(); @@ -148,6 +151,15 @@ void BloomRenderer::UpdateView(const float* pViewMatrix, const float* pProjectio void BloomRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + constexpr StringCrc sceneRenderTarget("SceneRenderTarget"); const RenderTarget* pInputRT = GetRenderContext()->GetRenderTarget(sceneRenderTarget); @@ -188,7 +200,7 @@ void BloomRenderer::Render(float deltaTime) bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - GetRenderContext()->Submit(GetViewID(), "CapTureBrightnessProgram"); + GetRenderContext()->Submit(GetViewID(), CapTureBrightnessProgramCrc); // downsample int sampleTimes = std::min(pCameraComponent->GetBloomDownSampleTimes(), pCameraComponent->GetBloomDownSampleMaxTimes()); @@ -218,7 +230,7 @@ void BloomRenderer::Render(float deltaTime) bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - GetRenderContext()->Submit(m_startDowmSamplePassID + sampleIndex, "DownSampleProgram"); + GetRenderContext()->Submit(m_startDowmSamplePassID + sampleIndex, DownSampleProgramCrc); } if (pCameraComponent->GetIsBlurEnable() && pCameraComponent->GetBlurTimes() != 0) @@ -261,7 +273,7 @@ void BloomRenderer::Render(float deltaTime) bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_BLEND_ADD); Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - GetRenderContext()->Submit(m_startUpSamplePassID + sampleIndex, "UpSampleProgram"); + GetRenderContext()->Submit(m_startUpSamplePassID + sampleIndex, UpSampleProgramCrc); } // combine @@ -279,7 +291,7 @@ void BloomRenderer::Render(float deltaTime) bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - GetRenderContext()->Submit(m_combinePassID, "CombineProgram"); + GetRenderContext()->Submit(m_combinePassID, CombineProgramCrc); bgfx::blit(m_blitColorPassID, screenTextureHandle, 0, 0, bgfx::getTexture(m_combineFB)); } @@ -322,7 +334,7 @@ void BloomRenderer::Blur(uint16_t width, uint16_t height, int iteration, float b bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - GetRenderContext()->Submit(verticalViewID, "KawaseBlurProgram"); + GetRenderContext()->Submit(verticalViewID, KawaseBlurProgramCrc); //constexpr StringCrc BlurHorizontalprogramName("BlurVerticalProgram"); // use Gaussian Blur //bgfx::submit(horizontal, GetRenderContext()->GetProgram(BlurHorizontalprogramName)); @@ -340,7 +352,7 @@ void BloomRenderer::Blur(uint16_t width, uint16_t height, int iteration, float b bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - GetRenderContext()->Submit(horizontalViewID, "KawaseBlurProgram"); + GetRenderContext()->Submit(horizontalViewID, KawaseBlurProgramCrc); //constexpr StringCrc BlurVerticalprogramName("BlurVerticalProgram"); // use Gaussian Blur //bgfx::submit(horizontal, GetRenderContext()->GetProgram(BlurVerticalprogramName)); diff --git a/Engine/Source/Runtime/Rendering/BloomRenderer.h b/Engine/Source/Runtime/Rendering/BloomRenderer.h index 3988a1e4..04f3bb38 100644 --- a/Engine/Source/Runtime/Rendering/BloomRenderer.h +++ b/Engine/Source/Runtime/Rendering/BloomRenderer.h @@ -16,7 +16,6 @@ namespace engine 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/CelluloidRenderer.cpp b/Engine/Source/Runtime/Rendering/CelluloidRenderer.cpp index f3c00a37..5430a1bf 100644 --- a/Engine/Source/Runtime/Rendering/CelluloidRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/CelluloidRenderer.cpp @@ -11,6 +11,7 @@ #include "Math/Transform.hpp" #include "Rendering/RenderContext.h" #include "Rendering/Resources/MeshResource.h" +#include "Rendering/Resources/ShaderResource.h" #include "Rendering/Resources/TextureResource.h" #include "Scene/Texture.h" #include "U_AtmophericScattering.sh" @@ -36,11 +37,6 @@ constexpr uint64_t defaultRenderingState = BGFX_STATE_WRITE_MASK | BGFX_STATE_MS } void CelluloidRenderer::Init() -{ - bgfx::setViewName(GetViewID(), "CelluloidRenderer"); -} - -void CelluloidRenderer::Warmup() { GetRenderContext()->CreateUniform(dividLine, bgfx::UniformType::Vec4, 1); GetRenderContext()->CreateUniform(specular, bgfx::UniformType::Vec4, 1); @@ -49,6 +45,8 @@ void CelluloidRenderer::Warmup() GetRenderContext()->CreateUniform(rimLight, bgfx::UniformType::Vec4, 1); GetRenderContext()->CreateUniform(rimLightColor, bgfx::UniformType::Vec4, 1); GetRenderContext()->CreateUniform(albedoUVOffsetAndScale, bgfx::UniformType::Vec4, 1); + + bgfx::setViewName(GetViewID(), "CelluloidRenderer"); } void CelluloidRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -70,6 +68,14 @@ void CelluloidRenderer::Render(float deltaTime) { continue; } + + const ShaderResource* pShaderResource = pMaterialComponent->GetShaderResource(); + if (ResourceStatus::Ready != pShaderResource->GetStatus() && + ResourceStatus::Optimized != pShaderResource->GetStatus()) + { + continue; + } + bool textureSlotBindTable[32] = { false }; for (const auto& [textureType, propertyGroup] : pMaterialComponent->GetPropertyGroups()) { @@ -117,7 +123,7 @@ void CelluloidRenderer::Render(float deltaTime) constexpr StringCrc rimLightCrc(rimLight); GetRenderContext()->FillUniform(rimLightCrc, pMaterialComponent->GetToonParameters().rimLight.begin(), 1); - GetRenderContext()->Submit(GetViewID(), pMaterialComponent->GetShaderProgramName(), pMaterialComponent->GetFeaturesCombine()); + GetRenderContext()->Submit(GetViewID(), pShaderResource->GetHandle()); } } diff --git a/Engine/Source/Runtime/Rendering/CelluloidRenderer.h b/Engine/Source/Runtime/Rendering/CelluloidRenderer.h index 88410495..8dac3d87 100644 --- a/Engine/Source/Runtime/Rendering/CelluloidRenderer.h +++ b/Engine/Source/Runtime/Rendering/CelluloidRenderer.h @@ -15,7 +15,6 @@ namespace engine 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/ImGuiRenderer.cpp b/Engine/Source/Runtime/Rendering/ImGuiRenderer.cpp index 5862a700..1804fe0d 100644 --- a/Engine/Source/Runtime/Rendering/ImGuiRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/ImGuiRenderer.cpp @@ -2,6 +2,8 @@ #include "Core/StringCrc.h" #include "Rendering/RenderContext.h" +#include "Rendering/Resources/ResourceContext.h" +#include "Rendering/Resources/ShaderResource.h" #include @@ -10,14 +12,8 @@ namespace engine void ImGuiRenderer::Init() { - constexpr StringCrc programCrc = StringCrc("ImGuiProgram"); - GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_imgui", "fs_imgui" }); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ImGuiProgram", "vs_imgui", "fs_imgui")); - bgfx::setViewName(GetViewID(), "ImGuiRenderer"); -} - -void ImGuiRenderer::Warmup() -{ constexpr StringCrc imguiVertexLayoutName("imgui_vertex_layout"); if (0 == GetRenderContext()->GetVertexAttributeLayouts(imguiVertexLayoutName).m_stride) { @@ -31,7 +27,8 @@ void ImGuiRenderer::Warmup() } GetRenderContext()->CreateUniform("s_tex", bgfx::UniformType::Sampler); - GetRenderContext()->UploadShaderProgram("ImGuiProgram"); + + bgfx::setViewName(GetViewID(), "ImGuiRenderer"); } void ImGuiRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -79,6 +76,15 @@ void ImGuiRenderer::UpdateView(const float* pViewMatrix, const float* pProjectio void ImGuiRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + ImDrawData* pImGuiDrawData = ImGui::GetDrawData(); int frameBufferWidth = static_cast(pImGuiDrawData->DisplaySize.x * pImGuiDrawData->FramebufferScale.x); @@ -172,7 +178,8 @@ void ImGuiRenderer::Render(float deltaTime) pEncoder->setVertexBuffer(0, &vertexBuffer, cmd->VtxOffset, numVertices); pEncoder->setIndexBuffer(&indexBuffer, cmd->IdxOffset, cmd->ElemCount); - pEncoder->submit(GetViewID(), GetRenderContext()->GetShaderProgramHandle("ImGuiProgram")); + constexpr StringCrc programHandleIndex{ "ImGuiProgram" }; + pEncoder->submit(GetViewID(), bgfx::ProgramHandle{ GetRenderContext()->GetResourceContext()->GetShaderResource(programHandleIndex)->GetHandle()}); } } } diff --git a/Engine/Source/Runtime/Rendering/ImGuiRenderer.h b/Engine/Source/Runtime/Rendering/ImGuiRenderer.h index 7ade340d..50443a13 100644 --- a/Engine/Source/Runtime/Rendering/ImGuiRenderer.h +++ b/Engine/Source/Runtime/Rendering/ImGuiRenderer.h @@ -11,7 +11,6 @@ class ImGuiRenderer final : public engine::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/OutLineRenderer.cpp b/Engine/Source/Runtime/Rendering/OutLineRenderer.cpp index 642916ef..fd7b1ffa 100644 --- a/Engine/Source/Runtime/Rendering/OutLineRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/OutLineRenderer.cpp @@ -5,6 +5,7 @@ #include "ECWorld/StaticMeshComponent.h" #include "ECWorld/TransformComponent.h" #include "Rendering/RenderContext.h" +#include "Rendering/Resources/ShaderResource.h" #include "Scene/Texture.h" namespace engine @@ -20,16 +21,12 @@ constexpr const char* outLineSize = "u_outLineSize"; void OutLineRenderer::Init() { - constexpr StringCrc programCrc = StringCrc("OutLineProgram"); - GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_outline", "fs_outline" }); - bgfx::setViewName(GetViewID(), "OutLineRenderer"); -} + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("OutLineProgram", "vs_outline", "fs_outline")); -void OutLineRenderer::Warmup() -{ GetRenderContext()->CreateUniform(outLineColor, bgfx::UniformType::Vec4, 1); GetRenderContext()->CreateUniform(outLineSize, bgfx::UniformType::Vec4, 1); - GetRenderContext()->UploadShaderProgram("OutLineProgram"); + + bgfx::setViewName(GetViewID(), "OutLineRenderer"); } void OutLineRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -40,6 +37,15 @@ void OutLineRenderer::UpdateView(const float* pViewMatrix, const float* pProject void OutLineRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + for (Entity entity : m_pCurrentSceneWorld->GetStaticMeshEntities()) { StaticMeshComponent* pMeshComponent = m_pCurrentSceneWorld->GetStaticMeshComponent(entity); @@ -79,7 +85,8 @@ void OutLineRenderer::Render(float deltaTime) constexpr uint64_t state = BGFX_STATE_WRITE_MASK | BGFX_STATE_MSAA | BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_CULL_CW; bgfx::setState(state); - SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), "OutLineProgram", pMaterialComponent->GetFeaturesCombine()); + constexpr StringCrc programHandleIndex{ "OutLineProgram" }; + SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), programHandleIndex); } } diff --git a/Engine/Source/Runtime/Rendering/OutLineRenderer.h b/Engine/Source/Runtime/Rendering/OutLineRenderer.h index 3bbc22fd..9b0dca0e 100644 --- a/Engine/Source/Runtime/Rendering/OutLineRenderer.h +++ b/Engine/Source/Runtime/Rendering/OutLineRenderer.h @@ -15,7 +15,6 @@ namespace engine 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/PBRSkyRenderer.cpp b/Engine/Source/Runtime/Rendering/PBRSkyRenderer.cpp index 7cdfc3b3..1bd106a4 100644 --- a/Engine/Source/Runtime/Rendering/PBRSkyRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/PBRSkyRenderer.cpp @@ -6,6 +6,7 @@ #include "Math/Box.hpp" #include "Rendering/RenderContext.h" #include "Rendering/Resources/MeshResource.h" +#include "Rendering/Resources/ShaderResource.h" #include "Scene/Mesh.h" #include "Scene/VertexFormat.h" #include "U_AtmophericScattering.sh" @@ -27,6 +28,15 @@ constexpr const char* ProgramComputeScatteringDensity = "ProgramComputeScatte constexpr const char* ProgramComputeIndirectIrradiance = "ProgramComputeIndirectIrradiance"; constexpr const char* ProgramComputeMultipleScattering = "ProgramComputeMultipleScattering"; +constexpr StringCrc ProgramAtmosphericScatteringLUTCrc{ ProgramAtmosphericScatteringLUT }; +constexpr StringCrc ProgramSingleScatteringRayMarchingCrc{ ProgramSingleScatteringRayMarching }; +constexpr StringCrc ProgramComputeTransmittanceCrc{ ProgramComputeTransmittance }; +constexpr StringCrc ProgramComputeDirectIrradianceCrc{ ProgramComputeDirectIrradiance }; +constexpr StringCrc ProgramComputeSingleScatteringCrc{ ProgramComputeSingleScattering }; +constexpr StringCrc ProgramComputeScatteringDensityCrc{ ProgramComputeScatteringDensity }; +constexpr StringCrc ProgramComputeIndirectIrradianceCrc{ ProgramComputeIndirectIrradiance }; +constexpr StringCrc ProgramComputeMultipleScatteringCrc{ ProgramComputeMultipleScattering }; + constexpr const char* TextureTransmittance = "TextureTransmittance"; constexpr const char* TextureIrradiance = "TextureIrradiance"; constexpr const char* TextureScattering = "TextureScattering"; @@ -50,29 +60,15 @@ constexpr uint16_t ScatteringOrders = 6; void PBRSkyRenderer::Init() { - constexpr StringCrc ProgramAtmosphericScatteringLUTCrc(ProgramAtmosphericScatteringLUT); - constexpr StringCrc ProgramSingleScatteringRayMarchingCrc(ProgramSingleScatteringRayMarching); - constexpr StringCrc ProgramComputeTransmittanceCrc(ProgramComputeTransmittance); - constexpr StringCrc ProgramComputeDirectIrradianceCrc(ProgramComputeDirectIrradiance); - constexpr StringCrc ProgramComputeSingleScatteringCrc(ProgramComputeSingleScattering); - constexpr StringCrc ProgramComputeScatteringDensityCrc(ProgramComputeScatteringDensity); - constexpr StringCrc ProgramComputeIndirectIrradianceCrc(ProgramComputeIndirectIrradiance); - constexpr StringCrc ProgramComputeMultipleScatteringCrc(ProgramComputeMultipleScattering); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ProgramAtmosphericScatteringLUT", "vs_atmSkyBox", "fs_PrecomputedAtmosphericScattering_LUT")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ProgramSingleScatteringRayMarching", "vs_atmSkyBox", "fs_SingleScattering_RayMarching")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ProgramComputeTransmittance", "cs_ComputeTransmittance", ShaderProgramType::Compute)); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ProgramComputeDirectIrradiance", "cs_ComputeDirectIrradiance", ShaderProgramType::Compute)); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ProgramComputeSingleScattering", "cs_ComputeSingleScattering", ShaderProgramType::Compute)); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ProgramComputeScatteringDensity", "cs_ComputeScatteringDensity", ShaderProgramType::Compute)); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ProgramComputeIndirectIrradiance", "cs_ComputeIndirectIrradiance", ShaderProgramType::Compute)); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ProgramComputeMultipleScattering", "cs_ComputeMultipleScattering", ShaderProgramType::Compute)); - 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" }); - - 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, @@ -95,15 +91,7 @@ void PBRSkyRenderer::Warmup() GetRenderContext()->CreateUniform(HeightOffset, bgfx::UniformType::Enum::Vec4, 1); GetRenderContext()->CreateUniform(NumScatteringOrders, bgfx::UniformType::Enum::Vec4, 1); - GetRenderContext()->UploadShaderProgram(ProgramAtmosphericScatteringLUT); - GetRenderContext()->UploadShaderProgram(ProgramSingleScatteringRayMarching); - - GetRenderContext()->UploadShaderProgram(ProgramComputeTransmittance); - GetRenderContext()->UploadShaderProgram(ProgramComputeDirectIrradiance); - GetRenderContext()->UploadShaderProgram(ProgramComputeSingleScattering); - GetRenderContext()->UploadShaderProgram(ProgramComputeScatteringDensity); - GetRenderContext()->UploadShaderProgram(ProgramComputeIndirectIrradiance); - GetRenderContext()->UploadShaderProgram(ProgramComputeMultipleScattering); + bgfx::setViewName(GetViewID(), "PBRSkyRenderer"); } void PBRSkyRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -129,6 +117,15 @@ void PBRSkyRenderer::UpdateView(const float* pViewMatrix, const float* pProjecti void PBRSkyRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + if (!IsEnable()) { return; @@ -171,7 +168,7 @@ void PBRSkyRenderer::Render(float deltaTime) bgfx::setState(StateRendering); - SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), ProgramAtmosphericScatteringLUT); + SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), ProgramAtmosphericScatteringLUTCrc); } bool PBRSkyRenderer::IsEnable() const @@ -204,20 +201,23 @@ void PBRSkyRenderer::Precompute() const // Compute Transmittance. bgfx::setImage(0, GetRenderContext()->GetTexture(TextureTransmittanceCrc), 0, bgfx::Access::Write, bgfx::TextureFormat::RGBA32F); - GetRenderContext()->Dispatch(viewId, ProgramComputeTransmittance, TRANSMITTANCE_TEXTURE_WIDTH / 8U, TRANSMITTANCE_TEXTURE_HEIGHT / 8U, 1U); + GetRenderContext()->Dispatch(viewId, ProgramComputeTransmittanceCrc, + 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); - GetRenderContext()->Dispatch(viewId, ProgramComputeDirectIrradiance, IRRADIANCE_TEXTURE_WIDTH / 8U, IRRADIANCE_TEXTURE_HEIGHT / 8U, 1U); + GetRenderContext()->Dispatch(viewId, ProgramComputeDirectIrradianceCrc, + 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); - GetRenderContext()->Dispatch(viewId, ProgramComputeSingleScattering, SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); + GetRenderContext()->Dispatch(viewId, ProgramComputeSingleScatteringCrc, + SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); // Compute multiple Scattering. cd::Vec4f tmpOrder; @@ -233,7 +233,8 @@ 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); - GetRenderContext()->Dispatch(viewId, ProgramComputeScatteringDensity, SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); + GetRenderContext()->Dispatch(viewId, ProgramComputeScatteringDensityCrc, + SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); // 2. Compute indirect Irradiance. tmpOrder.x() = static_cast(order - 1); @@ -244,14 +245,16 @@ 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); - GetRenderContext()->Dispatch(viewId, ProgramComputeIndirectIrradiance, IRRADIANCE_TEXTURE_WIDTH / 8U, IRRADIANCE_TEXTURE_HEIGHT / 8U, 1U); + GetRenderContext()->Dispatch(viewId, ProgramComputeIndirectIrradianceCrc, + 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); - GetRenderContext()->Dispatch(viewId, ProgramComputeMultipleScattering, SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); + GetRenderContext()->Dispatch(viewId, ProgramComputeMultipleScatteringCrc, + SCATTERING_TEXTURE_WIDTH / 8U, SCATTERING_TEXTURE_HEIGHT / 8U, SCATTERING_TEXTURE_DEPTH / 8U); } CD_ENGINE_TRACE("All compute shaders for precomputing atmospheric scattering texture dispatched."); diff --git a/Engine/Source/Runtime/Rendering/PBRSkyRenderer.h b/Engine/Source/Runtime/Rendering/PBRSkyRenderer.h index f16870c5..380e5620 100644 --- a/Engine/Source/Runtime/Rendering/PBRSkyRenderer.h +++ b/Engine/Source/Runtime/Rendering/PBRSkyRenderer.h @@ -15,7 +15,6 @@ 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/ParticleForceFieldRenderer.cpp b/Engine/Source/Runtime/Rendering/ParticleForceFieldRenderer.cpp index 2cfc3199..a2ade1ed 100644 --- a/Engine/Source/Runtime/Rendering/ParticleForceFieldRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/ParticleForceFieldRenderer.cpp @@ -4,23 +4,18 @@ #include "ECWorld/SceneWorld.h" #include "ECWorld/TransformComponent.h" #include "Rendering/RenderContext.h" +#include "Rendering/Resources/ShaderResource.h" namespace engine { void ParticleForceFieldRenderer::Init() { - constexpr StringCrc programCrc = StringCrc("ParticleForceFieldProgram"); - GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_particleforcefield", "fs_particleforcefield" }); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ParticleForceFieldProgram", "vs_particleforcefield", "fs_particleforcefield")); bgfx::setViewName(GetViewID(), "ParticleForceFieldRenderer"); } -void ParticleForceFieldRenderer::Warmup() -{ - GetRenderContext()->UploadShaderProgram("ParticleForceFieldProgram"); -} - void ParticleForceFieldRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { UpdateViewRenderTarget(); @@ -29,6 +24,15 @@ void ParticleForceFieldRenderer::UpdateView(const float* pViewMatrix, const floa void ParticleForceFieldRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + for (Entity entity : m_pCurrentSceneWorld->GetParticleForceFieldEntities()) { if (auto* pTransformComponent = m_pCurrentSceneWorld->GetTransformComponent(entity)) @@ -44,7 +48,8 @@ void ParticleForceFieldRenderer::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); - GetRenderContext()->Submit(GetViewID(), "ParticleForceFieldProgram"); + constexpr StringCrc programHandleIndex{ "ParticleForceFieldProgram" }; + GetRenderContext()->Submit(GetViewID(), programHandleIndex); } } diff --git a/Engine/Source/Runtime/Rendering/ParticleForceFieldRenderer.h b/Engine/Source/Runtime/Rendering/ParticleForceFieldRenderer.h index 2b021bfc..4a53918a 100644 --- a/Engine/Source/Runtime/Rendering/ParticleForceFieldRenderer.h +++ b/Engine/Source/Runtime/Rendering/ParticleForceFieldRenderer.h @@ -13,7 +13,6 @@ class ParticleForceFieldRenderer 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/ParticleRenderer.cpp b/Engine/Source/Runtime/Rendering/ParticleRenderer.cpp index ed72070b..3295ad78 100644 --- a/Engine/Source/Runtime/Rendering/ParticleRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/ParticleRenderer.cpp @@ -1,15 +1,19 @@ -#include "Log/Log.h" #include "ParticleRenderer.h" + #include "ECWorld/CameraComponent.h" -#include "ECWorld/SceneWorld.h" #include "ECWorld/ParticleForceFieldComponent.h" +#include "ECWorld/SceneWorld.h" #include "ECWorld/TransformComponent.h" +#include "Log/Log.h" #include "Rendering/RenderContext.h" +#include "Rendering/Resources/ShaderResource.h" -namespace engine { +namespace engine +{ namespace { + constexpr const char* particlePos = "u_particlePos"; constexpr const char* particleScale = "u_particleScale"; constexpr const char* shapeRange = "u_shapeRange"; @@ -21,26 +25,15 @@ BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA uint64_t state_lines = BGFX_STATE_WRITE_MASK | BGFX_STATE_MSAA | BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) | BGFX_STATE_PT_LINES; -constexpr const char* ParticleProgram = "ParticleProgram"; -constexpr const char* ParticleEmitterShapeProgram = "ParticleEmitterShapeProgram"; -constexpr const char* WO_BillboardParticleProgram = "WO_BillboardParticleProgram"; - -constexpr StringCrc ParticleProgramCrc = StringCrc{ "ParticleProgram" }; -constexpr StringCrc ParticleEmitterShapeProgramCrc = StringCrc{ "ParticleEmitterShapeProgram" }; -constexpr StringCrc WO_BillboardParticleProgramCrc = StringCrc{ "WO_BillboardParticleProgram" }; } void ParticleRenderer::Init() { - GetRenderContext()->RegisterShaderProgram(ParticleProgramCrc, { "vs_particle", "fs_particle" }); - GetRenderContext()->RegisterShaderProgram(ParticleEmitterShapeProgramCrc, {"vs_particleEmitterShape", "fs_particleEmitterShape"}); - GetRenderContext()->RegisterShaderProgram(WO_BillboardParticleProgramCrc, { "vs_wo_billboardparticle","fs_wo_billboardparticle" }); - - bgfx::setViewName(GetViewID(), "ParticleRenderer"); -} + // TODO : ParticleRenderer should use material to manage ShaderResource instead of Renderer::AddShaderResource. + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ParticleProgram", "vs_particle", "fs_particle")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("WO_BillboardParticleProgram", "vs_wo_billboardparticle", "fs_wo_billboardparticle")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ParticleEmitterShapeProgram", "vs_particleEmitterShape", "fs_particleEmitterShape")); -void ParticleRenderer::Warmup() -{ constexpr const char* particleTexture = "Textures/textures/Particle.png"; m_particleTextureHandle = GetRenderContext()->CreateTexture(particleTexture); GetRenderContext()->CreateUniform("s_texColor", bgfx::UniformType::Sampler); @@ -49,9 +42,7 @@ void ParticleRenderer::Warmup() GetRenderContext()->CreateUniform(shapeRange, bgfx::UniformType::Vec4, 1); GetRenderContext()->CreateUniform(particleColor, bgfx::UniformType::Vec4, 1); - GetRenderContext()->UploadShaderProgram(ParticleProgram); - GetRenderContext()->UploadShaderProgram(ParticleEmitterShapeProgram); - GetRenderContext()->UploadShaderProgram(WO_BillboardParticleProgram); + bgfx::setViewName(GetViewID(), "ParticleRenderer"); } void ParticleRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -62,6 +53,15 @@ void ParticleRenderer::UpdateView(const float* pViewMatrix, const float* pProjec void ParticleRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + for (Entity entity : m_pCurrentSceneWorld->GetParticleForceFieldEntities()) { ParticleForceFieldComponent* pForceFieldComponent = m_pCurrentSceneWorld->GetParticleForceFieldComponent(entity); @@ -169,11 +169,13 @@ void ParticleRenderer::Render(float deltaTime) if (pEmitterComponent->GetRenderMode() == engine::ParticleRenderMode::Mesh) { - GetRenderContext()->Submit(GetViewID(), ParticleProgram); + constexpr StringCrc programHandleIndex{ "ParticleProgram" }; + GetRenderContext()->Submit(GetViewID(), programHandleIndex); } else if (pEmitterComponent->GetRenderMode() == engine::ParticleRenderMode::Billboard) { - GetRenderContext()->Submit(GetViewID(), WO_BillboardParticleProgram); + constexpr StringCrc programHandleIndex{ "WO_BillboardParticleProgram" }; + GetRenderContext()->Submit(GetViewID(), programHandleIndex); } } else @@ -215,11 +217,13 @@ void ParticleRenderer::Render(float deltaTime) if (pEmitterComponent->GetRenderMode() == engine::ParticleRenderMode::Mesh) { - GetRenderContext()->Submit(GetViewID(), ParticleProgram); + constexpr StringCrc programHandleIndex{ "ParticleProgram" }; + GetRenderContext()->Submit(GetViewID(), programHandleIndex); } else if (pEmitterComponent->GetRenderMode() == engine::ParticleRenderMode::Billboard) { - GetRenderContext()->Submit(GetViewID(), WO_BillboardParticleProgram); + constexpr StringCrc programHandleIndex{ "WO_BillboardParticleProgram" }; + GetRenderContext()->Submit(GetViewID(), programHandleIndex); } } } @@ -236,7 +240,8 @@ void ParticleRenderer::Render(float deltaTime) bgfx::setIndexBuffer(bgfx::IndexBufferHandle{ pEmitterComponent->GetEmitterShapeIndexBufferHandle() }); bgfx::setState(state_lines); - GetRenderContext()->Submit(GetViewID(), ParticleEmitterShapeProgram); + constexpr StringCrc programHandleIndex{ "ParticleEmitterShapeProgram" }; + GetRenderContext()->Submit(GetViewID(), programHandleIndex); } } diff --git a/Engine/Source/Runtime/Rendering/ParticleRenderer.h b/Engine/Source/Runtime/Rendering/ParticleRenderer.h index 6766fb78..4ce854d1 100644 --- a/Engine/Source/Runtime/Rendering/ParticleRenderer.h +++ b/Engine/Source/Runtime/Rendering/ParticleRenderer.h @@ -18,7 +18,6 @@ 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 182cde07..ec9e26e5 100644 --- a/Engine/Source/Runtime/Rendering/PostProcessRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/PostProcessRenderer.cpp @@ -1,31 +1,19 @@ #include "PostProcessRenderer.h" #include "Rendering/RenderContext.h" +#include "Rendering/Resources/ShaderResource.h" namespace engine { -namespace -{ - -constexpr const char *PostProcessProgram = "PostProcessProgram"; -constexpr StringCrc PostProcessProgramCrc = StringCrc(PostProcessProgram); - -} - void PostProcessRenderer::Init() { - GetRenderContext()->RegisterShaderProgram(PostProcessProgramCrc, { "vs_fullscreen", "fs_PBR_postProcessing" }); - - bgfx::setViewName(GetViewID(), "PostProcessRenderer"); -} + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("PostProcessProgram", "vs_fullscreen", "fs_PBR_postProcessing")); -void PostProcessRenderer::Warmup() -{ GetRenderContext()->CreateUniform("s_lightingColor", bgfx::UniformType::Sampler); GetRenderContext()->CreateUniform("u_postProcessingParams", bgfx::UniformType::Vec4); - GetRenderContext()->UploadShaderProgram(PostProcessProgram); + bgfx::setViewName(GetViewID(), "PostProcessRenderer"); } void PostProcessRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -38,8 +26,16 @@ void PostProcessRenderer::UpdateView(const float* pViewMatrix, const float* pPro void PostProcessRenderer::Render(float deltaTime) { - constexpr StringCrc sceneRenderTarget("SceneRenderTarget"); + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + constexpr StringCrc sceneRenderTarget("SceneRenderTarget"); const RenderTarget* pInputRT = GetRenderContext()->GetRenderTarget(sceneRenderTarget); const RenderTarget* pOutputRT = GetRenderTarget(); @@ -70,7 +66,8 @@ void PostProcessRenderer::Render(float deltaTime) bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A); Renderer::ScreenSpaceQuad(GetRenderTarget(), false); - GetRenderContext()->Submit(GetViewID(), PostProcessProgram); + constexpr StringCrc programHandleIndex{ "PostProcessProgram" }; + GetRenderContext()->Submit(GetViewID(), programHandleIndex); } } \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/PostProcessRenderer.h b/Engine/Source/Runtime/Rendering/PostProcessRenderer.h index 9dffb805..b51ce4c0 100644 --- a/Engine/Source/Runtime/Rendering/PostProcessRenderer.h +++ b/Engine/Source/Runtime/Rendering/PostProcessRenderer.h @@ -12,7 +12,6 @@ class PostProcessRenderer 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/RenderContext.cpp b/Engine/Source/Runtime/Rendering/RenderContext.cpp index 832e12de..10801ba1 100644 --- a/Engine/Source/Runtime/Rendering/RenderContext.cpp +++ b/Engine/Source/Runtime/Rendering/RenderContext.cpp @@ -4,7 +4,8 @@ #include "Log/Log.h" #include "Path/Path.h" #include "Renderer.h" -#include "Rendering/ShaderCollections.h" +#include "Rendering/Resources/ResourceContext.h" +#include "Rendering/Resources/ShaderResource.h" #include "Rendering/ShaderType.h" #include "Rendering/Utility/VertexLayoutUtility.h" #include "Resources/ResourceLoader.h" @@ -15,7 +16,6 @@ #include #include -//#include #include #include @@ -35,34 +35,6 @@ static void imageReleaseCb(void* _ptr, void* _userData) bimg::imageFree(imageContainer); } -std::tuple IdentifyShaderTypes(const std::set& shaders) -{ - assert(shaders.size() <= 2); - std::tuple shadersTuple = { "", "", "" }; - for (const auto& name : shaders) - { - 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; -} - } namespace engine @@ -122,16 +94,6 @@ void RenderContext::Init(GraphicsBackend backend, void* hwnd) void RenderContext::Shutdown() { - for (auto it : m_shaderHandles) - { - bgfx::destroy(bgfx::ShaderHandle{ it.second }); - } - - for (auto it : m_shaderProgramHandles) - { - bgfx::destroy(bgfx::ProgramHandle{ it.second }); - } - for (auto it : m_textureHandleCaches) { bgfx::destroy(bgfx::TextureHandle{ it.second }); @@ -147,16 +109,25 @@ void RenderContext::BeginFrame() { } -void RenderContext::Submit(uint16_t viewID, const std::string& programName, const std::string& featuresCombine) +void RenderContext::Submit(uint16_t viewID, uint16_t programHandle) { - assert(bgfx::isValid(GetShaderProgramHandle(programName, featuresCombine))); - bgfx::submit(viewID, GetShaderProgramHandle(programName, featuresCombine)); + assert(bgfx::isValid(bgfx::ProgramHandle{ programHandle })); + bgfx::submit(viewID, bgfx::ProgramHandle{ programHandle }); } -void RenderContext::Dispatch(uint16_t viewID, const std::string& programName, uint32_t numX, uint32_t numY, uint32_t numZ) +void RenderContext::Submit(uint16_t viewID, StringCrc programHandleIndex) { - assert(bgfx::isValid(GetShaderProgramHandle(programName))); - bgfx::dispatch(viewID, GetShaderProgramHandle(programName), numX, numY, numZ); + Submit(viewID, m_pResourceContext->GetShaderResource(programHandleIndex)->GetHandle()); +} + +void RenderContext::Dispatch(uint16_t viewID, uint16_t programHandle, uint32_t numX, uint32_t numY, uint32_t numZ) +{ + assert(bgfx::isValid(bgfx::ProgramHandle{ programHandle })); + bgfx::dispatch(viewID, bgfx::ProgramHandle{ programHandle }, numX, numY, numZ); +} +void RenderContext::Dispatch(uint16_t viewID, StringCrc programHandleIndex, uint32_t numX, uint32_t numY, uint32_t numZ) +{ + Dispatch(viewID, m_pResourceContext->GetShaderResource(programHandleIndex)->GetHandle(), numX, numY, numZ); } void RenderContext::EndFrame() @@ -179,143 +150,74 @@ 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) +ShaderResource* RenderContext::RegisterShaderProgram(const std::string& programName, const std::string& vsName, const std::string& fsName, const std::string& combine) { - m_pShaderCollections->AddFeatureCombine(programNameCrc, cd::MoveTemp(combine)); -} - -bool RenderContext::CheckShaderProgram(Entity entity, const std::string& programName, const std::string& featuresCombine) -{ - assert(m_pShaderCollections->IsProgramValid(StringCrc{ programName })); - - if (m_shaderProgramHandles.find(StringCrc{ programName + featuresCombine }) == m_shaderProgramHandles.end()) + const StringCrc programCrc{ programName + combine }; + if (m_pResourceContext->GetShaderResource(programCrc)) { - // It 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. - AddShaderCompileInfo(ShaderCompileInfo{ entity, programName, featuresCombine }); - m_pShaderCollections->AddFeatureCombine(StringCrc{ programName }, featuresCombine); - - return true; + return m_pResourceContext->GetShaderResource(programCrc); } - return false; -} - -bool RenderContext::OnShaderHotModified(Entity entity, const std::string& programName, const std::string& featuresCombine) -{ - assert(m_pShaderCollections->IsProgramValid(StringCrc{ programName })); - - // m_modifiedProgramNameCrcs will be filled by callback function which bound to FileWatcher. - if (m_modifiedProgramNameCrcs.find(engine::StringCrc{ programName }) != m_modifiedProgramNameCrcs.end()) - { - AddShaderCompileInfo(engine::ShaderCompileInfo{ entity, programName, featuresCombine }); + ShaderResource* pShaderResource = m_pResourceContext->AddShaderResource(programCrc); + pShaderResource->SetType(ShaderProgramType::Standard); + pShaderResource->SetName(programName); + pShaderResource->SetShaders(vsName, fsName, combine); - return true; - } + AddShaderResource(StringCrc{ vsName }, pShaderResource); + AddShaderResource(StringCrc{ fsName }, pShaderResource); - return false; + return pShaderResource; } -void RenderContext::UploadShaderProgram(const std::string& programName, const std::string& featuresCombine) +ShaderResource* RenderContext::RegisterShaderProgram(const std::string& programName, const std::string& shaderName, ShaderProgramType type, const std::string& combine) { - 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 + StringCrc programCrc{ programName + combine }; + if (m_pResourceContext->GetShaderResource(programCrc)) { - // 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); - } + return m_pResourceContext->GetShaderResource(programCrc); } -} -void RenderContext::DestroyShaderProgram(const std::string& programName, const std::string& featuresCombine) -{ - DestoryProgram(StringCrc{ programName + featuresCombine }); + ShaderResource* pShaderResource = m_pResourceContext->AddShaderResource(StringCrc{ programName + combine }); + pShaderResource->SetType(type); + pShaderResource->SetName(programName); + pShaderResource->SetShader(ProgramTypeToSingleShaderType.at(type), shaderName, combine); - auto [vsName, fsName, csName] = IdentifyShaderTypes(m_pShaderCollections->GetShaders(StringCrc{ programName })); - StringCrc vsCrc{ vsName.data() }; - StringCrc fsCrc{ fsName.data() + featuresCombine }; - StringCrc csCrc{ csName.data() }; + AddShaderResource(StringCrc{ shaderName }, pShaderResource); - DestoryShader(vsCrc); - DestoryShader(fsCrc); - DestoryShader(csCrc); + return pShaderResource; } -void RenderContext::AddShaderCompileInfo(ShaderCompileInfo info) +void RenderContext::OnShaderHotModified(StringCrc modifiedShaderNameCrc) { - if (m_shaderCompileInfos.find(info) == m_shaderCompileInfos.end()) + // Get all ShaderResource variants by shader name. + auto range = m_shaderResources.equal_range(modifiedShaderNameCrc); + for (auto it = range.first; it != range.second; ++it) { - CD_ENGINE_INFO("Shader compile task added for {0} with shader features : [{1}]", info.m_programName, info.m_featuresCombine); - m_shaderCompileInfos.insert(cd::MoveTemp(info)); + m_modifiedShaderResources.insert(it->second); } } -void RenderContext::ClearShaderCompileInfos() -{ - m_shaderCompileInfos.clear(); -} - -void RenderContext::SetShaderCompileInfos(std::set tasks) -{ - m_shaderCompileInfos = cd::MoveTemp(tasks); -} - -void RenderContext::CheckModifiedProgram(std::string modifiedShaderName) +void RenderContext::OnShaderRecompile() { - // Find Shader Program name by Shader File Name. - // TODO : We could devise a mechanism like unity's meta file for recording dependencies on asset files, - // and perhaps both Program and Material information could be retrieved directly from the meta file. - for (const auto& [programName, shaderNames] : m_pShaderCollections->GetShaderPrograms()) + // m_modifiedShaderResources will be filled by callback function which bound to FileWatcher. + auto it = m_modifiedShaderResources.begin(); + while (it != m_modifiedShaderResources.end()) { - for (const auto& shaderName : shaderNames) + ShaderResource* pShaderResource = *it; + if (pShaderResource->IsActive()) + { + pShaderResource->Reset(); + AddRecompileShaderResource(pShaderResource); + + it = m_modifiedShaderResources.erase(it); + } + else { - if (shaderName == modifiedShaderName) - { - // Use set to ensure no duplicate detection are recorded. - m_modifiedProgramNameCrcs.insert(programName); - break; - } + ++it; } } } -void RenderContext::ClearModifiedProgramNameCrcs() -{ - m_modifiedProgramNameCrcs.clear(); -} - void RenderContext::AddCompileFailedEntity(uint32_t entity) { m_compileFailedEntities.insert(entity); @@ -326,44 +228,6 @@ void RenderContext::ClearCompileFailedEntity() m_compileFailedEntities.clear(); } -const RenderContext::ShaderBlob& RenderContext::AddShaderBlob(StringCrc shaderNameCrc, ShaderBlob blob) -{ - const auto& it = m_shaderBlobs.find(shaderNameCrc); - if (it != m_shaderBlobs.end()) - { - return *(it->second); - } - m_shaderBlobs[shaderNameCrc] = std::make_unique(cd::MoveTemp(blob)); - return *m_shaderBlobs.at(shaderNameCrc); -} - -const RenderContext::ShaderBlob& RenderContext::GetShaderBlob(StringCrc shaderNameCrc) const -{ - assert(m_shaderBlobs.find(shaderNameCrc) != m_shaderBlobs.end() && "Shader blob does not exist!"); - return *m_shaderBlobs.at(shaderNameCrc).get(); -} - -bool RenderContext::IsShaderProgramValid(const std::string& programName, const std::string& featuresCombine) const -{ - return bgfx::isValid(GetShaderProgramHandle(programName, featuresCombine)); -} - -void RenderContext::SetShaderProgramHandle(const std::string& programName, bgfx::ProgramHandle handle, const std::string& featuresCombine) -{ - m_shaderProgramHandles[StringCrc{ programName + featuresCombine }] = handle.idx; -} - -bgfx::ProgramHandle RenderContext::GetShaderProgramHandle(const std::string& programName, const std::string& featuresCombine) const -{ - const auto& it = m_shaderProgramHandles.find(StringCrc{ programName + featuresCombine }); - 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))); @@ -388,81 +252,6 @@ RenderTarget* RenderContext::CreateRenderTarget(StringCrc resourceCrc, std::uniq return m_renderTargetCaches[resourceCrc].get(); } -bgfx::ShaderHandle RenderContext::CreateShader(const char* pShaderName, const std::string& combine) -{ - StringCrc shaderNameCrc{ pShaderName + combine }; - auto itShaderCache = m_shaderHandles.find(shaderNameCrc); - if(itShaderCache != m_shaderHandles.end()) - { - return { itShaderCache->second }; - } - - std::string shaderFileFullPath = Path::GetShaderOutputPath(pShaderName, combine); - 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(shaderHandle)) - { - bgfx::setName(shaderHandle, pShaderName); - m_shaderHandles[shaderNameCrc] = shaderHandle.idx; - } - - return shaderHandle; -} - -bgfx::ProgramHandle RenderContext::CreateProgram(const std::string& programName, const std::string& csName) -{ - StringCrc programNameCrc{ programName }; - auto itProgram = m_shaderProgramHandles.find(programNameCrc); - if (itProgram != m_shaderProgramHandles.end()) - { - return { itProgram->second }; - } - - bgfx::ProgramHandle programHandle = bgfx::createProgram(CreateShader(csName.c_str())); - if (bgfx::isValid(programHandle)) - { - m_shaderProgramHandles[programNameCrc] = programHandle.idx; - } - - return programHandle; -} - -bgfx::ProgramHandle RenderContext::CreateProgram(const std::string& programName, const std::string& vsName, const std::string& fsName, const std::string& featuresCombine) -{ - StringCrc fullProgramNameCrc = StringCrc{ programName + featuresCombine }; - - const auto& it = m_shaderProgramHandles.find(fullProgramNameCrc); - if (it != m_shaderProgramHandles.end()) - { - return { it->second }; - } - - // BGFX will return a valid ProgramHandle with valid VSHandle and invalid FSHandle. - - bgfx::ShaderHandle vsHandle = CreateShader(vsName.c_str()); - if (!bgfx::isValid(vsHandle)) - { - DestoryShader(StringCrc{ vsName }); - return bgfx::ProgramHandle{ bgfx::kInvalidHandle }; - } - - bgfx::ShaderHandle fsHandle = CreateShader(fsName.c_str(), featuresCombine); - if (!bgfx::isValid(fsHandle)) - { - DestoryShader(StringCrc{ fsName + featuresCombine }); - return bgfx::ProgramHandle{ bgfx::kInvalidHandle }; - } - - bgfx::ProgramHandle programHandle = bgfx::createProgram(vsHandle, fsHandle); - if (bgfx::isValid(programHandle)) - { - m_shaderProgramHandles[fullProgramNameCrc] = programHandle.idx; - } - - return programHandle; -} - bgfx::TextureHandle RenderContext::CreateTexture(const char* pFilePath, uint64_t flags) { StringCrc filePathCrc{ pFilePath }; @@ -704,17 +493,6 @@ const bgfx::VertexLayout& RenderContext::GetVertexAttributeLayouts(StringCrc res return dummy; } -bgfx::ShaderHandle RenderContext::GetShader(StringCrc resourceCrc) const -{ - auto itResource = m_shaderHandles.find(resourceCrc); - if (itResource != m_shaderHandles.end()) - { - return { itResource->second }; - } - - return bgfx::ShaderHandle{ bgfx::kInvalidHandle }; -} - bgfx::TextureHandle RenderContext::GetTexture(StringCrc resourceCrc) const { auto itResource = m_textureHandleCaches.find(resourceCrc); @@ -764,29 +542,4 @@ void RenderContext::DestoryUniform(StringCrc resourceCrc) } } -void RenderContext::DestoryShader(StringCrc resourceCrc) -{ - auto it = m_shaderHandles.find(resourceCrc); - if (it != m_shaderHandles.end()) - { - assert(bgfx::isValid(bgfx::ShaderHandle{ it->second })); - bgfx::destroy(bgfx::ShaderHandle{ it->second }); - m_shaderHandles.erase(it); - } - - // Erase shader blob anyway. - m_shaderBlobs.erase(resourceCrc); -} - -void RenderContext::DestoryProgram(StringCrc resourceCrc) -{ - auto it = m_shaderProgramHandles.find(resourceCrc); - 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 5b0ceecb..9caf04c9 100644 --- a/Engine/Source/Runtime/Rendering/RenderContext.h +++ b/Engine/Source/Runtime/Rendering/RenderContext.h @@ -3,7 +3,7 @@ #include "Core/StringCrc.h" #include "Graphics/GraphicsBackend.h" #include "Math/Matrix.hpp" -#include "Rendering/ShaderCompileInfo.h" +#include "Rendering/ShaderType.h" #include "RenderTarget.h" #include "Scene/VertexAttribute.h" #include "Scene/VertexFormat.h" @@ -23,7 +23,7 @@ namespace engine class Camera; class Renderer; class ResourceContext; -class ShaderCollections; +class ShaderResource; static constexpr uint8_t MaxViewCount = 255; static constexpr uint8_t MaxRenderTargetCount = 255; @@ -46,8 +46,10 @@ 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& featuresCombine = ""); - void Dispatch(uint16_t viewID, const std::string& programName, uint32_t numX, uint32_t numY, uint32_t numZ); + void Submit(uint16_t viewID, uint16_t programHandle); + void Submit(uint16_t viewID, StringCrc programHandleIndex); + void Dispatch(uint16_t viewID, uint16_t programHandle, uint32_t numX, uint32_t numY, uint32_t numZ); + void Dispatch(uint16_t viewID, StringCrc programHandleIndex, uint32_t numX, uint32_t numY, uint32_t numZ); void EndFrame(); void Shutdown(); @@ -62,59 +64,40 @@ 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(Entity entity, const std::string& programName, const std::string& featuresCombine = ""); - bool OnShaderHotModified(Entity entity, const std::string& programName, const std::string& featuresCombine = ""); - void UploadShaderProgram(const std::string& programName, const std::string& featuresCombine = ""); - void DestroyShaderProgram(const std::string& programName, const std::string& featuresCombine = ""); - - void AddShaderCompileInfo(ShaderCompileInfo info); - void ClearShaderCompileInfos(); - void SetShaderCompileInfos(std::set tasks); - std::set& GetShaderCompileInfos() { return m_shaderCompileInfos; } - const std::set& GetShaderCompileInfos() const { return m_shaderCompileInfos; } - - void CheckModifiedProgram(std::string modifiedShaderName); - void ClearModifiedProgramNameCrcs(); - std::set& GetModifiedProgramNameCrcs() { return m_modifiedProgramNameCrcs; } - const std::set& GetModifiedProgramNameCrcs() const { return m_modifiedProgramNameCrcs; } + // For Standard ShaderProgramType + ShaderResource* RegisterShaderProgram(const std::string& programName, const std::string& vsName, const std::string& fsName, const std::string& combine = ""); + // For non-Standard ShaderProgramType + ShaderResource* RegisterShaderProgram(const std::string& programName, const std::string& shaderName, ShaderProgramType type, const std::string& combine = ""); + + void AddShaderResource(StringCrc shaderName, ShaderResource* resource) { m_shaderResources.insert({ shaderName, resource }); } + void DeleteShaderResource(StringCrc shaderName) { m_shaderResources.erase(shaderName); } + void SetShaderResources(std::multimap resources) { m_shaderResources = cd::MoveTemp(resources); } + std::multimap& GetShaderResources() { return m_shaderResources; } + const std::multimap& GetShaderResources() const { return m_shaderResources; } + + // Call back function bind to file watcher. + void OnShaderHotModified(StringCrc modifiedShaderNameCrc); + void ClearModifiedShaderResources() { m_modifiedShaderResources.clear(); } + std::set& GetModifiedShaderResources() { return m_modifiedShaderResources; } + const std::set& GetModifiedShaderResources() const { return m_modifiedShaderResources; } + + void OnShaderRecompile(); + void AddRecompileShaderResource(ShaderResource* pShaderResource) { m_recompileShaderResources.insert(pShaderResource); } + void DeleteRecompileShaderResource(ShaderResource* pShaderResource) { m_recompileShaderResources.erase(pShaderResource); } + void ClearRecompileShaderResources() { m_recompileShaderResources.clear(); } + void SetRecompileShaderResources(std::set recompileShaderResources) { m_recompileShaderResources = cd::MoveTemp(recompileShaderResources); } + std::set GetRecompileShaderResources() { return m_recompileShaderResources; } + const std::set GetRecompileShaderResources() const { return m_recompileShaderResources; } void AddCompileFailedEntity(uint32_t entity); void ClearCompileFailedEntity(); std::set& GetCompileFailedEntities() { return m_compileFailedEntities; } const std::set& GetCompileFailedEntities() const { return m_compileFailedEntities; } - ///////////////////////////////////////////////////////////////////// - // Shader blob apis - ///////////////////////////////////////////////////////////////////// - const RenderContext::ShaderBlob& AddShaderBlob(StringCrc shaderNameCrc, ShaderBlob blob); - const ShaderBlob& GetShaderBlob(StringCrc shaderNameCrc) const; - - ///////////////////////////////////////////////////////////////////// - // Resource related apis - ///////////////////////////////////////////////////////////////////// - - bool IsShaderProgramValid(const std::string& programName, const std::string& featuresCombine = "") const; - - void SetShaderProgramHandle(const std::string& programName, bgfx::ProgramHandle handle, const std::string& featuresCombine = ""); - bgfx::ProgramHandle GetShaderProgramHandle(const std::string& programName, const std::string& featuresCombine = "") 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, const std::string& combine = ""); - 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& featuresCombine = ""); - 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); bgfx::TextureHandle UpdateTexture(const char* pName, uint16_t layer, uint8_t mip, uint16_t x, uint16_t y, uint16_t z, uint16_t width, uint16_t height, uint16_t depth, const void* data = nullptr, uint32_t size = 0); @@ -130,15 +113,12 @@ class RenderContext RenderTarget* GetRenderTarget(StringCrc resourceCrc) const; const bgfx::VertexLayout& GetVertexAttributeLayouts(StringCrc resourceCrc) const; - bgfx::ShaderHandle GetShader(StringCrc resourceCrc) const; bgfx::TextureHandle GetTexture(StringCrc resourceCrc) const; bgfx::UniformHandle GetUniform(StringCrc resourceCrc) const; void DestoryRenderTarget(StringCrc resourceCrc); void DestoryTexture(StringCrc resourceCrc); void DestoryUniform(StringCrc resourceCrc); - void DestoryShader(StringCrc resourceCrc); - void DestoryProgram(StringCrc resourceCrc); private: ResourceContext* m_pResourceContext = nullptr; @@ -152,18 +132,10 @@ class RenderContext 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::set m_shaderCompileInfos; - std::set m_modifiedProgramNameCrcs; + // Key : StringCrc(shader name), Value : ShaderResource* + std::multimap m_shaderResources; + std::set m_modifiedShaderResources; + std::set m_recompileShaderResources; std::set m_compileFailedEntities; }; diff --git a/Engine/Source/Runtime/Rendering/Renderer.cpp b/Engine/Source/Runtime/Rendering/Renderer.cpp index c1eda68e..ffa61a95 100644 --- a/Engine/Source/Runtime/Rendering/Renderer.cpp +++ b/Engine/Source/Runtime/Rendering/Renderer.cpp @@ -4,6 +4,8 @@ #include "Rendering/RenderContext.h" #include "Rendering/RenderTarget.h" #include "Rendering/Resources/MeshResource.h" +#include "Rendering/Resources/ResourceContext.h" +#include "Rendering/Resources/ShaderResource.h" #include @@ -141,7 +143,7 @@ void Renderer::ScreenSpaceQuad(const RenderTarget* pRenderTarget, bool _originBo } } -void Renderer::SubmitStaticMeshDrawCall(StaticMeshComponent* pMeshComponent, uint16_t viewID, const std::string& programName, const std::string& featuresCombine) +void Renderer::SubmitStaticMeshDrawCall(StaticMeshComponent* pMeshComponent, uint16_t viewID, uint16_t programHandle) { const MeshResource* pMeshResource = pMeshComponent->GetMeshResource(); assert(ResourceStatus::Ready == pMeshResource->GetStatus() || ResourceStatus::Optimized == pMeshResource->GetStatus()); @@ -150,9 +152,13 @@ void Renderer::SubmitStaticMeshDrawCall(StaticMeshComponent* pMeshComponent, uin { bgfx::setIndexBuffer(bgfx::IndexBufferHandle{ pMeshResource->GetIndexBufferHandle(indexBufferIndex) }, pMeshComponent->GetStartIndex(), pMeshComponent->GetIndexCount()); - // TODO : Submit interface requires runtime string construction which may hurt performance. - GetRenderContext()->Submit(viewID, programName, featuresCombine); + GetRenderContext()->Submit(viewID, programHandle); } } +void Renderer::SubmitStaticMeshDrawCall(StaticMeshComponent* pMeshComponent, uint16_t viewID, StringCrc programHandleIndex) +{ + SubmitStaticMeshDrawCall(pMeshComponent, viewID, m_pRenderContext->GetResourceContext()->GetShaderResource(programHandleIndex)->GetHandle()); +} + } \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/Renderer.h b/Engine/Source/Runtime/Rendering/Renderer.h index 6c716651..b2d259db 100644 --- a/Engine/Source/Runtime/Rendering/Renderer.h +++ b/Engine/Source/Runtime/Rendering/Renderer.h @@ -1,6 +1,9 @@ #pragma once +#include "Core/StringCrc.h" + #include +#include #include namespace engine @@ -9,7 +12,7 @@ namespace engine class Camera; class RenderContext; class RenderTarget; -class ShaderCollections; +class ShaderResource; class StaticMeshComponent; class Renderer @@ -27,8 +30,6 @@ 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; @@ -41,15 +42,20 @@ class Renderer virtual void SetEnable(bool value) { m_isEnable = value; } virtual bool IsEnable() const { return m_isEnable; } - void SubmitStaticMeshDrawCall(StaticMeshComponent* pMeshComponent, uint16_t viewID, const std::string& programName, const std::string& featuresCombine = ""); + void SubmitStaticMeshDrawCall(StaticMeshComponent* pMeshComponent, uint16_t viewID, uint16_t programHandle); + void SubmitStaticMeshDrawCall(StaticMeshComponent* pMeshComponent, uint16_t viewID, StringCrc programHandleIndex); public: static void ScreenSpaceQuad(const RenderTarget* pRenderTarget, bool _originBottomLeft = false, float _width = 1.0f, float _height = 1.0f); + void AddDependentShaderResource(ShaderResource *shaderResource) { m_dependentShaderResources.insert(shaderResource); } protected: + bool m_isEnable = true; uint16_t m_viewID = 0; RenderTarget* m_pRenderTarget = nullptr; - bool m_isEnable = true; + + // TODO : Need a generic way to manage the Renderer's dependency on shader resources, improve it. + std::set m_dependentShaderResources; }; } \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/Resources/IResource.h b/Engine/Source/Runtime/Rendering/Resources/IResource.h index 1da2aa9e..b33a6c8f 100644 --- a/Engine/Source/Runtime/Rendering/Resources/IResource.h +++ b/Engine/Source/Runtime/Rendering/Resources/IResource.h @@ -20,6 +20,7 @@ enum class ResourceStatus enum class ResourceType { Mesh, + Shader, Texture, }; diff --git a/Engine/Source/Runtime/Rendering/Resources/MeshResource.cpp b/Engine/Source/Runtime/Rendering/Resources/MeshResource.cpp index fde3eafa..98b3dbb1 100644 --- a/Engine/Source/Runtime/Rendering/Resources/MeshResource.cpp +++ b/Engine/Source/Runtime/Rendering/Resources/MeshResource.cpp @@ -168,7 +168,7 @@ void MeshResource::Reset() { DestroyVertexBufferHandle(); DestroyIndexBufferHandle(); - FreeMeshData(); + ClearMeshData(); SetStatus(ResourceStatus::Loading); } @@ -276,12 +276,19 @@ void MeshResource::SubmitIndexBuffer() } } -void MeshResource::FreeMeshData() +void MeshResource::ClearMeshData() { m_vertexBuffer.clear(); m_indexBuffers.clear(); } +void MeshResource::FreeMeshData() +{ + ClearMeshData(); + VertexBuffer().swap(m_vertexBuffer); + std::vector().swap(m_indexBuffers); +} + void MeshResource::DestroyVertexBufferHandle() { if (m_vertexBufferHandle != UINT16_MAX) diff --git a/Engine/Source/Runtime/Rendering/Resources/MeshResource.h b/Engine/Source/Runtime/Rendering/Resources/MeshResource.h index e3a3f161..62f77bd3 100644 --- a/Engine/Source/Runtime/Rendering/Resources/MeshResource.h +++ b/Engine/Source/Runtime/Rendering/Resources/MeshResource.h @@ -49,6 +49,7 @@ class MeshResource : public IResource bool BuildIndexBuffer(); void SubmitVertexBuffer(); void SubmitIndexBuffer(); + void ClearMeshData(); void FreeMeshData(); void DestroyVertexBufferHandle(); void DestroyIndexBufferHandle(); diff --git a/Engine/Source/Runtime/Rendering/Resources/ResourceContext.cpp b/Engine/Source/Runtime/Rendering/Resources/ResourceContext.cpp index 62a64a65..a8d43121 100644 --- a/Engine/Source/Runtime/Rendering/Resources/ResourceContext.cpp +++ b/Engine/Source/Runtime/Rendering/Resources/ResourceContext.cpp @@ -2,6 +2,7 @@ #include "Base/NameOf.h" #include "MeshResource.h" +#include "ShaderResource.h" #include "TextureResource.h" namespace engine @@ -31,6 +32,11 @@ MeshResource* ResourceContext::AddMeshResource(StringCrc nameCrc) return static_cast(AddResourceImpl(nameCrc)); } +ShaderResource* ResourceContext::AddShaderResource(StringCrc nameCrc) +{ + return static_cast(AddResourceImpl(nameCrc)); +} + TextureResource* ResourceContext::AddTextureResource(StringCrc nameCrc) { return static_cast(AddResourceImpl(nameCrc)); @@ -41,6 +47,11 @@ MeshResource* ResourceContext::GetMeshResource(StringCrc nameCrc) return static_cast(GetResourceImpl(nameCrc)); } +ShaderResource* ResourceContext::GetShaderResource(StringCrc nameCrc) +{ + return static_cast(GetResourceImpl(nameCrc)); +} + TextureResource* ResourceContext::GetTextureResource(StringCrc nameCrc) { return static_cast(GetResourceImpl(nameCrc)); @@ -60,6 +71,10 @@ IResource* ResourceContext::AddResourceImpl(StringCrc nameCrc) { m_resources[resourceCrc] = std::make_unique(); } + else if constexpr (ResourceType::Shader == RT) + { + m_resources[resourceCrc] = std::make_unique(); + } else if constexpr (ResourceType::Texture == RT) { m_resources[resourceCrc] = std::make_unique(); diff --git a/Engine/Source/Runtime/Rendering/Resources/ResourceContext.h b/Engine/Source/Runtime/Rendering/Resources/ResourceContext.h index 6cb0a0c7..cc32afa7 100644 --- a/Engine/Source/Runtime/Rendering/Resources/ResourceContext.h +++ b/Engine/Source/Runtime/Rendering/Resources/ResourceContext.h @@ -11,6 +11,7 @@ namespace engine enum class ResourceType; class IResource; class MeshResource; +class ShaderResource; class TextureResource; class ResourceContext @@ -28,8 +29,10 @@ class ResourceContext StringCrc GetResourceCrc(ResourceType resourceType, StringCrc nameCrc); MeshResource* AddMeshResource(StringCrc nameCrc); + ShaderResource* AddShaderResource(StringCrc nameCrc); TextureResource* AddTextureResource(StringCrc nameCrc); MeshResource* GetMeshResource(StringCrc nameCrc); + ShaderResource* GetShaderResource(StringCrc nameCrc); TextureResource* GetTextureResource(StringCrc nameCrc); private: diff --git a/Engine/Source/Runtime/Rendering/Resources/ShaderResource.cpp b/Engine/Source/Runtime/Rendering/Resources/ShaderResource.cpp new file mode 100644 index 00000000..1da3bb02 --- /dev/null +++ b/Engine/Source/Runtime/Rendering/Resources/ShaderResource.cpp @@ -0,0 +1,273 @@ +#include "ShaderResource.h" + +#include "Log/Log.h" +#include "Path/Path.h" +#include "Resources/ResourceLoader.h" + +#include + +#include + +namespace engine +{ + +ShaderResource::~ShaderResource() +{ + SetStatus(ResourceStatus::Garbage); + Update(); +} + +void ShaderResource::Update() +{ + switch (GetStatus()) + { + case ResourceStatus::Loading: + { + // TODO : Should integrate the "compiling shader sc file to bin file" process in ShaderResource::Update. + // For now, we just read the shader bin file. + + if (LoadShader()) + { + SetStatus(ResourceStatus::Loaded); + } + break; + } + case ResourceStatus::Loaded: + { + if (!m_shaders[0].binBlob.empty() && !(ShaderProgramType::Standard == m_type && m_shaders[1].binBlob.empty())) + { + // It seems no Rendering data for shader? Skip Building status. + SetStatus(ResourceStatus::Built); + } + break; + } + case ResourceStatus::Building: + { + SetStatus(ResourceStatus::Built); + break; + } + case ResourceStatus::Built: + { + // Build GPU handles + if (BuildShaderHandle() && BuildProgramHandle()) + { + m_recycleCount = 0U; + SetStatus(ResourceStatus::Ready); + } + break; + } + case ResourceStatus::Ready: + { + // Delete CPU data delayed + constexpr uint32_t recycleDelayFrames = 30U; + if (m_recycleCount++ >= recycleDelayFrames) + { + FreeShaderData(0); + FreeShaderData(1); + + m_recycleCount = 0U; + SetStatus(ResourceStatus::Optimized); + } + break; + } + case ResourceStatus::Garbage: + { + // Distory GPU handles + DistoryShaderHandle(0); + DistoryShaderHandle(1); + DistoryProgramHandle(); + SetStatus(ResourceStatus::Destroyed); + break; + } + default: + break; + } +} +void ShaderResource::Reset() +{ + ClearShaderData(0); + ClearShaderData(1); + DistoryShaderHandle(0); + DistoryShaderHandle(1); + DistoryProgramHandle(); + SetStatus(ResourceStatus::Loading); +} + +void ShaderResource::SetShaders(const std::string& vsName, const std::string& fsName, const std::string& combine) +{ + assert(ShaderProgramType::Standard == m_type); + + m_shaders[0].type = ShaderType::Vertex; + m_shaders[0].name = vsName; + m_shaders[0].scPath = engine::Path::GetBuiltinShaderInputPath(vsName.c_str()); + // TODO : Uber Vertex Shader + m_shaders[0].binPath = engine::Path::GetShaderOutputPath(vsName.c_str()); + + m_shaders[1].type = ShaderType::Fragment; + m_shaders[1].name = fsName; + m_shaders[1].scPath = engine::Path::GetBuiltinShaderInputPath(fsName.c_str()); + m_shaders[1].binPath = engine::Path::GetShaderOutputPath(fsName.c_str(), combine); + + m_featuresCombine = combine; +} + +void ShaderResource::SetShader(ShaderType type, const std::string& name, const std::string& combine) +{ + assert(ShaderProgramType::Standard != m_type); + + m_shaders[0].type = type; + m_shaders[0].name = name; + m_shaders[0].scPath = engine::Path::GetBuiltinShaderInputPath(name.c_str()); + m_shaders[0].binPath = engine::Path::GetShaderOutputPath(name.c_str(), combine); + + m_featuresCombine = combine; +} + +void ShaderResource::SetShaderInfo(ShaderInfo info, size_t index) +{ + CheckIndex(index); + m_shaders[index] = cd::MoveTemp(info); +} + +ShaderResource::ShaderInfo& ShaderResource::GetShaderInfo(size_t index) +{ + CheckIndex(index); + return m_shaders[index]; +} + +const ShaderResource::ShaderInfo& ShaderResource::GetShaderInfo(size_t index) const +{ + CheckIndex(index); + return m_shaders[index]; +} + +bool ShaderResource::LoadShader() +{ + auto& shader = m_shaders[0]; + if (!Path::FileExists(shader.binPath.c_str())) + { + return false; + } + shader.binBlob = engine::ResourceLoader::LoadFile(shader.binPath.c_str()); + + if (ShaderProgramType::Standard == m_type) + { + auto& fragmentShader = m_shaders[1]; + if (!Path::FileExists(fragmentShader.binPath.c_str())) + { + ClearShaderData(0); + return false; + } + fragmentShader.binBlob = engine::ResourceLoader::LoadFile(fragmentShader.binPath.c_str()); + } + + return true; +} + +bool ShaderResource::BuildShaderHandle() +{ + if (m_shaders[0].binBlob.empty()) + { + return false; + } + + assert(!bgfx::isValid(bgfx::ShaderHandle{ m_shaders[0].handle })); + bgfx::ShaderHandle handle = bgfx::createShader(bgfx::makeRef(m_shaders[0].binBlob.data(), static_cast(m_shaders[0].binBlob.size()))); + if (!bgfx::isValid(handle)) + { + ClearShaderData(0); + return false; + } + m_shaders[0].handle = handle.idx; + + if (ShaderProgramType::Standard == m_type) + { + if (m_shaders[1].binBlob.empty()) + { + ClearShaderData(0); + DistoryShaderHandle(0); + return false; + } + + assert(!bgfx::isValid(bgfx::ShaderHandle{ m_shaders[1].handle })); + bgfx::ShaderHandle fragmentShaderHandle = bgfx::createShader(bgfx::makeRef(m_shaders[1].binBlob.data(), static_cast(m_shaders[1].binBlob.size()))); + if (!bgfx::isValid(fragmentShaderHandle)) + { + ClearShaderData(0); + ClearShaderData(1); + DistoryShaderHandle(0); + return false; + } + m_shaders[1].handle = fragmentShaderHandle.idx; + } + + return true; +} + +bool ShaderResource::BuildProgramHandle() +{ + assert(!bgfx::isValid(bgfx::ProgramHandle{ m_programHandle })); + + if (ShaderProgramType::Standard == m_type) + { + m_programHandle = bgfx::createProgram(bgfx::ShaderHandle{ m_shaders[0].handle }, bgfx::ShaderHandle{ m_shaders[1].handle }).idx; + } + else if (ShaderProgramType::Compute == m_type || ShaderProgramType::VertexOnly == m_type) + { + m_programHandle = bgfx::createProgram(bgfx::ShaderHandle{ m_shaders[0].handle }).idx; + } + else + { + CD_WARN("Unknow shader program type of {}!", m_name); + } + + if (!bgfx::isValid(bgfx::ProgramHandle{ m_programHandle })) + { + return false; + } + + return true; +} + +void ShaderResource::ClearShaderData(size_t index) +{ + m_shaders[index].binBlob.clear(); +} + +void ShaderResource::FreeShaderData(size_t index) +{ + ClearShaderData(index); + ShaderBlob().swap(m_shaders[index].binBlob); +} + +void ShaderResource::DistoryShaderHandle(size_t index) +{ + if (bgfx::isValid(bgfx::ShaderHandle{ m_shaders[index].handle })) + { + bgfx::destroy(bgfx::ShaderHandle{ m_shaders[index].handle }); + m_shaders[index].handle = bgfx::kInvalidHandle; + } +} + +void ShaderResource::DistoryProgramHandle() +{ + if (bgfx::isValid(bgfx::ProgramHandle{ m_programHandle })) + { + bgfx::destroy(bgfx::ProgramHandle{ m_programHandle }); + m_programHandle = bgfx::kInvalidHandle; + } +} + +void ShaderResource::CheckIndex(size_t index) const +{ + if (ShaderProgramType::Standard == m_type) + { + assert(index <= 1); + } + else + { + assert(index == 0); + } +} + +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/Resources/ShaderResource.h b/Engine/Source/Runtime/Rendering/Resources/ShaderResource.h new file mode 100644 index 00000000..5134cced --- /dev/null +++ b/Engine/Source/Runtime/Rendering/Resources/ShaderResource.h @@ -0,0 +1,90 @@ +#pragma once + +#include "Base/Template.h" +#include "IResource.h" +#include "Rendering/ShaderType.h" + +#include +#include + +namespace engine +{ + +class ShaderResource : public IResource +{ +public: + using ShaderBlob = std::vector; + + struct ShaderInfo + { + ShaderType type; + // Name without shader frature. + std::string name; + std::string scPath; + // Should be the path to a specific variant file. + std::string binPath; + + ShaderBlob binBlob; + uint16_t handle = UINT16_MAX; + }; + +public: + ShaderResource() = default; + ShaderResource(const ShaderResource&) = default; + ShaderResource& operator=(const ShaderResource&) = default; + ShaderResource(ShaderResource&&) = default; + ShaderResource& operator=(ShaderResource&&) = default; + virtual ~ShaderResource(); + + virtual void Update() override; + virtual void Reset() override; + + void SetShaders(const std::string& vsName, const std::string& fsName, const std::string& combine = ""); + void SetShader(ShaderType type, const std::string& name, const std::string& combine = ""); + + void SetShaderInfo(ShaderInfo info, size_t index); + ShaderInfo& GetShaderInfo(size_t index); + const ShaderInfo& GetShaderInfo(size_t index) const; + + void SetActive(bool active) { m_active = active; } + bool IsActive() const { return m_active; } + + void SetName(std::string name) { m_name = cd::MoveTemp(name); } + std::string& GetName() { return m_name; } + const std::string& GetName() const { return m_name; } + + ShaderProgramType GetType() const { return m_type; } + void SetType(ShaderProgramType type) { m_type = type; } + + void SetFeaturesCombine(std::string combine) { m_featuresCombine = cd::MoveTemp(combine); } + std::string& GetFeaturesCombine() { return m_featuresCombine; } + const std::string& GetFeaturesCombine() const { return m_featuresCombine; } + + uint16_t GetHandle() const { return m_programHandle; } + +private: + bool LoadShader(); + bool BuildShaderHandle(); + bool BuildProgramHandle(); + + void ClearShaderData(size_t index); + void FreeShaderData(size_t index); + void DistoryShaderHandle(size_t index); + void DistoryProgramHandle(); + + void CheckIndex(size_t index) const; + + ShaderInfo m_shaders[2]; + + // Runtime + bool m_active = false; + std::string m_name; + ShaderProgramType m_type = ShaderProgramType::None; + std::string m_featuresCombine; + uint32_t m_recycleCount = 0; + + // GPU + uint16_t m_programHandle = UINT16_MAX; +}; + +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/Resources/TextureResource.cpp b/Engine/Source/Runtime/Rendering/Resources/TextureResource.cpp index 8e2aee8c..f3637956 100644 --- a/Engine/Source/Runtime/Rendering/Resources/TextureResource.cpp +++ b/Engine/Source/Runtime/Rendering/Resources/TextureResource.cpp @@ -128,7 +128,7 @@ void TextureResource::Update() constexpr uint32_t recycleDelayFrames = 30U; if (m_recycleCount++ >= recycleDelayFrames) { - FreeTextureData(); + ClearTextureData(); m_recycleCount = 0U; SetStatus(ResourceStatus::Optimized); @@ -213,10 +213,9 @@ void TextureResource::BuildTextureHandle() assert(m_textureHandle != UINT16_MAX); } -void TextureResource::FreeTextureData() +void TextureResource::ClearTextureData() { m_textureRawData.clear(); - if (m_textureImageData) { auto* pImageContainer = reinterpret_cast(m_textureImageData); @@ -225,6 +224,12 @@ void TextureResource::FreeTextureData() } } +void TextureResource::FreeTextureData() +{ + ClearTextureData(); + TextureRawData().swap(m_textureRawData); +} + void TextureResource::DestroySamplerHandle() { if (m_samplerHandle != UINT16_MAX) diff --git a/Engine/Source/Runtime/Rendering/Resources/TextureResource.h b/Engine/Source/Runtime/Rendering/Resources/TextureResource.h index d5df475c..f4d20694 100644 --- a/Engine/Source/Runtime/Rendering/Resources/TextureResource.h +++ b/Engine/Source/Runtime/Rendering/Resources/TextureResource.h @@ -51,6 +51,7 @@ class TextureResource : public IResource void BuildSamplerHandle(); void BuildTextureHandle(); + void ClearTextureData(); void FreeTextureData(); void DestroySamplerHandle(); diff --git a/Engine/Source/Runtime/Rendering/ShaderCollections.cpp b/Engine/Source/Runtime/Rendering/ShaderCollections.cpp deleted file mode 100644 index 947c3fc9..00000000 --- a/Engine/Source/Runtime/Rendering/ShaderCollections.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#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] = cd::MoveTemp(names); -} - -void ShaderCollections::AddFeatureCombine(StringCrc programNameCrc, std::string combine) -{ - assert(IsProgramValid(programNameCrc) && "Shader program does not exist!"); - - m_programFeatureCombines[programNameCrc].insert(cd::MoveTemp(combine)); -} - -void ShaderCollections::DeleteFeatureCombine(StringCrc programNameCrc, std::string combine) -{ - assert(HasFeatureCombine(programNameCrc) && "Feature combine does not exist!"); - - m_programFeatureCombines[programNameCrc].erase(cd::MoveTemp(combine)); -} - -void ShaderCollections::SetShaders(StringCrc programNameCrc, std::set shaders) -{ - assert(IsProgramValid(programNameCrc) && "Shader program does not exist!"); - - m_shaderPrograms[programNameCrc] = cd::MoveTemp(shaders); -} - -void ShaderCollections::SetFeatureCombines(StringCrc programNameCrc, std::set combine) -{ - assert(IsProgramValid(programNameCrc) && "Shader program does not exist!"); - - m_programFeatureCombines[programNameCrc] = cd::MoveTemp(combine); -} - -bool ShaderCollections::IsProgramValid(StringCrc programNameCrc) const -{ - return (m_shaderPrograms.find(programNameCrc) != m_shaderPrograms.end()); -} - -bool ShaderCollections::HasFeatureCombine(StringCrc programNameCrc) const -{ - return (m_programFeatureCombines.find(programNameCrc) != m_programFeatureCombines.end()); -} - -void ShaderCollections::SetShaderPrograms(std::map> shaders) -{ - m_shaderPrograms = cd::MoveTemp(shaders); -} - -void ShaderCollections::SetProgramFeatureCombines(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 deleted file mode 100644 index 8ee8429e..00000000 --- a/Engine/Source/Runtime/Rendering/ShaderCollections.h +++ /dev/null @@ -1,57 +0,0 @@ -#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]; } - const std::set& GetShaders(StringCrc programNameCrc) const { return m_shaderPrograms.at(programNameCrc); } - - void SetFeatureCombines(StringCrc programNameCrc, std::set combine); - std::set& GetFeatureCombines(StringCrc programNameCrc) { return m_programFeatureCombines[programNameCrc]; } - const std::set& GetFeatureCombines(StringCrc programNameCrc) const { return m_programFeatureCombines.at(programNameCrc); } - - 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 SetProgramFeatureCombines(std::map> combines); - std::map>& GetProgramFeatureCombines() { return m_programFeatureCombines; } - const std::map>& GetProgramFeatureCombiness() const { return m_programFeatureCombines; } - -private: - // Key : Program name, Value : Shader names - std::map> m_shaderPrograms; - // Key : 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 deleted file mode 100644 index 1ece2c39..00000000 --- a/Engine/Source/Runtime/Rendering/ShaderCompileInfo.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "Base/Template.h" -#include "ECWorld/Entity.h" - -#include -#include - -namespace engine -{ - -class ShaderCompileInfo -{ -public: - ShaderCompileInfo(Entity entity, std::string name, std::string combine = "") : - m_entity(entity), m_programName(cd::MoveTemp(name)), m_featuresCombine(cd::MoveTemp(combine)) {} - ShaderCompileInfo() = delete; - ShaderCompileInfo(const ShaderCompileInfo&) = default; - ShaderCompileInfo& operator=(const ShaderCompileInfo&) = default; - ShaderCompileInfo(ShaderCompileInfo&&) = default; - ShaderCompileInfo& operator=(ShaderCompileInfo&&) = default; - ~ShaderCompileInfo() = default; - - Entity m_entity = INVALID_ENTITY; - std::string m_programName; - std::string m_featuresCombine; - std::set m_taskHandles; - - bool operator==(const ShaderCompileInfo& other) const - { - return (m_entity == other.m_entity) && (m_programName == other.m_programName) && (m_featuresCombine == other.m_featuresCombine); - } - - bool operator<(const ShaderCompileInfo& other) const - { - if (m_entity < other.m_entity) - { - return true; - } - if (m_entity > other.m_entity) - { - return false; - } - - if (m_programName < other.m_programName) - { - return true; - } - if (m_programName > other.m_programName) - { - return false; - } - - return 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 index c91ba474..d63321c5 100644 --- a/Engine/Source/Runtime/Rendering/ShaderFeature.h +++ b/Engine/Source/Runtime/Rendering/ShaderFeature.h @@ -46,7 +46,7 @@ constexpr const char* ShaderFeatureNames[] = static_assert(static_cast(ShaderFeature::COUNT) == sizeof(ShaderFeatureNames) / sizeof(char*), "Shader features and names mismatch."); -CD_FORCEINLINE constexpr const char* GetFeatureName(ShaderFeature feature) +constexpr const char* GetFeatureName(ShaderFeature feature) { return ShaderFeatureNames[static_cast(feature)]; } diff --git a/Engine/Source/Runtime/Rendering/ShaderType.h b/Engine/Source/Runtime/Rendering/ShaderType.h index a13f5a00..85c68ea7 100644 --- a/Engine/Source/Runtime/Rendering/ShaderType.h +++ b/Engine/Source/Runtime/Rendering/ShaderType.h @@ -2,6 +2,7 @@ #include "base/Platform.h" +#include #include namespace engine @@ -10,12 +11,25 @@ namespace engine enum class ShaderType { None, - Compute, Vertex, - Fragment + Fragment, + Compute, +}; + +enum class ShaderProgramType +{ + None, + Standard, + VertexOnly, + Compute, +}; + +inline const std::map ProgramTypeToSingleShaderType = { + { ShaderProgramType::VertexOnly, ShaderType::Vertex }, + { ShaderProgramType::Compute, ShaderType::Compute }, }; -CD_FORCEINLINE static const ShaderType GetShaderType(const std::string& fileName) +inline ShaderType GetShaderType(const std::string& fileName) { if (fileName._Starts_with("vs_") || fileName._Starts_with("VS_")) { diff --git a/Engine/Source/Runtime/Rendering/ShadowMapRenderer.cpp b/Engine/Source/Runtime/Rendering/ShadowMapRenderer.cpp index 2bc7dddf..705aee72 100644 --- a/Engine/Source/Runtime/Rendering/ShadowMapRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/ShadowMapRenderer.cpp @@ -1,15 +1,16 @@ #include "ShadowMapRenderer.h" #include "ECWorld/CameraComponent.h" +#include "ECWorld/LightComponent.h" #include "ECWorld/SceneWorld.h" #include "ECWorld/StaticMeshComponent.h" #include "ECWorld/TransformComponent.h" -#include "ECWorld/LightComponent.h" #include "LightUniforms.h" #include "Material/ShaderSchema.h" #include "Math/Transform.hpp" #include "Rendering/RenderContext.h" #include "Rendering/Resources/MeshResource.h" +#include "Rendering/Resources/ShaderResource.h" #include @@ -18,18 +19,16 @@ namespace engine namespace { -// uniform name -constexpr const char* cameraPos = "u_cameraPos"; -constexpr const char* lightCountAndStride = "u_lightCountAndStride"; -constexpr const char* lightParams = "u_lightParams"; -constexpr const char* lightPosAndFarPlane = "u_lightWorldPos_farPlane"; -constexpr const char* lightDir = "u_LightDir"; + +constexpr const char* cameraPos = "u_cameraPos"; +constexpr const char* lightCountAndStride = "u_lightCountAndStride"; +constexpr const char* lightParams = "u_lightParams"; +constexpr const char* lightPosAndFarPlane = "u_lightWorldPos_farPlane"; +constexpr const char* lightDir = "u_LightDir"; constexpr const char* heightOffsetAndshadowLength = "u_HeightOffsetAndshadowLength"; -// constexpr uint64_t samplerFlags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_W_CLAMP; -constexpr uint64_t defaultRenderingState = BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_WRITE_Z -| BGFX_STATE_WRITE_MASK | BGFX_STATE_MSAA | BGFX_STATE_DEPTH_TEST_LESS; +constexpr uint64_t defaultRenderingState = BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_WRITE_Z | BGFX_STATE_WRITE_MASK | BGFX_STATE_MSAA | BGFX_STATE_DEPTH_TEST_LESS; constexpr uint64_t depthBufferFlags = BGFX_TEXTURE_RT | BGFX_SAMPLER_COMPARE_LEQUAL; constexpr uint64_t linearDepthBufferFlags = BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP; @@ -37,10 +36,8 @@ constexpr uint64_t linearDepthBufferFlags = BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLA void ShadowMapRenderer::Init() { - constexpr StringCrc shadowMapProgramCrc = StringCrc("ShadowMapProgram"); - GetRenderContext()->RegisterShaderProgram(shadowMapProgramCrc, { "vs_shadowMap", "fs_shadowMap" }); - constexpr StringCrc linearshadowMapProgramCrc = StringCrc("LinearShadowMapProgram"); - GetRenderContext()->RegisterShaderProgram(linearshadowMapProgramCrc, { "vs_shadowMap", "fs_shadowMap_linear" }); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("ShadowMapProgram", "vs_shadowMap", "fs_shadowMap")); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("LinearShadowMapProgram", "vs_shadowMap", "fs_shadowMap_linear")); for (int lightIndex = 0; lightIndex < shadowLightMaxNum; lightIndex++) { @@ -50,12 +47,7 @@ void ShadowMapRenderer::Init() bgfx::setViewName(m_renderPassID[lightIndex * shadowTexturePassMaxNum + mapId], "ShadowMapRenderer"); } } -} -void ShadowMapRenderer::Warmup() -{ - GetRenderContext()->UploadShaderProgram("ShadowMapProgram"); - GetRenderContext()->UploadShaderProgram("LinearShadowMapProgram"); GetRenderContext()->CreateUniform(lightPosAndFarPlane, bgfx::UniformType::Vec4, 1); } @@ -66,6 +58,15 @@ void ShadowMapRenderer::UpdateView(const float* pViewMatrix, const float* pProje void ShadowMapRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + // TODO : Remove it. If every renderer need to submit camera related uniform, it should be done not inside Renderer class. const cd::Transform& cameraTransform = m_pCurrentSceneWorld->GetTransformComponent(m_pCurrentSceneWorld->GetMainCameraEntity())->GetTransform(); @@ -206,7 +207,7 @@ void ShadowMapRenderer::Render(float deltaTime) for (const auto& corner : cascadeFrustum) { const auto lightSpaceCorner = lightView * cd::Vec4f(corner.x(), corner.y(), corner.z(), 1.0); - minX = std::min(minX, lightSpaceCorner.x()); + minX = std::min(minX, lightSpaceCorner.x()); maxX = std::max(maxX, lightSpaceCorner.x()); minY = std::min(minY, lightSpaceCorner.y()); maxY = std::max(maxY, lightSpaceCorner.y()); @@ -229,7 +230,7 @@ void ShadowMapRenderer::Render(float deltaTime) cd::Matrix4x4 lightCSMViewProj = lightProjection * lightView; lightComponent->AddLightViewProjMatrix(lightCSMViewProj); - // Submit draw call (TODO : one pass MRT + // Submit draw call (TODO : one pass MRT for (Entity entity : m_pCurrentSceneWorld->GetMaterialEntities()) { // No mesh attached? @@ -258,7 +259,8 @@ void ShadowMapRenderer::Render(float deltaTime) } // Mesh - SubmitStaticMeshDrawCall(pMeshComponent, viewId, "ShadowMapProgram"); + constexpr StringCrc programHandleIndex{ "ShadowMapProgram" }; + SubmitStaticMeshDrawCall(pMeshComponent, viewId, programHandleIndex); } } } @@ -336,7 +338,8 @@ void ShadowMapRenderer::Render(float deltaTime) bgfx::setTransform(pTransformComponent->GetWorldMatrix().begin()); } - SubmitStaticMeshDrawCall(pMeshComponent, viewId, "LinearShadowMapProgram"); + constexpr StringCrc programHandleIndex{ "LinearShadowMapProgram" }; + SubmitStaticMeshDrawCall(pMeshComponent, viewId, programHandleIndex); } } } @@ -403,7 +406,8 @@ void ShadowMapRenderer::Render(float deltaTime) } // Mesh - SubmitStaticMeshDrawCall(pMeshComponent, viewId, "ShadowMapProgram"); + constexpr StringCrc programHandleIndex{ "ShadowMapProgram" }; + SubmitStaticMeshDrawCall(pMeshComponent, viewId, programHandleIndex); } } break; @@ -418,4 +422,4 @@ void ShadowMapRenderer::Render(float deltaTime) } } -} +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Rendering/ShadowMapRenderer.h b/Engine/Source/Runtime/Rendering/ShadowMapRenderer.h index 567feba3..0f4a5db6 100644 --- a/Engine/Source/Runtime/Rendering/ShadowMapRenderer.h +++ b/Engine/Source/Runtime/Rendering/ShadowMapRenderer.h @@ -18,7 +18,6 @@ class ShadowMapRenderer 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/SkeletonRenderer.cpp b/Engine/Source/Runtime/Rendering/SkeletonRenderer.cpp index 5cb6f9ed..39a87fee 100644 --- a/Engine/Source/Runtime/Rendering/SkeletonRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/SkeletonRenderer.cpp @@ -5,6 +5,7 @@ #include "ECWorld/TransformComponent.h" #include "Rendering/RenderContext.h" #include "Rendering/Utility/VertexLayoutUtility.h" +#include "Rendering/Resources/ShaderResource.h" namespace engine { @@ -56,17 +57,11 @@ void TraverseBone(const cd::Bone& bone, const cd::SceneDatabase* pSceneDatabase, void SkeletonRenderer::Init() { - constexpr StringCrc programCrc = StringCrc("SkeletonProgram"); - GetRenderContext()->RegisterShaderProgram(programCrc, {"vs_AABB", "fs_AABB"}); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("SkeletonProgram", "vs_AABB", "fs_AABB")); bgfx::setViewName(GetViewID(), "SkeletonRenderer"); } -void SkeletonRenderer::Warmup() -{ - GetRenderContext()->UploadShaderProgram("SkeletonProgram"); -} - void SkeletonRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { UpdateViewRenderTarget(); @@ -114,6 +109,15 @@ void SkeletonRenderer::Build() void SkeletonRenderer::Render(float delataTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + for (Entity entity : m_pCurrentSceneWorld->GetAnimationEntities()) { auto pAnimationComponent = m_pCurrentSceneWorld->GetAnimationComponent(entity); @@ -135,7 +139,8 @@ void SkeletonRenderer::Render(float delataTime) bgfx::setState(state); - GetRenderContext()->Submit(GetViewID(), "SkeletonProgram"); + constexpr StringCrc programHandleIndex{ "SkeletonProgram" }; + GetRenderContext()->Submit(GetViewID(), programHandleIndex); } } diff --git a/Engine/Source/Runtime/Rendering/SkeletonRenderer.h b/Engine/Source/Runtime/Rendering/SkeletonRenderer.h index 3ced1d57..81632f97 100644 --- a/Engine/Source/Runtime/Rendering/SkeletonRenderer.h +++ b/Engine/Source/Runtime/Rendering/SkeletonRenderer.h @@ -14,7 +14,6 @@ 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/SkyboxRenderer.cpp b/Engine/Source/Runtime/Rendering/SkyboxRenderer.cpp index bbd4dda7..fb454a74 100644 --- a/Engine/Source/Runtime/Rendering/SkyboxRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/SkyboxRenderer.cpp @@ -5,6 +5,7 @@ #include "ECWorld/SkyComponent.h" #include "Rendering/RenderContext.h" #include "Rendering/Resources/MeshResource.h" +#include "Rendering/Resources/ShaderResource.h" namespace engine { @@ -23,21 +24,14 @@ 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"}); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("skyboxProgram", "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()->CreateUniform("s_texSkybox", bgfx::UniformType::Sampler); GetRenderContext()->CreateUniform(skyboxStrength, bgfx::UniformType::Vec4, 1); + SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); GetRenderContext()->CreateTexture(pSkyComponent->GetRadianceTexturePath().c_str(), sampleFalg); - GetRenderContext()->UploadShaderProgram(skyboxProgram); + bgfx::setViewName(GetViewID(), "SkyboxRenderer"); } void SkyboxRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -68,6 +62,15 @@ void SkyboxRenderer::Render(float deltaTime) return; } + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + StaticMeshComponent* pMeshComponent = m_pCurrentSceneWorld->GetStaticMeshComponent(m_pCurrentSceneWorld->GetSkyEntity()); if (!pMeshComponent) { @@ -95,7 +98,9 @@ void SkyboxRenderer::Render(float deltaTime) GetRenderContext()->GetTexture(StringCrc(pSkyComponent->GetRadianceTexturePath()))); bgfx::setState(renderState); - SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), skyboxProgram); + + constexpr StringCrc programHandleIndex{ "skyboxProgram" }; + SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), programHandleIndex); } bool SkyboxRenderer::IsEnable() const diff --git a/Engine/Source/Runtime/Rendering/SkyboxRenderer.h b/Engine/Source/Runtime/Rendering/SkyboxRenderer.h index d61cf64b..6cc9ec9a 100644 --- a/Engine/Source/Runtime/Rendering/SkyboxRenderer.h +++ b/Engine/Source/Runtime/Rendering/SkyboxRenderer.h @@ -13,7 +13,6 @@ 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 a2ddf6d1..0b05e160 100644 --- a/Engine/Source/Runtime/Rendering/TerrainRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/TerrainRenderer.cpp @@ -11,6 +11,7 @@ #include "Math/Transform.hpp" #include "Rendering/RenderContext.h" #include "Rendering/Resources/MeshResource.h" +#include "Rendering/Resources/ShaderResource.h" #include "Scene/Texture.h" #include "U_IBL.sh" #include "U_Terrain.sh" @@ -56,11 +57,6 @@ constexpr uint64_t defaultRenderingState = BGFX_STATE_WRITE_MASK | BGFX_STATE_MS } void TerrainRenderer::Init() -{ - bgfx::setViewName(GetViewID(), "TerrainRenderer"); -} - -void TerrainRenderer::Warmup() { SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); @@ -92,6 +88,8 @@ void TerrainRenderer::Warmup() GetRenderContext()->CreateUniform(lightParams, bgfx::UniformType::Vec4, LightUniform::VEC4_COUNT); GetRenderContext()->CreateTexture(elevationTexture, 129U, 129U, 1, bgfx::TextureFormat::Enum::R32F, samplerFlags, nullptr, 0); + + bgfx::setViewName(GetViewID(), "TerrainRenderer"); } void TerrainRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -111,8 +109,7 @@ void TerrainRenderer::Render(float deltaTime) { MaterialComponent* pMaterialComponent = m_pCurrentSceneWorld->GetMaterialComponent(entity); if (!pMaterialComponent || - pMaterialComponent->GetMaterialType() != m_pCurrentSceneWorld->GetTerrainMaterialType() || - !GetRenderContext()->IsShaderProgramValid(pMaterialComponent->GetShaderProgramName(), pMaterialComponent->GetFeaturesCombine())) + pMaterialComponent->GetMaterialType() != m_pCurrentSceneWorld->GetTerrainMaterialType()) { // TODO : improve this condition. As we want to skip some feature-specified entities to render. // For example, terrain/particle/... @@ -133,6 +130,13 @@ void TerrainRenderer::Render(float deltaTime) continue; } + const ShaderResource* pShaderResource = pMaterialComponent->GetShaderResource(); + if (ResourceStatus::Ready != pShaderResource->GetStatus() && + ResourceStatus::Optimized != pShaderResource->GetStatus()) + { + continue; + } + // Transform if (TransformComponent* pTransformComponent = m_pCurrentSceneWorld->GetTransformComponent(entity)) { @@ -229,7 +233,7 @@ void TerrainRenderer::Render(float deltaTime) bgfx::setState(state); - SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), pMaterialComponent->GetShaderProgramName()); + SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), pShaderResource->GetHandle()); } } diff --git a/Engine/Source/Runtime/Rendering/TerrainRenderer.h b/Engine/Source/Runtime/Rendering/TerrainRenderer.h index 1e7d5342..01915a3e 100644 --- a/Engine/Source/Runtime/Rendering/TerrainRenderer.h +++ b/Engine/Source/Runtime/Rendering/TerrainRenderer.h @@ -13,7 +13,6 @@ 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 c535bb77..6b45aa51 100644 --- a/Engine/Source/Runtime/Rendering/WhiteModelRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/WhiteModelRenderer.cpp @@ -6,6 +6,7 @@ #include "ECWorld/TransformComponent.h" #include "Rendering/RenderContext.h" #include "Rendering/Resources/MeshResource.h" +#include "Rendering/Resources/ShaderResource.h" #include "Scene/Texture.h" namespace engine @@ -13,17 +14,11 @@ namespace engine void WhiteModelRenderer::Init() { - constexpr StringCrc programCrc = StringCrc("WhiteModelProgram"); - GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_whiteModel", "fs_whiteModel" }); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("WhiteModelProgram", "vs_whiteModel", "fs_whiteModel")); bgfx::setViewName(GetViewID(), "WhiteModelRenderer"); } -void WhiteModelRenderer::Warmup() -{ - GetRenderContext()->UploadShaderProgram("WhiteModelProgram"); -} - void WhiteModelRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) { UpdateViewRenderTarget(); @@ -32,6 +27,15 @@ void WhiteModelRenderer::UpdateView(const float* pViewMatrix, const float* pProj void WhiteModelRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + for (Entity entity : m_pCurrentSceneWorld->GetStaticMeshEntities()) { if (m_pCurrentSceneWorld->GetSkyEntity() == entity) @@ -68,7 +72,8 @@ void WhiteModelRenderer::Render(float deltaTime) BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA); bgfx::setState(state); - SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), "WhiteModelProgram"); + constexpr StringCrc programHandleIndex{ "WhiteModelProgram" }; + SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), programHandleIndex); } } diff --git a/Engine/Source/Runtime/Rendering/WhiteModelRenderer.h b/Engine/Source/Runtime/Rendering/WhiteModelRenderer.h index c7a97f99..62325dec 100644 --- a/Engine/Source/Runtime/Rendering/WhiteModelRenderer.h +++ b/Engine/Source/Runtime/Rendering/WhiteModelRenderer.h @@ -15,7 +15,6 @@ 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 53e3809a..c4cbf42f 100644 --- a/Engine/Source/Runtime/Rendering/WireframeRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/WireframeRenderer.cpp @@ -6,6 +6,7 @@ #include "ECWorld/TransformComponent.h" #include "Rendering/RenderContext.h" #include "Rendering/Resources/MeshResource.h" +#include "Rendering/Resources/ShaderResource.h" #include "Scene/Texture.h" #undef EDITOR_MODE @@ -15,17 +16,11 @@ namespace engine void WireframeRenderer::Init() { - constexpr StringCrc programCrc = StringCrc("WireframeLineProgram"); - GetRenderContext()->RegisterShaderProgram(programCrc, { "vs_wireframe_line", "fs_wireframe_line" }); + AddDependentShaderResource(GetRenderContext()->RegisterShaderProgram("WireframeLineProgram", "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(); @@ -34,6 +29,15 @@ void WireframeRenderer::UpdateView(const float* pViewMatrix, const float* pProje void WireframeRenderer::Render(float deltaTime) { + for (const auto pResource : m_dependentShaderResources) + { + if (ResourceStatus::Ready != pResource->GetStatus() && + ResourceStatus::Optimized != pResource->GetStatus()) + { + return; + } + } + for (Entity entity : m_pCurrentSceneWorld->GetStaticMeshEntities()) { if (!m_enableGlobalWireframe && m_pCurrentSceneWorld->GetSelectedEntity() != entity) @@ -75,7 +79,8 @@ 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); - SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), "WireframeLineProgram"); + constexpr StringCrc programHandleIndex{ "ImGuiProgram" }; + SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), programHandleIndex); } } diff --git a/Engine/Source/Runtime/Rendering/WireframeRenderer.h b/Engine/Source/Runtime/Rendering/WireframeRenderer.h index 90d1b191..209befd1 100644 --- a/Engine/Source/Runtime/Rendering/WireframeRenderer.h +++ b/Engine/Source/Runtime/Rendering/WireframeRenderer.h @@ -15,7 +15,6 @@ 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 f5f3d6f9..404bb2e1 100644 --- a/Engine/Source/Runtime/Rendering/WorldRenderer.cpp +++ b/Engine/Source/Runtime/Rendering/WorldRenderer.cpp @@ -11,6 +11,7 @@ #include "Math/Transform.hpp" #include "Rendering/RenderContext.h" #include "Rendering/Resources/MeshResource.h" +#include "Rendering/Resources/ShaderResource.h" #include "Rendering/Resources/TextureResource.h" #include "Scene/Texture.h" #include "U_AtmophericScattering.sh" @@ -62,11 +63,6 @@ constexpr uint64_t blitDstTextureFlags = BGFX_TEXTURE_BLIT_DST | BGFX_SAMPLER_ } void WorldRenderer::Init() -{ - bgfx::setViewName(GetViewID(), "WorldRenderer"); -} - -void WorldRenderer::Warmup() { SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); @@ -99,6 +95,8 @@ void WorldRenderer::Warmup() GetRenderContext()->CreateUniform(cameraNearFarPlane, bgfx::UniformType::Vec4, 1); GetRenderContext()->CreateUniform(clipFrustumDepth, bgfx::UniformType::Vec4, 1); + + bgfx::setViewName(GetViewID(), "WorldRenderer"); } void WorldRenderer::UpdateView(const float* pViewMatrix, const float* pProjectionMatrix) @@ -114,13 +112,13 @@ void WorldRenderer::Render(float deltaTime) const cd::Transform& cameraTransform = m_pCurrentSceneWorld->GetTransformComponent(m_pCurrentSceneWorld->GetMainCameraEntity())->GetTransform(); SkyComponent* pSkyComponent = m_pCurrentSceneWorld->GetSkyComponent(m_pCurrentSceneWorld->GetSkyEntity()); - auto lightEntities = m_pCurrentSceneWorld->GetLightEntities(); + const auto lightEntities = m_pCurrentSceneWorld->GetLightEntities(); size_t lightEntityCount = lightEntities.size(); // Blit RTV to SRV to update light shadow map for (int i = 0; i < lightEntityCount; i++) { - auto lightComponent = m_pCurrentSceneWorld->GetLightComponent(lightEntities[i]); + LightComponent* lightComponent = m_pCurrentSceneWorld->GetLightComponent(lightEntities[i]); cd::LightType lightType = lightComponent->GetType(); if (cd::LightType::Directional == lightType) { @@ -179,15 +177,20 @@ void WorldRenderer::Render(float deltaTime) for (Entity entity : m_pCurrentSceneWorld->GetMaterialEntities()) { MaterialComponent* pMaterialComponent = m_pCurrentSceneWorld->GetMaterialComponent(entity); - if (!pMaterialComponent || - (pMaterialComponent->GetMaterialType() == m_pCurrentSceneWorld->GetPBRMaterialType() && pMaterialComponent->GetMaterialType() == m_pCurrentSceneWorld->GetCelluloidMaterialType()) || - !GetRenderContext()->IsShaderProgramValid(pMaterialComponent->GetShaderProgramName(), pMaterialComponent->GetFeaturesCombine())) + if (!pMaterialComponent) { // TODO : improve this condition. As we want to skip some feature-specified entities to render. // For example, terrain/particle/... continue; } + // TODO : Temporary solution for CelluloidRenderer, remove it. + if (pMaterialComponent->GetMaterialType() != m_pCurrentSceneWorld->GetPBRMaterialType() && + pMaterialComponent->GetMaterialType() != m_pCurrentSceneWorld->GetCelluloidMaterialType()) + { + continue; + } + // No mesh attached? StaticMeshComponent* pMeshComponent = m_pCurrentSceneWorld->GetStaticMeshComponent(entity); if (!pMeshComponent) @@ -202,6 +205,13 @@ void WorldRenderer::Render(float deltaTime) continue; } + const ShaderResource* pShaderResource = pMaterialComponent->GetShaderResource(); + if (ResourceStatus::Ready != pShaderResource->GetStatus() && + ResourceStatus::Optimized != pShaderResource->GetStatus()) + { + continue; + } + // SkinMesh if(m_pCurrentSceneWorld->GetAnimationComponent(entity)) { @@ -358,7 +368,7 @@ void WorldRenderer::Render(float deltaTime) if (cd::LightType::Directional == lightType) { bgfx::TextureHandle blitDstShadowMapTexture = static_cast(lightComponent->GetShadowMapTexture()); - bgfx::setTexture(SHADOW_MAP_CUBE_FIRST_SLOT+lightIndex, GetRenderContext()->GetUniform(shadowMapSamplerCrcs[lightIndex]), blitDstShadowMapTexture); + bgfx::setTexture(SHADOW_MAP_CUBE_FIRST_SLOT + lightIndex, GetRenderContext()->GetUniform(shadowMapSamplerCrcs[lightIndex]), blitDstShadowMapTexture); // TODO : manual constexpr StringCrc clipFrustumDepthCrc(clipFrustumDepth); GetRenderContext()->FillUniform(clipFrustumDepthCrc, lightComponent->GetComputedCascadeSplit(), 1); @@ -366,13 +376,13 @@ void WorldRenderer::Render(float deltaTime) else if (cd::LightType::Point == lightType) { bgfx::TextureHandle blitDstShadowMapTexture = static_cast(lightComponent->GetShadowMapTexture()); - bgfx::setTexture(SHADOW_MAP_CUBE_FIRST_SLOT+lightIndex, GetRenderContext()->GetUniform(shadowMapSamplerCrcs[lightIndex]), blitDstShadowMapTexture); + bgfx::setTexture(SHADOW_MAP_CUBE_FIRST_SLOT + lightIndex, GetRenderContext()->GetUniform(shadowMapSamplerCrcs[lightIndex]), blitDstShadowMapTexture); } else if (cd::LightType::Spot == lightType) { // Blit RTV(FrameBuffer Texture) to SRV(Texture) bgfx::TextureHandle blitDstShadowMapTexture = static_cast(lightComponent->GetShadowMapTexture()); - bgfx::setTexture(SHADOW_MAP_CUBE_FIRST_SLOT+lightIndex, GetRenderContext()->GetUniform(shadowMapSamplerCrcs[lightIndex]), blitDstShadowMapTexture); + bgfx::setTexture(SHADOW_MAP_CUBE_FIRST_SLOT + lightIndex, GetRenderContext()->GetUniform(shadowMapSamplerCrcs[lightIndex]), blitDstShadowMapTexture); } } @@ -397,11 +407,11 @@ void WorldRenderer::Render(float deltaTime) bgfx::setVertexBuffer(1, bgfx::VertexBufferHandle{ pBlendShapeComponent->GetNonMorphAffectedVB() }); // TODO : BlendShape + multiple index buffers. bgfx::setIndexBuffer(bgfx::IndexBufferHandle{ pMeshComponent->GetMeshResource()->GetIndexBufferHandle(0U) }); - GetRenderContext()->Submit(GetViewID(), pMaterialComponent->GetShaderProgramName(), pMaterialComponent->GetFeaturesCombine()); + GetRenderContext()->Submit(GetViewID(), pShaderResource->GetHandle()); } else { - SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), pMaterialComponent->GetShaderProgramName(), pMaterialComponent->GetFeaturesCombine()); + SubmitStaticMeshDrawCall(pMeshComponent, GetViewID(), pShaderResource->GetHandle()); } } } diff --git a/Engine/Source/Runtime/Rendering/WorldRenderer.h b/Engine/Source/Runtime/Rendering/WorldRenderer.h index 19d79d93..7ddc7357 100644 --- a/Engine/Source/Runtime/Rendering/WorldRenderer.h +++ b/Engine/Source/Runtime/Rendering/WorldRenderer.h @@ -13,7 +13,6 @@ 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;