55
66using namespace metal;
77
8- // Returns the determinant of a 2x2 matrix.
9- static inline __attribute__((always_inline))
10- float spvDet2x2(float a1, float a2, float b1, float b2)
11- {
12- return a1 * b2 - b1 * a2;
13- }
14-
15- // Returns the determinant of a 3x3 matrix.
16- static inline __attribute__((always_inline))
17- float spvDet3x3(float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3)
18- {
19- return a1 * spvDet2x2(b2, b3, c2, c3) - b1 * spvDet2x2(a2, a3, c2, c3) + c1 * spvDet2x2(a2, a3, b2, b3);
20- }
21-
22- // Returns the inverse of a matrix, by using the algorithm of calculating the classical
23- // adjoint and dividing by the determinant. The contents of the matrix are changed.
24- static inline __attribute__((always_inline))
25- float4x4 spvInverse4x4(float4x4 m)
26- {
27- float4x4 adj; // The adjoint matrix (inverse after dividing by determinant)
28-
29- // Create the transpose of the cofactors, as the classical adjoint of the matrix.
30- adj[0][0] = spvDet3x3(m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3]);
31- adj[0][1] = -spvDet3x3(m[0][1], m[0][2], m[0][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3]);
32- adj[0][2] = spvDet3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[3][1], m[3][2], m[3][3]);
33- adj[0][3] = -spvDet3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3]);
34-
35- adj[1][0] = -spvDet3x3(m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3]);
36- adj[1][1] = spvDet3x3(m[0][0], m[0][2], m[0][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3]);
37- adj[1][2] = -spvDet3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[3][0], m[3][2], m[3][3]);
38- adj[1][3] = spvDet3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3]);
39-
40- adj[2][0] = spvDet3x3(m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3]);
41- adj[2][1] = -spvDet3x3(m[0][0], m[0][1], m[0][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3]);
42- adj[2][2] = spvDet3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]);
43- adj[2][3] = -spvDet3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3]);
44-
45- adj[3][0] = -spvDet3x3(m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2]);
46- adj[3][1] = spvDet3x3(m[0][0], m[0][1], m[0][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2]);
47- adj[3][2] = -spvDet3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[3][0], m[3][1], m[3][2]);
48- adj[3][3] = spvDet3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2]);
49-
50- // Calculate the determinant as a combination of the cofactors of the first row.
51- float det = (adj[0][0] * m[0][0]) + (adj[0][1] * m[1][0]) + (adj[0][2] * m[2][0]) + (adj[0][3] * m[3][0]);
52-
53- // Divide the classical adjoint matrix by the determinant.
54- // If determinant is zero, matrix is not invertable, so leave it unchanged.
55- return (det != 0.0f) ? (adj * (1.0f / det)) : m;
56- }
57-
588struct Camera
599{
6010 float4x4 projection;
11+ float4x4 projectionInverse;
12+ uint kernelSize;
6113};
6214
6315struct SSAOParams
@@ -79,7 +31,7 @@ static inline __attribute__((always_inline))
7931float3 getViewPos(thread const float& depth, thread const float2& uv, constant Camera& camera)
8032{
8133 float4 clipPos = float4((uv * 2.0) - float2(1.0), depth, 1.0);
82- float4 viewPos = spvInverse4x4( camera.projection) * clipPos;
34+ float4 viewPos = camera.projectionInverse * clipPos;
8335 return viewPos.xyz / float3(viewPos.w);
8436}
8537
@@ -111,28 +63,28 @@ float calculatePixelAO(thread const float2& uv, constant Camera& camera, texture
11163 float3 bitangent = cross(tangent, viewNormal);
11264 float3x3 TBN = float3x3(float3(tangent), float3(bitangent), float3(viewNormal));
11365 float occlusion = 0.0;
114- for (int i = 0; i < 64 ; i++)
66+ for (int i = 0; i < int(camera.kernelSize) ; i++)
11567 {
11668 float3 samplePos = TBN * kernel0.samples[i].xyz;
11769 samplePos = viewPos + (samplePos * 1.0);
11870 float4 offset = camera.projection * float4(samplePos, 1.0);
119- float _197 = offset.w;
120- float4 _198 = offset;
121- float2 _201 = _198 .xy / float2(_197 );
122- offset.x = _201 .x;
123- offset.y = _201 .y;
124- float4 _206 = offset;
125- float2 _211 = (_206 .xy * 0.5) + float2(0.5);
126- offset.x = _211 .x;
127- offset.y = _211 .y;
71+ float _201 = offset.w;
72+ float4 _202 = offset;
73+ float2 _205 = _202 .xy / float2(_201 );
74+ offset.x = _205 .x;
75+ offset.y = _205 .y;
76+ float4 _210 = offset;
77+ float2 _215 = (_210 .xy * 0.5) + float2(0.5);
78+ offset.x = _215 .x;
79+ offset.y = _215 .y;
12880 float sampleDepth = depthTex.sample(depthTexSmplr, offset.xy).x;
12981 float param_3 = sampleDepth;
13082 float2 param_4 = offset.xy;
13183 float3 sampleViewPos = getViewPos(param_3, param_4, camera);
13284 float rangeCheck = smoothstep(0.0, 1.0, 1.0 / abs((viewPos.z - sampleViewPos.z) - 0.00999999977648258209228515625));
13385 occlusion += (float(sampleViewPos.z >= (samplePos.z + 0.00999999977648258209228515625)) * rangeCheck);
13486 }
135- occlusion = 1.0 - ((occlusion / 64.0 ) * 1.5);
87+ occlusion = 1.0 - ((occlusion / float(camera.kernelSize) ) * 1.5);
13688 return occlusion;
13789}
13890
0 commit comments