• Advertisement
Sign in to follow this  

SAO Ambient occlusion : What is wrong ?

This topic is 1228 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I try to implement a glsl shader for screen-space ambient occlusion.

 

I tried somthing similar to this: 

https://gist.github.com/fisch0920/6770311

 

But there are some strange black dots in the render. What is wrong ?

 

No AO: http://s18.postimg.org/k21sqjgav/SAO1.jpg

 

With AO : http://s3.postimg.org/7lxraqehd/SAO2.jpg

 

Code:

#version 330

uniform sampler2D ColorSampler;
uniform sampler2D NormalSampler;
uniform sampler2D WorldPosSampler;
uniform mat4 ViewMatrix;
uniform mat4 ProjMatrix;

out float FragAO;

float SampleRadius = 20.0;
float PI = 3.14159265359;

float Random(vec4 seed4)
{
    float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673));
    return fract(sin(dot_product) * 43758.5453);
}

float GetAOSample(vec3 SamplePos, vec3 fNormal, vec4 fViewPos)
{
    vec4 SampleCoord = ProjMatrix * vec4(SamplePos, 1.0);
    SampleCoord.xy /= SampleCoord.w;
    SampleCoord.xy = SampleCoord.xy * 0.5 + 0.5;
        
    vec4 sWorldPos = vec4(texture(WorldPosSampler, SampleCoord.xy, 0).xyz, 1.0);
    vec4 sViewPos = ViewMatrix*sWorldPos; 
    
    vec3 sampleDir = sViewPos.xyz-fViewPos.xyz;
    float NdotS = max(dot(fNormal, sampleDir), 0.0);
    float dist2 = dot(sampleDir,sampleDir);
    
    float SampleRadius2 = SampleRadius * SampleRadius;
    float f = max(SampleRadius2 - dist2, 0.0) / SampleRadius2;
    return f * f * f * NdotS / (0.0001 + dist2);
}

void main(void)
{
    ivec2 FragCoord = ivec2(gl_FragCoord.xy);
    vec4 fWorldPos = vec4(texelFetch(WorldPosSampler, FragCoord, 0).xyz, 1.0);
    
    vec3 fNormal = texelFetch(NormalSampler, FragCoord, 0).xyz * 2.0 - 1.0;
    vec4 fViewPos = ViewMatrix*fWorldPos;
    fNormal.z = sqrt(1.0-dot(fNormal.xy, fNormal.xy));
    
    float AOValue = 0.0;
    float thetaRand = Random(vec4(gl_FragCoord.yyxx))*2.0*PI;
    
    for(int i=0; i<32; i++)
    {
        float iStep = float(i) / 32.0;
        float radius = iStep*SampleRadius;
        float theta = thetaRand + iStep * 4.0*PI;
        
        vec3 offset = vec3(radius*cos(theta), radius*sin(theta), 0.0);
        offset *= sign(dot(offset,fNormal));
        
        vec3 SamplePos = fViewPos.xyz + offset;
        AOValue += GetAOSample(SamplePos, fNormal, fViewPos);
    }
    FragAO = max( AOValue/32.0, 0.0);
} 

Then in my final shader I use:

float AO = pow(1.0 - texelFetch(AOSampler, FragCoord, 0).x, 1.0 + AOCoeff * 8.0);
Edited by Marc477

Share this post


Link to post
Share on other sites
Advertisement

The banding artifact is very clearly visible in the image you posted. 

Have a look here: http://mtnphil.wordpress.com/2013/06/26/know-your-ssao-artifacts/

Theres a good explanation how to get rid of those bandings by using mixups when sampling.

 

Also are you blurring the SSAO texture. A 3x3 gaussian blur can help a lot against the high frequency noise in there.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement