Optimize Scene Rendering (cache drawable bounds and layers for culling with less cache misses)
This commit is contained in:
@@ -51,74 +51,14 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DrawIcons(RenderContext& renderContext, Scene* scene, Mesh::DrawInfo& draw);
|
||||||
|
static void DrawIcons(RenderContext& renderContext, Actor* actor, Mesh::DrawInfo& draw);
|
||||||
bool Init() override;
|
bool Init() override;
|
||||||
void Dispose() override;
|
void Dispose() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
ViewportIconsRendererService ViewportIconsRendererServiceInstance;
|
ViewportIconsRendererService ViewportIconsRendererServiceInstance;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void DrawIcons(RenderContext& renderContext, Scene* scene, Mesh::DrawInfo& draw)
|
|
||||||
{
|
|
||||||
auto& view = renderContext.View;
|
|
||||||
const BoundingFrustum frustum = view.Frustum;
|
|
||||||
auto& icons = scene->GetSceneRendering()->ViewportIcons;
|
|
||||||
Matrix m1, m2, world;
|
|
||||||
for (Actor* icon : icons)
|
|
||||||
{
|
|
||||||
BoundingSphere sphere(icon->GetPosition(), ICON_RADIUS);
|
|
||||||
IconTypes iconType;
|
|
||||||
if (frustum.Intersects(sphere) && ActorTypeToIconType.TryGet(icon->GetTypeHandle(), iconType))
|
|
||||||
{
|
|
||||||
// Create world matrix
|
|
||||||
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
|
|
||||||
Matrix::RotationY(PI, world);
|
|
||||||
Matrix::Multiply(m2, world, m1);
|
|
||||||
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);
|
|
||||||
Matrix::Multiply(m1, m2, world);
|
|
||||||
|
|
||||||
// Draw icon
|
|
||||||
GeometryDrawStateData drawState;
|
|
||||||
draw.DrawState = &drawState;
|
|
||||||
draw.Buffer = &InstanceBuffers[static_cast<int32>(iconType)];
|
|
||||||
draw.World = &world;
|
|
||||||
draw.Bounds = sphere;
|
|
||||||
QuadModel->Draw(renderContext, draw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawIcons(RenderContext& renderContext, Actor* actor, Mesh::DrawInfo& draw)
|
|
||||||
{
|
|
||||||
auto& view = renderContext.View;
|
|
||||||
const BoundingFrustum frustum = view.Frustum;
|
|
||||||
Matrix m1, m2, world;
|
|
||||||
BoundingSphere sphere(actor->GetPosition(), ICON_RADIUS);
|
|
||||||
IconTypes iconType;
|
|
||||||
if (frustum.Intersects(sphere) && ActorTypeToIconType.TryGet(actor->GetTypeHandle(), iconType))
|
|
||||||
{
|
|
||||||
// Create world matrix
|
|
||||||
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
|
|
||||||
Matrix::RotationY(PI, world);
|
|
||||||
Matrix::Multiply(m2, world, m1);
|
|
||||||
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);
|
|
||||||
Matrix::Multiply(m1, m2, world);
|
|
||||||
|
|
||||||
// Draw icon
|
|
||||||
GeometryDrawStateData drawState;
|
|
||||||
draw.DrawState = &drawState;
|
|
||||||
draw.Buffer = &InstanceBuffers[static_cast<int32>(iconType)];
|
|
||||||
draw.World = &world;
|
|
||||||
draw.Bounds = sphere;
|
|
||||||
QuadModel->Draw(renderContext, draw);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto child : actor->Children)
|
|
||||||
DrawIcons(renderContext, child, draw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewportIconsRenderer::DrawIcons(RenderContext& renderContext, Actor* actor)
|
void ViewportIconsRenderer::DrawIcons(RenderContext& renderContext, Actor* actor)
|
||||||
{
|
{
|
||||||
auto& view = renderContext.View;
|
auto& view = renderContext.View;
|
||||||
@@ -137,14 +77,73 @@ void ViewportIconsRenderer::DrawIcons(RenderContext& renderContext, Actor* actor
|
|||||||
|
|
||||||
if (const auto scene = SceneObject::Cast<Scene>(actor))
|
if (const auto scene = SceneObject::Cast<Scene>(actor))
|
||||||
{
|
{
|
||||||
::DrawIcons(renderContext, scene, draw);
|
ViewportIconsRendererService::DrawIcons(renderContext, scene, draw);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
::DrawIcons(renderContext, actor, draw);
|
ViewportIconsRendererService::DrawIcons(renderContext, actor, draw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Scene* scene, Mesh::DrawInfo& draw)
|
||||||
|
{
|
||||||
|
auto& view = renderContext.View;
|
||||||
|
const BoundingFrustum frustum = view.Frustum;
|
||||||
|
auto& icons = scene->GetSceneRendering()->ViewportIcons;
|
||||||
|
Matrix m1, m2, world;
|
||||||
|
for (Actor* icon : icons)
|
||||||
|
{
|
||||||
|
BoundingSphere sphere(icon->GetPosition(), ICON_RADIUS);
|
||||||
|
IconTypes iconType;
|
||||||
|
if (frustum.Intersects(sphere) && ActorTypeToIconType.TryGet(icon->GetTypeHandle(), iconType))
|
||||||
|
{
|
||||||
|
// Create world matrix
|
||||||
|
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
|
||||||
|
Matrix::RotationY(PI, world);
|
||||||
|
Matrix::Multiply(m2, world, m1);
|
||||||
|
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);
|
||||||
|
Matrix::Multiply(m1, m2, world);
|
||||||
|
|
||||||
|
// Draw icon
|
||||||
|
GeometryDrawStateData drawState;
|
||||||
|
draw.DrawState = &drawState;
|
||||||
|
draw.Buffer = &InstanceBuffers[static_cast<int32>(iconType)];
|
||||||
|
draw.World = &world;
|
||||||
|
draw.Bounds = sphere;
|
||||||
|
QuadModel->Draw(renderContext, draw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Actor* actor, Mesh::DrawInfo& draw)
|
||||||
|
{
|
||||||
|
auto& view = renderContext.View;
|
||||||
|
const BoundingFrustum frustum = view.Frustum;
|
||||||
|
Matrix m1, m2, world;
|
||||||
|
BoundingSphere sphere(actor->GetPosition(), ICON_RADIUS);
|
||||||
|
IconTypes iconType;
|
||||||
|
if (frustum.Intersects(sphere) && ActorTypeToIconType.TryGet(actor->GetTypeHandle(), iconType))
|
||||||
|
{
|
||||||
|
// Create world matrix
|
||||||
|
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
|
||||||
|
Matrix::RotationY(PI, world);
|
||||||
|
Matrix::Multiply(m2, world, m1);
|
||||||
|
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);
|
||||||
|
Matrix::Multiply(m1, m2, world);
|
||||||
|
|
||||||
|
// Draw icon
|
||||||
|
GeometryDrawStateData drawState;
|
||||||
|
draw.DrawState = &drawState;
|
||||||
|
draw.Buffer = &InstanceBuffers[static_cast<int32>(iconType)];
|
||||||
|
draw.World = &world;
|
||||||
|
draw.Bounds = sphere;
|
||||||
|
QuadModel->Draw(renderContext, draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto child : actor->Children)
|
||||||
|
DrawIcons(renderContext, child, draw);
|
||||||
|
}
|
||||||
|
|
||||||
bool ViewportIconsRendererService::Init()
|
bool ViewportIconsRendererService::Init()
|
||||||
{
|
{
|
||||||
QuadModel = Content::LoadAsyncInternal<Model>(TEXT("Engine/Models/Quad"));
|
QuadModel = Content::LoadAsyncInternal<Model>(TEXT("Engine/Models/Quad"));
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
|
|
||||||
LayersMask operator&(const LayersMask& other) const
|
LayersMask operator&(const LayersMask& other) const
|
||||||
{
|
{
|
||||||
return Mask && other.Mask;
|
return Mask & other.Mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayersMask operator|(const LayersMask& other) const
|
LayersMask operator|(const LayersMask& other) const
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "Engine/Core/Random.h"
|
#include "Engine/Core/Random.h"
|
||||||
#include "Engine/Engine/Engine.h"
|
#include "Engine/Engine/Engine.h"
|
||||||
#include "Engine/Graphics/RenderTask.h"
|
#include "Engine/Graphics/RenderTask.h"
|
||||||
#include "Engine/Level/Scene/Scene.h"
|
|
||||||
#include "Engine/Level/SceneQuery.h"
|
#include "Engine/Level/SceneQuery.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
#include "Engine/Serialization/Serialization.h"
|
#include "Engine/Serialization/Serialization.h"
|
||||||
@@ -68,6 +67,8 @@ void Foliage::EnsureRoot()
|
|||||||
// Cache bounds
|
// Cache bounds
|
||||||
_box = Root->Bounds;
|
_box = Root->Bounds;
|
||||||
BoundingSphere::FromBox(_box, _sphere);
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Foliage::AddToCluster(FoliageCluster* cluster, FoliageInstance& instance)
|
void Foliage::AddToCluster(FoliageCluster* cluster, FoliageInstance& instance)
|
||||||
@@ -785,9 +786,15 @@ void Foliage::Deserialize(DeserializeStream& stream, ISerializeModifier* modifie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Foliage::OnLayerChanged()
|
||||||
|
{
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
|
}
|
||||||
|
|
||||||
void Foliage::OnEnable()
|
void Foliage::OnEnable()
|
||||||
{
|
{
|
||||||
GetScene()->Rendering.AddGeometry(this);
|
_sceneRenderingKey = GetSceneRendering()->AddGeometry(this);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnEnable();
|
Actor::OnEnable();
|
||||||
@@ -795,7 +802,7 @@ void Foliage::OnEnable()
|
|||||||
|
|
||||||
void Foliage::OnDisable()
|
void Foliage::OnDisable()
|
||||||
{
|
{
|
||||||
GetScene()->Rendering.RemoveGeometry(this);
|
GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnDisable();
|
Actor::OnDisable();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ DECLARE_SCENE_OBJECT(Foliage);
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
bool _disableFoliageTypeEvents;
|
bool _disableFoliageTypeEvents;
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -191,6 +192,7 @@ public:
|
|||||||
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
|
void OnLayerChanged() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|||||||
@@ -439,6 +439,8 @@ void AnimatedModel::UpdateBounds()
|
|||||||
|
|
||||||
BoundingBox::Transform(_boxLocal, _world, _box);
|
BoundingBox::Transform(_boxLocal, _world, _box);
|
||||||
BoundingSphere::FromBox(_box, _sphere);
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimatedModel::UpdateSockets()
|
void AnimatedModel::UpdateSockets()
|
||||||
@@ -758,4 +760,6 @@ void AnimatedModel::OnTransformChanged()
|
|||||||
_transform.GetWorld(_world);
|
_transform.GetWorld(_world);
|
||||||
BoundingBox::Transform(_boxLocal, _world, _box);
|
BoundingBox::Transform(_boxLocal, _world, _box);
|
||||||
BoundingSphere::FromBox(_box, _sphere);
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,12 @@ void Decal::OnDebugDrawSelected()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void Decal::OnLayerChanged()
|
||||||
|
{
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey);
|
||||||
|
}
|
||||||
|
|
||||||
void Decal::Draw(RenderContext& renderContext)
|
void Decal::Draw(RenderContext& renderContext)
|
||||||
{
|
{
|
||||||
if ((renderContext.View.Flags & ViewFlags::Decals) != 0 &&
|
if ((renderContext.View.Flags & ViewFlags::Decals) != 0 &&
|
||||||
@@ -109,7 +115,7 @@ bool Decal::IntersectsItself(const Ray& ray, float& distance, Vector3& normal)
|
|||||||
|
|
||||||
void Decal::OnEnable()
|
void Decal::OnEnable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->AddCommon(this);
|
_sceneRenderingKey = GetSceneRendering()->AddCommon(this);
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
GetSceneRendering()->AddViewportIcon(this);
|
GetSceneRendering()->AddViewportIcon(this);
|
||||||
#endif
|
#endif
|
||||||
@@ -123,7 +129,7 @@ void Decal::OnDisable()
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
GetSceneRendering()->RemoveViewportIcon(this);
|
GetSceneRendering()->RemoveViewportIcon(this);
|
||||||
#endif
|
#endif
|
||||||
GetSceneRendering()->RemoveCommon(this);
|
GetSceneRendering()->RemoveCommon(this, _sceneRenderingKey);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnDisable();
|
Actor::OnDisable();
|
||||||
@@ -142,4 +148,7 @@ void Decal::OnTransformChanged()
|
|||||||
_bounds.Transformation = _world;
|
_bounds.Transformation = _world;
|
||||||
_bounds.GetBoundingBox(_box);
|
_bounds.GetBoundingBox(_box);
|
||||||
BoundingSphere::FromBox(_box, _sphere);
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ private:
|
|||||||
Vector3 _size;
|
Vector3 _size;
|
||||||
OrientedBoundingBox _bounds;
|
OrientedBoundingBox _bounds;
|
||||||
Matrix _world;
|
Matrix _world;
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -77,6 +78,7 @@ public:
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
void OnDebugDrawSelected() override;
|
void OnDebugDrawSelected() override;
|
||||||
#endif
|
#endif
|
||||||
|
void OnLayerChanged() override;
|
||||||
void Draw(RenderContext& renderContext) override;
|
void Draw(RenderContext& renderContext) override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ EnvironmentProbe::EnvironmentProbe(const SpawnParams& params)
|
|||||||
, _isUsingCustomProbe(false)
|
, _isUsingCustomProbe(false)
|
||||||
, _probe(nullptr)
|
, _probe(nullptr)
|
||||||
{
|
{
|
||||||
UpdateBounds();
|
_sphere = BoundingSphere(Vector3::Zero, _radius);
|
||||||
|
BoundingBox::FromSphere(_sphere, _box);
|
||||||
}
|
}
|
||||||
|
|
||||||
float EnvironmentProbe::GetRadius() const
|
float EnvironmentProbe::GetRadius() const
|
||||||
@@ -125,6 +126,8 @@ void EnvironmentProbe::UpdateBounds()
|
|||||||
{
|
{
|
||||||
_sphere = BoundingSphere(GetPosition(), GetScaledRadius());
|
_sphere = BoundingSphere(GetPosition(), GetScaledRadius());
|
||||||
BoundingBox::FromSphere(_sphere, _box);
|
BoundingBox::FromSphere(_sphere, _box);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentProbe::Draw(RenderContext& renderContext)
|
void EnvironmentProbe::Draw(RenderContext& renderContext)
|
||||||
@@ -150,6 +153,12 @@ void EnvironmentProbe::OnDebugDrawSelected()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void EnvironmentProbe::OnLayerChanged()
|
||||||
|
{
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey);
|
||||||
|
}
|
||||||
|
|
||||||
void EnvironmentProbe::Serialize(SerializeStream& stream, const void* otherObj)
|
void EnvironmentProbe::Serialize(SerializeStream& stream, const void* otherObj)
|
||||||
{
|
{
|
||||||
// Base
|
// Base
|
||||||
@@ -190,7 +199,7 @@ bool EnvironmentProbe::IntersectsItself(const Ray& ray, float& distance, Vector3
|
|||||||
|
|
||||||
void EnvironmentProbe::OnEnable()
|
void EnvironmentProbe::OnEnable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->AddCommon(this);
|
_sceneRenderingKey = GetSceneRendering()->AddCommon(this);
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
GetSceneRendering()->AddViewportIcon(this);
|
GetSceneRendering()->AddViewportIcon(this);
|
||||||
#endif
|
#endif
|
||||||
@@ -204,7 +213,7 @@ void EnvironmentProbe::OnDisable()
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
GetSceneRendering()->RemoveViewportIcon(this);
|
GetSceneRendering()->RemoveViewportIcon(this);
|
||||||
#endif
|
#endif
|
||||||
GetSceneRendering()->RemoveCommon(this);
|
GetSceneRendering()->RemoveCommon(this, _sceneRenderingKey);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnDisable();
|
Actor::OnDisable();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ private:
|
|||||||
|
|
||||||
float _radius;
|
float _radius;
|
||||||
bool _isUsingCustomProbe;
|
bool _isUsingCustomProbe;
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
AssetReference<CubeTexture> _probe;
|
AssetReference<CubeTexture> _probe;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -138,6 +139,7 @@ public:
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
void OnDebugDrawSelected() override;
|
void OnDebugDrawSelected() override;
|
||||||
#endif
|
#endif
|
||||||
|
void OnLayerChanged() override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
bool HasContentLoaded() const override;
|
bool HasContentLoaded() const override;
|
||||||
|
|||||||
@@ -31,9 +31,15 @@ MaterialInstance* ModelInstanceActor::CreateAndSetVirtualMaterialInstance(int32
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelInstanceActor::OnLayerChanged()
|
||||||
|
{
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
|
}
|
||||||
|
|
||||||
void ModelInstanceActor::OnEnable()
|
void ModelInstanceActor::OnEnable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->AddGeometry(this);
|
_sceneRenderingKey = GetSceneRendering()->AddGeometry(this);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnEnable();
|
Actor::OnEnable();
|
||||||
@@ -41,7 +47,7 @@ void ModelInstanceActor::OnEnable()
|
|||||||
|
|
||||||
void ModelInstanceActor::OnDisable()
|
void ModelInstanceActor::OnDisable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->RemoveGeometry(this);
|
GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnDisable();
|
Actor::OnDisable();
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
API_CLASS(Abstract) class FLAXENGINE_API ModelInstanceActor : public Actor
|
API_CLASS(Abstract) class FLAXENGINE_API ModelInstanceActor : public Actor
|
||||||
{
|
{
|
||||||
DECLARE_SCENE_OBJECT_ABSTRACT(ModelInstanceActor);
|
DECLARE_SCENE_OBJECT_ABSTRACT(ModelInstanceActor);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -79,6 +83,11 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// [Actor]
|
||||||
|
void OnLayerChanged() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// [Actor]
|
// [Actor]
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ PointLight::PointLight(const SpawnParams& params)
|
|||||||
ShadowsDistance = 2000.0f;
|
ShadowsDistance = 2000.0f;
|
||||||
ShadowsFadeDistance = 100.0f;
|
ShadowsFadeDistance = 100.0f;
|
||||||
ShadowsDepthBias = 0.5f;
|
ShadowsDepthBias = 0.5f;
|
||||||
UpdateBounds();
|
_direction = Vector3::Forward;
|
||||||
|
_sphere = BoundingSphere(Vector3::Zero, _radius);
|
||||||
|
BoundingBox::FromSphere(_sphere, _box);
|
||||||
}
|
}
|
||||||
|
|
||||||
float PointLight::ComputeBrightness() const
|
float PointLight::ComputeBrightness() const
|
||||||
@@ -62,11 +64,14 @@ void PointLight::UpdateBounds()
|
|||||||
// Cache bounding box
|
// Cache bounding box
|
||||||
_sphere = BoundingSphere(GetPosition(), GetScaledRadius());
|
_sphere = BoundingSphere(GetPosition(), GetScaledRadius());
|
||||||
BoundingBox::FromSphere(_sphere, _box);
|
BoundingBox::FromSphere(_sphere, _box);
|
||||||
|
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointLight::OnEnable()
|
void PointLight::OnEnable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->AddCommon(this);
|
_sceneRenderingKey = GetSceneRendering()->AddCommon(this);
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
GetSceneRendering()->AddViewportIcon(this);
|
GetSceneRendering()->AddViewportIcon(this);
|
||||||
#endif
|
#endif
|
||||||
@@ -80,7 +85,7 @@ void PointLight::OnDisable()
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
GetSceneRendering()->RemoveViewportIcon(this);
|
GetSceneRendering()->RemoveViewportIcon(this);
|
||||||
#endif
|
#endif
|
||||||
GetSceneRendering()->RemoveCommon(this);
|
GetSceneRendering()->RemoveCommon(this, _sceneRenderingKey);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
LightWithShadow::OnDisable();
|
LightWithShadow::OnDisable();
|
||||||
@@ -157,6 +162,12 @@ void PointLight::OnDebugDrawSelected()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void PointLight::OnLayerChanged()
|
||||||
|
{
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey);
|
||||||
|
}
|
||||||
|
|
||||||
void PointLight::Serialize(SerializeStream& stream, const void* otherObj)
|
void PointLight::Serialize(SerializeStream& stream, const void* otherObj)
|
||||||
{
|
{
|
||||||
// Base
|
// Base
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ private:
|
|||||||
|
|
||||||
Vector3 _direction;
|
Vector3 _direction;
|
||||||
float _radius;
|
float _radius;
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -101,6 +102,7 @@ public:
|
|||||||
void OnDebugDraw() override;
|
void OnDebugDraw() override;
|
||||||
void OnDebugDrawSelected() override;
|
void OnDebugDrawSelected() override;
|
||||||
#endif
|
#endif
|
||||||
|
void OnLayerChanged() override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
||||||
|
|||||||
@@ -18,7 +18,14 @@ SpotLight::SpotLight(const SpawnParams& params)
|
|||||||
ShadowsDistance = 2000.0f;
|
ShadowsDistance = 2000.0f;
|
||||||
ShadowsFadeDistance = 100.0f;
|
ShadowsFadeDistance = 100.0f;
|
||||||
ShadowsDepthBias = 0.5f;
|
ShadowsDepthBias = 0.5f;
|
||||||
UpdateBounds();
|
|
||||||
|
_direction = Vector3::Forward;
|
||||||
|
_cosOuterCone = Math::Cos(_outerConeAngle * DegreesToRadians);
|
||||||
|
_cosInnerCone = Math::Cos(_innerConeAngle * DegreesToRadians);
|
||||||
|
_invCosConeDifference = 1.0f / (_cosInnerCone - _cosOuterCone);
|
||||||
|
const float boundsRadius = Math::Sqrt(1.25f * _radius * _radius - _radius * _radius * _cosOuterCone);
|
||||||
|
_sphere = BoundingSphere(GetPosition() + 0.5f * GetDirection() * _radius, boundsRadius);
|
||||||
|
BoundingBox::FromSphere(_sphere, _box);
|
||||||
}
|
}
|
||||||
|
|
||||||
float SpotLight::ComputeBrightness() const
|
float SpotLight::ComputeBrightness() const
|
||||||
@@ -105,11 +112,14 @@ void SpotLight::UpdateBounds()
|
|||||||
const float boundsRadius = Math::Sqrt(1.25f * radius * radius - radius * radius * _cosOuterCone);
|
const float boundsRadius = Math::Sqrt(1.25f * radius * radius - radius * radius * _cosOuterCone);
|
||||||
_sphere = BoundingSphere(GetPosition() + 0.5f * GetDirection() * radius, boundsRadius);
|
_sphere = BoundingSphere(GetPosition() + 0.5f * GetDirection() * radius, boundsRadius);
|
||||||
BoundingBox::FromSphere(_sphere, _box);
|
BoundingBox::FromSphere(_sphere, _box);
|
||||||
|
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateCommon(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpotLight::OnEnable()
|
void SpotLight::OnEnable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->AddCommon(this);
|
_sceneRenderingKey = GetSceneRendering()->AddCommon(this);
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
GetSceneRendering()->AddViewportIcon(this);
|
GetSceneRendering()->AddViewportIcon(this);
|
||||||
#endif
|
#endif
|
||||||
@@ -123,7 +133,7 @@ void SpotLight::OnDisable()
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
GetSceneRendering()->RemoveViewportIcon(this);
|
GetSceneRendering()->RemoveViewportIcon(this);
|
||||||
#endif
|
#endif
|
||||||
GetSceneRendering()->RemoveCommon(this);
|
GetSceneRendering()->RemoveCommon(this, _sceneRenderingKey);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
LightWithShadow::OnDisable();
|
LightWithShadow::OnDisable();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ private:
|
|||||||
float _cosOuterCone;
|
float _cosOuterCone;
|
||||||
float _cosInnerCone;
|
float _cosInnerCone;
|
||||||
float _invCosConeDifference;
|
float _invCosConeDifference;
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -193,6 +193,8 @@ void StaticModel::UpdateBounds()
|
|||||||
_box = BoundingBox(_transform.Translation);
|
_box = BoundingBox(_transform.Translation);
|
||||||
}
|
}
|
||||||
BoundingSphere::FromBox(_box, _sphere);
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StaticModel::HasContentLoaded() const
|
bool StaticModel::HasContentLoaded() const
|
||||||
@@ -245,7 +247,7 @@ void StaticModel::Draw(RenderContext& renderContext)
|
|||||||
draw.DrawState = &_drawState;
|
draw.DrawState = &_drawState;
|
||||||
draw.Lightmap = _scene->LightmapsData.GetReadyLightmap(Lightmap.TextureIndex);
|
draw.Lightmap = _scene->LightmapsData.GetReadyLightmap(Lightmap.TextureIndex);
|
||||||
draw.LightmapUVs = &Lightmap.UVsArea;
|
draw.LightmapUVs = &Lightmap.UVsArea;
|
||||||
draw.Flags = GetStaticFlags();
|
draw.Flags = _staticFlags;
|
||||||
draw.DrawModes = drawModes;
|
draw.DrawModes = drawModes;
|
||||||
draw.Bounds = _sphere;
|
draw.Bounds = _sphere;
|
||||||
draw.PerInstanceRandom = GetPerInstanceRandom();
|
draw.PerInstanceRandom = GetPerInstanceRandom();
|
||||||
|
|||||||
@@ -4,10 +4,14 @@
|
|||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "Engine/Graphics/RenderTask.h"
|
#include "Engine/Graphics/RenderTask.h"
|
||||||
#include "Engine/Graphics/RenderView.h"
|
#include "Engine/Graphics/RenderView.h"
|
||||||
#include "Engine/Level/Actors/PostFxVolume.h"
|
|
||||||
|
|
||||||
|
#define SCENE_RENDERING_USE_PROFILER 0
|
||||||
#define SCENE_RENDERING_USE_SIMD 0
|
#define SCENE_RENDERING_USE_SIMD 0
|
||||||
|
|
||||||
|
#if SCENE_RENDERING_USE_PROFILER
|
||||||
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SCENE_RENDERING_USE_SIMD
|
#if SCENE_RENDERING_USE_SIMD
|
||||||
|
|
||||||
#include "Engine/Core/SIMD.h"
|
#include "Engine/Core/SIMD.h"
|
||||||
@@ -22,14 +26,49 @@ ALIGN_BEGIN(16) struct CullDataSIMD
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SceneRendering::SceneRendering(::Scene* scene)
|
int32 SceneRendering::DrawEntries::Add(Actor* obj)
|
||||||
: Scene(scene)
|
|
||||||
{
|
{
|
||||||
|
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 CullAndDraw(const BoundingFrustum& frustum, RenderContext& renderContext, const Array<Actor*>& actors)
|
void SceneRendering::DrawEntries::Update(Actor* obj, int32 key)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneRendering::DrawEntries::Clear()
|
||||||
|
{
|
||||||
|
List.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneRendering::DrawEntries::CullAndDraw(RenderContext& renderContext)
|
||||||
{
|
{
|
||||||
auto& view = renderContext.View;
|
auto& view = renderContext.View;
|
||||||
|
const BoundingFrustum frustum = view.CullingFrustum;
|
||||||
#if SCENE_RENDERING_USE_SIMD
|
#if SCENE_RENDERING_USE_SIMD
|
||||||
CullDataSIMD cullData;
|
CullDataSIMD cullData;
|
||||||
{
|
{
|
||||||
@@ -97,8 +136,10 @@ void CullAndDraw(const BoundingFrustum& frustum, RenderContext& renderContext, c
|
|||||||
float4 pz2 = SIMD::Load(&cullData.zs[4]);
|
float4 pz2 = SIMD::Load(&cullData.zs[4]);
|
||||||
float4 pd2 = SIMD::Load(&cullData.ds[4]);
|
float4 pd2 = SIMD::Load(&cullData.ds[4]);
|
||||||
|
|
||||||
for (int32 i = 0; i < actors.Count(); i++)
|
for (int32 i = 0; i < List.Count(); i++)
|
||||||
{
|
{
|
||||||
|
auto& e = List[i];
|
||||||
|
|
||||||
const auto& sphere = actors[i]->GetSphere();
|
const auto& sphere = actors[i]->GetSphere();
|
||||||
float4 cx = SIMD::Splat(sphere.Center.X);
|
float4 cx = SIMD::Splat(sphere.Center.X);
|
||||||
float4 cy = SIMD::Splat(sphere.Center.Y);
|
float4 cy = SIMD::Splat(sphere.Center.Y);
|
||||||
@@ -121,21 +162,28 @@ void CullAndDraw(const BoundingFrustum& frustum, RenderContext& renderContext, c
|
|||||||
if (SIMD::MoveMask(t))
|
if (SIMD::MoveMask(t))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
actors[i]->Draw(renderContext);
|
e.Actor->Draw(renderContext);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (int32 i = 0; i < actors.Count(); i++)
|
for (int32 i = 0; i < List.Count(); i++)
|
||||||
{
|
{
|
||||||
auto actor = actors[i];
|
auto e = List[i];
|
||||||
if (view.RenderLayersMask.HasLayer(actor->GetLayer()) && frustum.Intersects(actor->GetSphere()))
|
if (view.RenderLayersMask.Mask & e.LayerMask && frustum.Intersects(e.Bounds))
|
||||||
actor->Draw(renderContext);
|
{
|
||||||
|
#if SCENE_RENDERING_USE_PROFILER
|
||||||
|
PROFILE_CPU();
|
||||||
|
___tracy_scoped_zone.Name(*e.Actor->GetName(), e.Actor->GetName().Length());
|
||||||
|
#endif
|
||||||
|
e.Actor->Draw(renderContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CullAndDrawOffline(const BoundingFrustum& frustum, RenderContext& renderContext, const Array<Actor*>& actors)
|
void SceneRendering::DrawEntries::CullAndDrawOffline(RenderContext& renderContext)
|
||||||
{
|
{
|
||||||
auto& view = renderContext.View;
|
auto& view = renderContext.View;
|
||||||
|
const BoundingFrustum frustum = view.CullingFrustum;
|
||||||
#if SCENE_RENDERING_USE_SIMD
|
#if SCENE_RENDERING_USE_SIMD
|
||||||
CullDataSIMD cullData;
|
CullDataSIMD cullData;
|
||||||
{
|
{
|
||||||
@@ -231,15 +279,26 @@ void CullAndDrawOffline(const BoundingFrustum& frustum, RenderContext& renderCon
|
|||||||
actors[i]->Draw(renderContext);
|
actors[i]->Draw(renderContext);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (int32 i = 0; i < actors.Count(); i++)
|
for (int32 i = 0; i < List.Count(); i++)
|
||||||
{
|
{
|
||||||
auto actor = actors[i];
|
auto e = List[i];
|
||||||
if (actor->GetStaticFlags() & view.StaticFlagsMask && view.RenderLayersMask.HasLayer(actor->GetLayer()) && frustum.Intersects(actor->GetSphere()))
|
if (view.RenderLayersMask.Mask & e.LayerMask && frustum.Intersects(e.Bounds) && e.Actor->GetStaticFlags() & view.StaticFlagsMask)
|
||||||
actor->Draw(renderContext);
|
{
|
||||||
|
#if SCENE_RENDERING_USE_PROFILER
|
||||||
|
PROFILE_CPU();
|
||||||
|
___tracy_scoped_zone.Name(*e.Actor->GetName(), e.Actor->GetName().Length());
|
||||||
|
#endif
|
||||||
|
e.Actor->Draw(renderContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SceneRendering::SceneRendering(::Scene* scene)
|
||||||
|
: Scene(scene)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void SceneRendering::Draw(RenderContext& renderContext)
|
void SceneRendering::Draw(RenderContext& renderContext)
|
||||||
{
|
{
|
||||||
// Skip if disabled
|
// Skip if disabled
|
||||||
@@ -248,13 +307,12 @@ void SceneRendering::Draw(RenderContext& renderContext)
|
|||||||
auto& view = renderContext.View;
|
auto& view = renderContext.View;
|
||||||
|
|
||||||
// Draw all visual components
|
// Draw all visual components
|
||||||
const BoundingFrustum frustum = view.CullingFrustum;
|
|
||||||
if (view.IsOfflinePass)
|
if (view.IsOfflinePass)
|
||||||
{
|
{
|
||||||
CullAndDrawOffline(frustum, renderContext, Geometry);
|
Geometry.CullAndDrawOffline(renderContext);
|
||||||
if (view.Pass & DrawPass::GBuffer)
|
if (view.Pass & DrawPass::GBuffer)
|
||||||
{
|
{
|
||||||
CullAndDrawOffline(frustum, renderContext, Common);
|
Common.CullAndDrawOffline(renderContext);
|
||||||
for (int32 i = 0; i < CommonNoCulling.Count(); i++)
|
for (int32 i = 0; i < CommonNoCulling.Count(); i++)
|
||||||
{
|
{
|
||||||
auto actor = CommonNoCulling[i];
|
auto actor = CommonNoCulling[i];
|
||||||
@@ -265,15 +323,21 @@ void SceneRendering::Draw(RenderContext& renderContext)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CullAndDraw(frustum, renderContext, Geometry);
|
Geometry.CullAndDraw(renderContext);
|
||||||
if (view.Pass & DrawPass::GBuffer)
|
if (view.Pass & DrawPass::GBuffer)
|
||||||
{
|
{
|
||||||
CullAndDraw(frustum, renderContext, Common);
|
Common.CullAndDraw(renderContext);
|
||||||
for (int32 i = 0; i < CommonNoCulling.Count(); i++)
|
for (int32 i = 0; i < CommonNoCulling.Count(); i++)
|
||||||
{
|
{
|
||||||
auto actor = CommonNoCulling[i];
|
auto actor = CommonNoCulling[i];
|
||||||
if (view.RenderLayersMask.HasLayer(actor->GetLayer()))
|
if (view.RenderLayersMask.HasLayer(actor->GetLayer()))
|
||||||
|
{
|
||||||
|
#if SCENE_RENDERING_USE_PROFILER
|
||||||
|
PROFILE_CPU();
|
||||||
|
___tracy_scoped_zone.Name(*actor->GetName(), actor->GetName().Length());
|
||||||
|
#endif
|
||||||
actor->Draw(renderContext);
|
actor->Draw(renderContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,6 +358,9 @@ void SceneRendering::Draw(RenderContext& renderContext)
|
|||||||
|
|
||||||
void SceneRendering::CollectPostFxVolumes(RenderContext& renderContext)
|
void SceneRendering::CollectPostFxVolumes(RenderContext& renderContext)
|
||||||
{
|
{
|
||||||
|
#if SCENE_RENDERING_USE_PROFILER
|
||||||
|
PROFILE_CPU();
|
||||||
|
#endif
|
||||||
for (int32 i = 0; i < PostFxProviders.Count(); i++)
|
for (int32 i = 0; i < PostFxProviders.Count(); i++)
|
||||||
{
|
{
|
||||||
PostFxProviders[i]->Collect(renderContext);
|
PostFxProviders[i]->Collect(renderContext);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "Engine/Core/Delegate.h"
|
#include "Engine/Core/Delegate.h"
|
||||||
#include "Engine/Core/Collections/Array.h"
|
#include "Engine/Core/Collections/Array.h"
|
||||||
|
#include "Engine/Core/Math/BoundingSphere.h"
|
||||||
|
#include "Engine/Level/Actor.h"
|
||||||
#include "Engine/Level/Types.h"
|
#include "Engine/Level/Types.h"
|
||||||
|
|
||||||
class SceneRenderTask;
|
class SceneRenderTask;
|
||||||
@@ -14,7 +16,7 @@ struct RenderView;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interface for actors that can override the default rendering settings (eg. PostFxVolume actor).
|
/// Interface for actors that can override the default rendering settings (eg. PostFxVolume actor).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class IPostFxSettingsProvider
|
class FLAXENGINE_API IPostFxSettingsProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -35,24 +37,37 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scene rendering helper subsystem that boosts the level rendering by providing efficient objects cache and culling implementation.
|
/// Scene rendering helper subsystem that boosts the level rendering by providing efficient objects cache and culling implementation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class SceneRendering
|
class FLAXENGINE_API SceneRendering
|
||||||
{
|
{
|
||||||
friend Scene;
|
friend Scene;
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
typedef Function<void(RenderView&)> PhysicsDebugCallback;
|
typedef Function<void(RenderView&)> PhysicsDebugCallback;
|
||||||
|
friend class ViewportIconsRendererService;
|
||||||
#endif
|
#endif
|
||||||
|
struct DrawEntry
|
||||||
|
{
|
||||||
|
Actor* Actor;
|
||||||
|
uint32 LayerMask;
|
||||||
|
BoundingSphere Bounds;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DrawEntries
|
||||||
|
{
|
||||||
|
Array<DrawEntry> 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);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Private data
|
|
||||||
Scene* Scene;
|
Scene* Scene;
|
||||||
|
DrawEntries Geometry;
|
||||||
public:
|
DrawEntries Common;
|
||||||
|
|
||||||
// Things to draw
|
|
||||||
Array<Actor*> Geometry;
|
|
||||||
Array<Actor*> Common;
|
|
||||||
Array<Actor*> CommonNoCulling;
|
Array<Actor*> CommonNoCulling;
|
||||||
Array<IPostFxSettingsProvider*> PostFxProviders;
|
Array<IPostFxSettingsProvider*> PostFxProviders;
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
@@ -83,24 +98,36 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FORCE_INLINE void AddGeometry(Actor* obj)
|
FORCE_INLINE int32 AddGeometry(Actor* obj)
|
||||||
{
|
{
|
||||||
Geometry.Add(obj);
|
return Geometry.Add(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE void RemoveGeometry(Actor* obj)
|
FORCE_INLINE void UpdateGeometry(Actor* obj, int32 key)
|
||||||
{
|
{
|
||||||
Geometry.Remove(obj);
|
Geometry.Update(obj, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE void AddCommon(Actor* obj)
|
FORCE_INLINE void RemoveGeometry(Actor* obj, int32& key)
|
||||||
{
|
{
|
||||||
Common.Add(obj);
|
Geometry.Remove(obj, key);
|
||||||
|
key = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE void RemoveCommon(Actor* obj)
|
FORCE_INLINE int32 AddCommon(Actor* obj)
|
||||||
{
|
{
|
||||||
Common.Remove(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)
|
FORCE_INLINE void AddCommonNoCulling(Actor* obj)
|
||||||
|
|||||||
@@ -311,6 +311,8 @@ void ParticleEffect::UpdateBounds()
|
|||||||
|
|
||||||
_box = bounds;
|
_box = bounds;
|
||||||
BoundingSphere::FromBox(bounds, _sphere);
|
BoundingSphere::FromBox(bounds, _sphere);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleEffect::Sync()
|
void ParticleEffect::Sync()
|
||||||
@@ -515,6 +517,12 @@ void ParticleEffect::OnDebugDrawSelected()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void ParticleEffect::OnLayerChanged()
|
||||||
|
{
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
|
}
|
||||||
|
|
||||||
void ParticleEffect::Serialize(SerializeStream& stream, const void* otherObj)
|
void ParticleEffect::Serialize(SerializeStream& stream, const void* otherObj)
|
||||||
{
|
{
|
||||||
// Base
|
// Base
|
||||||
@@ -691,7 +699,7 @@ void ParticleEffect::EndPlay()
|
|||||||
void ParticleEffect::OnEnable()
|
void ParticleEffect::OnEnable()
|
||||||
{
|
{
|
||||||
GetScene()->Ticking.Update.AddTick<ParticleEffect, &ParticleEffect::Update>(this);
|
GetScene()->Ticking.Update.AddTick<ParticleEffect, &ParticleEffect::Update>(this);
|
||||||
GetSceneRendering()->AddGeometry(this);
|
_sceneRenderingKey = GetSceneRendering()->AddGeometry(this);
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
GetSceneRendering()->AddViewportIcon(this);
|
GetSceneRendering()->AddViewportIcon(this);
|
||||||
GetScene()->Ticking.Update.AddTickExecuteInEditor<ParticleEffect, &ParticleEffect::UpdateExecuteInEditor>(this);
|
GetScene()->Ticking.Update.AddTickExecuteInEditor<ParticleEffect, &ParticleEffect::UpdateExecuteInEditor>(this);
|
||||||
@@ -707,7 +715,7 @@ void ParticleEffect::OnDisable()
|
|||||||
GetScene()->Ticking.Update.RemoveTickExecuteInEditor(this);
|
GetScene()->Ticking.Update.RemoveTickExecuteInEditor(this);
|
||||||
GetSceneRendering()->RemoveViewportIcon(this);
|
GetSceneRendering()->RemoveViewportIcon(this);
|
||||||
#endif
|
#endif
|
||||||
GetSceneRendering()->RemoveGeometry(this);
|
GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey);
|
||||||
GetScene()->Ticking.Update.RemoveTick(this);
|
GetScene()->Ticking.Update.RemoveTick(this);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ private:
|
|||||||
uint64 _lastUpdateFrame;
|
uint64 _lastUpdateFrame;
|
||||||
float _lastMinDstSqr;
|
float _lastMinDstSqr;
|
||||||
Matrix _world;
|
Matrix _world;
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
uint32 _parametersVersion = 0; // Version number for _parameters to be in sync with Instance.ParametersVersion
|
uint32 _parametersVersion = 0; // Version number for _parameters to be in sync with Instance.ParametersVersion
|
||||||
Array<ParticleEffectParameter> _parameters; // Cached for scripting API
|
Array<ParticleEffectParameter> _parameters; // Cached for scripting API
|
||||||
Array<ParameterOverride> _parametersOverrides; // Cached parameter modifications to be applied to the parameters
|
Array<ParameterOverride> _parametersOverrides; // Cached parameter modifications to be applied to the parameters
|
||||||
@@ -388,6 +389,7 @@ public:
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
void OnDebugDrawSelected() override;
|
void OnDebugDrawSelected() override;
|
||||||
#endif
|
#endif
|
||||||
|
void OnLayerChanged() override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ void Terrain::UpdateBounds()
|
|||||||
BoundingBox::Merge(_box, patch->_bounds, _box);
|
BoundingBox::Merge(_box, patch->_bounds, _box);
|
||||||
}
|
}
|
||||||
BoundingSphere::FromBox(_box, _sphere);
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terrain::CacheNeighbors()
|
void Terrain::CacheNeighbors()
|
||||||
@@ -752,7 +754,7 @@ RigidBody* Terrain::GetAttachedRigidBody() const
|
|||||||
|
|
||||||
void Terrain::OnEnable()
|
void Terrain::OnEnable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->AddGeometry(this);
|
_sceneRenderingKey = GetSceneRendering()->AddGeometry(this);
|
||||||
#if TERRAIN_USE_PHYSICS_DEBUG
|
#if TERRAIN_USE_PHYSICS_DEBUG
|
||||||
GetSceneRendering()->AddPhysicsDebug<Terrain, &Terrain::DrawPhysicsDebug>(this);
|
GetSceneRendering()->AddPhysicsDebug<Terrain, &Terrain::DrawPhysicsDebug>(this);
|
||||||
#endif
|
#endif
|
||||||
@@ -763,7 +765,7 @@ void Terrain::OnEnable()
|
|||||||
|
|
||||||
void Terrain::OnDisable()
|
void Terrain::OnDisable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->RemoveGeometry(this);
|
GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey);
|
||||||
#if TERRAIN_USE_PHYSICS_DEBUG
|
#if TERRAIN_USE_PHYSICS_DEBUG
|
||||||
GetSceneRendering()->RemovePhysicsDebug<Terrain, &Terrain::DrawPhysicsDebug>(this);
|
GetSceneRendering()->RemovePhysicsDebug<Terrain, &Terrain::DrawPhysicsDebug>(this);
|
||||||
#endif
|
#endif
|
||||||
@@ -803,6 +805,8 @@ void Terrain::OnLayerChanged()
|
|||||||
Actor::OnLayerChanged();
|
Actor::OnLayerChanged();
|
||||||
|
|
||||||
UpdateLayerBits();
|
UpdateLayerBits();
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terrain::OnActiveInTreeChanged()
|
void Terrain::OnActiveInTreeChanged()
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ private:
|
|||||||
char _collisionLod;
|
char _collisionLod;
|
||||||
byte _lodCount;
|
byte _lodCount;
|
||||||
uint16 _chunkSize;
|
uint16 _chunkSize;
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
float _scaleInLightmap;
|
float _scaleInLightmap;
|
||||||
float _lodDistribution;
|
float _lodDistribution;
|
||||||
Vector3 _boundsExtent;
|
Vector3 _boundsExtent;
|
||||||
@@ -444,6 +445,7 @@ public:
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
void OnDebugDrawSelected() override;
|
void OnDebugDrawSelected() override;
|
||||||
#endif
|
#endif
|
||||||
|
void OnLayerChanged() override;
|
||||||
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
@@ -455,7 +457,6 @@ protected:
|
|||||||
void OnEnable() override;
|
void OnEnable() override;
|
||||||
void OnDisable() override;
|
void OnDisable() override;
|
||||||
void OnTransformChanged() override;
|
void OnTransformChanged() override;
|
||||||
void OnLayerChanged() override;
|
|
||||||
void OnActiveInTreeChanged() override;
|
void OnActiveInTreeChanged() override;
|
||||||
void BeginPlay(SceneBeginData* data) override;
|
void BeginPlay(SceneBeginData* data) override;
|
||||||
void EndPlay() override;
|
void EndPlay() override;
|
||||||
|
|||||||
@@ -170,6 +170,12 @@ void SpriteRender::Deserialize(DeserializeStream& stream, ISerializeModifier* mo
|
|||||||
_paramColor->SetValue(_color);
|
_paramColor->SetValue(_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpriteRender::OnLayerChanged()
|
||||||
|
{
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
|
}
|
||||||
|
|
||||||
void SpriteRender::OnEndPlay()
|
void SpriteRender::OnEndPlay()
|
||||||
{
|
{
|
||||||
// Base
|
// Base
|
||||||
@@ -187,7 +193,7 @@ void SpriteRender::OnEndPlay()
|
|||||||
|
|
||||||
void SpriteRender::OnEnable()
|
void SpriteRender::OnEnable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->AddGeometry(this);
|
_sceneRenderingKey = GetSceneRendering()->AddGeometry(this);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnEnable();
|
Actor::OnEnable();
|
||||||
@@ -195,7 +201,7 @@ void SpriteRender::OnEnable()
|
|||||||
|
|
||||||
void SpriteRender::OnDisable()
|
void SpriteRender::OnDisable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->RemoveGeometry(this);
|
GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnDisable();
|
Actor::OnDisable();
|
||||||
@@ -211,4 +217,6 @@ void SpriteRender::OnTransformChanged()
|
|||||||
_transform.GetWorld(world);
|
_transform.GetWorld(world);
|
||||||
BoundingSphere::Transform(localSphere, world, _sphere);
|
BoundingSphere::Transform(localSphere, world, _sphere);
|
||||||
BoundingBox::FromSphere(_sphere, _box);
|
BoundingBox::FromSphere(_sphere, _box);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ private:
|
|||||||
MaterialParameter* _paramImageMAD = nullptr;
|
MaterialParameter* _paramImageMAD = nullptr;
|
||||||
MaterialParameter* _paramColor = nullptr;
|
MaterialParameter* _paramColor = nullptr;
|
||||||
AssetReference<Asset> _quadModel;
|
AssetReference<Asset> _quadModel;
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -97,6 +98,7 @@ public:
|
|||||||
void DrawGeneric(RenderContext& renderContext) override;
|
void DrawGeneric(RenderContext& renderContext) override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
|
void OnLayerChanged() override;
|
||||||
void OnEndPlay() override;
|
void OnEndPlay() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -329,6 +329,8 @@ void TextRender::UpdateLayout()
|
|||||||
_localBox = box;
|
_localBox = box;
|
||||||
BoundingBox::Transform(_localBox, _world, _box);
|
BoundingBox::Transform(_localBox, _world, _box);
|
||||||
BoundingSphere::FromBox(_box, _sphere);
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextRender::HasContentLoaded() const
|
bool TextRender::HasContentLoaded() const
|
||||||
@@ -421,6 +423,12 @@ void TextRender::OnDebugDrawSelected()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void TextRender::OnLayerChanged()
|
||||||
|
{
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
|
}
|
||||||
|
|
||||||
bool TextRender::IntersectsItself(const Ray& ray, float& distance, Vector3& normal)
|
bool TextRender::IntersectsItself(const Ray& ray, float& distance, Vector3& normal)
|
||||||
{
|
{
|
||||||
#if USE_PRECISE_MESH_INTERSECTS
|
#if USE_PRECISE_MESH_INTERSECTS
|
||||||
@@ -480,8 +488,6 @@ void TextRender::Deserialize(DeserializeStream& stream, ISerializeModifier* modi
|
|||||||
|
|
||||||
void TextRender::OnEnable()
|
void TextRender::OnEnable()
|
||||||
{
|
{
|
||||||
GetSceneRendering()->AddGeometry(this);
|
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnEnable();
|
Actor::OnEnable();
|
||||||
|
|
||||||
@@ -489,6 +495,7 @@ void TextRender::OnEnable()
|
|||||||
{
|
{
|
||||||
UpdateLayout();
|
UpdateLayout();
|
||||||
}
|
}
|
||||||
|
_sceneRenderingKey = GetSceneRendering()->AddGeometry(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextRender::OnDisable()
|
void TextRender::OnDisable()
|
||||||
@@ -498,7 +505,7 @@ void TextRender::OnDisable()
|
|||||||
_isLocalized = false;
|
_isLocalized = false;
|
||||||
Localization::LocalizationChanged.Unbind<TextRender, &TextRender::UpdateLayout>(this);
|
Localization::LocalizationChanged.Unbind<TextRender, &TextRender::UpdateLayout>(this);
|
||||||
}
|
}
|
||||||
GetSceneRendering()->RemoveGeometry(this);
|
GetSceneRendering()->RemoveGeometry(this, _sceneRenderingKey);
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
Actor::OnDisable();
|
Actor::OnDisable();
|
||||||
@@ -512,4 +519,6 @@ void TextRender::OnTransformChanged()
|
|||||||
_transform.GetWorld(_world);
|
_transform.GetWorld(_world);
|
||||||
BoundingBox::Transform(_localBox, _world, _box);
|
BoundingBox::Transform(_localBox, _world, _box);
|
||||||
BoundingSphere::FromBox(_box, _sphere);
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
if (_sceneRenderingKey != -1)
|
||||||
|
GetSceneRendering()->UpdateGeometry(this, _sceneRenderingKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ private:
|
|||||||
Color _color;
|
Color _color;
|
||||||
TextLayoutOptions _layoutOptions;
|
TextLayoutOptions _layoutOptions;
|
||||||
int32 _size;
|
int32 _size;
|
||||||
|
int32 _sceneRenderingKey = -1;
|
||||||
|
|
||||||
BoundingBox _localBox;
|
BoundingBox _localBox;
|
||||||
Matrix _world;
|
Matrix _world;
|
||||||
@@ -169,6 +170,7 @@ public:
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
void OnDebugDrawSelected() override;
|
void OnDebugDrawSelected() override;
|
||||||
#endif
|
#endif
|
||||||
|
void OnLayerChanged() override;
|
||||||
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
|
|||||||
Reference in New Issue
Block a user