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; }
|
||||
|
||||
// Touching light sources
|
||||
std::vector<const LevelMeshLight*> LightList;
|
||||
|
||||
int LightListPos = -1;
|
||||
int LightListCount = 0;
|
||||
int LightListResetCounter = -1;
|
||||
};
|
||||
|
||||
|
@ -209,7 +207,7 @@ public:
|
|||
virtual unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const { return 0xffffffff; }
|
||||
virtual int GetSurfaceCount() { return 0; }
|
||||
|
||||
virtual void UpdateLightLists() { }
|
||||
virtual int AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) { return 0; }
|
||||
|
||||
TArray<LevelMeshSmoothingGroup> SmoothingGroups;
|
||||
TArray<LevelMeshPortal> Portals;
|
||||
|
|
|
@ -30,6 +30,8 @@ VkLightmap::VkLightmap(VulkanRenderDevice* fb) : fb(fb)
|
|||
{
|
||||
useRayQuery = fb->GetDevice()->PhysicalDevice.Features.RayQuery.rayQuery;
|
||||
|
||||
templightlist.Resize(128);
|
||||
|
||||
CreateUniformBuffer();
|
||||
CreateLightBuffer();
|
||||
CreateTileBuffer();
|
||||
|
@ -158,11 +160,11 @@ void VkLightmap::Render()
|
|||
auto& selectedSurface = selectedSurfaces[i];
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
}*/
|
||||
|
||||
LightmapRaytracePC pc;
|
||||
pc.TileX = (float)selectedSurface.X;
|
||||
|
@ -193,10 +195,10 @@ void VkLightmap::Render()
|
|||
// Paint all surfaces visible in the tile
|
||||
for (LevelMeshSurface* surface : targetSurface->tileSurfaces)
|
||||
{
|
||||
int lightCount = (int)surface->LightList.size();
|
||||
|
||||
if (surface->LightListResetCounter != lights.ResetCounter)
|
||||
{
|
||||
int lightCount = mesh->AddSurfaceLights(surface, templightlist.Data(), (int)templightlist.Size());
|
||||
|
||||
if (lights.Pos + lightCount > lights.BufferSize)
|
||||
{
|
||||
// Our light buffer is full. Postpone the rest.
|
||||
|
@ -205,11 +207,13 @@ void VkLightmap::Render()
|
|||
}
|
||||
|
||||
surface->LightListPos = lights.Pos;
|
||||
surface->LightListCount = lightCount;
|
||||
surface->LightListResetCounter = lights.ResetCounter;
|
||||
|
||||
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->RelativeOrigin = light->RelativeOrigin;
|
||||
lightinfo->Radius = light->Radius;
|
||||
|
@ -225,7 +229,7 @@ void VkLightmap::Render()
|
|||
}
|
||||
|
||||
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->drawIndexed(surface->numElements, 1, surface->startElementIndex, 0, 0);
|
||||
}
|
||||
|
|
|
@ -159,6 +159,7 @@ private:
|
|||
|
||||
TArray<SelectedSurface> selectedSurfaces;
|
||||
TArray<TArray<SelectedSurface*>> copylists;
|
||||
TArray<LevelMeshLight> templightlist;
|
||||
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -483,7 +483,6 @@ void VulkanRenderDevice::BeginFrame()
|
|||
|
||||
if (levelMesh && levelMesh->GetSurfaceCount() > 0)
|
||||
{
|
||||
levelMesh->UpdateLightLists();
|
||||
GetTextureManager()->CreateLightmap(levelMesh->LMTextureSize, levelMesh->LMTextureCount, std::move(levelMesh->LMTextureData));
|
||||
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)
|
||||
{
|
||||
if (++lightPropagationRecursiveDepth > 32) // TODO is this too much?
|
||||
|
@ -495,11 +561,7 @@ void DoomLevelMesh::CreateLightList()
|
|||
PropagateLight(Lights[i].get(), touchedPortals, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void DoomLevelMesh::UpdateLightLists()
|
||||
{
|
||||
CreateLightList(); // full recreation
|
||||
}
|
||||
#endif
|
||||
|
||||
void DoomLevelMesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap)
|
||||
{
|
||||
|
|
|
@ -39,13 +39,12 @@ public:
|
|||
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]; }
|
||||
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(); }
|
||||
|
||||
|
||||
TArray<DoomLevelMeshSurface> Surfaces;
|
||||
std::vector<std::unique_ptr<LevelMeshLight>> Lights;
|
||||
TArray<FVector2> LightmapUvs;
|
||||
|
@ -72,9 +71,6 @@ private:
|
|||
void SetSideLightmap(DoomLevelMeshSurface* surface);
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue