Fix surface index passed to glsl

This commit is contained in:
RaveYard 2023-09-08 23:55:03 +02:00 committed by Christoph Oelckers
parent 710e151c06
commit acc50ef36e
8 changed files with 67 additions and 30 deletions

View file

@ -258,7 +258,7 @@ protected:
EPassType mPassType = NORMAL_PASS;
TArray<LevelMeshSurface*> mActiveLightmapSurfaces;
TArray<int> mActiveLightmapSurfaces;
public:
uint64_t firstFrame = 0;
@ -731,10 +731,10 @@ public:
return SetViewpoint(matrices);
}
inline void PushVisibleSurface(LevelMeshSurface* surface)
inline void PushVisibleSurface(int surfaceIndex, LevelMeshSurface* surface)
{
if(surface && surface->needsUpdate && mActiveLightmapSurfaces.Find(surface) >= mActiveLightmapSurfaces.Size()) // yikes, how awful
mActiveLightmapSurfaces.Push(surface);
if(surface->needsUpdate && mActiveLightmapSurfaces.Find(surfaceIndex) >= mActiveLightmapSurfaces.Size()) // yikes, how awful
mActiveLightmapSurfaces.Push(surfaceIndex);
}
inline const auto& GetVisibleSurfaceList() const

View file

@ -156,7 +156,7 @@ public:
virtual bool IsPoly() { return false; }
virtual bool CompileNextShader() { return true; }
virtual void SetLevelMesh(LevelMesh *mesh) { }
virtual void UpdateLightmaps(const TArray<LevelMeshSurface*>& surfaces) {}
virtual void UpdateLightmaps(const TArray<int>& surfaceIndices) {}
bool allowSSBO() const
{
#ifndef HW_BLOCK_SSBO

View file

@ -42,49 +42,78 @@ ADD_STAT(lightmapper)
return out;
}
void VkLightmap::Raytrace(LevelMesh* level, const TArray<LevelMeshSurface*>& surfaces)
#include <set>
void VkLightmap::Raytrace(LevelMesh* level, const TArray<int>& surfaceIndices)
{
bool newLevel = (mesh != level);
mesh = level;
if (newLevel)
{
UpdateAccelStructDescriptors();
CreateAtlasImages();
lightmapRaytrace.Reset();
lightmapRaytraceLast.Reset();
}
lightmapRaytrace.active = true;
lightmapRaytraceLast.active = true;
lightmapRaytrace.Clock();
lightmapRaytraceLast.ResetAndClock();
if (newLevel)
#if 0
TArray<int> allSurfaces;
std::set<int> s;
for (auto& surface : surfaceIndices)
{
UpdateAccelStructDescriptors();
CreateAtlasImages();
s.insert(mesh->GetSurface(surface)->smoothingGroupIndex);
}
for (auto surface : surfaces)
for (int i = 0, count = level->GetSurfaceCount(); i < count; ++i)
{
surface->needsUpdate = false;
auto surface = level->GetSurface(i);
if (s.find(surface->smoothingGroupIndex) != s.end())
{
allSurfaces.Push(i);
surface->needsUpdate = false;
}
}
#else
for (auto& surface : surfaceIndices)
{
mesh->GetSurface(surface)->needsUpdate = false;
}
const auto& allSurfaces = surfaceIndices;
#endif
UploadUniforms();
lastSurfaceCount = surfaces.Size();
lastSurfaceCount = allSurfaces.Size();
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
RenderAtlasImage(pageIndex, surfaces);
RenderAtlasImage(pageIndex, allSurfaces);
}
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
ResolveAtlasImage(pageIndex);
BlurAtlasImage(pageIndex);
CopyAtlasImageResult(pageIndex, surfaces);
CopyAtlasImageResult(pageIndex, allSurfaces);
}
lightmapRaytrace.Unclock();
lightmapRaytraceLast.Unclock();
}
void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray<LevelMeshSurface*>& surfaces)
void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray<int>& surfaceIndices)
{
LightmapImage& img = atlasImages[pageIndex];
@ -106,9 +135,9 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray<LevelMeshSurfac
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 1, raytrace.descriptorSet1.get());
}
for (int i = 0, count = surfaces.Size(); i < count; i++)
for (int i = 0, count = surfaceIndices.Size(); i < count; i++)
{
LevelMeshSurface* targetSurface = surfaces[i];
LevelMeshSurface* targetSurface = mesh->GetSurface(surfaceIndices[i]);
if (targetSurface->lightmapperAtlasPage != pageIndex)
continue;
@ -187,7 +216,7 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray<LevelMeshSurfac
LightmapPushConstants pc;
pc.LightStart = firstLight;
pc.LightEnd = firstLight + lightCount;
pc.SurfaceIndex = (int32_t)i;
pc.SurfaceIndex = (int32_t)std::distance((char*)mesh->GetSurface(0), (char*)targetSurface) / 288;
pc.LightmapOrigin = targetSurface->worldOrigin - targetSurface->worldStepX - targetSurface->worldStepY;
pc.LightmapStepX = targetSurface->worldStepX * viewport.width;
pc.LightmapStepY = targetSurface->worldStepY * viewport.height;
@ -402,14 +431,14 @@ void VkLightmap::BlurAtlasImage(size_t pageIndex)
}
}
void VkLightmap::CopyAtlasImageResult(size_t pageIndex, const TArray<LevelMeshSurface*>& surfaces)
void VkLightmap::CopyAtlasImageResult(size_t pageIndex, const TArray<int>& surfaceIndices)
{
LightmapImage& img = atlasImages[pageIndex];
std::vector<VkImageCopy> regions;
for (int i = 0, count = surfaces.Size(); i < count; i++)
for (int i = 0, count = surfaceIndices.Size(); i < count; i++)
{
LevelMeshSurface* surface = surfaces[i];
LevelMeshSurface* surface = mesh->GetSurface(surfaceIndices[i]);
if (surface->lightmapperAtlasPage != pageIndex)
continue;

View file

@ -86,17 +86,17 @@ public:
VkLightmap(VulkanRenderDevice* fb);
~VkLightmap();
void Raytrace(LevelMesh* level, const TArray<LevelMeshSurface*>& surfaces);
void Raytrace(LevelMesh* level, const TArray<int>& surfaceIndices);
private:
void UpdateAccelStructDescriptors();
void UploadUniforms();
void CreateAtlasImages();
void RenderAtlasImage(size_t pageIndex, const TArray<LevelMeshSurface*>& surfaces);
void RenderAtlasImage(size_t pageIndex, const TArray<int>& surfaceIndices);
void ResolveAtlasImage(size_t pageIndex);
void BlurAtlasImage(size_t pageIndex);
void CopyAtlasImageResult(size_t pageIndex, const TArray<LevelMeshSurface*>& surfaces);
void CopyAtlasImageResult(size_t pageIndex, const TArray<int>& surfaceIndices);
LightmapImage CreateImage(int width, int height);

View file

@ -559,15 +559,15 @@ void VulkanRenderDevice::SetLevelMesh(LevelMesh* mesh)
}
}
void VulkanRenderDevice::UpdateLightmaps(const TArray<LevelMeshSurface*>& surfaces)
void VulkanRenderDevice::UpdateLightmaps(const TArray<int>& surfaceIndices)
{
if (surfaces.Size() > 0)
if (surfaceIndices.Size() > 0)
{
auto levelMesh = lastMesh; // There's nothing more permanent than a temporary solution
if (levelMesh)
{
GetLightmap()->Raytrace(levelMesh, surfaces);
GetLightmap()->Raytrace(levelMesh, surfaceIndices);
}
}
}

