three-gpu-pathtracer 0.0.6 → 0.0.8

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.
Files changed (49) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +887 -781
  3. package/build/index.module.js +6070 -5224
  4. package/build/index.module.js.map +1 -1
  5. package/build/index.umd.cjs +6071 -5221
  6. package/build/index.umd.cjs.map +1 -1
  7. package/package.json +69 -68
  8. package/src/core/DynamicPathTracingSceneGenerator.js +119 -119
  9. package/src/core/MaterialReducer.js +256 -256
  10. package/src/core/PathTracingRenderer.js +270 -255
  11. package/src/core/PathTracingSceneGenerator.js +69 -68
  12. package/src/index.js +39 -33
  13. package/src/materials/AlphaDisplayMaterial.js +48 -48
  14. package/src/materials/AmbientOcclusionMaterial.js +197 -197
  15. package/src/materials/BlendMaterial.js +67 -67
  16. package/src/materials/DenoiseMaterial.js +142 -0
  17. package/src/materials/GraphMaterial.js +243 -0
  18. package/src/materials/LambertPathTracingMaterial.js +285 -285
  19. package/src/materials/MaterialBase.js +56 -56
  20. package/src/materials/PhysicalPathTracingMaterial.js +973 -922
  21. package/src/objects/EquirectCamera.js +13 -13
  22. package/src/objects/PhysicalCamera.js +28 -28
  23. package/src/objects/PhysicalSpotLight.js +14 -14
  24. package/src/objects/ShapedAreaLight.js +12 -12
  25. package/src/shader/shaderEnvMapSampling.js +59 -59
  26. package/src/shader/shaderGGXFunctions.js +100 -108
  27. package/src/shader/shaderIridescenceFunctions.js +130 -130
  28. package/src/shader/shaderLayerTexelFetchFunctions.js +25 -0
  29. package/src/shader/shaderLightSampling.js +231 -231
  30. package/src/shader/shaderMaterialSampling.js +504 -546
  31. package/src/shader/shaderSheenFunctions.js +98 -98
  32. package/src/shader/shaderStructs.js +321 -307
  33. package/src/shader/shaderUtils.js +403 -350
  34. package/src/textures/GradientEquirectTexture.js +35 -0
  35. package/src/textures/ProceduralEquirectTexture.js +75 -0
  36. package/src/uniforms/AttributesTextureArray.js +35 -0
  37. package/src/uniforms/EquirectHdrInfoUniform.js +259 -259
  38. package/src/uniforms/FloatAttributeTextureArray.js +169 -0
  39. package/src/uniforms/IESProfilesTexture.js +100 -100
  40. package/src/uniforms/LightsInfoUniformStruct.js +162 -162
  41. package/src/uniforms/MaterialsTexture.js +420 -406
  42. package/src/uniforms/PhysicalCameraUniform.js +36 -36
  43. package/src/uniforms/RenderTarget2DArray.js +97 -93
  44. package/src/uniforms/utils.js +21 -0
  45. package/src/utils/BlurredEnvMapGenerator.js +116 -113
  46. package/src/utils/GeometryPreparationUtils.js +214 -194
  47. package/src/utils/IESLoader.js +325 -325
  48. package/src/utils/UVUnwrapper.js +101 -101
  49. package/src/workers/PathTracingSceneWorker.js +42 -42
@@ -1,406 +1,420 @@
1
- import { DataTexture, RGBAFormat, ClampToEdgeWrapping, FloatType, FrontSide, BackSide, DoubleSide } from 'three';
2
-
3
- const MATERIAL_PIXELS = 44;
4
- const MATERIAL_STRIDE = MATERIAL_PIXELS * 4;
5
-
6
- const SIDE_OFFSET = 12 * 4 + 3; // s12.a
7
- const MATTE_OFFSET = 13 * 4 + 0; // s13.r
8
- const SHADOW_OFFSET = 13 * 4 + 1; // s13.g
9
-
10
- export class MaterialsTexture extends DataTexture {
11
-
12
- constructor() {
13
-
14
- super( new Float32Array( 4 ), 1, 1 );
15
-
16
- this.format = RGBAFormat;
17
- this.type = FloatType;
18
- this.wrapS = ClampToEdgeWrapping;
19
- this.wrapT = ClampToEdgeWrapping;
20
- this.generateMipmaps = false;
21
- this.threeCompatibilityTransforms = false;
22
-
23
- }
24
-
25
- setCastShadow( materialIndex, cast ) {
26
-
27
- // invert the shadow value so we default to "true" when initializing a material
28
- const array = this.image.data;
29
- const index = materialIndex * MATERIAL_STRIDE + SHADOW_OFFSET;
30
- array[ index ] = ! cast ? 1 : 0;
31
-
32
- }
33
-
34
- getCastShadow( materialIndex ) {
35
-
36
- const array = this.image.data;
37
- const index = materialIndex * MATERIAL_STRIDE + SHADOW_OFFSET;
38
- return ! Boolean( array[ index ] );
39
-
40
- }
41
-
42
- setSide( materialIndex, side ) {
43
-
44
- const array = this.image.data;
45
- const index = materialIndex * MATERIAL_STRIDE + SIDE_OFFSET;
46
- switch ( side ) {
47
-
48
- case FrontSide:
49
- array[ index ] = 1;
50
- break;
51
- case BackSide:
52
- array[ index ] = - 1;
53
- break;
54
- case DoubleSide:
55
- array[ index ] = 0;
56
- break;
57
-
58
- }
59
-
60
- }
61
-
62
- getSide( materialIndex ) {
63
-
64
- const array = this.image.data;
65
- const index = materialIndex * MATERIAL_STRIDE + SIDE_OFFSET;
66
- switch ( array[ index ] ) {
67
-
68
- case 0:
69
- return DoubleSide;
70
- case 1:
71
- return FrontSide;
72
- case - 1:
73
- return BackSide;
74
-
75
- }
76
-
77
- return 0;
78
-
79
- }
80
-
81
- setMatte( materialIndex, matte ) {
82
-
83
- const array = this.image.data;
84
- const index = materialIndex * MATERIAL_STRIDE + MATTE_OFFSET;
85
- array[ index ] = matte ? 1 : 0;
86
-
87
- }
88
-
89
- getMatte( materialIndex ) {
90
-
91
- const array = this.image.data;
92
- const index = materialIndex * MATERIAL_STRIDE + MATTE_OFFSET;
93
- return Boolean( array[ index ] );
94
-
95
- }
96
-
97
- updateFrom( materials, textures ) {
98
-
99
- function getTexture( material, key, def = - 1 ) {
100
-
101
- return key in material ? textures.indexOf( material[ key ] ) : def;
102
-
103
- }
104
-
105
- function getField( material, key, def ) {
106
-
107
- return key in material ? material[ key ] : def;
108
-
109
- }
110
-
111
- function getUVTransformTexture( material ) {
112
-
113
- // https://github.com/mrdoob/three.js/blob/f3a832e637c98a404c64dae8174625958455e038/src/renderers/webgl/WebGLMaterials.js#L204-L306
114
- // https://threejs.org/docs/#api/en/textures/Texture.offset
115
- // fallback order of textures to use as a common uv transform
116
- return material.map ||
117
- material.specularMap ||
118
- material.displacementMap ||
119
- material.normalMap ||
120
- material.bumpMap ||
121
- material.roughnessMap ||
122
- material.metalnessMap ||
123
- material.alphaMap ||
124
- material.emissiveMap ||
125
- material.clearcoatMap ||
126
- material.clearcoatNormalMap ||
127
- material.clearcoatRoughnessMap ||
128
- material.iridescenceMap ||
129
- material.iridescenceThicknessMap ||
130
- material.specularIntensityMap ||
131
- material.specularColorMap ||
132
- material.transmissionMap ||
133
- material.thicknessMap ||
134
- material.sheenColorMap ||
135
- material.sheenRoughnessMap ||
136
- null;
137
-
138
- }
139
-
140
- function writeTextureMatrixToArray( material, textureKey, array, offset ) {
141
-
142
- let texture;
143
- if ( threeCompatibilityTransforms ) {
144
-
145
- texture = getUVTransformTexture( material );
146
-
147
- } else {
148
-
149
- texture = material[ textureKey ] && material[ textureKey ].isTexture ? material[ textureKey ] : null;
150
-
151
- }
152
-
153
- // check if texture exists
154
- if ( texture ) {
155
-
156
- const elements = texture.matrix.elements;
157
-
158
- let i = 0;
159
-
160
- // first row
161
- array[ offset + i ++ ] = elements[ 0 ];
162
- array[ offset + i ++ ] = elements[ 3 ];
163
- array[ offset + i ++ ] = elements[ 6 ];
164
- i ++;
165
-
166
- // second row
167
- array[ offset + i ++ ] = elements[ 1 ];
168
- array[ offset + i ++ ] = elements[ 4 ];
169
- array[ offset + i ++ ] = elements[ 7 ];
170
- i ++;
171
-
172
- }
173
-
174
- return 8;
175
-
176
- }
177
-
178
- let index = 0;
179
- const pixelCount = materials.length * MATERIAL_PIXELS;
180
- const dimension = Math.ceil( Math.sqrt( pixelCount ) );
181
- const { threeCompatibilityTransforms, image } = this;
182
-
183
- if ( image.width !== dimension ) {
184
-
185
- this.dispose();
186
-
187
- image.data = new Float32Array( dimension * dimension * 4 );
188
- image.width = dimension;
189
- image.height = dimension;
190
-
191
- }
192
-
193
- const floatArray = image.data;
194
-
195
- // on some devices (Google Pixel 6) the "floatBitsToInt" function does not work correctly so we
196
- // can't encode texture ids that way.
197
- // const intArray = new Int32Array( floatArray.buffer );
198
-
199
- for ( let i = 0, l = materials.length; i < l; i ++ ) {
200
-
201
- const m = materials[ i ];
202
-
203
- // sample 0
204
- // color
205
- floatArray[ index ++ ] = m.color.r;
206
- floatArray[ index ++ ] = m.color.g;
207
- floatArray[ index ++ ] = m.color.b;
208
- floatArray[ index ++ ] = getTexture( m, 'map' );
209
-
210
- // sample 1
211
- // metalness & roughness
212
- floatArray[ index ++ ] = getField( m, 'metalness', 0.0 );
213
- floatArray[ index ++ ] = textures.indexOf( m.metalnessMap );
214
- floatArray[ index ++ ] = getField( m, 'roughness', 0.0 );
215
- floatArray[ index ++ ] = textures.indexOf( m.roughnessMap );
216
-
217
- // sample 2
218
- // transmission & emissiveIntensity
219
- floatArray[ index ++ ] = getField( m, 'ior', 1.0 );
220
- floatArray[ index ++ ] = getField( m, 'transmission', 0.0 );
221
- floatArray[ index ++ ] = getTexture( m, 'transmissionMap' );
222
- floatArray[ index ++ ] = getField( m, 'emissiveIntensity', 0.0 );
223
-
224
- // sample 3
225
- // emission
226
- if ( 'emissive' in m ) {
227
-
228
- floatArray[ index ++ ] = m.emissive.r;
229
- floatArray[ index ++ ] = m.emissive.g;
230
- floatArray[ index ++ ] = m.emissive.b;
231
-
232
- } else {
233
-
234
- floatArray[ index ++ ] = 0.0;
235
- floatArray[ index ++ ] = 0.0;
236
- floatArray[ index ++ ] = 0.0;
237
-
238
- }
239
-
240
- floatArray[ index ++ ] = getTexture( m, 'emissiveMap' );
241
-
242
- // sample 4
243
- // normals
244
- floatArray[ index ++ ] = getTexture( m, 'normalMap' );
245
- if ( 'normalScale' in m ) {
246
-
247
- floatArray[ index ++ ] = m.normalScale.x;
248
- floatArray[ index ++ ] = m.normalScale.y;
249
-
250
- } else {
251
-
252
- floatArray[ index ++ ] = 1;
253
- floatArray[ index ++ ] = 1;
254
-
255
- }
256
-
257
- // clearcoat
258
- floatArray[ index ++ ] = getField( m, 'clearcoat', 0.0 );
259
- floatArray[ index ++ ] = getTexture( m, 'clearcoatMap' ); // sample 5
260
-
261
- floatArray[ index ++ ] = getField( m, 'clearcoatRoughness', 0.0 );
262
- floatArray[ index ++ ] = getTexture( m, 'clearcoatRoughnessMap' );
263
-
264
- floatArray[ index ++ ] = getTexture( m, 'clearcoatNormalMap' );
265
-
266
- // sample 6
267
- if ( 'clearcoatNormalScale' in m ) {
268
-
269
- floatArray[ index ++ ] = m.clearcoatNormalScale.x;
270
- floatArray[ index ++ ] = m.clearcoatNormalScale.y;
271
-
272
- } else {
273
-
274
- floatArray[ index ++ ] = 1;
275
- floatArray[ index ++ ] = 1;
276
-
277
- }
278
-
279
- index ++;
280
- index ++;
281
-
282
- // sample 7
283
- // sheen
284
- if ( 'sheenColor' in m ) {
285
-
286
- floatArray[ index ++ ] = m.sheenColor.r;
287
- floatArray[ index ++ ] = m.sheenColor.g;
288
- floatArray[ index ++ ] = m.sheenColor.b;
289
-
290
- } else {
291
-
292
- floatArray[ index ++ ] = 0.0;
293
- floatArray[ index ++ ] = 0.0;
294
- floatArray[ index ++ ] = 0.0;
295
-
296
- }
297
-
298
- floatArray[ index ++ ] = getTexture( m, 'sheenColorMap' );
299
-
300
- // sample 8
301
- floatArray[ index ++ ] = getField( m, 'sheenRoughness', 0.0 );
302
- floatArray[ index ++ ] = getTexture( m, 'sheenRoughnessMap' );
303
-
304
- // iridescence
305
- floatArray[ index ++ ] = getTexture( m, 'iridescenceMap' );
306
- floatArray[ index ++ ] = getTexture( m, 'iridescenceThicknessMap' );
307
-
308
- floatArray[ index ++ ] = getField( m, 'iridescence', 0.0 ); // sample 9
309
- floatArray[ index ++ ] = getField( m, 'iridescenceIOR', 1.3 );
310
-
311
- const iridescenceThicknessRange = getField( m, 'iridescenceThicknessRange', [ 100, 400 ] );
312
- floatArray[ index ++ ] = iridescenceThicknessRange[ 0 ];
313
- floatArray[ index ++ ] = iridescenceThicknessRange[ 1 ];
314
-
315
- // sample 10
316
- // specular color
317
- if ( 'specularColor' in m ) {
318
-
319
- floatArray[ index ++ ] = m.specularColor.r;
320
- floatArray[ index ++ ] = m.specularColor.g;
321
- floatArray[ index ++ ] = m.specularColor.b;
322
-
323
- } else {
324
-
325
- floatArray[ index ++ ] = 0.0;
326
- floatArray[ index ++ ] = 0.0;
327
- floatArray[ index ++ ] = 0.0;
328
-
329
- }
330
-
331
- floatArray[ index ++ ] = getTexture( m, 'specularColorMap' );
332
-
333
- // sample 11
334
- // specular intensity
335
- floatArray[ index ++ ] = getField( m, 'specularIntensity', 1.0 );
336
- floatArray[ index ++ ] = getTexture( m, 'specularIntensityMap' );
337
- index ++;
338
- index ++;
339
-
340
- // sample 12
341
- // alphaMap
342
- floatArray[ index ++ ] = getTexture( m, 'alphaMap' );
343
-
344
- // side & matte
345
- floatArray[ index ++ ] = m.opacity;
346
- floatArray[ index ++ ] = m.alphaTest;
347
- index ++; // side
348
-
349
- // sample 13
350
- index ++; // matte
351
- index ++; // shadow
352
- index ++;
353
- index ++;
354
-
355
- // map transform 14
356
- index += writeTextureMatrixToArray( m, 'map', floatArray, index );
357
-
358
- // metalnessMap transform 16
359
- index += writeTextureMatrixToArray( m, 'metalnessMap', floatArray, index );
360
-
361
- // roughnessMap transform 18
362
- index += writeTextureMatrixToArray( m, 'roughnessMap', floatArray, index );
363
-
364
- // transmissionMap transform 20
365
- index += writeTextureMatrixToArray( m, 'transmissionMap', floatArray, index );
366
-
367
- // emissiveMap transform 22
368
- index += writeTextureMatrixToArray( m, 'emissiveMap', floatArray, index );
369
-
370
- // normalMap transform 24
371
- index += writeTextureMatrixToArray( m, 'normalMap', floatArray, index );
372
-
373
- // clearcoatMap transform 26
374
- index += writeTextureMatrixToArray( m, 'clearcoatMap', floatArray, index );
375
-
376
- // clearcoatNormalMap transform 28
377
- index += writeTextureMatrixToArray( m, 'clearcoatNormalMap', floatArray, index );
378
-
379
- // clearcoatRoughnessMap transform 30
380
- index += writeTextureMatrixToArray( m, 'clearcoatRoughnessMap', floatArray, index );
381
-
382
- // sheenColorMap transform 32
383
- index += writeTextureMatrixToArray( m, 'sheenColorMap', floatArray, index );
384
-
385
- // sheenRoughnessMap transform 34
386
- index += writeTextureMatrixToArray( m, 'sheenRoughnessMap', floatArray, index );
387
-
388
- // iridescenceMap transform 36
389
- index += writeTextureMatrixToArray( m, 'iridescenceMap', floatArray, index );
390
-
391
- // iridescenceThicknessMap transform 38
392
- index += writeTextureMatrixToArray( m, 'iridescenceThicknessMap', floatArray, index );
393
-
394
- // specularColorMap transform 40
395
- index += writeTextureMatrixToArray( m, 'specularColorMap', floatArray, index );
396
-
397
- // specularIntensityMap transform 42
398
- index += writeTextureMatrixToArray( m, 'specularIntensityMap', floatArray, index );
399
-
400
- }
401
-
402
- this.needsUpdate = true;
403
-
404
- }
405
-
406
- }
1
+ import { DataTexture, RGBAFormat, ClampToEdgeWrapping, FloatType, FrontSide, BackSide, DoubleSide } from 'three';
2
+ import { reduceTexturesToUniqueSources } from './utils.js';
3
+
4
+ const MATERIAL_PIXELS = 45;
5
+ const MATERIAL_STRIDE = MATERIAL_PIXELS * 4;
6
+
7
+ const MATTE_OFFSET = 14 * 4 + 0; // s14.r
8
+ const SHADOW_OFFSET = 14 * 4 + 1; // s14.g
9
+
10
+ export class MaterialsTexture extends DataTexture {
11
+
12
+ constructor() {
13
+
14
+ super( new Float32Array( 4 ), 1, 1 );
15
+
16
+ this.format = RGBAFormat;
17
+ this.type = FloatType;
18
+ this.wrapS = ClampToEdgeWrapping;
19
+ this.wrapT = ClampToEdgeWrapping;
20
+ this.generateMipmaps = false;
21
+ this.threeCompatibilityTransforms = false;
22
+
23
+ }
24
+
25
+ setCastShadow( materialIndex, cast ) {
26
+
27
+ // invert the shadow value so we default to "true" when initializing a material
28
+ const array = this.image.data;
29
+ const index = materialIndex * MATERIAL_STRIDE + SHADOW_OFFSET;
30
+ array[ index ] = ! cast ? 1 : 0;
31
+
32
+ }
33
+
34
+ getCastShadow( materialIndex ) {
35
+
36
+ const array = this.image.data;
37
+ const index = materialIndex * MATERIAL_STRIDE + SHADOW_OFFSET;
38
+ return ! Boolean( array[ index ] );
39
+
40
+ }
41
+
42
+ setMatte( materialIndex, matte ) {
43
+
44
+ const array = this.image.data;
45
+ const index = materialIndex * MATERIAL_STRIDE + MATTE_OFFSET;
46
+ array[ index ] = matte ? 1 : 0;
47
+
48
+ }
49
+
50
+ getMatte( materialIndex ) {
51
+
52
+ const array = this.image.data;
53
+ const index = materialIndex * MATERIAL_STRIDE + MATTE_OFFSET;
54
+ return Boolean( array[ index ] );
55
+
56
+ }
57
+
58
+ updateFrom( materials, textures ) {
59
+
60
+ function getTexture( material, key, def = - 1 ) {
61
+
62
+ if ( key in material && material[ key ] ) {
63
+
64
+ const source = material[ key ].source;
65
+ return uniqueTextures.findIndex( tex => tex.source === source );
66
+
67
+ } else {
68
+
69
+ return def;
70
+
71
+ }
72
+
73
+ }
74
+
75
+ function getField( material, key, def ) {
76
+
77
+ return key in material ? material[ key ] : def;
78
+
79
+ }
80
+
81
+ function getUVTransformTexture( material ) {
82
+
83
+ // https://github.com/mrdoob/three.js/blob/f3a832e637c98a404c64dae8174625958455e038/src/renderers/webgl/WebGLMaterials.js#L204-L306
84
+ // https://threejs.org/docs/#api/en/textures/Texture.offset
85
+ // fallback order of textures to use as a common uv transform
86
+ return material.map ||
87
+ material.specularMap ||
88
+ material.displacementMap ||
89
+ material.normalMap ||
90
+ material.bumpMap ||
91
+ material.roughnessMap ||
92
+ material.metalnessMap ||
93
+ material.alphaMap ||
94
+ material.emissiveMap ||
95
+ material.clearcoatMap ||
96
+ material.clearcoatNormalMap ||
97
+ material.clearcoatRoughnessMap ||
98
+ material.iridescenceMap ||
99
+ material.iridescenceThicknessMap ||
100
+ material.specularIntensityMap ||
101
+ material.specularColorMap ||
102
+ material.transmissionMap ||
103
+ material.thicknessMap ||
104
+ material.sheenColorMap ||
105
+ material.sheenRoughnessMap ||
106
+ null;
107
+
108
+ }
109
+
110
+ function writeTextureMatrixToArray( material, textureKey, array, offset ) {
111
+
112
+ let texture;
113
+ if ( threeCompatibilityTransforms ) {
114
+
115
+ texture = getUVTransformTexture( material );
116
+
117
+ } else {
118
+
119
+ texture = material[ textureKey ] && material[ textureKey ].isTexture ? material[ textureKey ] : null;
120
+
121
+ }
122
+
123
+ // check if texture exists
124
+ if ( texture ) {
125
+
126
+ const elements = texture.matrix.elements;
127
+
128
+ let i = 0;
129
+
130
+ // first row
131
+ array[ offset + i ++ ] = elements[ 0 ];
132
+ array[ offset + i ++ ] = elements[ 3 ];
133
+ array[ offset + i ++ ] = elements[ 6 ];
134
+ i ++;
135
+
136
+ // second row
137
+ array[ offset + i ++ ] = elements[ 1 ];
138
+ array[ offset + i ++ ] = elements[ 4 ];
139
+ array[ offset + i ++ ] = elements[ 7 ];
140
+ i ++;
141
+
142
+ }
143
+
144
+ return 8;
145
+
146
+ }
147
+
148
+ let index = 0;
149
+ const pixelCount = materials.length * MATERIAL_PIXELS;
150
+ const dimension = Math.ceil( Math.sqrt( pixelCount ) );
151
+ const { threeCompatibilityTransforms, image } = this;
152
+
153
+ // get the list of textures with unique sources
154
+ const uniqueTextures = reduceTexturesToUniqueSources( textures );
155
+
156
+ if ( image.width !== dimension ) {
157
+
158
+ this.dispose();
159
+
160
+ image.data = new Float32Array( dimension * dimension * 4 );
161
+ image.width = dimension;
162
+ image.height = dimension;
163
+
164
+ }
165
+
166
+ const floatArray = image.data;
167
+
168
+ // on some devices (Google Pixel 6) the "floatBitsToInt" function does not work correctly so we
169
+ // can't encode texture ids that way.
170
+ // const intArray = new Int32Array( floatArray.buffer );
171
+
172
+ for ( let i = 0, l = materials.length; i < l; i ++ ) {
173
+
174
+ const m = materials[ i ];
175
+
176
+ // sample 0
177
+ // color
178
+ floatArray[ index ++ ] = m.color.r;
179
+ floatArray[ index ++ ] = m.color.g;
180
+ floatArray[ index ++ ] = m.color.b;
181
+ floatArray[ index ++ ] = getTexture( m, 'map' );
182
+
183
+ // sample 1
184
+ // metalness & roughness
185
+ floatArray[ index ++ ] = getField( m, 'metalness', 0.0 );
186
+ floatArray[ index ++ ] = uniqueTextures.indexOf( m.metalnessMap );
187
+ floatArray[ index ++ ] = getField( m, 'roughness', 0.0 );
188
+ floatArray[ index ++ ] = uniqueTextures.indexOf( m.roughnessMap );
189
+
190
+ // sample 2
191
+ // transmission & emissiveIntensity
192
+ // three.js assumes a default f0 of 0.04 if no ior is provided which equates to an ior of 1.5
193
+ floatArray[ index ++ ] = getField( m, 'ior', 1.5 );
194
+ floatArray[ index ++ ] = getField( m, 'transmission', 0.0 );
195
+ floatArray[ index ++ ] = getTexture( m, 'transmissionMap' );
196
+ floatArray[ index ++ ] = getField( m, 'emissiveIntensity', 0.0 );
197
+
198
+ // sample 3
199
+ // emission
200
+ if ( 'emissive' in m ) {
201
+
202
+ floatArray[ index ++ ] = m.emissive.r;
203
+ floatArray[ index ++ ] = m.emissive.g;
204
+ floatArray[ index ++ ] = m.emissive.b;
205
+
206
+ } else {
207
+
208
+ floatArray[ index ++ ] = 0.0;
209
+ floatArray[ index ++ ] = 0.0;
210
+ floatArray[ index ++ ] = 0.0;
211
+
212
+ }
213
+
214
+ floatArray[ index ++ ] = getTexture( m, 'emissiveMap' );
215
+
216
+ // sample 4
217
+ // normals
218
+ floatArray[ index ++ ] = getTexture( m, 'normalMap' );
219
+ if ( 'normalScale' in m ) {
220
+
221
+ floatArray[ index ++ ] = m.normalScale.x;
222
+ floatArray[ index ++ ] = m.normalScale.y;
223
+
224
+ } else {
225
+
226
+ floatArray[ index ++ ] = 1;
227
+ floatArray[ index ++ ] = 1;
228
+
229
+ }
230
+
231
+ // clearcoat
232
+ floatArray[ index ++ ] = getField( m, 'clearcoat', 0.0 );
233
+ floatArray[ index ++ ] = getTexture( m, 'clearcoatMap' ); // sample 5
234
+
235
+ floatArray[ index ++ ] = getField( m, 'clearcoatRoughness', 0.0 );
236
+ floatArray[ index ++ ] = getTexture( m, 'clearcoatRoughnessMap' );
237
+
238
+ floatArray[ index ++ ] = getTexture( m, 'clearcoatNormalMap' );
239
+
240
+ // sample 6
241
+ if ( 'clearcoatNormalScale' in m ) {
242
+
243
+ floatArray[ index ++ ] = m.clearcoatNormalScale.x;
244
+ floatArray[ index ++ ] = m.clearcoatNormalScale.y;
245
+
246
+ } else {
247
+
248
+ floatArray[ index ++ ] = 1;
249
+ floatArray[ index ++ ] = 1;
250
+
251
+ }
252
+
253
+ index ++;
254
+ index ++;
255
+
256
+ // sample 7
257
+ // sheen
258
+ if ( 'sheenColor' in m ) {
259
+
260
+ floatArray[ index ++ ] = m.sheenColor.r;
261
+ floatArray[ index ++ ] = m.sheenColor.g;
262
+ floatArray[ index ++ ] = m.sheenColor.b;
263
+
264
+ } else {
265
+
266
+ floatArray[ index ++ ] = 0.0;
267
+ floatArray[ index ++ ] = 0.0;
268
+ floatArray[ index ++ ] = 0.0;
269
+
270
+ }
271
+
272
+ floatArray[ index ++ ] = getTexture( m, 'sheenColorMap' );
273
+
274
+ // sample 8
275
+ floatArray[ index ++ ] = getField( m, 'sheenRoughness', 0.0 );
276
+ floatArray[ index ++ ] = getTexture( m, 'sheenRoughnessMap' );
277
+
278
+ // iridescence
279
+ floatArray[ index ++ ] = getTexture( m, 'iridescenceMap' );
280
+ floatArray[ index ++ ] = getTexture( m, 'iridescenceThicknessMap' );
281
+
282
+ floatArray[ index ++ ] = getField( m, 'iridescence', 0.0 ); // sample 9
283
+ floatArray[ index ++ ] = getField( m, 'iridescenceIOR', 1.3 );
284
+
285
+ const iridescenceThicknessRange = getField( m, 'iridescenceThicknessRange', [ 100, 400 ] );
286
+ floatArray[ index ++ ] = iridescenceThicknessRange[ 0 ];
287
+ floatArray[ index ++ ] = iridescenceThicknessRange[ 1 ];
288
+
289
+ // sample 10
290
+ // specular color
291
+ if ( 'specularColor' in m ) {
292
+
293
+ floatArray[ index ++ ] = m.specularColor.r;
294
+ floatArray[ index ++ ] = m.specularColor.g;
295
+ floatArray[ index ++ ] = m.specularColor.b;
296
+
297
+ } else {
298
+
299
+ floatArray[ index ++ ] = 1.0;
300
+ floatArray[ index ++ ] = 1.0;
301
+ floatArray[ index ++ ] = 1.0;
302
+
303
+ }
304
+
305
+ floatArray[ index ++ ] = getTexture( m, 'specularColorMap' );
306
+
307
+ // sample 11
308
+ // specular intensity
309
+ floatArray[ index ++ ] = getField( m, 'specularIntensity', 1.0 );
310
+ floatArray[ index ++ ] = getTexture( m, 'specularIntensityMap' );
311
+
312
+ // isThinFilm
313
+ const isThinFilm = getField( m, 'thickness', 0.0 ) === 0.0 && getField( m, 'attenuationDistance', Infinity ) === Infinity;
314
+ floatArray[ index ++ ] = Number( isThinFilm );
315
+ index ++;
316
+
317
+ // sample 12
318
+ if ( 'attenuationColor' in m ) {
319
+
320
+ floatArray[ index ++ ] = m.attenuationColor.r;
321
+ floatArray[ index ++ ] = m.attenuationColor.g;
322
+ floatArray[ index ++ ] = m.attenuationColor.b;
323
+
324
+ } else {
325
+
326
+ floatArray[ index ++ ] = 1.0;
327
+ floatArray[ index ++ ] = 1.0;
328
+ floatArray[ index ++ ] = 1.0;
329
+
330
+ }
331
+
332
+ floatArray[ index ++ ] = getField( m, 'attenuationDistance', Infinity );
333
+
334
+ // sample 13
335
+ // alphaMap
336
+ floatArray[ index ++ ] = getTexture( m, 'alphaMap' );
337
+
338
+ // side & matte
339
+ floatArray[ index ++ ] = m.opacity;
340
+ floatArray[ index ++ ] = m.alphaTest;
341
+ if ( ! isThinFilm && m.transmission > 0.0 ) {
342
+
343
+ floatArray[ index ++ ] = 0;
344
+
345
+ } else {
346
+
347
+ switch ( m.side ) {
348
+
349
+ case FrontSide:
350
+ floatArray[ index ++ ] = 1;
351
+ break;
352
+ case BackSide:
353
+ floatArray[ index ++ ] = - 1;
354
+ break;
355
+ case DoubleSide:
356
+ floatArray[ index ++ ] = 0;
357
+ break;
358
+
359
+ }
360
+
361
+ }
362
+
363
+ // sample 14
364
+ index ++; // matte
365
+ index ++; // shadow
366
+ floatArray[ index ++ ] = Number( m.vertexColors ); // vertexColors
367
+ floatArray[ index ++ ] = Number( m.transparent ); // transparent
368
+
369
+ // map transform 15
370
+ index += writeTextureMatrixToArray( m, 'map', floatArray, index );
371
+
372
+ // metalnessMap transform 17
373
+ index += writeTextureMatrixToArray( m, 'metalnessMap', floatArray, index );
374
+
375
+ // roughnessMap transform 19
376
+ index += writeTextureMatrixToArray( m, 'roughnessMap', floatArray, index );
377
+
378
+ // transmissionMap transform 21
379
+ index += writeTextureMatrixToArray( m, 'transmissionMap', floatArray, index );
380
+
381
+ // emissiveMap transform 22
382
+ index += writeTextureMatrixToArray( m, 'emissiveMap', floatArray, index );
383
+
384
+ // normalMap transform 25
385
+ index += writeTextureMatrixToArray( m, 'normalMap', floatArray, index );
386
+
387
+ // clearcoatMap transform 27
388
+ index += writeTextureMatrixToArray( m, 'clearcoatMap', floatArray, index );
389
+
390
+ // clearcoatNormalMap transform 29
391
+ index += writeTextureMatrixToArray( m, 'clearcoatNormalMap', floatArray, index );
392
+
393
+ // clearcoatRoughnessMap transform 31
394
+ index += writeTextureMatrixToArray( m, 'clearcoatRoughnessMap', floatArray, index );
395
+
396
+ // sheenColorMap transform 33
397
+ index += writeTextureMatrixToArray( m, 'sheenColorMap', floatArray, index );
398
+
399
+ // sheenRoughnessMap transform 35
400
+ index += writeTextureMatrixToArray( m, 'sheenRoughnessMap', floatArray, index );
401
+
402
+ // iridescenceMap transform 37
403
+ index += writeTextureMatrixToArray( m, 'iridescenceMap', floatArray, index );
404
+
405
+ // iridescenceThicknessMap transform 39
406
+ index += writeTextureMatrixToArray( m, 'iridescenceThicknessMap', floatArray, index );
407
+
408
+ // specularColorMap transform 41
409
+ index += writeTextureMatrixToArray( m, 'specularColorMap', floatArray, index );
410
+
411
+ // specularIntensityMap transform 43
412
+ index += writeTextureMatrixToArray( m, 'specularIntensityMap', floatArray, index );
413
+
414
+ }
415
+
416
+ this.needsUpdate = true;
417
+
418
+ }
419
+
420
+ }