- implement shadow maps

This commit is contained in:
Magnus Norddahl 2019-03-15 07:54:34 +01:00
parent 836938440c
commit cce96ca87a
16 changed files with 200 additions and 26 deletions

View file

@ -91,6 +91,7 @@ OpenGLFrameBuffer::~OpenGLFrameBuffer()
if (mSkyData != nullptr) delete mSkyData;
if (mViewpoints != nullptr) delete mViewpoints;
if (mLights != nullptr) delete mLights;
mShadowMap.Reset();
if (GLRenderer)
{

View file

@ -8,7 +8,10 @@ enum
{
LIGHTBUF_BINDINGPOINT = 1,
POSTPROCESS_BINDINGPOINT = 2,
VIEWPOINT_BINDINGPOINT = 3
VIEWPOINT_BINDINGPOINT = 3,
LIGHTNODES_BINDINGPOINT = 4,
LIGHTLINES_BINDINGPOINT = 5,
LIGHTLIST_BINDINGPOINT = 6
};
enum class UniformType

View file

@ -24,6 +24,7 @@
#include "hwrenderer/utility/hw_cvars.h"
#include "hwrenderer/dynlights/hw_dynlightdata.h"
#include "hwrenderer/data/buffers.h"
#include "hwrenderer/data/shaderuniforms.h"
#include "stats.h"
#include "g_levellocals.h"
#include "v_video.h"
@ -188,7 +189,7 @@ void IShadowMap::UploadLights()
CollectLights();
if (mLightList == nullptr)
mLightList = screen->CreateDataBuffer(4, true);
mLightList = screen->CreateDataBuffer(LIGHTLIST_BINDINGPOINT, true);
mLightList->SetData(sizeof(float) * mLights.Size(), &mLights[0]);
}
@ -199,11 +200,11 @@ void IShadowMap::UploadAABBTree()
if (!ValidateAABBTree(&level))
{
if (!mNodesBuffer)
mNodesBuffer = screen->CreateDataBuffer(2, true);
mNodesBuffer = screen->CreateDataBuffer(LIGHTNODES_BINDINGPOINT, true);
mNodesBuffer->SetData(mAABBTree->NodesSize(), mAABBTree->Nodes());
if (!mLinesBuffer)
mLinesBuffer = screen->CreateDataBuffer(3, true);
mLinesBuffer = screen->CreateDataBuffer(LIGHTLINES_BINDINGPOINT, true);
mLinesBuffer->SetData(mAABBTree->LinesSize(), mAABBTree->Lines());
}
else if (mAABBTree->Update())
@ -213,10 +214,15 @@ void IShadowMap::UploadAABBTree()
}
}
IShadowMap::~IShadowMap()
void IShadowMap::Reset()
{
if (mLightList) delete mLightList;
if (mNodesBuffer) delete mNodesBuffer;
if (mLinesBuffer) delete mLinesBuffer;
delete mLightList; mLightList = nullptr;
delete mNodesBuffer; mNodesBuffer = nullptr;
delete mLinesBuffer; mLinesBuffer = nullptr;
}
IShadowMap::~IShadowMap()
{
Reset();
}

View file

@ -16,6 +16,8 @@ public:
IShadowMap() { }
virtual ~IShadowMap();
void Reset();
// Test if a world position is in shadow relative to the specified light and returns false if it is
bool ShadowTest(FDynamicLight *light, const DVector3 &pos);

View file

@ -17,6 +17,7 @@ Postprocess::Postprocess()
Managers.Push(new PPTonemap());
Managers.Push(new PPAmbientOcclusion());
Managers.Push(new PPPresent());
Managers.Push(new PPShadowMap());
}
Postprocess::~Postprocess()
@ -892,3 +893,32 @@ void PPPresent::UpdateTextures()
void PPPresent::UpdateSteps()
{
}
/////////////////////////////////////////////////////////////////////////////
void PPShadowMap::DeclareShaders()
{
hw_postprocess.Shaders["ShadowMap"] = { "shaders/glsl/shadowmap.fp", "", ShadowMapUniforms::Desc() };
}
void PPShadowMap::UpdateTextures()
{
}
void PPShadowMap::UpdateSteps()
{
ShadowMapUniforms uniforms;
uniforms.ShadowmapQuality = (float)gl_shadowmap_quality;
PPStep step;
step.ShaderName = "ShadowMap";
step.Uniforms.Set(uniforms);
step.Viewport = { 0, 0, gl_shadowmap_quality, 1024 };
step.SetShadowMapBuffers(true);
step.SetOutputShadowMap();
step.SetNoBlend();
TArray<PPStep> steps;
steps.Push(step);
hw_postprocess.Effects["UpdateShadowMap"] = steps;
}

