WIP VkLightmap integration
This commit is contained in:
parent
696166a726
commit
651903fe71
12 changed files with 262 additions and 41 deletions
|
|
@ -1,10 +1,12 @@
|
|||
|
||||
#include "vk_lightmap.h"
|
||||
#include "vulkan/vk_renderdevice.h"
|
||||
#include "vk_raytrace.h"
|
||||
#include "zvulkan/vulkanbuilders.h"
|
||||
#include "halffloat.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
|
||||
VkLightmap::VkLightmap(VulkanRenderDevice* fb) : fb(fb)
|
||||
{
|
||||
useRayQuery = fb->GetDevice()->PhysicalDevice.Features.RayQuery.rayQuery;
|
||||
|
|
@ -89,7 +91,7 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex)
|
|||
};
|
||||
beginPass();
|
||||
|
||||
for (size_t i = 0; i < mesh->surfaces.Size(); i++)
|
||||
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||
{
|
||||
hwrenderer::Surface* targetSurface = mesh->surfaces[i].get();
|
||||
if (targetSurface->atlasPageIndex != pageIndex)
|
||||
|
|
@ -156,14 +158,14 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex)
|
|||
lightinfo++;
|
||||
}
|
||||
|
||||
PushConstants pc;
|
||||
LightmapPushConstants pc;
|
||||
pc.LightStart = firstLight;
|
||||
pc.LightEnd = firstLight + lightCount;
|
||||
pc.SurfaceIndex = (int32_t)i;
|
||||
pc.LightmapOrigin = targetSurface->worldOrigin - targetSurface->worldStepX - targetSurface->worldStepY;
|
||||
pc.LightmapStepX = targetSurface->worldStepX * viewport.width;
|
||||
pc.LightmapStepY = targetSurface->worldStepY * viewport.height;
|
||||
cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants), &pc);
|
||||
cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapPushConstants), &pc);
|
||||
|
||||
SceneVertex* vertex = &vertices.Vertices[firstVertex];
|
||||
|
||||
|
|
@ -194,7 +196,7 @@ void VkLightmap::CreateAtlasImages()
|
|||
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));
|
||||
|
||||
for (size_t i = 0; i < mesh->surfaces.Size(); i++)
|
||||
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||
{
|
||||
hwrenderer::Surface* surface = mesh->surfaces[i].get();
|
||||
|
||||
|
|
@ -259,14 +261,14 @@ void VkLightmap::ResolveAtlasImage(size_t i)
|
|||
viewport.height = (float)atlasImageSize;
|
||||
cmdbuffer->setViewport(0, 1, &viewport);
|
||||
|
||||
PushConstants pc;
|
||||
LightmapPushConstants pc;
|
||||
pc.LightStart = 0;
|
||||
pc.LightEnd = 0;
|
||||
pc.SurfaceIndex = 0;
|
||||
pc.LightmapOrigin = FVector3(0.0f, 0.0f, 0.0f);
|
||||
pc.LightmapStepX = FVector3(0.0f, 0.0f, 0.0f);
|
||||
pc.LightmapStepY = FVector3(0.0f, 0.0f, 0.0f);
|
||||
cmdbuffer->pushConstants(resolve.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstants), &pc);
|
||||
cmdbuffer->pushConstants(resolve.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(LightmapPushConstants), &pc);
|
||||
|
||||
int firstVertex = vertices.Pos;
|
||||
int vertexCount = 4;
|
||||
|
|
@ -303,7 +305,7 @@ void VkLightmap::DownloadAtlasImage(size_t pageIndex)
|
|||
|
||||
hvec4* pixels = (hvec4*)atlasImages[pageIndex].Transfer->Map(0, atlasImageSize * atlasImageSize * sizeof(hvec4));
|
||||
|
||||
for (size_t i = 0; i < mesh->surfaces.Size(); i++)
|
||||
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||
{
|
||||
hwrenderer::Surface* surface = mesh->surfaces[i].get();
|
||||
if (surface->atlasPageIndex != pageIndex)
|
||||
|
|
@ -406,7 +408,7 @@ void VkLightmap::CreateRaytracePipeline()
|
|||
raytrace.pipelineLayout = PipelineLayoutBuilder()
|
||||
.AddSetLayout(raytrace.descriptorSetLayout0.get())
|
||||
.AddSetLayout(raytrace.descriptorSetLayout1.get())
|
||||
.AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants))
|
||||
.AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapPushConstants))
|
||||
.DebugName("raytrace.pipelineLayout")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
|
|
@ -476,32 +478,37 @@ void VkLightmap::CreateRaytracePipeline()
|
|||
|
||||
void VkLightmap::UpdateAccelStructDescriptors()
|
||||
{
|
||||
// To do: fetch this from VkDescriptorSetManager - perhaps manage it all over there?
|
||||
auto nodesBuffer = fb->GetRaytrace()->GetNodeBuffer();
|
||||
auto tlAccelStruct = fb->GetRaytrace()->GetAccelStruct();
|
||||
auto vertexBuffer = fb->GetRaytrace()->GetVertexBuffer();
|
||||
auto indexBuffer = fb->GetRaytrace()->GetIndexBuffer();
|
||||
auto surfaceIndexBuffer = fb->GetRaytrace()->GetSurfaceIndexBuffer();
|
||||
auto surfaceBuffer = fb->GetRaytrace()->GetSurfaceIndexBuffer();
|
||||
auto portalBuffer = fb->GetRaytrace()->GetPortalBuffer();
|
||||
|
||||
#if 0
|
||||
if (useRayQuery)
|
||||
{
|
||||
WriteDescriptors()
|
||||
.AddAccelerationStructure(raytrace.descriptorSet1.get(), 0, tlAccelStruct.get())
|
||||
.AddAccelerationStructure(raytrace.descriptorSet1.get(), 0, tlAccelStruct)
|
||||
.Execute(fb->GetDevice());
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteDescriptors()
|
||||
.AddBuffer(raytrace.descriptorSet1.get(), 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nodesBuffer.get())
|
||||
.AddBuffer(raytrace.descriptorSet1.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vertexBuffer.get())
|
||||
.AddBuffer(raytrace.descriptorSet1.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, indexBuffer.get())
|
||||
.AddBuffer(raytrace.descriptorSet1.get(), 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nodesBuffer)
|
||||
.AddBuffer(raytrace.descriptorSet1.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vertexBuffer)
|
||||
.AddBuffer(raytrace.descriptorSet1.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, indexBuffer)
|
||||
.Execute(fb->GetDevice());
|
||||
}
|
||||
|
||||
WriteDescriptors()
|
||||
.AddBuffer(raytrace.descriptorSet0.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uniformBuffer.get(), 0, sizeof(Uniforms))
|
||||
.AddBuffer(raytrace.descriptorSet0.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceIndexBuffer.get())
|
||||
.AddBuffer(raytrace.descriptorSet0.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceBuffer.get())
|
||||
.AddBuffer(raytrace.descriptorSet0.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, sceneLightBuffer.get())
|
||||
.AddBuffer(raytrace.descriptorSet0.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, portalBuffer.get())
|
||||
.AddBuffer(raytrace.descriptorSet0.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uniforms.Buffer.get(), 0, sizeof(Uniforms))
|
||||
.AddBuffer(raytrace.descriptorSet0.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceIndexBuffer)
|
||||
.AddBuffer(raytrace.descriptorSet0.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceBuffer)
|
||||
//.AddBuffer(raytrace.descriptorSet0.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, sceneLightBuffer.get()) // TODO !!!!!!!!!
|
||||
.AddBuffer(raytrace.descriptorSet0.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, portalBuffer)
|
||||
.Execute(fb->GetDevice());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void VkLightmap::CreateResolvePipeline()
|
||||
|
|
@ -513,7 +520,7 @@ void VkLightmap::CreateResolvePipeline()
|
|||
|
||||
resolve.pipelineLayout = PipelineLayoutBuilder()
|
||||
.AddSetLayout(resolve.descriptorSetLayout.get())
|
||||
.AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstants))
|
||||
.AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(LightmapPushConstants))
|
||||
.DebugName("resolve.pipelineLayout")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ struct Uniforms
|
|||
float SunIntensity;
|
||||
};
|
||||
|
||||
struct PushConstants
|
||||
struct LightmapPushConstants
|
||||
{
|
||||
uint32_t LightStart;
|
||||
uint32_t LightEnd;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ void VkRaytrace::Reset()
|
|||
deletelist->Add(std::move(indexBuffer));
|
||||
deletelist->Add(std::move(transferBuffer));
|
||||
deletelist->Add(std::move(nodesBuffer));
|
||||
deletelist->Add(std::move(surfaceBuffer));
|
||||
deletelist->Add(std::move(portalBuffer));
|
||||
deletelist->Add(std::move(blScratchBuffer));
|
||||
deletelist->Add(std::move(blAccelStructBuffer));
|
||||
deletelist->Add(std::move(blAccelStruct));
|
||||
|
|
@ -133,10 +135,32 @@ void VkRaytrace::CreateVertexAndIndexBuffers()
|
|||
.DebugName("nodesBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
surfaceIndexBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->MeshSurfaces.Size() * sizeof(int))
|
||||
.DebugName("surfaceBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
surfaceBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->surfaces.size() * sizeof(SurfaceInfo))
|
||||
.DebugName("surfaceBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
portalBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->portals.Size() * sizeof(SurfaceInfo))
|
||||
.DebugName("portalBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
|
||||
transferBuffer = BufferTransfer()
|
||||
.AddBuffer(vertexBuffer.get(), vertices.data(), vertices.size() * sizeof(FVector4))
|
||||
.AddBuffer(indexBuffer.get(), Mesh->MeshElements.Data(), (size_t)Mesh->MeshElements.Size() * sizeof(uint32_t))
|
||||
.AddBuffer(nodesBuffer.get(), &nodesHeader, sizeof(CollisionNodeBufferHeader), nodes.data(), nodes.size() * sizeof(CollisionNode))
|
||||
.AddBuffer(surfaceIndexBuffer.get(), &nodesHeader, sizeof(int), Mesh->MeshSurfaces.Data(), Mesh->MeshSurfaces.Size() * sizeof(int))
|
||||
.AddBuffer(surfaceBuffer.get(), Mesh->surfaceInfo.Data(), Mesh->surfaceInfo.Size() * sizeof(SurfaceInfo))
|
||||
.AddBuffer(portalBuffer.get(), Mesh->portalInfo.Data(), Mesh->portalInfo.Size() * sizeof(PortalInfo))
|
||||
.Execute(fb->GetDevice(), fb->GetCommands()->GetTransferCommands());
|
||||
|
||||
PipelineBarrier()
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ public:
|
|||
VulkanBuffer* GetVertexBuffer() { return vertexBuffer.get(); }
|
||||
VulkanBuffer* GetIndexBuffer() { return indexBuffer.get(); }
|
||||
VulkanBuffer* GetNodeBuffer() { return nodesBuffer.get(); }
|
||||
VulkanBuffer* GetSurfaceIndexBuffer() { return surfaceIndexBuffer.get(); }
|
||||
VulkanBuffer* GetSurfaceBuffer() { return surfaceBuffer.get(); }
|
||||
VulkanBuffer* GetPortalBuffer() { return portalBuffer.get(); }
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
|
|
@ -58,6 +61,9 @@ private:
|
|||
std::unique_ptr<VulkanBuffer> indexBuffer;
|
||||
std::unique_ptr<VulkanBuffer> transferBuffer;
|
||||
std::unique_ptr<VulkanBuffer> nodesBuffer;
|
||||
std::unique_ptr<VulkanBuffer> surfaceIndexBuffer;
|
||||
std::unique_ptr<VulkanBuffer> surfaceBuffer;
|
||||
std::unique_ptr<VulkanBuffer> portalBuffer;
|
||||
|
||||
std::unique_ptr<VulkanBuffer> blScratchBuffer;
|
||||
std::unique_ptr<VulkanBuffer> blAccelStructBuffer;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "vulkan/vk_renderstate.h"
|
||||
#include "vulkan/vk_postprocess.h"
|
||||
#include "vulkan/accelstructs/vk_raytrace.h"
|
||||
#include "vulkan/accelstructs/vk_lightmap.h"
|
||||
#include "vulkan/pipelines/vk_renderpass.h"
|
||||
#include "vulkan/descriptorsets/vk_descriptorset.h"
|
||||
#include "vulkan/shaders/vk_shader.h"
|
||||
|
|
@ -61,6 +62,7 @@
|
|||
#include <zvulkan/vulkancompatibledevice.h>
|
||||
#include "engineerrors.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "accelstructs/halffloat.h"
|
||||
|
||||
FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames, int maxFrames = -1);
|
||||
|
||||
|
|
@ -473,8 +475,47 @@ void VulkanRenderDevice::BeginFrame()
|
|||
mDescriptorSetManager->BeginFrame();
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::InitLightmap(int LMTextureSize, int LMTextureCount, TArray<uint16_t>& LMTextureData)
|
||||
void VulkanRenderDevice::InitLightmap(int LMTextureSize, int LMTextureCount, TArray<uint16_t>& LMTextureData, hwrenderer::LevelMesh& mesh)
|
||||
{
|
||||
if(mesh.surfaces.size() > 0)
|
||||
{
|
||||
Printf("Running VkLightmap.\n");
|
||||
|
||||
VkLightmap lightmap(this);
|
||||
lightmap.Raytrace(&mesh);
|
||||
|
||||
Printf("Copying data.\n");
|
||||
|
||||
// TODO refactor
|
||||
|
||||
auto clamp = [](float a, float min, float max) -> float { return a < min ? min : a > max ? max : a; };
|
||||
|
||||
RectPacker packer(LMTextureSize, LMTextureSize);
|
||||
|
||||
for (auto& surface : mesh.surfaces)
|
||||
{
|
||||
mesh.FinishSurface(LMTextureSize, LMTextureSize, packer, *surface.get());
|
||||
|
||||
uint16_t* currentTexture = LMTextureData.Data() + (LMTextureSize * LMTextureSize * 3) * surface->atlasPageIndex;
|
||||
|
||||
FVector3* colorSamples = surface->texPixels.data();
|
||||
// store results to lightmap texture
|
||||
for (int i = 0; i < surface->texHeight; i++)
|
||||
{
|
||||
for (int j = 0; j < surface->texWidth; j++)
|
||||
{
|
||||
// get texture offset
|
||||
int offs = ((surface->texWidth * (i + surface->atlasY)) + surface->atlasX) * 3;
|
||||
|
||||
// convert RGB to bytes
|
||||
currentTexture[offs + j * 3 + 0] = floatToHalf(clamp(colorSamples[i * surface->texWidth + j].X, 0.0f, 65000.0f));
|
||||
currentTexture[offs + j * 3 + 1] = floatToHalf(clamp(colorSamples[i * surface->texWidth + j].Y, 0.0f, 65000.0f));
|
||||
currentTexture[offs + j * 3 + 2] = floatToHalf(clamp(colorSamples[i * surface->texWidth + j].Z, 0.0f, 65000.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LMTextureData.Size() > 0)
|
||||
{
|
||||
GetTextureManager()->SetLightmap(LMTextureSize, LMTextureCount, LMTextureData);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public:
|
|||
void SetTextureFilterMode() override;
|
||||
void StartPrecaching() override;
|
||||
void BeginFrame() override;
|
||||
void InitLightmap(int LMTextureSize, int LMTextureCount, TArray<uint16_t>& LMTextureData) override;
|
||||
void InitLightmap(int LMTextureSize, int LMTextureCount, TArray<uint16_t>& LMTextureData, hwrenderer::LevelMesh& mesh) override;
|
||||
void BlurScene(float amount) override;
|
||||
void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D) override;
|
||||
void AmbientOccludeScene(float m5) override;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue