three-gpu-pathtracer 0.0.1 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +678 -386
- package/build/index.module.js +3166 -1690
- package/build/index.module.js.map +1 -1
- package/build/index.umd.cjs +3176 -1692
- package/build/index.umd.cjs.map +1 -1
- package/package.json +60 -57
- package/src/core/DynamicPathTracingSceneGenerator.js +106 -0
- package/src/core/MaterialReducer.js +256 -256
- package/src/core/PathTracingRenderer.js +125 -28
- package/src/core/PathTracingSceneGenerator.js +52 -46
- package/src/core/PhysicalCamera.js +28 -0
- package/src/index.js +25 -21
- package/src/materials/AlphaDisplayMaterial.js +48 -0
- package/src/materials/AmbientOcclusionMaterial.js +197 -197
- package/src/materials/BlendMaterial.js +67 -0
- package/src/materials/LambertPathTracingMaterial.js +285 -285
- package/src/materials/MaterialBase.js +56 -56
- package/src/materials/PhysicalPathTracingMaterial.js +684 -370
- package/src/shader/shaderEnvMapSampling.js +67 -0
- package/src/shader/shaderGGXFunctions.js +108 -107
- package/src/shader/shaderMaterialSampling.js +345 -333
- package/src/shader/shaderStructs.js +131 -30
- package/src/shader/shaderUtils.js +246 -140
- package/src/uniforms/EquirectHdrInfoUniform.js +263 -0
- package/src/uniforms/MaterialsTexture.js +251 -0
- package/src/uniforms/PhysicalCameraUniform.js +36 -0
- package/src/uniforms/RenderTarget2DArray.js +93 -80
- package/src/utils/BlurredEnvMapGenerator.js +113 -0
- package/src/utils/GeometryPreparationUtils.js +194 -172
- package/src/utils/UVUnwrapper.js +101 -101
- package/src/workers/PathTracingSceneWorker.js +40 -0
- package/src/uniforms/EquirectPdfUniform.js +0 -132
- package/src/uniforms/MaterialStructArrayUniform.js +0 -18
- package/src/uniforms/MaterialStructUniform.js +0 -94
- package/src/viewers/PathTracingViewer.js +0 -259
|
@@ -1,333 +1,345 @@
|
|
|
1
|
-
import { shaderGGXFunctions } from './shaderGGXFunctions.js';
|
|
2
|
-
|
|
3
|
-
export const shaderMaterialSampling = /* glsl */`
|
|
4
|
-
|
|
5
|
-
struct SurfaceRec {
|
|
6
|
-
vec3 normal;
|
|
7
|
-
vec3 faceNormal;
|
|
8
|
-
bool frontFace;
|
|
9
|
-
float roughness;
|
|
10
|
-
float filteredRoughness;
|
|
11
|
-
float metalness;
|
|
12
|
-
vec3 color;
|
|
13
|
-
vec3 emission;
|
|
14
|
-
float transmission;
|
|
15
|
-
float ior;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
struct SampleRec {
|
|
19
|
-
float
|
|
20
|
-
|
|
21
|
-
vec3
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
lightDirection
|
|
39
|
-
lightDirection
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
float
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
filteredRoughness,
|
|
74
|
-
|
|
75
|
-
rand()
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
float
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
float
|
|
94
|
-
float
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
float
|
|
98
|
-
float
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
color = mix(
|
|
108
|
-
color
|
|
109
|
-
color *=
|
|
110
|
-
color *=
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const {
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const {
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
minRoughness,
|
|
146
|
-
|
|
147
|
-
Math.random(),
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
.
|
|
163
|
-
.multiplyScalar(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
//
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
float
|
|
177
|
-
float
|
|
178
|
-
float
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
float
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
lightDirection
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
float
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
color
|
|
210
|
-
color *=
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
float
|
|
220
|
-
float
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
float
|
|
225
|
-
float
|
|
226
|
-
float
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
float
|
|
236
|
-
float
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
float
|
|
251
|
-
float
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
+
|
|
255
|
-
+
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
color =
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
}
|
|
333
|
-
|
|
1
|
+
import { shaderGGXFunctions } from './shaderGGXFunctions.js';
|
|
2
|
+
|
|
3
|
+
export const shaderMaterialSampling = /* glsl */`
|
|
4
|
+
|
|
5
|
+
struct SurfaceRec {
|
|
6
|
+
vec3 normal;
|
|
7
|
+
vec3 faceNormal;
|
|
8
|
+
bool frontFace;
|
|
9
|
+
float roughness;
|
|
10
|
+
float filteredRoughness;
|
|
11
|
+
float metalness;
|
|
12
|
+
vec3 color;
|
|
13
|
+
vec3 emission;
|
|
14
|
+
float transmission;
|
|
15
|
+
float ior;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
struct SampleRec {
|
|
19
|
+
float specularPdf;
|
|
20
|
+
float pdf;
|
|
21
|
+
vec3 direction;
|
|
22
|
+
vec3 color;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
${ shaderGGXFunctions }
|
|
26
|
+
|
|
27
|
+
// diffuse
|
|
28
|
+
float diffusePDF( vec3 wo, vec3 wi, SurfaceRec surf ) {
|
|
29
|
+
|
|
30
|
+
// https://raytracing.github.io/books/RayTracingTheRestOfYourLife.html#lightscattering/thescatteringpdf
|
|
31
|
+
float cosValue = wi.z;
|
|
32
|
+
return cosValue / PI;
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
vec3 diffuseDirection( vec3 wo, SurfaceRec surf ) {
|
|
37
|
+
|
|
38
|
+
vec3 lightDirection = randDirection();
|
|
39
|
+
lightDirection.z += 1.0;
|
|
40
|
+
lightDirection = normalize( lightDirection );
|
|
41
|
+
|
|
42
|
+
return lightDirection;
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
vec3 diffuseColor( vec3 wo, vec3 wi, SurfaceRec surf ) {
|
|
47
|
+
|
|
48
|
+
// TODO: scale by 1 - F here
|
|
49
|
+
// note on division by PI
|
|
50
|
+
// https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
|
|
51
|
+
float metalFactor = ( 1.0 - surf.metalness ) * wi.z / ( PI * PI );
|
|
52
|
+
float transmissionFactor = 1.0 - surf.transmission;
|
|
53
|
+
return surf.color * metalFactor * transmissionFactor;
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// specular
|
|
58
|
+
float specularPDF( vec3 wo, vec3 wi, SurfaceRec surf ) {
|
|
59
|
+
|
|
60
|
+
// See equation (17) in http://jcgt.org/published/0003/02/03/
|
|
61
|
+
float filteredRoughness = surf.filteredRoughness;
|
|
62
|
+
vec3 halfVector = getHalfVector( wi, wo );
|
|
63
|
+
return ggxPDF( wi, halfVector, filteredRoughness ) / ( 4.0 * dot( wi, halfVector ) );
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
vec3 specularDirection( vec3 wo, SurfaceRec surf ) {
|
|
68
|
+
|
|
69
|
+
// sample ggx vndf distribution which gives a new normal
|
|
70
|
+
float filteredRoughness = surf.filteredRoughness;
|
|
71
|
+
vec3 halfVector = ggxDirection(
|
|
72
|
+
wo,
|
|
73
|
+
filteredRoughness,
|
|
74
|
+
filteredRoughness,
|
|
75
|
+
rand(),
|
|
76
|
+
rand()
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// apply to new ray by reflecting off the new normal
|
|
80
|
+
return - reflect( wo, halfVector );
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
vec3 specularColor( vec3 wo, vec3 wi, SurfaceRec surf ) {
|
|
85
|
+
|
|
86
|
+
// if roughness is set to 0 then D === NaN which results in black pixels
|
|
87
|
+
float metalness = surf.metalness;
|
|
88
|
+
float ior = surf.ior;
|
|
89
|
+
bool frontFace = surf.frontFace;
|
|
90
|
+
float filteredRoughness = surf.filteredRoughness;
|
|
91
|
+
|
|
92
|
+
vec3 halfVector = getHalfVector( wo, wi );
|
|
93
|
+
float iorRatio = frontFace ? 1.0 / ior : ior;
|
|
94
|
+
float G = ggxShadowMaskG2( wi, wo, filteredRoughness );
|
|
95
|
+
float D = ggxDistribution( halfVector, filteredRoughness );
|
|
96
|
+
|
|
97
|
+
float F = schlickFresnelFromIor( dot( wi, halfVector ), iorRatio );
|
|
98
|
+
float cosTheta = min( wo.z, 1.0 );
|
|
99
|
+
float sinTheta = sqrt( 1.0 - cosTheta * cosTheta );
|
|
100
|
+
bool cannotRefract = iorRatio * sinTheta > 1.0;
|
|
101
|
+
if ( cannotRefract ) {
|
|
102
|
+
|
|
103
|
+
F = 1.0;
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
vec3 color = mix( vec3( 1.0 ), surf.color, metalness );
|
|
108
|
+
color = mix( color, vec3( 1.0 ), F );
|
|
109
|
+
color *= G * D / ( 4.0 * abs( wi.z * wo.z ) );
|
|
110
|
+
color *= mix( F, 1.0, metalness );
|
|
111
|
+
color *= wi.z; // scale the light by the direction the light is coming in from
|
|
112
|
+
|
|
113
|
+
return color;
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/*
|
|
118
|
+
// transmission
|
|
119
|
+
function transmissionPDF( wo, wi, material, surf ) {
|
|
120
|
+
|
|
121
|
+
// See section 4.2 in https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf
|
|
122
|
+
|
|
123
|
+
const { roughness, ior } = material;
|
|
124
|
+
const { frontFace } = hit;
|
|
125
|
+
const ratio = frontFace ? ior : 1 / ior;
|
|
126
|
+
const minRoughness = Math.max( roughness, MIN_ROUGHNESS );
|
|
127
|
+
|
|
128
|
+
halfVector.set( 0, 0, 0 ).addScaledVector( wi, ratio ).addScaledVector( wo, 1.0 ).normalize().multiplyScalar( - 1 );
|
|
129
|
+
|
|
130
|
+
const denom = Math.pow( ratio * halfVector.dot( wi ) + 1.0 * halfVector.dot( wo ), 2.0 );
|
|
131
|
+
return ggxPDF( wo, halfVector, minRoughness ) / denom;
|
|
132
|
+
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function transmissionDirection( wo, hit, material, lightDirection ) {
|
|
136
|
+
|
|
137
|
+
const { roughness, ior } = material;
|
|
138
|
+
const { frontFace } = hit;
|
|
139
|
+
const ratio = frontFace ? 1 / ior : ior;
|
|
140
|
+
const minRoughness = Math.max( roughness, MIN_ROUGHNESS );
|
|
141
|
+
|
|
142
|
+
// sample ggx vndf distribution which gives a new normal
|
|
143
|
+
ggxDirection(
|
|
144
|
+
wo,
|
|
145
|
+
minRoughness,
|
|
146
|
+
minRoughness,
|
|
147
|
+
Math.random(),
|
|
148
|
+
Math.random(),
|
|
149
|
+
halfVector,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
// apply to new ray by reflecting off the new normal
|
|
153
|
+
tempDir.copy( wo ).multiplyScalar( - 1 );
|
|
154
|
+
refract( tempDir, halfVector, ratio, lightDirection );
|
|
155
|
+
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function transmissionColor( wo, wi, material, hit, colorTarget ) {
|
|
159
|
+
|
|
160
|
+
const { metalness, transmission } = material;
|
|
161
|
+
colorTarget
|
|
162
|
+
.copy( material.color )
|
|
163
|
+
.multiplyScalar( ( 1.0 - metalness ) * wo.z )
|
|
164
|
+
.multiplyScalar( transmission );
|
|
165
|
+
|
|
166
|
+
}
|
|
167
|
+
*/
|
|
168
|
+
|
|
169
|
+
// TODO: This is just using a basic cosine-weighted specular distribution with an
|
|
170
|
+
// incorrect PDF value at the moment. Update it to correctly use a GGX distribution
|
|
171
|
+
float transmissionPDF( vec3 wo, vec3 wi, SurfaceRec surf ) {
|
|
172
|
+
|
|
173
|
+
float ior = surf.ior;
|
|
174
|
+
bool frontFace = surf.frontFace;
|
|
175
|
+
|
|
176
|
+
float ratio = frontFace ? 1.0 / ior : ior;
|
|
177
|
+
float cosTheta = min( wo.z, 1.0 );
|
|
178
|
+
float sinTheta = sqrt( 1.0 - cosTheta * cosTheta );
|
|
179
|
+
float reflectance = schlickFresnelFromIor( cosTheta, ratio );
|
|
180
|
+
bool cannotRefract = ratio * sinTheta > 1.0;
|
|
181
|
+
if ( cannotRefract ) {
|
|
182
|
+
|
|
183
|
+
return 0.0;
|
|
184
|
+
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return 1.0 / ( 1.0 - reflectance );
|
|
188
|
+
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
vec3 transmissionDirection( vec3 wo, SurfaceRec surf ) {
|
|
192
|
+
|
|
193
|
+
float roughness = surf.roughness;
|
|
194
|
+
float ior = surf.ior;
|
|
195
|
+
bool frontFace = surf.frontFace;
|
|
196
|
+
float ratio = frontFace ? 1.0 / ior : ior;
|
|
197
|
+
|
|
198
|
+
vec3 lightDirection = refract( - wo, vec3( 0.0, 0.0, 1.0 ), ratio );
|
|
199
|
+
lightDirection += randDirection() * roughness;
|
|
200
|
+
return normalize( lightDirection );
|
|
201
|
+
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
vec3 transmissionColor( vec3 wo, vec3 wi, SurfaceRec surf ) {
|
|
205
|
+
|
|
206
|
+
float metalness = surf.metalness;
|
|
207
|
+
float transmission = surf.transmission;
|
|
208
|
+
|
|
209
|
+
vec3 color = surf.color;
|
|
210
|
+
color *= ( 1.0 - metalness );
|
|
211
|
+
color *= transmission;
|
|
212
|
+
|
|
213
|
+
return color;
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
float bsdfPdf( vec3 wo, vec3 wi, SurfaceRec surf, out float specularPdf ) {
|
|
218
|
+
|
|
219
|
+
float ior = surf.ior;
|
|
220
|
+
float metalness = surf.metalness;
|
|
221
|
+
float transmission = surf.transmission;
|
|
222
|
+
bool frontFace = surf.frontFace;
|
|
223
|
+
|
|
224
|
+
float ratio = frontFace ? 1.0 / ior : ior;
|
|
225
|
+
float cosTheta = min( wo.z, 1.0 );
|
|
226
|
+
float sinTheta = sqrt( 1.0 - cosTheta * cosTheta );
|
|
227
|
+
float reflectance = schlickFresnelFromIor( cosTheta, ratio );
|
|
228
|
+
bool cannotRefract = ratio * sinTheta > 1.0;
|
|
229
|
+
if ( cannotRefract ) {
|
|
230
|
+
|
|
231
|
+
reflectance = 1.0;
|
|
232
|
+
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
float spdf = 0.0;
|
|
236
|
+
float dpdf = 0.0;
|
|
237
|
+
float tpdf = 0.0;
|
|
238
|
+
|
|
239
|
+
if ( wi.z < 0.0 ) {
|
|
240
|
+
|
|
241
|
+
tpdf = transmissionPDF( wo, wi, surf );
|
|
242
|
+
|
|
243
|
+
} else {
|
|
244
|
+
|
|
245
|
+
spdf = specularPDF( wo, wi, surf );
|
|
246
|
+
dpdf = diffusePDF( wo, wi, surf );
|
|
247
|
+
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
float transSpecularProb = mix( reflectance, 1.0, metalness );
|
|
251
|
+
float diffSpecularProb = 0.5 + 0.5 * metalness;
|
|
252
|
+
float pdf =
|
|
253
|
+
spdf * transmission * transSpecularProb
|
|
254
|
+
+ tpdf * transmission * ( 1.0 - transSpecularProb )
|
|
255
|
+
+ spdf * ( 1.0 - transmission ) * diffSpecularProb
|
|
256
|
+
+ dpdf * ( 1.0 - transmission ) * ( 1.0 - diffSpecularProb );
|
|
257
|
+
|
|
258
|
+
// retrieve specular rays for the shadows flag
|
|
259
|
+
specularPdf = spdf * transmission * transSpecularProb + spdf * ( 1.0 - transmission ) * diffSpecularProb;
|
|
260
|
+
|
|
261
|
+
return pdf;
|
|
262
|
+
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
vec3 bsdfColor( vec3 wo, vec3 wi, SurfaceRec surf ) {
|
|
266
|
+
|
|
267
|
+
vec3 color = vec3( 0.0 );
|
|
268
|
+
if ( wi.z < 0.0 ) {
|
|
269
|
+
|
|
270
|
+
color = transmissionColor( wo, wi, surf );
|
|
271
|
+
|
|
272
|
+
} else {
|
|
273
|
+
|
|
274
|
+
color = diffuseColor( wo, wi, surf );
|
|
275
|
+
color *= 1.0 - surf.transmission;
|
|
276
|
+
|
|
277
|
+
color += specularColor( wo, wi, surf );
|
|
278
|
+
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return color;
|
|
282
|
+
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
float bsdfResult( vec3 wo, vec3 wi, SurfaceRec surf, out vec3 color ) {
|
|
286
|
+
|
|
287
|
+
float specularPdf;
|
|
288
|
+
color = bsdfColor( wo, wi, surf );
|
|
289
|
+
return bsdfPdf( wo, wi, surf, specularPdf );
|
|
290
|
+
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
SampleRec bsdfSample( vec3 wo, SurfaceRec surf ) {
|
|
294
|
+
|
|
295
|
+
float ior = surf.ior;
|
|
296
|
+
float metalness = surf.metalness;
|
|
297
|
+
float transmission = surf.transmission;
|
|
298
|
+
bool frontFace = surf.frontFace;
|
|
299
|
+
|
|
300
|
+
float ratio = frontFace ? 1.0 / ior : ior;
|
|
301
|
+
float cosTheta = min( wo.z, 1.0 );
|
|
302
|
+
float sinTheta = sqrt( 1.0 - cosTheta * cosTheta );
|
|
303
|
+
float reflectance = schlickFresnelFromIor( cosTheta, ratio );
|
|
304
|
+
bool cannotRefract = ratio * sinTheta > 1.0;
|
|
305
|
+
if ( cannotRefract ) {
|
|
306
|
+
|
|
307
|
+
reflectance = 1.0;
|
|
308
|
+
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
SampleRec result;
|
|
312
|
+
if ( rand() < transmission ) {
|
|
313
|
+
|
|
314
|
+
float specularProb = mix( reflectance, 1.0, metalness );
|
|
315
|
+
if ( rand() < specularProb ) {
|
|
316
|
+
|
|
317
|
+
result.direction = specularDirection( wo, surf );
|
|
318
|
+
|
|
319
|
+
} else {
|
|
320
|
+
|
|
321
|
+
result.direction = transmissionDirection( wo, surf );
|
|
322
|
+
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
} else {
|
|
326
|
+
|
|
327
|
+
float specularProb = 0.5 + 0.5 * metalness;
|
|
328
|
+
if ( rand() < specularProb ) {
|
|
329
|
+
|
|
330
|
+
result.direction = specularDirection( wo, surf );
|
|
331
|
+
|
|
332
|
+
} else {
|
|
333
|
+
|
|
334
|
+
result.direction = diffuseDirection( wo, surf );
|
|
335
|
+
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
result.pdf = bsdfPdf( wo, result.direction, surf, result.specularPdf );
|
|
341
|
+
result.color = bsdfColor( wo, result.direction, surf );
|
|
342
|
+
return result;
|
|
343
|
+
|
|
344
|
+
}
|
|
345
|
+
`;
|