View file

@ -11,7 +11,7 @@ typedef IntRect PPViewport;
enum class PPFilterMode { Nearest, Linear };
enum class PPWrapMode { Clamp, Repeat };
enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain };
enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain, ShadowMap };
class PPTextureInput
{
@ -120,6 +120,11 @@ public:
tex.Texture = "";
}
void SetShadowMapBuffers(bool enable)
{
ShadowMapBuffers = enable;
}
void SetOutputTexture(PPTextureName texture)
{
Output.Type = PPTextureType::PPTexture;
@ -150,6 +155,12 @@ public:
Output.Texture = "";
}
void SetOutputShadowMap()
{
Output.Type = PPTextureType::ShadowMap;
Output.Texture = "";
}
void SetNoBlend()
{
BlendMode.BlendOp = STYLEOP_Add;
@ -180,6 +191,7 @@ public:
PPViewport Viewport;
PPBlendMode BlendMode;
PPOutput Output;
bool ShadowMapBuffers = false;
};
enum class PixelFormat
@ -658,3 +670,11 @@ struct ShadowMapUniforms
};
}
};
class PPShadowMap : public PPEffectManager
{
public:
void DeclareShaders() override;
void UpdateTextures() override;
void UpdateSteps() override;
};

View file

@ -225,6 +225,23 @@ void VkPostprocess::ClearTonemapPalette()
hw_postprocess.Textures.Remove("Tonemap.Palette");
}
void VkPostprocess::UpdateShadowMap()
{
if (screen->mShadowMap.PerformUpdate())
{
RenderEffect("UpdateShadowMap");
auto fb = GetVulkanFrameBuffer();
auto buffers = fb->GetBuffers();
VkPPImageTransition imageTransition;
imageTransition.addImage(buffers->Shadowmap.get(), &buffers->ShadowmapLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
imageTransition.execute(fb->GetDrawCommands());
screen->mShadowMap.FinishUpdate();
}
}
void VkPostprocess::BeginFrame()
{
mFrameDescriptorSets.clear();
@ -233,6 +250,7 @@ void VkPostprocess::BeginFrame()
{
DescriptorPoolBuilder builder;
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 100);
builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4);
builder.setMaxSets(100);
mDescriptorPool = builder.create(GetVulkanFrameBuffer()->device);
mDescriptorPool->SetDebugName("VkPostprocess.mDescriptorPool");
@ -405,10 +423,13 @@ void VkPostprocess::RenderEffect(const FString &name)
key.Uniforms = step.Uniforms.Data.Size();
key.Shader = mShaders[step.ShaderName].get();
key.SwapChain = (step.Output.Type == PPTextureType::SwapChain);
key.ShadowMapBuffers = step.ShadowMapBuffers;
if (step.Output.Type == PPTextureType::PPTexture)
key.OutputFormat = mTextures[step.Output.Texture]->Format;
else if (step.Output.Type == PPTextureType::SwapChain)
key.OutputFormat = GetVulkanFrameBuffer()->swapChain->swapChainFormat.format;
else if (step.Output.Type == PPTextureType::ShadowMap)
key.OutputFormat = VK_FORMAT_R32_SFLOAT;
else
key.OutputFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
@ -417,7 +438,7 @@ void VkPostprocess::RenderEffect(const FString &name)
passSetup.reset(new VkPPRenderPassSetup(key));
int framebufferWidth = 0, framebufferHeight = 0;
VulkanDescriptorSet *input = GetInput(passSetup.get(), step.Textures);
VulkanDescriptorSet *input = GetInput(passSetup.get(), step.Textures, step.ShadowMapBuffers);
VulkanFramebuffer *output = GetOutput(passSetup.get(), step.Output, framebufferWidth, framebufferHeight);
RenderScreenQuad(passSetup.get(), input, output, framebufferWidth, framebufferHeight, step.Viewport.left, step.Viewport.top, step.Viewport.width, step.Viewport.height, step.Uniforms.Data.Data(), step.Uniforms.Data.Size());
@ -470,7 +491,7 @@ void VkPostprocess::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescr
cmdbuffer->endRenderPass();
}
VulkanDescriptorSet *VkPostprocess::GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures)
VulkanDescriptorSet *VkPostprocess::GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures, bool bindShadowMapBuffers)
{
auto fb = GetVulkanFrameBuffer();
auto descriptors = mDescriptorPool->allocate(passSetup->DescriptorLayout.get());
@ -489,6 +510,13 @@ VulkanDescriptorSet *VkPostprocess::GetInput(VkPPRenderPassSetup *passSetup, con
imageTransition.addImage(tex.image, tex.layout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
}
if (bindShadowMapBuffers)
{
write.addBuffer(descriptors.get(), LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightNodes->mBuffer.get());
write.addBuffer(descriptors.get(), LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightLines->mBuffer.get());
write.addBuffer(descriptors.get(), LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightList->mBuffer.get());
}
write.updateSets(fb->device);
imageTransition.execute(fb->GetDrawCommands());
@ -588,6 +616,13 @@ VkPostprocess::TextureImage VkPostprocess::GetTexture(const PPTextureType &type,
tex.layout = &fb->GetBuffers()->SceneDepthStencilLayout;
tex.debugname = "SceneDepth";
}
else if (type == PPTextureType::ShadowMap)
{
tex.image = fb->GetBuffers()->Shadowmap.get();
tex.view = fb->GetBuffers()->ShadowmapView.get();
tex.layout = &fb->GetBuffers()->ShadowmapLayout;
tex.debugname = "Shadowmap";
}
else if (type == PPTextureType::SwapChain)
{
tex.image = nullptr;
@ -639,6 +674,12 @@ void VkPPRenderPassSetup::CreateDescriptorLayout(const VkPPRenderPassKey &key)
DescriptorSetLayoutBuilder builder;
for (int i = 0; i < key.InputTextures; i++)
builder.addBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
if (key.ShadowMapBuffers)
{
builder.addBinding(LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
DescriptorLayout = builder.create(GetVulkanFrameBuffer()->device);
DescriptorLayout->SetDebugName("VkPPRenderPassSetup.DescriptorLayout");
}

View file

@ -25,6 +25,7 @@ public:
PPBlendMode BlendMode;
VkFormat OutputFormat;
int SwapChain;
int ShadowMapBuffers;
bool operator<(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) < 0; }
bool operator==(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) == 0; }
@ -60,6 +61,8 @@ public:
void BlurScene(float gameinfobluramount);
void ClearTonemapPalette();
void UpdateShadowMap();
void BlitSceneToTexture();
void BlitCurrentToImage(VulkanImage *image, VkImageLayout *layout, VkImageLayout finallayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
void DrawPresentTexture(const IntRect &box, bool applyGamma, bool clearBorders);
@ -72,7 +75,7 @@ private:
void NextEye(int eyeCount);
void RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferWidth, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize);
VulkanDescriptorSet *GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures);
VulkanDescriptorSet *GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures, bool bindShadowMapBuffers);
VulkanFramebuffer *GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferWidth, int &framebufferHeight);
VulkanSampler *GetSampler(PPFilterMode filter, PPWrapMode wrap);

