@plastic-software/three 0.182.0 → 0.183.1

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 (299) hide show
  1. package/LICENSE +1 -1
  2. package/build/three.cjs +11521 -10878
  3. package/build/three.core.js +11732 -11340
  4. package/build/three.core.min.js +2 -2
  5. package/build/three.module.js +510 -263
  6. package/build/three.module.min.js +2 -2
  7. package/build/three.tsl.js +7 -11
  8. package/build/three.tsl.min.js +2 -2
  9. package/build/three.webgpu.js +3072 -2607
  10. package/build/three.webgpu.min.js +2 -2
  11. package/build/three.webgpu.nodes.js +3071 -2607
  12. package/build/three.webgpu.nodes.min.js +2 -2
  13. package/examples/jsm/Addons.js +0 -3
  14. package/examples/jsm/animation/CCDIKSolver.js +2 -2
  15. package/examples/jsm/controls/ArcballControls.js +3 -3
  16. package/examples/jsm/controls/OrbitControls.js +103 -0
  17. package/examples/jsm/effects/AnaglyphEffect.js +102 -7
  18. package/examples/jsm/environments/ColorEnvironment.js +59 -0
  19. package/examples/jsm/environments/RoomEnvironment.js +1 -0
  20. package/examples/jsm/exporters/EXRExporter.js +1 -1
  21. package/examples/jsm/exporters/GLTFExporter.js +131 -4
  22. package/examples/jsm/exporters/USDZExporter.js +22 -3
  23. package/examples/jsm/helpers/AnimationPathHelper.js +302 -0
  24. package/examples/jsm/helpers/ViewHelper.js +67 -8
  25. package/examples/jsm/inspector/Inspector.js +21 -5
  26. package/examples/jsm/inspector/tabs/Console.js +39 -5
  27. package/examples/jsm/inspector/tabs/Parameters.js +16 -0
  28. package/examples/jsm/inspector/ui/Style.js +25 -1
  29. package/examples/jsm/libs/meshopt_decoder.module.js +6 -5
  30. package/examples/jsm/lines/LineMaterial.js +6 -0
  31. package/examples/jsm/loaders/3MFLoader.js +2 -2
  32. package/examples/jsm/loaders/AMFLoader.js +2 -2
  33. package/examples/jsm/loaders/ColladaLoader.js +24 -4026
  34. package/examples/jsm/loaders/EXRLoader.js +5 -5
  35. package/examples/jsm/loaders/FBXLoader.js +2 -2
  36. package/examples/jsm/loaders/GCodeLoader.js +34 -8
  37. package/examples/jsm/loaders/GLTFLoader.js +122 -171
  38. package/examples/jsm/loaders/KMZLoader.js +5 -5
  39. package/examples/jsm/loaders/KTX2Loader.js +5 -5
  40. package/examples/jsm/loaders/LWOLoader.js +7 -39
  41. package/examples/jsm/loaders/NRRDLoader.js +2 -2
  42. package/examples/jsm/loaders/PCDLoader.js +3 -2
  43. package/examples/jsm/loaders/USDLoader.js +100 -40
  44. package/examples/jsm/loaders/UltraHDRLoader.js +182 -30
  45. package/examples/jsm/loaders/VRMLLoader.js +77 -0
  46. package/examples/jsm/loaders/VTKLoader.js +37 -24
  47. package/examples/jsm/loaders/collada/ColladaComposer.js +2950 -0
  48. package/examples/jsm/loaders/collada/ColladaParser.js +1962 -0
  49. package/examples/jsm/loaders/usd/USDAParser.js +447 -366
  50. package/examples/jsm/loaders/usd/USDCParser.js +1841 -6
  51. package/examples/jsm/loaders/usd/USDComposer.js +4041 -0
  52. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +2 -2
  53. package/examples/jsm/objects/LensflareMesh.js +1 -1
  54. package/examples/jsm/objects/Sky.js +76 -4
  55. package/examples/jsm/objects/SkyMesh.js +114 -7
  56. package/examples/jsm/objects/Water.js +4 -3
  57. package/examples/jsm/objects/Water2.js +5 -3
  58. package/examples/jsm/objects/WaterMesh.js +5 -7
  59. package/examples/jsm/physics/JoltPhysics.js +7 -5
  60. package/examples/jsm/physics/RapierPhysics.js +6 -4
  61. package/examples/jsm/postprocessing/EffectComposer.js +7 -5
  62. package/examples/jsm/postprocessing/RenderTransitionPass.js +1 -1
  63. package/examples/jsm/renderers/CSS3DRenderer.js +1 -1
  64. package/examples/jsm/renderers/SVGRenderer.js +2 -2
  65. package/examples/jsm/shaders/GTAOShader.js +19 -6
  66. package/examples/jsm/shaders/HalftoneShader.js +12 -1
  67. package/examples/jsm/shaders/PoissonDenoiseShader.js +6 -2
  68. package/examples/jsm/shaders/SAOShader.js +17 -4
  69. package/examples/jsm/shaders/SSAOShader.js +11 -1
  70. package/examples/jsm/shaders/SSRShader.js +6 -5
  71. package/examples/jsm/shaders/VignetteShader.js +1 -1
  72. package/examples/jsm/tsl/display/AfterImageNode.js +1 -1
  73. package/examples/jsm/tsl/display/AnaglyphPassNode.js +456 -16
  74. package/examples/jsm/tsl/display/AnamorphicNode.js +1 -1
  75. package/examples/jsm/tsl/display/BilateralBlurNode.js +364 -0
  76. package/examples/jsm/tsl/display/BloomNode.js +5 -5
  77. package/examples/jsm/tsl/display/CRT.js +150 -0
  78. package/examples/jsm/tsl/display/DenoiseNode.js +1 -1
  79. package/examples/jsm/tsl/display/DepthOfFieldNode.js +1 -1
  80. package/examples/jsm/tsl/display/DotScreenNode.js +1 -1
  81. package/examples/jsm/tsl/display/FXAANode.js +2 -2
  82. package/examples/jsm/tsl/display/GTAONode.js +2 -2
  83. package/examples/jsm/tsl/display/GaussianBlurNode.js +11 -2
  84. package/examples/jsm/tsl/display/GodraysNode.js +624 -0
  85. package/examples/jsm/tsl/display/LensflareNode.js +1 -1
  86. package/examples/jsm/tsl/display/Lut3DNode.js +1 -1
  87. package/examples/jsm/tsl/display/OutlineNode.js +3 -3
  88. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +2 -2
  89. package/examples/jsm/tsl/display/PixelationPassNode.js +5 -5
  90. package/examples/jsm/tsl/display/RGBShiftNode.js +2 -2
  91. package/examples/jsm/tsl/display/RetroPassNode.js +263 -0
  92. package/examples/jsm/tsl/display/SMAANode.js +2 -2
  93. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -2
  94. package/examples/jsm/tsl/display/SSGINode.js +2 -2
  95. package/examples/jsm/tsl/display/SSRNode.js +7 -7
  96. package/examples/jsm/tsl/display/SSSNode.js +2 -2
  97. package/examples/jsm/tsl/display/Shape.js +29 -0
  98. package/examples/jsm/tsl/display/SobelOperatorNode.js +2 -2
  99. package/examples/jsm/tsl/display/StereoPassNode.js +1 -2
  100. package/examples/jsm/tsl/display/TRAANode.js +9 -12
  101. package/examples/jsm/tsl/display/TransitionNode.js +1 -1
  102. package/examples/jsm/tsl/display/depthAwareBlend.js +80 -0
  103. package/examples/jsm/tsl/math/Bayer.js +40 -1
  104. package/examples/jsm/utils/LDrawUtils.js +1 -1
  105. package/package.json +11 -19
  106. package/src/Three.Core.js +1 -1
  107. package/src/Three.TSL.js +5 -9
  108. package/src/Three.WebGPU.Nodes.js +2 -0
  109. package/src/Three.WebGPU.js +3 -0
  110. package/src/Three.js +1 -0
  111. package/src/animation/AnimationAction.js +1 -1
  112. package/src/animation/AnimationClip.js +1 -1
  113. package/src/animation/AnimationMixer.js +6 -0
  114. package/src/animation/KeyframeTrack.js +46 -7
  115. package/src/animation/PropertyMixer.js +4 -4
  116. package/src/audio/Audio.js +1 -1
  117. package/src/audio/AudioListener.js +5 -3
  118. package/src/cameras/Camera.js +32 -2
  119. package/src/cameras/CubeCamera.js +20 -0
  120. package/src/constants.js +30 -1
  121. package/src/core/Clock.js +7 -0
  122. package/src/core/Object3D.js +56 -4
  123. package/src/core/RenderTarget.js +3 -4
  124. package/src/extras/PMREMGenerator.js +4 -8
  125. package/src/geometries/TorusGeometry.js +8 -3
  126. package/src/helpers/CameraHelper.js +3 -0
  127. package/src/helpers/DirectionalLightHelper.js +4 -1
  128. package/src/helpers/HemisphereLightHelper.js +3 -0
  129. package/src/helpers/PointLightHelper.js +0 -24
  130. package/src/helpers/SpotLightHelper.js +3 -0
  131. package/src/lights/LightShadow.js +15 -3
  132. package/src/lights/webgpu/IESSpotLight.js +2 -1
  133. package/src/loaders/Cache.js +28 -0
  134. package/src/loaders/FileLoader.js +1 -1
  135. package/src/loaders/ImageBitmapLoader.js +8 -3
  136. package/src/loaders/Loader.js +6 -0
  137. package/src/loaders/ObjectLoader.js +18 -1
  138. package/src/materials/MeshLambertMaterial.js +9 -0
  139. package/src/materials/MeshPhongMaterial.js +9 -0
  140. package/src/materials/nodes/Line2NodeMaterial.js +5 -5
  141. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +2 -0
  142. package/src/materials/nodes/NodeMaterial.js +15 -24
  143. package/src/materials/nodes/manager/NodeMaterialObserver.js +9 -3
  144. package/src/math/Line3.js +3 -5
  145. package/src/math/MathUtils.js +10 -10
  146. package/src/math/Matrix4.js +35 -26
  147. package/src/math/Quaternion.js +3 -29
  148. package/src/math/Vector3.js +3 -3
  149. package/src/math/interpolants/BezierInterpolant.js +108 -0
  150. package/src/nodes/Nodes.js +87 -68
  151. package/src/nodes/TSL.js +2 -5
  152. package/src/nodes/accessors/Arrays.js +1 -1
  153. package/src/nodes/accessors/Bitangent.js +5 -5
  154. package/src/nodes/accessors/BufferAttributeNode.js +1 -1
  155. package/src/nodes/accessors/Camera.js +149 -28
  156. package/src/nodes/accessors/InstanceNode.js +105 -40
  157. package/src/nodes/accessors/Normal.js +9 -9
  158. package/src/nodes/accessors/Position.js +34 -2
  159. package/src/nodes/accessors/SceneProperties.js +53 -0
  160. package/src/nodes/accessors/SkinningNode.js +12 -24
  161. package/src/nodes/accessors/StorageBufferNode.js +0 -19
  162. package/src/nodes/accessors/StorageTextureNode.js +37 -1
  163. package/src/nodes/accessors/Tangent.js +3 -3
  164. package/src/nodes/accessors/Texture3DNode.js +6 -34
  165. package/src/nodes/accessors/TextureNode.js +58 -22
  166. package/src/nodes/accessors/UniformArrayNode.js +2 -0
  167. package/src/nodes/core/MRTNode.js +48 -2
  168. package/src/nodes/core/Node.js +29 -3
  169. package/src/nodes/core/NodeBuilder.js +115 -40
  170. package/src/nodes/core/NodeError.js +28 -0
  171. package/src/nodes/core/NodeUtils.js +5 -3
  172. package/src/nodes/core/OutputStructNode.js +12 -10
  173. package/src/nodes/core/ParameterNode.js +2 -1
  174. package/src/nodes/core/StackNode.js +9 -8
  175. package/src/nodes/core/StackTrace.js +139 -0
  176. package/src/nodes/core/StructNode.js +15 -0
  177. package/src/nodes/core/SubBuildNode.js +1 -1
  178. package/src/nodes/core/UniformNode.js +2 -1
  179. package/src/nodes/core/VarNode.js +1 -1
  180. package/src/nodes/core/VaryingNode.js +1 -18
  181. package/src/nodes/display/BlendModes.js +0 -64
  182. package/src/nodes/display/ColorAdjustment.js +17 -0
  183. package/src/nodes/display/ColorSpaceNode.js +3 -3
  184. package/src/nodes/display/NormalMapNode.js +2 -2
  185. package/src/nodes/display/PassNode.js +21 -2
  186. package/src/nodes/display/RenderOutputNode.js +3 -3
  187. package/src/nodes/display/ScreenNode.js +2 -1
  188. package/src/nodes/display/ToneMappingNode.js +1 -1
  189. package/src/nodes/display/ToonOutlinePassNode.js +2 -2
  190. package/src/nodes/display/ViewportDepthNode.js +52 -4
  191. package/src/nodes/display/ViewportTextureNode.js +21 -4
  192. package/src/nodes/fog/Fog.js +18 -35
  193. package/src/nodes/functions/PhysicalLightingModel.js +25 -3
  194. package/src/nodes/geometry/RangeNode.js +4 -2
  195. package/src/nodes/gpgpu/ComputeNode.js +5 -4
  196. package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -1
  197. package/src/nodes/lighting/EnvironmentNode.js +28 -3
  198. package/src/nodes/lighting/PointShadowNode.js +24 -12
  199. package/src/nodes/lighting/ShadowFilterNode.js +15 -43
  200. package/src/nodes/lighting/ShadowNode.js +54 -32
  201. package/src/nodes/math/ConditionalNode.js +2 -2
  202. package/src/nodes/math/MathNode.js +3 -40
  203. package/src/nodes/math/OperatorNode.js +2 -1
  204. package/src/nodes/pmrem/PMREMUtils.js +9 -15
  205. package/src/nodes/tsl/TSLCore.js +13 -10
  206. package/src/nodes/utils/DebugNode.js +11 -11
  207. package/src/nodes/utils/JoinNode.js +2 -2
  208. package/src/nodes/utils/LoopNode.js +1 -1
  209. package/src/nodes/utils/MemberNode.js +1 -1
  210. package/src/nodes/utils/RTTNode.js +1 -1
  211. package/src/nodes/utils/ReflectorNode.js +2 -3
  212. package/src/nodes/utils/SpriteSheetUV.js +35 -0
  213. package/src/nodes/utils/UVUtils.js +4 -2
  214. package/src/objects/BatchedMesh.js +22 -12
  215. package/src/objects/InstancedMesh.js +11 -0
  216. package/src/renderers/WebGLRenderer.js +34 -60
  217. package/src/renderers/common/Backend.js +21 -0
  218. package/src/renderers/common/Background.js +7 -4
  219. package/src/renderers/common/BindGroup.js +1 -9
  220. package/src/renderers/common/Bindings.js +20 -5
  221. package/src/renderers/common/BlendMode.js +143 -0
  222. package/src/renderers/common/BundleGroup.js +1 -1
  223. package/src/renderers/common/CubeRenderTarget.js +50 -6
  224. package/src/renderers/common/Geometries.js +17 -3
  225. package/src/renderers/common/Lighting.js +5 -21
  226. package/src/renderers/common/Pipelines.js +4 -4
  227. package/src/renderers/common/PostProcessing.js +8 -206
  228. package/src/renderers/common/RenderBundles.js +2 -1
  229. package/src/renderers/common/RenderContext.js +16 -0
  230. package/src/renderers/common/RenderContexts.js +33 -56
  231. package/src/renderers/common/RenderLists.js +2 -1
  232. package/src/renderers/common/RenderObject.js +2 -3
  233. package/src/renderers/common/RenderObjectPipeline.js +40 -0
  234. package/src/renderers/common/RenderObjects.js +18 -2
  235. package/src/renderers/common/RenderPipeline.js +203 -17
  236. package/src/renderers/common/Renderer.js +207 -40
  237. package/src/renderers/common/Sampler.js +4 -4
  238. package/src/renderers/common/StorageBuffer.js +13 -1
  239. package/src/renderers/common/Textures.js +16 -0
  240. package/src/renderers/common/TimestampQueryPool.js +5 -3
  241. package/src/renderers/common/Uniform.js +8 -0
  242. package/src/renderers/common/UniformsGroup.js +60 -0
  243. package/src/renderers/common/XRManager.js +2 -2
  244. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  245. package/src/renderers/common/nodes/{Nodes.js → NodeManager.js} +18 -6
  246. package/src/renderers/common/nodes/NodeStorageBuffer.js +13 -2
  247. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +2 -2
  248. package/src/renderers/shaders/ShaderChunk/color_fragment.glsl.js +1 -5
  249. package/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js +1 -5
  250. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -5
  251. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +8 -10
  252. package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +4 -4
  253. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +7 -11
  254. package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +6 -0
  255. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +6 -2
  256. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +23 -1
  257. package/src/renderers/shaders/ShaderChunk/packing.glsl.js +20 -4
  258. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +55 -24
  259. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -0
  260. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -0
  261. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -0
  262. package/src/renderers/shaders/ShaderLib.js +4 -2
  263. package/src/renderers/shaders/UniformsLib.js +0 -3
  264. package/src/renderers/webgl/WebGLBackground.js +2 -2
  265. package/src/renderers/webgl/WebGLBindingStates.js +99 -27
  266. package/src/renderers/webgl/WebGLEnvironments.js +228 -0
  267. package/src/renderers/webgl/WebGLGeometries.js +10 -7
  268. package/src/renderers/webgl/WebGLMaterials.js +12 -0
  269. package/src/renderers/webgl/WebGLObjects.js +3 -1
  270. package/src/renderers/webgl/WebGLProgram.js +2 -2
  271. package/src/renderers/webgl/WebGLPrograms.js +10 -4
  272. package/src/renderers/webgl/WebGLRenderLists.js +15 -0
  273. package/src/renderers/webgl/WebGLShadowMap.js +5 -4
  274. package/src/renderers/webgl/WebGLState.js +12 -17
  275. package/src/renderers/webgl-fallback/WebGLBackend.js +71 -7
  276. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +98 -29
  277. package/src/renderers/webgl-fallback/utils/WebGLState.js +168 -7
  278. package/src/renderers/webgpu/WebGPUBackend.js +58 -9
  279. package/src/renderers/webgpu/WebGPURenderer.js +1 -0
  280. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +257 -45
  281. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +8 -19
  282. package/src/renderers/webgpu/utils/WebGPUConstants.js +1 -1
  283. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +56 -31
  284. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +152 -200
  285. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +25 -25
  286. package/src/renderers/webgpu/utils/WebGPUUtils.js +10 -6
  287. package/src/renderers/webxr/WebXRManager.js +2 -2
  288. package/src/textures/Texture.js +2 -2
  289. package/src/utils.js +246 -3
  290. package/examples/jsm/materials/MeshGouraudMaterial.js +0 -433
  291. package/examples/jsm/materials/MeshPostProcessingMaterial.js +0 -167
  292. package/examples/jsm/shaders/GodRaysShader.js +0 -333
  293. package/src/nodes/accessors/SceneNode.js +0 -145
  294. package/src/nodes/code/ScriptableNode.js +0 -726
  295. package/src/nodes/code/ScriptableValueNode.js +0 -253
  296. package/src/nodes/display/PosterizeNode.js +0 -65
  297. package/src/nodes/utils/SpriteSheetUVNode.js +0 -90
  298. package/src/renderers/webgl/WebGLCubeMaps.js +0 -99
  299. package/src/renderers/webgl/WebGLCubeUVMaps.js +0 -134
@@ -23,7 +23,8 @@ import {
23
23
  RepeatWrapping,
24
24
  SRGBColorSpace,
25
25
  TextureLoader,
26
- Vector2
26
+ Vector2,
27
+ Vector3
27
28
  } from 'three';
28
29
 
29
30
  import { IFFParser } from './lwo/IFFParser.js';
@@ -185,8 +186,6 @@ class LWOTreeParser {
185
186
 
186
187
  } );
187
188
 
188
- this.applyPivots( finalMeshes );
189
-
190
189
  return finalMeshes;
191
190
 
192
191
  }
@@ -204,38 +203,14 @@ class LWOTreeParser {
204
203
  if ( layer.name ) mesh.name = layer.name;
205
204
  else mesh.name = this.defaultLayerName + '_layer_' + layer.number;
206
205
 
207
- mesh.userData.pivot = layer.pivot;
208
-
209
- return mesh;
210
-
211
- }
212
-
213
- // TODO: may need to be reversed in z to convert LWO to three.js coordinates
214
- applyPivots( meshes ) {
215
-
216
- meshes.forEach( function ( mesh ) {
217
-
218
- mesh.traverse( function ( child ) {
219
-
220
- const pivot = child.userData.pivot;
221
-
222
- child.position.x += pivot[ 0 ];
223
- child.position.y += pivot[ 1 ];
224
- child.position.z += pivot[ 2 ];
206
+ const pivot = layer.pivot;
207
+ if ( pivot[ 0 ] !== 0 || pivot[ 1 ] !== 0 || pivot[ 2 ] !== 0 ) {
225
208
 
226
- if ( child.parent ) {
209
+ mesh.pivot = new Vector3( pivot[ 0 ], pivot[ 1 ], pivot[ 2 ] );
227
210
 
228
- const parentPivot = child.parent.userData.pivot;
229
-
230
- child.position.x -= parentPivot[ 0 ];
231
- child.position.y -= parentPivot[ 1 ];
232
- child.position.z -= parentPivot[ 2 ];
233
-
234
- }
235
-
236
- } );
211
+ }
237
212
 
238
- } );
213
+ return mesh;
239
214
 
240
215
  }
241
216
 
@@ -813,13 +788,6 @@ class GeometryParser {
813
788
  this.parseUVs( geometry, layer );
814
789
  this.parseMorphTargets( geometry, layer );
815
790
 
816
- // TODO: z may need to be reversed to account for coordinate system change
817
- geometry.translate( - layer.pivot[ 0 ], - layer.pivot[ 1 ], - layer.pivot[ 2 ] );
818
-
819
- // let userData = geometry.userData;
820
- // geometry = geometry.toNonIndexed()
821
- // geometry.userData = userData;
822
-
823
791
  return geometry;
824
792
 
825
793
  }
@@ -4,7 +4,7 @@ import {
4
4
  Matrix4,
5
5
  Vector3
6
6
  } from 'three';
7
- import * as fflate from '../libs/fflate.module.js';
7
+ import { gunzipSync } from '../libs/fflate.module.js';
8
8
  import { Volume } from '../misc/Volume.js';
9
9
 
10
10
  /**
@@ -356,7 +356,7 @@ class NRRDLoader extends Loader {
356
356
 
357
357
  // we need to decompress the datastream
358
358
  // here we start the unzipping and get a typed Uint8Array back
359
- _data = fflate.gunzipSync( new Uint8Array( _data ) );
359
+ _data = gunzipSync( new Uint8Array( _data ) );
360
360
 
361
361
  } else if ( headerObject.encoding === 'ascii' || headerObject.encoding === 'text' || headerObject.encoding === 'txt' || headerObject.encoding === 'hex' ) {
362
362
 
@@ -518,7 +518,7 @@ class PCDLoader extends Loader {
518
518
  if ( offset.label !== undefined ) {
519
519
 
520
520
  const labelIndex = PCDheader.fields.indexOf( 'label' );
521
- label.push( dataview.getInt32( ( PCDheader.points * offset.label ) + PCDheader.size[ labelIndex ] * i, this.littleEndian ) );
521
+ label.push( this._getDataView( dataview, ( PCDheader.points * offset.label ) + PCDheader.size[ labelIndex ] * i, PCDheader.type[ labelIndex ], PCDheader.size[ labelIndex ] ) );
522
522
 
523
523
  }
524
524
 
@@ -578,7 +578,8 @@ class PCDLoader extends Loader {
578
578
 
579
579
  if ( offset.label !== undefined ) {
580
580
 
581
- label.push( dataview.getInt32( row + offset.label, this.littleEndian ) );
581
+ const labelIndex = PCDheader.fields.indexOf( 'label' );
582
+ label.push( this._getDataView( dataview, row + offset.label, PCDheader.type[ labelIndex ], PCDheader.size[ labelIndex ] ) );
582
583
 
583
584
  }
584
585
 
@@ -3,18 +3,20 @@ import {
3
3
  Loader
4
4
  } from 'three';
5
5
 
6
- import * as fflate from '../libs/fflate.module.js';
6
+ import { unzipSync } from '../libs/fflate.module.js';
7
7
  import { USDAParser } from './usd/USDAParser.js';
8
8
  import { USDCParser } from './usd/USDCParser.js';
9
+ import { USDComposer } from './usd/USDComposer.js';
9
10
 
10
11
  /**
11
- * A loader for the USDZ format.
12
+ * A loader for the USD format (USD, USDA, USDC, USDZ).
12
13
  *
13
- * USDZ files that use USDC internally are not yet supported, only USDA.
14
+ * Supports both ASCII (USDA) and binary (USDC) USD files, as well as
15
+ * USDZ archives containing either format.
14
16
  *
15
17
  * ```js
16
- * const loader = new USDZLoader();
17
- * const model = await loader.loadAsync( 'saeukkang.usdz' );
18
+ * const loader = new USDLoader();
19
+ * const model = await loader.loadAsync( 'model.usdz' );
18
20
  * scene.add( model );
19
21
  * ```
20
22
  *
@@ -88,34 +90,60 @@ class USDLoader extends Loader {
88
90
 
89
91
  const usda = new USDAParser();
90
92
  const usdc = new USDCParser();
93
+ const textDecoder = new TextDecoder();
94
+
95
+ function toArrayBuffer( data ) {
96
+
97
+ if ( data instanceof ArrayBuffer ) return data;
98
+
99
+ if ( data.byteOffset === 0 && data.byteLength === data.buffer.byteLength ) {
100
+
101
+ return data.buffer;
102
+
103
+ }
104
+
105
+ return data.buffer.slice( data.byteOffset, data.byteOffset + data.byteLength );
106
+
107
+ }
108
+
109
+ function getLowercaseExtension( filename ) {
110
+
111
+ const lastDot = filename.lastIndexOf( '.' );
112
+ if ( lastDot < 0 ) return '';
113
+
114
+ const lastSlash = filename.lastIndexOf( '/' );
115
+ if ( lastSlash > lastDot ) return '';
116
+
117
+ return filename.slice( lastDot + 1 ).toLowerCase();
118
+
119
+ }
91
120
 
92
121
  function parseAssets( zip ) {
93
122
 
94
123
  const data = {};
95
- const loader = new FileLoader();
96
- loader.setResponseType( 'arraybuffer' );
97
124
 
98
125
  for ( const filename in zip ) {
99
126
 
100
- if ( filename.endsWith( 'png' ) ) {
127
+ const fileBytes = zip[ filename ];
128
+ const ext = getLowercaseExtension( filename );
101
129
 
102
- const blob = new Blob( [ zip[ filename ] ], { type: 'image/png' } );
103
- data[ filename ] = URL.createObjectURL( blob );
130
+ if ( ext === 'png' || ext === 'jpg' || ext === 'jpeg' || ext === 'avif' ) {
104
131
 
105
- }
132
+ // Keep raw image bytes and create object URLs lazily in USDComposer.
133
+ data[ filename ] = fileBytes;
134
+ continue;
106
135
 
107
- if ( filename.endsWith( 'usd' ) || filename.endsWith( 'usda' ) || filename.endsWith( 'usdc' ) ) {
136
+ }
108
137
 
109
- if ( isCrateFile( zip[ filename ] ) ) {
138
+ if ( ext !== 'usd' && ext !== 'usda' && ext !== 'usdc' ) continue;
110
139
 
111
- data[ filename ] = usdc.parse( zip[ filename ].buffer, data );
140
+ if ( isCrateFile( fileBytes ) ) {
112
141
 
113
- } else {
142
+ data[ filename ] = usdc.parseData( toArrayBuffer( fileBytes ) );
114
143
 
115
- const text = fflate.strFromU8( zip[ filename ] );
116
- data[ filename ] = usda.parseText( text );
144
+ } else {
117
145
 
118
- }
146
+ data[ filename ] = usda.parseData( textDecoder.decode( fileBytes ) );
119
147
 
120
148
  }
121
149
 
@@ -128,10 +156,9 @@ class USDLoader extends Loader {
128
156
  function isCrateFile( buffer ) {
129
157
 
130
158
  const crateHeader = new Uint8Array( [ 0x50, 0x58, 0x52, 0x2D, 0x55, 0x53, 0x44, 0x43 ] ); // PXR-USDC
159
+ const view = buffer instanceof Uint8Array ? buffer : new Uint8Array( buffer );
131
160
 
132
- if ( buffer.byteLength < crateHeader.length ) return false;
133
-
134
- const view = new Uint8Array( buffer, 0, crateHeader.length );
161
+ if ( view.byteLength < crateHeader.length ) return false;
135
162
 
136
163
  for ( let i = 0; i < crateHeader.length; i ++ ) {
137
164
 
@@ -145,26 +172,30 @@ class USDLoader extends Loader {
145
172
 
146
173
  function findUSD( zip ) {
147
174
 
148
- if ( zip.length < 1 ) return undefined;
175
+ const fileNames = Object.keys( zip );
176
+ if ( fileNames.length < 1 ) return { file: undefined, filename: '', basePath: '' };
149
177
 
150
- const firstFileName = Object.keys( zip )[ 0 ];
178
+ const firstFileName = fileNames[ 0 ];
179
+ const ext = getLowercaseExtension( firstFileName );
151
180
  let isCrate = false;
152
181
 
153
- // As per the USD specification, the first entry in the zip archive is used as the main file ("UsdStage").
182
+ const lastSlash = firstFileName.lastIndexOf( '/' );
183
+ const basePath = lastSlash >= 0 ? firstFileName.slice( 0, lastSlash ) : '';
184
+
185
+ // Per AOUSD core spec v1.0.1 section 16.4.1.2, the first ZIP entry is the root layer.
154
186
  // ASCII files can end in either .usda or .usd.
155
- // See https://openusd.org/release/spec_usdz.html#layout
156
- if ( firstFileName.endsWith( 'usda' ) ) return zip[ firstFileName ];
187
+ if ( ext === 'usda' ) return { file: zip[ firstFileName ], filename: firstFileName, basePath };
157
188
 
158
- if ( firstFileName.endsWith( 'usdc' ) ) {
189
+ if ( ext === 'usdc' ) {
159
190
 
160
191
  isCrate = true;
161
192
 
162
- } else if ( firstFileName.endsWith( 'usd' ) ) {
193
+ } else if ( ext === 'usd' ) {
163
194
 
164
195
  // If this is not a crate file, we assume it is a plain USDA file.
165
196
  if ( ! isCrateFile( zip[ firstFileName ] ) ) {
166
197
 
167
- return zip[ firstFileName ];
198
+ return { file: zip[ firstFileName ], filename: firstFileName, basePath };
168
199
 
169
200
  } else {
170
201
 
@@ -176,41 +207,70 @@ class USDLoader extends Loader {
176
207
 
177
208
  if ( isCrate ) {
178
209
 
179
- return zip[ firstFileName ];
210
+ return { file: zip[ firstFileName ], filename: firstFileName, basePath };
180
211
 
181
212
  }
182
213
 
214
+ return { file: undefined, filename: '', basePath: '' };
215
+
183
216
  }
184
217
 
185
- // USDA
218
+ const scope = this;
219
+
220
+ // USDA (standalone)
186
221
 
187
222
  if ( typeof buffer === 'string' ) {
188
223
 
189
- return usda.parse( buffer, {} );
224
+ const composer = new USDComposer( scope.manager );
225
+ const data = usda.parseData( buffer );
226
+ return composer.compose( data, {} );
190
227
 
191
228
  }
192
229
 
193
- // USDC
230
+ // USDC (standalone)
194
231
 
195
232
  if ( isCrateFile( buffer ) ) {
196
233
 
197
- return usdc.parse( buffer );
234
+ const composer = new USDComposer( scope.manager );
235
+ const data = usdc.parseData( toArrayBuffer( buffer ) );
236
+ return composer.compose( data, {} );
198
237
 
199
238
  }
200
239
 
240
+ const bytes = new Uint8Array( buffer );
241
+
201
242
  // USDZ
202
243
 
203
- const zip = fflate.unzipSync( new Uint8Array( buffer ) );
244
+ if ( bytes[ 0 ] === 0x50 && bytes[ 1 ] === 0x4B ) {
245
+
246
+ const zip = unzipSync( bytes );
247
+ const assets = parseAssets( zip );
248
+ const { file, filename, basePath } = findUSD( zip );
204
249
 
205
- const assets = parseAssets( zip );
250
+ if ( ! file ) {
206
251
 
207
- // console.log( assets );
252
+ throw new Error( 'USDLoader: Invalid USDZ package. The first ZIP entry must be a USD layer (.usd/.usda/.usdc).' );
208
253
 
209
- const file = findUSD( zip );
254
+ }
255
+
256
+ const composer = new USDComposer( scope.manager );
257
+ const data = assets[ filename ];
258
+ if ( ! data ) {
259
+
260
+ throw new Error( 'USDLoader: Failed to parse root layer "' + filename + '".' );
261
+
262
+ }
263
+
264
+ return composer.compose( data, assets, {}, basePath );
265
+
266
+ }
210
267
 
211
- const text = fflate.strFromU8( file );
268
+ // USDA (standalone, as ArrayBuffer)
212
269
 
213
- return usda.parse( text, assets );
270
+ const composer = new USDComposer( scope.manager );
271
+ const text = textDecoder.decode( bytes );
272
+ const data = usda.parseData( text );
273
+ return composer.compose( data, {} );
214
274
 
215
275
  }
216
276
 
@@ -18,11 +18,12 @@ import {
18
18
  * Short format brief:
19
19
  *
20
20
  * [JPEG headers]
21
- * [XMP metadata describing the MPF container and *both* SDR and gainmap images]
21
+ * [Metadata describing the MPF container and both SDR and gainmap images]
22
+ * - XMP metadata (legacy format)
23
+ * - ISO 21496-1 metadata (current standard)
22
24
  * [Optional metadata] [EXIF] [ICC Profile]
23
25
  * [SDR image]
24
- * [XMP metadata describing only the gainmap image]
25
- * [Gainmap image]
26
+ * [Gainmap image with metadata]
26
27
  *
27
28
  * Each section is separated by a 0xFFXX byte followed by a descriptor byte (0xFFE0, 0xFFE1, 0xFFE2.)
28
29
  * Binary image storages are prefixed with a unique 0xFFD8 16-bit descriptor.
@@ -45,7 +46,8 @@ for ( let i = 0; i < 1024; i ++ ) {
45
46
  *
46
47
  * Current feature set:
47
48
  * - JPEG headers (required)
48
- * - XMP metadata (required)
49
+ * - XMP metadata (legacy format, supported)
50
+ * - ISO 21496-1 metadata (current standard, supported)
49
51
  * - XMP validation (not implemented)
50
52
  * - EXIF profile (not implemented)
51
53
  * - ICC profile (not implemented)
@@ -109,7 +111,7 @@ class UltraHDRLoader extends Loader {
109
111
  */
