Hook up some more PBR stuff
This commit is contained in:
parent
5ac0b1b84c
commit
c0bbe3a43a
11 changed files with 333 additions and 54 deletions
|
|
@ -119,6 +119,8 @@ class ImageBuilder
|
|||
public:
|
||||
ImageBuilder();
|
||||
|
||||
ImageBuilder& Type(VkImageType type);
|
||||
ImageBuilder& Flags(VkImageCreateFlags flags);
|
||||
ImageBuilder& Size(int width, int height, int miplevels = 1, int arrayLayers = 1);
|
||||
ImageBuilder& Samples(VkSampleCountFlagBits samples);
|
||||
ImageBuilder& Format(VkFormat format);
|
||||
|
|
|
|||
|
|
@ -276,6 +276,18 @@ ImageBuilder::ImageBuilder()
|
|||
imageInfo.flags = 0;
|
||||
}
|
||||
|
||||
ImageBuilder& ImageBuilder::Type(VkImageType type)
|
||||
{
|
||||
imageInfo.imageType = type;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ImageBuilder& ImageBuilder::Flags(VkImageCreateFlags flags)
|
||||
{
|
||||
imageInfo.flags = flags;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ImageBuilder& ImageBuilder::Size(int width, int height, int mipLevels, int arrayLayers)
|
||||
{
|
||||
imageInfo.extent.width = width;
|
||||
|
|
@ -1759,6 +1771,7 @@ std::vector<VulkanCompatibleDevice> VulkanDeviceBuilder::FindDevices(const std::
|
|||
enabledFeatures.Features.shaderClipDistance = deviceFeatures.Features.shaderClipDistance;
|
||||
enabledFeatures.Features.multiDrawIndirect = deviceFeatures.Features.multiDrawIndirect;
|
||||
enabledFeatures.Features.independentBlend = deviceFeatures.Features.independentBlend;
|
||||
enabledFeatures.Features.imageCubeArray = deviceFeatures.Features.imageCubeArray;
|
||||
enabledFeatures.BufferDeviceAddress.bufferDeviceAddress = deviceFeatures.BufferDeviceAddress.bufferDeviceAddress;
|
||||
enabledFeatures.AccelerationStructure.accelerationStructure = deviceFeatures.AccelerationStructure.accelerationStructure;
|
||||
enabledFeatures.RayQuery.rayQuery = deviceFeatures.RayQuery.rayQuery;
|
||||
|
|
|
|||
|
|
@ -143,17 +143,19 @@ void VkDescriptorSetManager::UpdateFixedSet()
|
|||
|
||||
WriteDescriptors update;
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 0, fb->GetTextureManager()->Shadowmap.View.get(), fb->GetSamplerManager()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 1, fb->GetTextureManager()->Lightmap.View.get(), fb->GetSamplerManager()->LightmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 1, fb->GetTextureManager()->Lightmap.Image.View.get(), fb->GetSamplerManager()->LightmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 2, fb->GetBuffers()->SceneLinearDepth.View.get(), fb->GetSamplerManager()->Get(PPFilterMode::Nearest, PPWrapMode::Clamp), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 3, fb->GetTextureManager()->Irradiancemap.Image.View.get(), fb->GetSamplerManager()->IrradiancemapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 4, fb->GetTextureManager()->Prefiltermap.Image.View.get(), fb->GetSamplerManager()->PrefiltermapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
if (fb->IsRayQueryEnabled())
|
||||
{
|
||||
update.AddAccelerationStructure(Fixed.Set.get(), 3, fb->GetLevelMesh()->GetAccelStruct());
|
||||
update.AddAccelerationStructure(Fixed.Set.get(), 5, fb->GetLevelMesh()->GetAccelStruct());
|
||||
}
|
||||
else
|
||||
{
|
||||
update.AddBuffer(Fixed.Set.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetNodeBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetVertexBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetIndexBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetNodeBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetVertexBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetIndexBuffer());
|
||||
}
|
||||
update.Execute(fb->GetDevice());
|
||||
}
|
||||
|
|
@ -269,15 +271,17 @@ void VkDescriptorSetManager::CreateFixedLayout()
|
|||
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
if (fb->IsRayQueryEnabled())
|
||||
{
|
||||
builder.AddBinding(3, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(5, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
builder.DebugName("VkDescriptorSetManager.Fixed.SetLayout");
|
||||
Fixed.Layout = builder.Create(fb->GetDevice());
|
||||
|
|
@ -343,7 +347,7 @@ void VkDescriptorSetManager::CreateRSBufferPool()
|
|||
void VkDescriptorSetManager::CreateFixedPool()
|
||||
{
|
||||
DescriptorPoolBuilder poolbuilder;
|
||||
poolbuilder.AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3 * MaxFixedSets);
|
||||
poolbuilder.AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 5 * MaxFixedSets);
|
||||
if (fb->IsRayQueryEnabled())
|
||||
{
|
||||
poolbuilder.AddPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1 * MaxFixedSets);
|
||||
|
|
|
|||
|
|
@ -130,6 +130,8 @@ VkSamplerManager::VkSamplerManager(VulkanRenderDevice* fb) : fb(fb)
|
|||
CreateShadowmapSampler();
|
||||
CreateLightmapSampler();
|
||||
CreateZMinMaxSampler();
|
||||
CreateIrradiancemapSampler();
|
||||
CreatePrefiltermapSampler();
|
||||
}
|
||||
|
||||
VkSamplerManager::~VkSamplerManager()
|
||||
|
|
@ -325,3 +327,19 @@ void VkSamplerManager::CreateZMinMaxSampler()
|
|||
.DebugName("VkRenderBuffers.ZMinMaxSampler")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
void VkSamplerManager::CreateIrradiancemapSampler()
|
||||
{
|
||||
IrradiancemapSampler = SamplerBuilder()
|
||||
.AddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
|
||||
.DebugName("VkRenderBuffers.IrradiancemapSampler")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
void VkSamplerManager::CreatePrefiltermapSampler()
|
||||
{
|
||||
PrefiltermapSampler = SamplerBuilder()
|
||||
.AddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
|
||||
.DebugName("VkRenderBuffers.PrefiltermapSampler")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ public:
|
|||
std::unique_ptr<VulkanSampler> ShadowmapSampler;
|
||||
std::unique_ptr<VulkanSampler> LightmapSampler;
|
||||
std::unique_ptr<VulkanSampler> ZMinMaxSampler;
|
||||
std::unique_ptr<VulkanSampler> IrradiancemapSampler;
|
||||
std::unique_ptr<VulkanSampler> PrefiltermapSampler;
|
||||
|
||||
private:
|
||||
void CreateHWSamplers();
|
||||
|
|
@ -36,6 +38,8 @@ private:
|
|||
void CreateShadowmapSampler();
|
||||
void CreateLightmapSampler();
|
||||
void CreateZMinMaxSampler();
|
||||
void CreateIrradiancemapSampler();
|
||||
void CreatePrefiltermapSampler();
|
||||
|
||||
VulkanRenderDevice* fb = nullptr;
|
||||
std::array<std::unique_ptr<VulkanSampler>, NUMSAMPLERS> mSamplers;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ VkTextureManager::VkTextureManager(VulkanRenderDevice* fb) : fb(fb)
|
|||
CreateNullTexture();
|
||||
CreateShadowmap();
|
||||
CreateLightmap();
|
||||
CreateIrradiancemap();
|
||||
CreatePrefiltermap();
|
||||
}
|
||||
|
||||
VkTextureManager::~VkTextureManager()
|
||||
|
|
@ -192,32 +194,64 @@ void VkTextureManager::CreateLightmap()
|
|||
CreateLightmap(1, 1, std::move(data));
|
||||
}
|
||||
|
||||
void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCount, TArray<uint16_t>&& newPixelData)
|
||||
void VkTextureManager::CreateIrradiancemap()
|
||||
{
|
||||
if (LMTextureSize == newLMTextureSize && LMTextureCount == newLMTextureCount + 1 && newPixelData.Size() == 0)
|
||||
TArray<uint16_t> data;
|
||||
for (int arrayIndex = 0; arrayIndex < 6; arrayIndex++)
|
||||
{
|
||||
data.Push(0);
|
||||
data.Push(0);
|
||||
data.Push(0);
|
||||
}
|
||||
CreateIrradiancemap(1, 6, std::move(data));
|
||||
}
|
||||
|
||||
void VkTextureManager::CreatePrefiltermap()
|
||||
{
|
||||
TArray<uint16_t> data;
|
||||
int size = 1 << MAX_REFLECTION_LOD;
|
||||
for (int arrayIndex = 0; arrayIndex < 6; arrayIndex++)
|
||||
{
|
||||
for (int level = 0; level < MAX_REFLECTION_LOD; level++)
|
||||
{
|
||||
int mipsize = size >> level;
|
||||
for (int i = 0; i < mipsize; i++)
|
||||
{
|
||||
data.Push(0);
|
||||
data.Push(0);
|
||||
data.Push(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
CreatePrefiltermap(size, 6, std::move(data));
|
||||
}
|
||||
|
||||
void VkTextureManager::CreateIrradiancemap(int size, int count, TArray<uint16_t>&& newPixelData)
|
||||
{
|
||||
if (Irradiancemap.Size == size && Irradiancemap.Count == count && newPixelData.Size() == 0)
|
||||
return;
|
||||
|
||||
LMTextureSize = newLMTextureSize;
|
||||
LMTextureCount = newLMTextureCount + 1; // the extra texture is for the dynamic lightmap
|
||||
|
||||
int w = newLMTextureSize;
|
||||
int h = newLMTextureSize;
|
||||
int count = newLMTextureCount;
|
||||
Irradiancemap.Size = size;
|
||||
Irradiancemap.Count = count;
|
||||
|
||||
int w = size;
|
||||
int h = size;
|
||||
int pixelsize = 8;
|
||||
|
||||
Lightmap.Reset(fb);
|
||||
Irradiancemap.Image.Reset(fb);
|
||||
|
||||
Lightmap.Image = ImageBuilder()
|
||||
.Size(w, h, 1, LMTextureCount)
|
||||
Irradiancemap.Image.Image = ImageBuilder()
|
||||
.Size(w, h, 1, count)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||
.DebugName("VkRenderBuffers.Lightmap")
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||
.Flags(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
|
||||
.DebugName("VkTextureManager.Irradiancemap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
Lightmap.View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_2D_ARRAY)
|
||||
.Image(Lightmap.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkRenderBuffers.LightmapView")
|
||||
Irradiancemap.Image.View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
|
||||
.Image(Irradiancemap.Image.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.IrradiancemapView")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
|
@ -231,7 +265,7 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun
|
|||
auto stagingBuffer = BufferBuilder()
|
||||
.Size(totalSize)
|
||||
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
|
||||
.DebugName("VkHardwareTexture.mStagingBuffer")
|
||||
.DebugName("VkRenderBuffers.IrradiancemapStagingBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
uint16_t one = 0x3c00; // half-float 1.0
|
||||
|
|
@ -247,7 +281,7 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun
|
|||
stagingBuffer->Unmap();
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Lightmap, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, 1, 0, LMTextureCount)
|
||||
.AddImage(&Irradiancemap.Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, 1, 0, count)
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
|
|
@ -256,7 +290,176 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun
|
|||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = w;
|
||||
region.imageExtent.height = h;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Lightmap.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Irradiancemap.Image.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer));
|
||||
|
||||
newPixelData.Clear();
|
||||
}
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Irradiancemap.Image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, 1, 0, count)
|
||||
.Execute(cmdbuffer);
|
||||
}
|
||||
|
||||
void VkTextureManager::CreatePrefiltermap(int size, int count, TArray<uint16_t>&& newPixelData)
|
||||
{
|
||||
if (Prefiltermap.Size == size && Prefiltermap.Count == count && newPixelData.Size() == 0)
|
||||
return;
|
||||
|
||||
Prefiltermap.Size = size;
|
||||
Prefiltermap.Count = count;
|
||||
|
||||
int w = size;
|
||||
int h = size;
|
||||
int pixelsize = 8;
|
||||
int miplevels = MAX_REFLECTION_LOD + 1;
|
||||
|
||||
Prefiltermap.Image.Reset(fb);
|
||||
|
||||
Prefiltermap.Image.Image = ImageBuilder()
|
||||
.Size(w, h, miplevels, count)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||
.Flags(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
|
||||
.DebugName("VkTextureManager.Prefiltermap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
Prefiltermap.Image.View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
|
||||
.Image(Prefiltermap.Image.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.PrefiltermapView")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
if (count > 0 && newPixelData.Size() >= (size_t)w * h * count * 3)
|
||||
{
|
||||
assert(newPixelData.Size() == (size_t)w * h * count * 3);
|
||||
|
||||
int totalSize = 0;
|
||||
for (int level = 0; level < miplevels; level++)
|
||||
{
|
||||
int mipwidth = std::max(w >> level, 1);
|
||||
int mipheight = std::max(h >> level, 1);
|
||||
totalSize += mipwidth * mipheight * count * pixelsize;
|
||||
}
|
||||
|
||||
auto stagingBuffer = BufferBuilder()
|
||||
.Size(totalSize)
|
||||
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
|
||||
.DebugName("VkTextureManager.PrefiltermapStagingBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
uint16_t one = 0x3c00; // half-float 1.0
|
||||
const uint16_t* src = newPixelData.Data();
|
||||
uint16_t* data = (uint16_t*)stagingBuffer->Map(0, totalSize);
|
||||
for (int i = w * h * count; i > 0; i--)
|
||||
{
|
||||
*(data++) = *(src++);
|
||||
*(data++) = *(src++);
|
||||
*(data++) = *(src++);
|
||||
*(data++) = one;
|
||||
}
|
||||
stagingBuffer->Unmap();
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Prefiltermap.Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, miplevels, 0, count)
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
int offset = 0;
|
||||
for (int level = 0; level < miplevels; level++)
|
||||
{
|
||||
VkBufferImageCopy region = {};
|
||||
region.bufferOffset = offset;
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = count;
|
||||
region.imageSubresource.mipLevel = level;
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = w;
|
||||
region.imageExtent.height = h;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Prefiltermap.Image.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
int mipwidth = std::max(w >> level, 1);
|
||||
int mipheight = std::max(h >> level, 1);
|
||||
offset += mipwidth * mipheight * count * pixelsize;
|
||||
}
|
||||
|
||||
fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer));
|
||||
|
||||
newPixelData.Clear();
|
||||
}
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Prefiltermap.Image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, miplevels, 0, count)
|
||||
.Execute(cmdbuffer);
|
||||
}
|
||||
|
||||
void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCount, TArray<uint16_t>&& newPixelData)
|
||||
{
|
||||
if (Lightmap.Size == newLMTextureSize && Lightmap.Count == newLMTextureCount + 1 && newPixelData.Size() == 0)
|
||||
return;
|
||||
|
||||
Lightmap.Size = newLMTextureSize;
|
||||
Lightmap.Count = newLMTextureCount + 1; // the extra texture is for the dynamic lightmap
|
||||
|
||||
int w = newLMTextureSize;
|
||||
int h = newLMTextureSize;
|
||||
int count = newLMTextureCount;
|
||||
int pixelsize = 8;
|
||||
|
||||
Lightmap.Image.Reset(fb);
|
||||
|
||||
Lightmap.Image.Image = ImageBuilder()
|
||||
.Size(w, h, 1, Lightmap.Count)
|
||||
.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());
|
||||
|
||||
Lightmap.Image.View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_2D_ARRAY)
|
||||
.Image(Lightmap.Image.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.LightmapView")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
if (count > 0 && newPixelData.Size() >= (size_t)w * h * count * 3)
|
||||
{
|
||||
assert(newPixelData.Size() == (size_t)w * h * count * 3);
|
||||
|
||||
int totalSize = w * h * count * pixelsize;
|
||||
|
||||
auto stagingBuffer = BufferBuilder()
|
||||
.Size(totalSize)
|
||||
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
|
||||
.DebugName("VkTextureManager.LightmapStagingBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
uint16_t one = 0x3c00; // half-float 1.0
|
||||
const uint16_t* src = newPixelData.Data();
|
||||
uint16_t* data = (uint16_t*)stagingBuffer->Map(0, totalSize);
|
||||
for (int i = w * h * count; i > 0; i--)
|
||||
{
|
||||
*(data++) = *(src++);
|
||||
*(data++) = *(src++);
|
||||
*(data++) = *(src++);
|
||||
*(data++) = one;
|
||||
}
|
||||
stagingBuffer->Unmap();
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Lightmap.Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, 1, 0, Lightmap.Count)
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = count;
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = w;
|
||||
region.imageExtent.height = h;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Lightmap.Image.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer));
|
||||
|
||||
|
|
@ -264,13 +467,13 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun
|
|||
}
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, 1, 0, LMTextureCount)
|
||||
.AddImage(&Lightmap.Image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, 1, 0, Lightmap.Count)
|
||||
.Execute(cmdbuffer);
|
||||
}
|
||||
|
||||
void VkTextureManager::DownloadLightmap(int arrayIndex, uint16_t* buffer)
|
||||
{
|
||||
unsigned int totalSize = LMTextureSize * LMTextureSize * 4;
|
||||
unsigned int totalSize = Lightmap.Size * Lightmap.Size * 4;
|
||||
|
||||
auto stagingBuffer = BufferBuilder()
|
||||
.Size(totalSize * sizeof(uint16_t))
|
||||
|
|
@ -281,7 +484,7 @@ void VkTextureManager::DownloadLightmap(int arrayIndex, uint16_t* buffer)
|
|||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
PipelineBarrier()
|
||||
.AddImage(Lightmap.Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, arrayIndex, 1)
|
||||
.AddImage(Lightmap.Image.Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, arrayIndex, 1)
|
||||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
|
|
@ -289,13 +492,13 @@ void VkTextureManager::DownloadLightmap(int arrayIndex, uint16_t* buffer)
|
|||
region.imageSubresource.baseArrayLayer = arrayIndex;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageSubresource.mipLevel = 0;
|
||||
region.imageExtent.width = LMTextureSize;
|
||||
region.imageExtent.height = LMTextureSize;
|
||||
region.imageExtent.width = Lightmap.Size;
|
||||
region.imageExtent.height = Lightmap.Size;
|
||||
region.imageExtent.depth = 1;
|
||||
cmdbuffer->copyImageToBuffer(Lightmap.Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer->buffer, 1, ®ion);
|
||||
cmdbuffer->copyImageToBuffer(Lightmap.Image.Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer->buffer, 1, ®ion);
|
||||
|
||||
PipelineBarrier()
|
||||
.AddImage(Lightmap.Image.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, arrayIndex, 1)
|
||||
.AddImage(Lightmap.Image.Image.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, arrayIndex, 1)
|
||||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
fb->GetCommands()->WaitForCommands(false);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@ public:
|
|||
|
||||
void BeginFrame();
|
||||
|
||||
void CreateLightmap(int newLMTextureSize, int newLMTextureCount, TArray<uint16_t>&& newPixelData);
|
||||
void CreateLightmap(int size, int count, TArray<uint16_t>&& data);
|
||||
void CreateIrradiancemap(int size, int count, TArray<uint16_t>&& data);
|
||||
void CreatePrefiltermap(int size, int count, TArray<uint16_t>&& data);
|
||||
void DownloadLightmap(int arrayIndex, uint16_t* buffer);
|
||||
|
||||
VkTextureImage* GetTexture(const PPTextureType& type, PPTexture* tex);
|
||||
|
|
@ -41,14 +43,22 @@ public:
|
|||
int GetHWTextureCount() { return (int)Textures.size(); }
|
||||
|
||||
VkTextureImage Shadowmap;
|
||||
VkTextureImage Lightmap;
|
||||
int LMTextureSize = 0;
|
||||
int LMTextureCount = 0;
|
||||
|
||||
struct
|
||||
{
|
||||
VkTextureImage Image;
|
||||
int Size = 0;
|
||||
int Count = 0;
|
||||
} Lightmap, Irradiancemap, Prefiltermap;
|
||||
|
||||
static const int MAX_REFLECTION_LOD = 4; // Note: must match what lightmodel_pbr.glsl expects
|
||||
|
||||
private:
|
||||
void CreateNullTexture();
|
||||
void CreateShadowmap();
|
||||
void CreateLightmap();
|
||||
void CreateIrradiancemap();
|
||||
void CreatePrefiltermap();
|
||||
|
||||
VkPPTexture* GetVkTexture(PPTexture* texture);
|
||||
|
||||
|
|
|
|||
|
|
@ -378,8 +378,8 @@ void VkLightmapper::CopyResult()
|
|||
if (pixels == 0)
|
||||
return;
|
||||
|
||||
VkTextureImage* destTexture = &fb->GetTextureManager()->Lightmap;
|
||||
int destSize = fb->GetTextureManager()->LMTextureSize;
|
||||
VkTextureImage* destTexture = &fb->GetTextureManager()->Lightmap.Image;
|
||||
int destSize = fb->GetTextureManager()->Lightmap.Size;
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
layout(set = 0, binding = 0) uniform sampler2D ShadowMap;
|
||||
layout(set = 0, binding = 1) uniform sampler2DArray LightMap;
|
||||
layout(set = 0, binding = 2) uniform sampler2D LinearDepth;
|
||||
layout(set = 0, binding = 3) uniform samplerCubeArray IrradianceMap;
|
||||
layout(set = 0, binding = 4) uniform samplerCubeArray PrefilterMap;
|
||||
|
||||
#if defined(USE_RAYTRACE)
|
||||
#if defined(SUPPORTS_RAYQUERY)
|
||||
layout(set = 0, binding = 3) uniform accelerationStructureEXT TopLevelAS;
|
||||
layout(set = 0, binding = 5) uniform accelerationStructureEXT TopLevelAS;
|
||||
#else
|
||||
struct CollisionNode
|
||||
{
|
||||
|
|
@ -18,7 +20,7 @@ struct CollisionNode
|
|||
int element_index;
|
||||
int padding3;
|
||||
};
|
||||
layout(std430, set = 0, binding = 3) buffer NodeBuffer
|
||||
layout(std430, set = 0, binding = 5) buffer NodeBuffer
|
||||
{
|
||||
int nodesRoot;
|
||||
int nodebufferPadding1;
|
||||
|
|
@ -33,7 +35,7 @@ struct SurfaceVertex // Note: this must always match the FFlatVertex struct
|
|||
vec2 uv;
|
||||
vec2 luv;
|
||||
};
|
||||
layout(std430, set = 0, binding = 4) buffer VertexBuffer { SurfaceVertex vertices[]; };
|
||||
layout(std430, set = 0, binding = 5) buffer ElementBuffer { int elements[]; };
|
||||
layout(std430, set = 0, binding = 6) buffer VertexBuffer { SurfaceVertex vertices[]; };
|
||||
layout(std430, set = 0, binding = 7) buffer ElementBuffer { int elements[]; };
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ layout(push_constant) uniform PushConstants
|
|||
#define glowtexture texture4
|
||||
#endif
|
||||
|
||||
#define BrdfLUT 0 // the BRDF convoluted texture is always in this texture slot
|
||||
|
||||
#define uObjectColor data[uDataIndex].uObjectColor
|
||||
#define uObjectColor2 data[uDataIndex].uObjectColor2
|
||||
#define uDynLightColor data[uDataIndex].uDynLightColor
|
||||
|
|
|
|||
|
|
@ -66,8 +66,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
|||
{
|
||||
vec3 worldpos = pixelpos.xyz;
|
||||
|
||||
vec3 albedo = pow(material.Base.rgb, vec3(2.2)); // sRGB to linear
|
||||
ambientLight = pow(ambientLight, vec3(2.2));
|
||||
vec3 albedo = material.Base.rgb;
|
||||
|
||||
float metallic = material.Metallic;
|
||||
float roughness = material.Roughness;
|
||||
|
|
@ -168,28 +167,50 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
|||
}
|
||||
}
|
||||
|
||||
// Pretend we sampled the sector light level from an irradiance map
|
||||
// Treat the ambient sector light as if it is a light source next to the wall
|
||||
{
|
||||
vec3 NN = N;
|
||||
vec3 VV = V;
|
||||
vec3 LL = N;
|
||||
vec3 HH = normalize(VV + LL);
|
||||
|
||||
vec3 radiance = ambientLight.rgb * 2.5;
|
||||
|
||||
// cook-torrance brdf
|
||||
float NDF = DistributionGGX(NN, HH, roughness);
|
||||
float G = GeometrySmith(NN, VV, LL, roughness);
|
||||
vec3 F = fresnelSchlick(clamp(dot(HH, VV), 0.0, 1.0), F0);
|
||||
|
||||
vec3 kS = F;
|
||||
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
|
||||
|
||||
vec3 nominator = NDF * G * F;
|
||||
float denominator = 4.0 * clamp(dot(NN, VV), 0.0, 1.0) * clamp(dot(NN, LL), 0.0, 1.0);
|
||||
vec3 specular = nominator / max(denominator, 0.001);
|
||||
specular = metallic * albedo * 0.40;
|
||||
|
||||
Lo += (kD * albedo / PI + specular) * radiance;
|
||||
}
|
||||
|
||||
float probeIndex = 0.0; // To do: get this from an uniform
|
||||
|
||||
vec3 F = fresnelSchlickRoughness(clamp(dot(N, V), 0.0, 1.0), F0, roughness);
|
||||
|
||||
vec3 kS = F;
|
||||
vec3 kD = 1.0 - kS;
|
||||
|
||||
vec3 irradiance = ambientLight; // texture(irradianceMap, N).rgb
|
||||
vec3 irradiance = texture(IrradianceMap, vec4(N, probeIndex)).rgb;
|
||||
vec3 diffuse = irradiance * albedo;
|
||||
|
||||
//kD *= 1.0 - metallic;
|
||||
//const float MAX_REFLECTION_LOD = 4.0;
|
||||
//vec3 prefilteredColor = textureLod(prefilterMap, R, roughness * MAX_REFLECTION_LOD).rgb;
|
||||
//vec2 envBRDF = texture(brdfLUT, vec2(clamp(dot(N, V), 0.0, 1.0), roughness)).rg;
|
||||
//vec3 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);
|
||||
kD *= 1.0 - metallic;
|
||||
const float MAX_REFLECTION_LOD = 4.0;
|
||||
vec3 R = reflect(-V, N);
|
||||
vec3 prefilteredColor = textureLod(PrefilterMap, vec4(R, probeIndex), roughness * MAX_REFLECTION_LOD).rgb;
|
||||
vec2 envBRDF = texture(BrdfLUT, vec2(clamp(dot(N, V), 0.0, 1.0), roughness)).rg;
|
||||
vec3 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);
|
||||
|
||||
//vec3 ambient = (kD * diffuse + specular) * ao;
|
||||
vec3 ambient = (kD * diffuse) * ao;
|
||||
vec3 ambient = (kD * diffuse + specular) * ao;
|
||||
|
||||
vec3 color = max(ambient + Lo, vec3(0.0));
|
||||
|
||||
// Tonemap (reinhard) and apply sRGB gamma
|
||||
//color = color / (color + vec3(1.0));
|
||||
return pow(color, vec3(1.0 / 2.2));
|
||||
return color;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue