mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-04-21 10:20:46 +00:00
Change lightmapper to only use one image
This commit is contained in:
parent
644500de61
commit
39312e898f
6 changed files with 205 additions and 279 deletions
|
@ -54,6 +54,7 @@ struct LevelMeshSurface
|
|||
int texHeight = 0;
|
||||
|
||||
bool needsUpdate = true;
|
||||
bool alreadyInVisibleList = false;
|
||||
|
||||
//
|
||||
// Required for internal lightmapper:
|
||||
|
@ -83,18 +84,8 @@ struct LevelMeshSurface
|
|||
//
|
||||
inline uint32_t Area() const { return texWidth * texHeight; }
|
||||
|
||||
//
|
||||
// VkLightmap extra stuff that I dislike:
|
||||
//
|
||||
TArray<FVector3> verts;
|
||||
|
||||
// Touching light sources
|
||||
std::vector<const LevelMeshLight*> LightList;
|
||||
|
||||
// Lightmapper has a lot of additional padding around the borders
|
||||
int lightmapperAtlasPage = -1;
|
||||
int lightmapperAtlasX = -1;
|
||||
int lightmapperAtlasY = -1;
|
||||
};
|
||||
|
||||
inline float IsInFrontOfPlane(const FVector4& plane, const FVector3& point)
|
||||
|
|
|
@ -39,6 +39,7 @@ VkLightmap::VkLightmap(VulkanRenderDevice* fb) : fb(fb)
|
|||
CreateRaytracePipeline();
|
||||
CreateResolvePipeline();
|
||||
CreateBlurPipeline();
|
||||
CreateBakeImage();
|
||||
}
|
||||
|
||||
VkLightmap::~VkLightmap()
|
||||
|
@ -71,38 +72,14 @@ void VkLightmap::Raytrace(const TArray<LevelMeshSurface*>& surfaces)
|
|||
lightmapRaytrace.Clock();
|
||||
lightmapRaytraceLast.ResetAndClock();
|
||||
|
||||
CreateAtlasImages(surfaces);
|
||||
|
||||
uint32_t pixels = 0;
|
||||
|
||||
for (auto& surface : surfaces)
|
||||
SelectSurfaces(surfaces);
|
||||
if (selectedSurfaces.Size() > 0)
|
||||
{
|
||||
surface->needsUpdate = false; // it may have been set to false already, but lightmapper ultimately decides so
|
||||
pixels += surface->Area();
|
||||
}
|
||||
|
||||
UploadUniforms();
|
||||
|
||||
lastSurfaceCount = surfaces.Size();
|
||||
lastPixelCount = pixels;
|
||||
totalPixelCount += pixels;
|
||||
|
||||
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
|
||||
{
|
||||
if (atlasImages[pageIndex].pageMaxX && atlasImages[pageIndex].pageMaxY)
|
||||
{
|
||||
RenderAtlasImage(pageIndex, surfaces);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
|
||||
{
|
||||
if (atlasImages[pageIndex].pageMaxX && atlasImages[pageIndex].pageMaxY)
|
||||
{
|
||||
ResolveAtlasImage(pageIndex);
|
||||
BlurAtlasImage(pageIndex);
|
||||
CopyAtlasImageResult(pageIndex, surfaces);
|
||||
}
|
||||
UploadUniforms();
|
||||
RenderBakeImage();
|
||||
ResolveBakeImage();
|
||||
BlurBakeImage();
|
||||
CopyBakeImageResult();
|
||||
}
|
||||
|
||||
lightmapRaytrace.Unclock();
|
||||
|
@ -110,45 +87,79 @@ void VkLightmap::Raytrace(const TArray<LevelMeshSurface*>& surfaces)
|
|||
}
|
||||
}
|
||||
|
||||
void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray<LevelMeshSurface*>& surfaces)
|
||||
void VkLightmap::SelectSurfaces(const TArray<LevelMeshSurface*>& surfaces)
|
||||
{
|
||||
LightmapImage& img = atlasImages[pageIndex];
|
||||
bakeImage.maxX = 0;
|
||||
bakeImage.maxY = 0;
|
||||
selectedSurfaces.Clear();
|
||||
|
||||
// Begin with clear
|
||||
{
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
RenderPassBegin()
|
||||
.RenderPass(raytrace.renderPassBegin.get())
|
||||
.RenderArea(0, 0, atlasImageSize, atlasImageSize)
|
||||
.Framebuffer(img.raytrace.Framebuffer.get())
|
||||
.AddClearColor(0.0f, 0.0f, 0.0f, 0.0f)
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
VkDeviceSize offset = 0;
|
||||
cmdbuffer->bindVertexBuffers(0, 1, &vertices.Buffer->buffer, &offset);
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipeline.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 0, raytrace.descriptorSet0.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 1, raytrace.descriptorSet1.get());
|
||||
}
|
||||
const int spacing = 3; // Note: the spacing is here to avoid that the resolve sampler finds data from other surface tiles
|
||||
RectPacker packer(bakeImageSize, bakeImageSize, RectPacker::Spacing(spacing));
|
||||
|
||||
for (int i = 0, count = surfaces.Size(); i < count; i++)
|
||||
{
|
||||
LevelMeshSurface* targetSurface = surfaces[i];
|
||||
if (targetSurface->lightmapperAtlasPage != pageIndex)
|
||||
continue;
|
||||
LevelMeshSurface* surface = surfaces[i];
|
||||
|
||||
if (targetSurface->LightList.empty() && (targetSurface->plane.XYZ() | mesh->SunDirection) < 0.0f) // No lights, no sun //TODO fill the area with black pixels skipping blur and resolve pass
|
||||
// All surfaces needs to be updated until we rendered them.
|
||||
surface->needsUpdate = true;
|
||||
|
||||
// Only grab surfaces until our bake texture is full
|
||||
auto result = packer.insert(surface->texWidth + 2, surface->texHeight + 2);
|
||||
if (result.pageIndex == 0)
|
||||
{
|
||||
SelectedSurface selected;
|
||||
selected.Surface = surface;
|
||||
selected.X = result.pos.x + 1;
|
||||
selected.Y = result.pos.y + 1;
|
||||
selectedSurfaces.Push(selected);
|
||||
|
||||
bakeImage.maxX = std::max<uint16_t>(bakeImage.maxX, uint16_t(selected.X + surface->texWidth + spacing));
|
||||
bakeImage.maxY = std::max<uint16_t>(bakeImage.maxY, uint16_t(selected.Y + surface->texHeight + spacing));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VkLightmap::RenderBakeImage()
|
||||
{
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
RenderPassBegin()
|
||||
.RenderPass(raytrace.renderPass.get())
|
||||
.RenderArea(0, 0, bakeImageSize, bakeImageSize)
|
||||
.Framebuffer(bakeImage.raytrace.Framebuffer.get())
|
||||
.AddClearColor(0.0f, 0.0f, 0.0f, 0.0f)
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
VkDeviceSize offset = 0;
|
||||
cmdbuffer->bindVertexBuffers(0, 1, &vertices.Buffer->buffer, &offset);
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipeline.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 0, raytrace.descriptorSet0.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 1, raytrace.descriptorSet1.get());
|
||||
|
||||
lights.Pos = 0;
|
||||
vertices.Pos = 0;
|
||||
|
||||
for (int i = 0, count = selectedSurfaces.Size(); i < count; i++)
|
||||
{
|
||||
auto& selectedSurface = selectedSurfaces[i];
|
||||
LevelMeshSurface* targetSurface = selectedSurface.Surface;
|
||||
|
||||
if (targetSurface->LightList.empty() && (targetSurface->plane.XYZ() | mesh->SunDirection) < 0.0f) // No lights, no sun
|
||||
{
|
||||
selectedSurface.Rendered = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
VkViewport viewport = {};
|
||||
viewport.maxDepth = 1;
|
||||
viewport.x = (float)targetSurface->lightmapperAtlasX - 1;
|
||||
viewport.y = (float)targetSurface->lightmapperAtlasY - 1;
|
||||
viewport.x = (float)selectedSurface.X - 1;
|
||||
viewport.y = (float)selectedSurface.Y - 1;
|
||||
viewport.width = (float)(targetSurface->texWidth + 2);
|
||||
viewport.height = (float)(targetSurface->texHeight + 2);
|
||||
fb->GetCommands()->GetTransferCommands()->setViewport(0, 1, &viewport);
|
||||
|
||||
bool buffersFull = false;
|
||||
|
||||
// Paint all surfaces part of the smoothing group into the surface
|
||||
for (LevelMeshSurface* surface : mesh->SmoothingGroups[targetSurface->smoothingGroupIndex].surfaces)
|
||||
{
|
||||
|
@ -157,46 +168,18 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray<LevelMeshSurfac
|
|||
if (surface != targetSurface && (maxUV.X < 0.0f || maxUV.Y < 0.0f || minUV.X > 1.0f || minUV.Y > 1.0f))
|
||||
continue; // Bounding box not visible
|
||||
|
||||
int firstLight = lights.Pos;
|
||||
int firstVertex = vertices.Pos;
|
||||
int lightCount = (int)surface->LightList.size();
|
||||
int vertexCount = (int)surface->verts.Size();
|
||||
int vertexCount = surface->numVerts;
|
||||
|
||||
if (lights.Pos + lightCount > lights.BufferSize || vertices.Pos + vertexCount > vertices.BufferSize)
|
||||
{
|
||||
// Flush scene buffers
|
||||
fb->GetCommands()->GetTransferCommands()->endRenderPass();
|
||||
fb->GetCommands()->WaitForCommands(false);
|
||||
lights.Pos = 0;
|
||||
vertices.Pos = 0;
|
||||
firstLight = 0;
|
||||
firstVertex = 0;
|
||||
|
||||
// Begin without clear
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
RenderPassBegin()
|
||||
.RenderPass(raytrace.renderPassContinue.get())
|
||||
.RenderArea(0, 0, atlasImageSize, atlasImageSize)
|
||||
.Framebuffer(img.raytrace.Framebuffer.get())
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
VkDeviceSize offset = 0;
|
||||
cmdbuffer->bindVertexBuffers(0, 1, &vertices.Buffer->buffer, &offset);
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipeline.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 0, raytrace.descriptorSet0.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 1, raytrace.descriptorSet1.get());
|
||||
|
||||
cmdbuffer->setViewport(0, 1, &viewport);
|
||||
|
||||
if (lights.Pos + lightCount > lights.BufferSize)
|
||||
{
|
||||
throw std::runtime_error("SceneLightBuffer is too small!");
|
||||
}
|
||||
else if (vertices.Pos + vertexCount > vertices.BufferSize)
|
||||
{
|
||||
throw std::runtime_error("SceneVertexBuffer is too small!");
|
||||
}
|
||||
// Our vertex or light buffer is full. Postpone the rest.
|
||||
buffersFull = true;
|
||||
break;
|
||||
}
|
||||
|
||||
int firstLight = lights.Pos;
|
||||
int firstVertex = vertices.Pos;
|
||||
lights.Pos += lightCount;
|
||||
vertices.Pos += vertexCount;
|
||||
|
||||
|
@ -229,57 +212,29 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray<LevelMeshSurfac
|
|||
{
|
||||
for (int idx = 0; idx < vertexCount; idx++)
|
||||
{
|
||||
(vertex++)->Position = ToUV(surface->verts[idx], targetSurface);
|
||||
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + idx], targetSurface);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(vertex++)->Position = ToUV(surface->verts[0], targetSurface);
|
||||
(vertex++)->Position = ToUV(surface->verts[2], targetSurface);
|
||||
(vertex++)->Position = ToUV(surface->verts[3], targetSurface);
|
||||
(vertex++)->Position = ToUV(surface->verts[1], targetSurface);
|
||||
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 0], targetSurface);
|
||||
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 2], targetSurface);
|
||||
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 3], targetSurface);
|
||||
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 1], targetSurface);
|
||||
}
|
||||
|
||||
fb->GetCommands()->GetTransferCommands()->draw(vertexCount, 1, firstVertex, 0);
|
||||
}
|
||||
|
||||
if (buffersFull)
|
||||
break;
|
||||
|
||||
selectedSurface.Rendered = true;
|
||||
}
|
||||
|
||||
fb->GetCommands()->GetTransferCommands()->endRenderPass();
|
||||
}
|
||||
|
||||
void VkLightmap::CreateAtlasImages(const TArray<LevelMeshSurface*>& surfaces)
|
||||
{
|
||||
for (auto& page : atlasImages)
|
||||
{
|
||||
page.pageMaxX = 0;
|
||||
page.pageMaxY = 0;
|
||||
}
|
||||
|
||||
const int spacing = 3; // Note: the spacing is here to avoid that the resolve sampler finds data from other surface tiles
|
||||
RectPacker packer(atlasImageSize, atlasImageSize, RectPacker::Spacing(spacing));
|
||||
|
||||
size_t pageIndex = atlasImages.size();
|
||||
|
||||
for (int i = 0, count = surfaces.Size(); i < count; i++)
|
||||
{
|
||||
LevelMeshSurface* surface = surfaces[i];
|
||||
|
||||
auto result = packer.insert(surface->texWidth + 2, surface->texHeight + 2);
|
||||
surface->lightmapperAtlasX = result.pos.x + 1;
|
||||
surface->lightmapperAtlasY = result.pos.y + 1;
|
||||
surface->lightmapperAtlasPage = (int)result.pageIndex;
|
||||
|
||||
for (;pageIndex <= result.pageIndex; pageIndex++)
|
||||
{
|
||||
atlasImages.push_back(CreateImage(atlasImageSize, atlasImageSize));
|
||||
}
|
||||
|
||||
auto& image = atlasImages[result.pageIndex];
|
||||
image.pageMaxX = std::max<uint16_t>(image.pageMaxX, uint16_t(surface->lightmapperAtlasX + surface->texWidth + spacing));
|
||||
image.pageMaxY = std::max<uint16_t>(image.pageMaxY, uint16_t(surface->lightmapperAtlasY + surface->texHeight + spacing));
|
||||
}
|
||||
}
|
||||
|
||||
void VkLightmap::UploadUniforms()
|
||||
{
|
||||
Uniforms values = {};
|
||||
|
@ -298,31 +253,29 @@ void VkLightmap::UploadUniforms()
|
|||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
}
|
||||
|
||||
void VkLightmap::ResolveAtlasImage(size_t pageIndex)
|
||||
void VkLightmap::ResolveBakeImage()
|
||||
{
|
||||
LightmapImage& img = atlasImages[pageIndex];
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
PipelineBarrier()
|
||||
.AddImage(img.raytrace.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
|
||||
.AddImage(bakeImage.raytrace.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
|
||||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
RenderPassBegin()
|
||||
.RenderPass(resolve.renderPass.get())
|
||||
.RenderArea(0, 0, img.pageMaxX, img.pageMaxY)
|
||||
.Framebuffer(img.resolve.Framebuffer.get())
|
||||
.RenderArea(0, 0, bakeImage.maxX, bakeImage.maxY)
|
||||
.Framebuffer(bakeImage.resolve.Framebuffer.get())
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
VkDeviceSize offset = 0;
|
||||
cmdbuffer->bindVertexBuffers(0, 1, &vertices.Buffer->buffer, &offset);
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, resolve.pipeline.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, resolve.pipelineLayout.get(), 0, img.resolve.DescriptorSet.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, resolve.pipelineLayout.get(), 0, bakeImage.resolve.DescriptorSet.get());
|
||||
|
||||
VkViewport viewport = {};
|
||||
viewport.maxDepth = 1;
|
||||
viewport.width = (float)img.pageMaxX;
|
||||
viewport.height = (float)img.pageMaxY;
|
||||
viewport.width = (float)bakeImage.maxX;
|
||||
viewport.height = (float)bakeImage.maxY;
|
||||
cmdbuffer->setViewport(0, 1, &viewport);
|
||||
|
||||
LightmapPushConstants pc;
|
||||
|
@ -347,33 +300,31 @@ void VkLightmap::ResolveAtlasImage(size_t pageIndex)
|
|||
cmdbuffer->endRenderPass();
|
||||
}
|
||||
|
||||
void VkLightmap::BlurAtlasImage(size_t pageIndex)
|
||||
void VkLightmap::BlurBakeImage()
|
||||
{
|
||||
LightmapImage& img = atlasImages[pageIndex];
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
PipelineBarrier()
|
||||
.AddImage(img.resolve.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
|
||||
.AddImage(bakeImage.resolve.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
|
||||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
// Pass 0
|
||||
{
|
||||
RenderPassBegin()
|
||||
.RenderPass(blur.renderPass.get())
|
||||
.RenderArea(0, 0, img.pageMaxX, img.pageMaxY)
|
||||
.Framebuffer(img.blur.Framebuffer.get())
|
||||
.RenderArea(0, 0, bakeImage.maxX, bakeImage.maxY)
|
||||
.Framebuffer(bakeImage.blur.Framebuffer.get())
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
VkDeviceSize offset = 0;
|
||||
cmdbuffer->bindVertexBuffers(0, 1, &vertices.Buffer->buffer, &offset);
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, blur.pipeline[0].get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, blur.pipelineLayout.get(), 0, img.blur.DescriptorSet[0].get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, blur.pipelineLayout.get(), 0, bakeImage.blur.DescriptorSet[0].get());
|
||||
|
||||
VkViewport viewport = {};
|
||||
viewport.maxDepth = 1;
|
||||
viewport.width = (float)img.pageMaxX;
|
||||
viewport.height = (float)img.pageMaxY;
|
||||
viewport.width = (float)bakeImage.maxX;
|
||||
viewport.height = (float)bakeImage.maxY;
|
||||
cmdbuffer->setViewport(0, 1, &viewport);
|
||||
|
||||
LightmapPushConstants pc;
|
||||
|
@ -399,26 +350,26 @@ void VkLightmap::BlurAtlasImage(size_t pageIndex)
|
|||
}
|
||||
|
||||
PipelineBarrier()
|
||||
.AddImage(img.blur.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
|
||||
.AddImage(bakeImage.blur.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
|
||||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
// Pass 1 (outputs back into resolve fb)
|
||||
{
|
||||
RenderPassBegin()
|
||||
.RenderPass(blur.renderPass.get())
|
||||
.RenderArea(0, 0, img.pageMaxX, img.pageMaxY)
|
||||
.Framebuffer(img.resolve.Framebuffer.get())
|
||||
.RenderArea(0, 0, bakeImage.maxX, bakeImage.maxY)
|
||||
.Framebuffer(bakeImage.resolve.Framebuffer.get())
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
VkDeviceSize offset = 0;
|
||||
cmdbuffer->bindVertexBuffers(0, 1, &vertices.Buffer->buffer, &offset);
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, blur.pipeline[1].get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, blur.pipelineLayout.get(), 0, img.blur.DescriptorSet[1].get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, blur.pipelineLayout.get(), 0, bakeImage.blur.DescriptorSet[1].get());
|
||||
|
||||
VkViewport viewport = {};
|
||||
viewport.maxDepth = 1;
|
||||
viewport.width = (float)img.pageMaxX;
|
||||
viewport.height = (float)img.pageMaxY;
|
||||
viewport.width = (float)bakeImage.maxX;
|
||||
viewport.height = (float)bakeImage.maxY;
|
||||
cmdbuffer->setViewport(0, 1, &viewport);
|
||||
|
||||
LightmapPushConstants pc;
|
||||
|
@ -444,47 +395,61 @@ void VkLightmap::BlurAtlasImage(size_t pageIndex)
|
|||
}
|
||||
}
|
||||
|
||||
void VkLightmap::CopyAtlasImageResult(size_t pageIndex, const TArray<LevelMeshSurface*>& surfaces)
|
||||
void VkLightmap::CopyBakeImageResult()
|
||||
{
|
||||
LightmapImage& img = atlasImages[pageIndex];
|
||||
uint32_t pixels = 0;
|
||||
|
||||
std::set<int> seenPages;
|
||||
std::vector<VkImageCopy> regions;
|
||||
for (int i = 0, count = surfaces.Size(); i < count; i++)
|
||||
for (int i = 0, count = selectedSurfaces.Size(); i < count; i++)
|
||||
{
|
||||
LevelMeshSurface* surface = surfaces[i];
|
||||
if (surface->lightmapperAtlasPage != pageIndex)
|
||||
continue;
|
||||
auto& selected = selectedSurfaces[i];
|
||||
if (selected.Rendered)
|
||||
{
|
||||
LevelMeshSurface* surface = selected.Surface;
|
||||
VkImageCopy region = {};
|
||||
region.srcOffset.x = selected.X;
|
||||
region.srcOffset.y = selected.Y;
|
||||
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.srcSubresource.layerCount = 1;
|
||||
region.dstOffset.x = surface->atlasX;
|
||||
region.dstOffset.y = surface->atlasY;
|
||||
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.dstSubresource.layerCount = 1;
|
||||
region.dstSubresource.baseArrayLayer = surface->atlasPageIndex;
|
||||
region.extent.width = surface->texWidth;
|
||||
region.extent.height = surface->texHeight;
|
||||
region.extent.depth = 1;
|
||||
regions.push_back(region);
|
||||
seenPages.insert(surface->atlasPageIndex);
|
||||
|
||||
VkImageCopy region = {};
|
||||
region.srcOffset.x = surface->lightmapperAtlasX;
|
||||
region.srcOffset.y = surface->lightmapperAtlasY;
|
||||
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.srcSubresource.layerCount = 1;
|
||||
region.dstOffset.x = surface->atlasX;
|
||||
region.dstOffset.y = surface->atlasY;
|
||||
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.dstSubresource.layerCount = 1;
|
||||
region.dstSubresource.baseArrayLayer = surface->atlasPageIndex;
|
||||
region.extent.width = surface->texWidth;
|
||||
region.extent.height = surface->texHeight;
|
||||
region.extent.depth = 1;
|
||||
regions.push_back(region);
|
||||
// We rendered this surface. Does not need an update anymore.
|
||||
surface->needsUpdate = false;
|
||||
|
||||
pixels += surface->Area();
|
||||
lastSurfaceCount++;
|
||||
}
|
||||
}
|
||||
|
||||
lastPixelCount = pixels;
|
||||
totalPixelCount += pixels;
|
||||
|
||||
if (!regions.empty())
|
||||
{
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
PipelineBarrier()
|
||||
.AddImage(img.resolve.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT)
|
||||
.AddImage(fb->GetTextureManager()->Lightmap.Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, (int)pageIndex, 1)
|
||||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
PipelineBarrier barrier0;
|
||||
barrier0.AddImage(bakeImage.resolve.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
|
||||
for (int pageIndex : seenPages)
|
||||
barrier0.AddImage(fb->GetTextureManager()->Lightmap.Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, pageIndex, 1);
|
||||
barrier0.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
|
||||
cmdbuffer->copyImage(img.resolve.Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, fb->GetTextureManager()->Lightmap.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (uint32_t)regions.size(), regions.data());
|
||||
cmdbuffer->copyImage(bakeImage.resolve.Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, fb->GetTextureManager()->Lightmap.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (uint32_t)regions.size(), regions.data());
|
||||
|
||||
PipelineBarrier()
|
||||
.AddImage(fb->GetTextureManager()->Lightmap.Image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, (int)pageIndex, 1)
|
||||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
PipelineBarrier barrier1;
|
||||
for (int pageIndex : seenPages)
|
||||
barrier1.AddImage(fb->GetTextureManager()->Lightmap.Image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, pageIndex, 1);
|
||||
barrier1.Execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -584,7 +549,7 @@ void VkLightmap::CreateRaytracePipeline()
|
|||
.DebugName("raytrace.pipelineLayout")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
raytrace.renderPassBegin = RenderPassBuilder()
|
||||
raytrace.renderPass = RenderPassBuilder()
|
||||
.AddAttachment(
|
||||
VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
VK_SAMPLE_COUNT_4_BIT,
|
||||
|
@ -599,30 +564,12 @@ void VkLightmap::CreateRaytracePipeline()
|
|||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT)
|
||||
.DebugName("raytrace.renderPassBegin")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
raytrace.renderPassContinue = RenderPassBuilder()
|
||||
.AddAttachment(
|
||||
VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
VK_SAMPLE_COUNT_4_BIT,
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.AddSubpass()
|
||||
.AddSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.AddExternalSubpassDependency(
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT)
|
||||
.DebugName("raytrace.renderPassContinue")
|
||||
.DebugName("raytrace.renderPass")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
raytrace.pipeline = GraphicsPipelineBuilder()
|
||||
.Layout(raytrace.pipelineLayout.get())
|
||||
.RenderPass(raytrace.renderPassBegin.get())
|
||||
.RenderPass(raytrace.renderPass.get())
|
||||
.AddVertexShader(shaders.vert.get())
|
||||
.AddFragmentShader(shaders.fragRaytrace.get())
|
||||
.AddVertexBufferBinding(0, sizeof(SceneVertex))
|
||||
|
@ -808,11 +755,12 @@ void VkLightmap::CreateBlurPipeline()
|
|||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
LightmapImage VkLightmap::CreateImage(int width, int height)
|
||||
void VkLightmap::CreateBakeImage()
|
||||
{
|
||||
LightmapImage img;
|
||||
int width = bakeImageSize;
|
||||
int height = bakeImageSize;
|
||||
|
||||
img.raytrace.Image = ImageBuilder()
|
||||
bakeImage.raytrace.Image = ImageBuilder()
|
||||
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Size(width, height)
|
||||
|
@ -820,73 +768,71 @@ LightmapImage VkLightmap::CreateImage(int width, int height)
|
|||
.DebugName("LightmapImage.raytrace.Image")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
img.raytrace.View = ImageViewBuilder()
|
||||
.Image(img.raytrace.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
bakeImage.raytrace.View = ImageViewBuilder()
|
||||
.Image(bakeImage.raytrace.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("LightmapImage.raytrace.View")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
img.raytrace.Framebuffer = FramebufferBuilder()
|
||||
.RenderPass(raytrace.renderPassBegin.get())
|
||||
bakeImage.raytrace.Framebuffer = FramebufferBuilder()
|
||||
.RenderPass(raytrace.renderPass.get())
|
||||
.Size(width, height)
|
||||
.AddAttachment(img.raytrace.View.get())
|
||||
.AddAttachment(bakeImage.raytrace.View.get())
|
||||
.DebugName("LightmapImage.raytrace.Framebuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
img.resolve.Image = ImageBuilder()
|
||||
bakeImage.resolve.Image = ImageBuilder()
|
||||
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Size(width, height)
|
||||
.DebugName("LightmapImage.resolve.Image")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
img.resolve.View = ImageViewBuilder()
|
||||
.Image(img.resolve.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
bakeImage.resolve.View = ImageViewBuilder()
|
||||
.Image(bakeImage.resolve.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("LightmapImage.resolve.View")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
img.resolve.Framebuffer = FramebufferBuilder()
|
||||
bakeImage.resolve.Framebuffer = FramebufferBuilder()
|
||||
.RenderPass(resolve.renderPass.get())
|
||||
.Size(width, height)
|
||||
.AddAttachment(img.resolve.View.get())
|
||||
.AddAttachment(bakeImage.resolve.View.get())
|
||||
.DebugName("LightmapImage.resolve.Framebuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
img.resolve.DescriptorSet = resolve.descriptorPool->allocate(resolve.descriptorSetLayout.get());
|
||||
img.resolve.DescriptorSet->SetDebugName("resolve.descriptorSet");
|
||||
bakeImage.resolve.DescriptorSet = resolve.descriptorPool->allocate(resolve.descriptorSetLayout.get());
|
||||
bakeImage.resolve.DescriptorSet->SetDebugName("resolve.descriptorSet");
|
||||
|
||||
|
||||
img.blur.Image = ImageBuilder()
|
||||
bakeImage.blur.Image = ImageBuilder()
|
||||
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Size(width, height)
|
||||
.DebugName("LightmapImage.blur.Image")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
img.blur.View = ImageViewBuilder()
|
||||
.Image(img.blur.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
bakeImage.blur.View = ImageViewBuilder()
|
||||
.Image(bakeImage.blur.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("LightmapImage.blur.View")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
img.blur.Framebuffer = FramebufferBuilder()
|
||||
bakeImage.blur.Framebuffer = FramebufferBuilder()
|
||||
.RenderPass(blur.renderPass.get())
|
||||
.Size(width, height)
|
||||
.AddAttachment(img.blur.View.get())
|
||||
.AddAttachment(bakeImage.blur.View.get())
|
||||
.DebugName("LightmapImage.blur.Framebuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
img.blur.DescriptorSet[0] = blur.descriptorPool->allocate(blur.descriptorSetLayout.get());
|
||||
img.blur.DescriptorSet[0]->SetDebugName("blur.descriptorSet");
|
||||
bakeImage.blur.DescriptorSet[0] = blur.descriptorPool->allocate(blur.descriptorSetLayout.get());
|
||||
bakeImage.blur.DescriptorSet[0]->SetDebugName("blur.descriptorSet");
|
||||
|
||||
img.blur.DescriptorSet[1] = blur.descriptorPool->allocate(blur.descriptorSetLayout.get());
|
||||
img.blur.DescriptorSet[1]->SetDebugName("blur.descriptorSet");
|
||||
bakeImage.blur.DescriptorSet[1] = blur.descriptorPool->allocate(blur.descriptorSetLayout.get());
|
||||
bakeImage.blur.DescriptorSet[1]->SetDebugName("blur.descriptorSet");
|
||||
|
||||
WriteDescriptors()
|
||||
.AddCombinedImageSampler(img.resolve.DescriptorSet.get(), 0, img.raytrace.View.get(), resolve.sampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
.AddCombinedImageSampler(img.blur.DescriptorSet[0].get(), 0, img.resolve.View.get(), blur.sampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
.AddCombinedImageSampler(img.blur.DescriptorSet[1].get(), 0, img.blur.View.get(), blur.sampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
.AddCombinedImageSampler(bakeImage.resolve.DescriptorSet.get(), 0, bakeImage.raytrace.View.get(), resolve.sampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
.AddCombinedImageSampler(bakeImage.blur.DescriptorSet[0].get(), 0, bakeImage.resolve.View.get(), blur.sampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
.AddCombinedImageSampler(bakeImage.blur.DescriptorSet[1].get(), 0, bakeImage.blur.View.get(), blur.sampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
.Execute(fb->GetDevice());
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
void VkLightmap::CreateUniformBuffer()
|
||||
|
|
|
@ -31,7 +31,7 @@ struct LightmapPushConstants
|
|||
float PushPadding4;
|
||||
};
|
||||
|
||||
struct LightmapImage
|
||||
struct LightmapBakeImage
|
||||
{
|
||||
struct
|
||||
{
|
||||
|
@ -56,9 +56,9 @@ struct LightmapImage
|
|||
std::unique_ptr<VulkanDescriptorSet> DescriptorSet[2];
|
||||
} blur;
|
||||
|
||||
// how much of the page is used?
|
||||
uint16_t pageMaxX = 0;
|
||||
uint16_t pageMaxY = 0;
|
||||
// how much of the image is used for the baking
|
||||
uint16_t maxX = 0;
|
||||
uint16_t maxY = 0;
|
||||
};
|
||||
|
||||
struct SceneVertex
|
||||
|
@ -82,6 +82,14 @@ struct LightInfo
|
|||
float Padding3;
|
||||
};
|
||||
|
||||
struct SelectedSurface
|
||||
{
|
||||
LevelMeshSurface* Surface = nullptr;
|
||||
int X = -1;
|
||||
int Y = -1;
|
||||
bool Rendered = false;
|
||||
};
|
||||
|
||||
static_assert(sizeof(LightInfo) == sizeof(float) * 20);
|
||||
|
||||
class VkLightmap
|
||||
|
@ -92,17 +100,16 @@ public:
|
|||
|
||||
void Raytrace(const TArray<LevelMeshSurface*>& surfaces);
|
||||
void SetLevelMesh(LevelMesh* level);
|
||||
|
||||
private:
|
||||
void UpdateAccelStructDescriptors();
|
||||
|
||||
void SelectSurfaces(const TArray<LevelMeshSurface*>& surfaces);
|
||||
void UploadUniforms();
|
||||
void CreateAtlasImages(const TArray<LevelMeshSurface*>& surfaces);
|
||||
void RenderAtlasImage(size_t pageIndex, const TArray<LevelMeshSurface*>& surfaces);
|
||||
void ResolveAtlasImage(size_t pageIndex);
|
||||
void BlurAtlasImage(size_t pageIndex);
|
||||
void CopyAtlasImageResult(size_t pageIndex, const TArray<LevelMeshSurface*>& surfaces);
|
||||
void RenderBakeImage();
|
||||
void ResolveBakeImage();
|
||||
void BlurBakeImage();
|
||||
void CopyBakeImageResult();
|
||||
|
||||
LightmapImage CreateImage(int width, int height);
|
||||
void UpdateAccelStructDescriptors();
|
||||
|
||||
void CreateShaders();
|
||||
void CreateRaytracePipeline();
|
||||
|
@ -111,6 +118,7 @@ private:
|
|||
void CreateUniformBuffer();
|
||||
void CreateSceneVertexBuffer();
|
||||
void CreateSceneLightBuffer();
|
||||
void CreateBakeImage();
|
||||
|
||||
static FVector2 ToUV(const FVector3& vert, const LevelMeshSurface* targetSurface);
|
||||
|
||||
|
@ -121,6 +129,8 @@ private:
|
|||
|
||||
bool useRayQuery = true;
|
||||
|
||||
TArray<SelectedSurface> selectedSurfaces;
|
||||
|
||||
struct
|
||||
{
|
||||
std::unique_ptr<VulkanBuffer> Buffer;
|
||||
|
@ -162,8 +172,7 @@ private:
|
|||
std::unique_ptr<VulkanDescriptorSetLayout> descriptorSetLayout1;
|
||||
std::unique_ptr<VulkanPipelineLayout> pipelineLayout;
|
||||
std::unique_ptr<VulkanPipeline> pipeline;
|
||||
std::unique_ptr<VulkanRenderPass> renderPassBegin;
|
||||
std::unique_ptr<VulkanRenderPass> renderPassContinue;
|
||||
std::unique_ptr<VulkanRenderPass> renderPass;
|
||||
std::unique_ptr<VulkanDescriptorPool> descriptorPool0;
|
||||
std::unique_ptr<VulkanDescriptorPool> descriptorPool1;
|
||||
std::unique_ptr<VulkanDescriptorSet> descriptorSet0;
|
||||
|
@ -190,6 +199,6 @@ private:
|
|||
std::unique_ptr<VulkanSampler> sampler;
|
||||
} blur;
|
||||
|
||||
std::vector<LightmapImage> atlasImages;
|
||||
static const int atlasImageSize = 2048;
|
||||
LightmapBakeImage bakeImage;
|
||||
static const int bakeImageSize = 2048;
|
||||
};
|
||||
|
|
|
@ -221,7 +221,7 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun
|
|||
|
||||
if (newPixelData.Size() >= (size_t)w * h * count * 3)
|
||||
{
|
||||
assert(newPixelData.Size() == w * h * count * 3);
|
||||
assert(newPixelData.Size() == (size_t)w * h * count * 3);
|
||||
|
||||
int totalSize = w * h * count * pixelsize;
|
||||
|
||||
|
|
|
@ -476,17 +476,6 @@ void VulkanRenderDevice::BeginFrame()
|
|||
levelMesh->UpdateLightLists();
|
||||
GetTextureManager()->CreateLightmap(levelMesh->LMTextureSize, levelMesh->LMTextureCount, std::move(levelMesh->LMTextureData));
|
||||
GetLightmap()->SetLevelMesh(levelMesh);
|
||||
|
||||
#if 0 // full lightmap generation
|
||||
TArray<LevelMeshSurface*> surfaces;
|
||||
surfaces.Reserve(mesh->GetSurfaceCount());
|
||||
for (unsigned i = 0, count = mesh->GetSurfaceCount(); i < count; ++i)
|
||||
{
|
||||
surfaces[i] = mesh->GetSurface(i);
|
||||
}
|
||||
|
||||
GetLightmap()->Raytrace(surfaces);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1079,15 +1079,6 @@ void DoomLevelMesh::SetupLightmapUvs()
|
|||
sortedSurfaces.push_back(&surface);
|
||||
}
|
||||
|
||||
// VkLightmapper old ZDRay properties
|
||||
for (auto& surface : Surfaces)
|
||||
{
|
||||
for (int i = 0; i < surface.numVerts; ++i)
|
||||
{
|
||||
surface.verts.Push(MeshVertices[surface.startVertIndex + i]);
|
||||
}
|
||||
}
|
||||
|
||||
BuildSmoothingGroups();
|
||||
|
||||
std::sort(sortedSurfaces.begin(), sortedSurfaces.end(), [](LevelMeshSurface* a, LevelMeshSurface* b) { return a->texHeight != b->texHeight ? a->texHeight > b->texHeight : a->texWidth > b->texWidth; });
|
||||
|
|
Loading…
Reference in a new issue