super-three 0.177.0 → 0.181.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 (501) hide show
  1. package/README.md +1 -1
  2. package/build/three.cjs +1994 -749
  3. package/build/three.core.js +1358 -506
  4. package/build/three.core.min.js +1 -1
  5. package/build/three.module.js +631 -247
  6. package/build/three.module.min.js +1 -1
  7. package/build/three.tsl.js +113 -33
  8. package/build/three.tsl.min.js +1 -1
  9. package/build/three.webgpu.js +9571 -3424
  10. package/build/three.webgpu.min.js +1 -1
  11. package/build/three.webgpu.nodes.js +9397 -3426
  12. package/build/three.webgpu.nodes.min.js +1 -1
  13. package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
  14. package/examples/fonts/MPLUSRounded1c/OFL.txt +91 -0
  15. package/examples/jsm/Addons.js +2 -3
  16. package/examples/jsm/animation/CCDIKSolver.js +1 -1
  17. package/examples/jsm/capabilities/WebGL.js +0 -27
  18. package/examples/jsm/capabilities/WebGPU.js +1 -1
  19. package/examples/jsm/controls/ArcballControls.js +9 -9
  20. package/examples/jsm/controls/DragControls.js +7 -57
  21. package/examples/jsm/controls/FirstPersonControls.js +3 -3
  22. package/examples/jsm/controls/FlyControls.js +1 -1
  23. package/examples/jsm/controls/OrbitControls.js +2 -2
  24. package/examples/jsm/controls/PointerLockControls.js +2 -10
  25. package/examples/jsm/controls/TrackballControls.js +1 -1
  26. package/examples/jsm/controls/TransformControls.js +62 -15
  27. package/examples/jsm/csm/CSMShadowNode.js +4 -4
  28. package/examples/jsm/effects/AsciiEffect.js +8 -8
  29. package/examples/jsm/environments/RoomEnvironment.js +8 -3
  30. package/examples/jsm/exporters/DRACOExporter.js +2 -2
  31. package/examples/jsm/exporters/EXRExporter.js +1 -1
  32. package/examples/jsm/exporters/GLTFExporter.js +33 -25
  33. package/examples/jsm/exporters/KTX2Exporter.js +4 -2
  34. package/examples/jsm/exporters/PLYExporter.js +1 -1
  35. package/examples/jsm/exporters/USDZExporter.js +683 -299
  36. package/examples/jsm/geometries/DecalGeometry.js +2 -2
  37. package/examples/jsm/geometries/ParametricGeometry.js +1 -1
  38. package/examples/jsm/geometries/RoundedBoxGeometry.js +47 -8
  39. package/examples/jsm/geometries/TeapotGeometry.js +2 -2
  40. package/examples/jsm/geometries/TextGeometry.js +3 -2
  41. package/examples/jsm/gpgpu/BitonicSort.js +715 -0
  42. package/examples/jsm/helpers/ViewHelper.js +43 -5
  43. package/examples/jsm/inspector/Inspector.js +427 -0
  44. package/examples/jsm/inspector/RendererInspector.js +415 -0
  45. package/examples/jsm/inspector/tabs/Console.js +204 -0
  46. package/examples/jsm/inspector/tabs/Parameters.js +332 -0
  47. package/examples/jsm/inspector/tabs/Performance.js +268 -0
  48. package/examples/jsm/inspector/tabs/Viewer.js +166 -0
  49. package/examples/jsm/inspector/ui/Graph.js +95 -0
  50. package/examples/jsm/inspector/ui/Item.js +170 -0
  51. package/examples/jsm/inspector/ui/List.js +75 -0
  52. package/examples/jsm/inspector/ui/Profiler.js +170 -0
  53. package/examples/jsm/inspector/ui/Style.js +654 -0
  54. package/examples/jsm/inspector/ui/Tab.js +46 -0
  55. package/examples/jsm/inspector/ui/Values.js +423 -0
  56. package/examples/jsm/inspector/ui/utils.js +56 -0
  57. package/examples/jsm/interactive/HTMLMesh.js +11 -13
  58. package/examples/jsm/interactive/InteractiveGroup.js +1 -1
  59. package/examples/jsm/interactive/SelectionBox.js +30 -0
  60. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  61. package/examples/jsm/libs/meshopt_decoder.module.js +75 -58
  62. package/examples/jsm/lights/LightProbeGenerator.js +14 -3
  63. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  64. package/examples/jsm/lines/Line2.js +3 -3
  65. package/examples/jsm/lines/LineGeometry.js +1 -1
  66. package/examples/jsm/lines/LineSegments2.js +2 -2
  67. package/examples/jsm/lines/Wireframe.js +2 -2
  68. package/examples/jsm/lines/WireframeGeometry2.js +1 -1
  69. package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
  70. package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
  71. package/examples/jsm/loaders/3MFLoader.js +1 -1
  72. package/examples/jsm/loaders/ColladaLoader.js +4 -4
  73. package/examples/jsm/loaders/DDSLoader.js +1 -1
  74. package/examples/jsm/loaders/DRACOLoader.js +73 -22
  75. package/examples/jsm/loaders/EXRLoader.js +210 -22
  76. package/examples/jsm/loaders/FBXLoader.js +4 -4
  77. package/examples/jsm/loaders/FontLoader.js +23 -5
  78. package/examples/jsm/loaders/GLTFLoader.js +14 -8
  79. package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
  80. package/examples/jsm/loaders/HDRLoader.js +486 -0
  81. package/examples/jsm/loaders/KTX2Loader.js +136 -49
  82. package/examples/jsm/loaders/KTXLoader.js +2 -2
  83. package/examples/jsm/loaders/LDrawLoader.js +1 -1
  84. package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
  85. package/examples/jsm/loaders/LUTCubeLoader.js +1 -1
  86. package/examples/jsm/loaders/LWOLoader.js +2 -2
  87. package/examples/jsm/loaders/MaterialXLoader.js +233 -34
  88. package/examples/jsm/loaders/OBJLoader.js +1 -1
  89. package/examples/jsm/loaders/PDBLoader.js +1 -1
  90. package/examples/jsm/loaders/RGBELoader.js +7 -473
  91. package/examples/jsm/loaders/SVGLoader.js +2 -2
  92. package/examples/jsm/loaders/TTFLoader.js +13 -1
  93. package/examples/jsm/loaders/USDLoader.js +219 -0
  94. package/examples/jsm/loaders/USDZLoader.js +4 -892
  95. package/examples/jsm/loaders/UltraHDRLoader.js +2 -2
  96. package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
  97. package/examples/jsm/loaders/usd/USDAParser.js +741 -0
  98. package/examples/jsm/loaders/usd/USDCParser.js +17 -0
  99. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  100. package/examples/jsm/math/ColorSpaces.js +19 -1
  101. package/examples/jsm/math/ConvexHull.js +3 -3
  102. package/examples/jsm/math/ImprovedNoise.js +1 -1
  103. package/examples/jsm/math/Lut.js +2 -2
  104. package/examples/jsm/math/SimplexNoise.js +1 -1
  105. package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
  106. package/examples/jsm/misc/ProgressiveLightMap.js +9 -3
  107. package/examples/jsm/misc/ProgressiveLightMapGPU.js +7 -1
  108. package/examples/jsm/misc/TubePainter.js +383 -40
  109. package/examples/jsm/misc/Volume.js +1 -1
  110. package/examples/jsm/modifiers/SimplifyModifier.js +1 -1
  111. package/examples/jsm/objects/LensflareMesh.js +3 -3
  112. package/examples/jsm/objects/ReflectorForSSRPass.js +1 -0
  113. package/examples/jsm/objects/Sky.js +1 -1
  114. package/examples/jsm/objects/SkyMesh.js +3 -3
  115. package/examples/jsm/objects/Water.js +3 -3
  116. package/examples/jsm/objects/WaterMesh.js +6 -6
  117. package/examples/jsm/physics/RapierPhysics.js +95 -16
  118. package/examples/jsm/postprocessing/GTAOPass.js +10 -9
  119. package/examples/jsm/postprocessing/GlitchPass.js +2 -2
  120. package/examples/jsm/postprocessing/OutlinePass.js +17 -17
  121. package/examples/jsm/postprocessing/SSAOPass.js +10 -9
  122. package/examples/jsm/postprocessing/SSRPass.js +37 -8
  123. package/examples/jsm/postprocessing/UnrealBloomPass.js +8 -6
  124. package/examples/jsm/renderers/CSS2DRenderer.js +16 -5
  125. package/examples/jsm/renderers/CSS3DRenderer.js +7 -6
  126. package/examples/jsm/renderers/SVGRenderer.js +1 -1
  127. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +1 -1
  128. package/examples/jsm/shaders/AfterimageShader.js +1 -1
  129. package/examples/jsm/shaders/BleachBypassShader.js +1 -1
  130. package/examples/jsm/shaders/BokehShader.js +1 -1
  131. package/examples/jsm/shaders/BokehShader2.js +1 -1
  132. package/examples/jsm/shaders/DotScreenShader.js +1 -1
  133. package/examples/jsm/shaders/FocusShader.js +1 -1
  134. package/examples/jsm/shaders/GTAOShader.js +2 -2
  135. package/examples/jsm/shaders/GodRaysShader.js +1 -1
  136. package/examples/jsm/shaders/KaleidoShader.js +1 -1
  137. package/examples/jsm/shaders/PoissonDenoiseShader.js +2 -2
  138. package/examples/jsm/shaders/SSRShader.js +1 -1
  139. package/examples/jsm/shaders/SepiaShader.js +1 -1
  140. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +1 -1
  141. package/examples/jsm/shaders/TriangleBlurShader.js +1 -1
  142. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +11 -2
  143. package/examples/jsm/shaders/VignetteShader.js +1 -1
  144. package/examples/jsm/transpiler/AST.js +381 -30
  145. package/examples/jsm/transpiler/GLSLDecoder.js +247 -104
  146. package/examples/jsm/transpiler/Linker.js +327 -0
  147. package/examples/jsm/transpiler/TSLEncoder.js +196 -92
  148. package/examples/jsm/transpiler/Transpiler.js +17 -1
  149. package/examples/jsm/transpiler/TranspilerUtils.js +29 -0
  150. package/examples/jsm/transpiler/WGSLEncoder.js +812 -0
  151. package/examples/jsm/tsl/display/AfterImageNode.js +26 -24
  152. package/examples/jsm/tsl/display/AnamorphicNode.js +28 -4
  153. package/examples/jsm/tsl/display/BloomNode.js +11 -6
  154. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +207 -0
  155. package/examples/jsm/tsl/display/DenoiseNode.js +2 -0
  156. package/examples/jsm/tsl/display/DepthOfFieldNode.js +446 -90
  157. package/examples/jsm/tsl/display/GTAONode.js +53 -5
  158. package/examples/jsm/tsl/display/GaussianBlurNode.js +55 -43
  159. package/examples/jsm/tsl/display/OutlineNode.js +13 -2
  160. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -2
  161. package/examples/jsm/tsl/display/SSGINode.js +654 -0
  162. package/examples/jsm/tsl/display/SSRNode.js +182 -65
  163. package/examples/jsm/tsl/display/SSSNode.js +488 -0
  164. package/examples/jsm/tsl/display/TRAANode.js +578 -0
  165. package/examples/jsm/tsl/display/boxBlur.js +65 -0
  166. package/examples/jsm/tsl/display/hashBlur.js +18 -20
  167. package/examples/jsm/tsl/lighting/TiledLightsNode.js +22 -2
  168. package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
  169. package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
  170. package/examples/jsm/webxr/OculusHandModel.js +1 -1
  171. package/examples/jsm/webxr/XRControllerModelFactory.js +1 -1
  172. package/examples/jsm/webxr/XRHandModelFactory.js +2 -6
  173. package/package.json +5 -10
  174. package/src/Three.Core.js +5 -2
  175. package/src/Three.TSL.js +112 -32
  176. package/src/Three.WebGPU.Nodes.js +2 -0
  177. package/src/Three.WebGPU.js +4 -0
  178. package/src/animation/AnimationClip.js +20 -4
  179. package/src/animation/AnimationMixer.js +3 -3
  180. package/src/animation/AnimationObjectGroup.js +2 -1
  181. package/src/animation/KeyframeTrack.js +8 -7
  182. package/src/animation/PropertyBinding.js +12 -11
  183. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  184. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  185. package/src/audio/Audio.js +10 -9
  186. package/src/audio/PositionalAudio.js +1 -1
  187. package/src/cameras/Camera.js +14 -0
  188. package/src/cameras/OrthographicCamera.js +2 -2
  189. package/src/cameras/PerspectiveCamera.js +2 -2
  190. package/src/cameras/StereoCamera.js +2 -2
  191. package/src/constants.js +13 -5
  192. package/src/core/BufferAttribute.js +3 -3
  193. package/src/core/BufferGeometry.js +10 -10
  194. package/src/core/Clock.js +2 -8
  195. package/src/core/EventDispatcher.js +1 -1
  196. package/src/core/GLBufferAttribute.js +13 -1
  197. package/src/core/InterleavedBuffer.js +1 -1
  198. package/src/core/InterleavedBufferAttribute.js +3 -2
  199. package/src/core/Object3D.js +4 -3
  200. package/src/core/Raycaster.js +2 -1
  201. package/src/core/RenderTarget.js +10 -1
  202. package/{examples/jsm/misc → src/core}/Timer.js +4 -42
  203. package/src/extras/Controls.js +5 -4
  204. package/src/extras/DataUtils.js +2 -1
  205. package/src/extras/Earcut.js +6 -0
  206. package/src/extras/ImageUtils.js +2 -2
  207. package/src/extras/PMREMGenerator.js +279 -55
  208. package/src/extras/TextureUtils.js +2 -1
  209. package/src/extras/core/Curve.js +2 -1
  210. package/src/extras/core/Interpolations.js +7 -1
  211. package/src/extras/core/Path.js +22 -22
  212. package/src/extras/core/ShapePath.js +4 -4
  213. package/src/extras/lib/earcut.js +8 -8
  214. package/src/geometries/BoxGeometry.js +1 -0
  215. package/src/geometries/CapsuleGeometry.js +1 -0
  216. package/src/geometries/CircleGeometry.js +1 -0
  217. package/src/geometries/ConeGeometry.js +1 -0
  218. package/src/geometries/CylinderGeometry.js +1 -0
  219. package/src/geometries/DodecahedronGeometry.js +1 -0
  220. package/src/geometries/ExtrudeGeometry.js +8 -6
  221. package/src/geometries/IcosahedronGeometry.js +1 -0
  222. package/src/geometries/LatheGeometry.js +1 -0
  223. package/src/geometries/OctahedronGeometry.js +1 -0
  224. package/src/geometries/PlaneGeometry.js +1 -0
  225. package/src/geometries/RingGeometry.js +1 -0
  226. package/src/geometries/ShapeGeometry.js +1 -0
  227. package/src/geometries/SphereGeometry.js +1 -0
  228. package/src/geometries/TetrahedronGeometry.js +1 -0
  229. package/src/geometries/TorusGeometry.js +1 -0
  230. package/src/geometries/TorusKnotGeometry.js +1 -0
  231. package/src/geometries/TubeGeometry.js +1 -0
  232. package/src/helpers/CameraHelper.js +42 -12
  233. package/src/helpers/SkeletonHelper.js +35 -6
  234. package/src/lights/LightShadow.js +21 -8
  235. package/src/lights/PointLightShadow.js +1 -1
  236. package/src/lights/webgpu/ProjectorLight.js +1 -1
  237. package/src/loaders/AnimationLoader.js +2 -1
  238. package/src/loaders/AudioLoader.js +2 -1
  239. package/src/loaders/BufferGeometryLoader.js +2 -2
  240. package/src/loaders/Cache.js +2 -2
  241. package/src/loaders/DataTextureLoader.js +1 -1
  242. package/src/loaders/FileLoader.js +29 -5
  243. package/src/loaders/ImageBitmapLoader.js +32 -8
  244. package/src/loaders/ImageLoader.js +56 -9
  245. package/src/loaders/Loader.js +17 -3
  246. package/src/loaders/LoadingManager.js +45 -0
  247. package/src/loaders/MaterialLoader.js +3 -2
  248. package/src/loaders/ObjectLoader.js +13 -13
  249. package/src/loaders/TextureLoader.js +1 -1
  250. package/src/loaders/nodes/NodeLoader.js +3 -2
  251. package/src/materials/Material.js +16 -3
  252. package/src/materials/MeshBasicMaterial.js +2 -1
  253. package/src/materials/MeshDepthMaterial.js +1 -0
  254. package/src/materials/MeshDistanceMaterial.js +1 -1
  255. package/src/materials/MeshLambertMaterial.js +2 -1
  256. package/src/materials/MeshMatcapMaterial.js +22 -0
  257. package/src/materials/MeshNormalMaterial.js +1 -0
  258. package/src/materials/MeshPhongMaterial.js +2 -1
  259. package/src/materials/MeshPhysicalMaterial.js +2 -1
  260. package/src/materials/MeshStandardMaterial.js +8 -7
  261. package/src/materials/MeshToonMaterial.js +1 -0
  262. package/src/materials/PointsMaterial.js +1 -1
  263. package/src/materials/ShaderMaterial.js +2 -2
  264. package/src/materials/nodes/Line2NodeMaterial.js +2 -10
  265. package/src/materials/nodes/MeshBasicNodeMaterial.js +4 -3
  266. package/src/materials/nodes/MeshMatcapNodeMaterial.js +1 -1
  267. package/src/materials/nodes/MeshNormalNodeMaterial.js +2 -2
  268. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +2 -1
  269. package/src/materials/nodes/MeshSSSNodeMaterial.js +3 -3
  270. package/src/materials/nodes/NodeMaterial.js +90 -27
  271. package/src/materials/nodes/PointsNodeMaterial.js +86 -28
  272. package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
  273. package/src/materials/nodes/manager/NodeMaterialObserver.js +89 -3
  274. package/src/math/Color.js +6 -5
  275. package/src/math/ColorManagement.js +9 -3
  276. package/src/math/Cylindrical.js +1 -1
  277. package/src/math/Euler.js +2 -1
  278. package/src/math/Frustum.js +25 -9
  279. package/src/math/FrustumArray.js +10 -5
  280. package/src/math/Line3.js +129 -2
  281. package/src/math/MathUtils.js +13 -11
  282. package/src/math/Matrix2.js +1 -1
  283. package/src/math/Matrix3.js +2 -2
  284. package/src/math/Matrix4.js +55 -34
  285. package/src/math/Plane.js +1 -1
  286. package/src/math/Quaternion.js +69 -67
  287. package/src/math/Spherical.js +3 -3
  288. package/src/nodes/Nodes.js +6 -4
  289. package/src/nodes/TSL.js +9 -4
  290. package/src/nodes/accessors/AccessorsUtils.js +7 -8
  291. package/src/nodes/accessors/Bitangent.js +31 -25
  292. package/src/nodes/accessors/BufferNode.js +1 -1
  293. package/src/nodes/accessors/Camera.js +142 -16
  294. package/src/nodes/accessors/ClippingNode.js +6 -5
  295. package/src/nodes/accessors/CubeTextureNode.js +5 -4
  296. package/src/nodes/accessors/InstanceNode.js +25 -5
  297. package/src/nodes/accessors/Lights.js +10 -0
  298. package/src/nodes/accessors/Normal.js +97 -30
  299. package/src/nodes/accessors/Object3DNode.js +2 -2
  300. package/src/nodes/accessors/Position.js +25 -9
  301. package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
  302. package/src/nodes/accessors/ReferenceNode.js +20 -4
  303. package/src/nodes/accessors/ReflectVector.js +3 -3
  304. package/src/nodes/accessors/SceneNode.js +3 -2
  305. package/src/nodes/accessors/StorageBufferNode.js +2 -1
  306. package/src/nodes/accessors/StorageTextureNode.js +23 -1
  307. package/src/nodes/accessors/Tangent.js +25 -17
  308. package/src/nodes/accessors/TangentUtils.js +46 -0
  309. package/src/nodes/accessors/Texture3DNode.js +14 -1
  310. package/src/nodes/accessors/TextureBicubic.js +21 -3
  311. package/src/nodes/accessors/TextureNode.js +142 -44
  312. package/src/nodes/accessors/UniformArrayNode.js +0 -16
  313. package/src/nodes/code/FunctionCallNode.js +24 -4
  314. package/src/nodes/code/FunctionNode.js +23 -0
  315. package/src/nodes/core/ArrayNode.js +13 -0
  316. package/src/nodes/core/AssignNode.js +6 -2
  317. package/src/nodes/core/AttributeNode.js +2 -1
  318. package/src/nodes/core/ContextNode.js +48 -10
  319. package/src/nodes/core/IndexNode.js +2 -2
  320. package/src/nodes/core/InputNode.js +2 -1
  321. package/src/nodes/core/InspectorNode.js +128 -0
  322. package/src/nodes/core/{CacheNode.js → IsolateNode.js} +36 -17
  323. package/src/nodes/core/Node.js +167 -34
  324. package/src/nodes/core/NodeBuilder.js +404 -120
  325. package/src/nodes/core/NodeFrame.js +21 -21
  326. package/src/nodes/core/NodeFunction.js +2 -1
  327. package/src/nodes/core/NodeParser.js +2 -1
  328. package/src/nodes/core/NodeUniform.js +1 -1
  329. package/src/nodes/core/NodeUtils.js +17 -88
  330. package/src/nodes/core/ParameterNode.js +31 -0
  331. package/src/nodes/core/PropertyNode.js +7 -0
  332. package/src/nodes/core/StackNode.js +77 -30
  333. package/src/nodes/core/StructNode.js +5 -5
  334. package/src/nodes/core/StructTypeNode.js +1 -0
  335. package/src/nodes/core/SubBuildNode.js +89 -0
  336. package/src/nodes/core/UniformNode.js +80 -14
  337. package/src/nodes/core/VarNode.js +142 -16
  338. package/src/nodes/core/VaryingNode.js +9 -6
  339. package/src/nodes/display/BlendModes.js +7 -6
  340. package/src/nodes/display/BumpMapNode.js +1 -1
  341. package/src/nodes/display/ColorAdjustment.js +1 -1
  342. package/src/nodes/display/FrontFacingNode.js +35 -7
  343. package/src/nodes/display/NormalMapNode.js +20 -50
  344. package/src/nodes/display/PassNode.js +206 -17
  345. package/src/nodes/display/RenderOutputNode.js +28 -2
  346. package/src/nodes/display/ScreenNode.js +44 -40
  347. package/src/nodes/display/ToneMappingNode.js +31 -4
  348. package/src/nodes/display/ToonOutlinePassNode.js +8 -0
  349. package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
  350. package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
  351. package/src/nodes/display/ViewportTextureNode.js +94 -4
  352. package/src/nodes/fog/Fog.js +3 -2
  353. package/src/nodes/functions/BSDF/BRDF_GGX.js +2 -6
  354. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +52 -0
  355. package/src/nodes/functions/BSDF/BRDF_Sheen.js +4 -4
  356. package/src/nodes/functions/BSDF/DFGApprox.js +60 -19
  357. package/src/nodes/functions/BasicLightingModel.js +2 -1
  358. package/src/nodes/functions/PhongLightingModel.js +3 -3
  359. package/src/nodes/functions/PhysicalLightingModel.js +19 -18
  360. package/src/nodes/functions/VolumetricLightingModel.js +5 -5
  361. package/src/nodes/functions/material/getGeometryRoughness.js +2 -2
  362. package/src/nodes/geometry/RangeNode.js +40 -4
  363. package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
  364. package/src/nodes/gpgpu/ComputeBuiltinNode.js +2 -1
  365. package/src/nodes/gpgpu/ComputeNode.js +81 -25
  366. package/src/nodes/gpgpu/SubgroupFunctionNode.js +455 -0
  367. package/src/nodes/gpgpu/WorkgroupInfoNode.js +29 -3
  368. package/src/nodes/lighting/EnvironmentNode.js +11 -11
  369. package/src/nodes/lighting/LightsNode.js +7 -8
  370. package/src/nodes/lighting/PointShadowNode.js +6 -0
  371. package/src/nodes/lighting/ProjectorLightNode.js +19 -6
  372. package/src/nodes/lighting/ShadowFilterNode.js +3 -1
  373. package/src/nodes/lighting/ShadowNode.js +77 -10
  374. package/src/nodes/materialx/MaterialXNodes.js +131 -2
  375. package/src/nodes/materialx/lib/mx_noise.js +165 -1
  376. package/src/nodes/math/BitcastNode.js +156 -0
  377. package/src/nodes/math/ConditionalNode.js +25 -27
  378. package/src/nodes/math/MathNode.js +106 -65
  379. package/src/nodes/math/OperatorNode.js +28 -43
  380. package/src/nodes/pmrem/PMREMUtils.js +117 -2
  381. package/src/nodes/shapes/Shapes.js +1 -1
  382. package/src/nodes/tsl/TSLBase.js +6 -2
  383. package/src/nodes/tsl/TSLCore.js +546 -186
  384. package/src/nodes/utils/DebugNode.js +3 -2
  385. package/src/nodes/utils/EquirectUV.js +27 -0
  386. package/src/nodes/utils/EventNode.js +119 -0
  387. package/src/nodes/utils/FunctionOverloadingNode.js +37 -19
  388. package/src/nodes/utils/JoinNode.js +6 -3
  389. package/src/nodes/utils/LoopNode.js +20 -41
  390. package/src/nodes/utils/MatcapUV.js +22 -0
  391. package/src/nodes/utils/MemberNode.js +59 -7
  392. package/src/nodes/utils/PostProcessingUtils.js +28 -1
  393. package/src/nodes/utils/RTTNode.js +33 -6
  394. package/src/nodes/utils/ReflectorNode.js +68 -10
  395. package/src/nodes/utils/SampleNode.js +91 -0
  396. package/src/nodes/utils/SplitNode.js +11 -0
  397. package/src/nodes/utils/Timer.js +0 -47
  398. package/src/nodes/utils/TriplanarTextures.js +65 -0
  399. package/src/objects/BatchedMesh.js +6 -4
  400. package/src/objects/LOD.js +1 -1
  401. package/src/objects/Line.js +2 -1
  402. package/src/objects/LineSegments.js +2 -1
  403. package/src/objects/Skeleton.js +3 -2
  404. package/src/objects/SkinnedMesh.js +3 -1
  405. package/src/objects/Sprite.js +4 -3
  406. package/src/renderers/WebGLRenderer.js +77 -66
  407. package/src/renderers/common/Animation.js +13 -1
  408. package/src/renderers/common/Attributes.js +1 -1
  409. package/src/renderers/common/Backend.js +108 -27
  410. package/src/renderers/common/Background.js +4 -3
  411. package/src/renderers/common/Bindings.js +76 -19
  412. package/src/renderers/common/CanvasTarget.js +341 -0
  413. package/src/renderers/common/ChainMap.js +1 -1
  414. package/src/renderers/common/Color4.js +2 -2
  415. package/src/renderers/common/CubeRenderTarget.js +1 -1
  416. package/src/renderers/common/DataMap.js +1 -1
  417. package/src/renderers/common/Geometries.js +26 -0
  418. package/src/renderers/common/Info.js +4 -2
  419. package/src/renderers/common/InspectorBase.js +146 -0
  420. package/src/renderers/common/Pipelines.js +1 -1
  421. package/src/renderers/common/PostProcessing.js +61 -25
  422. package/src/renderers/common/QuadMesh.js +7 -1
  423. package/src/renderers/common/RenderContext.js +2 -2
  424. package/src/renderers/common/RenderList.js +7 -3
  425. package/src/renderers/common/RenderObject.js +84 -5
  426. package/src/renderers/common/RenderObjects.js +1 -1
  427. package/src/renderers/common/Renderer.js +486 -255
  428. package/src/renderers/common/RendererUtils.js +9 -0
  429. package/src/renderers/common/SampledTexture.js +8 -68
  430. package/src/renderers/common/Sampler.js +117 -0
  431. package/src/renderers/common/Storage3DTexture.js +100 -0
  432. package/src/renderers/common/StorageArrayTexture.js +84 -0
  433. package/src/renderers/common/StorageTexture.js +27 -0
  434. package/src/renderers/common/Textures.js +138 -46
  435. package/src/renderers/common/TimestampQueryPool.js +65 -3
  436. package/src/renderers/common/UniformsGroup.js +2 -1
  437. package/src/renderers/common/XRManager.js +63 -24
  438. package/src/renderers/common/XRRenderTarget.js +21 -4
  439. package/src/renderers/common/extras/PMREMGenerator.js +161 -66
  440. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  441. package/src/renderers/common/nodes/NodeLibrary.js +9 -7
  442. package/src/renderers/common/nodes/NodeSampledTexture.js +0 -12
  443. package/src/renderers/common/nodes/NodeSampler.js +13 -1
  444. package/src/renderers/common/nodes/Nodes.js +38 -16
  445. package/src/renderers/shaders/DFGLUTData.js +64 -0
  446. package/src/renderers/shaders/ShaderChunk/common.glsl.js +0 -12
  447. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -1
  448. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +1 -1
  449. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +52 -18
  450. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  451. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  452. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  453. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  454. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +21 -11
  455. package/src/renderers/shaders/ShaderLib/depth.glsl.js +11 -2
  456. package/src/renderers/shaders/UniformsLib.js +1 -0
  457. package/src/renderers/shaders/UniformsUtils.js +25 -4
  458. package/src/renderers/webgl/WebGLAttributes.js +4 -0
  459. package/src/renderers/webgl/WebGLCapabilities.js +4 -3
  460. package/src/renderers/webgl/WebGLExtensions.js +2 -25
  461. package/src/renderers/webgl/WebGLInfo.js +3 -1
  462. package/src/renderers/webgl/WebGLProgram.js +25 -18
  463. package/src/renderers/webgl/WebGLPrograms.js +9 -6
  464. package/src/renderers/webgl/WebGLShadowMap.js +13 -2
  465. package/src/renderers/webgl/WebGLState.js +17 -16
  466. package/src/renderers/webgl/WebGLTextures.js +38 -21
  467. package/src/renderers/webgl/WebGLUniformsGroups.js +5 -3
  468. package/src/renderers/webgl/WebGLUtils.js +3 -2
  469. package/src/renderers/webgl-fallback/WebGLBackend.js +245 -182
  470. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +184 -30
  471. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +4 -0
  472. package/src/renderers/webgl-fallback/utils/WebGLConstants.js +2 -3
  473. package/src/renderers/webgl-fallback/utils/WebGLState.js +9 -8
  474. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +171 -19
  475. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +51 -22
  476. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
  477. package/src/renderers/webgpu/WebGPUBackend.js +205 -128
  478. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +2 -1
  479. package/src/renderers/webgpu/WebGPURenderer.js +3 -2
  480. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +198 -121
  481. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +8 -1
  482. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +49 -33
  483. package/src/renderers/webgpu/utils/WebGPUConstants.js +14 -3
  484. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +56 -37
  485. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +6 -8
  486. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +266 -158
  487. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +32 -9
  488. package/src/renderers/webgpu/utils/WebGPUUtils.js +24 -19
  489. package/src/renderers/webxr/WebXRDepthSensing.js +6 -10
  490. package/src/renderers/webxr/WebXRManager.js +89 -13
  491. package/src/textures/ExternalTexture.js +56 -0
  492. package/src/textures/FramebufferTexture.js +2 -2
  493. package/src/textures/Source.js +14 -3
  494. package/src/textures/Texture.js +3 -2
  495. package/src/textures/VideoTexture.js +29 -2
  496. package/src/utils.js +67 -3
  497. package/examples/jsm/loaders/RGBMLoader.js +0 -1148
  498. package/examples/jsm/tsl/display/TRAAPassNode.js +0 -452
  499. package/src/nodes/utils/EquirectUVNode.js +0 -65
  500. package/src/nodes/utils/MatcapUVNode.js +0 -49
  501. package/src/nodes/utils/TriplanarTexturesNode.js +0 -148
@@ -9,6 +9,121 @@ import {
9
9
  zipSync,
10
10
  } from '../libs/fflate.module.js';
11
11
 
12
+ class USDNode {
13
+
14
+ constructor( name, type = '', metadata = [], properties = [] ) {
15
+
16
+ this.name = name;
17
+ this.type = type;
18
+ this.metadata = metadata;
19
+ this.properties = properties;
20
+ this.children = [];
21
+
22
+ }
23
+
24
+ addMetadata( key, value ) {
25
+
26
+ this.metadata.push( { key, value } );
27
+
28
+ }
29
+
30
+ addProperty( property, metadata = [] ) {
31
+
32
+ this.properties.push( { property, metadata } );
33
+
34
+ }
35
+
36
+ addChild( child ) {
37
+
38
+ this.children.push( child );
39
+
40
+ }
41
+
42
+ toString( indent = 0 ) {
43
+
44
+ const pad = '\t'.repeat( indent );
45
+
46
+ const formattedMetadata = this.metadata.map( ( item ) => {
47
+
48
+ const key = item.key;
49
+ const value = item.value;
50
+
51
+ if ( Array.isArray( value ) ) {
52
+
53
+ const lines = [];
54
+ lines.push( `${key} = {` );
55
+ value.forEach( ( line ) => {
56
+
57
+ lines.push( `${pad}\t\t${line}` );
58
+
59
+ } );
60
+ lines.push( `${pad}\t}` );
61
+ return lines.join( '\n' );
62
+
63
+ } else {
64
+
65
+ return `${key} = ${value}`;
66
+
67
+ }
68
+
69
+ } );
70
+
71
+ const meta = formattedMetadata.length
72
+ ? ` (\n${formattedMetadata
73
+ .map( ( l ) => `${pad}\t${l}` )
74
+ .join( '\n' )}\n${pad})`
75
+ : '';
76
+
77
+ const properties = this.properties.map( ( l ) => {
78
+
79
+ const property = l.property;
80
+ const metadata = l.metadata.length
81
+ ? ` (\n${l.metadata.map( ( m ) => `${pad}\t\t${m}` ).join( '\n' )}\n${pad}\t)`
82
+ : '';
83
+ return `${pad}\t${property}${metadata}`;
84
+
85
+ } );
86
+ const children = this.children.map( ( c ) => c.toString( indent + 1 ) );
87
+
88
+ const bodyLines = [];
89
+
90
+ if ( properties.length > 0 ) {
91
+
92
+ bodyLines.push( ...properties );
93
+
94
+ }
95
+
96
+ if ( children.length > 0 ) {
97
+
98
+ if ( properties.length > 0 ) {
99
+
100
+ bodyLines.push( '' );
101
+
102
+ }
103
+
104
+ for ( let i = 0; i < children.length; i ++ ) {
105
+
106
+ bodyLines.push( children[ i ] );
107
+ if ( i < children.length - 1 ) {
108
+
109
+ bodyLines.push( '' );
110
+
111
+ }
112
+
113
+ }
114
+
115
+ }
116
+
117
+ const bodyContent = bodyLines.join( '\n' );
118
+
119
+ const type = this.type ? this.type + ' ' : '';
120
+
121
+ return `${pad}def ${type}"${this.name}"${meta}\n${pad}{\n${bodyContent}\n${pad}}`;
122
+
123
+ }
124
+
125
+ }
126
+
12
127
  /**
13
128
  * An exporter for USDZ.
14
129
  *
@@ -74,15 +189,21 @@ class USDZExporter {
74
189
  */
