Set SSAO shader constants via specialization

This commit is contained in:
saschawillems 2016-11-01 15:39:54 +01:00
parent 1713a968d4
commit 3983cbd732
3 changed files with 31 additions and 13 deletions

View file

@ -7,9 +7,12 @@ layout (binding = 0) uniform sampler2D samplerPositionDepth;
layout (binding = 1) uniform sampler2D samplerNormal; layout (binding = 1) uniform sampler2D samplerNormal;
layout (binding = 2) uniform sampler2D ssaoNoise; layout (binding = 2) uniform sampler2D ssaoNoise;
layout (constant_id = 0) const int SSAO_KERNEL_SIZE = 64;
layout (constant_id = 1) const float SSAO_RADIUS = 0.5;
layout (binding = 3) uniform UBOSSAOKernel layout (binding = 3) uniform UBOSSAOKernel
{ {
vec4 samples[64]; // todo: specialization const vec4 samples[SSAO_KERNEL_SIZE];
} uboSSAOKernel; } uboSSAOKernel;
layout (binding = 4) uniform UBO layout (binding = 4) uniform UBO
@ -21,10 +24,6 @@ layout (location = 0) in vec2 inUV;
layout (location = 0) out float outFragColor; layout (location = 0) out float outFragColor;
// todo: specialization const
const int kernelSize = 32;
const float radius = 0.5;
void main() void main()
{ {
// Get G-Buffer values // Get G-Buffer values
@ -35,7 +34,7 @@ void main()
ivec2 texDim = textureSize(samplerPositionDepth, 0); ivec2 texDim = textureSize(samplerPositionDepth, 0);
ivec2 noiseDim = textureSize(ssaoNoise, 0); ivec2 noiseDim = textureSize(ssaoNoise, 0);
const vec2 noiseUV = vec2(float(texDim.x)/float(noiseDim.x), float(texDim.y)/(noiseDim.y)) * inUV; const vec2 noiseUV = vec2(float(texDim.x)/float(noiseDim.x), float(texDim.y)/(noiseDim.y)) * inUV;
vec3 randomVec = texture(ssaoNoise, noiseUV).xyz; vec3 randomVec = texture(ssaoNoise, noiseUV).xyz * 2.0 - 1.0;
// Create TBN matrix // Create TBN matrix
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal)); vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
@ -44,10 +43,10 @@ void main()
// Calculate occlusion value // Calculate occlusion value
float occlusion = 0.0f; float occlusion = 0.0f;
for(int i = 0; i < kernelSize; i++) for(int i = 0; i < SSAO_KERNEL_SIZE; i++)
{ {
vec3 samplePos = TBN * uboSSAOKernel.samples[i].xyz; vec3 samplePos = TBN * uboSSAOKernel.samples[i].xyz;
samplePos = fragPos + samplePos * radius; samplePos = fragPos + samplePos * SSAO_RADIUS;
// project // project
vec4 offset = vec4(samplePos, 1.0f); vec4 offset = vec4(samplePos, 1.0f);
@ -57,11 +56,16 @@ void main()
float sampleDepth = -texture(samplerPositionDepth, offset.xy).w; float sampleDepth = -texture(samplerPositionDepth, offset.xy).w;
#define RANGE_CHECK 1
#ifdef RANGE_CHECK
// Range check // Range check
float rangeCheck = smoothstep(0.0f, 1.0f, radius / abs(fragPos.z - sampleDepth)); float rangeCheck = smoothstep(0.0f, 1.0f, SSAO_RADIUS / abs(fragPos.z - sampleDepth));
occlusion += (sampleDepth >= samplePos.z ? 1.0f : 0.0f) * rangeCheck; occlusion += (sampleDepth >= samplePos.z ? 1.0f : 0.0f) * rangeCheck;
#else
occlusion += (sampleDepth >= samplePos.z ? 1.0f : 0.0f);
#endif
} }
occlusion = 1.0 - (occlusion / float(kernelSize)); occlusion = 1.0 - (occlusion / float(SSAO_KERNEL_SIZE));
outFragColor = occlusion; outFragColor = occlusion;
} }

Binary file not shown.

View file

@ -25,6 +25,7 @@
#define ENABLE_VALIDATION false #define ENABLE_VALIDATION false
#define SSAO_KERNEL_SIZE 32 #define SSAO_KERNEL_SIZE 32
#define SSAO_RADIUS 0.5f
#if defined(__ANDROID__) #if defined(__ANDROID__)
#define SSAO_NOISE_DIM 8 #define SSAO_NOISE_DIM 8
@ -948,9 +949,22 @@ public:
// SSAO Pass // SSAO Pass
shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/ssao.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/ssao.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
{
// Set constant parameters via specialization constants
std::array<VkSpecializationMapEntry, 2> specializationMapEntries;
specializationMapEntries[0] = vkTools::initializers::specializationMapEntry(0, 0, sizeof(uint32_t)); // SSAO Kernel size
specializationMapEntries[1] = vkTools::initializers::specializationMapEntry(1, sizeof(uint32_t), sizeof(float)); // SSAO radius
struct {
uint32_t kernelSize = SSAO_KERNEL_SIZE;
float radius = SSAO_RADIUS;
} specializationData;
VkSpecializationInfo specializationInfo = vkTools::initializers::specializationInfo(2, specializationMapEntries.data(), sizeof(specializationData), &specializationData);
shaderStages[1].pSpecializationInfo = &specializationInfo;
pipelineCreateInfo.renderPass = frameBuffers.ssao.renderPass; pipelineCreateInfo.renderPass = frameBuffers.ssao.renderPass;
pipelineCreateInfo.layout = pipelineLayouts.ssao; pipelineCreateInfo.layout = pipelineLayouts.ssao;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.ssao)); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.ssao));
}
// SSAO blur pass // SSAO blur pass
shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);