Skip to content

Commit a8eed0e

Browse files
First stab at trying to fix fireflies with rough dielectric
1 parent 1120ba7 commit a8eed0e

File tree

1 file changed

+18
-18
lines changed

1 file changed

+18
-18
lines changed

src/shaders/common/disney.glsl

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ vec3 ToLocal(vec3 X, vec3 Y, vec3 Z, vec3 V)
4343
return vec3(dot(V, X), dot(V, Y), dot(V, Z));
4444
}
4545

46-
float FresnelMix(Material mat, float eta, vec3 V, vec3 L, vec3 H)
46+
float FresnelMix(Material mat, float eta, float VDotH)
4747
{
48-
float metallicFresnel = SchlickFresnel(abs(dot(L, H)));
49-
float dielectricFresnel = DielectricFresnel(abs(dot(V, H)), eta);
48+
float metallicFresnel = SchlickFresnel(VDotH);
49+
float dielectricFresnel = DielectricFresnel(VDotH, eta);
5050
return mix(dielectricFresnel, metallicFresnel, mat.metallic);
5151
}
5252

@@ -81,7 +81,7 @@ vec3 EvalSpecReflection(Material mat, float eta, vec3 specCol, vec3 V, vec3 L, v
8181
if (L.z <= 0.0)
8282
return vec3(0.0);
8383

84-
float FM = FresnelMix(mat, eta, V, L, H);
84+
float FM = FresnelMix(mat, eta, dot(L, H));
8585
vec3 F = mix(specCol, vec3(1.0), FM);
8686
float D = GTR2(H.z, mat.roughness);
8787
float G1 = SmithG(abs(V.z), mat.roughness);
@@ -104,7 +104,7 @@ vec3 EvalSpecRefraction(Material mat, float eta, vec3 V, vec3 L, vec3 H, inout f
104104
denom *= denom;
105105
float G1 = SmithG(abs(V.z), mat.roughness);
106106
float G2 = G1 * SmithG(abs(L.z), mat.roughness);
107-
float jacobian = abs(dot(L, H)) * eta * eta / denom;
107+
float jacobian = abs(dot(L, H)) / denom;
108108

109109
pdf = G1 * max(0.0, dot(V, H)) * D * jacobian / V.z;
110110

@@ -160,13 +160,19 @@ vec3 DisneySample(State state, vec3 V, vec3 N, inout vec3 L, inout float pdf)
160160
float r1 = rand();
161161
float r2 = rand();
162162

163+
vec3 T, B;
164+
Onb(N, T, B);
165+
V = ToLocal(T, B, N, V); // NDotL = L.z; NDotV = V.z; NDotH = H.z
166+
163167
// Specular and sheen color
164168
vec3 specCol, sheenCol;
165169
GetSpecColor(state.mat, state.eta, specCol, sheenCol);
166170

167171
// Lobe weights
168172
float diffuseWt, specReflectWt, specRefractWt, clearcoatWt;
169-
float approxFresnel = FresnelMix(state.mat, state.eta, V, reflect(V, N), N);
173+
// TODO: Recheck fresnel. Not sure if correct. VDotN produces fireflies with rough dielectric.
174+
// VDotH matches Mitsuba and gets rid of all fireflies but H isn't available at this stage
175+
float approxFresnel = FresnelMix(state.mat, state.eta, V.z);
170176
GetLobeProbabilities(state.mat, state.eta, specCol, approxFresnel, diffuseWt, specReflectWt, specRefractWt, clearcoatWt);
171177

172178
// CDF for picking a lobe
@@ -176,11 +182,6 @@ vec3 DisneySample(State state, vec3 V, vec3 N, inout vec3 L, inout float pdf)
176182
cdf[2] = cdf[1] + specRefractWt;
177183
cdf[3] = cdf[2] + clearcoatWt;
178184

179-
vec3 T, B;
180-
Onb(N, T, B);
181-
// NDotL = L.z; NDotV = V.z; NDotH = H.z
182-
V = ToLocal(T, B, N, V);
183-
184185
if(r1 < cdf[0]) // Diffuse Reflection Lobe
185186
{
186187
r1 /= cdf[0];
@@ -196,7 +197,7 @@ vec3 DisneySample(State state, vec3 V, vec3 N, inout vec3 L, inout float pdf)
196197
r1 = (r1 - cdf[0]) / (cdf[1] - cdf[0]);
197198
vec3 H = SampleGGXVNDF(V, state.mat.roughness, r1, r2);
198199

199-
if (dot(V, H) < 0.0)
200+
if (H.z < 0.0)
200201
H = -H;
201202

202203
L = normalize(reflect(-V, H));
@@ -209,7 +210,7 @@ vec3 DisneySample(State state, vec3 V, vec3 N, inout vec3 L, inout float pdf)
209210
r1 = (r1 - cdf[1]) / (cdf[2] - cdf[1]);
210211
vec3 H = SampleGGXVNDF(V, state.mat.roughness, r1, r2);
211212

212-
if (dot(V, H) < 0.0)
213+
if (H.z < 0.0)
213214
H = -H;
214215

215216
L = normalize(refract(-V, H, state.eta));
@@ -222,7 +223,7 @@ vec3 DisneySample(State state, vec3 V, vec3 N, inout vec3 L, inout float pdf)
222223
r1 = (r1 - cdf[2]) / (1.0 - cdf[2]);
223224
vec3 H = SampleGTR1(state.mat.clearcoatRoughness, r1, r2);
224225

225-
if (dot(V, H) < 0.0)
226+
if (H.z < 0.0)
226227
H = -H;
227228

228229
L = normalize(reflect(-V, H));
@@ -242,8 +243,7 @@ vec3 DisneyEval(State state, vec3 V, vec3 N, vec3 L, inout float bsdfPdf)
242243

243244
vec3 T, B;
244245
Onb(N, T, B);
245-
// NDotL = L.z; NDotV = V.z; NDotH = H.z
246-
V = ToLocal(T, B, N, V);
246+
V = ToLocal(T, B, N, V); // NDotL = L.z; NDotV = V.z; NDotH = H.z
247247
L = ToLocal(T, B, N, L);
248248

249249
vec3 H;
@@ -252,7 +252,7 @@ vec3 DisneyEval(State state, vec3 V, vec3 N, vec3 L, inout float bsdfPdf)
252252
else
253253
H = normalize(L + V * state.eta);
254254

255-
if (dot(V, H) < 0.0)
255+
if (H.z < 0.0)
256256
H = -H;
257257

258258
// Specular and sheen color
@@ -261,7 +261,7 @@ vec3 DisneyEval(State state, vec3 V, vec3 N, vec3 L, inout float bsdfPdf)
261261

262262
// Lobe weights
263263
float diffuseWt, specReflectWt, specRefractWt, clearcoatWt;
264-
float approxFresnel = FresnelMix(state.mat, state.eta, V, L, H);
264+
float approxFresnel = FresnelMix(state.mat, state.eta, dot(V, H));
265265
GetLobeProbabilities(state.mat, state.eta, specCol, approxFresnel, diffuseWt, specReflectWt, specRefractWt, clearcoatWt);
266266

267267
float pdf;

0 commit comments

Comments
 (0)