forked from autodesk-forks/MaterialX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mx_generalized_schlick_brdf.glsl
75 lines (60 loc) · 2.4 KB
/
mx_generalized_schlick_brdf.glsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "pbrlib/genglsl/lib/mx_bsdfs.glsl"
void mx_generalized_schlick_brdf_reflection(vec3 L, vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, BSDF base, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = base;
return;
}
float NdotL = dot(N,L);
float NdotV = dot(N,V);
if (NdotL <= 0.0 || NdotV <= 0.0)
{
result = base;
return;
}
vec3 Y = normalize(cross(N, X));
vec3 H = normalize(L + V);
float NdotH = dot(N, H);
float D = mx_microfacet_ggx_NDF(X, Y, H, NdotH, roughness.x, roughness.y);
float G = mx_microfacet_ggx_smith_G(NdotL, NdotV, max(roughness.x, roughness.y));
float VdotH = dot(V, H);
vec3 F = mx_fresnel_schlick(VdotH, color0, color90, exponent);
F *= weight;
float avgF = dot(F, vec3(1.0 / 3.0));
// Note: NdotL is cancelled out
result = D * G * F / (4 * NdotV) // Top layer reflection
+ base * (1.0 - avgF); // Base layer reflection attenuated by top fresnel
}
void mx_generalized_schlick_brdf_transmission(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, BSDF base, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = base;
return;
}
// Glossy BRDF has no transmission but we must
// attenuate the base layer transmission by the
// inverse of top layer reflectance.
// Abs here to allow transparency through backfaces
float NdotV = abs(dot(N,V));
vec3 F = mx_fresnel_schlick(NdotV, color0, color90, exponent);
F *= weight;
float avgF = dot(F, vec3(1.0 / 3.0));
result = base * (1.0 - avgF); // Base layer transmission attenuated by top fresnel
}
void mx_generalized_schlick_brdf_indirect(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, BSDF base, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = base;
return;
}
vec3 Li = mx_environment_radiance(N, V, X, roughness, distribution);
float NdotV = dot(N,V);
vec3 F = mx_fresnel_schlick(NdotV, color0, color90, exponent);
F *= weight;
float avgF = dot(F, vec3(1.0 / 3.0));
result = Li * F // Top layer reflection
+ base * (1.0 - avgF); // Base layer reflection attenuated by top fresnel
}