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