Skip to content

Commit 069d1ac

Browse files
More code cleanup
1 parent 35f5ec6 commit 069d1ac

File tree

4 files changed

+111
-137
lines changed

4 files changed

+111
-137
lines changed

src/shaders/common/disney.glsl

Lines changed: 103 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -35,112 +35,105 @@
3535
*/
3636

3737
//-----------------------------------------------------------------------
38-
void EvalDielectricReflection(State state, inout BsdfSampleRec bRec)
38+
vec3 EvalDielectricReflection(State state, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
3939
//-----------------------------------------------------------------------
4040
{
41-
if (dot(bRec.N, bRec.L) < 0.0) return;
41+
if (dot(N, L) < 0.0) return vec3(0.0);
4242

43-
float F = DielectricFresnel(dot(bRec.V, bRec.H), state.eta);
44-
float D = GTR2(dot(bRec.N, bRec.H), state.mat.roughness);
43+
float F = DielectricFresnel(dot(V, H), state.eta);
44+
float D = GTR2(dot(N, H), state.mat.roughness);
4545

46-
bRec.pdf = D * dot(bRec.N, bRec.H) * F / (4.0 * dot(bRec.V, bRec.H));
46+
pdf = D * dot(N, H) * F / (4.0 * dot(V, H));
4747

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-
bRec.f = state.mat.albedo * F * D * G;
48+
float G = SmithG_GGX(abs(dot(N, L)), state.mat.roughness) * SmithG_GGX(dot(N, V), state.mat.roughness);
49+
return state.mat.albedo * F * D * G;
5050
}
5151

5252
//-----------------------------------------------------------------------
53-
void EvalDielectricRefraction(State state, inout BsdfSampleRec bRec)
53+
vec3 EvalDielectricRefraction(State state, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
5454
//-----------------------------------------------------------------------
5555
{
56-
float F = DielectricFresnel(abs(dot(bRec.V, bRec.H)), state.eta);
57-
float D = GTR2(dot(bRec.N, bRec.H), state.mat.roughness);
56+
float F = DielectricFresnel(abs(dot(V, H)), state.eta);
57+
float D = GTR2(dot(N, H), state.mat.roughness);
5858

59-
float denomSqrt = dot(bRec.L, bRec.H) * state.eta + dot(bRec.V, bRec.H);
60-
bRec.pdf = D * dot(bRec.N, bRec.H) * (1.0 - F) * abs(dot(bRec.L, bRec.H)) / (denomSqrt * denomSqrt);
59+
float denomSqrt = dot(L, H) * state.eta + dot(V, H);
60+
pdf = D * dot(N, H) * (1.0 - F) * abs(dot(L, H)) / (denomSqrt * denomSqrt);
6161

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-
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);
62+
float G = SmithG_GGX(abs(dot(N, L)), state.mat.roughness) * SmithG_GGX(dot(N, V), state.mat.roughness);
63+
return state.mat.albedo * (1.0 - F) * D * G * abs(dot(V, H)) * abs(dot(L, H)) * 4.0 * state.eta * state.eta / (denomSqrt * denomSqrt);
6464
}
6565

6666
//-----------------------------------------------------------------------
67-
void EvalSpecular(State state, inout BsdfSampleRec bRec, vec3 Cspec0)
67+
vec3 EvalSpecular(State state, vec3 Cspec0, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
6868
//-----------------------------------------------------------------------
6969
{
70-
if (dot(bRec.N, bRec.L) < 0.0) return;
70+
if (dot(N, L) < 0.0) return vec3(0.0);
7171

72-
float D = GTR2_aniso(dot(bRec.N, bRec.H), dot(bRec.H, state.tangent), dot(bRec.H, state.bitangent), state.mat.ax, state.mat.ay);
73-
bRec.pdf = D * dot(bRec.N, bRec.H) / (4.0 * dot(bRec.V, bRec.H));
72+
float D = GTR2_aniso(dot(N, H), dot(H, state.tangent), dot(H, state.bitangent), state.mat.ax, state.mat.ay);
73+
pdf = D * dot(N, H) / (4.0 * dot(V, H));
7474

75-
float FH = SchlickFresnel(dot(bRec.L, bRec.H));
75+
float FH = SchlickFresnel(dot(L, H));
7676
vec3 F = mix(Cspec0, vec3(1.0), FH);
77-
float G = SmithG_GGX_aniso(dot(bRec.N, bRec.L), dot(bRec.L, state.tangent), dot(bRec.L, state.bitangent), state.mat.ax, state.mat.ay);
78-
G *= SmithG_GGX_aniso(dot(bRec.N, bRec.V), dot(bRec.V, state.tangent), dot(bRec.V, state.bitangent), state.mat.ax, state.mat.ay);
79-
bRec.f = F * D * G;
77+
float G = SmithG_GGX_aniso(dot(N, L), dot(L, state.tangent), dot(L, state.bitangent), state.mat.ax, state.mat.ay);
78+
G *= SmithG_GGX_aniso(dot(N, V), dot(V, state.tangent), dot(V, state.bitangent), state.mat.ax, state.mat.ay);
79+
return F * D * G;
8080
}
8181

8282
//-----------------------------------------------------------------------
83-
void EvalClearcoat(State state, inout BsdfSampleRec bRec)
83+
vec3 EvalClearcoat(State state, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
8484
//-----------------------------------------------------------------------
8585
{
86-
if (dot(bRec.N, bRec.L) < 0.0) return;
86+
if (dot(N, L) < 0.0) return vec3(0.0);
8787

88-
float D = GTR1(dot(bRec.N, bRec.H), state.mat.clearcoatRoughness);
89-
bRec.pdf = D * dot(bRec.N, bRec.H) / (4.0 * dot(bRec.V, bRec.H));
88+
float D = GTR1(dot(N, H), state.mat.clearcoatRoughness);
89+
pdf = D * dot(N, H) / (4.0 * dot(V, H));
9090

91-
float FH = SchlickFresnel(dot(bRec.L, bRec.H));
91+
float FH = SchlickFresnel(dot(L, H));
9292
float F = mix(0.04, 1.0, FH);
93-
float G = SmithG_GGX(dot(bRec.N, bRec.L), 0.25) * SmithG_GGX(dot(bRec.N, bRec.V), 0.25);
94-
bRec.f = vec3(0.25 * state.mat.clearcoat * F * D * G);
93+
float G = SmithG_GGX(dot(N, L), 0.25) * SmithG_GGX(dot(N, V), 0.25);
94+
return vec3(0.25 * state.mat.clearcoat * F * D * G);
9595
}
9696

9797
//-----------------------------------------------------------------------
98-
void EvalDiffuse(State state, inout BsdfSampleRec bRec, vec3 Csheen)
98+
vec3 EvalDiffuse(State state, vec3 Csheen, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
9999
//-----------------------------------------------------------------------
100100
{
101-
if (dot(bRec.N, bRec.L) < 0.0) return;
101+
if (dot(N, L) < 0.0) return vec3(0.0);
102102

103-
bRec.pdf = dot(bRec.N, bRec.L) * (1.0 / PI);
103+
pdf = dot(N, L) * (1.0 / PI);
104104

105-
float FL = SchlickFresnel(dot(bRec.N, bRec.L));
106-
float FV = SchlickFresnel(dot(bRec.N, bRec.V));
107-
float FH = SchlickFresnel(dot(bRec.L, bRec.H));
108-
float Fd90 = 0.5 + 2.0 * dot(bRec.L, bRec.H) * dot(bRec.L, bRec.H) * state.mat.roughness;
105+
float FL = SchlickFresnel(dot(N, L));
106+
float FV = SchlickFresnel(dot(N, V));
107+
float FH = SchlickFresnel(dot(L, H));
108+
float Fd90 = 0.5 + 2.0 * dot(L, H) * dot(L, H) * state.mat.roughness;
109109
float Fd = mix(1.0, Fd90, FL) * mix(1.0, Fd90, FV);
110110
vec3 Fsheen = FH * state.mat.sheen * Csheen;
111-
bRec.f = ((1.0 / PI) * Fd * (1.0 - state.mat.subsurface) * state.mat.albedo + Fsheen) * (1.0 - state.mat.metallic);
111+
return ((1.0 / PI) * Fd * (1.0 - state.mat.subsurface) * state.mat.albedo + Fsheen) * (1.0 - state.mat.metallic);
112112
}
113113

114114
//-----------------------------------------------------------------------
115-
void EvalSubsurface(State state, inout BsdfSampleRec bRec)
115+
vec3 EvalSubsurface(State state, vec3 V, vec3 N, vec3 L, inout float pdf)
116116
//-----------------------------------------------------------------------
117117
{
118-
//if (dot(bRec.N, bRec.V) < 0.0) return;
118+
pdf = (1.0 / TWO_PI);
119119

120-
bRec.pdf = (1.0 / TWO_PI);
121-
122-
float FL = SchlickFresnel(abs(dot(bRec.N, bRec.L)));
123-
float FV = SchlickFresnel(dot(bRec.N, bRec.V));
120+
float FL = SchlickFresnel(abs(dot(N, L)));
121+
float FV = SchlickFresnel(dot(N, V));
124122
float Fd = (1.0f - 0.5f * FL) * (1.0f - 0.5f * FV);
125-
bRec.f = sqrt(state.mat.albedo) * state.mat.subsurface * (1.0 / PI) * Fd * (1.0 - state.mat.metallic);
123+
return sqrt(state.mat.albedo) * state.mat.subsurface * (1.0 / PI) * Fd * (1.0 - state.mat.metallic);
126124
}
127125

128126
//-----------------------------------------------------------------------
129-
void DisneySample(inout State state, inout BsdfSampleRec bRec)
127+
vec3 DisneySample(inout State state, vec3 V, vec3 N, inout vec3 L, inout float pdf)
130128
//-----------------------------------------------------------------------
131129
{
132130
state.isSubsurface = false;
133-
bRec.pdf = 0.0;
134-
bRec.L = vec3(0.0);
131+
pdf = 0.0;
132+
vec3 f = vec3(0.0);
135133

136134
float r1 = rand();
137135
float r2 = rand();
138136

139-
vec3 brdf = vec3(0.0);
140-
vec3 bsdf = vec3(0.0);
141-
float brdfPdf = 0.0;
142-
float bsdfPdf = 0.0;
143-
144137
float diffuseRatio = 0.5 * (1.0 - state.mat.metallic);
145138
float transWeight = (1.0 - state.mat.metallic) * state.mat.specTrans;
146139

@@ -155,25 +148,25 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
155148
if (rand() < transWeight)
156149
{
157150
vec3 H = ImportanceSampleGTR2(state.mat.roughness, r1, r2);
158-
bRec.H = state.tangent * H.x + state.bitangent * H.y + bRec.N * H.z;
151+
H = state.tangent * H.x + state.bitangent * H.y + N * H.z;
159152

160-
vec3 R = reflect(-bRec.V, bRec.H);
161-
float F = DielectricFresnel(abs(dot(R, bRec.H)), state.eta);
153+
vec3 R = reflect(-V, H);
154+
float F = DielectricFresnel(abs(dot(R, H)), state.eta);
162155

163156
// Reflection/Total internal reflection
164157
if (rand() < F)
165158
{
166-
bRec.L = normalize(R);
167-
EvalDielectricReflection(state, bRec);
159+
L = normalize(R);
160+
f = EvalDielectricReflection(state, V, N, L, H, pdf);
168161
}
169162
else // Transmission
170163
{
171-
bRec.L = normalize(refract(-bRec.V, bRec.H, state.eta));
172-
EvalDielectricRefraction(state, bRec);
164+
L = normalize(refract(-V, H, state.eta));
165+
f = EvalDielectricRefraction(state, V, N, L, H, pdf);
173166
}
174167

175-
bsdf = bRec.f;
176-
bsdfPdf = bRec.pdf;
168+
f *= transWeight;
169+
pdf *= transWeight;
177170
}
178171
else // BRDF
179172
{
@@ -183,24 +176,23 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
183176
// Simpler than random walk but not sure if accurate.
184177
if (rand() < state.mat.subsurface)
185178
{
186-
vec3 L = UniformSampleHemisphere(r1, r2);
187-
bRec.L = state.tangent * L.x + state.bitangent * L.y - bRec.N * L.z;
179+
L = UniformSampleHemisphere(r1, r2);
180+
L = state.tangent * L.x + state.bitangent * L.y - N * L.z;
188181

189-
EvalSubsurface(state, bRec);
190-
bRec.pdf *= state.mat.subsurface * diffuseRatio;
182+
f = EvalSubsurface(state, V, N, L, pdf);
183+
pdf *= state.mat.subsurface * diffuseRatio;
191184

192185
state.isSubsurface = true; // Required when sampling lights from inside surface
193-
//state.specularBounce = true;
194186
}
195187
else // Diffuse
196188
{
197-
vec3 L = CosineSampleHemisphere(r1, r2);
198-
bRec.L = state.tangent * L.x + state.bitangent * L.y + bRec.N * L.z;
189+
L = CosineSampleHemisphere(r1, r2);
190+
L = state.tangent * L.x + state.bitangent * L.y + N * L.z;
199191

200-
bRec.H = normalize(bRec.L + bRec.V);
192+
vec3 H = normalize(L + V);
201193

202-
EvalDiffuse(state, bRec, Csheen);
203-
bRec.pdf *= (1.0 - state.mat.subsurface) * diffuseRatio;
194+
f = EvalDiffuse(state, Csheen, V, N, L, H, pdf);
195+
pdf *= (1.0 - state.mat.subsurface) * diffuseRatio;
204196
}
205197
}
206198
else // Specular
@@ -212,79 +204,78 @@ void DisneySample(inout State state, inout BsdfSampleRec bRec)
212204
{
213205
// TODO: Implement http://jcgt.org/published/0007/04/01/
214206
vec3 H = ImportanceSampleGTR2_aniso(state.mat.ax, state.mat.ay, r1, r2);
215-
bRec.H = state.tangent * H.x + state.bitangent * H.y + bRec.N * H.z;
216-
bRec.L = normalize(reflect(-bRec.V, bRec.H));
207+
H = state.tangent * H.x + state.bitangent * H.y + N * H.z;
208+
L = normalize(reflect(-V, H));
217209

218-
EvalSpecular(state, bRec, Cspec0);
219-
bRec.pdf *= primarySpecRatio * (1.0 - diffuseRatio);
210+
f = EvalSpecular(state, Cspec0, V, N, L, H, pdf);
211+
pdf *= primarySpecRatio * (1.0 - diffuseRatio);
220212
}
221213
else // Sample clearcoat lobe
222214
{
223215
vec3 H = ImportanceSampleGTR1(state.mat.clearcoatRoughness, r1, r2);
224-
bRec.H = state.tangent * H.x + state.bitangent * H.y + bRec.N * H.z;
225-
bRec.L = normalize(reflect(-bRec.V, bRec.H));
216+
H = state.tangent * H.x + state.bitangent * H.y + N * H.z;
217+
L = normalize(reflect(-V, H));
226218

227-
EvalClearcoat(state, bRec);
228-
bRec.pdf *= (1.0 - primarySpecRatio) * (1.0 - diffuseRatio);
219+
f = EvalClearcoat(state, V, N, L, H, pdf);
220+
pdf *= (1.0 - primarySpecRatio) * (1.0 - diffuseRatio);
229221
}
230222
}
231-
brdf = bRec.f;
232-
brdfPdf = bRec.pdf;
233-
}
234223

235-
bRec.pdf = mix(brdfPdf, bsdfPdf, transWeight);
236-
bRec.f = mix(brdf, bsdf, transWeight);
224+
f *= (1.0 - transWeight);
225+
pdf *= (1.0 - transWeight);
226+
}
227+
return f;
237228
}
238229

239230
//-----------------------------------------------------------------------
240-
void DisneyEval(State state, inout BsdfSampleRec bRec)
231+
vec3 DisneyEval(State state, vec3 V, vec3 N, vec3 L, inout float pdf)
241232
//-----------------------------------------------------------------------
242233
{
243-
if (dot(bRec.N, bRec.L) < 0.0)
244-
bRec.H = normalize(bRec.L * (1.0 / state.eta) + bRec.V);
234+
vec3 H;
235+
236+
if (dot(N, L) < 0.0)
237+
H = normalize(L * (1.0 / state.eta) + V);
245238
else
246-
bRec.H = normalize(bRec.L + bRec.V);
239+
H = normalize(L + V);
247240

248-
if (dot(bRec.N, bRec.H) < 0.0)
249-
bRec.H = -bRec.H;
241+
if (dot(N, H) < 0.0)
242+
H = -H;
243+
244+
float diffuseRatio = 0.5 * (1.0 - state.mat.metallic);
245+
float primarySpecRatio = 1.0 / (1.0 + state.mat.clearcoat);
246+
float transWeight = (1.0 - state.mat.metallic) * state.mat.specTrans;
250247

251248
vec3 brdf = vec3(0.0);
252249
vec3 bsdf = vec3(0.0);
253250
float brdfPdf = 0.0;
254251
float bsdfPdf = 0.0;
255252

256-
float diffuseRatio = 0.5 * (1.0 - state.mat.metallic);
257-
float primarySpecRatio = 1.0 / (1.0 + state.mat.clearcoat);
258-
float transWeight = (1.0 - state.mat.metallic) * state.mat.specTrans;
259-
260253
// BSDF
261254
if (transWeight > 0.0)
262255
{
263256
// Transmission
264-
if (dot(bRec.N, bRec.L) < 0.0)
257+
if (dot(N, L) < 0.0)
265258
{
266-
EvalDielectricRefraction(state, bRec);
259+
bsdf = EvalDielectricRefraction(state, V, N, L, H, bsdfPdf);
267260
}
268261
else // Reflection
269262
{
270-
EvalDielectricReflection(state, bRec);
263+
bsdf = EvalDielectricReflection(state, V, N, L, H, bsdfPdf);
271264
}
272-
273-
bsdf += bRec.f;
274-
bsdfPdf += bRec.pdf;
275265
}
276266

267+
float m_pdf;
268+
277269
if (transWeight < 1.0)
278270
{
279271
// Subsurface
280-
if (dot(bRec.N, bRec.L) < 0.0)
272+
if (dot(N, L) < 0.0)
281273
{
282274
// TODO: Double check this. Causing occassional NaNs and fails furnace test when used with transmission
283275
if (state.mat.subsurface > 0.0)
284276
{
285-
EvalSubsurface(state, bRec);
286-
brdf += bRec.f;
287-
brdfPdf += bRec.pdf * state.mat.subsurface * diffuseRatio;
277+
brdf = EvalSubsurface(state, V, N, L, m_pdf);
278+
brdfPdf = m_pdf * state.mat.subsurface * diffuseRatio;
288279
}
289280
}
290281
// BRDF
@@ -298,22 +289,19 @@ void DisneyEval(State state, inout BsdfSampleRec bRec)
298289
vec3 Csheen = mix(vec3(1.0), Ctint, state.mat.sheenTint);
299290

300291
// Diffuse
301-
EvalDiffuse(state, bRec, Csheen);
302-
brdf += bRec.f;
303-
brdfPdf += bRec.pdf * (1.0 - state.mat.subsurface) * diffuseRatio;
292+
brdf += EvalDiffuse(state, Csheen, V, N, L, H, m_pdf);
293+
brdfPdf += m_pdf * (1.0 - state.mat.subsurface) * diffuseRatio;
304294

305295
// Specular
306-
EvalSpecular(state, bRec, Cspec0);
307-
brdf += bRec.f;
308-
brdfPdf += bRec.pdf * primarySpecRatio * (1.0 - diffuseRatio);
296+
brdf += EvalSpecular(state, Cspec0, V, N, L, H, m_pdf);
297+
brdfPdf += m_pdf * primarySpecRatio * (1.0 - diffuseRatio);
309298

310299
// Clearcoat
311-
EvalClearcoat(state, bRec);
312-
brdf += bRec.f;
313-
brdfPdf += bRec.pdf * (1.0 - primarySpecRatio) * (1.0 - diffuseRatio);
300+
brdf += EvalClearcoat(state, V, N, L, H, m_pdf);
301+
brdfPdf += m_pdf * (1.0 - primarySpecRatio) * (1.0 - diffuseRatio);
314302
}
315303
}
316304

317-
bRec.pdf = mix(brdfPdf, bsdfPdf, transWeight);
318-
bRec.f = mix(brdf, bsdf, transWeight);
305+
pdf = mix(brdfPdf, bsdfPdf, transWeight);
306+
return mix(brdf, bsdf, transWeight);
319307
}

src/shaders/common/globals.glsl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,7 @@ struct State
112112

113113
struct BsdfSampleRec
114114
{
115-
vec3 N;
116115
vec3 L;
117-
vec3 V;
118-
vec3 H;
119116
vec3 f;
120117
float pdf;
121118
};

0 commit comments

Comments
 (0)