Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio
// Generate tangent frame.
X = normalize(X - dot(X, N) * N);
vec3 Y = cross(N, X);
mat3 tangentToWorld = mat3(X, Y, N);
vec3 bentNormal = mx_bent_normal_anisotropy(N, V, X, Y, alpha);
X = normalize(X - dot(X, bentNormal) * bentNormal);
Y = cross(bentNormal, X);
mat3 tangentToWorld = mat3(X, Y, bentNormal);

// Transform the view vector to tangent space.
V = vec3(dot(V, X), dot(V, Y), dot(V, N));
V = vec3(dot(V, X), dot(V, Y), dot(V, bentNormal));

// Compute derived properties.
float NdotV = clamp(V.z, M_FLOAT_EPS, 1.0);
Expand Down
5 changes: 4 additions & 1 deletion libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ float mx_latlong_alpha_to_lod(float alpha)
vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
{
N = mx_forward_facing_normal(N, V);
vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, N, fd.ior.x) : -reflect(V, N);
X = normalize(X - dot(X, N) * N);
vec3 Y = cross(N, X);
vec3 bentNormal = mx_bent_normal_anisotropy(N, V, X, Y, alpha);
vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, N, fd.ior.x) : -reflect(V, bentNormal);

float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);

Expand Down
25 changes: 25 additions & 0 deletions libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,31 @@ float mx_average_alpha(vec2 alpha)
return sqrt(alpha.x * alpha.y);
}

// Approximate anisotropic IBL with a bent normal from alpha.x / alpha.y.
// https://google.github.io/filament/Filament.md.html Section Anisotropy
vec3 mx_bent_normal_anisotropy(vec3 N, vec3 V, vec3 X, vec3 Y, vec2 alpha)
{
float maxAlpha = max(max(alpha.x, alpha.y), M_FLOAT_EPS);
float minOverMax = min(alpha.x, alpha.y) / maxAlpha;
float anisotropy = 1.0 - clamp(minOverMax, 0.0, 1.0);
float anisotropySign = (alpha.x >= alpha.y) ? 1.0 : -1.0;
float signedAnisotropy = anisotropy * anisotropySign;

vec3 anisotropicDirection = (signedAnisotropy >= 0.0) ? Y : X;
vec3 anisotropicTangent = cross(anisotropicDirection, V);
float tangentLenSq = dot(anisotropicTangent, anisotropicTangent);
vec3 anisotropicNormal = (tangentLenSq > M_FLOAT_EPS) ?
normalize(cross(anisotropicTangent, anisotropicDirection)) : N;

float roughness = clamp(sqrt(mx_average_alpha(alpha)), 0.0, 1.0);
float bend = abs(signedAnisotropy) * (1.0 - roughness);
float normalWeight = 1.0 - bend;
normalWeight *= normalWeight;
normalWeight *= normalWeight;

return normalize(mix(anisotropicNormal, N, normalWeight));
}

// Convert a real-valued index of refraction to normal-incidence reflectivity.
float mx_ior_to_f0(float ior)
{
Expand Down