diff --git a/enginecustom/imgui.ini b/enginecustom/imgui.ini index 007bf98..e8a659c 100644 --- a/enginecustom/imgui.ini +++ b/enginecustom/imgui.ini @@ -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 diff --git a/enginecustom/src/inc/system/application_class.h b/enginecustom/src/inc/system/application_class.h index ab93d44..d0e8c81 100644 --- a/enginecustom/src/inc/system/application_class.h +++ b/enginecustom/src/inc/system/application_class.h @@ -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 culling_active_; std::mutex objects_mutex_; + + // Thread de culling pour les shadows + std::thread culling_sun_thread_; + std::atomic culling_sun_active_; + std::mutex objects_sun_mutex_; std::mutex terrain_mutex_; std::vector> terrain_generation_data_; @@ -715,6 +725,7 @@ private : // ------------------------------------------------- // frustum frustum_culling_; + frustum sun_culling_; int render_count_; float frustum_culling_tolerance_ = 5.f; diff --git a/enginecustom/src/inc/system/ecs/components/render_component.h b/enginecustom/src/inc/system/ecs/components/render_component.h index d6e5347..e82c477 100644 --- a/enginecustom/src/inc/system/ecs/components/render_component.h +++ b/enginecustom/src/inc/system/ecs/components/render_component.h @@ -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 diff --git a/enginecustom/src/src/system/application_class.cpp b/enginecustom/src/src/system/application_class.cpp index bd6a989..dc734aa 100644 --- a/enginecustom/src/src/system/application_class.cpp +++ b/enginecustom/src/src/system/application_class.cpp @@ -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(); + + // 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(); + 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 é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é"); @@ -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 diff --git a/x64/Debug/config.txt b/x64/Debug/config.txt index 72420a8..0894623 100644 --- a/x64/Debug/config.txt +++ b/x64/Debug/config.txt @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da6f91d4b7f6e40d04417930009ad66ebbf05fbfee58e6db0be9f6ceb84cf801 +oid sha256:304154dad9f9acd2c53dcaf83259a04e33671157d5745b925390cf5ec1afb3d1 size 9 diff --git a/x64/Release/config.txt b/x64/Release/config.txt index 72420a8..0894623 100644 --- a/x64/Release/config.txt +++ b/x64/Release/config.txt @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da6f91d4b7f6e40d04417930009ad66ebbf05fbfee58e6db0be9f6ceb84cf801 +oid sha256:304154dad9f9acd2c53dcaf83259a04e33671157d5745b925390cf5ec1afb3d1 size 9