Advertisement

SSAO using Opengles2

Started by November 23, 2017 02:07 PM
5 comments, last by AhmedSaleh 7 years, 2 months ago

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

Game Programming is the process of converting dead pictures to live ones .

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.

Advertisement

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 ? 

Game Programming is the process of converting dead pictures to live ones .

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.

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 ?

Game Programming is the process of converting dead pictures to live ones .

adjusting the offset didn't change anything... still there are outlines..

Game Programming is the process of converting dead pictures to live ones .

This topic is closed to new replies.

Advertisement