Minor - Ajoute le culling par la lumière du soleil - V14.7.0

Implémente un système de culling basé sur la position de la lumière du soleil pour améliorer les performances du rendu des ombres.

Crée un thread dédié au culling des objets non visibles par la lumière du soleil.
Ajoute une structure de frustum spécifique au culling par la lumière du soleil.
Modifie le RenderComponent pour suivre si un objet est visible par la lumière du soleil.
This commit is contained in:
2025-10-14 18:45:57 +02:00
parent 37bba7866c
commit 5ab98c9a0a
6 changed files with 85 additions and 14 deletions

View File

@@ -27,7 +27,7 @@ Collapsed=0
DockId=0x0000000B,0 DockId=0x0000000B,0
[Window][Terrain] [Window][Terrain]
Pos=236,19 Pos=0,19
Size=266,774 Size=266,774
Collapsed=0 Collapsed=0
DockId=0x00000007,0 DockId=0x00000007,0

View File

@@ -381,7 +381,7 @@ public:
* Construct the frustum for culling. * Construct the frustum for culling.
* This function will calculate the frustum based on the current camera view and projection matrices. * This function will calculate the frustum based on the current camera view and projection matrices.
*/ */
void construct_frustum(); void construct_frustum(frustum& frustum, float screen_depth, XMMATRIX projectionMatrix, XMMATRIX viewMatrix);
/** /**
* Get the number of objects rendered in the current frame. * Get the number of objects rendered in the current frame.
@@ -582,6 +582,11 @@ private:
*/ */
void culling_thread_function(); void culling_thread_function();
/**
* A thread function to handle culling of objects no visible by sun light.
*/
void sun_culling_thread_function();
/** /**
* Create the skysphere entity. * Create the skysphere entity.
*/ */
@@ -596,6 +601,11 @@ private :
std::thread culling_thread_; std::thread culling_thread_;
std::atomic<bool> culling_active_; std::atomic<bool> culling_active_;
std::mutex objects_mutex_; std::mutex objects_mutex_;
// Thread de culling pour les shadows
std::thread culling_sun_thread_;
std::atomic<bool> culling_sun_active_;
std::mutex objects_sun_mutex_;
std::mutex terrain_mutex_; std::mutex terrain_mutex_;
std::vector<std::tuple<float, float, float, std::string, int>> terrain_generation_data_; std::vector<std::tuple<float, float, float, std::string, int>> terrain_generation_data_;
@@ -715,6 +725,7 @@ private :
// ------------------------------------------------- // // ------------------------------------------------- //
frustum frustum_culling_; frustum frustum_culling_;
frustum sun_culling_;
int render_count_; int render_count_;
float frustum_culling_tolerance_ = 5.f; float frustum_culling_tolerance_ = 5.f;

View File

