@@ -43,7 +43,7 @@ void EvalDielectricReflection(State state, inout BsdfSampleRec bRec)
43
43
float F = DielectricFresnel(dot (bRec.V, bRec.H), state.eta);
44
44
float D = GTR2(dot (bRec.N, bRec.H), state.mat.roughness);
45
45
46
- bRec.pdf = D * dot (bRec.N, bRec.H) / (4.0 * dot (bRec.V, bRec.H));
46
+ bRec.pdf = D * dot (bRec.N, bRec.H) * F / (4.0 * dot (bRec.V, bRec.H));
47
47
48
48
float G = SmithG_GGX(abs (dot (bRec.N, bRec.L)), state.mat.roughness) * SmithG_GGX(dot (bRec.N, bRec.V), state.mat.roughness);
49
49
bRec.f = state.mat.albedo * F * D * G;
@@ -57,7 +57,7 @@ void EvalDielectricRefraction(State state, inout BsdfSampleRec bRec)
57
57
float D = GTR2(dot (bRec.N, bRec.H), state.mat.roughness);
58
58
59
59
float denomSqrt = dot (bRec.L, bRec.H) * state.eta + dot (bRec.V, bRec.H);
60
- bRec.pdf = D * abs (dot (bRec.L, bRec.H)) / (denomSqrt * denomSqrt);
60
+ bRec.pdf = D * dot (bRec.N, bRec.H) * ( 1.0 - F) * abs (dot (bRec.L, bRec.H)) / (denomSqrt * denomSqrt);
61
61
62
62
float G = SmithG_GGX(abs (dot (bRec.N, bRec.L)), state.mat.roughness) * SmithG_GGX(dot (bRec.N, bRec.V), state.mat.roughness);
63
63
bRec.f = state.mat.albedo * (1.0 - F) * D * G * abs (dot (bRec.V, bRec.H)) * abs (dot (bRec.L, bRec.H)) * 4.0 * state.eta * state.eta / (denomSqrt * denomSqrt);
@@ -136,6 +136,11 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
136
136
float r1 = rand();
137
137
float r2 = rand();
138
138
139
+ vec3 brdf = vec3 (0.0 );
140
+ vec3 bsdf = vec3 (0.0 );
141
+ float brdfPdf = 0.0 ;
142
+ float bsdfPdf = 0.0 ;
143
+
139
144
float diffuseRatio = 0.5 * (1.0 - state.mat.metallic);
140
145
float transWeight = (1.0 - state.mat.metallic) * state.mat.specTrans;
141
146
@@ -156,22 +161,19 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
156
161
float F = DielectricFresnel(abs (dot (R, bRec.H)), state.eta);
157
162
158
163
// Reflection/Total internal reflection
159
- if (rand() < F)
164
+ if (rand() < F)
160
165
{
161
- bRec.L = normalize (R);
162
-
166
+ bRec.L = normalize (R);
163
167
EvalDielectricReflection(state, bRec);
164
- bRec.pdf *= F * transWeight;
165
- bRec.f *= transWeight;
166
168
}
167
169
else // Transmission
168
170
{
169
171
bRec.L = normalize (refract (- bRec.V, bRec.H, state.eta));
170
-
171
172
EvalDielectricRefraction(state, bRec);
172
- bRec.pdf *= (1.0 - F) * transWeight;
173
- bRec.f *= transWeight;
174
173
}
174
+
175
+ bsdf = bRec.f;
176
+ bsdfPdf = bRec.pdf;
175
177
}
176
178
else // BRDF
177
179
{
@@ -185,10 +187,10 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
185
187
bRec.L = state.tangent * L.x + state.bitangent * L.y - bRec.N * L.z;
186
188
187
189
EvalSubsurface(state, bRec);
188
- bRec.pdf *= state.mat.subsurface * diffuseRatio * (1.0 - transWeight);
189
- bRec.f *= (1.0 - transWeight);
190
+ bRec.pdf *= state.mat.subsurface * diffuseRatio;
190
191
191
192
state.isSubsurface = true; // Required when sampling lights from inside surface
193
+ // state.specularBounce = true;
192
194
}
193
195
else // Diffuse
194
196
{
@@ -198,8 +200,7 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
198
200
bRec.H = normalize (bRec.L + bRec.V);
199
201
200
202
EvalDiffuse(state, bRec, Csheen);
201
- bRec.pdf *= (1.0 - state.mat.subsurface) * diffuseRatio * (1.0 - transWeight);
202
- bRec.f *= (1.0 - transWeight);
203
+ bRec.pdf *= (1.0 - state.mat.subsurface) * diffuseRatio;
203
204
}
204
205
}
205
206
else // Specular
@@ -215,8 +216,7 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
215
216
bRec.L = normalize (reflect (- bRec.V, bRec.H));
216
217
217
218
EvalSpecular(state, bRec, Cspec0);
218
- bRec.pdf *= primarySpecRatio * (1.0 - diffuseRatio) * (1.0 - transWeight);
219
- bRec.f *= (1.0 - transWeight);
219
+ bRec.pdf *= primarySpecRatio * (1.0 - diffuseRatio);
220
220
}
221
221
else // Sample clearcoat lobe
222
222
{
@@ -226,10 +226,14 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
226
226
227
227
EvalClearcoat(state, bRec);
228
228
bRec.pdf *= (1.0 - primarySpecRatio) * (1.0 - diffuseRatio);
229
- bRec.f *= (1.0 - transWeight);
230
229
}
231
230
}
231
+ brdf = bRec.f;
232
+ brdfPdf = bRec.pdf;
232
233
}
234
+
235
+ bRec.pdf = mix (brdfPdf, bsdfPdf, transWeight);
236
+ bRec.f = mix (brdf, bsdf, transWeight);
233
237
}
234
238
235
239
// -----------------------------------------------------------------------
@@ -256,29 +260,26 @@ void DisneyEval(State state, inout BsdfSampleRec bRec)
256
260
// BSDF
257
261
if (transWeight > 0.0 )
258
262
{
259
- float F = DielectricFresnel(abs (dot (bRec.V, bRec.H)), state.eta);
260
-
261
263
// Transmission
262
264
if (dot (bRec.N, bRec.L) < 0.0 )
263
265
{
264
266
EvalDielectricRefraction(state, bRec);
265
- bsdf += bRec.f;
266
- bsdfPdf += bRec.pdf * (1.0 - F);
267
267
}
268
268
else // Reflection
269
269
{
270
270
EvalDielectricReflection(state, bRec);
271
- bsdf += bRec.f;
272
- bsdfPdf += bRec.pdf * F;
273
271
}
272
+
273
+ bsdf += bRec.f;
274
+ bsdfPdf += bRec.pdf;
274
275
}
275
276
276
277
if (transWeight < 1.0 )
277
278
{
278
279
// Subsurface
279
280
if (dot (bRec.N, bRec.L) < 0.0 )
280
281
{
281
- // TODO: Double check this. Causing occassional NaNs
282
+ // TODO: Double check this. Causing occassional NaNs and fails furnace test when used with transmission
282
283
if (state.mat.subsurface > 0.0 )
283
284
{
284
285
EvalSubsurface(state, bRec);
0 commit comments