SSAO WIP
This commit is contained in:
parent
441207260b
commit
53b9c8f746
|
@ -19,10 +19,11 @@ layout(set = 4, binding = 2, rgba32f) uniform image2D outputImage;
|
|||
layout(std430, set = 5, binding = 0) buffer SSAOData
|
||||
{
|
||||
vec4 samples[NUM_SAMPLES];
|
||||
vec4 rotations[NUM_ROTATIONS];
|
||||
|
||||
} ssaoData;
|
||||
|
||||
layout (set = 5, binding = 1) uniform sampler2D noiseTexture;
|
||||
|
||||
layout(set = 2, binding = 0) uniform CameraData
|
||||
{
|
||||
vec4 position;
|
||||
|
@ -32,33 +33,28 @@ layout(set = 2, binding = 0) uniform CameraData
|
|||
|
||||
} cameraData;
|
||||
|
||||
shared vec4 sharedRotations[NUM_ROTATIONS];
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 size = imageSize (outputImage);
|
||||
|
||||
// load rotations into shared memory
|
||||
uint localThreadIndex = gl_LocalInvocationIndex;
|
||||
if (localThreadIndex < NUM_ROTATIONS)
|
||||
sharedRotations[localThreadIndex] = ssaoData.rotations[localThreadIndex];
|
||||
|
||||
barrier();
|
||||
|
||||
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
|
||||
|
||||
// load all the necessary variables
|
||||
vec3 viewSpacePos = imageLoad (positions, globalThread).rgb;
|
||||
vec3 viewSpaceNormal = normalize (imageLoad (normals, globalThread).rgb);
|
||||
|
||||
// Get random vector
|
||||
uint randomVecXIndex = globalThread.x % ROTATION_KERNEL_W;
|
||||
uint randomVecYIndex = globalThread.y % ROTATION_KERNEL_H;
|
||||
vec3 randomVec = (sharedRotations[randomVecYIndex * ROTATION_KERNEL_W + randomVecXIndex].rgb) * 2.0f - 1.0f;
|
||||
ivec2 noiseDim = textureSize(noiseTexture, 0);
|
||||
vec2 threadUV = globalThread / size;
|
||||
vec2 noiseUV = vec2 (float(size.x)/float(noiseDim.x), float(size.y) / float(noiseDim.y));
|
||||
noiseUV *= threadUV;
|
||||
vec3 randomVec = texture(noiseTexture, noiseUV).rgb * 2.0f - 1.0f;
|
||||
|
||||
// Gram schmidt
|
||||
vec3 tangent = normalize (randomVec - (viewSpaceNormal * dot(viewSpaceNormal, randomVec)));
|
||||
vec3 bitangent = cross (tangent, viewSpaceNormal);
|
||||
|
||||
// matrix for tangent to view
|
||||
mat3 TBN = mat3 (tangent, bitangent, viewSpaceNormal);
|
||||
|
||||
float occlusion = 0.0f;
|
||||
|
@ -85,7 +81,7 @@ void main()
|
|||
occlusion += (sampleDepth >= samplePos.z + BIAS ? 1.0f : 0.0f) * rangeCheck;
|
||||
}
|
||||
|
||||
occlusion = (occlusion / float(NUM_SAMPLES));
|
||||
occlusion = 1.0f - (occlusion / float(NUM_SAMPLES));
|
||||
|
||||
// store result into result image
|
||||
imageStore(outputImage, ivec2(gl_GlobalInvocationID.xy), vec4(occlusion.rrr, 0.0f));
|
||||
|
|
Binary file not shown.
|
@ -215,10 +215,15 @@ namespace SHADE
|
|||
|
||||
graphicsQueue->WaitIdle();
|
||||
|
||||
ssaoStorage->PrepareRotationVectorsVkData(device);
|
||||
|
||||
auto ssaoShader = shaderModuleLibrary.GetBuiltInShaderModule("SSAO_CS");
|
||||
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"});
|
||||
auto ssaoDataBuffer = ssaoStorage->GetBuffer();
|
||||
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BINDING, {&ssaoDataBuffer, 1}, 0, ssaoStorage->GetBuffer()->GetSizeStored());
|
||||
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
|
||||
|
||||
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
|
||||
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -2,15 +2,14 @@
|
|||
#include "SHSSAO.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||
#include "Graphics/Images/SHVkImage.h"
|
||||
#include "Graphics/Images/SHVkSampler.h"
|
||||
#include <random>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHSSAO::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkCommandBuffer> cmdBuffer) noexcept
|
||||
{
|
||||
// create memory on CPU side
|
||||
ssaoData = std::make_unique<SamplesAndKernel>();
|
||||
|
||||
// Initialize a distribution to get values from 0 to 1
|
||||
std::uniform_real_distribution<float> distrib{0.0f, 1.0f};
|
||||
|
||||
|
@ -18,7 +17,6 @@ namespace SHADE
|
|||
std::default_random_engine generator;
|
||||
|
||||
// generate samples
|
||||
auto& samples = ssaoData->samples;
|
||||
for (uint32_t i = 0; i < NUM_SAMPLES; ++i)
|
||||
{
|
||||
samples[i] = SHVec4
|
||||
|
@ -36,7 +34,6 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// generate rotation vector
|
||||
auto& rotationVectors = ssaoData->rotatationVectors;
|
||||
for (uint32_t i = 0; i < NUM_ROTATION_VECTORS; ++i)
|
||||
{
|
||||
rotationVectors[i] = SHVec4
|
||||
|
@ -48,15 +45,74 @@ namespace SHADE
|
|||
};
|
||||
}
|
||||
|
||||
SHImageCreateParams imageDetails =
|
||||
{
|
||||
.imageType = vk::ImageType::e2D,
|
||||
.width = NUM_ROTATION_VECTORS_W,
|
||||
.height = NUM_ROTATION_VECTORS_H,
|
||||
.depth = 1,
|
||||
.levels = 1,
|
||||
.arrayLayers = 1,
|
||||
.imageFormat = vk::Format::eR32G32B32A32Sfloat,
|
||||
.usageFlags = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst,
|
||||
.createFlags = {}
|
||||
};
|
||||
|
||||
uint32_t mipOffset = 0;
|
||||
rotationVectorsImage = logicalDevice->CreateImage(imageDetails, reinterpret_cast<unsigned char*>( rotationVectors.data()), static_cast<uint32_t>(sizeof(rotationVectors)), {&mipOffset, 1}, VMA_MEMORY_USAGE_AUTO, {});
|
||||
|
||||
vk::ImageMemoryBarrier transferBarrier{};
|
||||
rotationVectorsImage->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, transferBarrier);
|
||||
|
||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, {transferBarrier});
|
||||
|
||||
rotationVectorsImage->TransferToDeviceResource(cmdBuffer);
|
||||
|
||||
vk::ImageMemoryBarrier shaderReadBarrier{};
|
||||
rotationVectorsImage->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, shaderReadBarrier);
|
||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, { shaderReadBarrier });
|
||||
|
||||
|
||||
// Get aligned size for buffer
|
||||
uint32_t alignedSize = logicalDevice->PadSSBOSize(sizeof (SamplesAndKernel));
|
||||
uint32_t alignedSize = logicalDevice->PadSSBOSize(sizeof (samples));
|
||||
|
||||
// Create buffer
|
||||
ssaoDataBuffer = logicalDevice->CreateBuffer(alignedSize, ssaoData.get(), alignedSize, vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, {});
|
||||
ssaoDataBuffer = logicalDevice->CreateBuffer(alignedSize, samples.data(), alignedSize, vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, {});
|
||||
|
||||
ssaoDataBuffer->TransferToDeviceResource(cmdBuffer);
|
||||
}
|
||||
|
||||
void SHSSAO::PrepareRotationVectorsVkData(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||
{
|
||||
SHImageViewDetails DETAILS =
|
||||
{
|
||||
.viewType = vk::ImageViewType::e2D,
|
||||
.format = vk::Format::eR32G32B32A32Sfloat,
|
||||
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||
.baseMipLevel = 0,
|
||||
.mipLevelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1
|
||||
};
|
||||
rotationVectorsImageView = rotationVectorsImage->CreateImageView(logicalDevice, rotationVectorsImage, DETAILS);
|
||||
|
||||
SHVkSamplerParams samplerParams
|
||||
{
|
||||
.minFilter = vk::Filter::eNearest,
|
||||
.magFilter = vk::Filter::eNearest,
|
||||
.addressMode = vk::SamplerAddressMode::eRepeat,
|
||||
.mipmapMode = vk::SamplerMipmapMode::eNearest,
|
||||
.maxLod = 1u
|
||||
};
|
||||
|
||||
rotationVectorsSampler = logicalDevice->CreateSampler(samplerParams);
|
||||
}
|
||||
|
||||
SHVkDescriptorSetGroup::viewSamplerLayout SHSSAO::GetViewSamplerLayout(void) const noexcept
|
||||
{
|
||||
return std::make_tuple(rotationVectorsImageView, rotationVectorsSampler, vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||
}
|
||||
|
||||
Handle<SHVkBuffer> SHSSAO::GetBuffer(void) const noexcept
|
||||
{
|
||||
return ssaoDataBuffer;
|
||||
|
|
|
@ -3,39 +3,47 @@
|
|||
#include "Resource/SHHandle.h"
|
||||
#include "Graphics/SHVulkanIncludes.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHVkBuffer;
|
||||
class SHVkLogicalDevice;
|
||||
class SHVkCommandBuffer;
|
||||
class SHVkImage;
|
||||
class SHVkImageView;
|
||||
class SHVkSampler;
|
||||
|
||||
class SHSSAO
|
||||
{
|
||||
public:
|
||||
static constexpr uint32_t DESC_SET_BINDING = 0;
|
||||
static constexpr uint32_t DESC_SET_BUFFER_BINDING = 0;
|
||||
static constexpr uint32_t DESC_SET_IMAGE_BINDING = 1;
|
||||
|
||||
private:
|
||||
static constexpr uint32_t NUM_SAMPLES = 64;
|
||||
static constexpr uint32_t NUM_ROTATION_VECTORS = 16;
|
||||
|
||||
struct SamplesAndKernel
|
||||
{
|
||||
//! distances from a pixel we want to sample
|
||||
std::array<SHVec4, NUM_SAMPLES> samples;
|
||||
|
||||
std::array<SHVec4, NUM_ROTATION_VECTORS> rotatationVectors;
|
||||
};
|
||||
static constexpr uint32_t NUM_ROTATION_VECTORS_W = 4;
|
||||
static constexpr uint32_t NUM_ROTATION_VECTORS_H = 4;
|
||||
static constexpr uint32_t NUM_ROTATION_VECTORS = NUM_ROTATION_VECTORS_W * NUM_ROTATION_VECTORS_H;
|
||||
|
||||
private:
|
||||
//! Samples and kernel on CPU side
|
||||
std::unique_ptr<SamplesAndKernel> ssaoData;
|
||||
//! distances from a pixel we want to sample
|
||||
std::array<SHVec4, NUM_SAMPLES> samples;
|
||||
|
||||
//! For passing SSAO samples and kernel to GPU
|
||||
Handle<SHVkBuffer> ssaoDataBuffer;
|
||||
|
||||
std::array<SHVec4, NUM_ROTATION_VECTORS> rotationVectors;
|
||||
|
||||
Handle<SHVkImage> rotationVectorsImage;
|
||||
Handle<SHVkImageView> rotationVectorsImageView;
|
||||
Handle<SHVkSampler> rotationVectorsSampler;
|
||||
|
||||
public:
|
||||
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
|
||||
void PrepareRotationVectorsVkData (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||
SHVkDescriptorSetGroup::viewSamplerLayout GetViewSamplerLayout (void) const noexcept;
|
||||
|
||||
Handle<SHVkBuffer> GetBuffer (void) const noexcept;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -175,4 +175,11 @@ namespace SHADE
|
|||
computeResource->descSet->UpdateDescriptorSetBuffer(set, binding);
|
||||
}
|
||||
|
||||
void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept
|
||||
{
|
||||
computeResource->descSet->ModifyWriteDescImage(set, binding, viewSamplerLayouts);
|
||||
computeResource->descSet->UpdateDescriptorSetImages(set, binding);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Resource/SHHandle.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
#include "Graphics/SHVulkanIncludes.h"
|
||||
#include <initializer_list>
|
||||
#include <string>
|
||||
|
@ -10,7 +11,6 @@
|
|||
namespace SHADE
|
||||
{
|
||||
class SHVkPipeline;
|
||||
class SHVkDescriptorSetGroup;
|
||||
class SHVkDescriptorPool;
|
||||
class SHVkLogicalDevice;
|
||||
class SHVkPipelineLayout;
|
||||
|
@ -74,6 +74,8 @@ namespace SHADE
|
|||
void SetDynamicOffsets (std::span<uint32_t> perFrameSizes) noexcept;
|
||||
|
||||
void ModifyWriteDescBufferComputeResource (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||
void ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
|
||||
|
||||
|
||||
friend class SHRenderGraph;
|
||||
friend class SHRenderGraphNode;
|
||||
|
|
Loading…
Reference in New Issue