@plastic-software/three 0.181.3 → 0.183.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 (437) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -4
  3. package/build/three.cjs +11330 -10017
  4. package/build/three.core.js +10011 -9493
  5. package/build/three.core.min.js +2 -2
  6. package/build/three.module.js +1414 -631
  7. package/build/three.module.min.js +2 -2
  8. package/build/three.tsl.js +21 -13
  9. package/build/three.tsl.min.js +2 -2
  10. package/build/three.webgpu.js +8007 -5427
  11. package/build/three.webgpu.min.js +2 -2
  12. package/build/three.webgpu.nodes.js +8005 -5426
  13. package/build/three.webgpu.nodes.min.js +2 -2
  14. package/examples/jsm/Addons.js +0 -3
  15. package/examples/jsm/animation/CCDIKSolver.js +2 -2
  16. package/examples/jsm/controls/ArcballControls.js +3 -3
  17. package/examples/jsm/controls/MapControls.js +55 -1
  18. package/examples/jsm/controls/OrbitControls.js +109 -6
  19. package/examples/jsm/controls/TrackballControls.js +6 -6
  20. package/examples/jsm/csm/CSM.js +2 -1
  21. package/examples/jsm/effects/AnaglyphEffect.js +102 -7
  22. package/examples/jsm/environments/ColorEnvironment.js +59 -0
  23. package/examples/jsm/environments/RoomEnvironment.js +3 -0
  24. package/examples/jsm/exporters/EXRExporter.js +1 -1
  25. package/examples/jsm/exporters/GLTFExporter.js +131 -4
  26. package/examples/jsm/exporters/USDZExporter.js +22 -3
  27. package/examples/jsm/geometries/DecalGeometry.js +1 -1
  28. package/examples/jsm/helpers/AnimationPathHelper.js +302 -0
  29. package/examples/jsm/helpers/LightProbeHelperGPU.js +1 -1
  30. package/examples/jsm/helpers/TextureHelperGPU.js +1 -1
  31. package/examples/jsm/helpers/ViewHelper.js +67 -8
  32. package/examples/jsm/inspector/Inspector.js +74 -14
  33. package/examples/jsm/inspector/RendererInspector.js +12 -2
  34. package/examples/jsm/inspector/tabs/Console.js +41 -7
  35. package/examples/jsm/inspector/tabs/Parameters.js +18 -2
  36. package/examples/jsm/inspector/tabs/Performance.js +2 -2
  37. package/examples/jsm/inspector/tabs/Viewer.js +4 -4
  38. package/examples/jsm/inspector/ui/Profiler.js +1836 -31
  39. package/examples/jsm/inspector/ui/Style.js +973 -14
  40. package/examples/jsm/inspector/ui/Tab.js +188 -1
  41. package/examples/jsm/inspector/ui/Values.js +17 -1
  42. package/examples/jsm/libs/meshopt_decoder.module.js +6 -5
  43. package/examples/jsm/lines/LineMaterial.js +6 -0
  44. package/examples/jsm/loaders/3DMLoader.js +5 -4
  45. package/examples/jsm/loaders/3MFLoader.js +2 -2
  46. package/examples/jsm/loaders/AMFLoader.js +2 -2
  47. package/examples/jsm/loaders/ColladaLoader.js +24 -4026
  48. package/examples/jsm/loaders/DRACOLoader.js +5 -5
  49. package/examples/jsm/loaders/EXRLoader.js +5 -5
  50. package/examples/jsm/loaders/FBXLoader.js +2 -4
  51. package/examples/jsm/loaders/GCodeLoader.js +34 -8
  52. package/examples/jsm/loaders/GLTFLoader.js +122 -171
  53. package/examples/jsm/loaders/HDRLoader.js +0 -1
  54. package/examples/jsm/loaders/KMZLoader.js +5 -5
  55. package/examples/jsm/loaders/KTX2Loader.js +19 -3
  56. package/examples/jsm/loaders/LDrawLoader.js +2 -3
  57. package/examples/jsm/loaders/LWOLoader.js +7 -39
  58. package/examples/jsm/loaders/NRRDLoader.js +2 -2
  59. package/examples/jsm/loaders/PCDLoader.js +4 -2
  60. package/examples/jsm/loaders/SVGLoader.js +1 -1
  61. package/examples/jsm/loaders/TDSLoader.js +0 -2
  62. package/examples/jsm/loaders/TGALoader.js +0 -2
  63. package/examples/jsm/loaders/USDLoader.js +100 -40
  64. package/examples/jsm/loaders/UltraHDRLoader.js +285 -160
  65. package/examples/jsm/loaders/VOXLoader.js +660 -117
  66. package/examples/jsm/loaders/VRMLLoader.js +79 -2
  67. package/examples/jsm/loaders/VTKLoader.js +37 -24
  68. package/examples/jsm/loaders/collada/ColladaComposer.js +2950 -0
  69. package/examples/jsm/loaders/collada/ColladaParser.js +1962 -0
  70. package/examples/jsm/loaders/usd/USDAParser.js +447 -366
  71. package/examples/jsm/loaders/usd/USDCParser.js +1841 -6
  72. package/examples/jsm/loaders/usd/USDComposer.js +4041 -0
  73. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +2 -2
  74. package/examples/jsm/materials/WoodNodeMaterial.js +11 -11
  75. package/examples/jsm/math/Octree.js +131 -1
  76. package/examples/jsm/misc/Volume.js +0 -1
  77. package/examples/jsm/misc/VolumeSlice.js +0 -1
  78. package/examples/jsm/objects/LensflareMesh.js +1 -1
  79. package/examples/jsm/objects/Sky.js +76 -4
  80. package/examples/jsm/objects/SkyMesh.js +127 -10
  81. package/examples/jsm/objects/Water.js +4 -3
  82. package/examples/jsm/objects/Water2.js +5 -3
  83. package/examples/jsm/objects/WaterMesh.js +5 -7
  84. package/examples/jsm/physics/AmmoPhysics.js +12 -7
  85. package/examples/jsm/physics/JoltPhysics.js +10 -6
  86. package/examples/jsm/physics/RapierPhysics.js +9 -5
  87. package/examples/jsm/postprocessing/EffectComposer.js +7 -5
  88. package/examples/jsm/postprocessing/OutputPass.js +9 -0
  89. package/examples/jsm/postprocessing/RenderPass.js +10 -0
  90. package/examples/jsm/postprocessing/RenderTransitionPass.js +1 -1
  91. package/examples/jsm/postprocessing/UnrealBloomPass.js +48 -18
  92. package/examples/jsm/renderers/CSS3DRenderer.js +1 -1
  93. package/examples/jsm/renderers/Projector.js +268 -30
  94. package/examples/jsm/renderers/SVGRenderer.js +193 -60
  95. package/examples/jsm/shaders/GTAOShader.js +19 -6
  96. package/examples/jsm/shaders/HalftoneShader.js +12 -1
  97. package/examples/jsm/shaders/PoissonDenoiseShader.js +6 -2
  98. package/examples/jsm/shaders/SAOShader.js +17 -4
  99. package/examples/jsm/shaders/SSAOShader.js +11 -1
  100. package/examples/jsm/shaders/SSRShader.js +6 -5
  101. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -4
  102. package/examples/jsm/shaders/VignetteShader.js +1 -1
  103. package/examples/jsm/transpiler/AST.js +44 -0
  104. package/examples/jsm/transpiler/GLSLDecoder.js +61 -4
  105. package/examples/jsm/transpiler/ShaderToyDecoder.js +2 -0
  106. package/examples/jsm/transpiler/TSLEncoder.js +46 -3
  107. package/examples/jsm/transpiler/TranspilerUtils.js +3 -3
  108. package/examples/jsm/transpiler/WGSLEncoder.js +27 -0
  109. package/examples/jsm/tsl/display/AfterImageNode.js +1 -1
  110. package/examples/jsm/tsl/display/AnaglyphPassNode.js +458 -16
  111. package/examples/jsm/tsl/display/AnamorphicNode.js +1 -1
  112. package/examples/jsm/tsl/display/BilateralBlurNode.js +364 -0
  113. package/examples/jsm/tsl/display/BloomNode.js +16 -6
  114. package/examples/jsm/tsl/display/CRT.js +150 -0
  115. package/examples/jsm/tsl/display/DenoiseNode.js +1 -1
  116. package/examples/jsm/tsl/display/DepthOfFieldNode.js +1 -1
  117. package/examples/jsm/tsl/display/DotScreenNode.js +1 -1
  118. package/examples/jsm/tsl/display/FXAANode.js +2 -2
  119. package/examples/jsm/tsl/display/GTAONode.js +5 -4
  120. package/examples/jsm/tsl/display/GaussianBlurNode.js +11 -2
  121. package/examples/jsm/tsl/display/GodraysNode.js +624 -0
  122. package/examples/jsm/tsl/display/LensflareNode.js +1 -1
  123. package/examples/jsm/tsl/display/Lut3DNode.js +1 -1
  124. package/examples/jsm/tsl/display/OutlineNode.js +3 -3
  125. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +2 -2
  126. package/examples/jsm/tsl/display/PixelationPassNode.js +7 -6
  127. package/examples/jsm/tsl/display/RGBShiftNode.js +2 -2
  128. package/examples/jsm/tsl/display/RetroPassNode.js +263 -0
  129. package/examples/jsm/tsl/display/SMAANode.js +2 -2
  130. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -2
  131. package/examples/jsm/tsl/display/SSGINode.js +8 -20
  132. package/examples/jsm/tsl/display/SSRNode.js +8 -8
  133. package/examples/jsm/tsl/display/SSSNode.js +6 -4
  134. package/examples/jsm/tsl/display/Shape.js +29 -0
  135. package/examples/jsm/tsl/display/SobelOperatorNode.js +2 -2
  136. package/examples/jsm/tsl/display/StereoCompositePassNode.js +8 -1
  137. package/examples/jsm/tsl/display/StereoPassNode.js +1 -2
  138. package/examples/jsm/tsl/display/TRAANode.js +273 -125
  139. package/examples/jsm/tsl/display/TransitionNode.js +1 -1
  140. package/examples/jsm/tsl/display/depthAwareBlend.js +80 -0
  141. package/examples/jsm/tsl/display/radialBlur.js +68 -0
  142. package/examples/jsm/tsl/math/Bayer.js +40 -1
  143. package/examples/jsm/utils/LDrawUtils.js +1 -1
  144. package/examples/jsm/utils/ShadowMapViewer.js +24 -10
  145. package/examples/jsm/utils/ShadowMapViewerGPU.js +1 -1
  146. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  147. package/package.json +20 -26
  148. package/src/Three.Core.js +2 -1
  149. package/src/Three.TSL.js +19 -11
  150. package/src/Three.WebGPU.Nodes.js +2 -0
  151. package/src/Three.WebGPU.js +3 -0
  152. package/src/Three.js +1 -0
  153. package/src/animation/AnimationAction.js +1 -1
  154. package/src/animation/AnimationClip.js +1 -1
  155. package/src/animation/AnimationMixer.js +6 -0
  156. package/src/animation/AnimationUtils.js +1 -12
  157. package/src/animation/KeyframeTrack.js +47 -8
  158. package/src/animation/PropertyMixer.js +4 -4
  159. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  160. package/src/animation/tracks/ColorKeyframeTrack.js +1 -1
  161. package/src/animation/tracks/NumberKeyframeTrack.js +1 -1
  162. package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -1
  163. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  164. package/src/animation/tracks/VectorKeyframeTrack.js +1 -1
  165. package/src/audio/Audio.js +1 -1
  166. package/src/audio/AudioListener.js +5 -3
  167. package/src/cameras/Camera.js +32 -2
  168. package/src/cameras/CubeCamera.js +20 -0
  169. package/src/constants.js +90 -5
  170. package/src/core/BufferGeometry.js +14 -2
  171. package/src/core/Clock.js +7 -0
  172. package/src/core/Object3D.js +56 -4
  173. package/src/core/Raycaster.js +2 -2
  174. package/src/core/RenderTarget.js +3 -4
  175. package/src/extras/PMREMGenerator.js +7 -18
  176. package/src/extras/TextureUtils.js +5 -1
  177. package/src/geometries/ExtrudeGeometry.js +2 -2
  178. package/src/geometries/PolyhedronGeometry.js +1 -1
  179. package/src/geometries/TorusGeometry.js +8 -3
  180. package/src/helpers/CameraHelper.js +3 -0
  181. package/src/helpers/DirectionalLightHelper.js +4 -1
  182. package/src/helpers/HemisphereLightHelper.js +3 -0
  183. package/src/helpers/PointLightHelper.js +1 -25
  184. package/src/helpers/SpotLightHelper.js +3 -0
  185. package/src/lights/DirectionalLight.js +13 -0
  186. package/src/lights/HemisphereLight.js +10 -0
  187. package/src/lights/Light.js +1 -11
  188. package/src/lights/LightProbe.js +0 -15
  189. package/src/lights/LightShadow.js +15 -6
  190. package/src/lights/PointLight.js +15 -0
  191. package/src/lights/PointLightShadow.js +0 -86
  192. package/src/lights/SpotLight.js +22 -1
  193. package/src/lights/webgpu/IESSpotLight.js +2 -1
  194. package/src/loaders/Cache.js +28 -0
  195. package/src/loaders/FileLoader.js +1 -1
  196. package/src/loaders/ImageBitmapLoader.js +8 -3
  197. package/src/loaders/Loader.js +6 -0
  198. package/src/loaders/MaterialLoader.js +2 -1
  199. package/src/loaders/ObjectLoader.js +21 -2
  200. package/src/loaders/nodes/NodeLoader.js +2 -2
  201. package/src/materials/Material.js +2 -0
  202. package/src/materials/MeshLambertMaterial.js +9 -0
  203. package/src/materials/MeshPhongMaterial.js +9 -0
  204. package/src/materials/ShaderMaterial.js +20 -1
  205. package/src/materials/nodes/Line2NodeMaterial.js +7 -7
  206. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +5 -2
  207. package/src/materials/nodes/MeshStandardNodeMaterial.js +5 -4
  208. package/src/materials/nodes/NodeMaterial.js +72 -25
  209. package/src/materials/nodes/manager/NodeMaterialObserver.js +10 -4
  210. package/src/math/Line3.js +3 -5
  211. package/src/math/MathUtils.js +10 -10
  212. package/src/math/Matrix4.js +74 -65
  213. package/src/math/Quaternion.js +3 -29
  214. package/src/math/Sphere.js +1 -1
  215. package/src/math/Vector3.js +3 -5
  216. package/src/math/interpolants/BezierInterpolant.js +108 -0
  217. package/src/nodes/Nodes.js +87 -68
  218. package/src/nodes/TSL.js +6 -6
  219. package/src/nodes/accessors/Arrays.js +1 -1
  220. package/src/nodes/accessors/BatchNode.js +10 -10
  221. package/src/nodes/accessors/Bitangent.js +5 -5
  222. package/src/nodes/accessors/BufferAttributeNode.js +98 -12
  223. package/src/nodes/accessors/BufferNode.js +29 -2
  224. package/src/nodes/accessors/Camera.js +149 -28
  225. package/src/nodes/accessors/ClippingNode.js +4 -4
  226. package/src/nodes/accessors/CubeTextureNode.js +20 -1
  227. package/src/nodes/accessors/InstanceNode.js +148 -43
  228. package/src/nodes/accessors/MaterialNode.js +9 -1
  229. package/src/nodes/accessors/MaterialReferenceNode.js +1 -2
  230. package/src/nodes/accessors/ModelNode.js +1 -1
  231. package/src/nodes/accessors/Normal.js +11 -11
  232. package/src/nodes/accessors/Position.js +34 -2
  233. package/src/nodes/accessors/ReferenceBaseNode.js +4 -4
  234. package/src/nodes/accessors/ReferenceNode.js +4 -4
  235. package/src/nodes/accessors/RendererReferenceNode.js +1 -2
  236. package/src/nodes/accessors/SceneProperties.js +53 -0
  237. package/src/nodes/accessors/SkinningNode.js +27 -26
  238. package/src/nodes/accessors/StorageBufferNode.js +4 -21
  239. package/src/nodes/accessors/StorageTextureNode.js +37 -1
  240. package/src/nodes/accessors/Tangent.js +4 -14
  241. package/src/nodes/accessors/Texture3DNode.js +32 -35
  242. package/src/nodes/accessors/TextureNode.js +58 -22
  243. package/src/nodes/accessors/UniformArrayNode.js +4 -2
  244. package/src/nodes/accessors/UserDataNode.js +1 -2
  245. package/src/nodes/accessors/VertexColorNode.js +1 -2
  246. package/src/nodes/code/FunctionNode.js +1 -2
  247. package/src/nodes/core/ArrayNode.js +20 -1
  248. package/src/nodes/core/AssignNode.js +2 -2
  249. package/src/nodes/core/AttributeNode.js +2 -2
  250. package/src/nodes/core/ContextNode.js +103 -4
  251. package/src/nodes/core/MRTNode.js +48 -2
  252. package/src/nodes/core/Node.js +29 -3
  253. package/src/nodes/core/NodeBuilder.js +170 -53
  254. package/src/nodes/core/NodeError.js +28 -0
  255. package/src/nodes/core/NodeFrame.js +12 -4
  256. package/src/nodes/core/NodeUtils.js +10 -8
  257. package/src/nodes/core/OutputStructNode.js +12 -10
  258. package/src/nodes/core/ParameterNode.js +3 -3
  259. package/src/nodes/core/PropertyNode.js +19 -3
  260. package/src/nodes/core/StackNode.js +65 -16
  261. package/src/nodes/core/StackTrace.js +139 -0
  262. package/src/nodes/core/StructNode.js +16 -2
  263. package/src/nodes/core/StructTypeNode.js +11 -17
  264. package/src/nodes/core/SubBuildNode.js +1 -1
  265. package/src/nodes/core/UniformNode.js +21 -5
  266. package/src/nodes/core/VarNode.js +47 -22
  267. package/src/nodes/core/VaryingNode.js +1 -18
  268. package/src/nodes/display/BlendModes.js +0 -64
  269. package/src/nodes/display/ColorAdjustment.js +17 -0
  270. package/src/nodes/display/ColorSpaceNode.js +3 -3
  271. package/src/nodes/display/NormalMapNode.js +39 -4
  272. package/src/nodes/display/PassNode.js +98 -9
  273. package/src/nodes/display/RenderOutputNode.js +3 -3
  274. package/src/nodes/display/ScreenNode.js +3 -1
  275. package/src/nodes/display/ToneMappingNode.js +1 -1
  276. package/src/nodes/display/ToonOutlinePassNode.js +2 -2
  277. package/src/nodes/display/ViewportDepthNode.js +52 -4
  278. package/src/nodes/display/ViewportTextureNode.js +21 -4
  279. package/src/nodes/fog/Fog.js +18 -35
  280. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +3 -3
  281. package/src/nodes/functions/BSDF/DFGLUT.js +56 -0
  282. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  283. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +1 -1
  284. package/src/nodes/functions/PhysicalLightingModel.js +126 -45
  285. package/src/nodes/geometry/RangeNode.js +4 -2
  286. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -2
  287. package/src/nodes/gpgpu/ComputeNode.js +5 -4
  288. package/src/nodes/gpgpu/SubgroupFunctionNode.js +1 -1
  289. package/src/nodes/gpgpu/WorkgroupInfoNode.js +4 -4
  290. package/src/nodes/lighting/AnalyticLightNode.js +53 -0
  291. package/src/nodes/lighting/EnvironmentNode.js +28 -3
  292. package/src/nodes/lighting/LightsNode.js +2 -2
  293. package/src/nodes/lighting/PointShadowNode.js +162 -149
  294. package/src/nodes/lighting/ShadowFilterNode.js +53 -65
  295. package/src/nodes/lighting/ShadowNode.js +97 -41
  296. package/src/nodes/math/BitcountNode.js +433 -0
  297. package/src/nodes/math/ConditionalNode.js +2 -2
  298. package/src/nodes/math/MathNode.js +3 -40
  299. package/src/nodes/math/OperatorNode.js +2 -1
  300. package/src/nodes/math/PackFloatNode.js +98 -0
  301. package/src/nodes/math/UnpackFloatNode.js +96 -0
  302. package/src/nodes/pmrem/PMREMNode.js +1 -1
  303. package/src/nodes/pmrem/PMREMUtils.js +9 -15
  304. package/src/nodes/tsl/TSLCore.js +17 -14
  305. package/src/nodes/utils/ArrayElementNode.js +13 -0
  306. package/src/nodes/utils/DebugNode.js +11 -11
  307. package/src/nodes/utils/EventNode.js +1 -2
  308. package/src/nodes/utils/JoinNode.js +2 -2
  309. package/src/nodes/utils/LoopNode.js +1 -1
  310. package/src/nodes/utils/MemberNode.js +1 -1
  311. package/src/nodes/utils/Packing.js +13 -1
  312. package/src/nodes/utils/PostProcessingUtils.js +33 -1
  313. package/src/nodes/utils/RTTNode.js +1 -1
  314. package/src/nodes/utils/ReflectorNode.js +3 -4
  315. package/src/nodes/utils/SampleNode.js +1 -1
  316. package/src/nodes/utils/SpriteSheetUV.js +35 -0
  317. package/src/nodes/utils/UVUtils.js +28 -0
  318. package/src/objects/BatchedMesh.js +27 -14
  319. package/src/objects/InstancedMesh.js +11 -0
  320. package/src/objects/Line.js +1 -1
  321. package/src/objects/Mesh.js +1 -1
  322. package/src/objects/Points.js +1 -1
  323. package/src/objects/Skeleton.js +9 -0
  324. package/src/renderers/WebGLRenderer.js +178 -92
  325. package/src/renderers/common/Backend.js +29 -0
  326. package/src/renderers/common/Background.js +24 -11
  327. package/src/renderers/common/BindGroup.js +1 -9
  328. package/src/renderers/common/Binding.js +11 -0
  329. package/src/renderers/common/Bindings.js +27 -12
  330. package/src/renderers/common/BlendMode.js +143 -0
  331. package/src/renderers/common/Buffer.js +40 -0
  332. package/src/renderers/common/BundleGroup.js +1 -1
  333. package/src/renderers/common/ChainMap.js +30 -6
  334. package/src/renderers/common/CubeRenderTarget.js +50 -6
  335. package/src/renderers/common/Geometries.js +29 -3
  336. package/src/renderers/common/Lighting.js +5 -21
  337. package/src/renderers/common/Pipelines.js +4 -4
  338. package/src/renderers/common/PostProcessing.js +8 -206
  339. package/src/renderers/common/RenderBundles.js +2 -1
  340. package/src/renderers/common/RenderContext.js +16 -0
  341. package/src/renderers/common/RenderContexts.js +33 -49
  342. package/src/renderers/common/RenderLists.js +2 -1
  343. package/src/renderers/common/RenderObject.js +15 -3
  344. package/src/renderers/common/RenderObjectPipeline.js +40 -0
  345. package/src/renderers/common/RenderObjects.js +18 -2
  346. package/src/renderers/common/RenderPipeline.js +203 -17
  347. package/src/renderers/common/Renderer.js +257 -72
  348. package/src/renderers/common/Sampler.js +4 -4
  349. package/src/renderers/common/StorageBuffer.js +13 -1
  350. package/src/renderers/common/Textures.js +17 -1
  351. package/src/renderers/common/TimestampQueryPool.js +5 -3
  352. package/src/renderers/common/Uniform.js +8 -0
  353. package/src/renderers/common/UniformsGroup.js +61 -0
  354. package/src/renderers/common/XRManager.js +3 -2
  355. package/src/renderers/common/extras/PMREMGenerator.js +2 -8
  356. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  357. package/src/renderers/common/nodes/{Nodes.js → NodeManager.js} +18 -6
  358. package/src/renderers/common/nodes/NodeStorageBuffer.js +13 -2
  359. package/src/renderers/common/nodes/NodeUniformBuffer.js +52 -0
  360. package/src/renderers/shaders/DFGLUTData.js +19 -34
  361. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +2 -2
  362. package/src/renderers/shaders/ShaderChunk/color_fragment.glsl.js +1 -5
  363. package/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js +1 -5
  364. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -5
  365. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +8 -10
  366. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +7 -11
  367. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +5 -2
  368. package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +6 -0
  369. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +6 -2
  370. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +8 -4
  371. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +112 -51
  372. package/src/renderers/shaders/ShaderChunk/packing.glsl.js +20 -4
  373. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +225 -186
  374. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +1 -1
  375. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  376. package/src/renderers/shaders/ShaderChunk.js +3 -3
  377. package/src/renderers/shaders/ShaderLib/depth.glsl.js +3 -0
  378. package/src/renderers/shaders/ShaderLib/{distanceRGBA.glsl.js → distance.glsl.js} +1 -2
  379. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -1
  380. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -2
  381. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -1
  382. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -9
  383. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +0 -1
  384. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -1
  385. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +4 -6
  386. package/src/renderers/shaders/ShaderLib.js +7 -5
  387. package/src/renderers/shaders/UniformsLib.js +0 -3
  388. package/src/renderers/webgl/WebGLBackground.js +2 -2
  389. package/src/renderers/webgl/WebGLBindingStates.js +99 -27
  390. package/src/renderers/webgl/WebGLCapabilities.js +3 -4
  391. package/src/renderers/webgl/WebGLEnvironments.js +228 -0
  392. package/src/renderers/webgl/WebGLGeometries.js +10 -7
  393. package/src/renderers/webgl/WebGLLights.js +18 -1
  394. package/src/renderers/webgl/WebGLMaterials.js +12 -0
  395. package/src/renderers/webgl/WebGLObjects.js +3 -1
  396. package/src/renderers/webgl/WebGLOutput.js +267 -0
  397. package/src/renderers/webgl/WebGLProgram.js +45 -109
  398. package/src/renderers/webgl/WebGLPrograms.js +45 -49
  399. package/src/renderers/webgl/WebGLRenderLists.js +15 -0
  400. package/src/renderers/webgl/WebGLShadowMap.js +188 -24
  401. package/src/renderers/webgl/WebGLState.js +32 -37
  402. package/src/renderers/webgl/WebGLTextures.js +89 -28
  403. package/src/renderers/webgl/WebGLUniforms.js +40 -3
  404. package/src/renderers/webgl/WebGLUtils.js +6 -2
  405. package/src/renderers/webgl-fallback/WebGLBackend.js +148 -18
  406. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +156 -35
  407. package/src/renderers/webgl-fallback/utils/WebGLState.js +181 -5
  408. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +5 -3
  409. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -9
  410. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +6 -2
  411. package/src/renderers/webgpu/WebGPUBackend.js +119 -13
  412. package/src/renderers/webgpu/WebGPURenderer.js +2 -1
  413. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +322 -68
  414. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -17
  415. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +357 -200
  416. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -0
  417. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +61 -23
  418. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +152 -200
  419. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +65 -42
  420. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +7 -7
  421. package/src/renderers/webgpu/utils/WebGPUUtils.js +17 -11
  422. package/src/renderers/webxr/WebXRManager.js +2 -2
  423. package/src/textures/CubeDepthTexture.js +76 -0
  424. package/src/textures/Source.js +1 -1
  425. package/src/textures/Texture.js +3 -3
  426. package/src/utils.js +258 -3
  427. package/examples/jsm/materials/MeshGouraudMaterial.js +0 -434
  428. package/examples/jsm/materials/MeshPostProcessingMaterial.js +0 -167
  429. package/examples/jsm/shaders/GodRaysShader.js +0 -333
  430. package/src/nodes/accessors/SceneNode.js +0 -145
  431. package/src/nodes/code/ScriptableNode.js +0 -726
  432. package/src/nodes/code/ScriptableValueNode.js +0 -253
  433. package/src/nodes/display/PosterizeNode.js +0 -65
  434. package/src/nodes/functions/BSDF/DFGApprox.js +0 -71
  435. package/src/nodes/utils/SpriteSheetUVNode.js +0 -90
  436. package/src/renderers/webgl/WebGLCubeMaps.js +0 -99
  437. package/src/renderers/webgl/WebGLCubeUVMaps.js +0 -134
