frag_ao.cginc 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. half frag_ao (v2f_ao i, int sampleCount, float3 samples[INPUT_SAMPLE_COUNT])
  2. {
  3. // read random normal from noise texture
  4. half3 randN = tex2D (_RandomTexture, i.uvr).xyz * 2.0 - 1.0;
  5. // read scene depth/normal
  6. float4 depthnormal = tex2D (_CameraDepthNormalsTexture, i.uv);
  7. float3 viewNorm;
  8. float depth;
  9. DecodeDepthNormal (depthnormal, depth, viewNorm);
  10. depth *= _ProjectionParams.z;
  11. float scale = _Params.x / depth;
  12. // accumulated occlusion factor
  13. float occ = 0.0;
  14. for (int s = 0; s < sampleCount; ++s)
  15. {
  16. // Reflect sample direction around a random vector
  17. half3 randomDir = reflect(samples[s], randN);
  18. // Make it point to the upper hemisphere
  19. half flip = (dot(viewNorm,randomDir)<0) ? 1.0 : -1.0;
  20. randomDir *= -flip;
  21. // Add a bit of normal to reduce self shadowing
  22. randomDir += viewNorm * 0.3;
  23. float2 offset = randomDir.xy * scale;
  24. float sD = depth - (randomDir.z * _Params.x);
  25. // Sample depth at offset location
  26. float4 sampleND = tex2D (_CameraDepthNormalsTexture, i.uv + offset);
  27. float sampleD;
  28. float3 sampleN;
  29. DecodeDepthNormal (sampleND, sampleD, sampleN);
  30. sampleD *= _ProjectionParams.z;
  31. float zd = saturate(sD-sampleD);
  32. if (zd > _Params.y) {
  33. // This sample occludes, contribute to occlusion
  34. occ += pow(1-zd,_Params.z); // sc2
  35. //occ += 1.0-saturate(pow(1.0 - zd, 11.0) + zd); // nullsq
  36. //occ += 1.0/(1.0+zd*zd*10); // iq
  37. }
  38. }
  39. occ /= sampleCount;
  40. return 1-occ;
  41. }