@@ -192,6 +192,31 @@ float mx_average_alpha(vec2 alpha)
192192 return sqrt (alpha.x * alpha.y);
193193}
194194
195+ // Approximate anisotropic IBL with a bent normal from alpha.x / alpha.y.
196+ // https://google.github.io/filament/Filament.md.html Section Anisotropy
197+ vec3 mx_bent_normal_anisotropy(vec3 N, vec3 V, vec3 X, vec3 Y, vec2 alpha)
198+ {
199+ float maxAlpha = max (max (alpha.x, alpha.y), M_FLOAT_EPS);
200+ float minOverMax = min (alpha.x, alpha.y) / maxAlpha;
201+ float anisotropy = 1.0 - clamp (minOverMax, 0.0 , 1.0 );
202+ float anisotropySign = (alpha.x >= alpha.y) ? 1.0 : - 1.0 ;
203+ float signedAnisotropy = anisotropy * anisotropySign;
204+
205+ vec3 anisotropicDirection = (signedAnisotropy >= 0.0 ) ? Y : X;
206+ vec3 anisotropicTangent = cross (anisotropicDirection, V);
207+ float tangentLenSq = dot (anisotropicTangent, anisotropicTangent);
208+ vec3 anisotropicNormal = (tangentLenSq > M_FLOAT_EPS) ?
209+ normalize (cross (anisotropicTangent, anisotropicDirection)) : N;
210+
211+ float roughness = clamp (sqrt (mx_average_alpha(alpha)), 0.0 , 1.0 );
212+ float bend = abs (signedAnisotropy) * (1.0 - roughness);
213+ float normalWeight = 1.0 - bend;
214+ normalWeight *= normalWeight;
215+ normalWeight *= normalWeight;
216+
217+ return normalize (mix (anisotropicNormal, N, normalWeight));
218+ }
219+
195220// Convert a real-valued index of refraction to normal-incidence reflectivity.
196221float mx_ior_to_f0(float ior)
197222{
0 commit comments