Misc surface and lightmapper related cleanup and renaming

This commit is contained in:
Magnus Norddahl 2023-12-11 11:21:20 +01:00
commit 412be46e08
13 changed files with 200 additions and 185 deletions

View file

@ -32,8 +32,8 @@ LevelMeshSurface* LevelMesh::Trace(const FVector3& start, FVector3 direction, fl
}
hitSurface = hitmesh->GetSurface(hitmesh->Mesh.SurfaceIndexes[hit.triangle]);
auto portal = hitSurface->portalIndex;
int portal = hitSurface->PortalIndex;
if (!portal)
{
break;
@ -100,7 +100,7 @@ void LevelSubmesh::GatherSurfacePixelStats(LevelMeshSurfaceStats& stats)
for (int i = 0; i < count; ++i)
{
const auto* surface = GetSurface(i);
auto area = surface->Area();
auto area = surface->AtlasTile.Area();
stats.pixels.total += area;
@ -109,7 +109,7 @@ void LevelSubmesh::GatherSurfacePixelStats(LevelMeshSurfaceStats& stats)
stats.surfaces.dirty++;
stats.pixels.dirty += area;
}
if (surface->bSky)
if (surface->IsSky)
{
stats.surfaces.sky++;
stats.pixels.sky += area;
@ -133,12 +133,12 @@ void LevelSubmesh::BuildTileSurfaceLists()
for (size_t j = 0; j < SmoothingGroups.Size(); j++)
{
if (surface->sectorGroup == SmoothingGroups[j].sectorGroup)
if (surface->SectorGroup == SmoothingGroups[j].sectorGroup)
{
float direction = SmoothingGroups[j].plane.XYZ() | surface->plane.XYZ();
float direction = SmoothingGroups[j].plane.XYZ() | surface->Plane.XYZ();
if (direction >= 0.9999f && direction <= 1.001f)
{
auto point = (surface->plane.XYZ() * surface->plane.W);
auto point = (surface->Plane.XYZ() * surface->Plane.W);
auto planeDistance = (SmoothingGroups[j].plane.XYZ() | point) - SmoothingGroups[j].plane.W;
float dist = std::abs(planeDistance);
@ -157,8 +157,8 @@ void LevelSubmesh::BuildTileSurfaceLists()
smoothingGroupIndex = SmoothingGroups.Size();
LevelMeshSmoothingGroup group;
group.plane = surface->plane;
group.sectorGroup = surface->sectorGroup;
group.plane = surface->Plane;
group.sectorGroup = surface->SectorGroup;
SmoothingGroups.Push(group);
}
@ -169,23 +169,23 @@ void LevelSubmesh::BuildTileSurfaceLists()
for (int i = 0, count = GetSurfaceCount(); i < count; i++)
{
auto targetSurface = GetSurface(i);
targetSurface->tileSurfaces.Clear();
targetSurface->TileSurfaces.Clear();
for (LevelMeshSurface* surface : SmoothingGroups[SmoothingGroupIndexes[i]].surfaces)
{
FVector2 minUV = ToUV(surface->bounds.min, targetSurface);
FVector2 maxUV = ToUV(surface->bounds.max, targetSurface);
FVector2 minUV = ToUV(surface->Bounds.min, targetSurface);
FVector2 maxUV = ToUV(surface->Bounds.max, targetSurface);
if (surface != targetSurface && (maxUV.X < 0.0f || maxUV.Y < 0.0f || minUV.X > 1.0f || minUV.Y > 1.0f))
continue; // Bounding box not visible
targetSurface->tileSurfaces.Push(surface);
targetSurface->TileSurfaces.Push(surface);
}
}
}
FVector2 LevelSubmesh::ToUV(const FVector3& vert, const LevelMeshSurface* targetSurface)
{
FVector3 localPos = vert - targetSurface->translateWorldToLocal;
float u = (1.0f + (localPos | targetSurface->projLocalToU)) / (targetSurface->AtlasTile.Width + 2);
float v = (1.0f + (localPos | targetSurface->projLocalToV)) / (targetSurface->AtlasTile.Height + 2);
FVector3 localPos = vert - targetSurface->TileTransform.TranslateWorldToLocal;
float u = (1.0f + (localPos | targetSurface->TileTransform.ProjLocalToU)) / (targetSurface->AtlasTile.Width + 2);
float v = (1.0f + (localPos | targetSurface->TileTransform.ProjLocalToV)) / (targetSurface->AtlasTile.Height + 2);
return FVector2(u, v);
}

View file

@ -38,12 +38,15 @@ struct LevelMeshSurface
{
LevelSubmesh* Submesh = nullptr;
int numVerts = 0;
unsigned int startVertIndex = 0;
unsigned int startElementIndex = 0;
unsigned int numElements = 0;
FVector4 plane = FVector4(0.0f, 0.0f, 1.0f, 0.0f);
bool bSky = false;
struct
{
unsigned int StartVertIndex = 0;
int NumVerts = 0;
unsigned int StartElementIndex = 0;
unsigned int NumElements = 0;
} MeshLocation;
FVector4 Plane = FVector4(0.0f, 0.0f, 1.0f, 0.0f);
// Surface location in lightmap texture
struct
@ -53,30 +56,33 @@ struct LevelMeshSurface
int Width = 0;
int Height = 0;
int ArrayIndex = 0;
uint32_t Area() const { return Width * Height; }
} AtlasTile;
// True if the surface needs to be rendered into the lightmap texture before it can be used
bool NeedsUpdate = true;
bool AlwaysUpdate = false;
FGameTexture* texture = nullptr;
float alpha = 1.0;
FGameTexture* Texture = nullptr;
float Alpha = 1.0;
int portalIndex = 0;
int sectorGroup = 0;
bool IsSky = false;
int PortalIndex = 0;
int SectorGroup = 0;
BBox bounds;
uint16_t sampleDimension = 0;
BBox Bounds;
uint16_t SampleDimension = 0;
// Calculate world coordinates to UV coordinates
FVector3 translateWorldToLocal = { 0.f, 0.f, 0.f };
FVector3 projLocalToU = { 0.f, 0.f, 0.f };
FVector3 projLocalToV = { 0.f, 0.f, 0.f };
struct
{
FVector3 TranslateWorldToLocal = { 0.0f, 0.0f, 0.0f };
FVector3 ProjLocalToU = { 0.0f, 0.0f, 0.0f };
FVector3 ProjLocalToV = { 0.0f, 0.0f, 0.0f };
} TileTransform;
// Surfaces that are visible within the lightmap tile
TArray<LevelMeshSurface*> tileSurfaces;
uint32_t Area() const { return AtlasTile.Width * AtlasTile.Height; }
TArray<LevelMeshSurface*> TileSurfaces;
// Light list location in the lightmapper GPU buffers
struct

View file

@ -638,14 +638,14 @@ void VkLevelMeshUploader::UploadSurfaces()
LevelMeshSurface* surface = submesh->GetSurface(j);
SurfaceInfo info;
info.Normal = FVector3(surface->plane.X, surface->plane.Z, surface->plane.Y);
info.PortalIndex = surface->portalIndex;
info.SamplingDistance = (float)surface->sampleDimension;
info.Sky = surface->bSky;
info.Alpha = surface->alpha;
if (surface->texture)
info.Normal = FVector3(surface->Plane.X, surface->Plane.Z, surface->Plane.Y);
info.PortalIndex = surface->PortalIndex;
info.SamplingDistance = (float)surface->SampleDimension;
info.Sky = surface->IsSky;
info.Alpha = surface->Alpha;
if (surface->Texture)
{
auto mat = FMaterial::ValidateTexture(surface->texture, 0);
auto mat = FMaterial::ValidateTexture(surface->Texture, 0);
info.TextureIndex = Mesh->fb->GetBindlessTextureIndex(mat, CLAMP_NONE, 0);
}
else

View file

@ -200,14 +200,14 @@ void VkLightmapper::Render()
pc.TextureSize = (float)bakeImageSize;
pc.TileWidth = (float)targetSurface->AtlasTile.Width;
pc.TileHeight = (float)targetSurface->AtlasTile.Height;
pc.WorldToLocal = SwapYZ(targetSurface->translateWorldToLocal);
pc.ProjLocalToU = SwapYZ(targetSurface->projLocalToU);
pc.ProjLocalToV = SwapYZ(targetSurface->projLocalToV);
pc.WorldToLocal = SwapYZ(targetSurface->TileTransform.TranslateWorldToLocal);
pc.ProjLocalToU = SwapYZ(targetSurface->TileTransform.ProjLocalToU);
pc.ProjLocalToV = SwapYZ(targetSurface->TileTransform.ProjLocalToV);
bool buffersFull = false;
// Paint all surfaces visible in the tile
for (LevelMeshSurface* surface : targetSurface->tileSurfaces)
for (LevelMeshSurface* surface : targetSurface->TileSurfaces)
{
if (surface->LightList.ResetCounter != lights.ResetCounter)
{
@ -247,9 +247,9 @@ void VkLightmapper::Render()
#ifdef USE_DRAWINDIRECT
VkDrawIndexedIndirectCommand cmd;
cmd.indexCount = surface->numElements;
cmd.indexCount = surface->MeshLocation.NumElements;
cmd.instanceCount = 1;
cmd.firstIndex = firstIndexOffset + surface->startElementIndex;
cmd.firstIndex = firstIndexOffset + surface->MeshLocation.StartElementIndex;
cmd.vertexOffset = 0;
cmd.firstInstance = drawindexed.Pos;
drawindexed.Constants[drawindexed.Pos] = pc;
@ -419,7 +419,7 @@ void VkLightmapper::CopyResult()
}
copylists[pageIndex].Push(&selected);
pixels += selected.Surface->Area();
pixels += selected.Surface->AtlasTile.Area();
lastSurfaceCount++;
}
}