Advertisement Jump to content
Sign in to follow this  

SSAO using Opengles2

This topic is 423 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'm following the following article which uses the depth buffer to implement 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
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!