SSAO is fully implemented
This commit is contained in:
parent
78545889da
commit
b0d08d27fd
|
@ -21,7 +21,7 @@ layout(set = 4, binding = 0, rgba32f) uniform image2D positions;
|
|||
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
|
||||
layout(set = 4, binding = 2, rgba8) uniform image2D albedo;
|
||||
layout(set = 4, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
||||
layout(set = 4, binding = 4, rgba32f) uniform image2D ssaoImage;
|
||||
layout(set = 4, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
||||
layout(set = 4, binding = 5, rgba8) uniform image2D targetImage;
|
||||
|
||||
layout(set = 1, binding = 0) uniform LightCounts
|
||||
|
@ -55,7 +55,7 @@ void main()
|
|||
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
||||
|
||||
// normal of fragment
|
||||
vec3 normalView = -imageLoad(normals, globalThread).rgb;
|
||||
vec3 normalView = imageLoad(normals, globalThread).rgb;
|
||||
|
||||
vec3 fragColor = vec3 (0.0f);
|
||||
|
||||
|
@ -78,9 +78,11 @@ void main()
|
|||
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
||||
}
|
||||
|
||||
float ssaoVal = imageLoad (ssaoBlurredImage, globalThread).r;
|
||||
fragColor *= ssaoVal;
|
||||
|
||||
// store result into result image
|
||||
//imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(normalView, 1.0f));
|
||||
//imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor, 1.0f));
|
||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(imageLoad(ssaoImage, globalThread).rgba/*, 1.0f*/));
|
||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
||||
//imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(ssaoVal.rrr, 1.0f));
|
||||
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,58 @@
|
|||
#version 450
|
||||
|
||||
#define BLUR_WIDTH 5
|
||||
#define BLUR_HALF_WIDTH BLUR_WIDTH / 2
|
||||
#define SHM_WIDTH BLUR_WIDTH + 16 - 1
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 16) in;
|
||||
layout(set = 4, binding = 0, r8) uniform image2D ssaoImage;
|
||||
layout(set = 4, binding = 1, r8) uniform image2D ssaoBlurImage;
|
||||
|
||||
|
||||
float GetSSAOValue(ivec2 uv, ivec2 imageSize)
|
||||
{
|
||||
if (uv.x >= 0 && uv.y >= 0 && uv.x < imageSize.x && uv.y < imageSize.y)
|
||||
{
|
||||
return imageLoad (ssaoImage, uv).r;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
shared float sharedPixels[16 + BLUR_WIDTH - 1][16 + BLUR_WIDTH - 1];
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
|
||||
ivec2 localThread = ivec2 (gl_LocalInvocationID.xy);
|
||||
ivec2 inputImageSize = imageSize(ssaoImage);
|
||||
|
||||
// Load color into shared memory
|
||||
ivec2 start = ivec2 (gl_WorkGroupID) * ivec2 (gl_WorkGroupSize) - (BLUR_HALF_WIDTH);
|
||||
for (int i = localThread.x; i < SHM_WIDTH; i += int (gl_WorkGroupSize.x))
|
||||
{
|
||||
for (int j = localThread.y; j < SHM_WIDTH; j += int (gl_WorkGroupSize.y))
|
||||
{
|
||||
float value = GetSSAOValue (start + ivec2 (i, j), inputImageSize);
|
||||
sharedPixels[i][j] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// wait for all shared memory to load
|
||||
barrier();
|
||||
|
||||
ivec2 shmStart = ivec2 (localThread + (BLUR_HALF_WIDTH));
|
||||
|
||||
float sum = 0;
|
||||
for (int i = -BLUR_HALF_WIDTH; i <= BLUR_HALF_WIDTH; ++i)
|
||||
{
|
||||
for (int j = -BLUR_HALF_WIDTH; j <= BLUR_HALF_WIDTH; ++j)
|
||||
{
|
||||
float sharedVal = sharedPixels[shmStart.x + i][shmStart.y + j];
|
||||
sum += sharedVal;
|
||||
}
|
||||
}
|
||||
|
||||
sum /= (BLUR_WIDTH * BLUR_WIDTH);
|
||||
imageStore(ssaoBlurImage, globalThread, vec4(sum.rrr, 1.0f));
|
||||
}
|
Binary file not shown.
|
@ -36,37 +36,45 @@ layout(set = 2, binding = 0) uniform CameraData
|
|||
|
||||
void main()
|
||||
{
|
||||
ivec2 size = imageSize (outputImage);
|
||||
// image size of the SSAO image
|
||||
ivec2 ssaoSize = imageSize (outputImage);
|
||||
|
||||
// global thread
|
||||
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
|
||||
|
||||
// load all the necessary variables
|
||||
vec3 viewSpacePos = imageLoad (positions, globalThread).rgb;
|
||||
vec3 viewSpaceNormal = normalize (imageLoad (normals, globalThread).rgb);
|
||||
//viewSpaceNormal = -viewSpaceNormal;
|
||||
|
||||
// Get the noise dimension. This should be 4x4
|
||||
vec2 noiseDim = vec2 (textureSize(noiseTexture, 0));
|
||||
vec2 threadUV = (vec2(globalThread) + vec2 (0.5f)) / vec2(size);
|
||||
vec2 noiseUVMult = vec2 (vec2(size) / noiseDim);
|
||||
|
||||
// Get normlized thread UV coordinates
|
||||
vec2 threadUV = (vec2(globalThread)) / vec2(ssaoSize);
|
||||
vec2 noiseUVMult = vec2 (vec2(ssaoSize) / noiseDim);
|
||||
noiseUVMult *= threadUV;
|
||||
|
||||
// sample from the noise
|
||||
vec3 randomVec = texture(noiseTexture, noiseUVMult).rgb;
|
||||
|
||||
// Gram schmidt
|
||||
vec3 tangent = normalize (randomVec - (viewSpaceNormal * dot(viewSpaceNormal, randomVec)));
|
||||
vec3 bitangent = normalize (cross (tangent, viewSpaceNormal));
|
||||
|
||||
// matrix for tangent to view
|
||||
// matrix for tangent space to view space
|
||||
mat3 TBN = mat3(tangent, bitangent, viewSpaceNormal);
|
||||
|
||||
float occlusion = 0.0f;
|
||||
for (int i = 0; i < NUM_SAMPLES; ++i)
|
||||
{
|
||||
// We want to get a position at an offset from the view space position. Offset scaled by radius.
|
||||
vec3 samplePos = TBN * ssaoData.samples[i].rgb;
|
||||
samplePos = viewSpacePos + samplePos * RADIUS;
|
||||
vec3 displacementVector = TBN * ssaoData.samples[i].rgb;
|
||||
|
||||
// Why are we adding positions?
|
||||
displacementVector = viewSpacePos + displacementVector * RADIUS;
|
||||
|
||||
// Now we take that offset position and bring it to clip space
|
||||
vec4 offsetPos = vec4 (samplePos, 1.0f);
|
||||
vec4 offsetPos = vec4 (displacementVector, 1.0f);
|
||||
offsetPos = cameraData.projMat * offsetPos;
|
||||
|
||||
// then we do perspective division
|
||||
|
@ -74,20 +82,23 @@ void main()
|
|||
|
||||
// and bring it from [-1, 1] to screen coordinates
|
||||
offsetPos.xyz = ((offsetPos.xyz * 0.5f) + 0.5f);
|
||||
offsetPos.xy *= vec2(size.xy);
|
||||
offsetPos.xy *= vec2(ssaoSize.xy);
|
||||
|
||||
// Now we attempt to get a position at that point.
|
||||
float sampleDepth = imageLoad (positions, ivec2 (offsetPos.xy)).z;
|
||||
|
||||
// skip checks
|
||||
if (sampleDepth == 0.0f)
|
||||
continue;
|
||||
|
||||
// if sampled fragment is in front of current fragment, just occlude
|
||||
float rangeCheck = smoothstep (0.0f, 1.0f, RADIUS / abs (viewSpacePos.z - sampleDepth));
|
||||
occlusion += (sampleDepth <= samplePos.z - BIAS ? 1.0f : 0.0f) * rangeCheck;
|
||||
//occlusion += (sampleDepth <= samplePos.z + BIAS ? 1.0f : 0.0f);
|
||||
occlusion += (sampleDepth <= displacementVector.z - BIAS ? 1.0f : 0.0f) * rangeCheck;
|
||||
}
|
||||
|
||||
occlusion = 1.0f - (occlusion / float(NUM_SAMPLES));
|
||||
|
||||
// store result into result image
|
||||
imageStore(outputImage, globalThread, vec4(occlusion.rrr, 1.0f));
|
||||
imageStore(outputImage, globalThread, occlusion.rrrr);
|
||||
|
||||
}
|
Binary file not shown.
|
@ -115,6 +115,7 @@ namespace SHADE
|
|||
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_FS.glsl");
|
||||
SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl");
|
||||
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl");
|
||||
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl");
|
||||
|
||||
shaderModuleLibrary.ImportAllShaderSource(device);
|
||||
shaderModuleLibrary.ReflectAllShaderModules();
|
||||
|
@ -169,7 +170,8 @@ namespace SHADE
|
|||
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||
worldRenderGraph->AddResource("Light Layer Indices", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("SSAO", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||
worldRenderGraph->AddResource("SSAO", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||
worldRenderGraph->AddResource("SSAO Blur", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* MAIN NODE */
|
||||
|
@ -184,7 +186,8 @@ namespace SHADE
|
|||
"Albedo",
|
||||
"Depth Buffer",
|
||||
"Scene",
|
||||
"SSAO"
|
||||
"SSAO",
|
||||
"SSAO Blur"
|
||||
},
|
||||
{}); // no predecessors
|
||||
|
||||
|
@ -225,12 +228,15 @@ namespace SHADE
|
|||
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
|
||||
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
|
||||
|
||||
auto ssaoBlurShader = shaderModuleLibrary.GetBuiltInShaderModule("SSAOBlur_CS");
|
||||
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"});
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* DEFERRED COMPOSITE SUBPASS INIT */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
auto deferredCompositeShader = shaderModuleLibrary.GetBuiltInShaderModule("DeferredComposite_CS");
|
||||
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO", "Scene" });
|
||||
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* DUMMY SUBPASS TO TRANSITION SCENE FOR PRESENT USAGE */
|
||||
|
|
Loading…
Reference in New Issue