View file

@ -55,6 +55,8 @@ void VkRenderBuffers::BeginFrame(int width, int height, int sceneWidth, int scen
if (width != mWidth || height != mHeight || mSamples != samples)
CreateScene(width, height, samples);
CreateShadowmap();
mWidth = width;
mHeight = height;
mSamples = samples;
@ -206,3 +208,41 @@ void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlag
SceneNormalView = viewbuilder.create(fb->device);
SceneNormalView->SetDebugName("VkRenderBuffers.SceneNormalView");
}
void VkRenderBuffers::CreateShadowmap()
{
if (Shadowmap && Shadowmap->width == gl_shadowmap_quality)
return;
Shadowmap.reset();
ShadowmapView.reset();
auto fb = GetVulkanFrameBuffer();
ImageBuilder builder;
builder.setSize(gl_shadowmap_quality, 1024);
builder.setFormat(VK_FORMAT_R32_SFLOAT);
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
Shadowmap = builder.create(fb->device);
Shadowmap->SetDebugName("VkRenderBuffers.Shadowmap");
ImageViewBuilder viewbuilder;
viewbuilder.setImage(Shadowmap.get(), VK_FORMAT_R32_SFLOAT);
ShadowmapView = viewbuilder.create(fb->device);
ShadowmapView->SetDebugName("VkRenderBuffers.ShadowmapView");
PipelineBarrier barrier;
barrier.addImage(Shadowmap.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
if (!ShadowmapSampler)
{
SamplerBuilder builder;
builder.setMipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST);
builder.setMinFilter(VK_FILTER_NEAREST);
builder.setMagFilter(VK_FILTER_NEAREST);
builder.setAddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
ShadowmapSampler = builder.create(fb->device);
ShadowmapSampler->SetDebugName("VkRenderBuffers.ShadowmapSampler");
}
}

