Skip to content

Commit a7027c6

Browse files
author
Adrien GIVRY
committed
Light culling and draw frustum
Light culling now works. It is a camera option. When a camera is selected its frustum is now drawn
1 parent 8ddc040 commit a7027c6

32 files changed

Lines changed: 1071 additions & 184 deletions

File tree

Sources/Overload/OvCore/include/OvCore/ECS/Components/CCamera.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ namespace OvCore::ECS::Components
5959
*/
6060
void SetClearColor(const OvMaths::FVector3& p_clearColor);
6161

62+
/**
63+
* Defines if the camera should apply frustum geometry culling in rendering
64+
* @param p_enable
65+
*/
66+
void SetFrustumGeometryCulling(bool p_enable);
67+
68+
/**
69+
* Defines if the camera should apply frustum light culling in rendering
70+
* @param p_enable
71+
*/
72+
void SetFrustumLightCulling(bool p_enable);
73+
6274
/**
6375
* Returns the fov of the camera
6476
*/
@@ -79,6 +91,16 @@ namespace OvCore::ECS::Components
7991
*/
8092
const OvMaths::FVector3& GetClearColor() const;
8193

94+
/**
95+
* Returns true if the frustum geometry culling is enabled
96+
*/
97+
bool HasFrustumGeometryCulling() const;
98+
99+
/**
100+
* Returns true if the frustum light culling is enabled
101+
*/
102+
bool HasFrustumLightCulling() const;
103+
82104
/**
83105
* Returns the OvRendering camera instance attached to this component
84106
*/

