Update light level in level mesh

This commit is contained in:
Magnus Norddahl 2024-09-11 01:39:26 +02:00
commit f0c018fdc6
11 changed files with 216 additions and 63 deletions

View file

@ -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);

View file

@ -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<LevelMeshSurface> Surfaces;
TArray<SurfaceUniforms> Uniforms;
TArray<SurfaceLightUniforms> LightUniforms;
TArray<FMaterialState> Materials;
TArray<int32_t> LightIndexes;
// Lights
TArray<LevelMeshLight> Lights;
TArray<FVector4> DynLights;
// Index data
TArray<uint32_t> Indexes;
@ -143,8 +146,10 @@ public:
TArray<MeshBufferRange> Surface;
TArray<MeshBufferRange> UniformIndexes;
TArray<MeshBufferRange> Uniforms;
TArray<MeshBufferRange> LightUniforms;
TArray<MeshBufferRange> Portals;
TArray<MeshBufferRange> Light;
TArray<MeshBufferRange> DynLight;
TArray<MeshBufferRange> LightIndex;
TArray<MeshBufferRange> 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;
}

View file

@ -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;
};

View file

@ -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());

View file

@ -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;
}

View file

@ -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<VulkanBuffer> SurfaceIndexBuffer;
std::unique_ptr<VulkanBuffer> SurfaceBuffer;
std::unique_ptr<VulkanBuffer> UniformsBuffer;
std::unique_ptr<VulkanBuffer> LightUniformsBuffer;
std::unique_ptr<VulkanBuffer> PortalBuffer;
std::unique_ptr<VulkanBuffer> LightBuffer;
std::unique_ptr<VulkanBuffer> LightIndexBuffer;
std::unique_ptr<VulkanBuffer> DynLightBuffer;
std::unique_ptr<VulkanBuffer> DrawIndexBuffer;
std::unique_ptr<VulkanBuffer> NodeBuffer;

View file

@ -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);
}

View file

@ -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<HWWall>& 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;

View file

@ -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<HWWall> WallPortals;
bool InSidePortalsList = false;
TArray<DrawRangeInfo> DrawRanges;
bool InUpdateList = false;
SurfaceUpdateType UpdateType = SurfaceUpdateType::None;
};
struct FlatSurfaceBlock
@ -71,7 +78,7 @@ struct FlatSurfaceBlock
TArray<GeometryFreeInfo> Geometries;
TArray<UniformsAllocInfo> Uniforms;
TArray<DrawRangeInfo> 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);

View file

@ -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

View file

@ -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