super-three 0.163.0 → 0.165.0

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 (197) hide show
  1. package/README.md +3 -3
  2. package/build/three.cjs +1127 -452
  3. package/build/three.module.js +1127 -452
  4. package/build/three.module.min.js +2 -2
  5. package/examples/jsm/animation/CCDIKSolver.js +4 -2
  6. package/examples/jsm/controls/TransformControls.js +1 -1
  7. package/examples/jsm/environments/RoomEnvironment.js +1 -5
  8. package/examples/jsm/exporters/GLTFExporter.js +45 -1
  9. package/examples/jsm/exporters/USDZExporter.js +13 -5
  10. package/examples/jsm/helpers/ViewHelper.js +32 -67
  11. package/examples/jsm/libs/draco/README.md +2 -2
  12. package/examples/jsm/libs/tween.module.js +75 -64
  13. package/examples/jsm/lines/LineMaterial.js +1 -15
  14. package/examples/jsm/lines/LineSegments2.js +15 -0
  15. package/examples/jsm/lines/Wireframe.js +16 -1
  16. package/examples/jsm/loaders/DRACOLoader.js +1 -1
  17. package/examples/jsm/loaders/EXRLoader.js +283 -99
  18. package/examples/jsm/loaders/FBXLoader.js +24 -13
  19. package/examples/jsm/loaders/GLTFLoader.js +55 -0
  20. package/examples/jsm/loaders/KTX2Loader.js +3 -6
  21. package/examples/jsm/loaders/LDrawLoader.js +3 -2
  22. package/examples/jsm/loaders/MMDLoader.js +31 -12
  23. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  24. package/examples/jsm/loaders/lwo/IFFParser.js +8 -5
  25. package/examples/jsm/materials/MeshGouraudMaterial.js +7 -1
  26. package/examples/jsm/math/Octree.js +26 -20
  27. package/examples/jsm/modifiers/CurveModifier.js +11 -9
  28. package/examples/jsm/nodes/Nodes.js +15 -13
  29. package/examples/jsm/nodes/accessors/AccessorsUtils.js +16 -1
  30. package/examples/jsm/nodes/accessors/BitangentNode.js +7 -83
  31. package/examples/jsm/nodes/accessors/BufferNode.js +6 -0
  32. package/examples/jsm/nodes/accessors/CameraNode.js +12 -119
  33. package/examples/jsm/nodes/accessors/ClippingNode.js +3 -2
  34. package/examples/jsm/nodes/accessors/MaterialNode.js +109 -3
  35. package/examples/jsm/nodes/accessors/ModelNode.js +3 -0
  36. package/examples/jsm/nodes/accessors/NormalNode.js +9 -101
  37. package/examples/jsm/nodes/accessors/PositionNode.js +6 -100
  38. package/examples/jsm/nodes/accessors/ReferenceNode.js +6 -0
  39. package/examples/jsm/nodes/accessors/ReflectVectorNode.js +2 -31
  40. package/examples/jsm/nodes/accessors/StorageBufferNode.js +9 -0
  41. package/examples/jsm/nodes/accessors/{TextureStoreNode.js → StorageTextureNode.js} +19 -6
  42. package/examples/jsm/nodes/accessors/TangentNode.js +11 -97
  43. package/examples/jsm/nodes/accessors/Texture3DNode.js +100 -0
  44. package/examples/jsm/nodes/accessors/TextureNode.js +21 -3
  45. package/examples/jsm/nodes/accessors/TextureSizeNode.js +1 -1
  46. package/examples/jsm/nodes/accessors/UVNode.js +2 -46
  47. package/examples/jsm/nodes/code/FunctionNode.js +0 -8
  48. package/examples/jsm/nodes/core/AttributeNode.js +15 -3
  49. package/examples/jsm/nodes/core/ContextNode.js +6 -0
  50. package/examples/jsm/nodes/core/Node.js +23 -2
  51. package/examples/jsm/nodes/core/NodeBuilder.js +25 -18
  52. package/examples/jsm/nodes/core/NodeKeywords.js +1 -1
  53. package/examples/jsm/nodes/core/OutputStructNode.js +3 -6
  54. package/examples/jsm/nodes/core/PropertyNode.js +11 -0
  55. package/examples/jsm/nodes/core/VaryingNode.js +40 -9
  56. package/examples/jsm/nodes/display/AfterImageNode.js +14 -2
  57. package/examples/jsm/nodes/display/BumpMapNode.js +7 -26
  58. package/examples/jsm/nodes/display/FrontFacingNode.js +13 -0
  59. package/examples/jsm/nodes/display/PassNode.js +3 -1
  60. package/examples/jsm/nodes/display/ViewportDepthNode.js +1 -1
  61. package/examples/jsm/nodes/display/ViewportNode.js +5 -3
  62. package/examples/jsm/nodes/display/ViewportTextureNode.js +4 -1
  63. package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +26 -7
  64. package/examples/jsm/nodes/functions/BSDF/D_GGX_Anisotropic.js +28 -0
  65. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +1 -3
  66. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +29 -0
  67. package/examples/jsm/nodes/functions/PhongLightingModel.js +1 -1
  68. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +210 -12
  69. package/examples/jsm/nodes/functions/ShadowMaskModel.js +31 -0
  70. package/examples/jsm/nodes/functions/ToonLightingModel.js +49 -0
  71. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +20 -5
  72. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +2 -1
  73. package/examples/jsm/nodes/lighting/EnvironmentNode.js +11 -2
  74. package/examples/jsm/nodes/lighting/IrradianceNode.js +24 -0
  75. package/examples/jsm/nodes/lighting/LightsNode.js +28 -1
  76. package/examples/jsm/nodes/lighting/PointLightNode.js +2 -1
  77. package/examples/jsm/nodes/lighting/SpotLightNode.js +2 -1
  78. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +11 -7
  79. package/examples/jsm/nodes/materials/Materials.js +4 -0
  80. package/examples/jsm/nodes/materials/MeshMatcapNodeMaterial.js +52 -0
  81. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +0 -2
  82. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +2 -2
  83. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +94 -6
  84. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +11 -4
  85. package/examples/jsm/nodes/materials/MeshToonNodeMaterial.js +34 -0
  86. package/examples/jsm/nodes/materials/NodeMaterial.js +43 -45
  87. package/examples/jsm/nodes/materials/ShadowNodeMaterial.js +34 -0
  88. package/examples/jsm/nodes/materials/VolumeNodeMaterial.js +106 -0
  89. package/examples/jsm/nodes/math/HashNode.js +2 -2
  90. package/examples/jsm/nodes/pmrem/PMREMUtils.js +1 -1
  91. package/examples/jsm/nodes/shadernode/ShaderNode.js +57 -41
  92. package/examples/jsm/nodes/utils/ArrayElementNode.js +1 -1
  93. package/examples/jsm/nodes/utils/MatcapUVNode.js +1 -1
  94. package/examples/jsm/nodes/utils/TimerNode.js +1 -1
  95. package/examples/jsm/objects/Lensflare.js +2 -2
  96. package/examples/jsm/physics/JoltPhysics.js +281 -0
  97. package/examples/jsm/postprocessing/RenderPass.js +1 -1
  98. package/examples/jsm/postprocessing/RenderTransitionPass.js +193 -0
  99. package/examples/jsm/renderers/CSS2DRenderer.js +25 -5
  100. package/examples/jsm/renderers/CSS3DRenderer.js +24 -3
  101. package/examples/jsm/renderers/common/Attributes.js +2 -0
  102. package/examples/jsm/renderers/common/Background.js +3 -3
  103. package/examples/jsm/renderers/common/Bindings.js +17 -0
  104. package/examples/jsm/renderers/common/ChainMap.js +18 -48
  105. package/examples/jsm/renderers/common/ClippingContext.js +5 -5
  106. package/examples/jsm/renderers/common/Pipelines.js +2 -2
  107. package/examples/jsm/renderers/common/RenderBundle.js +18 -0
  108. package/examples/jsm/renderers/common/RenderBundles.js +38 -0
  109. package/examples/jsm/renderers/common/RenderList.js +10 -1
  110. package/examples/jsm/renderers/common/RenderObject.js +49 -1
  111. package/examples/jsm/renderers/common/Renderer.js +268 -25
  112. package/examples/jsm/renderers/common/Textures.js +1 -1
  113. package/examples/jsm/renderers/common/Uniform.js +1 -1
  114. package/examples/jsm/renderers/common/extras/PMREMGenerator.js +13 -17
  115. package/examples/jsm/renderers/common/nodes/NodeSampledTexture.js +18 -4
  116. package/examples/jsm/renderers/common/nodes/NodeSampler.js +6 -0
  117. package/examples/jsm/renderers/common/nodes/Nodes.js +31 -47
  118. package/examples/jsm/renderers/webgl/WebGLBackend.js +7 -21
  119. package/examples/jsm/renderers/webgl/WebGLBufferRenderer.js +5 -1
  120. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +23 -5
  121. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +114 -13
  122. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +3 -21
  123. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +80 -46
  124. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +85 -12
  125. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -1
  126. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +10 -1
  127. package/examples/jsm/renderers/webgpu/utils/WebGPUConstants.js +6 -0
  128. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +62 -19
  129. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -3
  130. package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
  131. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  132. package/examples/jsm/utils/BufferGeometryUtils.js +18 -16
  133. package/examples/jsm/utils/GPUStatsPanel.js +2 -0
  134. package/examples/jsm/utils/SceneUtils.js +60 -1
  135. package/examples/jsm/utils/SortUtils.js +8 -5
  136. package/examples/jsm/webxr/OculusHandModel.js +3 -2
  137. package/examples/jsm/webxr/XRHandModelFactory.js +4 -2
  138. package/package.json +3 -2
  139. package/src/animation/tracks/BooleanKeyframeTrack.js +10 -1
  140. package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -2
  141. package/src/animation/tracks/StringKeyframeTrack.js +10 -1
  142. package/src/constants.js +1 -1
  143. package/src/core/Object3D.js +2 -0
  144. package/src/core/Raycaster.js +6 -2
  145. package/src/core/RenderTarget.js +8 -0
  146. package/src/extras/PMREMGenerator.js +12 -11
  147. package/src/loaders/FileLoader.js +5 -1
  148. package/src/loaders/LoaderUtils.js +3 -1
  149. package/src/loaders/MaterialLoader.js +1 -0
  150. package/src/loaders/ObjectLoader.js +1 -0
  151. package/src/materials/Material.js +2 -0
  152. package/src/materials/MeshPhysicalMaterial.js +20 -0
  153. package/src/objects/BatchedMesh.js +114 -1
  154. package/src/objects/Line.js +66 -43
  155. package/src/renderers/WebGLRenderer.js +371 -109
  156. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +15 -0
  157. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -1
  158. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +9 -1
  159. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +8 -22
  160. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  161. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +1 -0
  162. package/src/renderers/shaders/ShaderChunk/morphcolor_vertex.glsl.js +1 -1
  163. package/src/renderers/shaders/ShaderChunk/morphinstance_vertex.glsl.js +1 -1
  164. package/src/renderers/shaders/ShaderChunk/morphnormal_vertex.glsl.js +3 -14
  165. package/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl.js +10 -31
  166. package/src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl.js +3 -23
  167. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +17 -9
  168. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  169. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +47 -13
  170. package/src/renderers/shaders/ShaderChunk.js +0 -2
  171. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  172. package/src/renderers/shaders/ShaderLib.js +1 -0
  173. package/src/renderers/webgl/WebGLBackground.js +24 -3
  174. package/src/renderers/webgl/WebGLBufferRenderer.js +36 -0
  175. package/src/renderers/webgl/WebGLCapabilities.js +33 -1
  176. package/src/renderers/webgl/WebGLExtensions.js +3 -1
  177. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +36 -0
  178. package/src/renderers/webgl/WebGLLights.js +9 -12
  179. package/src/renderers/webgl/WebGLMaterials.js +7 -5
  180. package/src/renderers/webgl/WebGLMorphtargets.js +1 -2
  181. package/src/renderers/webgl/WebGLProgram.js +5 -36
  182. package/src/renderers/webgl/WebGLPrograms.js +19 -14
  183. package/src/renderers/webgl/WebGLRenderStates.js +8 -4
  184. package/src/renderers/webgl/WebGLShadowMap.js +25 -25
  185. package/src/renderers/webgl/WebGLTextures.js +206 -129
  186. package/src/renderers/webgl/WebGLUtils.js +3 -21
  187. package/src/renderers/webxr/WebXRDepthSensing.js +3 -3
  188. package/src/renderers/webxr/WebXRManager.js +8 -6
  189. package/src/textures/CompressedArrayTexture.js +14 -0
  190. package/src/textures/DataArrayTexture.js +14 -0
  191. package/src/textures/DepthTexture.js +1 -3
  192. package/src/utils.js +30 -1
  193. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +0 -318
  194. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +0 -26
  195. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +0 -792
  196. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodes.js +0 -51
  197. package/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl.js +0 -10
@@ -1269,18 +1269,18 @@ class EXRLoader extends DataTextureLoader {
1269
1269
  const inDataView = info.viewer;
1270
1270
  const inOffset = { value: info.offset.value };
1271
1271
 
1272
- const outBuffer = new Uint16Array( info.width * info.scanlineBlockSize * ( info.channels * info.type ) );
1272
+ const outBuffer = new Uint16Array( info.columns * info.lines * ( info.inputChannels.length * info.type ) );
1273
1273
  const bitmap = new Uint8Array( BITMAP_SIZE );
1274
1274
 
1275
1275
  // Setup channel info
1276
1276
  let outBufferEnd = 0;
1277
- const pizChannelData = new Array( info.channels );
1278
- for ( let i = 0; i < info.channels; i ++ ) {
1277
+ const pizChannelData = new Array( info.inputChannels.length );
1278
+ for ( let i = 0, il = info.inputChannels.length; i < il; i ++ ) {
1279
1279
 
1280
1280
  pizChannelData[ i ] = {};
1281
1281
  pizChannelData[ i ][ 'start' ] = outBufferEnd;
1282
1282
  pizChannelData[ i ][ 'end' ] = pizChannelData[ i ][ 'start' ];
1283
- pizChannelData[ i ][ 'nx' ] = info.width;
1283
+ pizChannelData[ i ][ 'nx' ] = info.columns;
1284
1284
  pizChannelData[ i ][ 'ny' ] = info.lines;
1285
1285
  pizChannelData[ i ][ 'size' ] = info.type;
1286
1286
 
@@ -1319,7 +1319,7 @@ class EXRLoader extends DataTextureLoader {
1319
1319
  hufUncompress( info.array, inDataView, inOffset, length, outBuffer, outBufferEnd );
1320
1320
 
1321
1321
  // Wavelet decoding
1322
- for ( let i = 0; i < info.channels; ++ i ) {
1322
+ for ( let i = 0; i < info.inputChannels.length; ++ i ) {
1323
1323
 
1324
1324
  const cd = pizChannelData[ i ];
1325
1325
 
@@ -1347,7 +1347,7 @@ class EXRLoader extends DataTextureLoader {
1347
1347
  const tmpBuffer = new Uint8Array( outBuffer.buffer.byteLength );
1348
1348
  for ( let y = 0; y < info.lines; y ++ ) {
1349
1349
 
1350
- for ( let c = 0; c < info.channels; c ++ ) {
1350
+ for ( let c = 0; c < info.inputChannels.length; c ++ ) {
1351
1351
 
1352
1352
  const cd = pizChannelData[ c ];
1353
1353
 
@@ -1372,8 +1372,9 @@ class EXRLoader extends DataTextureLoader {
1372
1372
 
1373
1373
  const rawBuffer = fflate.unzlibSync( compressed );
1374
1374
 
1375
- const sz = info.lines * info.channels * info.width;
1376
- const tmpBuffer = ( info.type == 1 ) ? new Uint16Array( sz ) : new Uint32Array( sz );
1375
+ const byteSize = info.inputChannels.length * info.lines * info.columns * info.totalBytes;
1376
+ const tmpBuffer = new ArrayBuffer( byteSize );
1377
+ const viewer = new DataView( tmpBuffer );
1377
1378
 
1378
1379
  let tmpBufferEnd = 0;
1379
1380
  let writePtr = 0;
@@ -1381,26 +1382,27 @@ class EXRLoader extends DataTextureLoader {
1381
1382
 
1382
1383
  for ( let y = 0; y < info.lines; y ++ ) {
1383
1384
 
1384
- for ( let c = 0; c < info.channels; c ++ ) {
1385
+ for ( let c = 0; c < info.inputChannels.length; c ++ ) {
1385
1386
 
1386
1387
  let pixel = 0;
1387
1388
 
1388
- switch ( info.type ) {
1389
+ const type = info.inputChannels[ c ].pixelType;
1390
+ switch ( type ) {
1389
1391
 
1390
1392
  case 1:
1391
1393
 
1392
1394
  ptr[ 0 ] = tmpBufferEnd;
1393
- ptr[ 1 ] = ptr[ 0 ] + info.width;
1394
- tmpBufferEnd = ptr[ 1 ] + info.width;
1395
+ ptr[ 1 ] = ptr[ 0 ] + info.columns;
1396
+ tmpBufferEnd = ptr[ 1 ] + info.columns;
1395
1397
 
1396
- for ( let j = 0; j < info.width; ++ j ) {
1398
+ for ( let j = 0; j < info.columns; ++ j ) {
1397
1399
 
1398
1400
  const diff = ( rawBuffer[ ptr[ 0 ] ++ ] << 8 ) | rawBuffer[ ptr[ 1 ] ++ ];
1399
1401
 
1400
1402
  pixel += diff;
1401
1403
 
1402
- tmpBuffer[ writePtr ] = pixel;
1403
- writePtr ++;
1404
+ viewer.setUint16( writePtr, pixel, true );
1405
+ writePtr += 2;
1404
1406
 
1405
1407
  }
1406
1408
 
@@ -1409,18 +1411,18 @@ class EXRLoader extends DataTextureLoader {
1409
1411
  case 2:
1410
1412
 
1411
1413
  ptr[ 0 ] = tmpBufferEnd;
1412
- ptr[ 1 ] = ptr[ 0 ] + info.width;
1413
- ptr[ 2 ] = ptr[ 1 ] + info.width;
1414
- tmpBufferEnd = ptr[ 2 ] + info.width;
1414
+ ptr[ 1 ] = ptr[ 0 ] + info.columns;
1415
+ ptr[ 2 ] = ptr[ 1 ] + info.columns;
1416
+ tmpBufferEnd = ptr[ 2 ] + info.columns;
1415
1417
 
1416
- for ( let j = 0; j < info.width; ++ j ) {
1418
+ for ( let j = 0; j < info.columns; ++ j ) {
1417
1419
 
1418
1420
  const diff = ( rawBuffer[ ptr[ 0 ] ++ ] << 24 ) | ( rawBuffer[ ptr[ 1 ] ++ ] << 16 ) | ( rawBuffer[ ptr[ 2 ] ++ ] << 8 );
1419
1421
 
1420
1422
  pixel += diff;
1421
1423
 
1422
- tmpBuffer[ writePtr ] = pixel;
1423
- writePtr ++;
1424
+ viewer.setUint32( writePtr, pixel, true );
1425
+ writePtr += 4;
1424
1426
 
1425
1427
  }
1426
1428
 
@@ -1432,7 +1434,7 @@ class EXRLoader extends DataTextureLoader {
1432
1434
 
1433
1435
  }
1434
1436
 
1435
- return new DataView( tmpBuffer.buffer );
1437
+ return viewer;
1436
1438
 
1437
1439
  }
1438
1440
 
@@ -1440,7 +1442,7 @@ class EXRLoader extends DataTextureLoader {
1440
1442
 
1441
1443
  const inDataView = info.viewer;
1442
1444
  const inOffset = { value: info.offset.value };
1443
- const outBuffer = new Uint8Array( info.width * info.lines * ( info.channels * info.type * INT16_SIZE ) );
1445
+ const outBuffer = new Uint8Array( info.columns * info.lines * ( info.inputChannels.length * info.type * INT16_SIZE ) );
1444
1446
 
1445
1447
  // Read compression header information
1446
1448
  const dwaHeader = {
@@ -1488,9 +1490,9 @@ class EXRLoader extends DataTextureLoader {
1488
1490
 
1489
1491
  // Classify channels
1490
1492
  const channels = EXRHeader.channels;
1491
- const channelData = new Array( info.channels );
1493
+ const channelData = new Array( info.inputChannels.length );
1492
1494
 
1493
- for ( let i = 0; i < info.channels; ++ i ) {
1495
+ for ( let i = 0; i < info.inputChannels.length; ++ i ) {
1494
1496
 
1495
1497
  const cd = channelData[ i ] = {};
1496
1498
  const channel = channels[ i ];
@@ -1500,7 +1502,7 @@ class EXRLoader extends DataTextureLoader {
1500
1502
  cd.decoded = false;
1501
1503
  cd.type = channel.pixelType;
1502
1504
  cd.pLinear = channel.pLinear;
1503
- cd.width = info.width;
1505
+ cd.width = info.columns;
1504
1506
  cd.height = info.lines;
1505
1507
 
1506
1508
  }
@@ -1509,7 +1511,7 @@ class EXRLoader extends DataTextureLoader {
1509
1511
  idx: new Array( 3 )
1510
1512
  };
1511
1513
 
1512
- for ( let offset = 0; offset < info.channels; ++ offset ) {
1514
+ for ( let offset = 0; offset < info.inputChannels.length; ++ offset ) {
1513
1515
 
1514
1516
  const cd = channelData[ offset ];
1515
1517
 
@@ -1899,7 +1901,8 @@ class EXRLoader extends DataTextureLoader {
1899
1901
 
1900
1902
  const lineOrders = [
1901
1903
  'INCREASING_Y',
1902
- 'DECREASING_Y'
1904
+ 'DECREASING_Y',
1905
+ 'RANDOM_Y',
1903
1906
  ];
1904
1907
 
1905
1908
  const lineOrder = parseUint8( dataView, offset );
@@ -1908,6 +1911,45 @@ class EXRLoader extends DataTextureLoader {
1908
1911
 
1909
1912
  }
1910
1913
 
1914
+ function parseEnvmap( dataView, offset ) {
1915
+
1916
+ const envmaps = [
1917
+ 'ENVMAP_LATLONG',
1918
+ 'ENVMAP_CUBE'
1919
+ ];
1920
+
1921
+ const envmap = parseUint8( dataView, offset );
1922
+
1923
+ return envmaps[ envmap ];
1924
+
1925
+ }
1926
+
1927
+ function parseTiledesc( dataView, offset ) {
1928
+
1929
+ const levelModes = [
1930
+ 'ONE_LEVEL',
1931
+ 'MIPMAP_LEVELS',
1932
+ 'RIPMAP_LEVELS',
1933
+ ];
1934
+
1935
+ const roundingModes = [
1936
+ 'ROUND_DOWN',
1937
+ 'ROUND_UP',
1938
+ ];
1939
+
1940
+ const xSize = parseUint32( dataView, offset );
1941
+ const ySize = parseUint32( dataView, offset );
1942
+ const modes = parseUint8( dataView, offset );
1943
+
1944
+ return {
1945
+ xSize: xSize,
1946
+ ySize: ySize,
1947
+ levelMode: levelModes[ modes & 0xf ],
1948
+ roundingMode: roundingModes[ modes >> 4 ]
1949
+ };
1950
+
1951
+ }
1952
+
1911
1953
  function parseV2f( dataView, offset ) {
1912
1954
 
1913
1955
  const x = parseFloat32( dataView, offset );
@@ -1949,6 +1991,14 @@ class EXRLoader extends DataTextureLoader {
1949
1991
 
1950
1992
  return parseBox2i( dataView, offset );
1951
1993
 
1994
+ } else if ( type === 'envmap' ) {
1995
+
1996
+ return parseEnvmap( dataView, offset );
1997
+
1998
+ } else if ( type === 'tiledesc' ) {
1999
+
2000
+ return parseTiledesc( dataView, offset );
2001
+
1952
2002
  } else if ( type === 'lineOrder' ) {
1953
2003
 
1954
2004
  return parseLineOrder( dataView, offset );
@@ -1991,6 +2041,163 @@ class EXRLoader extends DataTextureLoader {
1991
2041
 
1992
2042
  }
1993
2043
 
2044
+ function roundLog2( x, mode ) {
2045
+
2046
+ const log2 = Math.log2( x );
2047
+ return mode == 'ROUND_DOWN' ? Math.floor( log2 ) : Math.ceil( log2 );
2048
+
2049
+ }
2050
+
2051
+ function calculateTileLevels( tiledesc, w, h ) {
2052
+
2053
+ let num = 0;
2054
+
2055
+ switch ( tiledesc.levelMode ) {
2056
+
2057
+ case 'ONE_LEVEL':
2058
+ num = 1;
2059
+ break;
2060
+
2061
+ case 'MIPMAP_LEVELS':
2062
+ num = roundLog2( Math.max( w, h ), tiledesc.roundingMode ) + 1;
2063
+ break;
2064
+
2065
+ case 'RIPMAP_LEVELS':
2066
+ throw new Error( 'THREE.EXRLoader: RIPMAP_LEVELS tiles currently unsupported.' );
2067
+
2068
+ }
2069
+
2070
+ return num;
2071
+
2072
+ }
2073
+
2074
+ function calculateTiles( count, dataSize, size, roundingMode ) {
2075
+
2076
+ const tiles = new Array( count );
2077
+
2078
+ for ( let i = 0; i < count; i ++ ) {
2079
+
2080
+ const b = ( 1 << i );
2081
+ let s = ( dataSize / b ) | 0;
2082
+
2083
+ if ( roundingMode == 'ROUND_UP' && s * b < dataSize ) s += 1;
2084
+
2085
+ const l = Math.max( s, 1 );
2086
+
2087
+ tiles[ i ] = ( ( l + size - 1 ) / size ) | 0;
2088
+
2089
+ }
2090
+
2091
+ return tiles;
2092
+
2093
+ }
2094
+
2095
+ function parseTiles() {
2096
+
2097
+ const EXRDecoder = this;
2098
+ const offset = EXRDecoder.offset;
2099
+ const tmpOffset = { value: 0 };
2100
+
2101
+ for ( let tile = 0; tile < EXRDecoder.tileCount; tile ++ ) {
2102
+
2103
+ const tileX = parseInt32( EXRDecoder.viewer, offset );
2104
+ const tileY = parseInt32( EXRDecoder.viewer, offset );
2105
+ offset.value += 8; // skip levels - only parsing top-level
2106
+ EXRDecoder.size = parseUint32( EXRDecoder.viewer, offset );
2107
+
2108
+ const startX = tileX * EXRDecoder.blockWidth;
2109
+ const startY = tileY * EXRDecoder.blockHeight;
2110
+ EXRDecoder.columns = ( startX + EXRDecoder.blockWidth > EXRDecoder.width ) ? EXRDecoder.width - startX : EXRDecoder.blockWidth;
2111
+ EXRDecoder.lines = ( startY + EXRDecoder.blockHeight > EXRDecoder.height ) ? EXRDecoder.height - startY : EXRDecoder.blockHeight;
2112
+
2113
+ const bytesBlockLine = EXRDecoder.columns * EXRDecoder.totalBytes;
2114
+ const isCompressed = EXRDecoder.size < EXRDecoder.lines * bytesBlockLine;
2115
+ const viewer = isCompressed ? EXRDecoder.uncompress( EXRDecoder ) : uncompressRAW( EXRDecoder );
2116
+
2117
+ offset.value += EXRDecoder.size;
2118
+
2119
+ for ( let line = 0; line < EXRDecoder.lines; line ++ ) {
2120
+
2121
+ const lineOffset = line * EXRDecoder.columns * EXRDecoder.totalBytes;
2122
+
2123
+ for ( let channelID = 0; channelID < EXRDecoder.inputChannels.length; channelID ++ ) {
2124
+
2125
+ const name = EXRHeader.channels[ channelID ].name;
2126
+ const lOff = EXRDecoder.channelByteOffsets[ name ] * EXRDecoder.columns;
2127
+ const cOff = EXRDecoder.decodeChannels[ name ];
2128
+
2129
+ if ( cOff === undefined ) continue;
2130
+
2131
+ tmpOffset.value = lineOffset + lOff;
2132
+ const outLineOffset = ( EXRDecoder.height - ( 1 + startY + line ) ) * EXRDecoder.outLineWidth;
2133
+
2134
+ for ( let x = 0; x < EXRDecoder.columns; x ++ ) {
2135
+
2136
+ const outIndex = outLineOffset + ( x + startX ) * EXRDecoder.outputChannels + cOff;
2137
+ EXRDecoder.byteArray[ outIndex ] = EXRDecoder.getter( viewer, tmpOffset );
2138
+
2139
+ }
2140
+
2141
+ }
2142
+
2143
+ }
2144
+
2145
+ }
2146
+
2147
+ }
2148
+
2149
+ function parseScanline() {
2150
+
2151
+ const EXRDecoder = this;
2152
+ const offset = EXRDecoder.offset;
2153
+ const tmpOffset = { value: 0 };
2154
+
2155
+ for ( let scanlineBlockIdx = 0; scanlineBlockIdx < EXRDecoder.height / EXRDecoder.blockHeight; scanlineBlockIdx ++ ) {
2156
+
2157
+ const line = parseInt32( EXRDecoder.viewer, offset ) - EXRHeader.dataWindow.yMin; // line_no
2158
+ EXRDecoder.size = parseUint32( EXRDecoder.viewer, offset ); // data_len
2159
+ EXRDecoder.lines = ( ( line + EXRDecoder.blockHeight > EXRDecoder.height ) ? ( EXRDecoder.height - line ) : EXRDecoder.blockHeight );
2160
+
2161
+ const bytesPerLine = EXRDecoder.columns * EXRDecoder.totalBytes;
2162
+ const isCompressed = EXRDecoder.size < EXRDecoder.lines * bytesPerLine;
2163
+ const viewer = isCompressed ? EXRDecoder.uncompress( EXRDecoder ) : uncompressRAW( EXRDecoder );
2164
+
2165
+ offset.value += EXRDecoder.size;
2166
+
2167
+ for ( let line_y = 0; line_y < EXRDecoder.blockHeight; line_y ++ ) {
2168
+
2169
+ const scan_y = scanlineBlockIdx * EXRDecoder.blockHeight;
2170
+ const true_y = line_y + EXRDecoder.scanOrder( scan_y );
2171
+ if ( true_y >= EXRDecoder.height ) continue;
2172
+
2173
+ const lineOffset = line_y * bytesPerLine;
2174
+ const outLineOffset = ( EXRDecoder.height - 1 - true_y ) * EXRDecoder.outLineWidth;
2175
+
2176
+ for ( let channelID = 0; channelID < EXRDecoder.inputChannels.length; channelID ++ ) {
2177
+
2178
+ const name = EXRHeader.channels[ channelID ].name;
2179
+ const lOff = EXRDecoder.channelByteOffsets[ name ] * EXRDecoder.columns;
2180
+ const cOff = EXRDecoder.decodeChannels[ name ];
2181
+
2182
+ if ( cOff === undefined ) continue;
2183
+
2184
+ tmpOffset.value = lineOffset + lOff;
2185
+
2186
+ for ( let x = 0; x < EXRDecoder.columns; x ++ ) {
2187
+
2188
+ const outIndex = outLineOffset + x * EXRDecoder.outputChannels + cOff;
2189
+ EXRDecoder.byteArray[ outIndex ] = EXRDecoder.getter( viewer, tmpOffset );
2190
+
2191
+ }
2192
+
2193
+ }
2194
+
2195
+ }
2196
+
2197
+ }
2198
+
2199
+ }
2200
+
1994
2201
  function parseHeader( dataView, buffer, offset ) {
1995
2202
 
1996
2203
  const EXRHeader = {};
@@ -2046,7 +2253,7 @@ class EXRLoader extends DataTextureLoader {
2046
2253
 
2047
2254
  }
2048
2255
 
2049
- if ( ( spec & ~ 0x04 ) != 0 ) { // unsupported tiled, deep-image, multi-part
2256
+ if ( ( spec & ~ 0x06 ) != 0 ) { // unsupported deep-image, multi-part
2050
2257
 
2051
2258
  console.error( 'THREE.EXRHeader:', EXRHeader );
2052
2259
  throw new Error( 'THREE.EXRLoader: Provided file is currently unsupported.' );
@@ -2066,12 +2273,12 @@ class EXRLoader extends DataTextureLoader {
2066
2273
  offset: offset,
2067
2274
  width: EXRHeader.dataWindow.xMax - EXRHeader.dataWindow.xMin + 1,
2068
2275
  height: EXRHeader.dataWindow.yMax - EXRHeader.dataWindow.yMin + 1,
2069
- channels: EXRHeader.channels.length,
2070
- channelLineOffsets: {},
2276
+ inputChannels: EXRHeader.channels,
2277
+ channelByteOffsets: {},
2071
2278
  scanOrder: null,
2072
- bytesPerLine: null,
2279
+ totalBytes: null,
2280
+ columns: null,
2073
2281
  lines: null,
2074
- inputSize: null,
2075
2282
  type: null,
2076
2283
  uncompress: null,
2077
2284
  getter: null,
@@ -2082,42 +2289,42 @@ class EXRLoader extends DataTextureLoader {
2082
2289
  switch ( EXRHeader.compression ) {
2083
2290
 
2084
2291
  case 'NO_COMPRESSION':
2085
- EXRDecoder.lines = 1;
2292
+ EXRDecoder.blockHeight = 1;
2086
2293
  EXRDecoder.uncompress = uncompressRAW;
2087
2294
  break;
2088
2295
 
2089
2296
  case 'RLE_COMPRESSION':
2090
- EXRDecoder.lines = 1;
2297
+ EXRDecoder.blockHeight = 1;
2091
2298
  EXRDecoder.uncompress = uncompressRLE;
2092
2299
  break;
2093
2300
 
2094
2301
  case 'ZIPS_COMPRESSION':
2095
- EXRDecoder.lines = 1;
2302
+ EXRDecoder.blockHeight = 1;
2096
2303
  EXRDecoder.uncompress = uncompressZIP;
2097
2304
  break;
2098
2305
 
2099
2306
  case 'ZIP_COMPRESSION':
2100
- EXRDecoder.lines = 16;
2307
+ EXRDecoder.blockHeight = 16;
2101
2308
  EXRDecoder.uncompress = uncompressZIP;
2102
2309
  break;
2103
2310
 
2104
2311
  case 'PIZ_COMPRESSION':
2105
- EXRDecoder.lines = 32;
2312
+ EXRDecoder.blockHeight = 32;
2106
2313
  EXRDecoder.uncompress = uncompressPIZ;
2107
2314
  break;
2108
2315
 
2109
2316
  case 'PXR24_COMPRESSION':
2110
- EXRDecoder.lines = 16;
2317
+ EXRDecoder.blockHeight = 16;
2111
2318
  EXRDecoder.uncompress = uncompressPXR;
2112
2319
  break;
2113
2320
 
2114
2321
  case 'DWAA_COMPRESSION':
2115
- EXRDecoder.lines = 32;
2322
+ EXRDecoder.blockHeight = 32;
2116
2323
  EXRDecoder.uncompress = uncompressDWA;
2117
2324
  break;
2118
2325
 
2119
2326
  case 'DWAB_COMPRESSION':
2120
- EXRDecoder.lines = 256;
2327
+ EXRDecoder.blockHeight = 256;
2121
2328
  EXRDecoder.uncompress = uncompressDWA;
2122
2329
  break;
2123
2330
 
@@ -2126,8 +2333,6 @@ class EXRLoader extends DataTextureLoader {
2126
2333
 
2127
2334
  }
2128
2335
 
2129
- EXRDecoder.scanlineBlockSize = EXRDecoder.lines;
2130
-
2131
2336
  const channels = {};
2132
2337
  for ( const channel of EXRHeader.channels ) {
2133
2338
 
@@ -2172,12 +2377,10 @@ class EXRLoader extends DataTextureLoader {
2172
2377
 
2173
2378
  case FloatType:
2174
2379
  EXRDecoder.getter = parseFloat16;
2175
- EXRDecoder.inputSize = INT16_SIZE;
2176
2380
  break;
2177
2381
 
2178
2382
  case HalfFloatType:
2179
2383
  EXRDecoder.getter = parseUint16;
2180
- EXRDecoder.inputSize = INT16_SIZE;
2181
2384
  break;
2182
2385
 
2183
2386
  }
@@ -2189,12 +2392,10 @@ class EXRLoader extends DataTextureLoader {
2189
2392
 
2190
2393
  case FloatType:
2191
2394
  EXRDecoder.getter = parseFloat32;
2192
- EXRDecoder.inputSize = FLOAT32_SIZE;
2193
2395
  break;
2194
2396
 
2195
2397
  case HalfFloatType:
2196
2398
  EXRDecoder.getter = decodeFloat32;
2197
- EXRDecoder.inputSize = FLOAT32_SIZE;
2198
2399
 
2199
2400
  }
2200
2401
 
@@ -2204,13 +2405,7 @@ class EXRLoader extends DataTextureLoader {
2204
2405
 
2205
2406
  }
2206
2407
 
2207
- EXRDecoder.blockCount = EXRDecoder.height / EXRDecoder.scanlineBlockSize;
2208
-
2209
- for ( let i = 0; i < EXRDecoder.blockCount; i ++ )
2210
- parseInt64( dataView, offset ); // scanlineOffset
2211
-
2212
- // we should be passed the scanline offset table, ready to start reading pixel data.
2213
-
2408
+ EXRDecoder.columns = EXRDecoder.width;
2214
2409
  const size = EXRDecoder.width * EXRDecoder.height * EXRDecoder.outputChannels;
2215
2410
 
2216
2411
  switch ( outputType ) {
@@ -2243,7 +2438,7 @@ class EXRLoader extends DataTextureLoader {
2243
2438
 
2244
2439
  if ( EXRDecoder.decodeChannels[ channel.name ] !== undefined ) {
2245
2440
 
2246
- EXRDecoder.channelLineOffsets[ channel.name ] = byteOffset * EXRDecoder.width;
2441
+ EXRDecoder.channelByteOffsets[ channel.name ] = byteOffset;
2247
2442
 
2248
2443
  }
2249
2444
 
@@ -2251,7 +2446,7 @@ class EXRLoader extends DataTextureLoader {
2251
2446
 
2252
2447
  }
2253
2448
 
2254
- EXRDecoder.bytesPerLine = EXRDecoder.width * byteOffset;
2449
+ EXRDecoder.totalBytes = byteOffset;
2255
2450
  EXRDecoder.outLineWidth = EXRDecoder.width * EXRDecoder.outputChannels;
2256
2451
 
2257
2452
  if ( EXRHeader.lineOrder === 'INCREASING_Y' ) {
@@ -2276,66 +2471,55 @@ class EXRLoader extends DataTextureLoader {
2276
2471
 
2277
2472
  }
2278
2473
 
2279
- return EXRDecoder;
2280
-
2281
- }
2282
-
2283
- // start parsing file [START]
2284
-
2285
- const bufferDataView = new DataView( buffer );
2286
- const uInt8Array = new Uint8Array( buffer );
2287
- const offset = { value: 0 };
2288
-
2289
- // get header information and validate format.
2290
- const EXRHeader = parseHeader( bufferDataView, buffer, offset );
2291
-
2292
- // get input compression information and prepare decoding.
2293
- const EXRDecoder = setupDecoder( EXRHeader, bufferDataView, uInt8Array, offset, this.type );
2294
-
2295
- const tmpOffset = { value: 0 };
2474
+ if ( EXRHeader.spec.singleTile ) {
2296
2475
 
2297
- for ( let scanlineBlockIdx = 0; scanlineBlockIdx < EXRDecoder.height / EXRDecoder.scanlineBlockSize; scanlineBlockIdx ++ ) {
2476
+ EXRDecoder.blockHeight = EXRHeader.tiles.ySize;
2477
+ EXRDecoder.blockWidth = EXRHeader.tiles.xSize;
2298
2478
 
2299
- const line = parseInt32( bufferDataView, offset ) - EXRHeader.dataWindow.yMin; // line_no
2300
- EXRDecoder.size = parseUint32( bufferDataView, offset ); // data_len
2301
- EXRDecoder.lines = ( ( line + EXRDecoder.scanlineBlockSize > EXRDecoder.height ) ? ( EXRDecoder.height - line ) : EXRDecoder.scanlineBlockSize );
2479
+ const numXLevels = calculateTileLevels( EXRHeader.tiles, EXRDecoder.width, EXRDecoder.height );
2480
+ // const numYLevels = calculateTileLevels( EXRHeader.tiles, EXRDecoder.width, EXRDecoder.height );
2302
2481
 
2303
- const isCompressed = EXRDecoder.size < EXRDecoder.lines * EXRDecoder.bytesPerLine;
2304
- const viewer = isCompressed ? EXRDecoder.uncompress( EXRDecoder ) : uncompressRAW( EXRDecoder );
2482
+ const numXTiles = calculateTiles( numXLevels, EXRDecoder.width, EXRHeader.tiles.xSize, EXRHeader.tiles.roundingMode );
2483
+ const numYTiles = calculateTiles( numXLevels, EXRDecoder.height, EXRHeader.tiles.ySize, EXRHeader.tiles.roundingMode );
2305
2484
 
2306
- offset.value += EXRDecoder.size;
2485
+ EXRDecoder.tileCount = numXTiles[ 0 ] * numYTiles[ 0 ];
2307
2486
 
2308
- for ( let line_y = 0; line_y < EXRDecoder.scanlineBlockSize; line_y ++ ) {
2487
+ for ( let l = 0; l < numXLevels; l ++ )
2488
+ for ( let y = 0; y < numYTiles[ l ]; y ++ )
2489
+ for ( let x = 0; x < numXTiles[ l ]; x ++ )
2490
+ parseInt64( dataView, offset ); // tileOffset
2309
2491
 
2310
- const scan_y = scanlineBlockIdx * EXRDecoder.scanlineBlockSize;
2311
- const true_y = line_y + EXRDecoder.scanOrder( scan_y );
2312
- if ( true_y >= EXRDecoder.height ) continue;
2492
+ EXRDecoder.decode = parseTiles.bind( EXRDecoder );
2313
2493
 
2314
- const lineOffset = line_y * EXRDecoder.bytesPerLine;
2315
- const outLineOffset = ( EXRDecoder.height - 1 - true_y ) * EXRDecoder.outLineWidth;
2494
+ } else {
2316
2495
 
2317
- for ( let channelID = 0; channelID < EXRDecoder.channels; channelID ++ ) {
2496
+ EXRDecoder.blockWidth = EXRDecoder.width;
2497
+ const blockCount = Math.ceil( EXRDecoder.height / EXRDecoder.blockHeight );
2318
2498
 
2319
- const name = EXRHeader.channels[ channelID ].name;
2320
- const lOff = EXRDecoder.channelLineOffsets[ name ];
2321
- const cOff = EXRDecoder.decodeChannels[ name ];
2499
+ for ( let i = 0; i < blockCount; i ++ )
2500
+ parseInt64( dataView, offset ); // scanlineOffset
2322
2501
 
2323
- if ( cOff === undefined ) continue;
2502
+ EXRDecoder.decode = parseScanline.bind( EXRDecoder );
2324
2503
 
2325
- tmpOffset.value = lineOffset + lOff;
2504
+ }
2326
2505
 
2327
- for ( let x = 0; x < EXRDecoder.width; x ++ ) {
2506
+ return EXRDecoder;
2328
2507
 
2329
- const outIndex = outLineOffset + x * EXRDecoder.outputChannels + cOff;
2330
- EXRDecoder.byteArray[ outIndex ] = EXRDecoder.getter( viewer, tmpOffset );
2508
+ }
2331
2509
 
2332
- }
2510
+ // start parsing file [START]
2511
+ const offset = { value: 0 };
2512
+ const bufferDataView = new DataView( buffer );
2513
+ const uInt8Array = new Uint8Array( buffer );
2333
2514
 
2334
- }
2515
+ // get header information and validate format.
2516
+ const EXRHeader = parseHeader( bufferDataView, buffer, offset );
2335
2517
 
2336
- }
2518
+ // get input compression information and prepare decoding.
2519
+ const EXRDecoder = setupDecoder( EXRHeader, bufferDataView, uInt8Array, offset, this.type );
2337
2520
 
2338
- }
2521
+ // parse input data
2522
+ EXRDecoder.decode();
2339
2523
 
2340
2524
  return {
2341
2525
  header: EXRHeader,