75
190
  async parseAsync( scene, options = {} ) {
76
191
 
77
- options = Object.assign( {
78
- ar: {
79
- anchoring: { type: 'plane' },
80
- planeAnchoring: { alignment: 'horizontal' }
192
+ options = Object.assign(
193
+ {
194
+ ar: {
195
+ anchoring: { type: 'plane' },
196
+ planeAnchoring: { alignment: 'horizontal' },
197
+ },
198
+ includeAnchoringProperties: true,
199
+ onlyVisible: true,
200
+ quickLookCompatible: false,
201
+ maxTextureSize: 1024,
81
202
  },
82
- includeAnchoringProperties: true,
83
- quickLookCompatible: false,
84
- maxTextureSize: 1024,
85
- }, options );
203
+ options
204
+ );
205
+
206
+ const usedNames = new Set();
86
207
 
87
208
  const files = {};
88
209
  const modelFileName = 'model.usda';
@@ -90,57 +211,50 @@ class USDZExporter {
90
211
  // model file should be first in USDZ archive so we init it here
91
212
  files[ modelFileName ] = null;
92
213
 
93
- let output = buildHeader();
94
-
95
- output += buildSceneStart( options );
96
-
97
- const materials = {};
98
- const textures = {};
99
-
100
- scene.traverseVisible( ( object ) => {
101
-
102
- if ( object.isMesh ) {
103
-
104
- const geometry = object.geometry;
105
- const material = object.material;
106
-
107
- if ( material.isMeshStandardMaterial ) {
108
-
109
- const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usda';
110
-
111
- if ( ! ( geometryFileName in files ) ) {
112
-
113
- const meshObject = buildMeshObject( geometry );
114
- files[ geometryFileName ] = buildUSDFileAsString( meshObject );
115
-
116
- }
214
+ const root = new USDNode( 'Root', 'Xform' );
215
+ const scenesNode = new USDNode( 'Scenes', 'Scope' );
216
+ scenesNode.addMetadata( 'kind', '"sceneLibrary"' );
217
+ root.addChild( scenesNode );
218
+
219
+ const sceneName = 'Scene';
220
+ const sceneNode = new USDNode( sceneName, 'Xform' );
221
+ sceneNode.addMetadata( 'customData', [
222
+ 'bool preliminary_collidesWithEnvironment = 0',
223
+ `string sceneName = "${sceneName}"`,
224
+ ] );
225
+ sceneNode.addMetadata( 'sceneName', `"${sceneName}"` );
226
+ if ( options.includeAnchoringProperties ) {
227
+
228
+ sceneNode.addProperty(
229
+ `token preliminary:anchoring:type = "${options.ar.anchoring.type}"`
230
+ );
231
+ sceneNode.addProperty(
232
+ `token preliminary:planeAnchoring:alignment = "${options.ar.planeAnchoring.alignment}"`
233
+ );
117
234
 
118
- if ( ! ( material.uuid in materials ) ) {
119
-
120
- materials[ material.uuid ] = material;
121
-
122
- }
123
-
124
- output += buildXform( object, geometry, materials[ material.uuid ] );
125
-
126
- } else {
127
-
128
- console.warn( 'THREE.USDZExporter: Unsupported material type (USDZ only supports MeshStandardMaterial)', object );
129
-
130
- }
131
-
132
- } else if ( object.isCamera ) {
235
+ }
133
236
 
134
- output += buildCamera( object );
237
+ scenesNode.addChild( sceneNode );
135
238
 
136
- }
239
+ let output;
137
240
 
138
- } );
241
+ const materials = {};
242
+ const textures = {};
139
243
 
244
+ buildHierarchy( scene, sceneNode, materials, usedNames, files, options );
140
245
 
141
- output += buildSceneEnd();
246
+ const materialsNode = buildMaterials(
247
+ materials,
248
+ textures,
249
+ options.quickLookCompatible
250
+ );
142
251
 
143
- output += buildMaterials( materials, textures, options.quickLookCompatible );
252
+ output =
253
+ buildHeader() +
254
+ '\n' +
255
+ root.toString() +
256
+ '\n\n' +
257
+ materialsNode.toString();
144
258
 
145
259
  files[ modelFileName ] = strToU8( output );
146
260
  output = null;
@@ -153,7 +267,9 @@ class USDZExporter {
153
267
 
154
268
  if ( this.textureUtils === null ) {
155
269
 
156
- throw new Error( 'THREE.USDZExporter: setTextureUtils() must be called to process compressed textures.' );
270
+ throw new Error(
271
+ 'THREE.USDZExporter: setTextureUtils() must be called to process compressed textures.'
272
+ );
157
273
 
158
274
  } else {
159
275
 
@@ -163,10 +279,18 @@ class USDZExporter {
163
279
 
164
280
  }
165
281
 
166
- const canvas = imageToCanvas( texture.image, texture.flipY, options.maxTextureSize );
167
- const blob = await new Promise( resolve => canvas.toBlob( resolve, 'image/png', 1 ) );
282
+ const canvas = imageToCanvas(
283
+ texture.image,
284
+ texture.flipY,
285
+ options.maxTextureSize
286
+ );
287
+ const blob = await new Promise( ( resolve ) =>
288
+ canvas.toBlob( resolve, 'image/png', 1 )
289
+ );
168
290
 
169
- files[ `textures/Texture_${ id }.png` ] = new Uint8Array( await blob.arrayBuffer() );
291
+ files[ `textures/Texture_${id}.png` ] = new Uint8Array(
292
+ await blob.arrayBuffer()
293
+ );
170
294
 
171
295
  }
172
296
 
@@ -203,12 +327,53 @@ class USDZExporter {
203
327
 
204
328
  }
205
329
 
330
+ function getName( object, namesSet ) {
331
+
332
+ let name = object.name;
333
+ name = name.replace( /[^A-Za-z0-9_]/g, '' );
334
+ if ( /^[0-9]/.test( name ) ) {
335
+
336
+ name = '_' + name;
337
+
338
+ }
339
+
340
+ if ( name === '' ) {
341
+
342
+ if ( object.isCamera ) {
343
+
344
+ name = 'Camera';
345
+
346
+ } else {
347
+
348
+ name = 'Object';
349
+
350
+ }
351
+
352
+ }
353
+
354
+ if ( namesSet.has( name ) ) {
355
+
356
+ name = name + '_' + object.id;
357
+
358
+ }
359
+
360
+ namesSet.add( name );
361
+
362
+ return name;
363
+
364
+ }
365
+
206
366
  function imageToCanvas( image, flipY, maxTextureSize ) {
207
367
 
208
- if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
209
- ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
210
- ( typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas ) ||
211
- ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
368
+ if (
369
+ ( typeof HTMLImageElement !== 'undefined' &&
370
+ image instanceof HTMLImageElement ) ||
371
+ ( typeof HTMLCanvasElement !== 'undefined' &&
372
+ image instanceof HTMLCanvasElement ) ||
373
+ ( typeof OffscreenCanvas !== 'undefined' &&
374
+ image instanceof OffscreenCanvas ) ||
375
+ ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap )
376
+ ) {
212
377
 
213
378
  const scale = maxTextureSize / Math.max( image.width, image.height );
214
379
 
@@ -233,7 +398,9 @@ function imageToCanvas( image, flipY, maxTextureSize ) {
233
398
 
234
399
  } else {
235
400
 
236
- throw new Error( 'THREE.USDZExporter: No valid image data found. Unable to process texture.' );
401
+ throw new Error(
402
+ 'THREE.USDZExporter: No valid image data found. Unable to process texture.'
403
+ );
237
404
 
238
405
  }
239
406
 
@@ -254,79 +421,121 @@ function buildHeader() {
254
421
  metersPerUnit = 1
255
422
  upAxis = "Y"
256
423
  )
257
-
258
424
  `;
259
425
 
260
426
  }
261
427
 
262
- function buildSceneStart( options ) {
263
-
264
- const alignment = options.includeAnchoringProperties === true ? `
265
- token preliminary:anchoring:type = "${options.ar.anchoring.type}"
266
- token preliminary:planeAnchoring:alignment = "${options.ar.planeAnchoring.alignment}"
267
- ` : '';
268
- return `def Xform "Root"
269
- {
270
- def Scope "Scenes" (
271
- kind = "sceneLibrary"
272
- )
273
- {
274
- def Xform "Scene" (
275
- customData = {
276
- bool preliminary_collidesWithEnvironment = 0
277
- string sceneName = "Scene"
428
+ // Xform
429
+
430
+ function buildHierarchy( object, parentNode, materials, usedNames, files, options ) {
431
+
432
+ for ( let i = 0, l = object.children.length; i < l; i ++ ) {
433
+
434
+ const child = object.children[ i ];
435
+
436
+ if ( child.visible === false && options.onlyVisible === true ) continue;
437
+
438
+ let childNode;
439
+
440
+ if ( child.isMesh ) {
441
+
442
+ const geometry = child.geometry;
443
+ const material = child.material;
444
+
445
+ if ( material.isMeshStandardMaterial ) {
446
+
447
+ const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usda';
448
+
449
+ if ( ! ( geometryFileName in files ) ) {
450
+
451
+ const meshObject = buildMeshObject( geometry );
452
+ files[ geometryFileName ] = strToU8(
453
+ buildHeader() + '\n' + meshObject.toString()
454
+ );
455
+
456
+ }
457
+
458
+ if ( ! ( material.uuid in materials ) ) {
459
+
460
+ materials[ material.uuid ] = material;
461
+
462
+ }
463
+
464
+ childNode = buildMesh(
465
+ child,
466
+ geometry,
467
+ materials[ material.uuid ],
468
+ usedNames
469
+ );
470
+
471
+ } else {
472
+
473
+ console.warn(
474
+ 'THREE.USDZExporter: Unsupported material type (USDZ only supports MeshStandardMaterial)',
475
+ child
476
+ );
477
+
278
478
  }
279
- sceneName = "Scene"
280
- )
281
- {${alignment}
282
- `;
283
479
 
284
- }
480
+ } else if ( child.isCamera ) {
481
+
482
+ childNode = buildCamera( child, usedNames );
483
+
484
+ } else {
485
+
486
+ childNode = buildXform( child, usedNames );
487
+
488
+ }
489
+
490
+ if ( childNode ) {
285
491
 
286
- function buildSceneEnd() {
492
+ parentNode.addChild( childNode );
493
+ buildHierarchy( child, childNode, materials, usedNames, files, options );
287
494
 
288
- return `
289
495
  }
496
+
290
497
  }
498
+
291
499
  }
292
500
 
293
- `;
501
+ function buildXform( object, usedNames ) {
294
502
 
295
- }
503
+ const name = getName( object, usedNames );
504
+ const transform = buildMatrix( object.matrix );
296
505
 
297
- function buildUSDFileAsString( dataToInsert ) {
506
+ if ( object.matrix.determinant() < 0 ) {
298
507
 
299
- let output = buildHeader();
300
- output += dataToInsert;
301
- return strToU8( output );
508
+ console.warn(
509
+ 'THREE.USDZExporter: USDZ does not support negative scales',
510
+ object
511
+ );
302
512
 
303
- }
513
+ }
304
514
 
305
- // Xform
515
+ const node = new USDNode( name, 'Xform' );
306
516
 
307
- function buildXform( object, geometry, material ) {
517
+ node.addProperty( `matrix4d xformOp:transform = ${transform}` );
518
+ node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' );
308
519
 
309
- const name = 'Object_' + object.id;
310
- const transform = buildMatrix( object.matrixWorld );
520
+ return node;
311
521
 
312
- if ( object.matrixWorld.determinant() < 0 ) {
522
+ }
313
523
 
314
- console.warn( 'THREE.USDZExporter: USDZ does not support negative scales', object );
524
+ function buildMesh( object, geometry, material, usedNames ) {
315
525
 
316
- }
526
+ const node = buildXform( object, usedNames );
317
527
 
318
- return ` def Xform "${ name }" (
319
- prepend references = @./geometries/Geometry_${ geometry.id }.usda@</Geometry>
320
- prepend apiSchemas = ["MaterialBindingAPI"]
321
- )
322
- {
323
- matrix4d xformOp:transform = ${ transform }
324
- uniform token[] xformOpOrder = ["xformOp:transform"]
528
+ node.addMetadata(
529
+ 'prepend references',
530
+ `@./geometries/Geometry_${geometry.id}.usda@</Geometry>`
531
+ );
532
+ node.addMetadata( 'prepend apiSchemas', '["MaterialBindingAPI"]' );
325
533
 
326
- rel material:binding = </Materials/Material_${ material.id }>
327
- }
534
+ node.addProperty(
535
+ `rel material:binding = </Materials/Material_${material.id}>`
536
+ );
328
537
 
329
- `;
538
+ return node;
330
539
 
331
540
  }
332
541
 
@@ -334,13 +543,18 @@ function buildMatrix( matrix ) {
334
543
 
335
544
  const array = matrix.elements;
336
545
 
337
- return `( ${ buildMatrixRow( array, 0 ) }, ${ buildMatrixRow( array, 4 ) }, ${ buildMatrixRow( array, 8 ) }, ${ buildMatrixRow( array, 12 ) } )`;
546
+ return `( ${buildMatrixRow( array, 0 )}, ${buildMatrixRow(
547
+ array,
548
+ 4
549
+ )}, ${buildMatrixRow( array, 8 )}, ${buildMatrixRow( array, 12 )} )`;
338
550
 
339
551
  }
340
552
 
341
553
  function buildMatrixRow( array, offset ) {
342
554
 
343
- return `(${ array[ offset + 0 ] }, ${ array[ offset + 1 ] }, ${ array[ offset + 2 ] }, ${ array[ offset + 3 ] })`;
555
+ return `(${array[ offset + 0 ]}, ${array[ offset + 1 ]}, ${array[ offset + 2 ]}, ${
556
+ array[ offset + 3 ]
557
+ })`;
344
558
 
345
559
  }
346
560
 
@@ -348,43 +562,81 @@ function buildMatrixRow( array, offset ) {
348
562
 
349
563
  function buildMeshObject( geometry ) {
350
564
 
351
- const mesh = buildMesh( geometry );
352
- return `
353
- def "Geometry"
354
- {
355
- ${mesh}
356
- }
357
- `;
565
+ const node = new USDNode( 'Geometry' );
566
+
567
+ const meshNode = buildMeshNode( geometry );
568
+ node.addChild( meshNode );
569
+
570
+ return node;
358
571
 
359
572
  }
360
573
 
361
- function buildMesh( geometry ) {
574
+ function buildMeshNode( geometry ) {
362
575
 
363
576
  const name = 'Geometry';
364
577
  const attributes = geometry.attributes;
365
578
  const count = attributes.position.count;
366
579
 
367
- return `
368
- def Mesh "${ name }"
369
- {
370
- int[] faceVertexCounts = [${ buildMeshVertexCount( geometry ) }]
371
- int[] faceVertexIndices = [${ buildMeshVertexIndices( geometry ) }]
372
- normal3f[] normals = [${ buildVector3Array( attributes.normal, count )}] (
373
- interpolation = "vertex"
374
- )
375
- point3f[] points = [${ buildVector3Array( attributes.position, count )}]
376
- ${ buildPrimvars( attributes ) }
377
- uniform token subdivisionScheme = "none"
580
+ const node = new USDNode( name, 'Mesh' );
581
+
582
+ node.addProperty(
583
+ `int[] faceVertexCounts = [${buildMeshVertexCount( geometry )}]`
584
+ );
585
+ node.addProperty(
586
+ `int[] faceVertexIndices = [${buildMeshVertexIndices( geometry )}]`
587
+ );
588
+ node.addProperty(
589
+ `normal3f[] normals = [${buildVector3Array( attributes.normal, count )}]`,
590
+ [ 'interpolation = "vertex"' ]
591
+ );
592
+ node.addProperty(
593
+ `point3f[] points = [${buildVector3Array( attributes.position, count )}]`
594
+ );
595
+
596
+ for ( let i = 0; i < 4; i ++ ) {
597
+
598
+ const id = i > 0 ? i : '';
599
+ const attribute = attributes[ 'uv' + id ];
600
+ if ( attribute !== undefined ) {
601
+
602
+ node.addProperty(
603
+ `texCoord2f[] primvars:st${id} = [${buildVector2Array( attribute )}]`,
604
+ [ 'interpolation = "vertex"' ]
605
+ );
606
+
607
+ }
608
+
378
609
  }
379
- `;
610
+
611
+ const colorAttribute = attributes.color;
612
+ if ( colorAttribute !== undefined ) {
613
+
614
+ node.addProperty(
615
+ `color3f[] primvars:displayColor = [${buildVector3Array(
616
+ colorAttribute,
617
+ count
618
+ )}]`,
619
+ [ 'interpolation = "vertex"' ]
620
+ );
621
+
622
+ }
623
+
624
+ node.addProperty( 'uniform token subdivisionScheme = "none"' );
625
+
626
+ return node;
380
627
 
381
628
  }
382
629
 
383
630
  function buildMeshVertexCount( geometry ) {
384
631
 
385
- const count = geometry.index !== null ? geometry.index.count : geometry.attributes.position.count;
632
+ const count =
633
+ geometry.index !== null
634
+ ? geometry.index.count
635
+ : geometry.attributes.position.count;
386
636
 
387
- return Array( count / 3 ).fill( 3 ).join( ', ' );
637
+ return Array( count / 3 )
638
+ .fill( 3 )
639
+ .join( ', ' );
388
640
 
389
641
  }
390
642
 
@@ -434,7 +686,11 @@ function buildVector3Array( attribute, count ) {
434
686
  const y = attribute.getY( i );
435
687
  const z = attribute.getZ( i );
436
688
 
437
- array.push( `(${ x.toPrecision( PRECISION ) }, ${ y.toPrecision( PRECISION ) }, ${ z.toPrecision( PRECISION ) })` );
689
+ array.push(
690
+ `(${x.toPrecision( PRECISION )}, ${y.toPrecision(
691
+ PRECISION
692
+ )}, ${z.toPrecision( PRECISION )})`
693
+ );
438
694
 
439
695
  }
440
696
 
@@ -451,7 +707,9 @@ function buildVector2Array( attribute ) {
451
707
  const x = attribute.getX( i );
452
708
  const y = attribute.getY( i );
453
709
 
454
- array.push( `(${ x.toPrecision( PRECISION ) }, ${ 1 - y.toPrecision( PRECISION ) })` );
710
+ array.push(
711
+ `(${x.toPrecision( PRECISION )}, ${1 - y.toPrecision( PRECISION )})`
712
+ );
455
713
 
456
714
  }
457
715
 
@@ -459,65 +717,23 @@ function buildVector2Array( attribute ) {
459
717
 
460
718
  }
461
719
 
462
- function buildPrimvars( attributes ) {
463
-
464
- let string = '';
465
-
466
- for ( let i = 0; i < 4; i ++ ) {
467
-
468
- const id = ( i > 0 ? i : '' );
469
- const attribute = attributes[ 'uv' + id ];
470
-
471
- if ( attribute !== undefined ) {
472
-
473
- string += `
474
- texCoord2f[] primvars:st${ id } = [${ buildVector2Array( attribute )}] (
475
- interpolation = "vertex"
476
- )`;
477
-
478
- }
479
-
480
- }
481
-
482
- // vertex colors
483
-
484
- const colorAttribute = attributes.color;
485
-
486
- if ( colorAttribute !== undefined ) {
487
-
488
- const count = colorAttribute.count;
489
-
490
- string += `
491
- color3f[] primvars:displayColor = [${buildVector3Array( colorAttribute, count )}] (
492
- interpolation = "vertex"
493
- )`;
494
-
495
- }
496
-
497
- return string;
498
-
499
- }
500
-
501
720
  // Materials
502
721
 
503
722
  function buildMaterials( materials, textures, quickLookCompatible = false ) {
504
723
 
505
- const array = [];
724
+ const materialsNode = new USDNode( 'Materials' );
506
725
 
507
726
  for ( const uuid in materials ) {
508
727
 
509
728
  const material = materials[ uuid ];
510
729
 
511
- array.push( buildMaterial( material, textures, quickLookCompatible ) );
730
+ materialsNode.addChild(
731
+ buildMaterial( material, textures, quickLookCompatible )
732
+ );
512
733
 
513
734
  }
514
735
 
515
- return `def "Materials"
516
- {
517
- ${ array.join( '' ) }
518
- }
519
-
520
- `;
736
+ return materialsNode;
521
737
 
522
738
  }
523
739
 
@@ -525,11 +741,9 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
525
741
 
526
742
  // https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html
527
743
 
528
- const pad = ' ';
529
- const inputs = [];
530
- const samplers = [];
744
+ const materialNode = new USDNode( `Material_${material.id}`, 'Material' );
531
745
 
532
- function buildTexture( texture, mapType, color ) {
746
+ function buildTextureNodes( texture, mapType, color ) {
533
747
 
534
748
  const id = texture.source.id + '_' + texture.flipY;
535
749
 
@@ -540,7 +754,7 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
540
754
  const WRAPPINGS = {
541
755
  1000: 'repeat', // RepeatWrapping
542
756
  1001: 'clamp', // ClampToEdgeWrapping
543
- 1002: 'mirror' // MirroredRepeatWrapping
757
+ 1002: 'mirror', // MirroredRepeatWrapping
544
758
  };
545
759
 
546
760
  const repeat = texture.repeat.clone();
@@ -575,135 +789,255 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
575
789
 
576
790
  }
577
791
 
578
- return `
579
- def Shader "PrimvarReader_${ mapType }"
580
- {
581
- uniform token info:id = "UsdPrimvarReader_float2"
582
- float2 inputs:fallback = (0.0, 0.0)
583
- token inputs:varname = "${ uv }"
584
- float2 outputs:result
792
+ const primvarReaderNode = new USDNode( `PrimvarReader_${mapType}`, 'Shader' );
793
+ primvarReaderNode.addProperty(
794
+ 'uniform token info:id = "UsdPrimvarReader_float2"'
795
+ );
796
+ primvarReaderNode.addProperty( 'float2 inputs:fallback = (0.0, 0.0)' );
797
+ primvarReaderNode.addProperty( `string inputs:varname = "${uv}"` );
798
+ primvarReaderNode.addProperty( 'float2 outputs:result' );
799
+
800
+ const transform2dNode = new USDNode( `Transform2d_${mapType}`, 'Shader' );
801
+ transform2dNode.addProperty( 'uniform token info:id = "UsdTransform2d"' );
802
+ transform2dNode.addProperty(
803
+ `float2 inputs:in.connect = </Materials/Material_${material.id}/PrimvarReader_${mapType}.outputs:result>`
804
+ );
805
+ transform2dNode.addProperty(
806
+ `float inputs:rotation = ${( rotation * ( 180 / Math.PI ) ).toFixed(
807
+ PRECISION
808
+ )}`
809
+ );
810
+ transform2dNode.addProperty(
811
+ `float2 inputs:scale = ${buildVector2( repeat )}`
812
+ );
813
+ transform2dNode.addProperty(
814
+ `float2 inputs:translation = ${buildVector2( offset )}`
815
+ );
816
+ transform2dNode.addProperty( 'float2 outputs:result' );
817
+
818
+ const textureNode = new USDNode(
819
+ `Texture_${texture.id}_${mapType}`,
820
+ 'Shader'
821
+ );
822
+ textureNode.addProperty( 'uniform token info:id = "UsdUVTexture"' );
823
+ textureNode.addProperty( `asset inputs:file = @textures/Texture_${id}.png@` );
824
+ textureNode.addProperty(
825
+ `float2 inputs:st.connect = </Materials/Material_${material.id}/Transform2d_${mapType}.outputs:result>`
826
+ );
827
+
828
+ if ( color !== undefined ) {
829
+
830
+ textureNode.addProperty( `float4 inputs:scale = ${buildColor4( color )}` );
831
+
585
832
  }
586
833
 
587
- def Shader "Transform2d_${ mapType }"
588
- {
589
- uniform token info:id = "UsdTransform2d"
590
- token inputs:in.connect = </Materials/Material_${ material.id }/PrimvarReader_${ mapType }.outputs:result>
591
- float inputs:rotation = ${ ( rotation * ( 180 / Math.PI ) ).toFixed( PRECISION ) }
592
- float2 inputs:scale = ${ buildVector2( repeat ) }
593
- float2 inputs:translation = ${ buildVector2( offset ) }
594
- float2 outputs:result
834
+ if ( mapType === 'normal' ) {
835
+
836
+ textureNode.addProperty( 'float4 inputs:scale = (2, 2, 2, 1)' );
837
+ textureNode.addProperty( 'float4 inputs:bias = (-1, -1, -1, 0)' );
838
+
595
839
  }
596
840
 
597
- def Shader "Texture_${ texture.id }_${ mapType }"
598
- {
599
- uniform token info:id = "UsdUVTexture"
600
- asset inputs:file = @textures/Texture_${ id }.png@
601
- float2 inputs:st.connect = </Materials/Material_${ material.id }/Transform2d_${ mapType }.outputs:result>
602
- ${ color !== undefined ? 'float4 inputs:scale = ' + buildColor4( color ) : '' }
603
- token inputs:sourceColorSpace = "${ texture.colorSpace === NoColorSpace ? 'raw' : 'sRGB' }"
604
- token inputs:wrapS = "${ WRAPPINGS[ texture.wrapS ] }"
605
- token inputs:wrapT = "${ WRAPPINGS[ texture.wrapT ] }"
606
- float outputs:r
607
- float outputs:g
608
- float outputs:b
609
- float3 outputs:rgb
610
- ${ material.transparent || material.alphaTest > 0.0 ? 'float outputs:a' : '' }
611
- }`;
841
+ textureNode.addProperty(
842
+ `token inputs:sourceColorSpace = "${
843
+ texture.colorSpace === NoColorSpace ? 'raw' : 'sRGB'
844
+ }"`
845
+ );
846
+ textureNode.addProperty(
847
+ `token inputs:wrapS = "${WRAPPINGS[ texture.wrapS ]}"`
848
+ );
849
+ textureNode.addProperty(
850
+ `token inputs:wrapT = "${WRAPPINGS[ texture.wrapT ]}"`
851
+ );
852
+ textureNode.addProperty( 'float outputs:r' );
853
+ textureNode.addProperty( 'float outputs:g' );
854
+ textureNode.addProperty( 'float outputs:b' );
855
+ textureNode.addProperty( 'float3 outputs:rgb' );
856
+
857
+ if ( material.transparent || material.alphaTest > 0.0 ) {
858
+
859
+ textureNode.addProperty( 'float outputs:a' );
612
860
 
613
- }
861
+ }
862
+
863
+ return [ primvarReaderNode, transform2dNode, textureNode ];
614
864
 
865
+ }
615
866
 
616
867
  if ( material.side === DoubleSide ) {
617
868
 
618
- console.warn( 'THREE.USDZExporter: USDZ does not support double sided materials', material );
869
+ console.warn(
870
+ 'THREE.USDZExporter: USDZ does not support double sided materials',
871
+ material
872
+ );
619
873
 
620
874
  }
621
875
 
876
+ const previewSurfaceNode = new USDNode( 'PreviewSurface', 'Shader' );
877
+ previewSurfaceNode.addProperty( 'uniform token info:id = "UsdPreviewSurface"' );
878
+
622
879
  if ( material.map !== null ) {
623
880
 
624
- inputs.push( `${ pad }color3f inputs:diffuseColor.connect = </Materials/Material_${ material.id }/Texture_${ material.map.id }_diffuse.outputs:rgb>` );
881
+ previewSurfaceNode.addProperty(
882
+ `color3f inputs:diffuseColor.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:rgb>`
883
+ );
625
884
 
626
885
  if ( material.transparent ) {
627
886
 
628
- inputs.push( `${ pad }float inputs:opacity.connect = </Materials/Material_${ material.id }/Texture_${ material.map.id }_diffuse.outputs:a>` );
887
+ previewSurfaceNode.addProperty(
888
+ `float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:a>`
889
+ );
629
890
 
630
891
  } else if ( material.alphaTest > 0.0 ) {
631
892
 
632
- inputs.push( `${ pad }float inputs:opacity.connect = </Materials/Material_${ material.id }/Texture_${ material.map.id }_diffuse.outputs:a>` );
633
- inputs.push( `${ pad }float inputs:opacityThreshold = ${material.alphaTest}` );
893
+ previewSurfaceNode.addProperty(
894
+ `float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:a>`
895
+ );
896
+ previewSurfaceNode.addProperty(
897
+ `float inputs:opacityThreshold = ${material.alphaTest}`
898
+ );
634
899
 
635
900
  }
636
901
 
637
- samplers.push( buildTexture( material.map, 'diffuse', material.color ) );
902
+ const textureNodes = buildTextureNodes(
903
+ material.map,
904
+ 'diffuse',
905
+ material.color
906
+ );
907
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
638
908
 
639
909
  } else {
640
910
 
641
- inputs.push( `${ pad }color3f inputs:diffuseColor = ${ buildColor( material.color ) }` );
911
+ previewSurfaceNode.addProperty(
912
+ `color3f inputs:diffuseColor = ${buildColor( material.color )}`
913
+ );
642
914
 
643
915
  }
644
916
 
645
917
  if ( material.emissiveMap !== null ) {
646
918
 
647
- inputs.push( `${ pad }color3f inputs:emissiveColor.connect = </Materials/Material_${ material.id }/Texture_${ material.emissiveMap.id }_emissive.outputs:rgb>` );
648
-
649
- samplers.push( buildTexture( material.emissiveMap, 'emissive', new Color( material.emissive.r * material.emissiveIntensity, material.emissive.g * material.emissiveIntensity, material.emissive.b * material.emissiveIntensity ) ) );
919
+ previewSurfaceNode.addProperty(
920
+ `color3f inputs:emissiveColor.connect = </Materials/Material_${material.id}/Texture_${material.emissiveMap.id}_emissive.outputs:rgb>`
921
+ );
922
+
923
+ const emissiveColor = new Color(
924
+ material.emissive.r * material.emissiveIntensity,
925
+ material.emissive.g * material.emissiveIntensity,
926
+ material.emissive.b * material.emissiveIntensity
927
+ );
928
+ const textureNodes = buildTextureNodes(
929
+ material.emissiveMap,
930
+ 'emissive',
931
+ emissiveColor
932
+ );
933
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
650
934
 
651
935
  } else if ( material.emissive.getHex() > 0 ) {
652
936
 
653
- inputs.push( `${ pad }color3f inputs:emissiveColor = ${ buildColor( material.emissive ) }` );
937
+ previewSurfaceNode.addProperty(
938
+ `color3f inputs:emissiveColor = ${buildColor( material.emissive )}`
939
+ );
654
940
 
655
941
  }
656
942
 
657
943
  if ( material.normalMap !== null ) {
658
944
 
659
- inputs.push( `${ pad }normal3f inputs:normal.connect = </Materials/Material_${ material.id }/Texture_${ material.normalMap.id }_normal.outputs:rgb>` );
945
+ previewSurfaceNode.addProperty(
946
+ `normal3f inputs:normal.connect = </Materials/Material_${material.id}/Texture_${material.normalMap.id}_normal.outputs:rgb>`
947
+ );
660
948
 
661
- samplers.push( buildTexture( material.normalMap, 'normal' ) );
949
+ const textureNodes = buildTextureNodes( material.normalMap, 'normal' );
950
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
662
951
 
663
952
  }
664
953
 
665
954
  if ( material.aoMap !== null ) {
666
955
 
667
- inputs.push( `${ pad }float inputs:occlusion.connect = </Materials/Material_${ material.id }/Texture_${ material.aoMap.id }_occlusion.outputs:r>` );
668
-
669
- samplers.push( buildTexture( material.aoMap, 'occlusion', new Color( material.aoMapIntensity, material.aoMapIntensity, material.aoMapIntensity ) ) );
956
+ previewSurfaceNode.addProperty(
957
+ `float inputs:occlusion.connect = </Materials/Material_${material.id}/Texture_${material.aoMap.id}_occlusion.outputs:r>`
958
+ );
959
+
960
+ const aoColor = new Color(
961
+ material.aoMapIntensity,
962
+ material.aoMapIntensity,
963
+ material.aoMapIntensity
964
+ );
965
+ const textureNodes = buildTextureNodes(
966
+ material.aoMap,
967
+ 'occlusion',
968
+ aoColor
969
+ );
970
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
670
971
 
671
972
  }
672
973
 
673
974
  if ( material.roughnessMap !== null ) {
674
975
 
675
- inputs.push( `${ pad }float inputs:roughness.connect = </Materials/Material_${ material.id }/Texture_${ material.roughnessMap.id }_roughness.outputs:g>` );
676
-
677
- samplers.push( buildTexture( material.roughnessMap, 'roughness', new Color( material.roughness, material.roughness, material.roughness ) ) );
976
+ previewSurfaceNode.addProperty(
977
+ `float inputs:roughness.connect = </Materials/Material_${material.id}/Texture_${material.roughnessMap.id}_roughness.outputs:g>`
978
+ );
979
+
980
+ const roughnessColor = new Color(
981
+ material.roughness,
982
+ material.roughness,
983
+ material.roughness
984
+ );
985
+ const textureNodes = buildTextureNodes(
986
+ material.roughnessMap,
987
+ 'roughness',
988
+ roughnessColor
989
+ );
990
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
678
991
 
679
992
  } else {
680
993
 
681
- inputs.push( `${ pad }float inputs:roughness = ${ material.roughness }` );
994
+ previewSurfaceNode.addProperty(
995
+ `float inputs:roughness = ${material.roughness}`
996
+ );
682
997
 
683
998
  }
684
999
 
685
1000
  if ( material.metalnessMap !== null ) {
686
1001
 
687
- inputs.push( `${ pad }float inputs:metallic.connect = </Materials/Material_${ material.id }/Texture_${ material.metalnessMap.id }_metallic.outputs:b>` );
688
-
689
- samplers.push( buildTexture( material.metalnessMap, 'metallic', new Color( material.metalness, material.metalness, material.metalness ) ) );
1002
+ previewSurfaceNode.addProperty(
1003
+ `float inputs:metallic.connect = </Materials/Material_${material.id}/Texture_${material.metalnessMap.id}_metallic.outputs:b>`
1004
+ );
1005
+
1006
+ const metalnessColor = new Color(
1007
+ material.metalness,
1008
+ material.metalness,
1009
+ material.metalness
1010
+ );
1011
+ const textureNodes = buildTextureNodes(
1012
+ material.metalnessMap,
1013
+ 'metallic',
1014
+ metalnessColor
1015
+ );
1016
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
690
1017
 
691
1018
  } else {
692
1019
 
693
- inputs.push( `${ pad }float inputs:metallic = ${ material.metalness }` );
1020
+ previewSurfaceNode.addProperty(
1021
+ `float inputs:metallic = ${material.metalness}`
1022
+ );
694
1023
 
695
1024
  }
696
1025
 
697
1026
  if ( material.alphaMap !== null ) {
698
1027
 
699
- inputs.push( `${pad}float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.alphaMap.id}_opacity.outputs:r>` );
700
- inputs.push( `${pad}float inputs:opacityThreshold = 0.0001` );
1028
+ previewSurfaceNode.addProperty(
1029
+ `float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.alphaMap.id}_opacity.outputs:r>`
1030
+ );
1031
+ previewSurfaceNode.addProperty( 'float inputs:opacityThreshold = 0.0001' );
701
1032
 
702
- samplers.push( buildTexture( material.alphaMap, 'opacity' ) );
1033
+ const textureNodes = buildTextureNodes( material.alphaMap, 'opacity' );
1034
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
703
1035
 
704
1036
  } else {
705
1037
 
706
- inputs.push( `${pad}float inputs:opacity = ${material.opacity}` );
1038
+ previewSurfaceNode.addProperty(
1039
+ `float inputs:opacity = ${material.opacity}`
1040
+ );
707
1041
 
708
1042
  }
709
1043
 
@@ -711,115 +1045,164 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
711
1045
 
712
1046
  if ( material.clearcoatMap !== null ) {
713
1047
 
714
- inputs.push( `${pad}float inputs:clearcoat.connect = </Materials/Material_${material.id}/Texture_${material.clearcoatMap.id}_clearcoat.outputs:r>` );
715
- samplers.push( buildTexture( material.clearcoatMap, 'clearcoat', new Color( material.clearcoat, material.clearcoat, material.clearcoat ) ) );
1048
+ previewSurfaceNode.addProperty(
1049
+ `float inputs:clearcoat.connect = </Materials/Material_${material.id}/Texture_${material.clearcoatMap.id}_clearcoat.outputs:r>`
1050
+ );
1051
+
1052
+ const clearcoatColor = new Color(
1053
+ material.clearcoat,
1054
+ material.clearcoat,
1055
+ material.clearcoat
1056
+ );
1057
+ const textureNodes = buildTextureNodes(
1058
+ material.clearcoatMap,
1059
+ 'clearcoat',
1060
+ clearcoatColor
1061
+ );
1062
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
716
1063
 
717
1064
  } else {
718
1065
 
719
- inputs.push( `${pad}float inputs:clearcoat = ${material.clearcoat}` );
1066
+ previewSurfaceNode.addProperty(
1067
+ `float inputs:clearcoat = ${material.clearcoat}`
1068
+ );
720
1069
 
721
1070
  }
722
1071
 
723
1072
  if ( material.clearcoatRoughnessMap !== null ) {
724
1073
 
725
- inputs.push( `${pad}float inputs:clearcoatRoughness.connect = </Materials/Material_${material.id}/Texture_${material.clearcoatRoughnessMap.id}_clearcoatRoughness.outputs:g>` );
726
- samplers.push( buildTexture( material.clearcoatRoughnessMap, 'clearcoatRoughness', new Color( material.clearcoatRoughness, material.clearcoatRoughness, material.clearcoatRoughness ) ) );
1074
+ previewSurfaceNode.addProperty(
1075
+ `float inputs:clearcoatRoughness.connect = </Materials/Material_${material.id}/Texture_${material.clearcoatRoughnessMap.id}_clearcoatRoughness.outputs:g>`
1076
+ );
1077
+
1078
+ const clearcoatRoughnessColor = new Color(
1079
+ material.clearcoatRoughness,
1080
+ material.clearcoatRoughness,
1081
+ material.clearcoatRoughness
1082
+ );
1083
+ const textureNodes = buildTextureNodes(
1084
+ material.clearcoatRoughnessMap,
1085
+ 'clearcoatRoughness',
1086
+ clearcoatRoughnessColor
1087
+ );
1088
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
727
1089
 
728
1090
  } else {
729
1091
 
730
- inputs.push( `${pad}float inputs:clearcoatRoughness = ${material.clearcoatRoughness}` );
1092
+ previewSurfaceNode.addProperty(
1093
+ `float inputs:clearcoatRoughness = ${material.clearcoatRoughness}`
1094
+ );
731
1095
 
732
1096
  }
733
1097
 
734
- inputs.push( `${ pad }float inputs:ior = ${ material.ior }` );
1098
+ previewSurfaceNode.addProperty( `float inputs:ior = ${material.ior}` );
735
1099
 
736
1100
  }
737
1101
 
738
- return `
739
- def Material "Material_${ material.id }"
740
- {
741
- def Shader "PreviewSurface"
742
- {
743
- uniform token info:id = "UsdPreviewSurface"
744
- ${ inputs.join( '\n' ) }
745
- int inputs:useSpecularWorkflow = 0
746
- token outputs:surface
747
- }
1102
+ previewSurfaceNode.addProperty( 'int inputs:useSpecularWorkflow = 0' );
1103
+ previewSurfaceNode.addProperty( 'token outputs:surface' );
748
1104
 
749
- token outputs:surface.connect = </Materials/Material_${ material.id }/PreviewSurface.outputs:surface>
1105
+ materialNode.addChild( previewSurfaceNode );
750
1106
 
751
- ${ samplers.join( '\n' ) }
1107
+ materialNode.addProperty(
1108
+ `token outputs:surface.connect = </Materials/Material_${material.id}/PreviewSurface.outputs:surface>`
1109
+ );
752
1110
 
753
- }
754
- `;
1111
+ return materialNode;
755
1112
 
756
1113
  }
757
1114
 
758
1115
  function buildColor( color ) {
759
1116
 
760
- return `(${ color.r }, ${ color.g }, ${ color.b })`;
1117
+ return `(${color.r}, ${color.g}, ${color.b})`;
761
1118
 
762
1119
  }
763
1120
 
764
1121
  function buildColor4( color ) {
765
1122
 
766
- return `(${ color.r }, ${ color.g }, ${ color.b }, 1.0)`;
1123
+ return `(${color.r}, ${color.g}, ${color.b}, 1.0)`;
767
1124
 
768
1125
  }
769
1126
 
770
1127
  function buildVector2( vector ) {
771
1128
 
772
- return `(${ vector.x }, ${ vector.y })`;
1129
+ return `(${vector.x}, ${vector.y})`;
773
1130
 
774
1131
  }
775
1132
 
1133
+ function buildCamera( camera, usedNames ) {
776
1134
 
777
- function buildCamera( camera ) {
778
-
779
- const name = camera.name ? camera.name : 'Camera_' + camera.id;
1135
+ const name = getName( camera, usedNames );
780
1136
 
781
- const transform = buildMatrix( camera.matrixWorld );
1137
+ const transform = buildMatrix( camera.matrix );
782
1138
 
783
- if ( camera.matrixWorld.determinant() < 0 ) {
1139
+ if ( camera.matrix.determinant() < 0 ) {
784
1140
 
785
- console.warn( 'THREE.USDZExporter: USDZ does not support negative scales', camera );
1141
+ console.warn(
1142
+ 'THREE.USDZExporter: USDZ does not support negative scales',
1143
+ camera
1144
+ );
786
1145
 
787
1146
  }
788
1147
 
1148
+ const node = new USDNode( name, 'Camera' );
1149
+ node.addProperty( `matrix4d xformOp:transform = ${transform}` );
1150
+ node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' );
1151
+
1152
+ const projection = camera.isOrthographicCamera
1153
+ ? 'orthographic'
1154
+ : 'perspective';
1155
+ node.addProperty( `token projection = "${projection}"` );
1156
+
1157
+ const clippingRange = `(${camera.near.toPrecision(
1158
+ PRECISION
1159
+ )}, ${camera.far.toPrecision( PRECISION )})`;
1160
+ node.addProperty( `float2 clippingRange = ${clippingRange}` );
1161
+
1162
+ let horizontalAperture;
789
1163
  if ( camera.isOrthographicCamera ) {
790
1164
 
791
- return `def Camera "${name}"
792
- {
793
- matrix4d xformOp:transform = ${ transform }
794
- uniform token[] xformOpOrder = ["xformOp:transform"]
1165
+ horizontalAperture = (
1166
+ ( Math.abs( camera.left ) + Math.abs( camera.right ) ) *
1167
+ 10
1168
+ ).toPrecision( PRECISION );
795
1169
 
796
- float2 clippingRange = (${ camera.near.toPrecision( PRECISION ) }, ${ camera.far.toPrecision( PRECISION ) })
797
- float horizontalAperture = ${ ( ( Math.abs( camera.left ) + Math.abs( camera.right ) ) * 10 ).toPrecision( PRECISION ) }
798
- float verticalAperture = ${ ( ( Math.abs( camera.top ) + Math.abs( camera.bottom ) ) * 10 ).toPrecision( PRECISION ) }
799
- token projection = "orthographic"
800
- }
1170
+ } else {
1171
+
1172
+ horizontalAperture = camera.getFilmWidth().toPrecision( PRECISION );
1173
+
1174
+ }
1175
+
1176
+ node.addProperty( `float horizontalAperture = ${horizontalAperture}` );
1177
+
1178
+ let verticalAperture;
1179
+ if ( camera.isOrthographicCamera ) {
801
1180
 
802
- `;
1181
+ verticalAperture = (
1182
+ ( Math.abs( camera.top ) + Math.abs( camera.bottom ) ) *
1183
+ 10
1184
+ ).toPrecision( PRECISION );
803
1185
 
804
1186
  } else {
805
1187
 
806
- return `def Camera "${name}"
807
- {
808
- matrix4d xformOp:transform = ${ transform }
809
- uniform token[] xformOpOrder = ["xformOp:transform"]
810
-
811
- float2 clippingRange = (${ camera.near.toPrecision( PRECISION ) }, ${ camera.far.toPrecision( PRECISION ) })
812
- float focalLength = ${ camera.getFocalLength().toPrecision( PRECISION ) }
813
- float focusDistance = ${ camera.focus.toPrecision( PRECISION ) }
814
- float horizontalAperture = ${ camera.getFilmWidth().toPrecision( PRECISION ) }
815
- token projection = "perspective"
816
- float verticalAperture = ${ camera.getFilmHeight().toPrecision( PRECISION ) }
817
- }
1188
+ verticalAperture = camera.getFilmHeight().toPrecision( PRECISION );
1189
+
1190
+ }
1191
+
1192
+ node.addProperty( `float verticalAperture = ${verticalAperture}` );
818
1193
 
819
- `;
1194
+ if ( camera.isPerspectiveCamera ) {
1195
+
1196
+ const focalLength = camera.getFocalLength().toPrecision( PRECISION );
1197
+ node.addProperty( `float focalLength = ${focalLength}` );
1198
+
1199
+ const focusDistance = camera.focus.toPrecision( PRECISION );
1200
+ node.addProperty( `float focusDistance = ${focusDistance}` );
820
1201
 
821
1202
  }
822
1203
 
1204
+ return node;
1205
+
823
1206
  }
824
1207
 
825
1208
  /**
@@ -828,6 +1211,7 @@ function buildCamera( camera ) {
828
1211
  * @typedef {Object} USDZExporter~Options
829
1212
  * @property {number} [maxTextureSize=1024] - The maximum texture size that is going to be exported.
830
1213
  * @property {boolean} [includeAnchoringProperties=true] - Whether to include anchoring properties or not.
1214
+ * @property {boolean} [onlyVisible=true] - Export only visible 3D objects.
831
1215
  * @property {Object} [ar] - If `includeAnchoringProperties` is set to `true`, the anchoring type and alignment
832
1216
  * can be configured via `ar.anchoring.type` and `ar.planeAnchoring.alignment`.
833
1217
  * @property {boolean} [quickLookCompatible=false] - Whether to make the exported USDZ compatible to QuickLook