mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 21:41:03 +00:00
Retrieve the light list on the fly rather than try to sync it
This commit is contained in:
parent
2549b0fa57
commit
ad97b5408a
7 changed files with 81 additions and 27 deletions
|
@ -90,10 +90,8 @@ struct LevelMeshSurface
|
||||||
//
|
//
|
||||||
inline uint32_t Area() const { return texWidth * texHeight; }
|
inline uint32_t Area() const { return texWidth * texHeight; }
|
||||||
|
|
||||||
// Touching light sources
|
|
||||||
std::vector<const LevelMeshLight*> LightList;
|
|
||||||
|
|
||||||
int LightListPos = -1;
|
int LightListPos = -1;
|
||||||
|
int LightListCount = 0;
|
||||||
int LightListResetCounter = -1;
|
int LightListResetCounter = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -209,7 +207,7 @@ public:
|
||||||
virtual unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const { return 0xffffffff; }
|
virtual unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const { return 0xffffffff; }
|
||||||
virtual int GetSurfaceCount() { return 0; }
|
virtual int GetSurfaceCount() { return 0; }
|
||||||
|
|
||||||
virtual void UpdateLightLists() { }
|
virtual int AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) { return 0; }
|
||||||
|
|
||||||
TArray<LevelMeshSmoothingGroup> SmoothingGroups;
|
TArray<LevelMeshSmoothingGroup> SmoothingGroups;
|
||||||
TArray<LevelMeshPortal> Portals;
|
TArray<LevelMeshPortal> Portals;
|
||||||
|
|
|
@ -30,6 +30,8 @@ VkLightmap::VkLightmap(VulkanRenderDevice* fb) : fb(fb)
|
||||||
{
|
{
|
||||||
useRayQuery = fb->GetDevice()->PhysicalDevice.Features.RayQuery.rayQuery;
|
useRayQuery = fb->GetDevice()->PhysicalDevice.Features.RayQuery.rayQuery;
|
||||||
|
|
||||||
|
templightlist.Resize(128);
|
||||||
|
|
||||||
CreateUniformBuffer();
|
CreateUniformBuffer();
|
||||||
CreateLightBuffer();
|
CreateLightBuffer();
|
||||||
CreateTileBuffer();
|
CreateTileBuffer();
|
||||||
|
@ -158,11 +160,11 @@ void VkLightmap::Render()
|
||||||
auto& selectedSurface = selectedSurfaces[i];
|
auto& selectedSurface = selectedSurfaces[i];
|
||||||
LevelMeshSurface* targetSurface = selectedSurface.Surface;
|
LevelMeshSurface* targetSurface = selectedSurface.Surface;
|
||||||
|
|
||||||
if (targetSurface->LightList.empty() && (targetSurface->plane.XYZ() | mesh->SunDirection) < 0.0f) // No lights, no sun
|
/*if (targetSurface->LightList.empty() && (targetSurface->plane.XYZ() | mesh->SunDirection) < 0.0f) // No lights, no sun
|
||||||
{
|
{
|
||||||
selectedSurface.Rendered = true;
|
selectedSurface.Rendered = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
LightmapRaytracePC pc;
|
LightmapRaytracePC pc;
|
||||||
pc.TileX = (float)selectedSurface.X;
|
pc.TileX = (float)selectedSurface.X;
|
||||||
|
@ -193,10 +195,10 @@ void VkLightmap::Render()
|
||||||
// Paint all surfaces visible in the tile
|
// Paint all surfaces visible in the tile
|
||||||
for (LevelMeshSurface* surface : targetSurface->tileSurfaces)
|
for (LevelMeshSurface* surface : targetSurface->tileSurfaces)
|
||||||
{
|
{
|
||||||
int lightCount = (int)surface->LightList.size();
|
|
||||||
|
|
||||||
if (surface->LightListResetCounter != lights.ResetCounter)
|
if (surface->LightListResetCounter != lights.ResetCounter)
|
||||||
{
|
{
|
||||||
|
int lightCount = mesh->AddSurfaceLights(surface, templightlist.Data(), (int)templightlist.Size());
|
||||||
|
|
||||||
if (lights.Pos + lightCount > lights.BufferSize)
|
if (lights.Pos + lightCount > lights.BufferSize)
|
||||||
{
|
{
|
||||||
// Our light buffer is full. Postpone the rest.
|
// Our light buffer is full. Postpone the rest.
|
||||||
|
@ -205,11 +207,13 @@ void VkLightmap::Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->LightListPos = lights.Pos;
|
surface->LightListPos = lights.Pos;
|
||||||
|
surface->LightListCount = lightCount;
|
||||||
surface->LightListResetCounter = lights.ResetCounter;
|
surface->LightListResetCounter = lights.ResetCounter;
|
||||||
|
|
||||||
LightInfo* lightinfo = &lights.Lights[lights.Pos];
|
LightInfo* lightinfo = &lights.Lights[lights.Pos];
|
||||||
for (const LevelMeshLight* light : surface->LightList)
|
for (int i = 0; i < lightCount; i++)
|
||||||
{
|
{
|
||||||
|
const LevelMeshLight* light = &templightlist[i];
|
||||||
lightinfo->Origin = light->Origin;
|
lightinfo->Origin = light->Origin;
|
||||||
lightinfo->RelativeOrigin = light->RelativeOrigin;
|
lightinfo->RelativeOrigin = light->RelativeOrigin;
|
||||||
lightinfo->Radius = light->Radius;
|
lightinfo->Radius = light->Radius;
|
||||||
|
@ -225,7 +229,7 @@ void VkLightmap::Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
pc.LightStart = surface->LightListPos;
|
pc.LightStart = surface->LightListPos;
|
||||||
pc.LightEnd = pc.LightStart + lightCount;
|
pc.LightEnd = pc.LightStart + surface->LightListCount;
|
||||||
cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapRaytracePC), &pc);
|
cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapRaytracePC), &pc);
|
||||||
cmdbuffer->drawIndexed(surface->numElements, 1, surface->startElementIndex, 0, 0);
|
cmdbuffer->drawIndexed(surface->numElements, 1, surface->startElementIndex, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,7 @@ private:
|
||||||
|
|
||||||
TArray<SelectedSurface> selectedSurfaces;
|
TArray<SelectedSurface> selectedSurfaces;
|
||||||
TArray<TArray<SelectedSurface*>> copylists;
|
TArray<TArray<SelectedSurface*>> copylists;
|
||||||
|
TArray<LevelMeshLight> templightlist;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -483,7 +483,6 @@ void VulkanRenderDevice::BeginFrame()
|
||||||
|
|
||||||
if (levelMesh && levelMesh->GetSurfaceCount() > 0)
|
if (levelMesh && levelMesh->GetSurfaceCount() > 0)
|
||||||
{
|
{
|
||||||
levelMesh->UpdateLightLists();
|
|
||||||
GetTextureManager()->CreateLightmap(levelMesh->LMTextureSize, levelMesh->LMTextureCount, std::move(levelMesh->LMTextureData));
|
GetTextureManager()->CreateLightmap(levelMesh->LMTextureSize, levelMesh->LMTextureCount, std::move(levelMesh->LMTextureData));
|
||||||
GetLightmap()->SetLevelMesh(levelMesh);
|
GetLightmap()->SetLevelMesh(levelMesh);
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,6 +363,72 @@ void DoomLevelMesh::CreatePortals()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DoomLevelMesh::AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize)
|
||||||
|
{
|
||||||
|
const DoomLevelMeshSurface* doomsurf = static_cast<const DoomLevelMeshSurface*>(surface);
|
||||||
|
|
||||||
|
FLightNode* node = nullptr;
|
||||||
|
if (doomsurf->Type == ST_FLOOR || doomsurf->Type == ST_CEILING)
|
||||||
|
{
|
||||||
|
node = doomsurf->Subsector->section->lighthead;
|
||||||
|
}
|
||||||
|
else if (doomsurf->Type == ST_MIDDLESIDE || doomsurf->Type == ST_UPPERSIDE || doomsurf->Type == ST_LOWERSIDE)
|
||||||
|
{
|
||||||
|
node = doomsurf->Side->lighthead;
|
||||||
|
}
|
||||||
|
if (!node)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int listpos = 0;
|
||||||
|
while (node && listpos < listMaxSize)
|
||||||
|
{
|
||||||
|
FDynamicLight* light = node->lightsource;
|
||||||
|
if (light && light->Trace())
|
||||||
|
{
|
||||||
|
DVector3 pos = light->Pos; //light->PosRelative(portalgroup);
|
||||||
|
|
||||||
|
LevelMeshLight& meshlight = list[listpos++];
|
||||||
|
meshlight.Origin = { (float)pos.X, (float)pos.Y, (float)pos.Z };
|
||||||
|
meshlight.RelativeOrigin = meshlight.Origin;
|
||||||
|
meshlight.Radius = (float)light->GetRadius();
|
||||||
|
meshlight.Intensity = (float)light->target->Alpha;
|
||||||
|
if (light->IsSpot())
|
||||||
|
{
|
||||||
|
meshlight.InnerAngleCos = (float)light->pSpotInnerAngle->Cos();
|
||||||
|
meshlight.OuterAngleCos = (float)light->pSpotOuterAngle->Cos();
|
||||||
|
|
||||||
|
DAngle negPitch = -*light->pPitch;
|
||||||
|
DAngle Angle = light->target->Angles.Yaw;
|
||||||
|
double xzLen = negPitch.Cos();
|
||||||
|
meshlight.SpotDir.X = float(-Angle.Cos() * xzLen);
|
||||||
|
meshlight.SpotDir.Y = float(-Angle.Sin() * xzLen);
|
||||||
|
meshlight.SpotDir.Z = float(-negPitch.Sin());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meshlight.InnerAngleCos = -1.0f;
|
||||||
|
meshlight.OuterAngleCos = -1.0f;
|
||||||
|
meshlight.SpotDir.X = 0.0f;
|
||||||
|
meshlight.SpotDir.Y = 0.0f;
|
||||||
|
meshlight.SpotDir.Z = 0.0f;
|
||||||
|
}
|
||||||
|
meshlight.Color.X = light->GetRed() * (1.0f / 255.0f);
|
||||||
|
meshlight.Color.Y = light->GetGreen() * (1.0f / 255.0f);
|
||||||
|
meshlight.Color.Z = light->GetBlue() * (1.0f / 255.0f);
|
||||||
|
|
||||||
|
if (light->Sector)
|
||||||
|
meshlight.SectorGroup = sectorGroup[light->Sector->Index()];
|
||||||
|
else
|
||||||
|
meshlight.SectorGroup = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = node->nextLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return listpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void DoomLevelMesh::PropagateLight(const LevelMeshLight* light, std::set<LevelMeshPortal, RecursivePortalComparator>& touchedPortals, int lightPropagationRecursiveDepth)
|
void DoomLevelMesh::PropagateLight(const LevelMeshLight* light, std::set<LevelMeshPortal, RecursivePortalComparator>& touchedPortals, int lightPropagationRecursiveDepth)
|
||||||
{
|
{
|
||||||
if (++lightPropagationRecursiveDepth > 32) // TODO is this too much?
|
if (++lightPropagationRecursiveDepth > 32) // TODO is this too much?
|
||||||
|
@ -495,11 +561,7 @@ void DoomLevelMesh::CreateLightList()
|
||||||
PropagateLight(Lights[i].get(), touchedPortals, 0);
|
PropagateLight(Lights[i].get(), touchedPortals, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
void DoomLevelMesh::UpdateLightLists()
|
|
||||||
{
|
|
||||||
CreateLightList(); // full recreation
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoomLevelMesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap)
|
void DoomLevelMesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,13 +39,12 @@ public:
|
||||||
return surface && surface->bSky;
|
return surface && surface->bSky;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateLightLists() override;
|
int AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) override;
|
||||||
|
|
||||||
LevelMeshSurface* GetSurface(int index) override { return &Surfaces[index]; }
|
LevelMeshSurface* GetSurface(int index) override { return &Surfaces[index]; }
|
||||||
unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const override { return (unsigned int)(ptrdiff_t)(static_cast<const DoomLevelMeshSurface*>(surface) - Surfaces.Data()); }
|
unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const override { return (unsigned int)(ptrdiff_t)(static_cast<const DoomLevelMeshSurface*>(surface) - Surfaces.Data()); }
|
||||||
int GetSurfaceCount() override { return Surfaces.Size(); }
|
int GetSurfaceCount() override { return Surfaces.Size(); }
|
||||||
|
|
||||||
|
|
||||||
TArray<DoomLevelMeshSurface> Surfaces;
|
TArray<DoomLevelMeshSurface> Surfaces;
|
||||||
std::vector<std::unique_ptr<LevelMeshLight>> Lights;
|
std::vector<std::unique_ptr<LevelMeshLight>> Lights;
|
||||||
TArray<FVector2> LightmapUvs;
|
TArray<FVector2> LightmapUvs;
|
||||||
|
@ -72,9 +71,6 @@ private:
|
||||||
void SetSideLightmap(DoomLevelMeshSurface* surface);
|
void SetSideLightmap(DoomLevelMeshSurface* surface);
|
||||||
|
|
||||||
void SetupLightmapUvs(FLevelLocals& doomMap);
|
void SetupLightmapUvs(FLevelLocals& doomMap);
|
||||||
void PropagateLight(const LevelMeshLight* light, std::set<LevelMeshPortal, RecursivePortalComparator>& touchedPortals, int lightPropagationRecursiveDepth);
|
|
||||||
void CreateLightList();
|
|
||||||
|
|
||||||
|
|
||||||
static bool IsTopSideSky(sector_t* frontsector, sector_t* backsector, side_t* side);
|
static bool IsTopSideSky(sector_t* frontsector, sector_t* backsector, side_t* side);
|
||||||
static bool IsTopSideVisible(side_t* side);
|
static bool IsTopSideVisible(side_t* side);
|
||||||
|
|
|
@ -429,12 +429,6 @@ void HWDrawInfo::UpdateLightmaps()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lm_always_update) // To do: this is stupid, but it lets us see the move for now!
|
|
||||||
{
|
|
||||||
//level.levelMesh->UpdateLightLists();
|
|
||||||
}
|
|
||||||
|
|
||||||
screen->UpdateLightmaps(VisibleSurfaces);
|
screen->UpdateLightmaps(VisibleSurfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue