summaryrefslogtreecommitdiffstats
path: root/filamented.cginc
diff options
context:
space:
mode:
Diffstat (limited to 'filamented.cginc')
-rwxr-xr-xfilamented.cginc35
1 files changed, 35 insertions, 0 deletions
diff --git a/filamented.cginc b/filamented.cginc
index 62ec4c3..6d34123 100755
--- a/filamented.cginc
+++ b/filamented.cginc
@@ -301,4 +301,39 @@ inline half3 UnityGI_prefilteredRadiance(const UnityGIInput data, const float pe
return specular;
}
+#if defined(_AMBIENT_OCCLUSION) || defined(_BENT_NORMALS)
+// Oat and Sander 2007, "Ambient Aperture Lighting"
+// Jimenez et al. 2016, "Practical Realtime Strategies for Accurate Indirect Occlusion"
+float sphericalCapsIntersection(float cosCap1, float cosCap2, float cosDistance) {
+ float r1 = acos(cosCap1);
+ float r2 = acos(cosCap2);
+ float d = acos(cosDistance);
+
+ if (min(r1, r2) <= max(r1, r2) - d) {
+ return 1.0 - max(cosCap1, cosCap2);
+ } else if (r1 + r2 <= d) {
+ return 0.0;
+ }
+
+ float delta = abs(r1 - r2);
+ float x = 1.0 - saturate((d - delta) / max(r1 + r2 - delta, 1e-4));
+ float x2 = x * x;
+ float area = -2.0 * x2 * x + 3.0 * x2;
+ return area * (1.0 - max(cosCap1, cosCap2));
+}
+
+float computeSpecularAO(float NoV, float visibility, float roughness, float3 bent_normal, float3 reflect_dir) {
+#if defined(_BENT_NORMALS)
+ // Jimenez et al. 2016, "Practical Realtime Strategies for Accurate Indirect Occlusion"
+ float cosAv = sqrt(1.0 - visibility); // aperture from AO
+ float cosAs = exp2(-3.321928 * roughness * roughness); // aperture from roughness; log(10)/log(2) = 3.321928
+ float cosB = dot(bent_normal, reflect_dir); // angle between bent normal and reflection
+ return sphericalCapsIntersection(cosAv, cosAs, saturate(0.5 * cosB + 0.5)) / (1.0 - cosAs);
+#else
+ // Lagarde and de Rousiers 2014, "Moving Frostbite to Physically Based Rendering"
+ return saturate(pow(NoV + visibility, exp2(-16.0 * roughness - 1.0)) - 1.0 + visibility);
+#endif
+}
+#endif // _AMBIENT_OCCLUSION || _BENT_NORMALS
+
#endif // __FILAMENTED_INC