2
\$\begingroup\$

I'm trying to implement SSAO based on this tutorial. My setup:

  • OpenGL 3.2
  • Forward renderer
  • View-space depth and normal in a single 16-bit floating point texture.

The result I get is this: SSAO Problem

The black area follows the camera and is always in the center of the screen. This is my depth/normal pass shader:

#version 150 core
#extension GL_ARB_explicit_attrib_location : enable

uniform mat4 _ViewMatrix;
uniform mat4 _ViewProjectionMatrix;
uniform mat4 modelMatrix;

layout (location = 0) in vec4 aPosition;
layout (location = 2) in vec3 aNormal;

out vec4 vPosition;
out vec3 vNormal;

// Vertex shader.
void main()
{
    gl_Position = _ViewProjectionMatrix * modelMatrix * aPosition;

    mat4 modelViewMatrix = _ViewMatrix * modelMatrix;
    vPosition = modelViewMatrix * aPosition;
    vNormal = mat3( modelViewMatrix ) * aNormal;
}

// Fragment shader:
#version 150 core

in vec4 vPosition;
in vec3 vNormal;

out vec4 outDepthNormal;

void main()
{
    outDepthNormal = vec4( vPosition.z, normalize( vNormal ));
}

This is my SSAO shader:

// Vertex shader:
#version 150 core
#extension GL_ARB_explicit_attrib_location : enable

uniform float uTanHalfFov;
uniform float uAspectRatio;

layout (location = 0) in vec4 aPosition;
layout (location = 1) in vec2 aTexCoord;

out vec2 vTexCoord;
noperspective out vec3 vViewDir;

void main()
{
    gl_Position = aPosition;
    vTexCoord = aTexCoord;

    vViewDir = vec3( -aPosition.x * uTanHalfFov * uAspectRatio, -aPosition.y * uTanHalfFov, 1.0 );
}

// Fragment shader:
#version 150 core

uniform sampler2D depthNormalMap;
uniform sampler2D noiseMap;
uniform mat4 _ProjectionMatrix;
uniform int uKernelSize;
const int MAX_KERNEL_SIZE = 128;
uniform vec3 uKernelOffsets[ MAX_KERNEL_SIZE ];
uniform float uRadius;
uniform float uPower;

in vec2 vTexCoord;
noperspective in vec3 vViewDir;

out vec4 fragColor;

float ssao( in mat3 kernelBasis, in vec3 originPos, in float radius )
{
    float occlusion = 0.0;

    for (int i = 0; i < uKernelSize; ++i)
    {
        vec3 samplePos = kernelBasis * uKernelOffsets[i];
        samplePos = samplePos * radius + originPos;

        // project sample position:
        vec4 offset = _ProjectionMatrix * vec4( samplePos, 1.0 );
        offset.xy /= offset.w; // only need xy
        offset.xy = offset.xy * 0.5 + 0.5; // scale/bias to texcoords

        // get sample depth:
        float sampleDepth = texture( depthNormalMap, offset.xy ).r;

        float rangeCheck = smoothstep( 0.0, 1.0, radius / abs( originPos.z - sampleDepth ) );
        occlusion += rangeCheck * step( sampleDepth, samplePos.z );
    }

    occlusion = 1.0 - (occlusion / float( uKernelSize ));

    return pow( abs( occlusion ), uPower );
}

void main()
{
    vec2 noiseTexCoords = vec2( textureSize( depthNormalMap, 0 )) / vec2( textureSize( noiseMap, 0 ) );
    noiseTexCoords *= vTexCoord;

    // get view space origin:
    float originDepth = texture( depthNormalMap, vTexCoord ).r;
    vec3 originPos = normalize( vViewDir ) * originDepth;

    // get view space normal:
    vec3 normal = normalize( texture( depthNormalMap, vTexCoord ).gba );

    // construct kernel basis matrix:
    vec3 rvec = normalize( texture( noiseMap, noiseTexCoords ).rgb );
    vec3 tangent = normalize( rvec - normal * dot( rvec, normal ) );
    vec3 bitangent = cross( tangent, normal );
    mat3 kernelBasis = mat3( tangent, bitangent, normal );

    fragColor = vec4( ssao( kernelBasis, originPos, uRadius ) );
}

I guess something is going wrong with the depth reconstruction.

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Ok, I got it working. My depth writing shader now looks like this:

void main()
{
    float linearDepth = -vPosition.z * uLinearDepthConstant;
    outDepthNormal = vec4( linearDepth, normalize( vNormal ) );
}

And when I read it in SSAO shader, I inverted normals and multiply depth value with (far - near).

enter image description here

\$\endgroup\$
1
  • 5
    \$\begingroup\$ maybe explain what was wrong and how that code change fixed it? for future visitors \$\endgroup\$
    – jhocking
    Feb 10, 2014 at 18:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .