forked from AcademySoftwareFoundation/MaterialX
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmx_dielectric_bsdf.glsl
More file actions
112 lines (91 loc) · 3.42 KB
/
mx_dielectric_bsdf.glsl
File metadata and controls
112 lines (91 loc) · 3.42 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "lib/mx_microfacet_specular.glsl"
void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
return;
}
N = mx_forward_facing_normal(N, V);
vec3 Y = normalize(cross(N, X));
vec3 H = normalize(L + V);
float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(safeAlpha);
vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));
FresnelData fd;
if (bsdf.thickness > 0.0)
{
fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
}
else
{
fd = mx_init_fresnel_dielectric(ior);
}
vec3 F = mx_compute_fresnel(VdotH, fd);
float D = mx_ggx_NDF(Ht, safeAlpha);
float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);
float F0 = mx_ior_to_f0(ior);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
bsdf.throughput = 1.0 - dirAlbedo * weight;
// Note: NdotL is cancelled out
bsdf.response = D * F * G * comp * tint * occlusion * weight / (4.0 * NdotV);
}
void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
return;
}
N = mx_forward_facing_normal(N, V);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd;
if (bsdf.thickness > 0.0)
{
fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
}
else
{
fd = mx_init_fresnel_dielectric(ior);
}
vec3 F = mx_compute_fresnel(NdotV, fd);
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(safeAlpha);
float F0 = mx_ior_to_f0(ior);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
bsdf.throughput = 1.0 - dirAlbedo * weight;
if (scatter_mode != 0)
{
bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd) * tint * weight;
}
}
void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
return;
}
N = mx_forward_facing_normal(N, V);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd;
if (bsdf.thickness > 0.0)
{
fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
}
else
{
fd = mx_init_fresnel_dielectric(ior);
}
vec3 F = mx_compute_fresnel(NdotV, fd);
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(safeAlpha);
float F0 = mx_ior_to_f0(ior);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
bsdf.throughput = 1.0 - dirAlbedo * weight;
vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, distribution, fd);
bsdf.response = Li * tint * comp * weight;
}