110
112
  parse( buffer, onLoad ) {
111
113
 
112
- const xmpMetadata = {
114
+ const metadata = {
113
115
  version: null,
114
116
  baseRenditionIsHDR: null,
115
117
  gainMapMin: null,
@@ -197,18 +199,47 @@ class UltraHDRLoader extends Loader {
197
199
  /* JPEG Header - no useful information */
198
200
  } else if ( sectionType === 0xe1 ) {
199
201
 
200
- /* XMP Metadata */
202
+ /* APP1: XMP Metadata */
201
203
 
202
204
  this._parseXMPMetadata(
203
205
  textDecoder.decode( new Uint8Array( section ) ),
204
- xmpMetadata
206
+ metadata
205
207
  );
206
208
 
207
209
  } else if ( sectionType === 0xe2 ) {
208
210
 
209
- /* Data Sections - MPF / EXIF / ICC Profile */
211
+ /* APP2: Data Sections - MPF / ICC Profile / ISO 21496-1 Metadata */
210
212
 
211
213
  const sectionData = new DataView( section.buffer, section.byteOffset + 2, section.byteLength - 2 );
214
+
215
+ // Check for ISO 21496-1 namespace: "urn:iso:std:iso:ts:21496:-1\0"
216
+ const isoNameSpace = 'urn:iso:std:iso:ts:21496:-1\0';
217
+ if ( section.byteLength >= isoNameSpace.length + 2 ) {
218
+
219
+ let isISO = true;
220
+ for ( let j = 0; j < isoNameSpace.length; j ++ ) {
221
+
222
+ if ( section[ 2 + j ] !== isoNameSpace.charCodeAt( j ) ) {
223
+
224
+ isISO = false;
225
+ break;
226
+
227
+ }
228
+
229
+ }
230
+
231
+ if ( isISO ) {
232
+
233
+ // Parse ISO 21496-1 metadata
234
+ const isoData = section.subarray( 2 + isoNameSpace.length );
235
+ this._parseISOMetadata( isoData, metadata );
236
+ continue;
237
+
238
+ }
239
+
240
+ }
241
+
242
+ // Check for MPF
212
243
  const sectionHeader = sectionData.getUint32( 2, false );
213
244
 
214
245
  if ( sectionHeader === 0x4d504600 ) {
@@ -277,7 +308,8 @@ class UltraHDRLoader extends Loader {
277
308
  }
278
309
 
279
310
  /* Minimal sufficient validation - https://developer.android.com/media/platform/hdr-image-format#signal_of_the_format */
280
- if ( ! xmpMetadata.version ) {
311
+ // Version can come from either XMP or ISO metadata
312
+ if ( ! metadata.version ) {
281
313
 
282
314
  throw new Error( 'THREE.UltraHDRLoader: Not a valid UltraHDR image' );
283
315
 
@@ -286,7 +318,7 @@ class UltraHDRLoader extends Loader {
286
318
  if ( primaryImage && gainmapImage ) {
287
319
 
288
320
  this._applyGainmapToSDR(
289
- xmpMetadata,
321
+ metadata,
290
322
  primaryImage,
291
323
  gainmapImage,
292
324
  ( hdrBuffer, width, height ) => {
@@ -315,6 +347,126 @@ class UltraHDRLoader extends Loader {
315
347
 
316
348
  }
317
349
 
350
+ /**
351
+ * Parses ISO 21496-1 gainmap metadata from binary data.
352
+ *
353
+ * @private
354
+ * @param {Uint8Array} data - The binary ISO metadata.
355
+ * @param {Object} metadata - The metadata object to populate.
356
+ */
357
+ _parseISOMetadata( data, metadata ) {
358
+
359
+ const view = new DataView( data.buffer, data.byteOffset, data.byteLength );
360
+
361
+ // Skip minimum version (2 bytes) and writer version (2 bytes)
362
+ let offset = 4;
363
+
364
+ // Read flags (1 byte)
365
+ const flags = view.getUint8( offset );
366
+ offset += 1;
367
+
368
+ const backwardDirection = ( flags & 0x4 ) !== 0;
369
+ const useCommonDenominator = ( flags & 0x8 ) !== 0;
370
+
371
+ let gainMapMin, gainMapMax, gamma, offsetSDR, offsetHDR, hdrCapacityMin, hdrCapacityMax;
372
+
373
+ if ( useCommonDenominator ) {
374
+
375
+ // Read common denominator (4 bytes, unsigned)
376
+ const commonDenominator = view.getUint32( offset, false );
377
+ offset += 4;
378
+
379
+ // Read baseHdrHeadroom (4 bytes, unsigned)
380
+ const baseHdrHeadroomN = view.getUint32( offset, false );
381
+ offset += 4;
382
+ hdrCapacityMin = Math.log2( baseHdrHeadroomN / commonDenominator );
383
+
384
+ // Read alternateHdrHeadroom (4 bytes, unsigned)
385
+ const alternateHdrHeadroomN = view.getUint32( offset, false );
386
+ offset += 4;
387
+ hdrCapacityMax = Math.log2( alternateHdrHeadroomN / commonDenominator );
388
+
389
+ // Read first channel (or only channel) parameters
390
+ const gainMapMinN = view.getInt32( offset, false );
391
+ offset += 4;
392
+ gainMapMin = gainMapMinN / commonDenominator;
393
+
394
+ const gainMapMaxN = view.getInt32( offset, false );
395
+ offset += 4;
396
+ gainMapMax = gainMapMaxN / commonDenominator;
397
+
398
+ const gammaN = view.getUint32( offset, false );
399
+ offset += 4;
400
+ gamma = gammaN / commonDenominator;
401
+
402
+ const offsetSDRN = view.getInt32( offset, false );
403
+ offset += 4;
404
+ offsetSDR = ( offsetSDRN / commonDenominator ) * 255.0;
405
+
406
+ const offsetHDRN = view.getInt32( offset, false );
407
+ offsetHDR = ( offsetHDRN / commonDenominator ) * 255.0;
408
+
409
+ } else {
410
+
411
+ // Read baseHdrHeadroom numerator and denominator
412
+ const baseHdrHeadroomN = view.getUint32( offset, false );
413
+ offset += 4;
414
+ const baseHdrHeadroomD = view.getUint32( offset, false );
415
+ offset += 4;
416
+ hdrCapacityMin = Math.log2( baseHdrHeadroomN / baseHdrHeadroomD );
417
+
418
+ // Read alternateHdrHeadroom numerator and denominator
419
+ const alternateHdrHeadroomN = view.getUint32( offset, false );
420
+ offset += 4;
421
+ const alternateHdrHeadroomD = view.getUint32( offset, false );
422
+ offset += 4;
423
+ hdrCapacityMax = Math.log2( alternateHdrHeadroomN / alternateHdrHeadroomD );
424
+
425
+ // Read first channel parameters
426
+ const gainMapMinN = view.getInt32( offset, false );
427
+ offset += 4;
428
+ const gainMapMinD = view.getUint32( offset, false );
429
+ offset += 4;
430
+ gainMapMin = gainMapMinN / gainMapMinD;
431
+
432
+ const gainMapMaxN = view.getInt32( offset, false );
433
+ offset += 4;
434
+ const gainMapMaxD = view.getUint32( offset, false );
435
+ offset += 4;
436
+ gainMapMax = gainMapMaxN / gainMapMaxD;
437
+
438
+ const gammaN = view.getUint32( offset, false );
439
+ offset += 4;
440
+ const gammaD = view.getUint32( offset, false );
441
+ offset += 4;
442
+ gamma = gammaN / gammaD;
443
+
444
+ const offsetSDRN = view.getInt32( offset, false );
445
+ offset += 4;
446
+ const offsetSDRD = view.getUint32( offset, false );
447
+ offset += 4;
448
+ offsetSDR = ( offsetSDRN / offsetSDRD ) * 255.0;
449
+
450
+ const offsetHDRN = view.getInt32( offset, false );
451
+ offset += 4;
452
+ const offsetHDRD = view.getUint32( offset, false );
453
+ offsetHDR = ( offsetHDRN / offsetHDRD ) * 255.0;
454
+
455
+ }
456
+
457
+ // Convert log2 values to linear
458
+ metadata.version = '1.0'; // ISO standard doesn't encode version string, use default
459
+ metadata.baseRenditionIsHDR = backwardDirection;
460
+ metadata.gainMapMin = gainMapMin;
461
+ metadata.gainMapMax = gainMapMax;
462
+ metadata.gamma = gamma;
463
+ metadata.offsetSDR = offsetSDR;
464
+ metadata.offsetHDR = offsetHDR;
465
+ metadata.hdrCapacityMin = hdrCapacityMin;
466
+ metadata.hdrCapacityMax = hdrCapacityMax;
467
+
468
+ }
469
+
318
470
  /**
319
471
  * Starts loading from the given URL and passes the loaded Ultra HDR texture
320
472
  * to the `onLoad()` callback.
@@ -383,7 +535,7 @@ class UltraHDRLoader extends Loader {
383
535
 
384
536
  }
385
537
 
386
- _parseXMPMetadata( xmpDataString, xmpMetadata ) {
538
+ _parseXMPMetadata( xmpDataString, metadata ) {
387
539
 
388
540
  const domParser = new DOMParser();
389
541
 
@@ -408,28 +560,28 @@ class UltraHDRLoader extends Loader {
408
560
 
409
561
  const [ gainmapNode ] = xmpXml.getElementsByTagName( 'rdf:Description' );
410
562
 
411
- xmpMetadata.version = gainmapNode.getAttribute( 'hdrgm:Version' );
412
- xmpMetadata.baseRenditionIsHDR =
563
+ metadata.version = gainmapNode.getAttribute( 'hdrgm:Version' );
564
+ metadata.baseRenditionIsHDR =
413
565
  gainmapNode.getAttribute( 'hdrgm:BaseRenditionIsHDR' ) === 'True';
414
- xmpMetadata.gainMapMin = parseFloat(
566
+ metadata.gainMapMin = parseFloat(
415
567
  gainmapNode.getAttribute( 'hdrgm:GainMapMin' ) || 0.0
416
568
  );
417
- xmpMetadata.gainMapMax = parseFloat(
569
+ metadata.gainMapMax = parseFloat(
418
570
  gainmapNode.getAttribute( 'hdrgm:GainMapMax' ) || 1.0
419
571
  );
420
- xmpMetadata.gamma = parseFloat(
572
+ metadata.gamma = parseFloat(
421
573
  gainmapNode.getAttribute( 'hdrgm:Gamma' ) || 1.0
422
574
  );
423
- xmpMetadata.offsetSDR = parseFloat(
575
+ metadata.offsetSDR = parseFloat(
424
576
  gainmapNode.getAttribute( 'hdrgm:OffsetSDR' ) / ( 1 / 64 )
425
577
  );
426
- xmpMetadata.offsetHDR = parseFloat(
578
+ metadata.offsetHDR = parseFloat(
427
579
  gainmapNode.getAttribute( 'hdrgm:OffsetHDR' ) / ( 1 / 64 )
428
580
  );
429
- xmpMetadata.hdrCapacityMin = parseFloat(
581
+ metadata.hdrCapacityMin = parseFloat(
430
582
  gainmapNode.getAttribute( 'hdrgm:HDRCapacityMin' ) || 0.0
431
583
  );
432
- xmpMetadata.hdrCapacityMax = parseFloat(
584
+ metadata.hdrCapacityMax = parseFloat(
433
585
  gainmapNode.getAttribute( 'hdrgm:HDRCapacityMax' ) || 1.0
434
586
  );
435
587
 
@@ -459,7 +611,7 @@ class UltraHDRLoader extends Loader {
459
611
  }
460
612
 
461
613
  _applyGainmapToSDR(
462
- xmpMetadata,
614
+ metadata,
463
615
  sdrBuffer,
464
616
  gainmapBuffer,
465
617
  onSuccess,
@@ -527,10 +679,10 @@ class UltraHDRLoader extends Loader {
527
679
  /* HDR Recovery formula - https://developer.android.com/media/platform/hdr-image-format#use_the_gain_map_to_create_adapted_HDR_rendition */
528
680
 
529
681
  /* 1.8 instead of 2 near-perfectly rectifies approximations introduced by precalculated SRGB_TO_LINEAR values */
530
- const maxDisplayBoost = 1.8 ** ( xmpMetadata.hdrCapacityMax * 0.5 );
682
+ const maxDisplayBoost = 1.8 ** ( metadata.hdrCapacityMax * 0.5 );
531
683
  const unclampedWeightFactor =
532
- ( Math.log2( maxDisplayBoost ) - xmpMetadata.hdrCapacityMin ) /
533
- ( xmpMetadata.hdrCapacityMax - xmpMetadata.hdrCapacityMin );
684
+ ( Math.log2( maxDisplayBoost ) - metadata.hdrCapacityMin ) /
685
+ ( metadata.hdrCapacityMax - metadata.hdrCapacityMin );
534
686
  const weightFactor = Math.min(
535
687
  Math.max( unclampedWeightFactor, 0.0 ),
536
688
  1.0
@@ -539,12 +691,12 @@ class UltraHDRLoader extends Loader {
539
691
  const sdrData = sdrImageData.data;
540
692
  const gainmapData = gainmapImageData.data;
541
693
  const dataLength = sdrData.length;
542
- const gainMapMin = xmpMetadata.gainMapMin;
543
- const gainMapMax = xmpMetadata.gainMapMax;
544
- const offsetSDR = xmpMetadata.offsetSDR;
545
- const offsetHDR = xmpMetadata.offsetHDR;
546
- const invGamma = 1.0 / xmpMetadata.gamma;
547
- const useGammaOne = xmpMetadata.gamma === 1.0;
694
+ const gainMapMin = metadata.gainMapMin;
695
+ const gainMapMax = metadata.gainMapMax;
696
+ const offsetSDR = metadata.offsetSDR;
697
+ const offsetHDR = metadata.offsetHDR;
698
+ const invGamma = 1.0 / metadata.gamma;
699
+ const useGammaOne = metadata.gamma === 1.0;
548
700
  const isHalfFloat = this.type === HalfFloatType;
549
701
  const toHalfFloat = DataUtils.toHalfFloat;
550
702
  const srgbToLinear = this._srgbToLinear;