@@ -96,6 +96,15 @@ struct LightData {
9696 alignas (4 ) float outerConeAngle; // For spotlights
9797};
9898
99+ struct ShadowUniforms {
100+ alignas (16 ) glm::mat4 view;
101+ alignas (16 ) glm::mat4 proj;
102+ };
103+
104+ struct ShadowPushConstants {
105+ alignas (16 ) glm::mat4 model;
106+ };
107+
99108/* *
100109 * @brief Structure for the uniform buffer object (now without fixed light arrays).
101110 */
@@ -598,15 +607,9 @@ class Renderer {
598607 }
599608 }
600609
601- // Descriptor set deferred update machinery
602- void MarkEntityDescriptorsDirty (Entity* entity);
603- void ProcessDirtyDescriptorsForFrame (uint32_t frameIndex);
604- bool updateDescriptorSetsForFrame (Entity* entity,
605- const std::string& texturePath,
606- bool usePBR,
607- uint32_t frameIndex,
608- bool imagesOnly = false ,
609- bool uboOnly = false );
610+ // Descriptor set deferred update machinery
611+ void MarkEntityDescriptorsDirty (Entity *entity);
612+ void ProcessDirtyDescriptorsForFrame (uint32_t frameIndex);
610613
611614 // Texture aliasing: map canonical IDs to actual loaded keys (e.g., file paths) to avoid duplicates
612615 inline void RegisterTextureAlias (const std::string& aliasId, const std::string& targetId) {
@@ -822,10 +825,16 @@ class Renderer {
822825 .count ());
823826 asBuildRequestStartNs.store (nowNs, std::memory_order_relaxed);
824827 }
825- if (reason)
828+ if (reason) {
826829 lastASBuildRequestReason = reason;
827- else
830+ std::cout << " [AS] Requesting rebuild. Reason: " << reason << std::endl;
831+ } else {
828832 lastASBuildRequestReason = " (no reason)" ;
833+ }
834+
835+ // Explicit requests bypass the freeze to ensure dynamic objects (like balls) are added
836+ asDevOverrideAllowRebuild = true ;
837+
829838 watchdogSuppressed.store (true , std::memory_order_relaxed);
830839 asBuildRequested.store (true , std::memory_order_release);
831840 }
@@ -860,7 +869,7 @@ class Renderer {
860869 * @param lights The light data to upload.
861870 * @return True if successful, false otherwise.
862871 */
863- bool updateLightStorageBuffer (uint32_t frameIndex, const std::vector<ExtractedLight>& lights);
872+ bool updateLightStorageBuffer (uint32_t frameIndex, const std::vector<ExtractedLight>& lights, CameraComponent* camera = nullptr );
864873
865874 /* *
866875 * @brief Update all existing descriptor sets with new light storage buffer references.
@@ -1514,13 +1523,24 @@ class Renderer {
15141523 bool materialCacheValid = false ;
15151524 const Material* cachedMaterial = nullptr ;
15161525 // Derived flags used by render queues and sorting heuristics
1517- bool cachedIsBlended = false ;
1518- bool cachedIsGlass = false ;
1519- bool cachedIsLiquid = false ;
1520- // Material-derived push constants defaults (static per-entity unless material changes)
1521- MaterialProperties cachedMaterialProps{};
1522- };
1523- std::unordered_map<Entity *, EntityResources> entityResources;
1526+ bool cachedIsBlended = false ;
1527+ bool cachedIsGlass = false ;
1528+ bool cachedIsLiquid = false ;
1529+ // Material-derived push constants defaults (static per-entity unless material changes)
1530+ MaterialProperties cachedMaterialProps{};
1531+ };
1532+
1533+ // Cached job for rendering a single entity in a frame
1534+ struct RenderJob
1535+ {
1536+ Entity *entity;
1537+ EntityResources *entityRes;
1538+ MeshResources *meshRes;
1539+ MeshComponent *meshComp;
1540+ TransformComponent *transformComp;
1541+ bool isAlphaMasked;
1542+ };
1543+ std::unordered_map<Entity *, EntityResources> entityResources;
15241544
15251545 // Descriptor pool (declared after entity resources to ensure proper destruction order)
15261546 vk::raii::DescriptorPool descriptorPool = nullptr ;
@@ -1639,7 +1659,7 @@ class Renderer {
16391659 const uint32_t MAX_FRAMES_IN_FLIGHT = 2u ;
16401660
16411661 // --- Performance & diagnostics ---
1642- // CPU-side frustum culling toggle and last-frame stats
1662+ UniformBufferObject frameUboTemplate{};
16431663 bool enableFrustumCulling = true ;
16441664 uint32_t lastCullingVisibleCount = 0 ;
16451665 uint32_t lastCullingCulledCount = 0 ;
@@ -1756,12 +1776,26 @@ class Renderer {
17561776 bool createUniformBuffers (Entity* entity);
17571777 bool createDescriptorPool ();
17581778 bool createDescriptorSets (Entity* entity, const std::string& texturePath, bool usePBR = false );
1759- // Refresh only the currentFrame PBR descriptor set bindings that Forward+ relies on
1760- // (b6 = lights SSBO, b7 = tile headers, b8 = tile indices). Safe to call after
1761- // we've waited on the frame fence at the start of Render().
1762- void refreshPBRForwardPlusBindingsForFrame (uint32_t frameIndex);
1763- bool createCommandBuffers ();
1764- bool createSyncObjects ();
1779+ bool createDescriptorSets (Entity *entity, EntityResources &res, const std::string &texturePath, bool usePBR = false );
1780+ bool updateDescriptorSetsForFrame (Entity *entity,
1781+ const std::string &texturePath,
1782+ bool usePBR,
1783+ uint32_t frameIndex,
1784+ bool imagesOnly = false ,
1785+ bool uboOnly = false );
1786+ bool updateDescriptorSetsForFrame (Entity *entity,
1787+ EntityResources &res,
1788+ const std::string &texturePath,
1789+ bool usePBR,
1790+ uint32_t frameIndex,
1791+ bool imagesOnly = false ,
1792+ bool uboOnly = false );
1793+ // Refresh only the currentFrame PBR descriptor set bindings that Forward+ relies on
1794+ // (b6 = lights SSBO, b7 = tile headers, b8 = tile indices). Safe to call after
1795+ // we've waited on the frame fence at the start of Render().
1796+ void refreshPBRForwardPlusBindingsForFrame (uint32_t frameIndex);
1797+ bool createCommandBuffers ();
1798+ bool createSyncObjects ();
17651799
17661800 void cleanupSwapChain ();
17671801
@@ -1772,14 +1806,14 @@ class Renderer {
17721806 void renderReflectionPass (vk::raii::CommandBuffer& cmd,
17731807 const glm::vec4& planeWS,
17741808 CameraComponent* camera,
1775- const std::vector<Entity *>& entities );
1809+ const std::vector<RenderJob> &jobs );
17761810
17771811 // Ensure Vulkan-Hpp dispatcher is initialized for the current thread when using RAII objects on worker threads
17781812 void ensureThreadLocalVulkanInit () const ;
17791813
17801814 // Cache and classify an entity's material for raster rendering (opaque vs blended, glass/liquid flags,
17811815 // and push-constant defaults). This avoids repeated per-frame string parsing and material lookups.
1782- void ensureEntityMaterialCache (Entity* entity);
1816+ void ensureEntityMaterialCache (Entity* entity, EntityResources &res );
17831817
17841818 // ===================== Culling helpers =====================
17851819 struct FrustumPlanes {
@@ -1800,9 +1834,10 @@ class Renderer {
18001834 const FrustumPlanes& frustum);
18011835 void recreateSwapChain ();
18021836
1803- void updateUniformBuffer (uint32_t currentImage, Entity* entity, CameraComponent* camera);
1804- void updateUniformBuffer (uint32_t currentImage, Entity* entity, CameraComponent* camera, const glm::mat4& customTransform);
1805- void updateUniformBufferInternal (uint32_t currentImage, Entity* entity, CameraComponent* camera, UniformBufferObject& ubo);
1837+ void updateUniformBuffer (uint32_t currentImage, Entity* entity, EntityResources *entityRes, CameraComponent* camera, TransformComponent *tc = nullptr );
1838+ void updateUniformBuffer (uint32_t currentImage, Entity* entity, EntityResources *entityRes, CameraComponent* camera, const glm::mat4& customTransform);
1839+ void updateUniformBufferInternal (uint32_t currentImage, Entity* entity, EntityResources *entityRes, CameraComponent* camera, UniformBufferObject& ubo);
1840+ void prepareFrameUboTemplate (CameraComponent *camera);
18061841
18071842 vk::raii::ShaderModule createShaderModule (const std::vector<char >& code);
18081843
0 commit comments