From f0c018fdc693ff1805d7ac55f5e62739a30c0608 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Wed, 11 Sep 2024 01:39:26 +0200 Subject: [PATCH] Update light level in level mesh --- .../hwrenderer/data/hw_levelmesh.cpp | 2 + .../rendering/hwrenderer/data/hw_levelmesh.h | 8 +- .../hwrenderer/data/hw_surfaceuniforms.h | 15 ++- .../descriptorsets/vk_descriptorset.cpp | 18 +-- src/common/rendering/vulkan/vk_levelmesh.cpp | 19 +++ src/common/rendering/vulkan/vk_levelmesh.h | 4 + .../rendering/vulkan/vk_renderstate.cpp | 8 +- src/rendering/hwrenderer/doom_levelmesh.cpp | 114 +++++++++++++----- src/rendering/hwrenderer/doom_levelmesh.h | 18 ++- .../shaders/scene/binding_rsbuffers.glsl | 66 +++++++--- .../static/shaders/scene/layout_shared.glsl | 19 ++- 11 files changed, 222 insertions(+), 69 deletions(-) diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp index 243f23fa1..85c6880d6 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp @@ -28,10 +28,12 @@ void LevelMesh::Reset(const LevelMeshLimits& limits) Mesh.Surfaces.Resize(limits.MaxSurfaces); Mesh.Uniforms.Resize(limits.MaxUniforms); + Mesh.LightUniforms.Resize(limits.MaxUniforms); Mesh.Materials.Resize(limits.MaxUniforms); Mesh.Lights.Resize(16); Mesh.LightIndexes.Resize(16); + Mesh.DynLights.Resize(16); Mesh.Indexes.Resize(limits.MaxIndexes); Mesh.SurfaceIndexes.Resize(limits.MaxIndexes / 3 + 1); diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index 9957f4a33..578f07bce 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -34,6 +34,7 @@ struct GeometryAllocInfo struct UniformsAllocInfo { SurfaceUniforms* Uniforms = nullptr; + SurfaceLightUniforms* LightUniforms = nullptr; FMaterialState* Materials = nullptr; int Start = 0; int Count = 0; @@ -115,11 +116,13 @@ public: // Surface info TArray Surfaces; TArray Uniforms; + TArray LightUniforms; TArray Materials; TArray LightIndexes; // Lights TArray Lights; + TArray DynLights; // Index data TArray Indexes; @@ -143,8 +146,10 @@ public: TArray Surface; TArray UniformIndexes; TArray Uniforms; + TArray LightUniforms; TArray Portals; TArray Light; + TArray DynLight; TArray LightIndex; TArray DrawIndex; } UploadRanges; @@ -178,7 +183,6 @@ public: uint32_t AtlasPixelCount() const { return uint32_t(LMTextureCount * LMTextureSize * LMTextureSize); } void UpdateCollision(); - void BuildTileSurfaceLists(); void SetupTileTransforms(); void PackLightmapAtlas(int lightmapStartIndex); @@ -229,9 +233,11 @@ inline UniformsAllocInfo LevelMesh::AllocUniforms(int count) info.Start = RemoveRange(FreeLists.Uniforms, count); info.Count = count; info.Uniforms = &Mesh.Uniforms[info.Start]; + info.LightUniforms = &Mesh.LightUniforms[info.Start]; info.Materials = &Mesh.Materials[info.Start]; AddRange(UploadRanges.Uniforms, { info.Start, info.Start + info.Count }); + AddRange(UploadRanges.LightUniforms, { info.Start, info.Start + info.Count }); return info; } diff --git a/src/common/rendering/hwrenderer/data/hw_surfaceuniforms.h b/src/common/rendering/hwrenderer/data/hw_surfaceuniforms.h index 9524e4f12..ad40bb137 100644 --- a/src/common/rendering/hwrenderer/data/hw_surfaceuniforms.h +++ b/src/common/rendering/hwrenderer/data/hw_surfaceuniforms.h @@ -13,11 +13,11 @@ struct SurfaceUniforms FVector4 uTextureModulateColor; FVector4 uTextureBlendColor; FVector4 uFogColor; - float uDesaturationFactor; // HWDrawInfo::SetColor + float uDesaturationFactor; float uInterpolationFactor; float timer; int useVertexData; - FVector4 uVertexColor; // HWDrawInfo::SetColor + FVector4 uVertexColor; FVector4 uVertexNormal; FVector4 uGlowTopPlane; @@ -37,7 +37,7 @@ struct SurfaceUniforms FVector2 uClipSplit; FVector2 uSpecularMaterial; - float uLightLevel; // HWDrawInfo::SetColor + float uLightLevel; float uFogDensity; float uLightFactor; float uLightDist; @@ -47,3 +47,12 @@ struct SurfaceUniforms float uDepthFadeThreshold; float padding3; }; + +struct SurfaceLightUniforms +{ + FVector4 uVertexColor; // HWDrawInfo::SetColor + float uDesaturationFactor; // HWDrawInfo::SetColor + float uLightLevel; // HWDrawInfo::SetColor + int uLightIndex; + int padding; +}; diff --git a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp index 387a5a794..c88b3f85a 100644 --- a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp @@ -90,9 +90,10 @@ void VkDescriptorSetManager::UpdateLevelMeshSet() .AddBuffer(LevelMesh.Set.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Viewpoint.UBO.get(), 0, sizeof(HWViewpointUniforms)) .AddBuffer(LevelMesh.Set.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->MatrixBuffer->UBO(), 0, sizeof(MatricesUBO)) .AddBuffer(LevelMesh.Set.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetUniformsBuffer()) - .AddBuffer(LevelMesh.Set.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Lightbuffer.UBO.get(), 0, sizeof(LightBufferUBO)) - .AddBuffer(LevelMesh.Set.get(), 4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Fogballbuffer.UBO.get(), 0, sizeof(FogballBufferUBO)) - .AddBuffer(LevelMesh.Set.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, rsbuffers->Bonebuffer.SSO.get()) + .AddBuffer(LevelMesh.Set.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetLightUniformsBuffer()) + .AddBuffer(LevelMesh.Set.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetDynLightBuffer()) + .AddBuffer(LevelMesh.Set.get(), 5, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Fogballbuffer.UBO.get(), 0, sizeof(FogballBufferUBO)) + .AddBuffer(LevelMesh.Set.get(), 6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, rsbuffers->Bonebuffer.SSO.get()) .Execute(fb->GetDevice()); } @@ -208,9 +209,10 @@ void VkDescriptorSetManager::CreateLevelMeshLayout() .AddBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) - .AddBinding(3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) - .AddBinding(4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) - .AddBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT) + .AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) + .AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT) + .AddBinding(5, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) + .AddBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT) .DebugName("VkDescriptorSetManager.LevelMesh.Layout") .Create(fb->GetDevice()); } @@ -251,8 +253,8 @@ void VkDescriptorSetManager::CreateFixedLayout() void VkDescriptorSetManager::CreateLevelMeshPool() { LevelMesh.Pool = DescriptorPoolBuilder() - .AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 4) - .AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2) + .AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 3) + .AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4) .MaxSets(1) .DebugName("VkDescriptorSetManager.LevelMesh.Pool") .Create(fb->GetDevice()); diff --git a/src/common/rendering/vulkan/vk_levelmesh.cpp b/src/common/rendering/vulkan/vk_levelmesh.cpp index 0164cd9fc..413cdff93 100644 --- a/src/common/rendering/vulkan/vk_levelmesh.cpp +++ b/src/common/rendering/vulkan/vk_levelmesh.cpp @@ -57,6 +57,7 @@ void VkLevelMesh::Reset() deletelist->Add(std::move(NodeBuffer)); deletelist->Add(std::move(SurfaceBuffer)); deletelist->Add(std::move(UniformsBuffer)); + deletelist->Add(std::move(LightUniformsBuffer)); deletelist->Add(std::move(SurfaceIndexBuffer)); deletelist->Add(std::move(PortalBuffer)); deletelist->Add(std::move(LightBuffer)); @@ -290,6 +291,12 @@ void VkLevelMesh::CreateBuffers() .DebugName("SurfaceUniformsBuffer") .Create(fb->GetDevice()); + LightUniformsBuffer = BufferBuilder() + .Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) + .Size(Mesh->Mesh.LightUniforms.Size() * sizeof(SurfaceLightUniforms)) + .DebugName("SurfaceLightUniformsBuffer") + .Create(fb->GetDevice()); + PortalBuffer = BufferBuilder() .Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) .Size(Mesh->Portals.Size() * sizeof(PortalInfo)) @@ -307,6 +314,12 @@ void VkLevelMesh::CreateBuffers() .Size(Mesh->Mesh.LightIndexes.Size() * sizeof(int32_t)) .DebugName("LightIndexBuffer") .Create(fb->GetDevice()); + + DynLightBuffer = BufferBuilder() + .Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) + .Size(Mesh->Mesh.DynLights.Size() * sizeof(FVector4)) + .DebugName("DynLightBuffer") + .Create(fb->GetDevice()); } VkLevelMesh::BLAS VkLevelMesh::CreateBLAS(bool preferFastBuild, int indexOffset, int indexCount) @@ -706,6 +719,8 @@ void VkLevelMeshUploader::Upload() UploadRanges(Mesh->Mesh->UploadRanges.SurfaceIndex, Mesh->Mesh->Mesh.SurfaceIndexes.Data(), Mesh->SurfaceIndexBuffer.get()); UploadRanges(Mesh->Mesh->UploadRanges.LightIndex, Mesh->Mesh->Mesh.LightIndexes.Data(), Mesh->LightIndexBuffer.get()); UploadRanges(Mesh->Mesh->UploadRanges.DrawIndex, Mesh->Mesh->Mesh.DrawIndexes.Data(), Mesh->DrawIndexBuffer.get()); + UploadRanges(Mesh->Mesh->UploadRanges.LightUniforms, Mesh->Mesh->Mesh.LightUniforms.Data(), Mesh->LightUniformsBuffer.get()); + UploadRanges(Mesh->Mesh->UploadRanges.DynLight, Mesh->Mesh->Mesh.DynLights.Data(), Mesh->DynLightBuffer.get()); UploadSurfaces(); UploadUniforms(); UploadPortals(); @@ -734,9 +749,11 @@ void VkLevelMeshUploader::ClearRanges() Mesh->Mesh->UploadRanges.Surface.clear(); Mesh->Mesh->UploadRanges.UniformIndexes.clear(); Mesh->Mesh->UploadRanges.Uniforms.clear(); + Mesh->Mesh->UploadRanges.LightUniforms.clear(); Mesh->Mesh->UploadRanges.Portals.clear(); Mesh->Mesh->UploadRanges.Light.clear(); Mesh->Mesh->UploadRanges.LightIndex.clear(); + Mesh->Mesh->UploadRanges.DynLight.clear(); Mesh->Mesh->UploadRanges.DrawIndex.clear(); } @@ -947,9 +964,11 @@ size_t VkLevelMeshUploader::GetTransferSize() for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.SurfaceIndex) transferBufferSize += range.Count() * sizeof(int); for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Surface) transferBufferSize += range.Count() * sizeof(SurfaceInfo); for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Uniforms) transferBufferSize += range.Count() * sizeof(SurfaceUniforms); + for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.LightUniforms) transferBufferSize += range.Count() * sizeof(SurfaceLightUniforms); for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Portals) transferBufferSize += range.Count() * sizeof(PortalInfo); for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.LightIndex) transferBufferSize += range.Count() * sizeof(int32_t); for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Light) transferBufferSize += range.Count() * sizeof(LightInfo); + for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.DynLight) transferBufferSize += range.Count() * sizeof(FVector4); for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.DrawIndex) transferBufferSize += range.Count() * sizeof(uint32_t); return transferBufferSize; } diff --git a/src/common/rendering/vulkan/vk_levelmesh.h b/src/common/rendering/vulkan/vk_levelmesh.h index 1d8e8382a..1a70de15f 100644 --- a/src/common/rendering/vulkan/vk_levelmesh.h +++ b/src/common/rendering/vulkan/vk_levelmesh.h @@ -96,6 +96,8 @@ public: VulkanBuffer* GetSurfaceIndexBuffer() { return SurfaceIndexBuffer.get(); } VulkanBuffer* GetSurfaceBuffer() { return SurfaceBuffer.get(); } VulkanBuffer* GetUniformsBuffer() { return UniformsBuffer.get(); } + VulkanBuffer* GetLightUniformsBuffer() { return LightUniformsBuffer.get(); } + VulkanBuffer* GetDynLightBuffer() { return DynLightBuffer.get(); } VulkanBuffer* GetPortalBuffer() { return PortalBuffer.get(); } VulkanBuffer* GetLightBuffer() { return LightBuffer.get(); } VulkanBuffer* GetLightIndexBuffer() { return LightIndexBuffer.get(); } @@ -145,9 +147,11 @@ private: std::unique_ptr SurfaceIndexBuffer; std::unique_ptr SurfaceBuffer; std::unique_ptr UniformsBuffer; + std::unique_ptr LightUniformsBuffer; std::unique_ptr PortalBuffer; std::unique_ptr LightBuffer; std::unique_ptr LightIndexBuffer; + std::unique_ptr DynLightBuffer; std::unique_ptr DrawIndexBuffer; std::unique_ptr NodeBuffer; diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index d64f5323c..3ee0d446e 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -941,21 +941,19 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip mPipelineKey = pipelineKey; PushConstants pushConstants = {}; - pushConstants.uDataIndex = 0; - pushConstants.uLightIndex = -1; pushConstants.uBoneIndexBase = -1; + pushConstants.uFogballIndex = -1; VulkanPipelineLayout* layout = fb->GetRenderPassManager()->GetPipelineLayout(pipelineKey.ShaderKey.UseLevelMesh); uint32_t viewpointOffset = mViewpointOffset; uint32_t matrixOffset = mRSBuffers->MatrixBuffer->Offset(); - uint32_t lightsOffset = 0; uint32_t fogballsOffset = 0; - uint32_t offsets[] = { viewpointOffset, matrixOffset, lightsOffset, fogballsOffset }; + uint32_t offsets[] = { viewpointOffset, matrixOffset, fogballsOffset }; auto descriptors = fb->GetDescriptorSetManager(); cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mPassSetup->GetPipeline(pipelineKey)); cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedSet()); - cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetLevelMeshSet(), 4, offsets); + cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetLevelMeshSet(), 3, offsets); cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptors->GetBindlessSet()); cmdbuffer->pushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &pushConstants); } diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 471b5b03c..2b205f870 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -220,20 +220,34 @@ void DoomLevelMesh::BeginFrame(FLevelLocals& doomMap) // To do: we don't need to always do this. UpdateLevelMesh should tell us when polyobjs move. for (side_t* side : PolySides) { - UpdateSide(side->Index()); + UpdateSide(side->Index(), SurfaceUpdateType::Full); } for (int sideIndex : SideUpdateList) { - CreateSide(doomMap, sideIndex); - Sides[sideIndex].InUpdateList = false; + if (Sides[sideIndex].UpdateType == SurfaceUpdateType::LightsOnly) + { + SetSideLights(doomMap, sideIndex); + } + else // SurfaceUpdateType::Full + { + CreateSide(doomMap, sideIndex); + } + Sides[sideIndex].UpdateType = SurfaceUpdateType::None; } SideUpdateList.Clear(); for (int flatIndex : FlatUpdateList) { - CreateFlat(doomMap, flatIndex); - Flats[flatIndex].InUpdateList = false; + if (Flats[flatIndex].UpdateType == SurfaceUpdateType::LightsOnly) + { + SetFlatLights(doomMap, flatIndex); + } + else // SurfaceUpdateType::Full + { + CreateFlat(doomMap, flatIndex); + } + Flats[flatIndex].UpdateType = SurfaceUpdateType::None; } FlatUpdateList.Clear(); @@ -490,65 +504,63 @@ void DoomLevelMesh::FreeFlat(FLevelLocals& doomMap, unsigned int sectorIndex) void DoomLevelMesh::FloorHeightChanged(struct sector_t* sector) { - UpdateFlat(sector->Index()); + UpdateFlat(sector->Index(), SurfaceUpdateType::Full); for (line_t* line : sector->Lines) { if (line->sidedef[0]) - UpdateSide(line->sidedef[0]->Index()); + UpdateSide(line->sidedef[0]->Index(), SurfaceUpdateType::Full); if (line->sidedef[1]) - UpdateSide(line->sidedef[1]->Index()); + UpdateSide(line->sidedef[1]->Index(), SurfaceUpdateType::Full); } } void DoomLevelMesh::CeilingHeightChanged(struct sector_t* sector) { - UpdateFlat(sector->Index()); + UpdateFlat(sector->Index(), SurfaceUpdateType::Full); for (line_t* line : sector->Lines) { if (line->sidedef[0]) - UpdateSide(line->sidedef[0]->Index()); + UpdateSide(line->sidedef[0]->Index(), SurfaceUpdateType::Full); if (line->sidedef[1]) - UpdateSide(line->sidedef[1]->Index()); + UpdateSide(line->sidedef[1]->Index(), SurfaceUpdateType::Full); } } void DoomLevelMesh::MidTex3DHeightChanged(struct sector_t* sector) { - // UpdateFlat(sector->Index()); + // UpdateFlat(sector->Index(), SurfaceUpdateType::Full); } void DoomLevelMesh::FloorTextureChanged(struct sector_t* sector) { - UpdateFlat(sector->Index()); + UpdateFlat(sector->Index(), SurfaceUpdateType::Full); } void DoomLevelMesh::CeilingTextureChanged(struct sector_t* sector) { - UpdateFlat(sector->Index()); + UpdateFlat(sector->Index(), SurfaceUpdateType::Full); } void DoomLevelMesh::SectorChangedOther(struct sector_t* sector) { - UpdateFlat(sector->Index()); + UpdateFlat(sector->Index(), SurfaceUpdateType::Full); } void DoomLevelMesh::SideTextureChanged(struct side_t* side, int section) { - UpdateSide(side->Index()); + UpdateSide(side->Index(), SurfaceUpdateType::Full); } void DoomLevelMesh::SectorLightChanged(struct sector_t* sector) { - /* - UpdateFlat(level, sector->Index()); + UpdateFlat(sector->Index(), SurfaceUpdateType::LightsOnly); for (line_t* line : sector->Lines) { if (line->frontsector == sector && line->sidedef[0]) - UpdateSide(line->sidedef[0]->Index()); + UpdateSide(line->sidedef[0]->Index(), SurfaceUpdateType::LightsOnly); else if (line->sidedef[1]) - UpdateSide(line->sidedef[1]->Index()); + UpdateSide(line->sidedef[1]->Index(), SurfaceUpdateType::LightsOnly); } - */ } void DoomLevelMesh::SectorLightThinkerCreated(struct sector_t* sector, class DLighting* lightthinker) @@ -559,21 +571,21 @@ void DoomLevelMesh::SectorLightThinkerDestroyed(struct sector_t* sector, class D { } -void DoomLevelMesh::UpdateSide(unsigned int sideIndex) +void DoomLevelMesh::UpdateSide(unsigned int sideIndex, SurfaceUpdateType updateType) { - if (!Sides[sideIndex].InUpdateList) + if (Sides[sideIndex].UpdateType == SurfaceUpdateType::None) { SideUpdateList.Push(sideIndex); - Sides[sideIndex].InUpdateList = true; + Sides[sideIndex].UpdateType = updateType; } } -void DoomLevelMesh::UpdateFlat(unsigned int sectorIndex) +void DoomLevelMesh::UpdateFlat(unsigned int sectorIndex, SurfaceUpdateType updateType) { - if (!Flats[sectorIndex].InUpdateList) + if (Flats[sectorIndex].UpdateType == SurfaceUpdateType::None) { FlatUpdateList.Push(sectorIndex); - Flats[sectorIndex].InUpdateList = true; + Flats[sectorIndex].UpdateType = updateType; } } @@ -682,6 +694,42 @@ void DoomLevelMesh::CreateFlat(FLevelLocals& doomMap, unsigned int sectorIndex) } } +void DoomLevelMesh::SetSideLights(FLevelLocals& doomMap, unsigned int sideIndex) +{ + for (UniformsAllocInfo& uinfo : Sides[sideIndex].Uniforms) + { + for (int i = 0, count = uinfo.Count; i < count; i++) + { + // To do: calculate this correctly (see HWDrawInfo::SetColor) + // uinfo.LightUniforms[i].uVertexColor + // uinfo.LightUniforms[i].uDesaturationFactor + if (uinfo.LightUniforms[i].uLightLevel >= 0.0f) + { + uinfo.LightUniforms[i].uLightLevel = clamp(doomMap.sides[sideIndex].sector->lightlevel * (1.0f / 255.0f), 0.0f, 1.0f); + } + } + AddRange(UploadRanges.LightUniforms, { uinfo.Start, uinfo.Start + uinfo.Count }); + } +} + +void DoomLevelMesh::SetFlatLights(FLevelLocals& doomMap, unsigned int sectorIndex) +{ + for (UniformsAllocInfo& uinfo : Flats[sectorIndex].Uniforms) + { + for (int i = 0, count = uinfo.Count; i < count; i++) + { + // To do: calculate this correctly (see HWDrawInfo::SetColor) + // uinfo.LightUniforms[i].uVertexColor + // uinfo.LightUniforms[i].uDesaturationFactor + if (uinfo.LightUniforms[i].uLightLevel >= 0.0f) + { + uinfo.LightUniforms[i].uLightLevel = clamp(doomMap.sectors[sectorIndex].lightlevel * (1.0f / 255.0f), 0.0f, 1.0f); + } + } + AddRange(UploadRanges.LightUniforms, { uinfo.Start, uinfo.Start + uinfo.Count }); + } +} + void DoomLevelMesh::CreateWallSurface(side_t* side, HWWallDispatcher& disp, MeshBuilder& state, TArray& list, LevelMeshDrawType drawType, bool translucent, unsigned int sideIndex) { for (HWWall& wallpart : list) @@ -771,6 +819,13 @@ void DoomLevelMesh::CreateWallSurface(side_t* side, HWWallDispatcher& disp, Mesh *(uinfo.Uniforms++) = applyState.surfaceUniforms; *(uinfo.Materials++) = applyState.material; + + uinfo.LightUniforms->uVertexColor = applyState.surfaceUniforms.uVertexColor; + uinfo.LightUniforms->uDesaturationFactor = applyState.surfaceUniforms.uDesaturationFactor; + uinfo.LightUniforms->uLightLevel = applyState.surfaceUniforms.uLightLevel; + uinfo.LightUniforms->uLightIndex = -1; + uinfo.LightUniforms++; + uniformsIndex++; } @@ -1051,6 +1106,11 @@ void DoomLevelMesh::CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state *uinfo.Uniforms = *uniforms; *uinfo.Materials = *material; + uinfo.LightUniforms->uVertexColor = uniforms->uVertexColor; + uinfo.LightUniforms->uDesaturationFactor = uniforms->uDesaturationFactor; + uinfo.LightUniforms->uLightLevel = uniforms->uLightLevel; + uinfo.LightUniforms->uLightIndex = -1; + int uniformsIndex = uinfo.Start; int vertIndex = ginfo.VertexStart; int elementIndex = ginfo.IndexStart; diff --git a/src/rendering/hwrenderer/doom_levelmesh.h b/src/rendering/hwrenderer/doom_levelmesh.h index 75f4edfe1..3f6263d9d 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.h +++ b/src/rendering/hwrenderer/doom_levelmesh.h @@ -54,6 +54,13 @@ struct DrawRangeInfo int DrawIndexCount = 0; }; +enum SurfaceUpdateType +{ + None, + LightsOnly, + Full +}; + struct SideSurfaceBlock { int FirstSurface = -1; @@ -62,7 +69,7 @@ struct SideSurfaceBlock TArray WallPortals; bool InSidePortalsList = false; TArray DrawRanges; - bool InUpdateList = false; + SurfaceUpdateType UpdateType = SurfaceUpdateType::None; }; struct FlatSurfaceBlock @@ -71,7 +78,7 @@ struct FlatSurfaceBlock TArray Geometries; TArray Uniforms; TArray DrawRanges; - bool InUpdateList = false; + SurfaceUpdateType UpdateType = SurfaceUpdateType::None; }; class DoomLevelMesh : public LevelMesh, public UpdateLevelMesh @@ -129,12 +136,15 @@ private: void CreateSurfaces(FLevelLocals& doomMap); void CreateLightList(FLevelLocals& doomMap, int surfaceIndex); - void UpdateSide(unsigned int sideIndex); - void UpdateFlat(unsigned int sectorIndex); + void UpdateSide(unsigned int sideIndex, SurfaceUpdateType updateType); + void UpdateFlat(unsigned int sectorIndex, SurfaceUpdateType updateType); void CreateSide(FLevelLocals& doomMap, unsigned int sideIndex); void CreateFlat(FLevelLocals& doomMap, unsigned int sectorIndex); + void SetSideLights(FLevelLocals& doomMap, unsigned int sideIndex); + void SetFlatLights(FLevelLocals& doomMap, unsigned int sectorIndex); + void FreeSide(FLevelLocals& doomMap, unsigned int sideIndex); void FreeFlat(FLevelLocals& doomMap, unsigned int sectorIndex); diff --git a/wadsrc/static/shaders/scene/binding_rsbuffers.glsl b/wadsrc/static/shaders/scene/binding_rsbuffers.glsl index 304aefc51..289385a05 100644 --- a/wadsrc/static/shaders/scene/binding_rsbuffers.glsl +++ b/wadsrc/static/shaders/scene/binding_rsbuffers.glsl @@ -28,7 +28,7 @@ layout(set = 1, binding = 1, std140) uniform MatricesUBO mat4 TextureMatrix; }; -// This must match the SurfaceUniforms struct +// This must match the C++ SurfaceUniforms struct struct SurfaceUniforms { vec4 uObjectColor; @@ -74,22 +74,13 @@ struct SurfaceUniforms float padding3; }; -#ifdef USE_LEVELMESH -layout(set = 1, binding = 2, std430) buffer SurfaceUniformsSSO +struct SurfaceLightUniforms { - SurfaceUniforms data[]; -}; -#else -layout(set = 1, binding = 2, std140) uniform SurfaceUniformsUBO -{ - SurfaceUniforms data[MAX_SURFACE_UNIFORMS]; -}; -#endif - -// light buffers -layout(set = 1, binding = 3, std140) uniform LightBufferUBO -{ - vec4 lights[MAX_LIGHT_DATA]; + vec4 uVertexColor; + float uDesaturationFactor; + float uLightLevel; + uint uLightIndex; + uint padding; }; struct Fogball @@ -100,6 +91,47 @@ struct Fogball float fog; }; +#ifdef USE_LEVELMESH + +layout(set = 1, binding = 2, std430) buffer SurfaceUniformsSSO +{ + SurfaceUniforms data[]; +}; + +layout(set = 1, binding = 3, std430) buffer SurfaceLightUniformsSSO +{ + SurfaceLightUniforms lightdata[]; +}; + +layout(set = 1, binding = 4, std430) buffer LightBufferSSO +{ + vec4 lights[]; +}; + +layout(set = 1, binding = 5, std140) uniform FogballBufferUBO +{ + Fogball fogballs[MAX_FOGBALL_DATA]; +}; + +// bone matrix buffers +layout(set = 1, binding = 6, std430) buffer BoneBufferSSO +{ + mat4 bones[]; +}; + +#else + +layout(set = 1, binding = 2, std140) uniform SurfaceUniformsUBO +{ + SurfaceUniforms data[MAX_SURFACE_UNIFORMS]; +}; + +// light buffers +layout(set = 1, binding = 3, std140) uniform LightBufferUBO +{ + vec4 lights[MAX_LIGHT_DATA]; +}; + layout(set = 1, binding = 4, std140) uniform FogballBufferUBO { Fogball fogballs[MAX_FOGBALL_DATA]; @@ -110,3 +142,5 @@ layout(set = 1, binding = 5, std430) buffer BoneBufferSSO { mat4 bones[]; }; + +#endif diff --git a/wadsrc/static/shaders/scene/layout_shared.glsl b/wadsrc/static/shaders/scene/layout_shared.glsl index 063fdaaf4..56cafd54a 100644 --- a/wadsrc/static/shaders/scene/layout_shared.glsl +++ b/wadsrc/static/shaders/scene/layout_shared.glsl @@ -7,11 +7,12 @@ layout(push_constant) uniform PushConstants { #if defined(USE_LEVELMESH) - int unused; + int unused0; + int unused1; #else int uDataIndex; // surfaceuniforms index -#endif int uLightIndex; // dynamic lights +#endif int uBoneIndexBase; // bone animation int uFogballIndex; // fog balls }; @@ -45,11 +46,9 @@ layout(push_constant) uniform PushConstants #define uTextureModulateColor data[uDataIndex].uTextureModulateColor #define uTextureAddColor data[uDataIndex].uTextureAddColor #define uFogColor data[uDataIndex].uFogColor -#define uDesaturationFactor data[uDataIndex].uDesaturationFactor #define uInterpolationFactor data[uDataIndex].uInterpolationFactor #define timer data[uDataIndex].timer #define useVertexData data[uDataIndex].useVertexData -#define uVertexColor data[uDataIndex].uVertexColor #define uVertexNormal data[uDataIndex].uVertexNormal #define uGlowTopPlane data[uDataIndex].uGlowTopPlane #define uGlowTopColor data[uDataIndex].uGlowTopColor @@ -63,7 +62,6 @@ layout(push_constant) uniform PushConstants #define uNpotEmulation data[uDataIndex].uNpotEmulation #define uClipSplit data[uDataIndex].uClipSplit #define uSpecularMaterial data[uDataIndex].uSpecularMaterial -#define uLightLevel data[uDataIndex].uLightLevel #define uFogDensity data[uDataIndex].uFogDensity #define uLightFactor data[uDataIndex].uLightFactor #define uLightDist data[uDataIndex].uLightDist @@ -71,6 +69,17 @@ layout(push_constant) uniform PushConstants #define uTextureIndex data[uDataIndex].uTextureIndex #define uDepthFadeThreshold data[uDataIndex].uDepthFadeThreshold +#if defined(USE_LEVELMESH) +#define uVertexColor lightdata[uDataIndex].uVertexColor +#define uDesaturationFactor lightdata[uDataIndex].uDesaturationFactor +#define uLightLevel lightdata[uDataIndex].uLightLevel +#define uLightIndex lightdata[uDataIndex].uLightIndex +#else +#define uVertexColor data[uDataIndex].uVertexColor +#define uDesaturationFactor data[uDataIndex].uDesaturationFactor +#define uLightLevel data[uDataIndex].uLightLevel +#endif + #define VULKAN_COORDINATE_SYSTEM #define HAS_UNIFORM_VERTEX_DATA