Search Unity

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,553
    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,553
    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 ?