28
28
* [3] https://github.com/wdas/brdf/blob/main/src/brdfs/disney.brdf
29
29
* [4] https://github.com/mmacklin/tinsel/blob/master/src/disney.h
30
30
* [5] http://simon-kallweit.me/rendercompo2015/report/
31
- * [6] http ://shihchinw. github.io/2015/07/implementing-disney-principled-brdf-in-arnold.html
32
- * [7] https://github.com/mmp/pbrt-v4/blob/0ec29d1ec8754bddd9d667f0e80c4ff025c900ce/src/pbrt/bxdfs.cpp#L76-L286
33
- * [8] https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf .pdf
31
+ * [6] https ://github.com/mmp/pbrt-v4/blob/0ec29d1ec8754bddd9d667f0e80c4ff025c900ce/src/pbrt/bxdfs.cpp#L76-L286
32
+ * [7] https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf
33
+ * [8] https://jcgt.org/published/0007/04/01/paper .pdf
34
34
*/
35
35
36
36
vec3 ToWorld(vec3 X, vec3 Y, vec3 Z, vec3 V)
@@ -84,11 +84,12 @@ vec3 EvalSpecReflection(Material mat, float eta, vec3 specCol, vec3 V, vec3 L, v
84
84
float FM = FresnelMix(mat, eta, V, L, H);
85
85
vec3 F = mix (specCol, vec3 (1.0 ), FM);
86
86
float D = GTR2(H.z, mat.roughness);
87
- float G = SmithG(abs (L.z), mat.roughness)
88
- * SmithG(abs (V.z), mat.roughness);
87
+ float G1 = SmithG(abs (V.z), mat.roughness);
88
+ float G2 = G1 * SmithG(abs (L.z), mat.roughness);
89
+ float jacobian = 1.0 / (4.0 * dot (V, H));
89
90
90
- pdf = D * H.z / ( 4.0 * abs ( dot (V, H))) ;
91
- return F * D * G ;
91
+ pdf = G1 * max ( 0.0 , dot (V, H)) * D * jacobian / V.z ;
92
+ return F * D * G2 / ( 4.0 * L.z * V.z) ;
92
93
}
93
94
94
95
vec3 EvalSpecRefraction(Material mat, float eta, vec3 V, vec3 L, vec3 H, inout float pdf)
@@ -99,13 +100,16 @@ vec3 EvalSpecRefraction(Material mat, float eta, vec3 V, vec3 L, vec3 H, inout f
99
100
100
101
float F = DielectricFresnel(abs (dot (V, H)), eta);
101
102
float D = GTR2(H.z, mat.roughness);
102
- float denomSqrt = dot (L, H) + dot (V, H) * eta;
103
- float G = SmithG(abs (L.z), mat.roughness)
104
- * SmithG(abs (V.z), mat.roughness);
105
-
106
- pdf = D * H.z * abs (dot (L, H)) / (denomSqrt * denomSqrt);
103
+ float denom = dot (L, H) + dot (V, H) * eta;
104
+ denom *= denom;
105
+ float G1 = SmithG(abs (V.z), mat.roughness);
106
+ float G2 = G1 * SmithG(abs (L.z), mat.roughness);
107
+ float jacobian = abs (dot (L, H)) * eta * eta / denom;
108
+
109
+ pdf = G1 * max (0.0 , dot (V, H)) * D * jacobian / V.z;
110
+
107
111
vec3 specColor = pow (mat.baseColor, vec3 (0.5 ));
108
- return specColor * (1.0 - mat.metallic) * mat.specTrans * (1.0 - F) * D * G * abs (dot (V, H)) * abs (dot (L, H)) * eta * eta * 4.0 / (denomSqrt * denomSqrt );
112
+ return specColor * (1.0 - mat.metallic) * mat.specTrans * (1.0 - F) * D * G2 * abs (dot (V, H)) * abs (dot (L, H)) * eta * eta / (denom * abs (L.z) * abs (V.z) );
109
113
}
110
114
111
115
vec3 EvalClearcoat(Material mat, vec3 V, vec3 L, vec3 H, inout float pdf)
@@ -119,8 +123,10 @@ vec3 EvalClearcoat(Material mat, vec3 V, vec3 L, vec3 H, inout float pdf)
119
123
float D = GTR1(H.z, mat.clearcoatRoughness);
120
124
float G = SmithG(L.z, 0.25 )
121
125
* SmithG(V.z, 0.25 );
122
- pdf = D * H.z / (4.0 * dot (V, H));
123
- return vec3 (0.25 * mat.clearcoat * F * D * G);
126
+ float jacobian = 1.0 / (4.0 * dot (V, H));
127
+
128
+ pdf = D * H.z * jacobian;
129
+ return vec3 (0.25 ) * mat.clearcoat * F * D * G / (4.0 * L.z * V.z);
124
130
}
125
131
126
132
void GetSpecColor(Material mat, float eta, inout vec3 specCol, inout vec3 sheenCol)
@@ -188,7 +194,7 @@ vec3 DisneySample(State state, vec3 V, vec3 N, inout vec3 L, inout float pdf)
188
194
else if (r1 < cdf[1 ]) // Specular Reflection Lobe
189
195
{
190
196
r1 = (r1 - cdf[0 ]) / (cdf[1 ] - cdf[0 ]);
191
- vec3 H = SampleGTR2( state.mat.roughness, r1, r2);
197
+ vec3 H = SampleGGXVNDF(V, state.mat.roughness, r1, r2);
192
198
193
199
if (dot (V, H) < 0.0 )
194
200
H = - H;
@@ -201,7 +207,7 @@ vec3 DisneySample(State state, vec3 V, vec3 N, inout vec3 L, inout float pdf)
201
207
else if (r1 < cdf[2 ]) // Specular Refraction Lobe
202
208
{
203
209
r1 = (r1 - cdf[1 ]) / (cdf[2 ] - cdf[1 ]);
204
- vec3 H = SampleGTR2( state.mat.roughness, r1, r2);
210
+ vec3 H = SampleGGXVNDF(V, state.mat.roughness, r1, r2);
205
211
206
212
if (dot (V, H) < 0.0 )
207
213
H = - H;
0 commit comments