Sources/Overload/OvCore/include/OvCore/ECS/Components/CModelRenderer.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ namespace OvCore::ECS::Components
2121
class API_OVCORE CModelRenderer : public AComponent
2222
{
2323
public:
24+
/**
25+
* Defines how the model renderer bounding sphere should be interpreted
26+
*/
27+
enum class EFrustumBehaviour
28+
{
29+
DISABLED = 0,
30+
CULL_MODEL = 1,
31+
CULL_MESHES = 2,
32+
CULL_CUSTOM = 3
33+
};
34+
2435
/**
2536
* Constructor
2637
* @param p_owner
@@ -43,6 +54,28 @@ namespace OvCore::ECS::Components
4354
*/
4455
OvRendering::Resources::Model* GetModel() const;
4556

57+
/**
58+
* Sets a bounding mode
59+
* @param p_boundingMode
60+
*/
61+
void SetFrustumBehaviour(EFrustumBehaviour p_boundingMode);
62+
63+
/**
64+
* Returns the current bounding mode
65+
*/
66+
EFrustumBehaviour GetFrustumBehaviour() const;
67+
68+
/**
69+
* Returns the custom bounding sphere
70+
*/
71+
const OvRendering::Geometry::BoundingSphere& GetCustomBoundingSphere() const;
72+
73+
/**
74+
* Sets the custom bounding sphere
75+
* @param p_boundingSphere
76+
*/
77+
void SetCustomBoundingSphere(const OvRendering::Geometry::BoundingSphere& p_boundingSphere);
78+
4679
/**
4780
* Serialize the component
4881
* @param p_doc
@@ -66,5 +99,7 @@ namespace OvCore::ECS::Components
6699
private:
67100
OvRendering::Resources::Model* m_model = nullptr;
68101
OvTools::Eventing::Event<> m_modelChangedEvent;
102+
OvRendering::Geometry::BoundingSphere m_customBoundingSphere = { {}, 1.0f };
103+
EFrustumBehaviour m_frustumBehaviour = EFrustumBehaviour::CULL_MODEL;
69104
};
70105
}

Sources/Overload/OvCore/include/OvCore/ECS/Renderer.h

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,31 +52,60 @@ namespace OvCore::ECS
5252
/**
5353
* Fill the given FMatrix4 vector with lights information
5454
* @param p_scene
55-
* @param p_out
5655
*/
57-
void FindLightMatrices(const OvCore::SceneSystem::Scene& p_scene, std::vector<OvMaths::FMatrix4>& p_out);
56+
std::vector<OvMaths::FMatrix4> FindLightMatrices(const OvCore::SceneSystem::Scene& p_scene);
57+
58+
/**
59+
* Fill the given FMatrix4 vector with lights information that are inside the frustum
60+
* @param p_scene
61+
* @param p_frustum
62+
*/
63+
std::vector<OvMaths::FMatrix4> FindLightMatricesInFrustum(const OvCore::SceneSystem::Scene& p_scene, const OvRendering::Data::Frustum& p_frustum);
5864

5965
/**
6066
* Draw the given scene using the given default material (optional) if no material found on an actor
6167
* @param p_scene
6268
* @param p_cameraPosition
63-
* @param p_frustum
69+
* @param p_camera
70+
* @param p_customFrustum
6471
* @param p_defaultMaterial
6572
*/
66-
void RenderScene(OvCore::SceneSystem::Scene& p_scene, const OvMaths::FVector3& p_cameraPosition, OvRendering::Data::Frustum const* p_frustum = nullptr, Resources::Material* p_defaultMaterial = nullptr);
73+
void RenderScene
74+
(
75+
OvCore::SceneSystem::Scene& p_scene,
76+
const OvMaths::FVector3& p_cameraPosition,
77+
const OvRendering::LowRenderer::Camera& p_camera,
78+
const OvRendering::Data::Frustum* p_customFrustum = nullptr,
79+
OvCore::Resources::Material* p_defaultMaterial = nullptr
80+
);
6781

6882
/**
69-
* Find every drawables objects in the scene. Sorting order:
70-
* - Opaques (Front to back)
71-
* - Transparents (Back to front)
72-
* @param p_opaques
73-
* @param p_transparents
83+
* Returns opaque and transparents drawables from the scene with frustum culling
7484
* @param p_scene
7585
* @param p_cameraPosition
7686
* @param p_frustum
7787
* @param p_defaultMaterial
7888
*/
79-
void FindAndSortDrawables(OpaqueDrawables& p_opaques, TransparentDrawables& p_transparents, const OvCore::SceneSystem::Scene& p_scene, const OvMaths::FVector3& p_cameraPosition, OvRendering::Data::Frustum const* p_frustum = nullptr, Resources::Material* p_defaultMaterial = nullptr);
89+
std::pair<OpaqueDrawables, TransparentDrawables> FindAndSortFrustumCulledDrawables
90+
(
91+
const OvCore::SceneSystem::Scene& p_scene,
92+
const OvMaths::FVector3& p_cameraPosition,
93+
const OvRendering::Data::Frustum& p_frustum,
94+
OvCore::Resources::Material* p_defaultMaterial
95+
);
96+
97+
/**
98+
* Returns opaque and transparents drawables from the scene
99+
* @param p_scene
100+
* @param p_cameraPosition
101+
* @param p_defaultMaterial
102+
*/
103+
std::pair<OpaqueDrawables, TransparentDrawables> FindAndSortDrawables
104+
(
105+
const OvCore::SceneSystem::Scene& p_scene,
106+
const OvMaths::FVector3& p_cameraPosition,
107+
OvCore::Resources::Material* p_defaultMaterial
108+
);
80109

81110
/**
82111
* Draw a Drawable instance

Sources/Overload/OvCore/src/OvCore/ECS/Components/CCamera.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ void OvCore::ECS::Components::CCamera::SetFar(float p_value)
5050
m_camera.SetFar(p_value);
5151
}
5252

53+
void OvCore::ECS::Components::CCamera::SetFrustumGeometryCulling(bool p_enable)
54+
{
55+
m_camera.SetFrustumGeometryCulling(p_enable);
56+
}
57+
58+
void OvCore::ECS::Components::CCamera::SetFrustumLightCulling(bool p_enable)
59+
{
60+
m_camera.SetFrustumLightCulling(p_enable);
61+
}
62+
5363
float OvCore::ECS::Components::CCamera::GetFov() const
5464
{
5565
return m_camera.GetFov();
@@ -70,11 +80,21 @@ const OvMaths::FVector3 & OvCore::ECS::Components::CCamera::GetClearColor() cons
7080
return m_camera.GetClearColor();
7181
}
7282

83+
bool OvCore::ECS::Components::CCamera::HasFrustumGeometryCulling() const
84+
{
85+
return m_camera.HasFrustumGeometryCulling();
86+
}
87+
7388
void OvCore::ECS::Components::CCamera::SetClearColor(const OvMaths::FVector3 & p_clearColor)
7489
{
7590
m_camera.SetClearColor(p_clearColor);
7691
}
7792

93+
bool OvCore::ECS::Components::CCamera::HasFrustumLightCulling() const
94+
{
95+
return m_camera.HasFrustumLightCulling();
96+
}
97+
7898
OvRendering::LowRenderer::Camera & OvCore::ECS::Components::CCamera::GetCamera()
7999
{
80100
return m_camera;
@@ -86,14 +106,18 @@ void OvCore::ECS::Components::CCamera::OnSerialize(tinyxml2::XMLDocument & p_doc
86106
OvCore::Helpers::Serializer::SerializeFloat(p_doc, p_node, "near", m_camera.GetNear());
87107
OvCore::Helpers::Serializer::SerializeFloat(p_doc, p_node, "far", m_camera.GetFar());
88108
OvCore::Helpers::Serializer::SerializeVec3(p_doc, p_node, "clear_color", m_camera.GetClearColor());
109+
OvCore::Helpers::Serializer::SerializeBoolean(p_doc, p_node, "frustum_geometry_culling", m_camera.HasFrustumGeometryCulling());
110+
OvCore::Helpers::Serializer::SerializeBoolean(p_doc, p_node, "frustum_light_culling", m_camera.HasFrustumLightCulling());
89111
}
90112

91113
void OvCore::ECS::Components::CCamera::OnDeserialize(tinyxml2::XMLDocument & p_doc, tinyxml2::XMLNode * p_node)
92114
{
93115
m_camera.SetFov(OvCore::Helpers::Serializer::DeserializeFloat(p_doc, p_node, "fov"));
94116
m_camera.SetNear(OvCore::Helpers::Serializer::DeserializeFloat(p_doc, p_node, "near"));
95117
m_camera.SetFar(OvCore::Helpers::Serializer::DeserializeFloat(p_doc, p_node, "far"));
96-
SetClearColor(OvCore::Helpers::Serializer::DeserializeVec3(p_doc, p_node, "clear_color"));
118+
m_camera.SetClearColor(OvCore::Helpers::Serializer::DeserializeVec3(p_doc, p_node, "clear_color"));
119+
m_camera.SetFrustumGeometryCulling(OvCore::Helpers::Serializer::DeserializeBoolean(p_doc, p_node, "frustum_geometry_culling"));
120+
m_camera.SetFrustumLightCulling(OvCore::Helpers::Serializer::DeserializeBoolean(p_doc, p_node, "frustum_light_culling"));
97121
}
98122

99123
void OvCore::ECS::Components::CCamera::OnInspector(OvUI::Internal::WidgetContainer& p_root)
@@ -102,4 +126,6 @@ void OvCore::ECS::Components::CCamera::OnInspector(OvUI::Internal::WidgetContain
102126
OvCore::Helpers::GUIDrawer::DrawScalar<float>(p_root, "Near", std::bind(&CCamera::GetNear, this), std::bind(&CCamera::SetNear, this, std::placeholders::_1));
103127
OvCore::Helpers::GUIDrawer::DrawScalar<float>(p_root, "Far", std::bind(&CCamera::GetFar, this), std::bind(&CCamera::SetFar, this, std::placeholders::_1));
104128
OvCore::Helpers::GUIDrawer::DrawColor(p_root, "Clear color", [this]() {return reinterpret_cast<const OvUI::Types::Color&>(GetClearColor()); }, [this](OvUI::Types::Color p_color) { SetClearColor({ p_color.r, p_color.g, p_color.b }); }, false);
129+
OvCore::Helpers::GUIDrawer::DrawBoolean(p_root, "Frustum Geometry Culling", std::bind(&CCamera::HasFrustumGeometryCulling, this), std::bind(&CCamera::SetFrustumGeometryCulling, this, std::placeholders::_1));
130+
OvCore::Helpers::GUIDrawer::DrawBoolean(p_root, "Frustum Light Culling", std::bind(&CCamera::HasFrustumLightCulling, this), std::bind(&CCamera::SetFrustumLightCulling, this, std::placeholders::_1));
105131
}

Sources/Overload/OvCore/src/OvCore/ECS/Components/CModelRenderer.cpp

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
*/
66

77
#include <OvUI/Widgets/Texts/Text.h>
8+
#include <OvUI/Widgets/Texts/TextColored.h>
89
#include <OvUI/Plugins/DDTarget.h>
910
#include <OvUI/Widgets/Visual/Image.h>
11+
#include <OvUI/Widgets/Selection/ComboBox.h>
12+
#include <OvUI/Widgets/Selection/CheckBox.h>
13+
#include <OvUI/Widgets/Drags/DragFloat.h>
1014

1115
#include "OvCore/Global/ServiceLocator.h"
1216
#include "OvCore/ResourceManagement/TextureManager.h"
@@ -41,17 +45,71 @@ OvRendering::Resources::Model * OvCore::ECS::Components::CModelRenderer::GetMode
4145
return m_model;
4246
}
4347

