37
37
vec3 EvalDielectricReflection(State state, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
38
38
// -----------------------------------------------------------------------
39
39
{
40
- if (dot (N, L) < 0.0 ) return vec3 (0.0 );
40
+ if (! (dot (N, L) * dot (N, V) > 0.0 ))
41
+ {
42
+ pdf = 0 ;
43
+ return vec3 (0.0 );
44
+ }
41
45
42
46
float F = DielectricFresnel(dot (V, H), state.eta);
43
47
float D = GTR2(dot (N, H), state.mat.roughness);
@@ -52,6 +56,12 @@ vec3 EvalDielectricReflection(State state, vec3 V, vec3 N, vec3 L, vec3 H, inout
52
56
vec3 EvalDielectricRefraction(State state, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
53
57
// -----------------------------------------------------------------------
54
58
{
59
+ if (dot (N, L) > 0.0 )
60
+ {
61
+ pdf = 0 ;
62
+ return vec3 (0.0 );
63
+ }
64
+
55
65
float F = DielectricFresnel(abs (dot (V, H)), state.eta);
56
66
float D = GTR2(dot (N, H), state.mat.roughness);
57
67
@@ -66,23 +76,30 @@ vec3 EvalDielectricRefraction(State state, vec3 V, vec3 N, vec3 L, vec3 H, inout
66
76
vec3 EvalSpecular(State state, vec3 Cspec0, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
67
77
// -----------------------------------------------------------------------
68
78
{
69
- if (dot (N, L) < 0.0 ) return vec3 (0.0 );
79
+ if (! (dot (N, L) * dot (N, V) > 0.0 ))
80
+ {
81
+ pdf = 0 ;
82
+ return vec3 (0.0 );
83
+ }
70
84
71
- float D = GTR2_aniso (dot (N, H), dot (H, state.tangent), dot (H, state.bitangent), state. mat.ax, state.mat.ay );
85
+ float D = GTR2 (dot (N, H), state.mat.roughness );
72
86
pdf = D * dot (N, H) / (4.0 * dot (V, H));
73
87
74
88
float FH = SchlickFresnel(dot (L, H));
75
89
vec3 F = mix (Cspec0, vec3 (1.0 ), FH);
76
- float G = SmithG_GGX_aniso(dot (N, L), dot (L, state.tangent), dot (L, state.bitangent), state.mat.ax, state.mat.ay);
77
- G *= SmithG_GGX_aniso(dot (N, V), dot (V, state.tangent), dot (V, state.bitangent), state.mat.ax, state.mat.ay);
90
+ float G = SmithG_GGX(abs (dot (N, L)), state.mat.roughness) * SmithG_GGX(abs (dot (N, V)), state.mat.roughness);
78
91
return F * D * G;
79
92
}
80
93
81
94
// -----------------------------------------------------------------------
82
95
vec3 EvalClearcoat(State state, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
83
96
// -----------------------------------------------------------------------
84
97
{
85
- if (dot (N, L) < 0.0 ) return vec3 (0.0 );
98
+ if (! (dot (N, L) * dot (N, V) > 0.0 ))
99
+ {
100
+ pdf = 0 ;
101
+ return vec3 (0.0 );
102
+ }
86
103
87
104
float D = GTR1(dot (N, H), mix (0.1 , 0.001 , state.mat.clearcoatGloss));
88
105
pdf = D * dot (N, H) / (4.0 * dot (V, H));
@@ -97,7 +114,11 @@ vec3 EvalClearcoat(State state, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
97
114
vec3 EvalDiffuse(State state, vec3 Csheen, vec3 V, vec3 N, vec3 L, vec3 H, inout float pdf)
98
115
// -----------------------------------------------------------------------
99
116
{
100
- if (dot (N, L) < 0.0 ) return vec3 (0.0 );
117
+ if (! (dot (N, L) * dot (N, V) > 0.0 ))
118
+ {
119
+ pdf = 0 ;
120
+ return vec3 (0.0 );
121
+ }
101
122
102
123
pdf = dot (N, L) * (1.0 / PI);
103
124
@@ -108,8 +129,7 @@ vec3 EvalDiffuse(State state, vec3 Csheen, vec3 V, vec3 N, vec3 L, vec3 H, inout
108
129
float Fd90 = 0.5 + 2.0 * dot (L, H) * dot (L, H) * state.mat.roughness;
109
130
float Fd = mix (1.0 , Fd90, FL) * mix (1.0 , Fd90, FV);
110
131
111
- // TODO: Replace with volumetric scattering
112
- // SS
132
+ // Fake Subsurface TODO: Replace with volumetric scattering
113
133
float Fss90 = dot (L, H) * dot (L, H) * state.mat.roughness;
114
134
float Fss = mix (1.0 , Fss90, FL) * mix (1.0 , Fss90, FV);
115
135
float ss = 1.25 * (Fss * (1.0 / (dot (N, L) + dot (N, V)) - 0.5 ) + 0.5 );
@@ -122,7 +142,6 @@ vec3 EvalDiffuse(State state, vec3 Csheen, vec3 V, vec3 N, vec3 L, vec3 H, inout
122
142
vec3 DisneySample(inout State state, vec3 V, vec3 N, inout vec3 L, inout float pdf)
123
143
// -----------------------------------------------------------------------
124
144
{
125
- state.specularBounce = false;
126
145
pdf = 0.0 ;
127
146
vec3 f = vec3 (0.0 );
128
147
@@ -140,13 +159,12 @@ vec3 DisneySample(inout State state, vec3 V, vec3 N, inout vec3 L, inout float p
140
159
vec3 Csheen = mix (vec3 (1.0 ), Ctint, state.mat.sheenTint);
141
160
142
161
// TODO: Reuse random numbers and reduce so many calls to rand()
143
- // BSDF
144
162
if (rand() < transWeight)
145
163
{
146
164
vec3 H = ImportanceSampleGTR2(state.mat.roughness, r1, r2);
147
165
H = state.tangent * H.x + state.bitangent * H.y + N * H.z;
148
166
149
- if (dot (V , H) < 0.0 )
167
+ if (dot (N , H) < 0.0 )
150
168
H = - H;
151
169
152
170
vec3 R = reflect (- V, H);
@@ -160,16 +178,14 @@ vec3 DisneySample(inout State state, vec3 V, vec3 N, inout vec3 L, inout float p
160
178
}
161
179
else // Transmission
162
180
{
163
- // TODO: Check how other renderers handle dielectrics
164
- state.specularBounce = true;
165
181
L = normalize (refract (- V, H, state.eta));
166
182
f = EvalDielectricRefraction(state, V, N, L, H, pdf);
167
183
}
168
184
169
185
f *= transWeight;
170
186
pdf *= transWeight;
171
187
}
172
- else // BRDF
188
+ else
173
189
{
174
190
if (rand() < diffuseRatio)
175
191
{
@@ -189,10 +205,10 @@ vec3 DisneySample(inout State state, vec3 V, vec3 N, inout vec3 L, inout float p
189
205
if (rand() < primarySpecRatio)
190
206
{
191
207
// TODO: Implement http://jcgt.org/published/0007/04/01/
192
- vec3 H = ImportanceSampleGTR2_aniso (state.mat.ax, state.mat.ay , r1, r2);
208
+ vec3 H = ImportanceSampleGTR2 (state.mat.roughness , r1, r2);
193
209
H = state.tangent * H.x + state.bitangent * H.y + N * H.z;
194
210
195
- if (dot (V , H) < 0.0 )
211
+ if (dot (N , H) < 0.0 )
196
212
H = - H;
197
213
198
214
L = normalize (reflect (- V, H));
@@ -205,7 +221,7 @@ vec3 DisneySample(inout State state, vec3 V, vec3 N, inout vec3 L, inout float p
205
221
vec3 H = ImportanceSampleGTR1(mix (0.1 , 0.001 , state.mat.clearcoatGloss), r1, r2);
206
222
H = state.tangent * H.x + state.bitangent * H.y + N * H.z;
207
223
208
- if (dot (V , H) < 0.0 )
224
+ if (dot (N , H) < 0.0 )
209
225
H = - H;
210
226
211
227
L = normalize (reflect (- V, H));
@@ -226,11 +242,12 @@ vec3 DisneyEval(State state, vec3 V, vec3 N, vec3 L, inout float pdf)
226
242
// -----------------------------------------------------------------------
227
243
{
228
244
vec3 H;
245
+ bool refl = dot (N, L) * dot (N, V) > 0.0 ;
229
246
230
- if (dot (N, L) < 0.0 )
231
- H = normalize (L * (1.0 / state.eta) + V);
232
- else
247
+ if (refl)
233
248
H = normalize (L + V);
249
+ else
250
+ H = normalize (L * (1.0 / state.eta) + V);
234
251
235
252
if (dot (N, H) < 0.0 )
236
253
H = - H;
@@ -244,17 +261,16 @@ vec3 DisneyEval(State state, vec3 V, vec3 N, vec3 L, inout float pdf)
244
261
float brdfPdf = 0.0 ;
245
262
float bsdfPdf = 0.0 ;
246
263
247
- // BSDF
248
264
if (transWeight > 0.0 )
249
265
{
250
- // Transmission
251
- if (dot (N, L) < 0.0 )
266
+ // Reflection
267
+ if (refl )
252
268
{
253
- bsdf = EvalDielectricRefraction (state, V, N, L, H, bsdfPdf);
269
+ bsdf = EvalDielectricReflection (state, V, N, L, H, bsdfPdf);
254
270
}
255
- else // Reflection
271
+ else // Transmission
256
272
{
257
- bsdf = EvalDielectricReflection (state, V, N, L, H, bsdfPdf);
273
+ bsdf = EvalDielectricRefraction (state, V, N, L, H, bsdfPdf);
258
274
}
259
275
}
260
276
0 commit comments