View file

@ -37,6 +37,11 @@ public:
std::unique_ptr<VulkanImageView> PipelineView[NumPipelineImages];
VkImageLayout PipelineLayout[NumPipelineImages];
std::unique_ptr<VulkanImage> Shadowmap;
std::unique_ptr<VulkanImageView> ShadowmapView;
std::unique_ptr<VulkanSampler> ShadowmapSampler;
VkImageLayout ShadowmapLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
private:
void CreatePipeline(int width, int height);
void CreateScene(int width, int height, VkSampleCountFlagBits samples);
@ -44,6 +49,7 @@ private:
void CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples);
void CreateSceneFog(int width, int height, VkSampleCountFlagBits samples);
void CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples);
void CreateShadowmap();
VkSampleCountFlagBits GetBestSampleCount();
int mWidth = 0;

View file

@ -79,6 +79,7 @@ void VkRenderPassManager::CreateDynamicSetLayout()
builder.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
DynamicSetLayout = builder.create(GetVulkanFrameBuffer()->device);
DynamicSetLayout->SetDebugName("VkRenderPassManager.DynamicSetLayout");
}
@ -90,7 +91,6 @@ void VkRenderPassManager::CreateTextureSetLayout()
{
builder.addBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
builder.addBinding(16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
TextureSetLayout = builder.create(GetVulkanFrameBuffer()->device);
TextureSetLayout->SetDebugName("VkRenderPassManager.TextureSetLayout");
}
@ -119,13 +119,18 @@ void VkRenderPassManager::CreateDescriptorPool()
void VkRenderPassManager::CreateDynamicSet()
{
DynamicSet = DescriptorPool->allocate(DynamicSetLayout.get());
}
void VkRenderPassManager::UpdateDynamicSet()
{
auto fb = GetVulkanFrameBuffer();
WriteDescriptors update;
update.addBuffer(DynamicSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms));
update.addBuffer(DynamicSet.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, fb->LightBufferSSO->mBuffer.get(), 0, fb->GetLightBufferBlockSize());
update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatricesUBO->mBuffer.get(), 0, sizeof(MatricesUBO));
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamUBO->mBuffer.get(), 0, sizeof(StreamUBO));
update.addCombinedImageSampler(DynamicSet.get(), 4, fb->GetBuffers()->ShadowmapView.get(), fb->GetBuffers()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
update.updateSets(fb->device);
}

View file

@ -68,6 +68,7 @@ public:
void Init();
void RenderBuffersReset();
void UpdateDynamicSet();
VkRenderPassSetup *GetRenderPass(const VkRenderPassKey &key);
int GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs);

View file

@ -139,6 +139,8 @@ static const char *shaderBindings = R"(
StreamData data[256];
};
layout(set = 0, binding = 4) uniform sampler2D ShadowMap;
// textures
layout(set = 1, binding = 0) uniform sampler2D tex;
layout(set = 1, binding = 1) uniform sampler2D texture2;
@ -146,7 +148,6 @@ static const char *shaderBindings = R"(
layout(set = 1, binding = 3) uniform sampler2D texture4;
layout(set = 1, binding = 4) uniform sampler2D texture5;
layout(set = 1, binding = 5) uniform sampler2D texture6;
layout(set = 1, binding = 16) uniform sampler2D ShadowMap;
// This must match the PushConstants struct
layout(push_constant) uniform PushConstants
@ -207,7 +208,7 @@ static const char *shaderBindings = R"(
#define uSplitTopPlane data[uDataIndex].uSplitTopPlane
#define uSplitBottomPlane data[uDataIndex].uSplitBottomPlane
// #define SUPPORTS_SHADOWMAPS
#define SUPPORTS_SHADOWMAPS
#define VULKAN_COORDINATE_SYSTEM
#define HAS_UNIFORM_VERTEX_DATA
)";

View file

@ -95,6 +95,7 @@ VulkanFrameBuffer::~VulkanFrameBuffer()
delete mSkyData;
delete mViewpoints;
delete mLights;
mShadowMap.Reset();
}
void VulkanFrameBuffer::InitializeState()
@ -390,10 +391,8 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
R_SetupFrame(mainvp, r_viewwindow, camera);
#if 0
if (mainview && toscreen)
UpdateShadowMap();
#endif
// Update the attenuation flag of all light defaults for each viewpoint.
// This function will only do something if the setting differs.
@ -629,14 +628,19 @@ IIndexBuffer *VulkanFrameBuffer::CreateIndexBuffer()
IDataBuffer *VulkanFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo)
{
auto buffer = new VKDataBuffer(bindingpoint, ssbo);
if (bindingpoint == VIEWPOINT_BINDINGPOINT)
auto fb = GetVulkanFrameBuffer();
switch (bindingpoint)
{
ViewpointUBO = buffer;
}
else if (bindingpoint == LIGHTBUF_BINDINGPOINT)
{
LightBufferSSO = buffer;
case LIGHTBUF_BINDINGPOINT: LightBufferSSO = buffer; break;
case VIEWPOINT_BINDINGPOINT: ViewpointUBO = buffer; break;
case LIGHTNODES_BINDINGPOINT: LightNodes = buffer; break;
case LIGHTLINES_BINDINGPOINT: LightLines = buffer; break;
case LIGHTLIST_BINDINGPOINT: LightList = buffer; break;
case POSTPROCESS_BINDINGPOINT: break;
default: break;
}
return buffer;
}
@ -758,6 +762,7 @@ void VulkanFrameBuffer::BeginFrame()
mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
mSaveBuffers->BeginFrame(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT);
mPostprocess->BeginFrame();
mRenderPassManager->UpdateDynamicSet();
}
void VulkanFrameBuffer::Draw2D()
@ -841,3 +846,8 @@ void VulkanFrameBuffer::CreateFanToTrisIndexBuffer()
FanToTrisIndexBuffer.reset(CreateIndexBuffer());
FanToTrisIndexBuffer->SetData(sizeof(uint32_t) * data.Size(), data.Data());
}
void VulkanFrameBuffer::UpdateShadowMap()
{
mPostprocess->UpdateShadowMap();
}

View file

@ -44,6 +44,10 @@ public:
VKDataBuffer *MatricesUBO = nullptr;
VKDataBuffer *StreamUBO = nullptr;
VKDataBuffer *LightNodes = nullptr;
VKDataBuffer *LightLines = nullptr;
VKDataBuffer *LightList = nullptr;
std::unique_ptr<IIndexBuffer> FanToTrisIndexBuffer;
std::vector<std::unique_ptr<VulkanBuffer>> mFrameDeleteList;
@ -90,6 +94,7 @@ private:
void CreateFanToTrisIndexBuffer();
void SubmitCommands(bool finish);
void CopyScreenToBuffer(int w, int h, void *data);
void UpdateShadowMap();
std::unique_ptr<VkShaderManager> mShaderManager;
std::unique_ptr<VkSamplerManager> mSamplerManager;

View file

@ -20,17 +20,17 @@ struct GPULine
vec2 delta; // Line end position - line start position
};
layout(std430, binding = 2) buffer LightNodes
layout(std430, binding = 4) buffer LightNodes
{
GPUNode nodes[];
};
layout(std430, binding = 3) buffer LightLines
layout(std430, binding = 5) buffer LightLines
{
GPULine lines[];
};
layout(std430, binding = 4) buffer LightList
layout(std430, binding = 6) buffer LightList
{
vec4 lights[];
};