48+
void OvCore::ECS::Components::CModelRenderer::SetFrustumBehaviour(EFrustumBehaviour p_boundingMode)
49+
{
50+
m_frustumBehaviour = p_boundingMode;
51+
}
52+
53+
OvCore::ECS::Components::CModelRenderer::EFrustumBehaviour OvCore::ECS::Components::CModelRenderer::GetFrustumBehaviour() const
54+
{
55+
return m_frustumBehaviour;
56+
}
57+
58+
const OvRendering::Geometry::BoundingSphere& OvCore::ECS::Components::CModelRenderer::GetCustomBoundingSphere() const
59+
{
60+
return m_customBoundingSphere;
61+
}
62+
63+
void OvCore::ECS::Components::CModelRenderer::SetCustomBoundingSphere(const OvRendering::Geometry::BoundingSphere& p_boundingSphere)
64+
{
65+
m_customBoundingSphere = p_boundingSphere;
66+
}
67+
4468
void OvCore::ECS::Components::CModelRenderer::OnSerialize(tinyxml2::XMLDocument & p_doc, tinyxml2::XMLNode * p_node)
4569
{
4670
OvCore::Helpers::Serializer::SerializeModel(p_doc, p_node, "model", m_model);
71+
OvCore::Helpers::Serializer::SerializeInt(p_doc, p_node, "frustum_behaviour", reinterpret_cast<int&>(m_frustumBehaviour));
72+
OvCore::Helpers::Serializer::SerializeVec3(p_doc, p_node, "custom_bounding_sphere_position", m_customBoundingSphere.position);
73+
OvCore::Helpers::Serializer::SerializeFloat(p_doc, p_node, "custom_bounding_sphere_radius", m_customBoundingSphere.radius);
4774
}
4875

