1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
#ifndef __SSAO_INC
#define __SSAO_INC
#include "audiolink.cginc"
#include "globals.cginc"
#include "interpolators.cginc"
#if defined(_SSAO)
float get_ssao(v2f i, float3x3 tangentToWorld, out float2 debug) {
float3 objPos = mul(unity_WorldToObject, float4(i.worldPos, 1));
float4 clipPos = UnityObjectToClipPos(objPos);
float4 screenPos = ComputeScreenPos(clipPos);
const float2 screen_uv = screenPos.xy / screenPos.w;
const float2 screen_px = screen_uv * _ScreenParams.xy;
const float fragment_depth = GetDepthOfWorldPos(i.worldPos, debug);
const float3 noise = _SSAO_Noise.SampleLevel(point_repeat_s, screen_px * _SSAO_Noise_TexelSize.xy, 0);
float ssao_theta = noise.x;
const float frame = ((float) AudioLinkData(ALPASS_GENERALVU + int2(1, 0)).x);
ssao_theta += frame * PHI;
ssao_theta *= TAU;
const float2x2 ssao_rot = float2x2(
cos(ssao_theta), -sin(ssao_theta),
sin(ssao_theta), cos(ssao_theta));
float ssao_occlusion = 0;
const float ssao_eps = 1E-5;
[loop]
for (uint ii = 0; ii < round(_SSAO_Samples); ii++) {
// Compute random vector in tangent space.
// Get the index of the current pixels, on the range [0, screen_width] x
// [0, screen_height].
// Map that onto the noise texture's pixels. Add an offset for each
// index.
float2 noise_uv = (float2(ii % _ScreenParams.x, ii * (_ScreenParams.z - 1.0f))) * _SSAO_Noise_TexelSize.xy;
#if 1
float3 sample_point = _SSAO_Noise.SampleLevel(point_repeat_s, noise_uv, 0).rgb;
#else
float3 sample_point = frac(noise + PHI * ii);
#endif
sample_point.xy = 2.0 * sample_point.xy - 1.0;
sample_point.xy = mul(ssao_rot, sample_point.xy);
// Remap to world space.
sample_point = mul(sample_point, tangentToWorld);
float scale = (ii * 1.0f) / _SSAO_Samples;
sample_point *= lerp(0.1f, 1.0f, scale * scale) * _SSAO_Radius;
sample_point += i.worldPos;
float sample_depth = GetDepthOfWorldPos(sample_point, debug);
// Depth values we're working with indicate how far you have to go along
// the view vector before you hit the object in question. Therefore, we
// care when the sample is *closer* to us than the object.
float occlusion_amount = saturate((fragment_depth - sample_depth) - _SSAO_Bias);
ssao_occlusion += occlusion_amount;
}
return saturate(1.0 - _SSAO_Strength * ssao_occlusion / _SSAO_Samples);
}
#endif
#endif // __SSAO_INC
|