Skip to content

Commit cf29907

Browse files
Merge pull request #29 from knightcrawler25/dev
Fix fresnel and some further simplification
2 parents 09f10b8 + 35f5ec6 commit cf29907

File tree

1 file changed

+25
-24
lines changed

1 file changed

+25
-24
lines changed

src/shaders/common/disney.glsl

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void EvalDielectricReflection(State state, inout BsdfSampleRec bRec)
4343
float F = DielectricFresnel(dot(bRec.V, bRec.H), state.eta);
4444
float D = GTR2(dot(bRec.N, bRec.H), state.mat.roughness);
4545

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));
4747

4848
float G = SmithG_GGX(abs(dot(bRec.N, bRec.L)), state.mat.roughness) * SmithG_GGX(dot(bRec.N, bRec.V), state.mat.roughness);
4949
bRec.f = state.mat.albedo * F * D * G;
@@ -57,7 +57,7 @@ void EvalDielectricRefraction(State state, inout BsdfSampleRec bRec)
5757
float D = GTR2(dot(bRec.N, bRec.H), state.mat.roughness);
5858

5959
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);
6161

6262
float G = SmithG_GGX(abs(dot(bRec.N, bRec.L)), state.mat.roughness) * SmithG_GGX(dot(bRec.N, bRec.V), state.mat.roughness);
6363
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)
136136
float r1 = rand();
137137
float r2 = rand();
138138

139+
vec3 brdf = vec3(0.0);
140+
vec3 bsdf = vec3(0.0);
141+
float brdfPdf = 0.0;
142+
float bsdfPdf = 0.0;
143+
139144
float diffuseRatio = 0.5 * (1.0 - state.mat.metallic);
140145
float transWeight = (1.0 - state.mat.metallic) * state.mat.specTrans;
141146

@@ -156,22 +161,19 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
156161
float F = DielectricFresnel(abs(dot(R, bRec.H)), state.eta);
157162

158163
// Reflection/Total internal reflection
159-
if (rand() < F)
164+
if (rand() < F)
160165
{
161-
bRec.L = normalize(R);
162-
166+
bRec.L = normalize(R);
163167
EvalDielectricReflection(state, bRec);
164-
bRec.pdf *= F * transWeight;
165-
bRec.f *= transWeight;
166168
}
167169
else // Transmission
168170
{
169171
bRec.L = normalize(refract(-bRec.V, bRec.H, state.eta));
170-
171172
EvalDielectricRefraction(state, bRec);
172-
bRec.pdf *= (1.0 - F) * transWeight;
173-
bRec.f *= transWeight;
174173
}
174+
175+
bsdf = bRec.f;
176+
bsdfPdf = bRec.pdf;
175177
}
176178
else // BRDF
177179
{
@@ -185,10 +187,10 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
185187
bRec.L = state.tangent * L.x + state.bitangent * L.y - bRec.N * L.z;
186188

187189
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;
190191

191192
state.isSubsurface = true; // Required when sampling lights from inside surface
193+
//state.specularBounce = true;
192194
}
193195
else // Diffuse
194196
{
@@ -198,8 +200,7 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
198200
bRec.H = normalize(bRec.L + bRec.V);
199201

200202
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;
203204
}
204205
}
205206
else // Specular
@@ -215,8 +216,7 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
215216
bRec.L = normalize(reflect(-bRec.V, bRec.H));
216217

217218
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);
220220
}
221221
else // Sample clearcoat lobe
222222
{
@@ -226,10 +226,14 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
226226

227227
EvalClearcoat(state, bRec);
228228
bRec.pdf *= (1.0 - primarySpecRatio) * (1.0 - diffuseRatio);
229-
bRec.f *= (1.0 - transWeight);
230229
}
231230
}
231+
brdf = bRec.f;
232+
brdfPdf = bRec.pdf;
232233
}
234+
235+
bRec.pdf = mix(brdfPdf, bsdfPdf, transWeight);
236+
bRec.f = mix(brdf, bsdf, transWeight);
233237
}
234238

235239
//-----------------------------------------------------------------------
@@ -256,29 +260,26 @@ void DisneyEval(State state, inout BsdfSampleRec bRec)
256260
// BSDF
257261
if (transWeight > 0.0)
258262
{
259-
float F = DielectricFresnel(abs(dot(bRec.V, bRec.H)), state.eta);
260-
261263
// Transmission
262264
if (dot(bRec.N, bRec.L) < 0.0)
263265
{
264266
EvalDielectricRefraction(state, bRec);
265-
bsdf += bRec.f;
266-
bsdfPdf += bRec.pdf * (1.0 - F);
267267
}
268268
else // Reflection
269269
{
270270
EvalDielectricReflection(state, bRec);
271-
bsdf += bRec.f;
272-
bsdfPdf += bRec.pdf * F;
273271
}
272+
273+
bsdf += bRec.f;
274+
bsdfPdf += bRec.pdf;
274275
}
275276

276277
if (transWeight < 1.0)
277278
{
278279
// Subsurface
279280
if (dot(bRec.N, bRec.L) < 0.0)
280281
{
281-
// TODO: Double check this. Causing occassional NaNs
282+
// TODO: Double check this. Causing occassional NaNs and fails furnace test when used with transmission
282283
if (state.mat.subsurface > 0.0)
283284
{
284285
EvalSubsurface(state, bRec);

0 commit comments

Comments
 (0)