4976
void OvCore::ECS::Components::CModelRenderer::OnDeserialize(tinyxml2::XMLDocument & p_doc, tinyxml2::XMLNode* p_node)
5077
{
5178
OvCore::Helpers::Serializer::DeserializeModel(p_doc, p_node, "model", m_model);
79+
OvCore::Helpers::Serializer::DeserializeInt(p_doc, p_node, "frustum_behaviour", reinterpret_cast<int&>(m_frustumBehaviour));
80+
OvCore::Helpers::Serializer::DeserializeVec3(p_doc, p_node, "custom_bounding_sphere_position", m_customBoundingSphere.position);
81+
OvCore::Helpers::Serializer::DeserializeFloat(p_doc, p_node, "custom_bounding_sphere_radius", m_customBoundingSphere.radius);
5282
}
5383

5484
void OvCore::ECS::Components::CModelRenderer::OnInspector(OvUI::Internal::WidgetContainer& p_root)
5585
{
56-
OvCore::Helpers::GUIDrawer::DrawMesh(p_root, "Model", m_model, &m_modelChangedEvent);
86+
using namespace OvCore::Helpers;
87+
88+
GUIDrawer::DrawMesh(p_root, "Model", m_model, &m_modelChangedEvent);
89+
90+
GUIDrawer::CreateTitle(p_root, "Frustum Culling Behaviour");
91+
auto& boundingMode = p_root.CreateWidget<OvUI::Widgets::Selection::ComboBox>(0);
92+
boundingMode.choices.emplace(0, "Disabled");
93+
boundingMode.choices.emplace(1, "Cull model");
94+
boundingMode.choices.emplace(2, "Cull model & sub-meshes");
95+
boundingMode.choices.emplace(3, "Cull custom bounding sphere");
96+
auto& boundingModeDispatcher = boundingMode.AddPlugin<OvUI::Plugins::DataDispatcher<int>>();
97+
boundingModeDispatcher.RegisterReference(reinterpret_cast<int&>(m_frustumBehaviour));
98+
99+
auto& centerLabel = p_root.CreateWidget<OvUI::Widgets::Texts::TextColored>("Bounding Sphere Center", GUIDrawer::TitleColor);
100+
auto& centerWidget = p_root.CreateWidget<OvUI::Widgets::Drags::DragMultipleScalars<float, 3>>(GUIDrawer::GetDataType<float>(), GUIDrawer::_MIN_FLOAT, GUIDrawer::_MAX_FLOAT, 0.f, 0.05f, "", GUIDrawer::GetFormat<float>());
101+
auto& centerDispatcher = centerWidget.AddPlugin<OvUI::Plugins::DataDispatcher<std::array<float, 3>>>();
102+
centerDispatcher.RegisterReference(reinterpret_cast<std::array<float, 3>&>(m_customBoundingSphere.position));
103+
104+
auto& radiusLabel = p_root.CreateWidget<OvUI::Widgets::Texts::TextColored>("Bounding Sphere Radius", GUIDrawer::TitleColor);
105+
auto& radiusWidget = p_root.CreateWidget<OvUI::Widgets::Drags::DragFloat>(0.0f, GUIDrawer::_MAX_FLOAT, 0.f, 0.1f);
106+
auto& radiusDispatcher = radiusWidget.AddPlugin<OvUI::Plugins::DataDispatcher<float>>();
107+
radiusDispatcher.RegisterReference(m_customBoundingSphere.radius);
108+
109+
boundingMode.ValueChangedEvent += [&](int p_choice)
110+
{
111+
centerLabel.enabled = centerWidget.enabled = radiusLabel.enabled = radiusWidget.enabled = p_choice == 3;
112+
};
113+
114+
centerLabel.enabled = centerWidget.enabled = radiusLabel.enabled = radiusWidget.enabled = m_frustumBehaviour == EFrustumBehaviour::CULL_CUSTOM;
57115
}

0 commit comments

Comments
 (0)