@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.
- package/LICENSE +1 -1
- package/build/three.cjs +11521 -10878
- package/build/three.core.js +11732 -11340
- package/build/three.core.min.js +2 -2
- package/build/three.module.js +510 -263
- package/build/three.module.min.js +2 -2
- package/build/three.tsl.js +7 -11
- package/build/three.tsl.min.js +2 -2
- package/build/three.webgpu.js +3072 -2607
- package/build/three.webgpu.min.js +2 -2
- package/build/three.webgpu.nodes.js +3071 -2607
- package/build/three.webgpu.nodes.min.js +2 -2
- package/examples/jsm/Addons.js +0 -3
- package/examples/jsm/animation/CCDIKSolver.js +2 -2
- package/examples/jsm/controls/ArcballControls.js +3 -3
- package/examples/jsm/controls/OrbitControls.js +103 -0
- package/examples/jsm/effects/AnaglyphEffect.js +102 -7
- package/examples/jsm/environments/ColorEnvironment.js +59 -0
- package/examples/jsm/environments/RoomEnvironment.js +1 -0
- package/examples/jsm/exporters/EXRExporter.js +1 -1
- package/examples/jsm/exporters/GLTFExporter.js +131 -4
- package/examples/jsm/exporters/USDZExporter.js +22 -3
- package/examples/jsm/helpers/AnimationPathHelper.js +302 -0
- package/examples/jsm/helpers/ViewHelper.js +67 -8
- package/examples/jsm/inspector/Inspector.js +21 -5
- package/examples/jsm/inspector/tabs/Console.js +39 -5
- package/examples/jsm/inspector/tabs/Parameters.js +16 -0
- package/examples/jsm/inspector/ui/Style.js +25 -1
- package/examples/jsm/libs/meshopt_decoder.module.js +6 -5
- package/examples/jsm/lines/LineMaterial.js +6 -0
- package/examples/jsm/loaders/3MFLoader.js +2 -2
- package/examples/jsm/loaders/AMFLoader.js +2 -2
- package/examples/jsm/loaders/ColladaLoader.js +24 -4026
- package/examples/jsm/loaders/EXRLoader.js +5 -5
- package/examples/jsm/loaders/FBXLoader.js +2 -2
- package/examples/jsm/loaders/GCodeLoader.js +34 -8
- package/examples/jsm/loaders/GLTFLoader.js +122 -171
- package/examples/jsm/loaders/KMZLoader.js +5 -5
- package/examples/jsm/loaders/KTX2Loader.js +5 -5
- package/examples/jsm/loaders/LWOLoader.js +7 -39
- package/examples/jsm/loaders/NRRDLoader.js +2 -2
- package/examples/jsm/loaders/PCDLoader.js +3 -2
- package/examples/jsm/loaders/USDLoader.js +100 -40
- package/examples/jsm/loaders/UltraHDRLoader.js +182 -30
- package/examples/jsm/loaders/VRMLLoader.js +77 -0
- package/examples/jsm/loaders/VTKLoader.js +37 -24
- package/examples/jsm/loaders/collada/ColladaComposer.js +2950 -0
- package/examples/jsm/loaders/collada/ColladaParser.js +1962 -0
- package/examples/jsm/loaders/usd/USDAParser.js +447 -366
- package/examples/jsm/loaders/usd/USDCParser.js +1841 -6
- package/examples/jsm/loaders/usd/USDComposer.js +4041 -0
- package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +2 -2
- package/examples/jsm/objects/LensflareMesh.js +1 -1
- package/examples/jsm/objects/Sky.js +76 -4
- package/examples/jsm/objects/SkyMesh.js +114 -7
- package/examples/jsm/objects/Water.js +4 -3
- package/examples/jsm/objects/Water2.js +5 -3
- package/examples/jsm/objects/WaterMesh.js +5 -7
- package/examples/jsm/physics/JoltPhysics.js +7 -5
- package/examples/jsm/physics/RapierPhysics.js +6 -4
- package/examples/jsm/postprocessing/EffectComposer.js +7 -5
- package/examples/jsm/postprocessing/RenderTransitionPass.js +1 -1
- package/examples/jsm/renderers/CSS3DRenderer.js +1 -1
- package/examples/jsm/renderers/SVGRenderer.js +2 -2
- package/examples/jsm/shaders/GTAOShader.js +19 -6
- package/examples/jsm/shaders/HalftoneShader.js +12 -1
- package/examples/jsm/shaders/PoissonDenoiseShader.js +6 -2
- package/examples/jsm/shaders/SAOShader.js +17 -4
- package/examples/jsm/shaders/SSAOShader.js +11 -1
- package/examples/jsm/shaders/SSRShader.js +6 -5
- package/examples/jsm/shaders/VignetteShader.js +1 -1
- package/examples/jsm/tsl/display/AfterImageNode.js +1 -1
- package/examples/jsm/tsl/display/AnaglyphPassNode.js +456 -16
- package/examples/jsm/tsl/display/AnamorphicNode.js +1 -1
- package/examples/jsm/tsl/display/BilateralBlurNode.js +364 -0
- package/examples/jsm/tsl/display/BloomNode.js +5 -5
- package/examples/jsm/tsl/display/CRT.js +150 -0
- package/examples/jsm/tsl/display/DenoiseNode.js +1 -1
- package/examples/jsm/tsl/display/DepthOfFieldNode.js +1 -1
- package/examples/jsm/tsl/display/DotScreenNode.js +1 -1
- package/examples/jsm/tsl/display/FXAANode.js +2 -2
- package/examples/jsm/tsl/display/GTAONode.js +2 -2
- package/examples/jsm/tsl/display/GaussianBlurNode.js +11 -2
- package/examples/jsm/tsl/display/GodraysNode.js +624 -0
- package/examples/jsm/tsl/display/LensflareNode.js +1 -1
- package/examples/jsm/tsl/display/Lut3DNode.js +1 -1
- package/examples/jsm/tsl/display/OutlineNode.js +3 -3
- package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +2 -2
- package/examples/jsm/tsl/display/PixelationPassNode.js +5 -5
- package/examples/jsm/tsl/display/RGBShiftNode.js +2 -2
- package/examples/jsm/tsl/display/RetroPassNode.js +263 -0
- package/examples/jsm/tsl/display/SMAANode.js +2 -2
- package/examples/jsm/tsl/display/SSAAPassNode.js +2 -2
- package/examples/jsm/tsl/display/SSGINode.js +2 -2
- package/examples/jsm/tsl/display/SSRNode.js +7 -7
- package/examples/jsm/tsl/display/SSSNode.js +2 -2
- package/examples/jsm/tsl/display/Shape.js +29 -0
- package/examples/jsm/tsl/display/SobelOperatorNode.js +2 -2
- package/examples/jsm/tsl/display/StereoPassNode.js +1 -2
- package/examples/jsm/tsl/display/TRAANode.js +9 -12
- package/examples/jsm/tsl/display/TransitionNode.js +1 -1
- package/examples/jsm/tsl/display/depthAwareBlend.js +80 -0
- package/examples/jsm/tsl/math/Bayer.js +40 -1
- package/examples/jsm/utils/LDrawUtils.js +1 -1
- package/package.json +11 -19
- package/src/Three.Core.js +1 -1
- package/src/Three.TSL.js +5 -9
- package/src/Three.WebGPU.Nodes.js +2 -0
- package/src/Three.WebGPU.js +3 -0
- package/src/Three.js +1 -0
- package/src/animation/AnimationAction.js +1 -1
- package/src/animation/AnimationClip.js +1 -1
- package/src/animation/AnimationMixer.js +6 -0
- package/src/animation/KeyframeTrack.js +46 -7
- package/src/animation/PropertyMixer.js +4 -4
- package/src/audio/Audio.js +1 -1
- package/src/audio/AudioListener.js +5 -3
- package/src/cameras/Camera.js +32 -2
- package/src/cameras/CubeCamera.js +20 -0
- package/src/constants.js +30 -1
- package/src/core/Clock.js +7 -0
- package/src/core/Object3D.js +56 -4
- package/src/core/RenderTarget.js +3 -4
- package/src/extras/PMREMGenerator.js +4 -8
- package/src/geometries/TorusGeometry.js +8 -3
- package/src/helpers/CameraHelper.js +3 -0
- package/src/helpers/DirectionalLightHelper.js +4 -1
- package/src/helpers/HemisphereLightHelper.js +3 -0
- package/src/helpers/PointLightHelper.js +0 -24
- package/src/helpers/SpotLightHelper.js +3 -0
- package/src/lights/LightShadow.js +15 -3
- package/src/lights/webgpu/IESSpotLight.js +2 -1
- package/src/loaders/Cache.js +28 -0
- package/src/loaders/FileLoader.js +1 -1
- package/src/loaders/ImageBitmapLoader.js +8 -3
- package/src/loaders/Loader.js +6 -0
- package/src/loaders/ObjectLoader.js +18 -1
- package/src/materials/MeshLambertMaterial.js +9 -0
- package/src/materials/MeshPhongMaterial.js +9 -0
- package/src/materials/nodes/Line2NodeMaterial.js +5 -5
- package/src/materials/nodes/MeshPhysicalNodeMaterial.js +2 -0
- package/src/materials/nodes/NodeMaterial.js +15 -24
- package/src/materials/nodes/manager/NodeMaterialObserver.js +9 -3
- package/src/math/Line3.js +3 -5
- package/src/math/MathUtils.js +10 -10
- package/src/math/Matrix4.js +35 -26
- package/src/math/Quaternion.js +3 -29
- package/src/math/Vector3.js +3 -3
- package/src/math/interpolants/BezierInterpolant.js +108 -0
- package/src/nodes/Nodes.js +87 -68
- package/src/nodes/TSL.js +2 -5
- package/src/nodes/accessors/Arrays.js +1 -1
- package/src/nodes/accessors/Bitangent.js +5 -5
- package/src/nodes/accessors/BufferAttributeNode.js +1 -1
- package/src/nodes/accessors/Camera.js +149 -28
- package/src/nodes/accessors/InstanceNode.js +105 -40
- package/src/nodes/accessors/Normal.js +9 -9
- package/src/nodes/accessors/Position.js +34 -2
- package/src/nodes/accessors/SceneProperties.js +53 -0
- package/src/nodes/accessors/SkinningNode.js +12 -24
- package/src/nodes/accessors/StorageBufferNode.js +0 -19
- package/src/nodes/accessors/StorageTextureNode.js +37 -1
- package/src/nodes/accessors/Tangent.js +3 -3
- package/src/nodes/accessors/Texture3DNode.js +6 -34
- package/src/nodes/accessors/TextureNode.js +58 -22
- package/src/nodes/accessors/UniformArrayNode.js +2 -0
- package/src/nodes/core/MRTNode.js +48 -2
- package/src/nodes/core/Node.js +29 -3
- package/src/nodes/core/NodeBuilder.js +115 -40
- package/src/nodes/core/NodeError.js +28 -0
- package/src/nodes/core/NodeUtils.js +5 -3
- package/src/nodes/core/OutputStructNode.js +12 -10
- package/src/nodes/core/ParameterNode.js +2 -1
- package/src/nodes/core/StackNode.js +9 -8
- package/src/nodes/core/StackTrace.js +139 -0
- package/src/nodes/core/StructNode.js +15 -0
- package/src/nodes/core/SubBuildNode.js +1 -1
- package/src/nodes/core/UniformNode.js +2 -1
- package/src/nodes/core/VarNode.js +1 -1
- package/src/nodes/core/VaryingNode.js +1 -18
- package/src/nodes/display/BlendModes.js +0 -64
- package/src/nodes/display/ColorAdjustment.js +17 -0
- package/src/nodes/display/ColorSpaceNode.js +3 -3
- package/src/nodes/display/NormalMapNode.js +2 -2
- package/src/nodes/display/PassNode.js +21 -2
- package/src/nodes/display/RenderOutputNode.js +3 -3
- package/src/nodes/display/ScreenNode.js +2 -1
- package/src/nodes/display/ToneMappingNode.js +1 -1
- package/src/nodes/display/ToonOutlinePassNode.js +2 -2
- package/src/nodes/display/ViewportDepthNode.js +52 -4
- package/src/nodes/display/ViewportTextureNode.js +21 -4
- package/src/nodes/fog/Fog.js +18 -35
- package/src/nodes/functions/PhysicalLightingModel.js +25 -3
- package/src/nodes/geometry/RangeNode.js +4 -2
- package/src/nodes/gpgpu/ComputeNode.js +5 -4
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -1
- package/src/nodes/lighting/EnvironmentNode.js +28 -3
- package/src/nodes/lighting/PointShadowNode.js +24 -12
- package/src/nodes/lighting/ShadowFilterNode.js +15 -43
- package/src/nodes/lighting/ShadowNode.js +54 -32
- package/src/nodes/math/ConditionalNode.js +2 -2
- package/src/nodes/math/MathNode.js +3 -40
- package/src/nodes/math/OperatorNode.js +2 -1
- package/src/nodes/pmrem/PMREMUtils.js +9 -15
- package/src/nodes/tsl/TSLCore.js +13 -10
- package/src/nodes/utils/DebugNode.js +11 -11
- package/src/nodes/utils/JoinNode.js +2 -2
- package/src/nodes/utils/LoopNode.js +1 -1
- package/src/nodes/utils/MemberNode.js +1 -1
- package/src/nodes/utils/RTTNode.js +1 -1
- package/src/nodes/utils/ReflectorNode.js +2 -3
- package/src/nodes/utils/SpriteSheetUV.js +35 -0
- package/src/nodes/utils/UVUtils.js +4 -2
- package/src/objects/BatchedMesh.js +22 -12
- package/src/objects/InstancedMesh.js +11 -0
- package/src/renderers/WebGLRenderer.js +34 -60
- package/src/renderers/common/Backend.js +21 -0
- package/src/renderers/common/Background.js +7 -4
- package/src/renderers/common/BindGroup.js +1 -9
- package/src/renderers/common/Bindings.js +20 -5
- package/src/renderers/common/BlendMode.js +143 -0
- package/src/renderers/common/BundleGroup.js +1 -1
- package/src/renderers/common/CubeRenderTarget.js +50 -6
- package/src/renderers/common/Geometries.js +17 -3
- package/src/renderers/common/Lighting.js +5 -21
- package/src/renderers/common/Pipelines.js +4 -4
- package/src/renderers/common/PostProcessing.js +8 -206
- package/src/renderers/common/RenderBundles.js +2 -1
- package/src/renderers/common/RenderContext.js +16 -0
- package/src/renderers/common/RenderContexts.js +33 -56
- package/src/renderers/common/RenderLists.js +2 -1
- package/src/renderers/common/RenderObject.js +2 -3
- package/src/renderers/common/RenderObjectPipeline.js +40 -0
- package/src/renderers/common/RenderObjects.js +18 -2
- package/src/renderers/common/RenderPipeline.js +203 -17
- package/src/renderers/common/Renderer.js +207 -40
- package/src/renderers/common/Sampler.js +4 -4
- package/src/renderers/common/StorageBuffer.js +13 -1
- package/src/renderers/common/Textures.js +16 -0
- package/src/renderers/common/TimestampQueryPool.js +5 -3
- package/src/renderers/common/Uniform.js +8 -0
- package/src/renderers/common/UniformsGroup.js +60 -0
- package/src/renderers/common/XRManager.js +2 -2
- package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
- package/src/renderers/common/nodes/{Nodes.js → NodeManager.js} +18 -6
- package/src/renderers/common/nodes/NodeStorageBuffer.js +13 -2
- package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk/color_fragment.glsl.js +1 -5
- package/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js +1 -5
- package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -5
- package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +8 -10
- package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +4 -4
- package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +7 -11
- package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +6 -0
- package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +6 -2
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +23 -1
- package/src/renderers/shaders/ShaderChunk/packing.glsl.js +20 -4
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +55 -24
- package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -0
- package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -0
- package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -0
- package/src/renderers/shaders/ShaderLib.js +4 -2
- package/src/renderers/shaders/UniformsLib.js +0 -3
- package/src/renderers/webgl/WebGLBackground.js +2 -2
- package/src/renderers/webgl/WebGLBindingStates.js +99 -27
- package/src/renderers/webgl/WebGLEnvironments.js +228 -0
- package/src/renderers/webgl/WebGLGeometries.js +10 -7
- package/src/renderers/webgl/WebGLMaterials.js +12 -0
- package/src/renderers/webgl/WebGLObjects.js +3 -1
- package/src/renderers/webgl/WebGLProgram.js +2 -2
- package/src/renderers/webgl/WebGLPrograms.js +10 -4
- package/src/renderers/webgl/WebGLRenderLists.js +15 -0
- package/src/renderers/webgl/WebGLShadowMap.js +5 -4
- package/src/renderers/webgl/WebGLState.js +12 -17
- package/src/renderers/webgl-fallback/WebGLBackend.js +71 -7
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +98 -29
- package/src/renderers/webgl-fallback/utils/WebGLState.js +168 -7
- package/src/renderers/webgpu/WebGPUBackend.js +58 -9
- package/src/renderers/webgpu/WebGPURenderer.js +1 -0
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +257 -45
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +8 -19
- package/src/renderers/webgpu/utils/WebGPUConstants.js +1 -1
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +56 -31
- package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +152 -200
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +25 -25
- package/src/renderers/webgpu/utils/WebGPUUtils.js +10 -6
- package/src/renderers/webxr/WebXRManager.js +2 -2
- package/src/textures/Texture.js +2 -2
- package/src/utils.js +246 -3
- package/examples/jsm/materials/MeshGouraudMaterial.js +0 -433
- package/examples/jsm/materials/MeshPostProcessingMaterial.js +0 -167
- package/examples/jsm/shaders/GodRaysShader.js +0 -333
- package/src/nodes/accessors/SceneNode.js +0 -145
- package/src/nodes/code/ScriptableNode.js +0 -726
- package/src/nodes/code/ScriptableValueNode.js +0 -253
- package/src/nodes/display/PosterizeNode.js +0 -65
- package/src/nodes/utils/SpriteSheetUVNode.js +0 -90
- package/src/renderers/webgl/WebGLCubeMaps.js +0 -99
- 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
|
-
|
|
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
|
-
|
|
209
|
+
mesh.pivot = new Vector3( pivot[ 0 ], pivot[ 1 ], pivot[ 2 ] );
|
|
227
210
|
|
|
228
|
-
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
12
|
+
* A loader for the USD format (USD, USDA, USDC, USDZ).
|
|
12
13
|
*
|
|
13
|
-
*
|
|
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
|
|
17
|
-
* const model = await loader.loadAsync( '
|
|
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
|
-
|
|
127
|
+
const fileBytes = zip[ filename ];
|
|
128
|
+
const ext = getLowercaseExtension( filename );
|
|
101
129
|
|
|
102
|
-
|
|
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
|
-
|
|
136
|
+
}
|
|
108
137
|
|
|
109
|
-
|
|
138
|
+
if ( ext !== 'usd' && ext !== 'usda' && ext !== 'usdc' ) continue;
|
|
110
139
|
|
|
111
|
-
|
|
140
|
+
if ( isCrateFile( fileBytes ) ) {
|
|
112
141
|
|
|
113
|
-
|
|
142
|
+
data[ filename ] = usdc.parseData( toArrayBuffer( fileBytes ) );
|
|
114
143
|
|
|
115
|
-
|
|
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 (
|
|
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
|
-
|
|
175
|
+
const fileNames = Object.keys( zip );
|
|
176
|
+
if ( fileNames.length < 1 ) return { file: undefined, filename: '', basePath: '' };
|
|
149
177
|
|
|
150
|
-
const firstFileName =
|
|
178
|
+
const firstFileName = fileNames[ 0 ];
|
|
179
|
+
const ext = getLowercaseExtension( firstFileName );
|
|
151
180
|
let isCrate = false;
|
|
152
181
|
|
|
153
|
-
|
|
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
|
-
|
|
156
|
-
if ( firstFileName.endsWith( 'usda' ) ) return zip[ firstFileName ];
|
|
187
|
+
if ( ext === 'usda' ) return { file: zip[ firstFileName ], filename: firstFileName, basePath };
|
|
157
188
|
|
|
158
|
-
if (
|
|
189
|
+
if ( ext === 'usdc' ) {
|
|
159
190
|
|
|
160
191
|
isCrate = true;
|
|
161
192
|
|
|
162
|
-
} else if (
|
|
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
|
-
|
|
218
|
+
const scope = this;
|
|
219
|
+
|
|
220
|
+
// USDA (standalone)
|
|
186
221
|
|
|
187
222
|
if ( typeof buffer === 'string' ) {
|
|
188
223
|
|
|
189
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
250
|
+
if ( ! file ) {
|
|
206
251
|
|
|
207
|
-
|
|
252
|
+
throw new Error( 'USDLoader: Invalid USDZ package. The first ZIP entry must be a USD layer (.usd/.usda/.usdc).' );
|
|
208
253
|
|
|
209
|
-
|
|
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
|
-
|
|
268
|
+
// USDA (standalone, as ArrayBuffer)
|
|
212
269
|
|
|
213
|
-
|
|
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
|
-
* [
|
|
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
|
-
* [
|
|
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 (
|
|
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
|
|
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
|
-
|
|
206
|
+
metadata
|
|
205
207
|
);
|
|
206
208
|
|
|
207
209
|
} else if ( sectionType === 0xe2 ) {
|
|
208
210
|
|
|
209
|
-
/* Data Sections - MPF /
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
412
|
-
|
|
563
|
+
metadata.version = gainmapNode.getAttribute( 'hdrgm:Version' );
|
|
564
|
+
metadata.baseRenditionIsHDR =
|
|
413
565
|
gainmapNode.getAttribute( 'hdrgm:BaseRenditionIsHDR' ) === 'True';
|
|
414
|
-
|
|
566
|
+
metadata.gainMapMin = parseFloat(
|
|
415
567
|
gainmapNode.getAttribute( 'hdrgm:GainMapMin' ) || 0.0
|
|
416
568
|
);
|
|
417
|
-
|
|
569
|
+
metadata.gainMapMax = parseFloat(
|
|
418
570
|
gainmapNode.getAttribute( 'hdrgm:GainMapMax' ) || 1.0
|
|
419
571
|
);
|
|
420
|
-
|
|
572
|
+
metadata.gamma = parseFloat(
|
|
421
573
|
gainmapNode.getAttribute( 'hdrgm:Gamma' ) || 1.0
|
|
422
574
|
);
|
|
423
|
-
|
|
575
|
+
metadata.offsetSDR = parseFloat(
|
|
424
576
|
gainmapNode.getAttribute( 'hdrgm:OffsetSDR' ) / ( 1 / 64 )
|
|
425
577
|
);
|
|
426
|
-
|
|
578
|
+
metadata.offsetHDR = parseFloat(
|
|
427
579
|
gainmapNode.getAttribute( 'hdrgm:OffsetHDR' ) / ( 1 / 64 )
|
|
428
580
|
);
|
|
429
|
-
|
|
581
|
+
metadata.hdrCapacityMin = parseFloat(
|
|
430
582
|
gainmapNode.getAttribute( 'hdrgm:HDRCapacityMin' ) || 0.0
|
|
431
583
|
);
|
|
432
|
-
|
|
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
|
-
|
|
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 ** (
|
|
682
|
+
const maxDisplayBoost = 1.8 ** ( metadata.hdrCapacityMax * 0.5 );
|
|
531
683
|
const unclampedWeightFactor =
|
|
532
|
-
( Math.log2( maxDisplayBoost ) -
|
|
533
|
-
(
|
|
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 =
|
|
543
|
-
const gainMapMax =
|
|
544
|
-
const offsetSDR =
|
|
545
|
-
const offsetHDR =
|
|
546
|
-
const invGamma = 1.0 /
|
|
547
|
-
const useGammaOne =
|
|
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;
|