I have a problem with SSAO. On left hand black area.
Code shader:
Texture2D<uint> texGBufferNormal : register(t0);
Texture2D<float> texGBufferDepth : register(t1);
Texture2D<float4> texSSAONoise : register(t2);
float3 GetUV(float3 position)
{
float4 vp = mul(float4(position, 1.0), ViewProject);
vp.xy = float2(0.5, 0.5) + float2(0.5, -0.5) * vp.xy / vp.w;
return float3(vp.xy, vp.z / vp.w);
}
float3 GetNormal(in Texture2D<uint> texNormal, in int3 coord) {
return normalize(2.0 * UnpackNormalSphermap(texNormal.Load(coord)) - 1.0);
}
float3 GetPosition(in Texture2D<float> texDepth, in int3 coord) {
float4 position = 1.0;
float2 size;
texDepth.GetDimensions(size.x, size.y);
position.x = 2.0 * (coord.x / size.x) - 1.0;
position.y = -(2.0 * (coord.y / size.y) - 1.0);
position.z = texDepth.Load(coord);
position = mul(position, ViewProjectInverse);
position /= position.w;
return position.xyz;
}
float3 GetPosition(in float2 coord, float depth) {
float4 position = 1.0;
position.x = 2.0 * coord.x - 1.0;
position.y = -(2.0 * coord.y - 1.0);
position.z = depth;
position = mul(position, ViewProjectInverse);
position /= position.w;
return position.xyz;
}
float DepthInvSqrt(float nonLinearDepth) {
return 1 / sqrt(1.0 - nonLinearDepth);
}
float GetDepth(in Texture2D<float> texDepth, float2 uv) {
return texGBufferDepth.Sample(samplerPoint, uv);
}
float GetDepth(in Texture2D<float> texDepth, int3 screenPos) {
return texGBufferDepth.Load(screenPos);
}
float CalculateOcclusion(in float3 position, in float3 direction, in float radius, in float pixelDepth) {
float3 uv = GetUV(position + radius * direction);
float d1 = DepthInvSqrt(GetDepth(texGBufferDepth, uv.xy));
float d2 = DepthInvSqrt(uv.z);
return step(d1 - d2, 0) * min(1.0, radius / abs(d2 - pixelDepth));
}
float GetRNDTexFactor(float2 texSize) {
float width;
float height;
texGBufferDepth.GetDimensions(width, height);
return float2(width, height) / texSize;
}
float main(FullScreenPSIn input) : SV_TARGET0 {
int3 screenPos = int3(input.Position.xy, 0);
float depth = DepthInvSqrt(GetDepth(texGBufferDepth, screenPos));
float3 normal = GetNormal(texGBufferNormal, screenPos);
float3 position = GetPosition(texGBufferDepth, screenPos) + normal * SSAO_NORMAL_BIAS;
float3 random = normalize(2.0 * texSSAONoise.Sample(samplerNoise, input.Texcoord * GetRNDTexFactor(SSAO_RND_TEX_SIZE)).rgb - 1.0);
float SSAO = 0;
[unroll]
for (int index = 0; index < SSAO_KERNEL_SIZE; index++) {
float3 dir = reflect(SamplesKernel[index].xyz, random);
SSAO += CalculateOcclusion(position, dir * sign(dot(dir, normal)), SSAO_RADIUS, depth);
}
return 1.0 - SSAO / SSAO_KERNEL_SIZE;
}