From e217d5e79b9554e7f1d54f2ce58ee00be0e09882 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 27 Oct 2022 18:27:12 +0200 Subject: [PATCH] Refactor scene rendering to separate drawable actors --- Source/Engine/Debug/DebugDraw.cpp | 15 ++-- .../VolumeParticleMaterialShader.cpp | 2 +- Source/Engine/Graphics/RenderTask.cpp | 33 +++++---- Source/Engine/Graphics/RenderTask.h | 13 ++-- Source/Engine/Graphics/RenderView.h | 2 +- Source/Engine/Level/Actors/Decal.cpp | 8 +-- .../Engine/Level/Actors/DirectionalLight.cpp | 4 +- .../Engine/Level/Actors/EnvironmentProbe.cpp | 8 +-- .../Level/Actors/ExponentialHeightFog.cpp | 4 +- Source/Engine/Level/Actors/PointLight.cpp | 8 +-- Source/Engine/Level/Actors/Sky.cpp | 4 +- Source/Engine/Level/Actors/SkyLight.cpp | 4 +- Source/Engine/Level/Actors/Skybox.cpp | 4 +- Source/Engine/Level/Actors/SpotLight.cpp | 6 +- Source/Engine/Level/Level.cpp | 4 +- Source/Engine/Level/Level.h | 3 +- Source/Engine/Level/Scene/SceneRendering.cpp | 70 ++++++++++--------- Source/Engine/Level/Scene/SceneRendering.h | 22 ++++-- .../Renderer/GI/GlobalSurfaceAtlasPass.cpp | 3 +- .../Renderer/GlobalSignDistanceFieldPass.cpp | 3 +- Source/Engine/Renderer/Renderer.cpp | 5 +- .../Renderer/ScreenSpaceReflectionsPass.cpp | 6 +- 22 files changed, 129 insertions(+), 102 deletions(-) diff --git a/Source/Engine/Debug/DebugDraw.cpp b/Source/Engine/Debug/DebugDraw.cpp index 1d76014e4..cdf55f9c0 100644 --- a/Source/Engine/Debug/DebugDraw.cpp +++ b/Source/Engine/Debug/DebugDraw.cpp @@ -718,16 +718,17 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe if (renderContext.Buffers == nullptr || !DebugDrawVB) return; auto context = GPUDevice::Instance->GetMainContext(); - if (Context->Origin != renderContext.View.Origin) + const RenderView& view = renderContext.View; + if (Context->Origin != view.Origin) { // Teleport existing debug shapes to maintain their location - Float3 delta = Context->Origin - renderContext.View.Origin; + Float3 delta = Context->Origin - view.Origin; Context->DebugDrawDefault.Teleport(delta); Context->DebugDrawDepthTest.Teleport(delta); - Context->Origin = renderContext.View.Origin; + Context->Origin = view.Origin; } - Context->LastViewPos = renderContext.View.Position; - Context->LastViewProj = renderContext.View.Projection; + Context->LastViewPos = view.Position; + Context->LastViewProj = view.Projection; // Fallback to task buffers if (target == nullptr && renderContext.Task) @@ -755,7 +756,7 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe const auto cb = DebugDrawShader->GetShader()->GetCB(0); Data data; Matrix vp; - Matrix::Multiply(renderContext.View.View, renderContext.View.NonJitteredProjection, vp); + Matrix::Multiply(view.View, view.NonJitteredProjection, vp); Matrix::Transpose(vp, data.ViewProjection); data.EnableDepthTest = enableDepthTest; context->UpdateCB(cb, &data); @@ -866,7 +867,7 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe Matrix f; Matrix::RotationZ(PI, f); Float3 viewUp; - Float3::Transform(Float3::Up, Quaternion::LookRotation(renderContext.View.Direction, Float3::Up), viewUp); + Float3::Transform(Float3::Up, Quaternion::LookRotation(view.Direction, Float3::Up), viewUp); for (auto& t : Context->DebugDrawDefault.DefaultText3D) DrawText3D(t, renderContext, viewUp, f, vp, viewport, context, target, nullptr); for (auto& t : Context->DebugDrawDefault.OneFrameText3D) diff --git a/Source/Engine/Graphics/Materials/VolumeParticleMaterialShader.cpp b/Source/Engine/Graphics/Materials/VolumeParticleMaterialShader.cpp index f57a4df36..42d8ec87e 100644 --- a/Source/Engine/Graphics/Materials/VolumeParticleMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/VolumeParticleMaterialShader.cpp @@ -43,7 +43,7 @@ void VolumeParticleMaterialShader::Bind(BindParameters& params) { // Prepare auto context = params.GPUContext; - auto& view = params.RenderContext.View; + const RenderView& view = params.RenderContext.View; auto& drawCall = *params.FirstDrawCall; Span cb(_cbData.Get(), _cbData.Count()); ASSERT_LOW_LAYER(cb.Length() >= sizeof(VolumeParticleMaterialShaderData)); diff --git a/Source/Engine/Graphics/RenderTask.cpp b/Source/Engine/Graphics/RenderTask.cpp index b0aef806a..df35f809f 100644 --- a/Source/Engine/Graphics/RenderTask.cpp +++ b/Source/Engine/Graphics/RenderTask.cpp @@ -32,27 +32,26 @@ #if USE_MONO // TODO: use API for events and remove this manual wrapper code -class RenderContextInternal +struct RenderContextManaged { -public: MonoObject* Buffers; MonoObject* List; - RenderView View; - RenderView* LodProxyView; MonoObject* Task; + RenderView* LodProxyView; + RenderView View; }; // TODO: use API for events and remove this manual wrapper code namespace { - RenderContextInternal ToManaged(const RenderContext& value) + RenderContextManaged ToManaged(const RenderContext& value) { - RenderContextInternal result; + RenderContextManaged result; result.Buffers = ScriptingObject::ToManaged((ScriptingObject*)value.Buffers); result.List = ScriptingObject::ToManaged((ScriptingObject*)value.List); - result.View = value.View; - result.LodProxyView = value.LodProxyView; result.Task = ScriptingObject::ToManaged((ScriptingObject*)value.Task); + result.LodProxyView = value.LodProxyView; + result.View = value.View; return result; } } @@ -204,7 +203,7 @@ void ManagedPostProcessEffect::Render(RenderContext& renderContext, GPUTexture* auto renderMethod = mclass->FindMethod("Render", 4, true); if (renderMethod == nullptr) return; - RenderContextInternal tmp = ::ToManaged(renderContext); + RenderContextManaged tmp = ::ToManaged(renderContext); void* params[4]; params[0] = context->GetOrCreateManagedInstance(); params[1] = &tmp; @@ -286,7 +285,7 @@ void AddActorToSceneRendering(SceneRendering* s, Actor* a) } } -void SceneRenderTask::OnCollectDrawCalls(RenderContext& renderContext) +void SceneRenderTask::OnCollectDrawCalls(RenderContext& renderContext, byte category) { // Draw actors (collect draw calls) if ((ActorsSource & ActorsSources::CustomActors) != 0) @@ -297,11 +296,11 @@ void SceneRenderTask::OnCollectDrawCalls(RenderContext& renderContext) _customActorsScene->Clear(); for (Actor* a : CustomActors) AddActorToSceneRendering(_customActorsScene, a); - _customActorsScene->Draw(renderContext); + _customActorsScene->Draw(renderContext, (SceneRendering::DrawCategory)category); } if ((ActorsSource & ActorsSources::Scenes) != 0) { - Level::DrawActors(renderContext); + Level::DrawActors(renderContext, category); } // External drawing event @@ -311,10 +310,18 @@ void SceneRenderTask::OnCollectDrawCalls(RenderContext& renderContext) void SceneRenderTask::OnPreRender(GPUContext* context, RenderContext& renderContext) { PreRender(context, renderContext); + + // Collect initial draw calls + renderContext.View.Pass = DrawPass::GBuffer; + OnCollectDrawCalls(renderContext, SceneRendering::PreRender); } void SceneRenderTask::OnPostRender(GPUContext* context, RenderContext& renderContext) { + // Collect final draw calls + renderContext.View.Pass = DrawPass::GBuffer; + OnCollectDrawCalls(renderContext, SceneRendering::PostRender); + PostRender(context, renderContext); } @@ -474,6 +481,6 @@ void MainRenderTask::OnBegin(GPUContext* context) RenderContext::RenderContext(SceneRenderTask* task) { Buffers = task->Buffers; - View = task->View; Task = task; + View = task->View; } diff --git a/Source/Engine/Graphics/RenderTask.h b/Source/Engine/Graphics/RenderTask.h index 71c122ffd..0c25aca05 100644 --- a/Source/Engine/Graphics/RenderTask.h +++ b/Source/Engine/Graphics/RenderTask.h @@ -311,7 +311,8 @@ public: /// Calls drawing scene objects. /// /// The rendering context. - virtual void OnCollectDrawCalls(RenderContext& renderContext); + /// The actors category to draw (see SceneRendering::DrawCategory). + virtual void OnCollectDrawCalls(RenderContext& renderContext, byte category = 0); /// /// The action called after scene rendering. Can be used to perform custom pre-rendering or to modify the render view. @@ -394,7 +395,7 @@ public: /// /// The high-level renderer context. Used to collect the draw calls for the scene rendering. Can be used to perform a custom rendering. /// -API_STRUCT() struct RenderContext +API_STRUCT(NoDefault) struct RenderContext { DECLARE_SCRIPTING_TYPE_MINIMAL(RenderContext); @@ -409,9 +410,9 @@ API_STRUCT() struct RenderContext API_FIELD() RenderList* List = nullptr; /// - /// The render view. + /// The scene rendering task that is a source of renderable objects (optional). /// - API_FIELD() RenderView View; + API_FIELD() SceneRenderTask* Task = nullptr; /// /// The proxy render view used to synchronize objects level of detail during rendering (eg. during shadow maps rendering passes). It's optional. @@ -419,9 +420,9 @@ API_STRUCT() struct RenderContext API_FIELD() RenderView* LodProxyView = nullptr; /// - /// The scene rendering task that is a source of renderable objects (optional). + /// The render view. /// - API_FIELD() SceneRenderTask* Task = nullptr; + API_FIELD() RenderView View; RenderContext() { diff --git a/Source/Engine/Graphics/RenderView.h b/Source/Engine/Graphics/RenderView.h index 4cb453f8b..bd7a7f331 100644 --- a/Source/Engine/Graphics/RenderView.h +++ b/Source/Engine/Graphics/RenderView.h @@ -19,7 +19,7 @@ class SceneRenderTask; /// /// Rendering view description that defines how to render the objects (camera placement, rendering properties, etc.). /// -API_STRUCT() struct FLAXENGINE_API RenderView +API_STRUCT(NoDefault) struct FLAXENGINE_API RenderView { DECLARE_SCRIPTING_TYPE_MINIMAL(RenderView); diff --git a/Source/Engine/Level/Actors/Decal.cpp b/Source/Engine/Level/Actors/Decal.cpp index 998e2bfad..ab10c8ed0 100644 --- a/Source/Engine/Level/Actors/Decal.cpp +++ b/Source/Engine/Level/Actors/Decal.cpp @@ -63,7 +63,7 @@ BoundingBox Decal::GetEditorBox() const void Decal::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender); } void Decal::Draw(RenderContext& renderContext) @@ -118,7 +118,7 @@ bool Decal::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) void Decal::OnEnable() { - GetSceneRendering()->AddActor(this, _sceneRenderingKey); + GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -132,7 +132,7 @@ void Decal::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender); // Base Actor::OnDisable(); @@ -148,5 +148,5 @@ void Decal::OnTransformChanged() BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender); } diff --git a/Source/Engine/Level/Actors/DirectionalLight.cpp b/Source/Engine/Level/Actors/DirectionalLight.cpp index 621a0faf0..38c438d4f 100644 --- a/Source/Engine/Level/Actors/DirectionalLight.cpp +++ b/Source/Engine/Level/Actors/DirectionalLight.cpp @@ -73,7 +73,7 @@ bool DirectionalLight::IntersectsItself(const Ray& ray, Real& distance, Vector3& void DirectionalLight::OnEnable() { - GetSceneRendering()->AddActor(this, _sceneRenderingKey); + GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -87,7 +87,7 @@ void DirectionalLight::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender); // Base LightWithShadow::OnDisable(); diff --git a/Source/Engine/Level/Actors/EnvironmentProbe.cpp b/Source/Engine/Level/Actors/EnvironmentProbe.cpp index 0cf876c67..9bde5e6c6 100644 --- a/Source/Engine/Level/Actors/EnvironmentProbe.cpp +++ b/Source/Engine/Level/Actors/EnvironmentProbe.cpp @@ -170,7 +170,7 @@ void EnvironmentProbe::UpdateBounds() _sphere = BoundingSphere(GetPosition(), GetScaledRadius()); BoundingBox::FromSphere(_sphere, _box); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender); } void EnvironmentProbe::Draw(RenderContext& renderContext) @@ -206,7 +206,7 @@ void EnvironmentProbe::OnDebugDrawSelected() void EnvironmentProbe::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender); } void EnvironmentProbe::Serialize(SerializeStream& stream, const void* otherObj) @@ -259,7 +259,7 @@ bool EnvironmentProbe::IntersectsItself(const Ray& ray, Real& distance, Vector3& void EnvironmentProbe::OnEnable() { - GetSceneRendering()->AddActor(this, _sceneRenderingKey); + GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -273,7 +273,7 @@ void EnvironmentProbe::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender); // Base Actor::OnDisable(); diff --git a/Source/Engine/Level/Actors/ExponentialHeightFog.cpp b/Source/Engine/Level/Actors/ExponentialHeightFog.cpp index d2b2b6952..6bd8bf00b 100644 --- a/Source/Engine/Level/Actors/ExponentialHeightFog.cpp +++ b/Source/Engine/Level/Actors/ExponentialHeightFog.cpp @@ -209,7 +209,7 @@ void ExponentialHeightFog::DrawFog(GPUContext* context, RenderContext& renderCon void ExponentialHeightFog::OnEnable() { - GetSceneRendering()->AddActor(this, _sceneRenderingKey); + GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -223,7 +223,7 @@ void ExponentialHeightFog::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender); // Base Actor::OnDisable(); diff --git a/Source/Engine/Level/Actors/PointLight.cpp b/Source/Engine/Level/Actors/PointLight.cpp index a995a71f5..720a36a71 100644 --- a/Source/Engine/Level/Actors/PointLight.cpp +++ b/Source/Engine/Level/Actors/PointLight.cpp @@ -66,12 +66,12 @@ void PointLight::UpdateBounds() BoundingBox::FromSphere(_sphere, _box); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender); } void PointLight::OnEnable() { - GetSceneRendering()->AddActor(this, _sceneRenderingKey); + GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -85,7 +85,7 @@ void PointLight::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender); // Base LightWithShadow::OnDisable(); @@ -170,7 +170,7 @@ void PointLight::OnDebugDrawSelected() void PointLight::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender); } void PointLight::Serialize(SerializeStream& stream, const void* otherObj) diff --git a/Source/Engine/Level/Actors/Sky.cpp b/Source/Engine/Level/Actors/Sky.cpp index d9c6558ae..024075dda 100644 --- a/Source/Engine/Level/Actors/Sky.cpp +++ b/Source/Engine/Level/Actors/Sky.cpp @@ -248,7 +248,7 @@ void Sky::EndPlay() void Sky::OnEnable() { - GetSceneRendering()->AddActor(this, _sceneRenderingKey); + GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -262,7 +262,7 @@ void Sky::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender); // Base Actor::OnDisable(); diff --git a/Source/Engine/Level/Actors/SkyLight.cpp b/Source/Engine/Level/Actors/SkyLight.cpp index 16ee6576e..acfbe5df8 100644 --- a/Source/Engine/Level/Actors/SkyLight.cpp +++ b/Source/Engine/Level/Actors/SkyLight.cpp @@ -181,7 +181,7 @@ bool SkyLight::HasContentLoaded() const void SkyLight::OnEnable() { - GetSceneRendering()->AddActor(this, _sceneRenderingKey); + GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -195,7 +195,7 @@ void SkyLight::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender); // Base Light::OnDisable(); diff --git a/Source/Engine/Level/Actors/Skybox.cpp b/Source/Engine/Level/Actors/Skybox.cpp index 958c9ee53..f3d022609 100644 --- a/Source/Engine/Level/Actors/Skybox.cpp +++ b/Source/Engine/Level/Actors/Skybox.cpp @@ -127,7 +127,7 @@ void Skybox::ApplySky(GPUContext* context, RenderContext& renderContext, const M void Skybox::OnEnable() { - GetSceneRendering()->AddActor(this, _sceneRenderingKey); + GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -141,7 +141,7 @@ void Skybox::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender); // Base Actor::OnDisable(); diff --git a/Source/Engine/Level/Actors/SpotLight.cpp b/Source/Engine/Level/Actors/SpotLight.cpp index 344c25542..d65bbcbe8 100644 --- a/Source/Engine/Level/Actors/SpotLight.cpp +++ b/Source/Engine/Level/Actors/SpotLight.cpp @@ -114,12 +114,12 @@ void SpotLight::UpdateBounds() BoundingBox::FromSphere(_sphere, _box); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender); } void SpotLight::OnEnable() { - GetSceneRendering()->AddActor(this, _sceneRenderingKey); + GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -133,7 +133,7 @@ void SpotLight::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender); // Base LightWithShadow::OnDisable(); diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp index 7f78c1561..745f753bf 100644 --- a/Source/Engine/Level/Level.cpp +++ b/Source/Engine/Level/Level.cpp @@ -389,7 +389,7 @@ void Level::CallBeginPlay(Actor* obj) } } -void Level::DrawActors(RenderContext& renderContext) +void Level::DrawActors(RenderContext& renderContext, byte category) { PROFILE_CPU(); @@ -398,7 +398,7 @@ void Level::DrawActors(RenderContext& renderContext) for (Scene* scene : Scenes) { if (scene->IsActiveInHierarchy()) - scene->Rendering.Draw(renderContext); + scene->Rendering.Draw(renderContext, (SceneRendering::DrawCategory)category); } } diff --git a/Source/Engine/Level/Level.h b/Source/Engine/Level/Level.h index 5fc4c909b..561d07150 100644 --- a/Source/Engine/Level/Level.h +++ b/Source/Engine/Level/Level.h @@ -164,7 +164,8 @@ public: /// Draws all the actors. /// /// The rendering context. - static void DrawActors(RenderContext& renderContext); + /// The actors category to draw (see SceneRendering::DrawCategory). + static void DrawActors(RenderContext& renderContext, byte category = 0); /// /// Collects all the post fx volumes. diff --git a/Source/Engine/Level/Scene/SceneRendering.cpp b/Source/Engine/Level/Scene/SceneRendering.cpp index 111a30f65..830375753 100644 --- a/Source/Engine/Level/Scene/SceneRendering.cpp +++ b/Source/Engine/Level/Scene/SceneRendering.cpp @@ -28,20 +28,21 @@ void ISceneRenderingListener::ListenSceneRendering(SceneRendering* scene) } } -void SceneRendering::Draw(RenderContext& renderContext) +void SceneRendering::Draw(RenderContext& renderContext, DrawCategory category) { ScopeLock lock(Locker); auto& view = renderContext.View; const BoundingFrustum frustum = view.CullingFrustum; const Vector3 origin = view.Origin; renderContext.List->Scenes.Add(this); + auto& list = Actors[(int32)category]; // Draw all visual components if (view.IsOfflinePass) { - for (int32 i = 0; i < Actors.Count(); i++) + for (int32 i = 0; i < list.Count(); i++) { - auto e = Actors.Get()[i]; + auto e = list.Get()[i]; e.Bounds.Center -= origin; if (view.RenderLayersMask.Mask & e.LayerMask && (e.NoCulling || frustum.Intersects(e.Bounds)) && e.Actor->GetStaticFlags() & view.StaticFlagsMask) { @@ -54,9 +55,9 @@ void SceneRendering::Draw(RenderContext& renderContext) } else if (origin.IsZero()) { - for (int32 i = 0; i < Actors.Count(); i++) + for (int32 i = 0; i < list.Count(); i++) { - auto e = Actors.Get()[i]; + auto e = list.Get()[i]; if (view.RenderLayersMask.Mask & e.LayerMask && (e.NoCulling || frustum.Intersects(e.Bounds))) { #if SCENE_RENDERING_USE_PROFILER @@ -68,9 +69,9 @@ void SceneRendering::Draw(RenderContext& renderContext) } else { - for (int32 i = 0; i < Actors.Count(); i++) + for (int32 i = 0; i < list.Count(); i++) { - auto e = Actors.Get()[i]; + auto e = list.Get()[i]; e.Bounds.Center -= origin; if (view.RenderLayersMask.Mask & e.LayerMask && (e.NoCulling || frustum.Intersects(e.Bounds))) { @@ -82,7 +83,7 @@ void SceneRendering::Draw(RenderContext& renderContext) } } #if USE_EDITOR - if (view.Pass & DrawPass::GBuffer) + if (view.Pass & DrawPass::GBuffer && category == SceneDraw) { // Draw physics shapes if (view.Flags & ViewFlags::PhysicsDebug || view.Mode == ViewMode::PhysicsColliders) @@ -116,42 +117,44 @@ void SceneRendering::Clear() listener->_scenes.Remove(this); } _listeners.Clear(); - Actors.Clear(); + for (auto& e : Actors) + e.Clear(); #if USE_EDITOR PhysicsDebug.Clear(); #endif } -void SceneRendering::AddActor(Actor* a, int32& key) +void SceneRendering::AddActor(Actor* a, int32& key, DrawCategory category) { + if (key != -1) + return; ScopeLock lock(Locker); - if (key == -1) + auto& list = Actors[(int32)category]; + // TODO: track removedCount and skip searching for free entry if there is none + key = 0; + for (; key < list.Count(); key++) { - // TODO: track removedCount and skip searching for free entry if there is none - key = 0; - for (; key < Actors.Count(); key++) - { - if (Actors[key].Actor == nullptr) - break; - } - if (key == Actors.Count()) - Actors.AddOne(); - auto& e = Actors[key]; - e.Actor = a; - e.LayerMask = a->GetLayerMask(); - e.Bounds = a->GetSphere(); - e.NoCulling = a->_drawNoCulling; - for (auto* listener : _listeners) - listener->OnSceneRenderingAddActor(a); + if (list[key].Actor == nullptr) + break; } + if (key == list.Count()) + list.AddOne(); + auto& e = list[key]; + e.Actor = a; + e.LayerMask = a->GetLayerMask(); + e.Bounds = a->GetSphere(); + e.NoCulling = a->_drawNoCulling; + for (auto* listener : _listeners) + listener->OnSceneRenderingAddActor(a); } -void SceneRendering::UpdateActor(Actor* a, int32 key) +void SceneRendering::UpdateActor(Actor* a, int32 key, DrawCategory category) { ScopeLock lock(Locker); - if (Actors.IsEmpty()) + auto& list = Actors[(int32)category]; + if (list.IsEmpty()) return; - auto& e = Actors[key]; + auto& e = list[key]; ASSERT_LOW_LAYER(a == e.Actor); for (auto* listener : _listeners) listener->OnSceneRenderingUpdateActor(a, e.Bounds); @@ -159,12 +162,13 @@ void SceneRendering::UpdateActor(Actor* a, int32 key) e.Bounds = a->GetSphere(); } -void SceneRendering::RemoveActor(Actor* a, int32& key) +void SceneRendering::RemoveActor(Actor* a, int32& key, DrawCategory category) { ScopeLock lock(Locker); - if (Actors.HasItems()) + auto& list = Actors[(int32)category]; + if (list.HasItems()) { - auto& e = Actors[key]; + auto& e = list[key]; ASSERT_LOW_LAYER(a == e.Actor); for (auto* listener : _listeners) listener->OnSceneRenderingRemoveActor(a); diff --git a/Source/Engine/Level/Scene/SceneRendering.h b/Source/Engine/Level/Scene/SceneRendering.h index 9faa8d6f5..ffa22c5c3 100644 --- a/Source/Engine/Level/Scene/SceneRendering.h +++ b/Source/Engine/Level/Scene/SceneRendering.h @@ -74,7 +74,18 @@ public: BoundingSphere Bounds; }; - Array Actors; + /// + /// Drawing categories for separate draw stages. + /// + enum DrawCategory + { + SceneDraw = 0, + PreRender, + PostRender, + MAX + }; + + Array Actors[MAX]; Array PostFxProviders; CriticalSection Locker; @@ -93,7 +104,8 @@ public: /// Draws the scene. Performs the optimized actors culling and draw calls submission for the current render pass (defined by the render view). /// /// The rendering context. - void Draw(RenderContext& renderContext); + /// The actors category to draw. + void Draw(RenderContext& renderContext, DrawCategory category = DrawCategory::SceneDraw); /// /// Collects the post fx volumes for the given rendering view. @@ -107,9 +119,9 @@ public: void Clear(); public: - void AddActor(Actor* a, int32& key); - void UpdateActor(Actor* a, int32 key); - void RemoveActor(Actor* a, int32& key); + void AddActor(Actor* a, int32& key, DrawCategory category = SceneDraw); + void UpdateActor(Actor* a, int32 key, DrawCategory category = SceneDraw); + void RemoveActor(Actor* a, int32& key, DrawCategory category = SceneDraw); FORCE_INLINE void AddPostFxProvider(IPostFxSettingsProvider* obj) { diff --git a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp index ecd35ba4c..9b541509c 100644 --- a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp +++ b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp @@ -483,7 +483,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co _cullingPosDistance = Vector4(viewPosition, distance); for (auto* scene : renderContext.List->Scenes) { - for (auto& e : scene->Actors) + auto& list = scene->Actors[SceneRendering::SceneDraw]; + for (auto& e : list) { if (viewMask & e.LayerMask && e.Bounds.Radius >= minObjectRadius && CollisionsHelper::DistanceSpherePoint(e.Bounds, viewPosition) < distance) { diff --git a/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp b/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp index 9f5377afd..2e3e8f205 100644 --- a/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp +++ b/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp @@ -542,7 +542,8 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex _cascadeCullingBounds = cascadeBoundsWorld; for (SceneRendering* scene : renderContext.List->Scenes) { - for (const auto& e : scene->Actors) + auto& list = scene->Actors[SceneRendering::SceneDraw]; + for (const auto& e : list) { if (viewMask & e.LayerMask && e.Bounds.Radius >= minObjectRadius && CollisionsHelper::BoxIntersectsSphere(cascadeBoundsWorld, e.Bounds)) { diff --git a/Source/Engine/Renderer/Renderer.cpp b/Source/Engine/Renderer/Renderer.cpp index e0055f19b..30ff7675a 100644 --- a/Source/Engine/Renderer/Renderer.cpp +++ b/Source/Engine/Renderer/Renderer.cpp @@ -122,7 +122,8 @@ void RendererService::Dispose() void RenderAntiAliasingPass(RenderContext& renderContext, GPUTexture* input, GPUTextureView* output) { auto context = GPUDevice::Instance->GetMainContext(); - context->SetViewportAndScissors(renderContext.View.ScreenSize.X, renderContext.View.ScreenSize.Y); + auto screenSize = renderContext.View.ScreenSize; + context->SetViewportAndScissors(screenSize.X, screenSize.Y); const auto aaMode = renderContext.List->Settings.AntiAliasing.Mode; if (aaMode == AntialiasingMode::FastApproximateAntialiasing) @@ -165,10 +166,8 @@ void Renderer::Render(SceneRenderTask* task) PROFILE_GPU_CPU_NAMED("Render Frame"); auto context = GPUDevice::Instance->GetMainContext(); - context->ClearState(); context->FlushState(); - const Viewport viewport = task->GetViewport(); context->SetViewportAndScissors(viewport); diff --git a/Source/Engine/Renderer/ScreenSpaceReflectionsPass.cpp b/Source/Engine/Renderer/ScreenSpaceReflectionsPass.cpp index 543320fd4..4d192a8a0 100644 --- a/Source/Engine/Renderer/ScreenSpaceReflectionsPass.cpp +++ b/Source/Engine/Renderer/ScreenSpaceReflectionsPass.cpp @@ -161,8 +161,8 @@ void ScreenSpaceReflectionsPass::Render(RenderContext& renderContext, GPUTexture // Skip pass if resources aren't ready if (checkIfSkipPass()) return; - auto& view = renderContext.View; - auto buffers = renderContext.Buffers; + const RenderView& view = renderContext.View; + RenderBuffers* buffers = renderContext.Buffers; // TODO: add support for SSR in ortho projection if (view.IsOrthographicProjection()) @@ -275,7 +275,7 @@ void ScreenSpaceReflectionsPass::Render(RenderContext& renderContext, GPUTexture GlobalSignDistanceFieldPass::BindingData bindingDataSDF; GlobalSurfaceAtlasPass::BindingData bindingDataSurfaceAtlas; if (settings.TraceMode == ReflectionsTraceMode::SoftwareTracing && - renderContext.View.Flags & ViewFlags::GI && + view.Flags & ViewFlags::GI && renderContext.List->Settings.GlobalIllumination.Mode == GlobalIlluminationMode::DDGI) { if (!GlobalSignDistanceFieldPass::Instance()->Render(renderContext, context, bindingDataSDF) &&