Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Alternative Screen Space Ambient Occlusion (SSAO) Shader

Discussion in 'Shaders' started by AnomalusUndrdog, May 27, 2010.

  1. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,551
    I saw an article in Gamedev.net about a shader for SSAO
    http://www.gamedev.net/reference/programming/features/simpleSSAO/

    I'm wondering if this can be used in the free version of Unity as the SSAO shader that comes with Unity requires Pro.

    The code unfortunately, is in HLSL. I hardly know cg or GLSL in the first place, so I'm having trouble trying to convert it to cg.

    Code (csharp):
    1.  
    2. sampler g_buffer_norm;
    3. sampler g_buffer_pos;
    4. sampler g_random;
    5. float random_size;
    6. float g_sample_rad;
    7. float g_intensity;
    8. float g_scale;
    9. float g_bias;
    10.  
    11. struct PS_INPUT
    12. {
    13.  float2 uv : TEXCOORD0;
    14. };
    15.  
    16. struct PS_OUTPUT
    17. {
    18.  float4 color : COLOR0;
    19. };
    20.  
    21. float3 getPosition(in float2 uv)
    22. {
    23.  return tex2D(g_buffer_pos,uv).xyz;
    24. }
    25.  
    26. float3 getNormal(in float2 uv)
    27. {
    28.  return normalize(tex2D(g_buffer_norm, uv).xyz * 2.0f - 1.0f);
    29. }
    30.  
    31. float2 getRandom(in float2 uv)
    32. {
    33.  return normalize(tex2D(g_random, g_screen_size * uv / random_size).xy * 2.0f - 1.0f);
    34. }
    35.  
    36. float doAmbientOcclusion(in float2 tcoord,in float2 uv, in float3 p, in float3 cnorm)
    37. {
    38.  float3 diff = getPosition(tcoord + uv) - p;
    39.  const float3 v = normalize(diff);
    40.  const float d = length(diff)*g_scale;
    41.  return max(0.0,dot(cnorm,v)-g_bias)*(1.0/(1.0+d))*g_intensity;
    42. }
    43.  
    44. PS_OUTPUT main(PS_INPUT i)
    45. {
    46.  PS_OUTPUT o = (PS_OUTPUT)0;
    47.  
    48.  o.color.rgb = 1.0f;
    49.  const float2 vec[4] = {float2(1,0),float2(-1,0),
    50.             float2(0,1),float2(0,-1)};
    51.  
    52.  float3 p = getPosition(i.uv);
    53.  float3 n = getNormal(i.uv);
    54.  float2 rand = getRandom(i.uv);
    55.  
    56.  float ao = 0.0f;
    57.  float rad = g_sample_rad/p.z;
    58.  
    59.  //**SSAO Calculation**//
    60.  int iterations = 4;
    61.  for (int j = 0; j < iterations; ++j)
    62.  {
    63.   float2 coord1 = reflect(vec[j],rand)*rad;
    64.   float2 coord2 = float2(coord1.x*0.707 - coord1.y*0.707, coord1.x*0.707 + coord1.y*0.707);
    65.  
    66.   ao += doAmbientOcclusion(i.uv,coord1*0.25, p, n);
    67.   ao += doAmbientOcclusion(i.uv,coord2*0.5, p, n);
    68.   ao += doAmbientOcclusion(i.uv,coord1*0.75, p, n);
    69.   ao += doAmbientOcclusion(i.uv,coord2, p, n);
    70.  }
    71.  ao/=(float)iterations*4.0;
    72.  //**END**//
    73.  
    74. //Do stuff here with your occlusion value “ao”: modulate ambient lighting, write it to a buffer for later //use, etc.
    75.  return o;
    76. }
    77.  
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    SSAO requires rendering information to buffers called RenderTextures, which are only supported in Unity Pro. This is true of most full-screen effects. The approach you linked is no different:
     
  3. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,551
    I see, thanks for clearing that up for me.
     
  4. bugsbun

    bugsbun

    Joined:
    Jun 26, 2017
    Posts:
    27
    Hello ! were u able to convert this into CG ?