diff --git a/Resources/Engine/Shaders/Standard.ovfx b/Resources/Engine/Shaders/Standard.ovfx index 3a8f73aad..97e11ba33 100644 --- a/Resources/Engine/Shaders/Standard.ovfx +++ b/Resources/Engine/Shaders/Standard.ovfx @@ -1,4 +1,11 @@ #pass SHADOW_PASS +#pass ALBEDO_PASS +#pass METALLIC_PASS +#pass ROUGHNESS_PASS +#pass AO_PASS +#pass NORMAL_PASS +#pass UV_PASS +#pass DEPTH_PASS #feature PARALLAX_MAPPING #feature ALPHA_CLIPPING @@ -129,6 +136,16 @@ void main() } #endif +#if defined(DEPTH_PASS) + const float near = 0.1; + const float far = 50.0; + const float depth = gl_FragCoord.z; + const float z = depth * 2.0 - 1.0; // back to NDC + float linearDepth = (2.0 * near * far) / (far + near - z * (far - near)) / far; + FRAGMENT_COLOR = vec4(vec3(linearDepth), 1.0); + return; +#endif + vec2 texCoords = TileAndOffsetTexCoords(fs_in.TexCoords, u_TextureTiling, u_TextureOffset); #if defined(PARALLAX_MAPPING) @@ -170,6 +187,18 @@ void main() const vec3 normal = normalize(fs_in.Normal); #endif +#if defined(NORMAL_PASS) + FRAGMENT_COLOR = vec4((normal + 1.0) / 2.0, 1.0); + return; +#endif + + const float ao = texture(u_AmbientOcclusionMap, texCoords).r; + +#if defined(AO_PASS) + FRAGMENT_COLOR = vec4(ao.rrr, 1.0); + return; +#endif + #if defined(SPECULAR_WORKFLOW) const float specular = texture(u_SpecularMap, texCoords).r * u_Specular; const float glossiness = texture(u_GlossinessMap, texCoords).r * u_Glossiness; @@ -180,7 +209,25 @@ void main() const float roughness = texture(u_RoughnessMap, texCoords).r * u_Roughness; #endif - const float ao = texture(u_AmbientOcclusionMap, texCoords).r; +#if defined(ALBEDO_PASS) + FRAGMENT_COLOR = vec4(albedo.rgba); + return; +#endif + +#if defined(METALLIC_PASS) + FRAGMENT_COLOR = vec4(metallic.rrr, 1.0); + return; +#endif + +#if defined(ROUGHNESS_PASS) + FRAGMENT_COLOR = vec4(roughness.rrr, 1.0); + return; +#endif + +#if defined(UV_PASS) + FRAGMENT_COLOR = vec4(texCoords.x, texCoords.y, 0.0, 1.0); + return; +#endif vec3 pbr = PBRLightingModel( albedo.rgb, diff --git a/Sources/Overload/OvCore/include/OvCore/Rendering/EngineBufferRenderFeature.h b/Sources/Overload/OvCore/include/OvCore/Rendering/EngineBufferRenderFeature.h index 2d909c14b..4f05ac7af 100644 --- a/Sources/Overload/OvCore/include/OvCore/Rendering/EngineBufferRenderFeature.h +++ b/Sources/Overload/OvCore/include/OvCore/Rendering/EngineBufferRenderFeature.h @@ -37,7 +37,7 @@ namespace OvCore::Rendering protected: virtual void OnBeginFrame(const OvRendering::Data::FrameDescriptor& p_frameDescriptor) override; virtual void OnEndFrame() override; - virtual void OnBeforeDraw(OvRendering::Data::PipelineState& p_pso, const OvRendering::Entities::Drawable& p_drawable) override; + virtual void OnBeforeDraw(OvRendering::Data::PipelineState& p_pso, OvRendering::Entities::Drawable& p_drawable) override; protected: std::chrono::high_resolution_clock::time_point m_startTime; diff --git a/Sources/Overload/OvCore/include/OvCore/Rendering/ShadowRenderFeature.h b/Sources/Overload/OvCore/include/OvCore/Rendering/ShadowRenderFeature.h index d49c69d56..b94a9594b 100644 --- a/Sources/Overload/OvCore/include/OvCore/Rendering/ShadowRenderFeature.h +++ b/Sources/Overload/OvCore/include/OvCore/Rendering/ShadowRenderFeature.h @@ -32,7 +32,7 @@ namespace OvCore::Rendering ShadowRenderFeature(OvRendering::Core::CompositeRenderer& p_renderer); protected: - virtual void OnBeforeDraw(OvRendering::Data::PipelineState& p_pso, const OvRendering::Entities::Drawable& p_drawable); + virtual void OnBeforeDraw(OvRendering::Data::PipelineState& p_pso, OvRendering::Entities::Drawable& p_drawable); virtual void OnAfterDraw(OvRendering::Data::PipelineState& p_pso, const OvRendering::Entities::Drawable& p_drawable); }; } \ No newline at end of file diff --git a/Sources/Overload/OvCore/src/OvCore/Rendering/EngineBufferRenderFeature.cpp b/Sources/Overload/OvCore/src/OvCore/Rendering/EngineBufferRenderFeature.cpp index 715404feb..f03d66276 100644 --- a/Sources/Overload/OvCore/src/OvCore/Rendering/EngineBufferRenderFeature.cpp +++ b/Sources/Overload/OvCore/src/OvCore/Rendering/EngineBufferRenderFeature.cpp @@ -80,7 +80,7 @@ void OvCore::Rendering::EngineBufferRenderFeature::OnEndFrame() m_engineBuffer->Unbind(); } -void OvCore::Rendering::EngineBufferRenderFeature::OnBeforeDraw(OvRendering::Data::PipelineState& p_pso, const OvRendering::Entities::Drawable& p_drawable) +void OvCore::Rendering::EngineBufferRenderFeature::OnBeforeDraw(OvRendering::Data::PipelineState& p_pso, OvRendering::Entities::Drawable& p_drawable) { OvTools::Utils::OptRef descriptor; diff --git a/Sources/Overload/OvCore/src/OvCore/Rendering/ShadowRenderFeature.cpp b/Sources/Overload/OvCore/src/OvCore/Rendering/ShadowRenderFeature.cpp index 95c48be76..47e110b0a 100644 --- a/Sources/Overload/OvCore/src/OvCore/Rendering/ShadowRenderFeature.cpp +++ b/Sources/Overload/OvCore/src/OvCore/Rendering/ShadowRenderFeature.cpp @@ -19,7 +19,7 @@ OvCore::Rendering::ShadowRenderFeature::ShadowRenderFeature(OvRendering::Core::C { } -void OvCore::Rendering::ShadowRenderFeature::OnBeforeDraw(OvRendering::Data::PipelineState& p_pso, const OvRendering::Entities::Drawable& p_drawable) +void OvCore::Rendering::ShadowRenderFeature::OnBeforeDraw(OvRendering::Data::PipelineState& p_pso, OvRendering::Entities::Drawable& p_drawable) { auto& material = p_drawable.material.value(); diff --git a/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h b/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h index 7ed7fd4df..7ff0fefe8 100644 --- a/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h +++ b/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h @@ -23,6 +23,11 @@ namespace tinyxml2 class XMLDocument; } +namespace OvEditor::Rendering +{ + enum class EDebugViewMode; +} + namespace OvEditor::Core { enum class EGizmoOperation; @@ -162,6 +167,12 @@ namespace OvEditor::Core * Returns the current gizmo operation */ EGizmoOperation GetGizmoOperation() const; + + /** + * Sets the debug view mode to use + * @param p_mode + */ + void SetSceneViewDebugMode(OvEditor::Rendering::EDebugViewMode p_mode); #pragma endregion #pragma region ACTOR_CREATION_DESTRUCTION diff --git a/Sources/Overload/OvEditor/include/OvEditor/Rendering/DebugSceneRenderer.h b/Sources/Overload/OvEditor/include/OvEditor/Rendering/DebugSceneRenderer.h index c2a86019c..6a8b22640 100644 --- a/Sources/Overload/OvEditor/include/OvEditor/Rendering/DebugSceneRenderer.h +++ b/Sources/Overload/OvEditor/include/OvEditor/Rendering/DebugSceneRenderer.h @@ -24,6 +24,19 @@ namespace OvEditor::Panels { class AView; } namespace OvEditor::Rendering { + enum class EDebugViewMode + { + NONE, + ALBEDO, + METALLIC, + ROUGHNESS, + AO, + NORMAL, + UV, + DEPTH, + WIREFRAME + }; + /** * Provide a debug layer on top of the default scene renderer to see "invisible" entities such as * lights, cameras, @@ -44,5 +57,11 @@ namespace OvEditor::Rendering * @param p_driver */ DebugSceneRenderer(OvRendering::Context::Driver& p_driver); + + /** + * Set a debug view mode + * @param p_mode + */ + void SetDebugViewMode(EDebugViewMode p_mode) const; }; } \ No newline at end of file diff --git a/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp b/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp index e3eb250a3..62c3c4a95 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -503,6 +504,13 @@ OvEditor::Core::EGizmoOperation OvEditor::Core::EditorActions::GetGizmoOperation return sceneView.GetGizmoOperation(); } +void OvEditor::Core::EditorActions::SetSceneViewDebugMode(OvEditor::Rendering::EDebugViewMode p_mode) +{ + auto& sceneView = m_panelsManager.GetPanelAs("Scene View"); + const auto& debugSceneRenderer = static_cast(sceneView.GetRenderer()); + debugSceneRenderer.SetDebugViewMode(p_mode); +} + OvMaths::FVector3 OvEditor::Core::EditorActions::CalculateActorSpawnPoint(float p_distanceToCamera) { auto& sceneView = m_panelsManager.GetPanelAs("Scene View"); diff --git a/Sources/Overload/OvEditor/src/OvEditor/Panels/Toolbar.cpp b/Sources/Overload/OvEditor/src/OvEditor/Panels/Toolbar.cpp index 46b46d8aa..91e3ce88a 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Panels/Toolbar.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Panels/Toolbar.cpp @@ -10,8 +10,10 @@ #include #include #include +#include #include +#include namespace { @@ -91,6 +93,25 @@ OvEditor::Panels::Toolbar::Toolbar }; EDITOR_EXEC(SetEditorMode(OvEditor::Core::EditorActions::EEditorMode::EDIT)); + + using enum OvEditor::Rendering::EDebugViewMode; + auto& debugViewSelector = CreateWidget(); + debugViewSelector.lineBreak = false; + debugViewSelector.choices = { + { static_cast(NONE), "Default" }, + { static_cast(ALBEDO), "Albedo" }, + { static_cast(METALLIC), "Metallic" }, + { static_cast(ROUGHNESS), "Roughness" }, + { static_cast(AO), "Ambient Occlusion" }, + { static_cast(NORMAL), "Normal"}, + { static_cast(UV), "UV"}, + { static_cast(DEPTH), "Depth"}, + { static_cast(WIREFRAME), "Wireframe"} + }; + debugViewSelector.currentChoice = 0; + debugViewSelector.ValueChangedEvent += [](int choice) { + EDITOR_EXEC(SetSceneViewDebugMode(static_cast(choice))); + }; } void OvEditor::Panels::Toolbar::_Draw_Impl() diff --git a/Sources/Overload/OvEditor/src/OvEditor/Rendering/DebugSceneRenderer.cpp b/Sources/Overload/OvEditor/src/OvEditor/Rendering/DebugSceneRenderer.cpp index 9d2b06dfa..9722cbb91 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Rendering/DebugSceneRenderer.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Rendering/DebugSceneRenderer.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -110,6 +111,63 @@ namespace } } +class DebugViewRenderFeature : public OvRendering::Features::ARenderFeature +{ +public: + DebugViewRenderFeature(OvRendering::Core::CompositeRenderer& p_renderer) : ARenderFeature(p_renderer) + { + } + + void SetDebugViewMode(OvEditor::Rendering::EDebugViewMode p_mode) + { + m_debugViewMode = p_mode; + } + +protected: + void OnBeforeDraw(OvRendering::Data::PipelineState& p_pso, OvRendering::Entities::Drawable& p_drawable) + { + if (m_debugViewMode != OvEditor::Rendering::EDebugViewMode::NONE && !p_drawable.pass.has_value()) + { + if (m_debugViewMode == OvEditor::Rendering::EDebugViewMode::WIREFRAME) + { + p_pso.rasterizationMode = OvRendering::Settings::ERasterizationMode::LINE; + } + + const std::string pass = _GetCurrentPassName(); + + if (p_drawable.material->HasPass(pass)) + { + p_drawable.pass = pass; + } + } + } + +private: + std::string _GetCurrentPassName() + { + using enum OvEditor::Rendering::EDebugViewMode; + + OVASSERT(m_debugViewMode != NONE, "Cannot retrieve current pass name if no debug view is set."); + + switch (m_debugViewMode) + { + case ALBEDO: return "ALBEDO_PASS"; + case METALLIC: return "METALLIC_PASS"; + case ROUGHNESS: return "ROUGHNESS_PASS"; + case AO: return "AO_PASS"; + case NORMAL: return "NORMAL_PASS"; + case UV: return "UV_PASS"; + case DEPTH: return "DEPTH_PASS"; + case WIREFRAME: return "ALBEDO_PASS"; + } + + return {}; + } + +private: + OvEditor::Rendering::EDebugViewMode m_debugViewMode = OvEditor::Rendering::EDebugViewMode::NONE; +}; + class DebugCamerasRenderPass : public OvRendering::Core::ARenderPass { public: @@ -643,6 +701,7 @@ OvEditor::Rendering::DebugSceneRenderer::DebugSceneRenderer(OvRendering::Context AddFeature(); AddFeature(); AddFeature(); + AddFeature(); AddPass("Grid", OvRendering::Settings::ERenderPassOrder::Debug); AddPass("Debug Cameras", OvRendering::Settings::ERenderPassOrder::Debug); @@ -650,3 +709,9 @@ OvEditor::Rendering::DebugSceneRenderer::DebugSceneRenderer(OvRendering::Context AddPass("Debug Actor", OvRendering::Settings::ERenderPassOrder::Debug); AddPass("Picking", OvRendering::Settings::ERenderPassOrder::Debug); } + +void OvEditor::Rendering::DebugSceneRenderer::SetDebugViewMode(EDebugViewMode p_mode) const +{ + GetFeature().SetDebugViewMode(p_mode); + GetPass("Post-Process").SetEnabled(p_mode == EDebugViewMode::NONE); +} diff --git a/Sources/Overload/OvRendering/include/OvRendering/Features/ARenderFeature.h b/Sources/Overload/OvRendering/include/OvRendering/Features/ARenderFeature.h index 519ee7877..61c74c8dd 100644 --- a/Sources/Overload/OvRendering/include/OvRendering/Features/ARenderFeature.h +++ b/Sources/Overload/OvRendering/include/OvRendering/Features/ARenderFeature.h @@ -59,7 +59,7 @@ namespace OvRendering::Features * Invoked before drawing a drawable entity * @param p_drawable */ - virtual void OnBeforeDraw(Data::PipelineState& p_pso, const Entities::Drawable& p_drawable); + virtual void OnBeforeDraw(Data::PipelineState& p_pso, Entities::Drawable& p_drawable); /** * Invoked after drawing a drawable entity diff --git a/Sources/Overload/OvRendering/src/OvRendering/Core/CompositeRenderer.cpp b/Sources/Overload/OvRendering/src/OvRendering/Core/CompositeRenderer.cpp index 3b4bd77c5..8ba90b2a1 100644 --- a/Sources/Overload/OvRendering/src/OvRendering/Core/CompositeRenderer.cpp +++ b/Sources/Overload/OvRendering/src/OvRendering/Core/CompositeRenderer.cpp @@ -91,6 +91,8 @@ void OvRendering::Core::CompositeRenderer::DrawEntity( { ZoneScoped; + Entities::Drawable drawable = p_drawable; + // Ensure the drawable is valid. // If not, skip the draw call and the attached features. if (!IsDrawable(p_drawable)) @@ -102,17 +104,17 @@ void OvRendering::Core::CompositeRenderer::DrawEntity( { if (feature->IsEnabled()) { - feature->OnBeforeDraw(p_pso, p_drawable); + feature->OnBeforeDraw(p_pso, drawable); } } - ABaseRenderer::DrawEntity(p_pso, p_drawable); + ABaseRenderer::DrawEntity(p_pso, drawable); for (const auto& [_, feature] : m_features) { if (feature->IsEnabled()) { - feature->OnAfterDraw(p_drawable); + feature->OnAfterDraw(drawable); } } } diff --git a/Sources/Overload/OvRendering/src/OvRendering/Features/ARenderFeature.cpp b/Sources/Overload/OvRendering/src/OvRendering/Features/ARenderFeature.cpp index 0e3f58296..0327b5440 100644 --- a/Sources/Overload/OvRendering/src/OvRendering/Features/ARenderFeature.cpp +++ b/Sources/Overload/OvRendering/src/OvRendering/Features/ARenderFeature.cpp @@ -32,7 +32,7 @@ void OvRendering::Features::ARenderFeature::OnEndFrame() { } -void OvRendering::Features::ARenderFeature::OnBeforeDraw(Data::PipelineState& p_pso, const Entities::Drawable& p_drawable) +void OvRendering::Features::ARenderFeature::OnBeforeDraw(Data::PipelineState& p_pso, Entities::Drawable& p_drawable) { }