Jump to content
  • Advertisement
Sign in to follow this  

SSAO using Opengles2

Recommended Posts

I'm following the following article which uses the depth buffer to implement ssao.http://theorangeduck.com/page/pure-depth-ssao

I have got the following result result image I don't know what's wrong.. I made sure that the depth buffer image is correct and the random texture is correct also.

As you see there are antialiasing effect, and its very dark..

I'm not doing any post processing like blurring.

Would someone take a look at the shader ? maybe there is something wrong..


#version 100

precision mediump int;
precision mediump float;

uniform sampler2D DepthMap;
uniform sampler2D RandomtextureSampler;
varying vec2 uv;

vec3 normal_from_depth(float depth, vec2 texcoords) {

  const vec2 offset1 = vec2(0.0,0.001);
  const vec2 offset2 = vec2(0.001,0.0);

  float depth1 = texture2D(DepthMap, texcoords + offset1).r;
  float depth2 = texture2D(DepthMap, texcoords + offset2).r;

  vec3 p1 = vec3(offset1, depth1 - depth);
  vec3 p2 = vec3(offset2, depth2 - depth);

  vec3 normal = cross(p1, p2);
  normal.z = -normal.z;

  return normalize(normal);

void main()

  const float total_strength = 1.40;
  const float base = 0.2;

  const float area = 0.0075;
  const float falloff = 0.000001;

  const float radius = 0.0002;
  const int samples  = 16;
  vec3 sample_sphere[16];

   sample_sphere[0] = vec3( 0.5381, 0.1856,-0.4319);
   sample_sphere[1] = vec3( 0.1379, 0.2486, 0.4430);
   sample_sphere[2] = vec3( 0.3371, 0.5679,-0.0057);
   sample_sphere[3] = vec3(-0.6999,-0.0451,-0.0019);
   sample_sphere[4] = vec3( 0.0689,-0.1598,-0.8547);
   sample_sphere[5] = vec3( 0.0560, 0.0069,-0.1843);
   sample_sphere[6] = vec3(-0.0146, 0.1402, 0.0762);
   sample_sphere[7] = vec3( 0.0100,-0.1924,-0.0344);
   sample_sphere[8] = vec3(-0.3577,-0.5301,-0.4358);
   sample_sphere[9] = vec3(-0.3169, 0.1063, 0.0158);
   sample_sphere[10] = vec3( 0.0103,-0.5869, 0.0046);
   sample_sphere[11] = vec3(-0.0897,-0.4940, 0.3287);
   sample_sphere[12] = vec3( 0.7119,-0.0154,-0.0918); 
   sample_sphere[13] = vec3(-0.0533, 0.0596,-0.5411);
   sample_sphere[14] = vec3( 0.0352,-0.0631, 0.5460); 
   sample_sphere[15] = vec3(-0.4776, 0.2847,-0.0271);

  vec3 random = normalize( texture2D(RandomtextureSampler, uv * 4.0).rgb );

  float depth = texture2D(DepthMap, uv).r;

  vec3 position = vec3(uv, depth);
  vec3 normal = normal_from_depth(depth, uv);

  float radius_depth = radius/depth;
  float occlusion = 0.0;
  for(int i=0; i < 16; i++) {

    vec3 ray = radius_depth * reflect(sample_sphere[i], random);
    vec3 hemi_ray = position + sign(dot(ray,normal)) * ray;

    float occ_depth = texture2D(DepthMap, clamp(hemi_ray.xy, 0.0, 1.0)).r;
    float difference = depth - occ_depth;

    occlusion += step(falloff, difference) * (1.0-smoothstep(falloff, area, difference));

  float ao = 1.0 - total_strength * occlusion * (1.0 / 16.0);
  float oc = clamp(ao + base, 0.0, 1.0);
  gl_FragColor = vec4(oc,oc,oc, 1.0) ;


The depth texture is a render to texture and its format PF_FLOAT16R

Edited by AhmedSaleh

Share this post

Link to post
Share on other sites

At first glance I'd say the offsets for your "normal_from_depth" function are wrong, they should be in the scale of a texel, so 1/resolution, not hardcoded to 0.001. With your current value each sample is too far from the original pixel, which can cause this sort of edge filter artifact.

I'd start there and see if it fixes the issue.

Share this post

Link to post
Share on other sites

Thanks a lot for your reply. 

Which resoultion should I take into account ?  1/width of depth buffer ?

The effect is like edge filtering actually, is that what SSAO should do ? 

Share this post

Link to post
Share on other sites

Yeah, 1/width of the depth buffer. You want to take the delta between the neighboring pixels of the source image. Also no, SSAO should definitely not be causing this sort of aliased outline.

As a side note, generating a normal buffer from depth this way results in faceted/flat surfaces and not smooth surfaces (so spheres will look like bundles of triangles instead of smooth spheres). This can be a problem so if it's not something desirable for you consider outputting a thin GBuffer or not using normals in your SSAO approach.

Edited by Styves

Share this post

Link to post
Share on other sites

The problem is I'm using opengles 2 with no GBuffer... is there any alternative to not using normals in ssao ?

Also I think the offset should be 1/width for x, and 1/height for y is that correct ?

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!