diff --git a/src/common/rendering/hwrenderer/data/hw_renderstate.h b/src/common/rendering/hwrenderer/data/hw_renderstate.h index e305c2ae06..6187eee2b1 100644 --- a/src/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/src/common/rendering/hwrenderer/data/hw_renderstate.h @@ -258,7 +258,7 @@ protected: EPassType mPassType = NORMAL_PASS; - TArray mActiveLightmapSurfaces; + TArray mActiveLightmapSurfaces; public: uint64_t firstFrame = 0; @@ -731,10 +731,10 @@ public: return SetViewpoint(matrices); } - inline void PushVisibleSurface(LevelMeshSurface* surface) + inline void PushVisibleSurface(int surfaceIndex, LevelMeshSurface* surface) { - if(surface && surface->needsUpdate && mActiveLightmapSurfaces.Find(surface) >= mActiveLightmapSurfaces.Size()) // yikes, how awful - mActiveLightmapSurfaces.Push(surface); + if(surface->needsUpdate && mActiveLightmapSurfaces.Find(surfaceIndex) >= mActiveLightmapSurfaces.Size()) // yikes, how awful + mActiveLightmapSurfaces.Push(surfaceIndex); } inline const auto& GetVisibleSurfaceList() const diff --git a/src/common/rendering/v_video.h b/src/common/rendering/v_video.h index e0452890bc..c2c7420d29 100644 --- a/src/common/rendering/v_video.h +++ b/src/common/rendering/v_video.h @@ -156,7 +156,7 @@ public: virtual bool IsPoly() { return false; } virtual bool CompileNextShader() { return true; } virtual void SetLevelMesh(LevelMesh *mesh) { } - virtual void UpdateLightmaps(const TArray& surfaces) {} + virtual void UpdateLightmaps(const TArray& surfaceIndices) {} bool allowSSBO() const { #ifndef HW_BLOCK_SSBO diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp index 87a39f707f..03f3cdb74e 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp @@ -42,49 +42,78 @@ ADD_STAT(lightmapper) return out; } -void VkLightmap::Raytrace(LevelMesh* level, const TArray& surfaces) +#include + +void VkLightmap::Raytrace(LevelMesh* level, const TArray& surfaceIndices) { bool newLevel = (mesh != level); mesh = level; + if (newLevel) + { + UpdateAccelStructDescriptors(); + CreateAtlasImages(); + + lightmapRaytrace.Reset(); + lightmapRaytraceLast.Reset(); + } + lightmapRaytrace.active = true; lightmapRaytraceLast.active = true; lightmapRaytrace.Clock(); lightmapRaytraceLast.ResetAndClock(); - if (newLevel) +#if 0 + TArray allSurfaces; + + std::set s; + + for (auto& surface : surfaceIndices) { - UpdateAccelStructDescriptors(); - CreateAtlasImages(); + s.insert(mesh->GetSurface(surface)->smoothingGroupIndex); } - for (auto surface : surfaces) + for (int i = 0, count = level->GetSurfaceCount(); i < count; ++i) { - surface->needsUpdate = false; + auto surface = level->GetSurface(i); + + if (s.find(surface->smoothingGroupIndex) != s.end()) + { + allSurfaces.Push(i); + surface->needsUpdate = false; + } } +#else + for (auto& surface : surfaceIndices) + { + mesh->GetSurface(surface)->needsUpdate = false; + } + + const auto& allSurfaces = surfaceIndices; +#endif UploadUniforms(); - lastSurfaceCount = surfaces.Size(); + lastSurfaceCount = allSurfaces.Size(); for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++) { - RenderAtlasImage(pageIndex, surfaces); + RenderAtlasImage(pageIndex, allSurfaces); } for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++) { ResolveAtlasImage(pageIndex); BlurAtlasImage(pageIndex); - CopyAtlasImageResult(pageIndex, surfaces); + CopyAtlasImageResult(pageIndex, allSurfaces); } lightmapRaytrace.Unclock(); lightmapRaytraceLast.Unclock(); } -void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray& surfaces) +void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray& surfaceIndices) { LightmapImage& img = atlasImages[pageIndex]; @@ -106,9 +135,9 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArraybindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 1, raytrace.descriptorSet1.get()); } - for (int i = 0, count = surfaces.Size(); i < count; i++) + for (int i = 0, count = surfaceIndices.Size(); i < count; i++) { - LevelMeshSurface* targetSurface = surfaces[i]; + LevelMeshSurface* targetSurface = mesh->GetSurface(surfaceIndices[i]); if (targetSurface->lightmapperAtlasPage != pageIndex) continue; @@ -187,7 +216,7 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArrayGetSurface(0), (char*)targetSurface) / 288; pc.LightmapOrigin = targetSurface->worldOrigin - targetSurface->worldStepX - targetSurface->worldStepY; pc.LightmapStepX = targetSurface->worldStepX * viewport.width; pc.LightmapStepY = targetSurface->worldStepY * viewport.height; @@ -402,14 +431,14 @@ void VkLightmap::BlurAtlasImage(size_t pageIndex) } } -void VkLightmap::CopyAtlasImageResult(size_t pageIndex, const TArray& surfaces) +void VkLightmap::CopyAtlasImageResult(size_t pageIndex, const TArray& surfaceIndices) { LightmapImage& img = atlasImages[pageIndex]; std::vector regions; - for (int i = 0, count = surfaces.Size(); i < count; i++) + for (int i = 0, count = surfaceIndices.Size(); i < count; i++) { - LevelMeshSurface* surface = surfaces[i]; + LevelMeshSurface* surface = mesh->GetSurface(surfaceIndices[i]); if (surface->lightmapperAtlasPage != pageIndex) continue; diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.h b/src/common/rendering/vulkan/accelstructs/vk_lightmap.h index ffbf1e853f..709fa75f4c 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.h +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.h @@ -86,17 +86,17 @@ public: VkLightmap(VulkanRenderDevice* fb); ~VkLightmap(); - void Raytrace(LevelMesh* level, const TArray& surfaces); + void Raytrace(LevelMesh* level, const TArray& surfaceIndices); private: void UpdateAccelStructDescriptors(); void UploadUniforms(); void CreateAtlasImages(); - void RenderAtlasImage(size_t pageIndex, const TArray& surfaces); + void RenderAtlasImage(size_t pageIndex, const TArray& surfaceIndices); void ResolveAtlasImage(size_t pageIndex); void BlurAtlasImage(size_t pageIndex); - void CopyAtlasImageResult(size_t pageIndex, const TArray& surfaces); + void CopyAtlasImageResult(size_t pageIndex, const TArray& surfaceIndices); LightmapImage CreateImage(int width, int height); diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index 8d3d44c2d7..53dbc9afba 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -559,15 +559,15 @@ void VulkanRenderDevice::SetLevelMesh(LevelMesh* mesh) } } -void VulkanRenderDevice::UpdateLightmaps(const TArray& surfaces) +void VulkanRenderDevice::UpdateLightmaps(const TArray& surfaceIndices) { - if (surfaces.Size() > 0) + if (surfaceIndices.Size() > 0) { auto levelMesh = lastMesh; // There's nothing more permanent than a temporary solution if (levelMesh) { - GetLightmap()->Raytrace(levelMesh, surfaces); + GetLightmap()->Raytrace(levelMesh, surfaceIndices); } } } diff --git a/src/common/rendering/vulkan/vk_renderdevice.h b/src/common/rendering/vulkan/vk_renderdevice.h index 9de2e53813..4b4927431a 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.h +++ b/src/common/rendering/vulkan/vk_renderdevice.h @@ -63,7 +63,7 @@ public: void AmbientOccludeScene(float m5) override; void SetSceneRenderTarget(bool useSSAO) override; void SetLevelMesh(LevelMesh* mesh) override; - void UpdateLightmaps(const TArray& surfaces) override; + void UpdateLightmaps(const TArray& surfaceIndices) override; void SetShadowMaps(const TArray& lights, hwrenderer::LevelAABBTree* tree, bool newTree) override; void SetSaveBuffers(bool yes) override; void ImageTransitionScene(bool unknown) override; diff --git a/src/rendering/hwrenderer/scene/hw_flats.cpp b/src/rendering/hwrenderer/scene/hw_flats.cpp index 8130f694ef..c2c36f46a4 100644 --- a/src/rendering/hwrenderer/scene/hw_flats.cpp +++ b/src/rendering/hwrenderer/scene/hw_flats.cpp @@ -194,7 +194,11 @@ void HWFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state) for (auto& subsector : section->subsectors) { - state.PushVisibleSurface(subsector->lightmap[ceiling ? 1 : 0][0]); + auto lightmap = subsector->lightmap[ceiling ? 1 : 0][0]; + if (lightmap) + { + state.PushVisibleSurface(lightmap - &subsector->sector->Level->levelMesh->Surfaces[0], lightmap); + } } state.DrawIndexed(DT_Triangles, iboindex + section->vertexindex, section->vertexcount); diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 4a262bfc69..a612c09dd1 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -347,7 +347,11 @@ void HWWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent) MakeVertices(di, state, !!(flags & HWWall::HWF_TRANSLUCENT)); } - state.PushVisibleSurface(lightmap); + if (lightmap) + { + state.PushVisibleSurface(lightmap - &seg->Subsector->sector->Level->levelMesh->Surfaces[0], lightmap); + } + state.SetNormal(glseg.Normal()); if (!translucent) {