diff options
Diffstat (limited to 'filamented.cginc')
| -rwxr-xr-x | filamented.cginc | 35 |
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 |