View file

@ -63,7 +63,7 @@ public:
void AmbientOccludeScene(float m5) override;
void SetSceneRenderTarget(bool useSSAO) override;
void SetLevelMesh(LevelMesh* mesh) override;
void UpdateLightmaps(const TArray<LevelMeshSurface*>& surfaces) override;
void UpdateLightmaps(const TArray<int>& surfaceIndices) override;
void SetShadowMaps(const TArray<float>& lights, hwrenderer::LevelAABBTree* tree, bool newTree) override;
void SetSaveBuffers(bool yes) override;
void ImageTransitionScene(bool unknown) override;

View file

@ -194,7 +194,11 @@ void HWFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
for (auto& subsector : section->subsectors)
{
state.PushVisibleSurface(subsector->lightmap[ceiling ? 1 : 0][0]);
auto lightmap = subsector->lightmap[ceiling ? 1 : 0][0];
if (lightmap)
{
state.PushVisibleSurface(lightmap - &subsector->sector->Level->levelMesh->Surfaces[0], lightmap);
}
}
state.DrawIndexed(DT_Triangles, iboindex + section->vertexindex, section->vertexcount);

View file

@ -347,7 +347,11 @@ void HWWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent)
MakeVertices(di, state, !!(flags & HWWall::HWF_TRANSLUCENT));
}
state.PushVisibleSurface(lightmap);
if (lightmap)
{
state.PushVisibleSurface(lightmap - &seg->Subsector->sector->Level->levelMesh->Surfaces[0], lightmap);
}
state.SetNormal(glseg.Normal());
if (!translucent)
{