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:
@@ -27,7 +27,7 @@ Collapsed=0
|
||||
DockId=0x0000000B,0
|
||||
|
||||
[Window][Terrain]
|
||||
Pos=236,19
|
||||
Pos=0,19
|
||||
Size=266,774
|
||||
Collapsed=0
|
||||
DockId=0x00000007,0
|
||||
|
||||
@@ -381,7 +381,7 @@ public:
|
||||
* Construct the frustum for culling.
|
||||
* 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.
|
||||
@@ -582,6 +582,11 @@ private:
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@@ -596,6 +601,11 @@ private :
|
||||
std::thread culling_thread_;
|
||||
std::atomic<bool> culling_active_;
|
||||
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::vector<std::tuple<float, float, float, std::string, int>> terrain_generation_data_;
|
||||
@@ -715,6 +725,7 @@ private :
|
||||
// ------------------------------------------------- //
|
||||
|
||||
frustum frustum_culling_;
|
||||
frustum sun_culling_;
|
||||
int render_count_;
|
||||
float frustum_culling_tolerance_ = 5.f;
|
||||
|
||||
|
||||
@@ -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.
|
||||
* This method is useful for saving the component's state or debugging.
|
||||
@@ -477,6 +486,7 @@ private:
|
||||
ID3D11DeviceContext* context;
|
||||
TextureContainer texture_container_buffer;
|
||||
bool is_shadow_caster_ = true;
|
||||
bool m_is_in_sun_pov;
|
||||
};
|
||||
|
||||
} // namespace ecs
|
||||
|
||||
@@ -419,8 +419,6 @@ bool application_class::initialize(int screenWidth, int screenHeight, HWND hwnd,
|
||||
|
||||
physics_thread_ = std::thread(&application_class::physics_thread_function, this);
|
||||
|
||||
//ConstructSkyboxWithPlanes();
|
||||
|
||||
culling_active_ = true;
|
||||
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
|
||||
shadow_texture_ = new render_texture_class();
|
||||
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")
|
||||
|
||||
}
|
||||
@@ -965,7 +967,7 @@ bool application_class::render_shadow_map()
|
||||
|
||||
|
||||
// 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
|
||||
result = shader_manager_->render_depth_shader(
|
||||
direct_3d_->get_device_context(),
|
||||
@@ -1639,6 +1641,53 @@ void application_class::set_screen_width(int 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()
|
||||
{
|
||||
LOG_INFO("Thread de culling d<>marr<72>");
|
||||
@@ -1646,7 +1695,12 @@ void application_class::culling_thread_function()
|
||||
while (culling_active_)
|
||||
{
|
||||
// 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)
|
||||
auto all_entity = entity_manager_->GetAllEntities();
|
||||
@@ -1734,13 +1788,9 @@ bool application_class::render_pass(XMFLOAT4* diffuse, XMFLOAT4* position, XMFLO
|
||||
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();
|
||||
XMMATRIX viewMatrix;
|
||||
active_camera_->get_view_matrix(viewMatrix);
|
||||
|
||||
frustum_culling_.ConstructFrustum(screen_depth, projectionMatrix, viewMatrix);
|
||||
frustum_culling.ConstructFrustum(screen_depth, projectionMatrix, viewMatrix);
|
||||
}
|
||||
|
||||
// Update the position of the skybox based on the camera position
|
||||
|
||||
Reference in New Issue
Block a user