From 3fe1e2c7631667bf5fb3b773916b81d3e4a1f6a4 Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Tue, 22 Feb 2022 17:06:19 +0100 Subject: [PATCH] Refactor SceneRendering to simplify actors impl of drawing flow at high level --- Source/Engine/Foliage/Foliage.cpp | 17 +- Source/Engine/Foliage/Foliage.h | 1 - Source/Engine/Graphics/RenderTask.cpp | 25 +- Source/Engine/Graphics/RenderTask.h | 4 + Source/Engine/Level/Actor.cpp | 40 +- Source/Engine/Level/Actor.h | 14 +- Source/Engine/Level/Actors/AnimatedModel.cpp | 12 +- Source/Engine/Level/Actors/AnimatedModel.h | 1 - Source/Engine/Level/Actors/Camera.cpp | 4 +- Source/Engine/Level/Actors/Camera.h | 1 + Source/Engine/Level/Actors/Decal.cpp | 9 +- .../Engine/Level/Actors/DirectionalLight.cpp | 5 +- Source/Engine/Level/Actors/DirectionalLight.h | 8 +- .../Engine/Level/Actors/EnvironmentProbe.cpp | 13 +- .../Level/Actors/ExponentialHeightFog.cpp | 6 +- .../Level/Actors/ExponentialHeightFog.h | 10 +- .../Level/Actors/ModelInstanceActor.cpp | 6 +- Source/Engine/Level/Actors/PointLight.cpp | 9 +- Source/Engine/Level/Actors/Sky.cpp | 6 +- Source/Engine/Level/Actors/Sky.h | 9 +- Source/Engine/Level/Actors/SkyLight.cpp | 5 +- Source/Engine/Level/Actors/SkyLight.h | 11 +- Source/Engine/Level/Actors/Skybox.cpp | 5 +- Source/Engine/Level/Actors/Skybox.h | 8 +- Source/Engine/Level/Actors/SplineModel.cpp | 7 +- Source/Engine/Level/Actors/SplineModel.h | 1 - Source/Engine/Level/Actors/SpotLight.cpp | 7 +- Source/Engine/Level/Actors/StaticModel.cpp | 10 +- Source/Engine/Level/Actors/StaticModel.h | 1 - Source/Engine/Level/Level.cpp | 10 +- Source/Engine/Level/Scene/Scene.cpp | 1 - Source/Engine/Level/Scene/SceneRendering.cpp | 401 +++--------------- Source/Engine/Level/Scene/SceneRendering.h | 76 +--- Source/Engine/Particles/ParticleEffect.cpp | 13 +- Source/Engine/Particles/ParticleEffect.h | 1 - Source/Engine/Renderer/RenderList.cpp | 1 + Source/Engine/Renderer/RenderList.h | 6 + Source/Engine/Terrain/Terrain.cpp | 13 +- Source/Engine/Terrain/Terrain.h | 1 - Source/Engine/UI/SpriteRender.cpp | 13 +- Source/Engine/UI/SpriteRender.h | 1 - Source/Engine/UI/TextRender.cpp | 15 +- Source/Engine/UI/TextRender.h | 1 - 43 files changed, 191 insertions(+), 617 deletions(-) diff --git a/Source/Engine/Foliage/Foliage.cpp b/Source/Engine/Foliage/Foliage.cpp index 5d86ba4d3..1d367c5ef 100644 --- a/Source/Engine/Foliage/Foliage.cpp +++ b/Source/Engine/Foliage/Foliage.cpp @@ -559,7 +559,7 @@ void Foliage::OnFoliageTypeModelLoaded(int32 index) } BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } { PROFILE_CPU_NAMED("Create Clusters"); @@ -606,7 +606,7 @@ void Foliage::RebuildClusters() _box = BoundingBox(_transform.Translation, _transform.Translation); _sphere = BoundingSphere(_transform.Translation, 0.0f); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); return; } @@ -696,7 +696,7 @@ void Foliage::RebuildClusters() _box = totalBounds; BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } // Insert all instances to the clusters @@ -1016,11 +1016,6 @@ void Foliage::Draw(RenderContext& renderContext) #endif } -void Foliage::DrawGeneric(RenderContext& renderContext) -{ - Draw(renderContext); -} - bool Foliage::IntersectsItself(const Ray& ray, float& distance, Vector3& normal) { int32 instanceIndex; @@ -1227,12 +1222,12 @@ void Foliage::Deserialize(DeserializeStream& stream, ISerializeModifier* modifie void Foliage::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void Foliage::OnEnable() { - _sceneRenderingKey = GetSceneRendering()->AddGeometry(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); // Base Actor::OnEnable(); @@ -1240,7 +1235,7 @@ void Foliage::OnEnable() void Foliage::OnDisable() { - GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Actor::OnDisable(); diff --git a/Source/Engine/Foliage/Foliage.h b/Source/Engine/Foliage/Foliage.h index e4f32529f..19e45fbeb 100644 --- a/Source/Engine/Foliage/Foliage.h +++ b/Source/Engine/Foliage/Foliage.h @@ -197,7 +197,6 @@ public: // [Actor] void Draw(RenderContext& renderContext) override; - void DrawGeneric(RenderContext& renderContext) override; bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override; void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; diff --git a/Source/Engine/Graphics/RenderTask.cpp b/Source/Engine/Graphics/RenderTask.cpp index 42e7f6805..23ac08591 100644 --- a/Source/Engine/Graphics/RenderTask.cpp +++ b/Source/Engine/Graphics/RenderTask.cpp @@ -229,6 +229,8 @@ SceneRenderTask::~SceneRenderTask() { if (Buffers) Buffers->DeleteObjectNow(); + if (_customActorsScene) + Delete(_customActorsScene); } void SceneRenderTask::CameraCut() @@ -270,18 +272,27 @@ void SceneRenderTask::CollectPostFxVolumes(RenderContext& renderContext) } } +void AddActorToSceneRendering(SceneRendering* s, Actor* a) +{ + if (a && a->IsActiveInHierarchy()) + { + s->AddActor(a); + for (Actor* child : a->Children) + AddActorToSceneRendering(s, child); + } +} + void SceneRenderTask::OnCollectDrawCalls(RenderContext& renderContext) { // Draw actors (collect draw calls) if ((ActorsSource & ActorsSources::CustomActors) != 0) { - for (auto a : CustomActors) - { - if (a && a->GetIsActive()) - { - a->DrawHierarchy(renderContext); - } - } + if (_customActorsScene == nullptr) + _customActorsScene = New(); + _customActorsScene->Clear(); + for (Actor* a : CustomActors) + AddActorToSceneRendering(_customActorsScene, a); + _customActorsScene->Draw(renderContext); } if ((ActorsSource & ActorsSources::Scenes) != 0) { diff --git a/Source/Engine/Graphics/RenderTask.h b/Source/Engine/Graphics/RenderTask.h index 741e9c7ed..0604ccdfc 100644 --- a/Source/Engine/Graphics/RenderTask.h +++ b/Source/Engine/Graphics/RenderTask.h @@ -220,6 +220,10 @@ public: API_CLASS() class FLAXENGINE_API SceneRenderTask : public RenderTask { DECLARE_SCRIPTING_TYPE(SceneRenderTask); +protected: + class SceneRendering* _customActorsScene = nullptr; + +public: /// /// Finalizes an instance of the class. diff --git a/Source/Engine/Level/Actor.cpp b/Source/Engine/Level/Actor.cpp index 4eff57a54..72c35da56 100644 --- a/Source/Engine/Level/Actor.cpp +++ b/Source/Engine/Level/Actor.cpp @@ -81,6 +81,7 @@ Actor::Actor(const SpawnParams& params) , _physicsScene(nullptr) , HideFlags(HideFlags::None) { + _drawNoCulling = 0; } SceneRendering* Actor::GetSceneRendering() const @@ -1221,45 +1222,6 @@ void Actor::Draw(RenderContext& renderContext) { } -void Actor::DrawGeneric(RenderContext& renderContext) -{ - // Generic drawing uses only GBuffer Fill Pass and simple frustum culling (see SceneRendering for more optimized drawing) - if (renderContext.View.Pass & DrawPass::GBuffer) - { - Draw(renderContext); - } -} - -void Actor::DrawHierarchy(RenderContext& renderContext) -{ - // Draw actor itself - DrawGeneric(renderContext); - - // Draw children - if (renderContext.View.IsOfflinePass) - { - for (int32 i = 0; i < Children.Count(); i++) - { - auto child = Children[i]; - if (child->GetIsActive() && child->GetStaticFlags() & renderContext.View.StaticFlagsMask) - { - child->DrawHierarchy(renderContext); - } - } - } - else - { - for (int32 i = 0; i < Children.Count(); i++) - { - auto child = Children[i]; - if (child->GetIsActive()) - { - child->DrawHierarchy(renderContext); - } - } - } -} - #if USE_EDITOR void Actor::OnDebugDraw() diff --git a/Source/Engine/Level/Actor.h b/Source/Engine/Level/Actor.h index 474694e99..8d580fdde 100644 --- a/Source/Engine/Level/Actor.h +++ b/Source/Engine/Level/Actor.h @@ -30,6 +30,7 @@ DECLARE_SCENE_OBJECT(Actor); friend Level; friend PrefabManager; friend Scene; + friend SceneRendering; friend Prefab; friend PrefabInstanceData; @@ -39,6 +40,7 @@ protected: int8 _isActiveInHierarchy : 1; int8 _isPrefabRoot : 1; int8 _isEnabled : 1; + int8 _drawNoCulling : 1; byte _layer; byte _tag; Scene* _scene; @@ -645,18 +647,6 @@ public: /// The rendering context. virtual void Draw(RenderContext& renderContext); - /// - /// Draws this actor. Called during custom actor rendering or any other generic rendering from code. - /// - /// The rendering context. - virtual void DrawGeneric(RenderContext& renderContext); - - /// - /// Draws this actor and all its children (full scene hierarchy part). - /// - /// The rendering context. - void DrawHierarchy(RenderContext& renderContext); - #if USE_EDITOR /// diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index 0e59f36c0..c6a770de7 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -545,7 +545,7 @@ void AnimatedModel::UpdateBounds() BoundingBox::Transform(_boxLocal, _world, _box); BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void AnimatedModel::UpdateSockets() @@ -725,14 +725,6 @@ void AnimatedModel::Draw(RenderContext& renderContext) GEOMETRY_DRAW_STATE_EVENT_END(_drawState, _world); } -void AnimatedModel::DrawGeneric(RenderContext& renderContext) -{ - if (renderContext.View.RenderLayersMask.Mask & GetLayerMask() && renderContext.View.CullingFrustum.Intersects(_box)) - { - Draw(renderContext); - } -} - #if USE_EDITOR #include "Engine/Debug/DebugDraw.h" @@ -878,5 +870,5 @@ void AnimatedModel::OnTransformChanged() BoundingBox::Transform(_boxLocal, _world, _box); BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h index 556a1d1cf..087099a84 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.h +++ b/Source/Engine/Level/Actors/AnimatedModel.h @@ -375,7 +375,6 @@ public: // [ModelInstanceActor] bool HasContentLoaded() const override; void Draw(RenderContext& renderContext) override; - void DrawGeneric(RenderContext& renderContext) override; #if USE_EDITOR void OnDebugDrawSelected() override; BoundingBox GetEditorBox() const override; diff --git a/Source/Engine/Level/Actors/Camera.cpp b/Source/Engine/Level/Actors/Camera.cpp index ab736c673..76cb7d667 100644 --- a/Source/Engine/Level/Actors/Camera.cpp +++ b/Source/Engine/Level/Actors/Camera.cpp @@ -354,7 +354,7 @@ void Camera::OnEnable() { Cameras.Add(this); #if USE_EDITOR - GetSceneRendering()->AddCommonNoCulling(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #endif // Base @@ -364,7 +364,7 @@ void Camera::OnEnable() void Camera::OnDisable() { #if USE_EDITOR - GetSceneRendering()->RemoveCommonNoCulling(this); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); #endif Cameras.Remove(this); if (CutSceneCamera == this) diff --git a/Source/Engine/Level/Actors/Camera.h b/Source/Engine/Level/Actors/Camera.h index 938fe1bdc..35d2df94d 100644 --- a/Source/Engine/Level/Actors/Camera.h +++ b/Source/Engine/Level/Actors/Camera.h @@ -52,6 +52,7 @@ private: ModelInstanceEntries _previewModelBuffer; BoundingBox _previewModelBox; Matrix _previewModelWorld; + int32 _sceneRenderingKey = -1; #endif public: diff --git a/Source/Engine/Level/Actors/Decal.cpp b/Source/Engine/Level/Actors/Decal.cpp index a55f51c85..ebf9f7361 100644 --- a/Source/Engine/Level/Actors/Decal.cpp +++ b/Source/Engine/Level/Actors/Decal.cpp @@ -69,12 +69,13 @@ BoundingBox Decal::GetEditorBox() const void Decal::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void Decal::Draw(RenderContext& renderContext) { if ((renderContext.View.Flags & ViewFlags::Decals) != 0 && + renderContext.View.Pass & DrawPass::GBuffer && Material && Material->IsLoaded() && Material->IsDecal()) @@ -121,7 +122,7 @@ bool Decal::IntersectsItself(const Ray& ray, float& distance, Vector3& normal) void Decal::OnEnable() { - _sceneRenderingKey = GetSceneRendering()->AddCommon(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -135,7 +136,7 @@ void Decal::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveCommon(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Actor::OnDisable(); @@ -156,5 +157,5 @@ void Decal::OnTransformChanged() BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } diff --git a/Source/Engine/Level/Actors/DirectionalLight.cpp b/Source/Engine/Level/Actors/DirectionalLight.cpp index 854b36aac..e8bcfbba4 100644 --- a/Source/Engine/Level/Actors/DirectionalLight.cpp +++ b/Source/Engine/Level/Actors/DirectionalLight.cpp @@ -10,6 +10,7 @@ DirectionalLight::DirectionalLight(const SpawnParams& params) : LightWithShadow(params) { + _drawNoCulling = 1; Brightness = 8.0f; } @@ -67,7 +68,7 @@ bool DirectionalLight::IntersectsItself(const Ray& ray, float& distance, Vector3 void DirectionalLight::OnEnable() { - GetSceneRendering()->AddCommonNoCulling(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -81,7 +82,7 @@ void DirectionalLight::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveCommonNoCulling(this); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base LightWithShadow::OnDisable(); diff --git a/Source/Engine/Level/Actors/DirectionalLight.h b/Source/Engine/Level/Actors/DirectionalLight.h index ab6330953..ae966559e 100644 --- a/Source/Engine/Level/Actors/DirectionalLight.h +++ b/Source/Engine/Level/Actors/DirectionalLight.h @@ -9,9 +9,11 @@ /// API_CLASS() class FLAXENGINE_API DirectionalLight : public LightWithShadow { -DECLARE_SCENE_OBJECT(DirectionalLight); -public: + DECLARE_SCENE_OBJECT(DirectionalLight); +private: + int32 _sceneRenderingKey = -1; +public: /// /// The number of cascades used for slicing the range of depth covered by the light. Values are 1, 2 or 4 cascades; a typical scene uses 4 cascades. /// @@ -19,7 +21,6 @@ public: int32 CascadeCount = 4; public: - // [LightWithShadow] void Draw(RenderContext& renderContext) override; void Serialize(SerializeStream& stream, const void* otherObj) override; @@ -27,7 +28,6 @@ public: bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override; protected: - // [LightWithShadow] void OnEnable() override; void OnDisable() override; diff --git a/Source/Engine/Level/Actors/EnvironmentProbe.cpp b/Source/Engine/Level/Actors/EnvironmentProbe.cpp index 9778836eb..6ad0c6091 100644 --- a/Source/Engine/Level/Actors/EnvironmentProbe.cpp +++ b/Source/Engine/Level/Actors/EnvironmentProbe.cpp @@ -127,12 +127,15 @@ void EnvironmentProbe::UpdateBounds() _sphere = BoundingSphere(GetPosition(), GetScaledRadius()); BoundingBox::FromSphere(_sphere, _box); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void EnvironmentProbe::Draw(RenderContext& renderContext) { - if (Brightness > ZeroTolerance && (renderContext.View.Flags & ViewFlags::Reflections) != 0 && HasProbeLoaded()) + if (Brightness > ZeroTolerance && + (renderContext.View.Flags & ViewFlags::Reflections) != 0 && + renderContext.View.Pass & DrawPass::GBuffer && + HasProbeLoaded()) { renderContext.List->EnvironmentProbes.Add(this); } @@ -156,7 +159,7 @@ void EnvironmentProbe::OnDebugDrawSelected() void EnvironmentProbe::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void EnvironmentProbe::Serialize(SerializeStream& stream, const void* otherObj) @@ -199,7 +202,7 @@ bool EnvironmentProbe::IntersectsItself(const Ray& ray, float& distance, Vector3 void EnvironmentProbe::OnEnable() { - _sceneRenderingKey = GetSceneRendering()->AddCommon(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -213,7 +216,7 @@ void EnvironmentProbe::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveCommon(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Actor::OnDisable(); diff --git a/Source/Engine/Level/Actors/ExponentialHeightFog.cpp b/Source/Engine/Level/Actors/ExponentialHeightFog.cpp index 34d1dd255..5521b888d 100644 --- a/Source/Engine/Level/Actors/ExponentialHeightFog.cpp +++ b/Source/Engine/Level/Actors/ExponentialHeightFog.cpp @@ -16,6 +16,8 @@ ExponentialHeightFog::ExponentialHeightFog(const SpawnParams& params) : Actor(params) { + _drawNoCulling = 1; + // Load shader _shader = Content::LoadAsyncInternal(TEXT("Shaders/Fog")); if (_shader == nullptr) @@ -203,7 +205,7 @@ void ExponentialHeightFog::DrawFog(GPUContext* context, RenderContext& renderCon void ExponentialHeightFog::OnEnable() { - GetSceneRendering()->AddCommonNoCulling(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -217,7 +219,7 @@ void ExponentialHeightFog::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveCommonNoCulling(this); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Actor::OnDisable(); diff --git a/Source/Engine/Level/Actors/ExponentialHeightFog.h b/Source/Engine/Level/Actors/ExponentialHeightFog.h index dc205ce62..302fd07b3 100644 --- a/Source/Engine/Level/Actors/ExponentialHeightFog.h +++ b/Source/Engine/Level/Actors/ExponentialHeightFog.h @@ -14,14 +14,13 @@ /// API_CLASS() class FLAXENGINE_API ExponentialHeightFog : public Actor, public IFogRenderer { -DECLARE_SCENE_OBJECT(ExponentialHeightFog); + DECLARE_SCENE_OBJECT(ExponentialHeightFog); private: - AssetReference _shader; GPUPipelineStatePermutationsPs<2> _psFog; + int32 _sceneRenderingKey = -1; public: - /// /// The fog density factor. /// @@ -61,7 +60,6 @@ public: float FogCutoffDistance = 0.0f; public: - /// /// Directional light used for Directional Inscattering. /// @@ -90,7 +88,6 @@ public: Color DirectionalInscatteringColor = Color(0.25, 0.25f, 0.125f); public: - /// /// Whether to enable Volumetric fog. Graphics quality settings control the resolution of the fog simulation. /// @@ -133,7 +130,6 @@ public: float VolumetricFogDistance = 6000.0f; private: - #if COMPILE_WITH_DEV_ENV void OnShaderReloading(Asset* obj) { @@ -142,7 +138,6 @@ private: #endif public: - // [Actor] #if USE_EDITOR BoundingBox GetEditorBox() const override @@ -163,7 +158,6 @@ public: void DrawFog(GPUContext* context, RenderContext& renderContext, GPUTextureView* output) override; protected: - // [Actor] void OnEnable() override; void OnDisable() override; diff --git a/Source/Engine/Level/Actors/ModelInstanceActor.cpp b/Source/Engine/Level/Actors/ModelInstanceActor.cpp index 69e78fd6a..e71d66f05 100644 --- a/Source/Engine/Level/Actors/ModelInstanceActor.cpp +++ b/Source/Engine/Level/Actors/ModelInstanceActor.cpp @@ -34,12 +34,12 @@ MaterialInstance* ModelInstanceActor::CreateAndSetVirtualMaterialInstance(int32 void ModelInstanceActor::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void ModelInstanceActor::OnEnable() { - _sceneRenderingKey = GetSceneRendering()->AddGeometry(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); // Base Actor::OnEnable(); @@ -47,7 +47,7 @@ void ModelInstanceActor::OnEnable() void ModelInstanceActor::OnDisable() { - GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Actor::OnDisable(); diff --git a/Source/Engine/Level/Actors/PointLight.cpp b/Source/Engine/Level/Actors/PointLight.cpp index 36aa08805..9c827a877 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()->UpdateCommon(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void PointLight::OnEnable() { - _sceneRenderingKey = GetSceneRendering()->AddCommon(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -85,7 +85,7 @@ void PointLight::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveCommon(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base LightWithShadow::OnDisable(); @@ -106,6 +106,7 @@ void PointLight::Draw(RenderContext& renderContext) const float radius = GetScaledRadius(); if ((renderContext.View.Flags & ViewFlags::PointLights) != 0 && brightness > ZeroTolerance + && renderContext.View.Pass & DrawPass::GBuffer && radius > ZeroTolerance && (ViewDistance < ZeroTolerance || Vector3::DistanceSquared(renderContext.View.Position, GetPosition()) < ViewDistance * ViewDistance)) { @@ -165,7 +166,7 @@ void PointLight::OnDebugDrawSelected() void PointLight::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } 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 046602010..c5107ae0c 100644 --- a/Source/Engine/Level/Actors/Sky.cpp +++ b/Source/Engine/Level/Actors/Sky.cpp @@ -29,6 +29,8 @@ Sky::Sky(const SpawnParams& params) , _psSky(nullptr) , _psFog(nullptr) { + _drawNoCulling = 1; + // Load shader _shader = Content::LoadAsyncInternal(TEXT("Shaders/Sky")); if (_shader == nullptr) @@ -237,7 +239,7 @@ void Sky::EndPlay() void Sky::OnEnable() { - GetSceneRendering()->AddCommonNoCulling(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -251,7 +253,7 @@ void Sky::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveCommonNoCulling(this); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Actor::OnDisable(); diff --git a/Source/Engine/Level/Actors/Sky.h b/Source/Engine/Level/Actors/Sky.h index 57c2fd42a..5f2f78a2f 100644 --- a/Source/Engine/Level/Actors/Sky.h +++ b/Source/Engine/Level/Actors/Sky.h @@ -16,19 +16,17 @@ class GPUPipelineState; /// API_CLASS() class FLAXENGINE_API Sky : public Actor, public IAtmosphericFogRenderer, public ISkyRenderer { -DECLARE_SCENE_OBJECT(Sky); + DECLARE_SCENE_OBJECT(Sky); private: - AssetReference _shader; GPUPipelineState* _psSky; GPUPipelineState* _psFog; + int32 _sceneRenderingKey = -1; public: - ~Sky(); public: - /// /// Directional light that is used to simulate the sun. /// @@ -48,7 +46,6 @@ public: float SunPower = 8.0f; private: - #if COMPILE_WITH_DEV_ENV void OnShaderReloading(Asset* obj) { @@ -59,7 +56,6 @@ private: void InitConfig(AtmosphericFogData& config) const; public: - // [Actor] #if USE_EDITOR BoundingBox GetEditorBox() const override @@ -81,7 +77,6 @@ public: void ApplySky(GPUContext* context, RenderContext& renderContext, const Matrix& world) override; protected: - // [Actor] void EndPlay() override; void OnEnable() override; diff --git a/Source/Engine/Level/Actors/SkyLight.cpp b/Source/Engine/Level/Actors/SkyLight.cpp index 2fd4d226b..a5d4fb0a3 100644 --- a/Source/Engine/Level/Actors/SkyLight.cpp +++ b/Source/Engine/Level/Actors/SkyLight.cpp @@ -17,6 +17,7 @@ SkyLight::SkyLight(const SpawnParams& params) : Light(params) , _radius(1000000.0f) { + _drawNoCulling = 1; Brightness = 2.0f; UpdateBounds(); } @@ -170,7 +171,7 @@ bool SkyLight::HasContentLoaded() const void SkyLight::OnEnable() { - GetSceneRendering()->AddCommonNoCulling(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -184,7 +185,7 @@ void SkyLight::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveCommonNoCulling(this); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Light::OnDisable(); diff --git a/Source/Engine/Level/Actors/SkyLight.h b/Source/Engine/Level/Actors/SkyLight.h index ad5a7f7f4..605be3af2 100644 --- a/Source/Engine/Level/Actors/SkyLight.h +++ b/Source/Engine/Level/Actors/SkyLight.h @@ -11,9 +11,8 @@ /// API_CLASS() class FLAXENGINE_API SkyLight : public Light { -DECLARE_SCENE_OBJECT(SkyLight); + DECLARE_SCENE_OBJECT(SkyLight); public: - /// /// Sky light source mode. /// @@ -31,12 +30,11 @@ public: }; private: - AssetReference _bakedProbe; float _radius; + int32 _sceneRenderingKey = -1; public: - /// /// Additional color to add. Source texture colors are summed with it. Can be used to apply custom ambient color. /// @@ -62,7 +60,6 @@ public: AssetReference CustomTexture; public: - /// /// Gets the radius. /// @@ -98,7 +95,6 @@ public: } public: - /// /// Bakes that probe. /// @@ -112,11 +108,9 @@ public: void SetProbeData(TextureData& data); private: - void UpdateBounds(); public: - // [Light] void Draw(RenderContext& renderContext) override; #if USE_EDITOR @@ -127,7 +121,6 @@ public: bool HasContentLoaded() const override; protected: - // [Light] void OnEnable() override; void OnDisable() override; diff --git a/Source/Engine/Level/Actors/Skybox.cpp b/Source/Engine/Level/Actors/Skybox.cpp index 25510a5ff..580145da3 100644 --- a/Source/Engine/Level/Actors/Skybox.cpp +++ b/Source/Engine/Level/Actors/Skybox.cpp @@ -14,6 +14,7 @@ Skybox::Skybox(const SpawnParams& params) : Actor(params) { + _drawNoCulling = 1; } void Skybox::setupProxy() @@ -121,7 +122,7 @@ void Skybox::ApplySky(GPUContext* context, RenderContext& renderContext, const M void Skybox::OnEnable() { - GetSceneRendering()->AddCommonNoCulling(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -135,7 +136,7 @@ void Skybox::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveCommonNoCulling(this); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Actor::OnDisable(); diff --git a/Source/Engine/Level/Actors/Skybox.h b/Source/Engine/Level/Actors/Skybox.h index ba64be45d..3e44dd015 100644 --- a/Source/Engine/Level/Actors/Skybox.h +++ b/Source/Engine/Level/Actors/Skybox.h @@ -13,13 +13,12 @@ /// API_CLASS() class FLAXENGINE_API Skybox : public Actor, public ISkyRenderer { -DECLARE_SCENE_OBJECT(Skybox); + DECLARE_SCENE_OBJECT(Skybox); private: - AssetReference _proxyMaterial; + int32 _sceneRenderingKey = -1; public: - /// /// The cube texture to draw. /// @@ -51,11 +50,9 @@ public: float Exposure = 0.0f; private: - void setupProxy(); public: - // [Actor] #if USE_EDITOR BoundingBox GetEditorBox() const override @@ -74,7 +71,6 @@ public: void ApplySky(GPUContext* context, RenderContext& renderContext, const Matrix& world) override; protected: - // [Actor] void OnEnable() override; void OnDisable() override; diff --git a/Source/Engine/Level/Actors/SplineModel.cpp b/Source/Engine/Level/Actors/SplineModel.cpp index 5160c993c..f432e1da5 100644 --- a/Source/Engine/Level/Actors/SplineModel.cpp +++ b/Source/Engine/Level/Actors/SplineModel.cpp @@ -210,7 +210,7 @@ void SplineModel::OnSplineUpdated() BoundingSphere::Merge(_sphere, _instances[i].Sphere, _sphere); BoundingBox::FromSphere(_sphere, _box); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void SplineModel::UpdateDeformationBuffer() @@ -431,11 +431,6 @@ void SplineModel::Draw(RenderContext& renderContext) } } -void SplineModel::DrawGeneric(RenderContext& renderContext) -{ - Draw(renderContext); -} - bool SplineModel::IntersectsItself(const Ray& ray, float& distance, Vector3& normal) { return false; diff --git a/Source/Engine/Level/Actors/SplineModel.h b/Source/Engine/Level/Actors/SplineModel.h index 94bbb28c0..b21edbb3a 100644 --- a/Source/Engine/Level/Actors/SplineModel.h +++ b/Source/Engine/Level/Actors/SplineModel.h @@ -115,7 +115,6 @@ public: // [ModelInstanceActor] bool HasContentLoaded() const override; void Draw(RenderContext& renderContext) override; - void DrawGeneric(RenderContext& renderContext) override; bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override; void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; diff --git a/Source/Engine/Level/Actors/SpotLight.cpp b/Source/Engine/Level/Actors/SpotLight.cpp index 1cfcda89f..8dbea083c 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()->UpdateCommon(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void SpotLight::OnEnable() { - _sceneRenderingKey = GetSceneRendering()->AddCommon(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); #endif @@ -133,7 +133,7 @@ void SpotLight::OnDisable() #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveCommon(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base LightWithShadow::OnDisable(); @@ -154,6 +154,7 @@ void SpotLight::Draw(RenderContext& renderContext) const float radius = GetScaledRadius(); const float outerConeAngle = GetOuterConeAngle(); if ((renderContext.View.Flags & ViewFlags::SpotLights) != 0 + && renderContext.View.Pass & DrawPass::GBuffer && brightness > ZeroTolerance && radius > ZeroTolerance && outerConeAngle > ZeroTolerance diff --git a/Source/Engine/Level/Actors/StaticModel.cpp b/Source/Engine/Level/Actors/StaticModel.cpp index fe3c7f9be..cbb700dda 100644 --- a/Source/Engine/Level/Actors/StaticModel.cpp +++ b/Source/Engine/Level/Actors/StaticModel.cpp @@ -199,7 +199,7 @@ void StaticModel::UpdateBounds() } BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } bool StaticModel::HasContentLoaded() const @@ -267,14 +267,6 @@ void StaticModel::Draw(RenderContext& renderContext) GEOMETRY_DRAW_STATE_EVENT_END(_drawState, _world); } -void StaticModel::DrawGeneric(RenderContext& renderContext) -{ - if (renderContext.View.RenderLayersMask.Mask & GetLayerMask() && renderContext.View.CullingFrustum.Intersects(_box)) - { - Draw(renderContext); - } -} - bool StaticModel::IntersectsItself(const Ray& ray, float& distance, Vector3& normal) { bool result = false; diff --git a/Source/Engine/Level/Actors/StaticModel.h b/Source/Engine/Level/Actors/StaticModel.h index d51e50aee..60f0355bf 100644 --- a/Source/Engine/Level/Actors/StaticModel.h +++ b/Source/Engine/Level/Actors/StaticModel.h @@ -189,7 +189,6 @@ public: // [ModelInstanceActor] bool HasContentLoaded() const override; void Draw(RenderContext& renderContext) override; - void DrawGeneric(RenderContext& renderContext) override; bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override; void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp index 39e358faf..5ff5d8c89 100644 --- a/Source/Engine/Level/Level.cpp +++ b/Source/Engine/Level/Level.cpp @@ -378,9 +378,10 @@ void Level::DrawActors(RenderContext& renderContext) //ScopeLock lock(ScenesLock); - for (int32 i = 0; i < Scenes.Count(); i++) + for (Scene* scene : Scenes) { - Scenes[i]->Rendering.Draw(renderContext); + if (scene->IsActiveInHierarchy()) + scene->Rendering.Draw(renderContext); } } @@ -390,9 +391,10 @@ void Level::CollectPostFxVolumes(RenderContext& renderContext) //ScopeLock lock(ScenesLock); - for (int32 i = 0; i < Scenes.Count(); i++) + for (Scene* scene : Scenes) { - Scenes[i]->Rendering.CollectPostFxVolumes(renderContext); + if (scene->IsActiveInHierarchy()) + scene->Rendering.CollectPostFxVolumes(renderContext); } } diff --git a/Source/Engine/Level/Scene/Scene.cpp b/Source/Engine/Level/Scene/Scene.cpp index 166373e27..6c25c2f89 100644 --- a/Source/Engine/Level/Scene/Scene.cpp +++ b/Source/Engine/Level/Scene/Scene.cpp @@ -60,7 +60,6 @@ NavMeshBoundsVolume* SceneNavigation::FindNavigationBoundsOverlap(const Bounding Scene::Scene(const SpawnParams& params) : Actor(params) - , Rendering(this) , LightmapsData(this) , CSGData(this) { diff --git a/Source/Engine/Level/Scene/SceneRendering.cpp b/Source/Engine/Level/Scene/SceneRendering.cpp index 252793eae..51dea146b 100644 --- a/Source/Engine/Level/Scene/SceneRendering.cpp +++ b/Source/Engine/Level/Scene/SceneRendering.cpp @@ -1,369 +1,53 @@ // Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. +#define SCENE_RENDERING_USE_PROFILER 0 + #include "SceneRendering.h" -#include "Scene.h" #include "Engine/Graphics/RenderTask.h" #include "Engine/Graphics/RenderView.h" - -#define SCENE_RENDERING_USE_PROFILER 0 -#define SCENE_RENDERING_USE_SIMD 0 - +#include "Engine/Renderer/RenderList.h" #if SCENE_RENDERING_USE_PROFILER #include "Engine/Profiler/ProfilerCPU.h" #endif -#if SCENE_RENDERING_USE_SIMD - -#include "Engine/Core/SIMD.h" - -ALIGN_BEGIN(16) struct CullDataSIMD -{ - float xs[8]; - float ys[8]; - float zs[8]; - float ds[8]; -} ALIGN_END(16); - -#endif - -int32 SceneRendering::DrawEntries::Add(Actor* obj) -{ - int32 key = 0; - for (; key < List.Count(); key++) - { - if (List[key].Actor == nullptr) - break; - } - if (key == List.Count()) - List.AddOne(); - auto& e = List[key]; - e.Actor = obj; - e.LayerMask = obj->GetLayerMask(); - e.Bounds = obj->GetSphere(); - return key; -} - -void SceneRendering::DrawEntries::Update(Actor* obj, int32 key) -{ - if (List.IsEmpty()) - return; - auto& e = List[key]; - ASSERT_LOW_LAYER(obj == e.Actor); - e.LayerMask = obj->GetLayerMask(); - e.Bounds = obj->GetSphere(); -} - -void SceneRendering::DrawEntries::Remove(Actor* obj, int32 key) -{ - if (List.IsEmpty()) - return; - auto& e = List[key]; - ASSERT_LOW_LAYER(obj == e.Actor); - e.Actor = nullptr; - e.LayerMask = 0; -} - -void SceneRendering::DrawEntries::Clear() -{ - List.Clear(); -} - -void SceneRendering::DrawEntries::CullAndDraw(RenderContext& renderContext) -{ - auto& view = renderContext.View; - const BoundingFrustum frustum = view.CullingFrustum; -#if SCENE_RENDERING_USE_SIMD - CullDataSIMD cullData; - { - // Near - auto plane = view.Frustum.GetNear(); - cullData.xs[0] = plane.Normal.X; - cullData.ys[0] = plane.Normal.Y; - cullData.zs[0] = plane.Normal.Z; - cullData.ds[0] = plane.D; - - // Far - plane = view.Frustum.GetFar(); - cullData.xs[1] = plane.Normal.X; - cullData.ys[1] = plane.Normal.Y; - cullData.zs[1] = plane.Normal.Z; - cullData.ds[1] = plane.D; - - // Left - plane = view.Frustum.GetLeft(); - cullData.xs[2] = plane.Normal.X; - cullData.ys[2] = plane.Normal.Y; - cullData.zs[2] = plane.Normal.Z; - cullData.ds[2] = plane.D; - - // Right - plane = view.Frustum.GetRight(); - cullData.xs[3] = plane.Normal.X; - cullData.ys[3] = plane.Normal.Y; - cullData.zs[3] = plane.Normal.Z; - cullData.ds[3] = plane.D; - - // Top - plane = view.Frustum.GetTop(); - cullData.xs[4] = plane.Normal.X; - cullData.ys[4] = plane.Normal.Y; - cullData.zs[4] = plane.Normal.Z; - cullData.ds[4] = plane.D; - - // Bottom - plane = view.Frustum.GetBottom(); - cullData.xs[5] = plane.Normal.X; - cullData.ys[5] = plane.Normal.Y; - cullData.zs[5] = plane.Normal.Z; - cullData.ds[5] = plane.D; - - // Extra 0 - cullData.xs[6] = 0; - cullData.ys[6] = 0; - cullData.zs[6] = 0; - cullData.ds[6] = 0; - - // Extra 1 - cullData.xs[7] = 0; - cullData.ys[7] = 0; - cullData.zs[7] = 0; - cullData.ds[7] = 0; - } - - SimdVector4 px = SIMD::Load(cullData.xs); - SimdVector4 py = SIMD::Load(cullData.ys); - SimdVector4 pz = SIMD::Load(cullData.zs); - SimdVector4 pd = SIMD::Load(cullData.ds); - SimdVector4 px2 = SIMD::Load(&cullData.xs[4]); - SimdVector4 py2 = SIMD::Load(&cullData.ys[4]); - SimdVector4 pz2 = SIMD::Load(&cullData.zs[4]); - SimdVector4 pd2 = SIMD::Load(&cullData.ds[4]); - - for (int32 i = 0; i < List.Count(); i++) - { - auto e = List[i]; - - SimdVector4 cx = SIMD::Splat(e.Bounds.Center.X); - SimdVector4 cy = SIMD::Splat(e.Bounds.Center.Y); - SimdVector4 cz = SIMD::Splat(e.Bounds.Center.Z); - SimdVector4 r = SIMD::Splat(-e.Bounds.Radius); - - SimdVector4 t = SIMD::Mul(cx, px); - t = SIMD::Add(t, SIMD::Mul(cy, py)); - t = SIMD::Add(t, SIMD::Mul(cz, pz)); - t = SIMD::Add(t, pd); - t = SIMD::Sub(t, r); - if (SIMD::MoveMask(t)) - continue; - - t = SIMD::Mul(cx, px2); - t = SIMD::Add(t, SIMD::Mul(cy, py2)); - t = SIMD::Add(t, SIMD::Mul(cz, pz2)); - t = SIMD::Add(t, pd2); - t = SIMD::Sub(t, r); - if (SIMD::MoveMask(t)) - continue; - - if (view.RenderLayersMask.Mask & e.LayerMask) - { -#if SCENE_RENDERING_USE_PROFILER - PROFILE_CPU(); -#if TRACY_ENABLE - ___tracy_scoped_zone.Name(*e.Actor->GetName(), e.Actor->GetName().Length()); -#endif -#endif - e.Actor->Draw(renderContext); - } - } -#else - for (int32 i = 0; i < List.Count(); i++) - { - auto e = List[i]; - if (view.RenderLayersMask.Mask & e.LayerMask && frustum.Intersects(e.Bounds)) - { -#if SCENE_RENDERING_USE_PROFILER - PROFILE_CPU(); -#if TRACY_ENABLE - ___tracy_scoped_zone.Name(*e.Actor->GetName(), e.Actor->GetName().Length()); -#endif -#endif - e.Actor->Draw(renderContext); - } - } -#endif -} - -void SceneRendering::DrawEntries::CullAndDrawOffline(RenderContext& renderContext) -{ - auto& view = renderContext.View; - const BoundingFrustum frustum = view.CullingFrustum; -#if SCENE_RENDERING_USE_SIMD - CullDataSIMD cullData; - { - // Near - auto plane = view.Frustum.GetNear(); - cullData.xs[0] = plane.Normal.X; - cullData.ys[0] = plane.Normal.Y; - cullData.zs[0] = plane.Normal.Z; - cullData.ds[0] = plane.D; - - // Far - plane = view.Frustum.GetFar(); - cullData.xs[1] = plane.Normal.X; - cullData.ys[1] = plane.Normal.Y; - cullData.zs[1] = plane.Normal.Z; - cullData.ds[1] = plane.D; - - // Left - plane = view.Frustum.GetLeft(); - cullData.xs[2] = plane.Normal.X; - cullData.ys[2] = plane.Normal.Y; - cullData.zs[2] = plane.Normal.Z; - cullData.ds[2] = plane.D; - - // Right - plane = view.Frustum.GetRight(); - cullData.xs[3] = plane.Normal.X; - cullData.ys[3] = plane.Normal.Y; - cullData.zs[3] = plane.Normal.Z; - cullData.ds[3] = plane.D; - - // Top - plane = view.Frustum.GetTop(); - cullData.xs[4] = plane.Normal.X; - cullData.ys[4] = plane.Normal.Y; - cullData.zs[4] = plane.Normal.Z; - cullData.ds[4] = plane.D; - - // Bottom - plane = view.Frustum.GetBottom(); - cullData.xs[5] = plane.Normal.X; - cullData.ys[5] = plane.Normal.Y; - cullData.zs[5] = plane.Normal.Z; - cullData.ds[5] = plane.D; - - // Extra 0 - cullData.xs[6] = 0; - cullData.ys[6] = 0; - cullData.zs[6] = 0; - cullData.ds[6] = 0; - - // Extra 1 - cullData.xs[7] = 0; - cullData.ys[7] = 0; - cullData.zs[7] = 0; - cullData.ds[7] = 0; - } - - SimdVector4 px = SIMD::Load(cullData.xs); - SimdVector4 py = SIMD::Load(cullData.ys); - SimdVector4 pz = SIMD::Load(cullData.zs); - SimdVector4 pd = SIMD::Load(cullData.ds); - SimdVector4 px2 = SIMD::Load(&cullData.xs[4]); - SimdVector4 py2 = SIMD::Load(&cullData.ys[4]); - SimdVector4 pz2 = SIMD::Load(&cullData.zs[4]); - SimdVector4 pd2 = SIMD::Load(&cullData.ds[4]); - - for (int32 i = 0; i < List.Count(); i++) - { - auto e = List[i]; - - SimdVector4 cx = SIMD::Splat(e.Bounds.Center.X); - SimdVector4 cy = SIMD::Splat(e.Bounds.Center.Y); - SimdVector4 cz = SIMD::Splat(e.Bounds.Center.Z); - SimdVector4 r = SIMD::Splat(-e.Bounds.Radius); - - SimdVector4 t = SIMD::Mul(cx, px); - t = SIMD::Add(t, SIMD::Mul(cy, py)); - t = SIMD::Add(t, SIMD::Mul(cz, pz)); - t = SIMD::Add(t, pd); - t = SIMD::Sub(t, r); - if (SIMD::MoveMask(t)) - continue; - - t = SIMD::Mul(cx, px2); - t = SIMD::Add(t, SIMD::Mul(cy, py2)); - t = SIMD::Add(t, SIMD::Mul(cz, pz2)); - t = SIMD::Add(t, pd2); - t = SIMD::Sub(t, r); - if (SIMD::MoveMask(t)) - continue; - - if (view.RenderLayersMask.Mask & e.LayerMask && e.Actor->GetStaticFlags() & renderContext.View.StaticFlagsMask) - { -#if SCENE_RENDERING_USE_PROFILER - PROFILE_CPU(); -#if TRACY_ENABLE - ___tracy_scoped_zone.Name(*e.Actor->GetName(), e.Actor->GetName().Length()); -#endif -#endif - e.Actor->Draw(renderContext); - } - } -#else - for (int32 i = 0; i < List.Count(); i++) - { - auto e = List[i]; - if (view.RenderLayersMask.Mask & e.LayerMask && frustum.Intersects(e.Bounds) && e.Actor->GetStaticFlags() & view.StaticFlagsMask) - { -#if SCENE_RENDERING_USE_PROFILER - PROFILE_CPU(); -#if TRACY_ENABLE - ___tracy_scoped_zone.Name(*e.Actor->GetName(), e.Actor->GetName().Length()); -#endif -#endif - e.Actor->Draw(renderContext); - } - } -#endif -} - -SceneRendering::SceneRendering(::Scene* scene) - : Scene(scene) -{ -} - void SceneRendering::Draw(RenderContext& renderContext) { - // Skip if disabled - if (!Scene->GetIsActive()) - return; auto& view = renderContext.View; + const BoundingFrustum frustum = view.CullingFrustum; + renderContext.List->Scenes.Add(this); // Draw all visual components if (view.IsOfflinePass) { - Geometry.CullAndDrawOffline(renderContext); - if (view.Pass & DrawPass::GBuffer) + for (int32 i = 0; i < Actors.Count(); i++) { - Common.CullAndDrawOffline(renderContext); - for (int32 i = 0; i < CommonNoCulling.Count(); i++) + auto& e = Actors[i]; + if (view.RenderLayersMask.Mask & e.LayerMask && (e.NoCulling || frustum.Intersects(e.Bounds)) && e.Actor->GetStaticFlags() & view.StaticFlagsMask) { - auto actor = CommonNoCulling[i]; - if (actor->GetStaticFlags() & view.StaticFlagsMask && view.RenderLayersMask.HasLayer(actor->GetLayer())) - actor->Draw(renderContext); +#if SCENE_RENDERING_USE_PROFILER + PROFILE_CPU(); +#if TRACY_ENABLE + ___tracy_scoped_zone.Name(*e.Actor->GetName(), e.Actor->GetName().Length()); +#endif +#endif + e.Actor->Draw(renderContext); } } } else { - Geometry.CullAndDraw(renderContext); - if (view.Pass & DrawPass::GBuffer) + for (int32 i = 0; i < Actors.Count(); i++) { - Common.CullAndDraw(renderContext); - for (int32 i = 0; i < CommonNoCulling.Count(); i++) + auto& e = Actors[i]; + if (view.RenderLayersMask.Mask & e.LayerMask && (e.NoCulling || frustum.Intersects(e.Bounds))) { - auto actor = CommonNoCulling[i]; - if (view.RenderLayersMask.HasLayer(actor->GetLayer())) - { #if SCENE_RENDERING_USE_PROFILER - PROFILE_CPU(); + PROFILE_CPU(); #if TRACY_ENABLE - ___tracy_scoped_zone.Name(*actor->GetName(), actor->GetName().Length()); + ___tracy_scoped_zone.Name(*e.Actor->GetName(), e.Actor->GetName().Length()); #endif #endif - actor->Draw(renderContext); - } + e.Actor->Draw(renderContext); } } } @@ -395,10 +79,47 @@ void SceneRendering::CollectPostFxVolumes(RenderContext& renderContext) void SceneRendering::Clear() { - Geometry.Clear(); - Common.Clear(); - CommonNoCulling.Clear(); + Actors.Clear(); #if USE_EDITOR PhysicsDebug.Clear(); #endif } + +int32 SceneRendering::AddActor(Actor* a) +{ + int32 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; + return key; +} + +void SceneRendering::UpdateActor(Actor* a, int32 key) +{ + if (Actors.IsEmpty()) + return; + auto& e = Actors[key]; + ASSERT_LOW_LAYER(a == e.Actor); + e.LayerMask = a->GetLayerMask(); + e.Bounds = a->GetSphere(); +} + +void SceneRendering::RemoveActor(Actor* a, int32& key) +{ + if (Actors.IsEmpty()) + return; + auto& e = Actors[key]; + ASSERT_LOW_LAYER(a == e.Actor); + e.Actor = nullptr; + e.LayerMask = 0; + key = -1; +} diff --git a/Source/Engine/Level/Scene/SceneRendering.h b/Source/Engine/Level/Scene/SceneRendering.h index 0f6c32c73..afcb078ea 100644 --- a/Source/Engine/Level/Scene/SceneRendering.h +++ b/Source/Engine/Level/Scene/SceneRendering.h @@ -6,7 +6,6 @@ #include "Engine/Core/Collections/Array.h" #include "Engine/Core/Math/BoundingSphere.h" #include "Engine/Level/Actor.h" -#include "Engine/Level/Types.h" class SceneRenderTask; struct PostProcessSettings; @@ -19,7 +18,6 @@ struct RenderView; class FLAXENGINE_API IPostFxSettingsProvider { public: - /// /// Collects the settings for rendering of the specified task. /// @@ -39,46 +37,29 @@ public: /// class FLAXENGINE_API SceneRendering { - friend Scene; #if USE_EDITOR typedef Function PhysicsDebugCallback; friend class ViewportIconsRendererService; #endif - struct DrawEntry +public: + struct DrawActor { Actor* Actor; uint32 LayerMask; + int8 NoCulling : 1; BoundingSphere Bounds; }; - struct DrawEntries - { - Array List; - - int32 Add(Actor* obj); - void Update(Actor* obj, int32 key); - void Remove(Actor* obj, int32 key); - void Clear(); - void CullAndDraw(RenderContext& renderContext); - void CullAndDrawOffline(RenderContext& renderContext); - }; + Array Actors; + Array PostFxProviders; private: - - Scene* Scene; - DrawEntries Geometry; - DrawEntries Common; - Array CommonNoCulling; - Array PostFxProviders; #if USE_EDITOR Array PhysicsDebug; Array ViewportIcons; #endif - explicit SceneRendering(::Scene* scene); - public: - /// /// Draws the scene. Performs the optimized actors culling and draw calls submission for the current render pass (defined by the render view). /// @@ -97,48 +78,9 @@ public: void Clear(); public: - - FORCE_INLINE int32 AddGeometry(Actor* obj) - { - return Geometry.Add(obj); - } - - FORCE_INLINE void UpdateGeometry(Actor* obj, int32 key) - { - Geometry.Update(obj, key); - } - - FORCE_INLINE void RemoveGeometry(Actor* obj, int32& key) - { - Geometry.Remove(obj, key); - key = -1; - } - - FORCE_INLINE int32 AddCommon(Actor* obj) - { - return Common.Add(obj); - } - - FORCE_INLINE void UpdateCommon(Actor* obj, int32 key) - { - Common.Update(obj, key); - } - - FORCE_INLINE void RemoveCommon(Actor* obj, int32& key) - { - Common.Remove(obj, key); - key = -1; - } - - FORCE_INLINE void AddCommonNoCulling(Actor* obj) - { - CommonNoCulling.Add(obj); - } - - FORCE_INLINE void RemoveCommonNoCulling(Actor* obj) - { - CommonNoCulling.Remove(obj); - } + int32 AddActor(Actor* a); + void UpdateActor(Actor* a, int32 key); + void RemoveActor(Actor* a, int32& key); FORCE_INLINE void AddPostFxProvider(IPostFxSettingsProvider* obj) { @@ -151,7 +93,6 @@ public: } #if USE_EDITOR - template FORCE_INLINE void AddPhysicsDebug(T* obj) { @@ -177,6 +118,5 @@ public: { ViewportIcons.Remove(obj); } - #endif }; diff --git a/Source/Engine/Particles/ParticleEffect.cpp b/Source/Engine/Particles/ParticleEffect.cpp index 4b088951b..7cf2420ca 100644 --- a/Source/Engine/Particles/ParticleEffect.cpp +++ b/Source/Engine/Particles/ParticleEffect.cpp @@ -312,7 +312,7 @@ void ParticleEffect::UpdateBounds() _box = bounds; BoundingSphere::FromBox(bounds, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void ParticleEffect::Sync() @@ -498,11 +498,6 @@ void ParticleEffect::Draw(RenderContext& renderContext) Particles::DrawParticles(renderContext, this); } -void ParticleEffect::DrawGeneric(RenderContext& renderContext) -{ - Draw(renderContext); -} - #if USE_EDITOR #include "Engine/Debug/DebugDraw.h" @@ -520,7 +515,7 @@ void ParticleEffect::OnDebugDrawSelected() void ParticleEffect::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void ParticleEffect::Serialize(SerializeStream& stream, const void* otherObj) @@ -699,7 +694,7 @@ void ParticleEffect::EndPlay() void ParticleEffect::OnEnable() { GetScene()->Ticking.Update.AddTick(this); - _sceneRenderingKey = GetSceneRendering()->AddGeometry(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); GetScene()->Ticking.Update.AddTickExecuteInEditor(this); @@ -715,7 +710,7 @@ void ParticleEffect::OnDisable() GetScene()->Ticking.Update.RemoveTickExecuteInEditor(this); GetSceneRendering()->RemoveViewportIcon(this); #endif - GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); GetScene()->Ticking.Update.RemoveTick(this); // Base diff --git a/Source/Engine/Particles/ParticleEffect.h b/Source/Engine/Particles/ParticleEffect.h index c0c13b642..454eba474 100644 --- a/Source/Engine/Particles/ParticleEffect.h +++ b/Source/Engine/Particles/ParticleEffect.h @@ -385,7 +385,6 @@ public: // [Actor] bool HasContentLoaded() const override; void Draw(RenderContext& renderContext) override; - void DrawGeneric(RenderContext& renderContext) override; #if USE_EDITOR void OnDebugDrawSelected() override; #endif diff --git a/Source/Engine/Renderer/RenderList.cpp b/Source/Engine/Renderer/RenderList.cpp index 09e6bc6b2..43dcfd82e 100644 --- a/Source/Engine/Renderer/RenderList.cpp +++ b/Source/Engine/Renderer/RenderList.cpp @@ -392,6 +392,7 @@ void RenderList::Init(RenderContext& renderContext) void RenderList::Clear() { + Scenes.Clear(); DrawCalls.Clear(); BatchedDrawCalls.Clear(); for (auto& list : DrawCallsLists) diff --git a/Source/Engine/Renderer/RenderList.h b/Source/Engine/Renderer/RenderList.h index 1b514f824..1a83065ac 100644 --- a/Source/Engine/Renderer/RenderList.h +++ b/Source/Engine/Renderer/RenderList.h @@ -11,6 +11,7 @@ enum class StaticFlags; class RenderBuffers; +class SceneRendering; class LightWithShadow; class IPostFxSettingsProvider; class CubeTexture; @@ -345,6 +346,11 @@ DECLARE_SCRIPTING_TYPE(RenderList); public: + /// + /// All scenes for rendering. + /// + Array Scenes; + /// /// Draw calls list (for all draw passes). /// diff --git a/Source/Engine/Terrain/Terrain.cpp b/Source/Engine/Terrain/Terrain.cpp index c405b390e..76c02e75d 100644 --- a/Source/Engine/Terrain/Terrain.cpp +++ b/Source/Engine/Terrain/Terrain.cpp @@ -47,7 +47,7 @@ void Terrain::UpdateBounds() } BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void Terrain::CacheNeighbors() @@ -557,11 +557,6 @@ void Terrain::Draw(RenderContext& renderContext) } } -void Terrain::DrawGeneric(RenderContext& renderContext) -{ - Draw(renderContext); -} - #if USE_EDITOR //#include "Engine/Debug/DebugDraw.h" @@ -742,7 +737,7 @@ RigidBody* Terrain::GetAttachedRigidBody() const void Terrain::OnEnable() { - _sceneRenderingKey = GetSceneRendering()->AddGeometry(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); #if TERRAIN_USE_PHYSICS_DEBUG GetSceneRendering()->AddPhysicsDebug(this); #endif @@ -753,7 +748,7 @@ void Terrain::OnEnable() void Terrain::OnDisable() { - GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); #if TERRAIN_USE_PHYSICS_DEBUG GetSceneRendering()->RemovePhysicsDebug(this); #endif @@ -794,7 +789,7 @@ void Terrain::OnLayerChanged() UpdateLayerBits(); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void Terrain::OnActiveInTreeChanged() diff --git a/Source/Engine/Terrain/Terrain.h b/Source/Engine/Terrain/Terrain.h index 8a442582e..95a41bf22 100644 --- a/Source/Engine/Terrain/Terrain.h +++ b/Source/Engine/Terrain/Terrain.h @@ -441,7 +441,6 @@ public: // [PhysicsColliderActor] void Draw(RenderContext& renderContext) override; - void DrawGeneric(RenderContext& renderContext) override; #if USE_EDITOR void OnDebugDrawSelected() override; #endif diff --git a/Source/Engine/UI/SpriteRender.cpp b/Source/Engine/UI/SpriteRender.cpp index 32d26623a..2e9ac8392 100644 --- a/Source/Engine/UI/SpriteRender.cpp +++ b/Source/Engine/UI/SpriteRender.cpp @@ -131,11 +131,6 @@ void SpriteRender::Draw(RenderContext& renderContext) model->LODs[0].Draw(renderContext, _materialInstance, world, GetStaticFlags(), false, DrawModes, GetPerInstanceRandom()); } -void SpriteRender::DrawGeneric(RenderContext& renderContext) -{ - Draw(renderContext); -} - void SpriteRender::Serialize(SerializeStream& stream, const void* otherObj) { // Base @@ -173,7 +168,7 @@ void SpriteRender::Deserialize(DeserializeStream& stream, ISerializeModifier* mo void SpriteRender::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } void SpriteRender::OnEndPlay() @@ -193,7 +188,7 @@ void SpriteRender::OnEndPlay() void SpriteRender::OnEnable() { - _sceneRenderingKey = GetSceneRendering()->AddGeometry(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); // Base Actor::OnEnable(); @@ -201,7 +196,7 @@ void SpriteRender::OnEnable() void SpriteRender::OnDisable() { - GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Actor::OnDisable(); @@ -218,5 +213,5 @@ void SpriteRender::OnTransformChanged() BoundingSphere::Transform(localSphere, world, _sphere); BoundingBox::FromSphere(_sphere, _box); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } diff --git a/Source/Engine/UI/SpriteRender.h b/Source/Engine/UI/SpriteRender.h index 00b232266..e28399860 100644 --- a/Source/Engine/UI/SpriteRender.h +++ b/Source/Engine/UI/SpriteRender.h @@ -95,7 +95,6 @@ public: // [Actor] bool HasContentLoaded() const override; void Draw(RenderContext& renderContext) override; - void DrawGeneric(RenderContext& renderContext) override; void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; void OnLayerChanged() override; diff --git a/Source/Engine/UI/TextRender.cpp b/Source/Engine/UI/TextRender.cpp index 10e17d16b..0ec85ff5d 100644 --- a/Source/Engine/UI/TextRender.cpp +++ b/Source/Engine/UI/TextRender.cpp @@ -330,7 +330,7 @@ void TextRender::UpdateLayout() BoundingBox::Transform(_localBox, _world, _box); BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } bool TextRender::HasContentLoaded() const @@ -400,11 +400,6 @@ void TextRender::Draw(RenderContext& renderContext) GEOMETRY_DRAW_STATE_EVENT_END(_drawState, _world); } -void TextRender::DrawGeneric(RenderContext& renderContext) -{ - Draw(renderContext); -} - #if USE_EDITOR #include "Engine/Debug/DebugDraw.h" @@ -426,7 +421,7 @@ void TextRender::OnDebugDrawSelected() void TextRender::OnLayerChanged() { if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } bool TextRender::IntersectsItself(const Ray& ray, float& distance, Vector3& normal) @@ -495,7 +490,7 @@ void TextRender::OnEnable() { UpdateLayout(); } - _sceneRenderingKey = GetSceneRendering()->AddGeometry(this); + _sceneRenderingKey = GetSceneRendering()->AddActor(this); } void TextRender::OnDisable() @@ -505,7 +500,7 @@ void TextRender::OnDisable() _isLocalized = false; Localization::LocalizationChanged.Unbind(this); } - GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey); + GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); // Base Actor::OnDisable(); @@ -520,5 +515,5 @@ void TextRender::OnTransformChanged() BoundingBox::Transform(_localBox, _world, _box); BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) - GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey); + GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); } diff --git a/Source/Engine/UI/TextRender.h b/Source/Engine/UI/TextRender.h index 1b19737ad..c6a49b84e 100644 --- a/Source/Engine/UI/TextRender.h +++ b/Source/Engine/UI/TextRender.h @@ -166,7 +166,6 @@ public: // [Actor] bool HasContentLoaded() const override; void Draw(RenderContext& renderContext) override; - void DrawGeneric(RenderContext& renderContext) override; #if USE_EDITOR void OnDebugDrawSelected() override; #endif