@@ -18,23 +18,26 @@ 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.
29
30
  */
30
31
 
31
32
 
32
- // Calculating this SRGB powers is extremely slow for 4K images and can be sufficiently precalculated for a 3-4x speed boost
33
- const SRGB_TO_LINEAR = Array( 1024 )
34
- .fill( 0 )
35
- .map( ( _, value ) =>
36
- Math.pow( ( value / 255 ) * 0.9478672986 + 0.0521327014, 2.4 )
37
- );
33
+ // Pre-calculated sRGB to linear lookup table for values 0-1023
34
+ const SRGB_TO_LINEAR = new Float64Array( 1024 );
35
+ for ( let i = 0; i < 1024; i ++ ) {
36
+
37
+ // (1/255) * 0.9478672986 = 0.003717127
38
+ SRGB_TO_LINEAR[ i ] = Math.pow( i * 0.003717127 + 0.0521327014, 2.4 );
39
+
40
+ }
38
41
 
39
42
  /**
40
43
  * A loader for the Ultra HDR Image Format.
@@ -43,7 +46,8 @@ const SRGB_TO_LINEAR = Array( 1024 )
43
46
  *
44
47
  * Current feature set:
45
48
  * - JPEG headers (required)
46
- * - XMP metadata (required)
49
+ * - XMP metadata (legacy format, supported)
50
+ * - ISO 21496-1 metadata (current standard, supported)
47
51
  * - XMP validation (not implemented)
48
52
  * - EXIF profile (not implemented)
49
53
  * - ICC profile (not implemented)
@@ -107,7 +111,7 @@ class UltraHDRLoader extends Loader {
107
111
  */
