SHADE_Y3/Assets/Shaders/SSAO_CS.glsl

106 lines
3.1 KiB
Plaintext
Raw Normal View History

#version 450
2022-12-28 20:47:20 +08:00
#pragma vscode_glsllint_stage : comp
2022-10-31 20:49:28 +08:00
const uint NUM_SAMPLES = 64;
const uint NUM_ROTATIONS = 16;
const int ROTATION_KERNEL_W = 4;
const int ROTATION_KERNEL_H = 4;
// can perhaps pass in as push constant.
const float RADIUS = 0.35f;
2022-11-22 16:00:05 +08:00
const float BIAS = 0.0025f;
layout(local_size_x = 16, local_size_y = 16) in;
2022-12-28 20:47:20 +08:00
layout(set = 3, binding = 0, rgba32f) uniform image2D positions;
layout(set = 3, binding = 1, rgba32f) uniform image2D normals;
layout(set = 3, binding = 2, rgba32f) uniform image2D outputImage;
// SSAO data
2022-12-28 20:47:20 +08:00
layout(std430, set = 4, binding = 0) buffer SSAOData
{
2022-10-31 20:49:28 +08:00
vec4 samples[NUM_SAMPLES];
} ssaoData;
2022-12-28 20:47:20 +08:00
layout (set = 4, binding = 1) uniform sampler2D noiseTexture;
2022-10-31 23:28:46 +08:00
2022-10-31 20:49:28 +08:00
layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 projMat;
} cameraData;
void main()
{
2022-11-01 20:10:59 +08:00
// image size of the SSAO image
ivec2 ssaoSize = imageSize (outputImage);
2022-10-31 20:49:28 +08:00
2022-11-01 20:10:59 +08:00
// global thread
2022-10-31 20:49:28 +08:00
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
// load all the necessary variables
vec3 viewSpacePos = imageLoad (positions, globalThread).rgb;
vec3 viewSpaceNormal = normalize (imageLoad (normals, globalThread).rgb);
2022-11-01 20:10:59 +08:00
// Get the noise dimension. This should be 4x4
2022-11-01 11:57:08 +08:00
vec2 noiseDim = vec2 (textureSize(noiseTexture, 0));
2022-11-01 20:10:59 +08:00
// Get normlized thread UV coordinates
vec2 threadUV = (vec2(globalThread)) / vec2(ssaoSize);
vec2 noiseUVMult = vec2 (vec2(ssaoSize) / noiseDim);
2022-11-01 02:32:14 +08:00
noiseUVMult *= threadUV;
2022-11-01 20:10:59 +08:00
// sample from the noise
2022-11-01 11:57:08 +08:00
vec3 randomVec = texture(noiseTexture, noiseUVMult).rgb;
2022-10-31 20:49:28 +08:00
// Gram schmidt
vec3 tangent = normalize (randomVec - (viewSpaceNormal * dot(viewSpaceNormal, randomVec)));
2022-11-01 11:57:08 +08:00
vec3 bitangent = normalize (cross (tangent, viewSpaceNormal));
2022-10-31 23:28:46 +08:00
2022-11-01 20:10:59 +08:00
// matrix for tangent space to view space
2022-11-01 02:32:14 +08:00
mat3 TBN = mat3(tangent, bitangent, viewSpaceNormal);
2022-10-31 20:49:28 +08:00
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.
2022-11-01 20:10:59 +08:00
vec3 displacementVector = TBN * ssaoData.samples[i].rgb;
// Why are we adding positions?
displacementVector = viewSpacePos + displacementVector * RADIUS;
2022-10-31 20:49:28 +08:00
// Now we take that offset position and bring it to clip space
2022-11-01 20:10:59 +08:00
vec4 offsetPos = vec4 (displacementVector, 1.0f);
2022-10-31 20:49:28 +08:00
offsetPos = cameraData.projMat * offsetPos;
// then we do perspective division
offsetPos.xyz /= offsetPos.w;
// and bring it from [-1, 1] to screen coordinates
offsetPos.xyz = ((offsetPos.xyz * 0.5f) + 0.5f);
2022-11-01 20:10:59 +08:00
offsetPos.xy *= vec2(ssaoSize.xy);
2022-10-31 20:49:28 +08:00
2022-11-01 20:10:59 +08:00
// Now we attempt to get a position at that point.
2022-10-31 20:49:28 +08:00
float sampleDepth = imageLoad (positions, ivec2 (offsetPos.xy)).z;
2022-11-01 20:10:59 +08:00
// skip checks
2022-11-01 12:47:50 +08:00
if (sampleDepth == 0.0f)
continue;
2022-11-01 20:10:59 +08:00
// if sampled fragment is in front of current fragment, just occlude
2022-10-31 20:49:28 +08:00
float rangeCheck = smoothstep (0.0f, 1.0f, RADIUS / abs (viewSpacePos.z - sampleDepth));
2022-11-01 20:10:59 +08:00
occlusion += (sampleDepth <= displacementVector.z - BIAS ? 1.0f : 0.0f) * rangeCheck;
2022-10-31 20:49:28 +08:00
}
2022-10-31 23:28:46 +08:00
occlusion = 1.0f - (occlusion / float(NUM_SAMPLES));
2022-10-31 20:49:28 +08:00
// store result into result image
2022-11-01 20:10:59 +08:00
imageStore(outputImage, globalThread, occlusion.rrrr);
}