@@ -190,6 +190,15 @@ public:
} }
} }
void RenderOnlyGeometryFromSun(ID3D11DeviceContext* ctx)
{
if (m_model && m_is_in_sun_pov) m_model->Render(ctx);
}
void set_is_sun_visible(bool v) { m_is_in_sun_pov = v; }
bool is_in_sun_pov() const { return m_is_in_sun_pov; }
/** /**
* Serialize the RenderComponent's state to a string. * Serialize the RenderComponent's state to a string.
* This method is useful for saving the component's state or debugging. * This method is useful for saving the component's state or debugging.
@@ -477,6 +486,7 @@ private:
ID3D11DeviceContext* context; ID3D11DeviceContext* context;
TextureContainer texture_container_buffer; TextureContainer texture_container_buffer;
bool is_shadow_caster_ = true; bool is_shadow_caster_ = true;
bool m_is_in_sun_pov;
}; };
} // namespace ecs } // namespace ecs

View File

@@ -419,8 +419,6 @@ bool application_class::initialize(int screenWidth, int screenHeight, HWND hwnd,
physics_thread_ = std::thread(&application_class::physics_thread_function, this); physics_thread_ = std::thread(&application_class::physics_thread_function, this);
//ConstructSkyboxWithPlanes();
culling_active_ = true; culling_active_ = true;
culling_thread_ = std::thread(&application_class::culling_thread_function, this); culling_thread_ = std::thread(&application_class::culling_thread_function, this);
@@ -451,6 +449,10 @@ bool application_class::initialize(int screenWidth, int screenHeight, HWND hwnd,
// create the render textures for the shadow map // create the render textures for the shadow map
shadow_texture_ = new render_texture_class(); shadow_texture_ = new render_texture_class();
result = shadow_texture_->Initialize(direct_3d_->get_device(), 2048, 2048, screen_depth, screen_near, 1); result = shadow_texture_->Initialize(direct_3d_->get_device(), 2048, 2048, screen_depth, screen_near, 1);
culling_sun_active_ = true;
culling_sun_thread_ = std::thread(&application_class::sun_culling_thread_function, this);
R_LOG_ERROR(result, "Could not initialize the shadow render texture object") R_LOG_ERROR(result, "Could not initialize the shadow render texture object")
} }
@@ -965,7 +967,7 @@ bool application_class::render_shadow_map()
// Render the geometry of the model // Render the geometry of the model
render_cpnt->Render(direct_3d_->get_device_context()); render_cpnt->RenderOnlyGeometryFromSun(direct_3d_->get_device_context());
// render using the depth shader to create the shadow map // render using the depth shader to create the shadow map
result = shader_manager_->render_depth_shader( result = shader_manager_->render_depth_shader(
direct_3d_->get_device_context(), direct_3d_->get_device_context(),
@@ -1639,6 +1641,53 @@ void application_class::set_screen_width(int width)
screen_width_ = width; screen_width_ = width;
} }
void application_class::sun_culling_thread_function()
{
LOG_INFO("Sun culling thread started");
XMMATRIX viewMatrix = XMMATRIX();
XMMATRIX projectionMatrix = XMMATRIX();
shadow_texture_->GetProjectionMatrix(projectionMatrix);
while (culling_sun_active_)
{
construct_frustum(
sun_culling_,
screen_depth,
projectionMatrix,
sun_camera_->get_view_matrix(viewMatrix)
);
auto all_entity = entity_manager_->GetAllEntities();
for (auto& entity : all_entity)
{
auto render = entity->GetComponent<ecs::RenderComponent>();
// skip if no render component
if (!render) continue;
// set visible to false if not a shadow caster
if (!render->IsShadowCaster()) render->set_is_sun_visible(false);
auto transform = entity->GetComponent<ecs::TransformComponent>();
if (!transform) continue;
XMVECTOR position = transform->GetPosition();
float x = XMVectorGetX(position);
float y = XMVectorGetY(position);
float z = XMVectorGetZ(position);
XMVECTOR scale = transform->GetScale();
float radius = max(max(XMVectorGetX(scale), XMVectorGetY(scale)), XMVectorGetZ(scale));
bool visible = sun_culling_.CheckCube(x, y, z, radius, get_frustum_tolerance());
render->set_is_sun_visible(visible);
}
// Pause pour <20>viter de surcharger le CPU ~ 30 Hz
std::this_thread::sleep_for(std::chrono::milliseconds(33));
}
}
void application_class::culling_thread_function() void application_class::culling_thread_function()
{ {
LOG_INFO("Thread de culling d<>marr<72>"); LOG_INFO("Thread de culling d<>marr<72>");
@@ -1646,7 +1695,12 @@ void application_class::culling_thread_function()
while (culling_active_) while (culling_active_)
{ {
// Construction du frustum une fois par cycle de culling // Construction du frustum une fois par cycle de culling
construct_frustum(); construct_frustum(
frustum_culling_,
screen_depth,
direct_3d_->get_projection_matrix(),
active_camera_->get_view_matrix(base_view_matrix_)
);
// Traitement des files d'objets normaux (sans la skybox) // Traitement des files d'objets normaux (sans la skybox)
auto all_entity = entity_manager_->GetAllEntities(); auto all_entity = entity_manager_->GetAllEntities();
@@ -1734,13 +1788,9 @@ bool application_class::render_pass(XMFLOAT4* diffuse, XMFLOAT4* position, XMFLO
R_TRUE R_TRUE
} }
void application_class::construct_frustum() void application_class::construct_frustum(frustum& frustum_culling, float screen_depth, XMMATRIX projectionMatrix, XMMATRIX viewMatrix )
{ {
XMMATRIX projectionMatrix = direct_3d_->get_projection_matrix(); frustum_culling.ConstructFrustum(screen_depth, projectionMatrix, viewMatrix);
XMMATRIX viewMatrix;
active_camera_->get_view_matrix(viewMatrix);
frustum_culling_.ConstructFrustum(screen_depth, projectionMatrix, viewMatrix);
} }
// Update the position of the skybox based on the camera position // Update the position of the skybox based on the camera position

BIN
x64/Debug/config.txt (Stored with Git LFS)

Binary file not shown.

BIN
x64/Release/config.txt (Stored with Git LFS)

Binary file not shown.