Create probemap texture for every lightmap atlas texture

This commit is contained in:
Magnus Norddahl 2025-07-18 19:28:57 +02:00
commit 8faa4e65bc
5 changed files with 68 additions and 23 deletions

View file

@ -407,8 +407,9 @@ void VkDescriptorSetManager::UpdateBindlessDescriptorSet()
int index = FixedBindlessSlots;
for (auto& lightmap : fb->GetTextureManager()->Lightmaps)
{
Bindless.Writer.AddCombinedImageSampler(Bindless.Set.get(), 0, index, lightmap.View.get(), sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
index++;
Bindless.Writer.AddCombinedImageSampler(Bindless.Set.get(), 0, index, lightmap.Light.View.get(), sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
Bindless.Writer.AddCombinedImageSampler(Bindless.Set.get(), 0, index + 1, lightmap.Probe.View.get(), sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
index += 2;
}
Bindless.Writer.Execute(fb->GetDevice());

View file

@ -836,32 +836,51 @@ void VkTextureManager::SetLightmapCount(int size, int count)
for (int i = startIndex; i < count; i++)
{
Lightmaps[i].Image = ImageBuilder()
Lightmaps[i].Light.Image = ImageBuilder()
.Size(size, size)
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.DebugName("VkTextureManager.Lightmap")
.Create(fb->GetDevice());
Lightmaps[i].View = ImageViewBuilder()
Lightmaps[i].Light.View = ImageViewBuilder()
.Type(VK_IMAGE_VIEW_TYPE_2D)
.Image(Lightmaps[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
.Image(Lightmaps[i].Light.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
.DebugName("VkTextureManager.LightmapView")
.Create(fb->GetDevice());
Lightmaps[i].Probe.Image = ImageBuilder()
.Size(size, size)
.Format(VK_FORMAT_R16_UINT)
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.DebugName("VkTextureManager.Probemap")
.Create(fb->GetDevice());
Lightmaps[i].Probe.View = ImageViewBuilder()
.Type(VK_IMAGE_VIEW_TYPE_2D)
.Image(Lightmaps[i].Probe.Image.get(), VK_FORMAT_R16_UINT)
.DebugName("VkTextureManager.ProbemapView")
.Create(fb->GetDevice());
}
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
VkImageTransition barrier;
for (int i = startIndex; i < count; i++)
barrier.AddImage(&Lightmaps[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
{
barrier.AddImage(&Lightmaps[i].Light, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
barrier.AddImage(&Lightmaps[i].Probe, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
}
barrier.Execute(cmdbuffer);
}
void VkTextureManager::CreateLightmap(int size, int count, const TArray<uint16_t>& srcPixels)
{
for (auto& tex : Lightmaps)
tex.Reset(fb);
{
tex.Light.Reset(fb);
tex.Probe.Reset(fb);
}
Lightmaps.clear();
Lightmaps.resize(count);
@ -871,18 +890,31 @@ void VkTextureManager::CreateLightmap(int size, int count, const TArray<uint16_t
for (int i = 0; i < count; i++)
{
Lightmaps[i].Image = ImageBuilder()
Lightmaps[i].Light.Image = ImageBuilder()
.Size(w, h)
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.DebugName("VkTextureManager.Lightmap")
.Create(fb->GetDevice());
Lightmaps[i].View = ImageViewBuilder()
Lightmaps[i].Light.View = ImageViewBuilder()
.Type(VK_IMAGE_VIEW_TYPE_2D)
.Image(Lightmaps[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
.Image(Lightmaps[i].Light.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
.DebugName("VkTextureManager.LightmapView")
.Create(fb->GetDevice());
Lightmaps[i].Probe.Image = ImageBuilder()
.Size(w, h)
.Format(VK_FORMAT_R16_UINT)
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.DebugName("VkTextureManager.Probemap")
.Create(fb->GetDevice());
Lightmaps[i].Probe.View = ImageViewBuilder()
.Type(VK_IMAGE_VIEW_TYPE_2D)
.Image(Lightmaps[i].Probe.Image.get(), VK_FORMAT_R16_UINT)
.DebugName("VkTextureManager.ProbemapView")
.Create(fb->GetDevice());
}
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
@ -913,7 +945,10 @@ void VkTextureManager::CreateLightmap(int size, int count, const TArray<uint16_t
VkImageTransition barrier0;
for (int i = 0; i < count; i++)
barrier0.AddImage(&Lightmaps[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
{
barrier0.AddImage(&Lightmaps[i].Light, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
barrier0.AddImage(&Lightmaps[i].Probe, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
}
barrier0.Execute(cmdbuffer);
for (int i = 0; i < count; i++)
@ -925,7 +960,7 @@ void VkTextureManager::CreateLightmap(int size, int count, const TArray<uint16_t
region.imageExtent.width = w;
region.imageExtent.height = h;
region.bufferOffset = w * h * pixelsize * i;
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Lightmaps[i].Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Lightmaps[i].Light.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
}
fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer));
@ -933,13 +968,16 @@ void VkTextureManager::CreateLightmap(int size, int count, const TArray<uint16_t
VkImageTransition barrier1;
for (int i = 0; i < count; i++)
barrier1.AddImage(&Lightmaps[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
{
barrier1.AddImage(&Lightmaps[i].Light, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
barrier1.AddImage(&Lightmaps[i].Probe, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
}
barrier1.Execute(cmdbuffer);
}
void VkTextureManager::DownloadLightmap(int arrayIndex, uint16_t* buffer)
{
DownloadTexture(&Lightmaps[arrayIndex], buffer);
DownloadTexture(&Lightmaps[arrayIndex].Light, buffer);
}
void VkTextureManager::DownloadTexture(VkTextureImage* texture, uint16_t* buffer)

View file

@ -68,8 +68,14 @@ public:
int GetHWTextureCount() { return (int)Textures.size(); }
struct Lightmap
{
VkTextureImage Light;
VkTextureImage Probe;
};
VkTextureImage Shadowmap;
std::vector<VkTextureImage> Lightmaps;
std::vector<Lightmap> Lightmaps;
std::vector<VkTextureImage> Irradiancemaps;
std::vector<VkTextureImage> Prefiltermaps;

View file

@ -402,7 +402,7 @@ void VkLightmapper::CopyResult()
if (pixels == 0)
return;
std::vector<VkTextureImage>& destTexture = fb->GetTextureManager()->Lightmaps;
std::vector<VkTextureManager::Lightmap>& destTexture = fb->GetTextureManager()->Lightmaps;
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
@ -414,7 +414,7 @@ void VkLightmapper::CopyResult()
for (unsigned int i = 0, count = copylists.Size(); i < count; i++)
{
if (copylists[i].Size() > 0)
barrier0.AddImage(destTexture[i].Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
barrier0.AddImage(destTexture[i].Light.Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
}
barrier0.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
@ -427,18 +427,18 @@ void VkLightmapper::CopyResult()
if (list.Size() == 0)
continue;
int destSize = destTexture[i].Image->width;
int destSize = destTexture[i].Light.Image->width;
// Create framebuffer object if it doesn't exist
auto& framebuffer = destTexture[i].LMFramebuffer;
auto& framebuffer = destTexture[i].Light.LMFramebuffer;
if (!framebuffer)
{
auto& view = destTexture[i].LMView;
auto& view = destTexture[i].Light.LMView;
if (!view)
{
view = ImageViewBuilder()
.Type(VK_IMAGE_VIEW_TYPE_2D)
.Image(destTexture[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1, 1)
.Image(destTexture[i].Light.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1, 1)
.DebugName("LMView")
.Create(fb->GetDevice());
}
@ -499,7 +499,7 @@ void VkLightmapper::CopyResult()
for (unsigned int i = 0, count = copylists.Size(); i < count; i++)
{
if (copylists[i].Size() > 0)
barrier1.AddImage(destTexture[i].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, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
barrier1.AddImage(destTexture[i].Light.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, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
}
barrier1.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);