108
112
  parse( buffer, onLoad ) {
109
113
 
110
- const xmpMetadata = {
114
+ const metadata = {
111
115
  version: null,
112
116
  baseRenditionIsHDR: null,
113
117
  gainMapMin: null,
@@ -120,53 +124,69 @@ class UltraHDRLoader extends Loader {
120
124
  };
121
125
  const textDecoder = new TextDecoder();
122
126
 
123
- const data = new DataView( buffer );
127
+ const bytes = new Uint8Array( buffer );
124
128
 
125
- let byteOffset = 0;
126
129
  const sections = [];
127
130
 
128
- while ( byteOffset < data.byteLength ) {
131
+ // JPEG segment-aware scanner using length headers
132
+ let offset = 0;
129
133
 
130
- const byte = data.getUint8( byteOffset );
134
+ while ( offset < bytes.length - 1 ) {
131
135
 
132
- if ( byte === 0xff ) {
136
+ // Find marker prefix
137
+ if ( bytes[ offset ] !== 0xff ) {
133
138
 
134
- const leadingByte = data.getUint8( byteOffset + 1 );
139
+ offset ++;
140
+ continue;
135
141
 
136
- if (
137
- [
138
- /* Valid section headers */
139
- 0xd8, // SOI
140
- 0xe0, // APP0
141
- 0xe1, // APP1
142
- 0xe2, // APP2
143
- ].includes( leadingByte )
144
- ) {
142
+ }
145
143
 
146
- sections.push( {
147
- sectionType: leadingByte,
148
- section: [ byte, leadingByte ],
149
- sectionOffset: byteOffset + 2,
150
- } );
144
+ const markerType = bytes[ offset + 1 ];
151
145
 
152
- byteOffset += 2;
146
+ // SOI (0xD8) - Start of Image, no length field
147
+ if ( markerType === 0xd8 ) {
153
148
 
154
- } else {
149
+ sections.push( {
150
+ sectionType: markerType,
151
+ section: bytes.subarray( offset, offset + 2 ),
152
+ sectionOffset: offset + 2,
153
+ } );
155
154
 
156
- sections[ sections.length - 1 ].section.push( byte, leadingByte );
155
+ offset += 2;
156
+ continue;
157
157
 
158
- byteOffset += 2;
158
+ }
159
159
 
160
- }
160
+ // APP0-APP2 segments have length headers
161
+ if ( markerType === 0xe0 || markerType === 0xe1 || markerType === 0xe2 ) {
162
+
163
+ // Length is stored as big-endian 16-bit value (includes length bytes, excludes marker)
164
+ const segmentLength = ( bytes[ offset + 2 ] << 8 ) | bytes[ offset + 3 ];
165
+ const segmentEnd = offset + 2 + segmentLength;
166
+
167
+ sections.push( {
168
+ sectionType: markerType,
169
+ section: bytes.subarray( offset, segmentEnd ),
170
+ sectionOffset: offset + 2,
171
+ } );
172
+
173
+ offset = segmentEnd;
174
+ continue;
161
175
 
162
- } else {
176
+ }
163
177
 
164
- sections[ sections.length - 1 ].section.push( byte );
178
+ // Skip other markers with length fields (0xC0-0xFE range, except RST and EOI)
179
+ if ( markerType >= 0xc0 && markerType <= 0xfe && markerType !== 0xd9 && ( markerType < 0xd0 || markerType > 0xd7 ) ) {
165
180
 
166
- byteOffset ++;
181
+ const segmentLength = ( bytes[ offset + 2 ] << 8 ) | bytes[ offset + 3 ];
182
+ offset += 2 + segmentLength;
183
+ continue;
167
184
 
168
185
  }
169
186
 
187
+ // EOI (0xD9) or RST markers (0xD0-0xD7) - no length field
188
+ offset += 2;
189
+
170
190
  }
171
191
 
172
192
  let primaryImage, gainmapImage;
@@ -179,20 +199,47 @@ class UltraHDRLoader extends Loader {
179
199
  /* JPEG Header - no useful information */
180
200
  } else if ( sectionType === 0xe1 ) {
181
201
 
182
- /* XMP Metadata */
202
+ /* APP1: XMP Metadata */
183
203
 
184
204
  this._parseXMPMetadata(
185
205
  textDecoder.decode( new Uint8Array( section ) ),
186
- xmpMetadata
206
+ metadata
187
207
  );
188
208
 
189
209
  } else if ( sectionType === 0xe2 ) {
190
210
 
191
- /* Data Sections - MPF / EXIF / ICC Profile */
211
+ /* APP2: Data Sections - MPF / ICC Profile / ISO 21496-1 Metadata */
192
212
 
193
- const sectionData = new DataView(
194
- new Uint8Array( section.slice( 2 ) ).buffer
195
- );
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
196
243
  const sectionHeader = sectionData.getUint32( 2, false );
197
244
 
198
245
  if ( sectionHeader === 0x4d504600 ) {
@@ -243,13 +290,13 @@ class UltraHDRLoader extends Loader {
243
290
  6;
244
291
 
245
292
  primaryImage = new Uint8Array(
246
- data.buffer,
293
+ buffer,
247
294
  primaryImageOffset,
248
295
  primaryImageSize
249
296
  );
250
297
 
251
298
  gainmapImage = new Uint8Array(
252
- data.buffer,
299
+ buffer,
253
300
  gainmapImageOffset,
254
301
  gainmapImageSize
255
302
  );
@@ -261,7 +308,8 @@ class UltraHDRLoader extends Loader {
261
308
  }
262
309
 
263
310
  /* Minimal sufficient validation - https://developer.android.com/media/platform/hdr-image-format#signal_of_the_format */
264
- if ( ! xmpMetadata.version ) {
311
+ // Version can come from either XMP or ISO metadata
312
+ if ( ! metadata.version ) {
265
313
 
266
314
  throw new Error( 'THREE.UltraHDRLoader: Not a valid UltraHDR image' );
267
315
 
@@ -270,7 +318,7 @@ class UltraHDRLoader extends Loader {
270
318
  if ( primaryImage && gainmapImage ) {
271
319
 
272
320
  this._applyGainmapToSDR(
273
- xmpMetadata,
321
+ metadata,
274
322
  primaryImage,
275
323
  gainmapImage,
276
324
  ( hdrBuffer, width, height ) => {
@@ -299,6 +347,126 @@ class UltraHDRLoader extends Loader {
299
347
 
300
348
  }
301
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
+
302
470
  /**
303
471
  * Starts loading from the given URL and passes the loaded Ultra HDR texture
304
472
  * to the `onLoad()` callback.
@@ -367,7 +535,7 @@ class UltraHDRLoader extends Loader {
367
535
 
368
536
  }
369
537
 
370
- _parseXMPMetadata( xmpDataString, xmpMetadata ) {
538
+ _parseXMPMetadata( xmpDataString, metadata ) {
371
539
 
372
540
  const domParser = new DOMParser();
373
541
 
@@ -392,28 +560,28 @@ class UltraHDRLoader extends Loader {
392
560
 
393
561
  const [ gainmapNode ] = xmpXml.getElementsByTagName( 'rdf:Description' );
394
562
 
395
- xmpMetadata.version = gainmapNode.getAttribute( 'hdrgm:Version' );
396
- xmpMetadata.baseRenditionIsHDR =
563
+ metadata.version = gainmapNode.getAttribute( 'hdrgm:Version' );
564
+ metadata.baseRenditionIsHDR =
397
565
  gainmapNode.getAttribute( 'hdrgm:BaseRenditionIsHDR' ) === 'True';
398
- xmpMetadata.gainMapMin = parseFloat(
566
+ metadata.gainMapMin = parseFloat(
399
567
  gainmapNode.getAttribute( 'hdrgm:GainMapMin' ) || 0.0
400
568
  );
401
- xmpMetadata.gainMapMax = parseFloat(
569
+ metadata.gainMapMax = parseFloat(
402
570
  gainmapNode.getAttribute( 'hdrgm:GainMapMax' ) || 1.0
403
571
  );
404
- xmpMetadata.gamma = parseFloat(
572
+ metadata.gamma = parseFloat(
405
573
  gainmapNode.getAttribute( 'hdrgm:Gamma' ) || 1.0
406
574
  );
407
- xmpMetadata.offsetSDR = parseFloat(
575
+ metadata.offsetSDR = parseFloat(
408
576
  gainmapNode.getAttribute( 'hdrgm:OffsetSDR' ) / ( 1 / 64 )
409
577
  );
410
- xmpMetadata.offsetHDR = parseFloat(
578
+ metadata.offsetHDR = parseFloat(
411
579
  gainmapNode.getAttribute( 'hdrgm:OffsetHDR' ) / ( 1 / 64 )
412
580
  );
413
- xmpMetadata.hdrCapacityMin = parseFloat(
581
+ metadata.hdrCapacityMin = parseFloat(
414
582
  gainmapNode.getAttribute( 'hdrgm:HDRCapacityMin' ) || 0.0
415
583
  );
416
- xmpMetadata.hdrCapacityMax = parseFloat(
584
+ metadata.hdrCapacityMax = parseFloat(
417
585
  gainmapNode.getAttribute( 'hdrgm:HDRCapacityMax' ) || 1.0
418
586
  );
419
587
 
@@ -423,70 +591,41 @@ class UltraHDRLoader extends Loader {
423
591
 
424
592
  _srgbToLinear( value ) {
425
593
 
426
- if ( value / 255 < 0.04045 ) {
594
+ // 0.04045 * 255 = 10.31475
595
+ if ( value < 10.31475 ) {
427
596
 
428
- return ( value / 255 ) * 0.0773993808;
597
+ // (1/255) * 0.0773993808
598
+ return value * 0.000303527;
429
599
 
430
600
  }
431
601
 
432
602
  if ( value < 1024 ) {
433
603
 
434
- return SRGB_TO_LINEAR[ ~ ~ value ];
604
+ return SRGB_TO_LINEAR[ value | 0 ];
435
605
 
436
606
  }
437
607
 
438
- return Math.pow( ( value / 255 ) * 0.9478672986 + 0.0521327014, 2.4 );
608
+ // (1/255) * 0.9478672986 = 0.003717127
609
+ return Math.pow( value * 0.003717127 + 0.0521327014, 2.4 );
439
610
 
440
611
  }
441
612
 
442
613
  _applyGainmapToSDR(
443
- xmpMetadata,
614
+ metadata,
444
615
  sdrBuffer,
445
616
  gainmapBuffer,
446
617
  onSuccess,
447
618
  onError
448
619
  ) {
449
620
 
450
- const getImageDataFromBuffer = ( buffer ) =>
451
- new Promise( ( resolve, reject ) => {
452
-
453
- const imageLoader = document.createElement( 'img' );
454
-
455
- imageLoader.onload = () => {
456
-
457
- const image = {
458
- width: imageLoader.naturalWidth,
459
- height: imageLoader.naturalHeight,
460
- source: imageLoader,
461
- };
621
+ const decodeImage = ( data ) => createImageBitmap( new Blob( [ data ], { type: 'image/jpeg' } ) );
462
622
 
463
- URL.revokeObjectURL( imageLoader.src );
464
-
465
- resolve( image );
466
-
467
- };
468
-
469
- imageLoader.onerror = () => {
470
-
471
- URL.revokeObjectURL( imageLoader.src );
472
-
473
- reject();
474
-
475
- };
476
-
477
- imageLoader.src = URL.createObjectURL(
478
- new Blob( [ buffer ], { type: 'image/jpeg' } )
479
- );
480
-
481
- } );
482
-
483
- Promise.all( [
484
- getImageDataFromBuffer( sdrBuffer ),
485
- getImageDataFromBuffer( gainmapBuffer ),
486
- ] )
623
+ Promise.all( [ decodeImage( sdrBuffer ), decodeImage( gainmapBuffer ) ] )
487
624
  .then( ( [ sdrImage, gainmapImage ] ) => {
488
625
 
489
- const sdrImageAspect = sdrImage.width / sdrImage.height;
626
+ const sdrWidth = sdrImage.width;
627
+ const sdrHeight = sdrImage.height;
628
+ const sdrImageAspect = sdrWidth / sdrHeight;
490
629
  const gainmapImageAspect = gainmapImage.width / gainmapImage.height;
491
630
 
492
631
  if ( sdrImageAspect !== gainmapImageAspect ) {
@@ -505,121 +644,107 @@ class UltraHDRLoader extends Loader {
505
644
  colorSpace: 'srgb',
506
645
  } );
507
646
 
508
- canvas.width = sdrImage.width;
509
- canvas.height = sdrImage.height;
647
+ canvas.width = sdrWidth;
648
+ canvas.height = sdrHeight;
510
649
 
511
650
  /* Use out-of-the-box interpolation of Canvas API to scale gainmap to fit the SDR resolution */
512
651
  ctx.drawImage(
513
- gainmapImage.source,
652
+ gainmapImage,
514
653
  0,
515
654
  0,
516
655
  gainmapImage.width,
517
656
  gainmapImage.height,
518
657
  0,
519
658
  0,
520
- sdrImage.width,
521
- sdrImage.height
659
+ sdrWidth,
660
+ sdrHeight
522
661
  );
523
662
  const gainmapImageData = ctx.getImageData(
524
663
  0,
525
664
  0,
526
- sdrImage.width,
527
- sdrImage.height,
665
+ sdrWidth,
666
+ sdrHeight,
528
667
  { colorSpace: 'srgb' }
529
668
  );
530
669
 
531
- ctx.drawImage( sdrImage.source, 0, 0 );
670
+ ctx.drawImage( sdrImage, 0, 0 );
532
671
  const sdrImageData = ctx.getImageData(
533
672
  0,
534
673
  0,
535
- sdrImage.width,
536
- sdrImage.height,
674
+ sdrWidth,
675
+ sdrHeight,
537
676
  { colorSpace: 'srgb' }
538
677
  );
539
678
 
540
679
  /* HDR Recovery formula - https://developer.android.com/media/platform/hdr-image-format#use_the_gain_map_to_create_adapted_HDR_rendition */
541
- let hdrBuffer;
542
-
543
- if ( this.type === HalfFloatType ) {
544
-
545
- hdrBuffer = new Uint16Array( sdrImageData.data.length ).fill( 23544 );
546
-
547
- } else {
548
-
549
- hdrBuffer = new Float32Array( sdrImageData.data.length ).fill( 255 );
550
680
 
551
- }
552
-
553
- const maxDisplayBoost = Math.sqrt(
554
- Math.pow(
555
- /* 1.8 instead of 2 near-perfectly rectifies approximations introduced by precalculated SRGB_TO_LINEAR values */
556
- 1.8,
557
- xmpMetadata.hdrCapacityMax
558
- )
559
- );
681
+ /* 1.8 instead of 2 near-perfectly rectifies approximations introduced by precalculated SRGB_TO_LINEAR values */
682
+ const maxDisplayBoost = 1.8 ** ( metadata.hdrCapacityMax * 0.5 );
560
683
  const unclampedWeightFactor =
561
- ( Math.log2( maxDisplayBoost ) - xmpMetadata.hdrCapacityMin ) /
562
- ( xmpMetadata.hdrCapacityMax - xmpMetadata.hdrCapacityMin );
684
+ ( Math.log2( maxDisplayBoost ) - metadata.hdrCapacityMin ) /
685
+ ( metadata.hdrCapacityMax - metadata.hdrCapacityMin );
563
686
  const weightFactor = Math.min(
564
687
  Math.max( unclampedWeightFactor, 0.0 ),
565
688
  1.0
566
689
  );
567
- const useGammaOne = xmpMetadata.gamma === 1.0;
568
690
 
569
- for (
570
- let pixelIndex = 0;
571
- pixelIndex < sdrImageData.data.length;
572
- pixelIndex += 4
573
- ) {
691
+ const sdrData = sdrImageData.data;
692
+ const gainmapData = gainmapImageData.data;
693
+ const dataLength = sdrData.length;
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;
700
+ const isHalfFloat = this.type === HalfFloatType;
701
+ const toHalfFloat = DataUtils.toHalfFloat;
702
+ const srgbToLinear = this._srgbToLinear;
574
703
 
575
- const x = ( pixelIndex / 4 ) % sdrImage.width;
576
- const y = Math.floor( pixelIndex / 4 / sdrImage.width );
704
+ const hdrBuffer = isHalfFloat
705
+ ? new Uint16Array( dataLength ).fill( 15360 )
706
+ : new Float32Array( dataLength ).fill( 1.0 );
577
707
 
578
- for ( let channelIndex = 0; channelIndex < 3; channelIndex ++ ) {
708
+ for ( let i = 0; i < dataLength; i += 4 ) {
579
709
 
580
- const sdrValue = sdrImageData.data[ pixelIndex + channelIndex ];
710
+ for ( let c = 0; c < 3; c ++ ) {
581
711
 
582
- const gainmapIndex = ( y * sdrImage.width + x ) * 4 + channelIndex;
583
- const gainmapValue = gainmapImageData.data[ gainmapIndex ] / 255.0;
712
+ const idx = i + c;
713
+ const sdrValue = sdrData[ idx ];
714
+ const gainmapValue = gainmapData[ idx ] * 0.00392156862745098; // 1/255
584
715
 
585
- /* Gamma is 1.0 by default */
586
716
  const logRecovery = useGammaOne
587
717
  ? gainmapValue
588
- : Math.pow( gainmapValue, 1.0 / xmpMetadata.gamma );
718
+ : Math.pow( gainmapValue, invGamma );
589
719
 
590
- const logBoost =
591
- xmpMetadata.gainMapMin * ( 1.0 - logRecovery ) +
592
- xmpMetadata.gainMapMax * logRecovery;
720
+ const logBoost = gainMapMin + ( gainMapMax - gainMapMin ) * logRecovery;
593
721
 
594
722
  const hdrValue =
595
- ( sdrValue + xmpMetadata.offsetSDR ) *
723
+ ( sdrValue + offsetSDR ) *
596
724
  ( logBoost * weightFactor === 0.0
597
725
  ? 1.0
598
726
  : Math.pow( 2, logBoost * weightFactor ) ) -
599
- xmpMetadata.offsetHDR;
727
+ offsetHDR;
600
728
 
601
729
  const linearHDRValue = Math.min(
602
- Math.max( this._srgbToLinear( hdrValue ), 0 ),
730
+ Math.max( srgbToLinear( hdrValue ), 0 ),
603
731
  65504
604
732
  );
605
733
 
606
- hdrBuffer[ pixelIndex + channelIndex ] =
607
- this.type === HalfFloatType
608
- ? DataUtils.toHalfFloat( linearHDRValue )
609
- : linearHDRValue;
734
+ hdrBuffer[ idx ] = isHalfFloat
735
+ ? toHalfFloat( linearHDRValue )
736
+ : linearHDRValue;
610
737
 
611
738
  }
612
739
 
613
740
  }
614
741
 
615
- onSuccess( hdrBuffer, sdrImage.width, sdrImage.height );
742
+ onSuccess( hdrBuffer, sdrWidth, sdrHeight );
616
743
 
617
744
  } )
618
- .catch( () => {
745
+ .catch( ( e ) => {
619
746
 
620
- throw new Error(
621
- 'THREE.UltraHDRLoader Error: Could not parse UltraHDR images'
622
- );
747
+ onError( e );
623
748
 
624
749
  } );
625
750