super-three 0.169.1 → 0.170.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/build/three.cjs +24628 -24228
  2. package/build/three.core.js +37002 -0
  3. package/build/three.core.min.js +6 -0
  4. package/build/three.module.js +10519 -47108
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +533 -0
  7. package/build/three.tsl.min.js +6 -0
  8. package/build/three.webgpu.js +17071 -53583
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +17134 -53623
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +3 -3
  13. package/examples/jsm/animation/MMDAnimationHelper.js +2 -0
  14. package/examples/jsm/animation/MMDPhysics.js +2 -0
  15. package/examples/jsm/capabilities/WebGPU.js +1 -10
  16. package/examples/jsm/controls/ArcballControls.js +25 -21
  17. package/examples/jsm/controls/OrbitControls.js +41 -9
  18. package/examples/jsm/controls/PointerLockControls.js +2 -5
  19. package/examples/jsm/controls/TransformControls.js +22 -6
  20. package/examples/jsm/csm/CSM.js +2 -2
  21. package/examples/jsm/csm/CSMFrustum.js +7 -4
  22. package/examples/jsm/csm/CSMHelper.js +2 -0
  23. package/examples/jsm/csm/CSMShadowNode.js +437 -0
  24. package/examples/jsm/curves/NURBSCurve.js +34 -3
  25. package/examples/jsm/exporters/GLTFExporter.js +138 -71
  26. package/examples/jsm/exporters/KTX2Exporter.js +35 -12
  27. package/examples/jsm/exporters/MMDExporter.js +6 -0
  28. package/examples/jsm/exporters/USDZExporter.js +21 -3
  29. package/examples/jsm/geometries/DecalGeometry.js +70 -21
  30. package/examples/jsm/geometries/InstancedPointsGeometry.js +2 -0
  31. package/examples/jsm/helpers/TextureHelperGPU.js +175 -0
  32. package/examples/jsm/interactive/HTMLMesh.js +1 -0
  33. package/examples/jsm/lighting/TiledLighting.js +18 -0
  34. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  35. package/examples/jsm/lines/LineGeometry.js +25 -0
  36. package/examples/jsm/lines/LineMaterial.js +0 -1
  37. package/examples/jsm/lines/LineSegmentsGeometry.js +2 -0
  38. package/examples/jsm/lines/webgpu/Line2.js +2 -1
  39. package/examples/jsm/lines/webgpu/LineSegments2.js +2 -16
  40. package/examples/jsm/lines/webgpu/Wireframe.js +57 -0
  41. package/examples/jsm/loaders/3DMLoader.js +1 -0
  42. package/examples/jsm/loaders/3MFLoader.js +91 -0
  43. package/examples/jsm/loaders/FBXLoader.js +12 -2
  44. package/examples/jsm/loaders/GLTFLoader.js +2 -0
  45. package/examples/jsm/loaders/KTX2Loader.js +143 -49
  46. package/examples/jsm/loaders/LDrawLoader.js +22 -136
  47. package/examples/jsm/loaders/LottieLoader.js +1 -0
  48. package/examples/jsm/loaders/MMDLoader.js +3 -0
  49. package/examples/jsm/loaders/MaterialXLoader.js +2 -2
  50. package/examples/jsm/materials/LDrawConditionalLineMaterial.js +143 -0
  51. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +114 -0
  52. package/examples/jsm/math/ColorSpaces.js +76 -0
  53. package/examples/jsm/misc/ProgressiveLightMap.js +52 -40
  54. package/examples/jsm/misc/ProgressiveLightMapGPU.js +293 -0
  55. package/examples/jsm/misc/VolumeSlice.js +1 -0
  56. package/examples/jsm/objects/InstancedPoints.js +2 -4
  57. package/examples/jsm/objects/LensflareMesh.js +4 -2
  58. package/examples/jsm/objects/SkyMesh.js +5 -3
  59. package/examples/jsm/objects/Water2Mesh.js +7 -3
  60. package/examples/jsm/objects/WaterMesh.js +12 -10
  61. package/examples/jsm/postprocessing/AfterimagePass.js +14 -3
  62. package/examples/jsm/postprocessing/SSRPass.js +6 -0
  63. package/examples/jsm/renderers/CSS2DRenderer.js +6 -3
  64. package/examples/jsm/renderers/CSS3DRenderer.js +7 -4
  65. package/examples/jsm/shaders/FXAAShader.js +225 -224
  66. package/examples/jsm/transpiler/AST.js +2 -2
  67. package/examples/jsm/transpiler/GLSLDecoder.js +57 -25
  68. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  69. package/examples/jsm/transpiler/TSLEncoder.js +11 -6
  70. package/{src/nodes → examples/jsm/tsl}/display/AfterImageNode.js +18 -21
  71. package/{src/nodes → examples/jsm/tsl}/display/AnaglyphPassNode.js +2 -6
  72. package/{src/nodes → examples/jsm/tsl}/display/AnamorphicNode.js +12 -18
  73. package/{src/nodes → examples/jsm/tsl}/display/BleachBypass.js +1 -3
  74. package/{src/nodes → examples/jsm/tsl}/display/BloomNode.js +12 -41
  75. package/{src/nodes → examples/jsm/tsl}/display/DenoiseNode.js +60 -47
  76. package/{src/nodes → examples/jsm/tsl}/display/DepthOfFieldNode.js +4 -9
  77. package/{src/nodes → examples/jsm/tsl}/display/DotScreenNode.js +2 -9
  78. package/examples/jsm/tsl/display/FXAANode.js +316 -0
  79. package/{src/nodes → examples/jsm/tsl}/display/FilmNode.js +4 -7
  80. package/{src/nodes → examples/jsm/tsl}/display/GTAONode.js +73 -78
  81. package/{src/nodes → examples/jsm/tsl}/display/GaussianBlurNode.js +78 -42
  82. package/examples/jsm/tsl/display/LensflareNode.js +161 -0
  83. package/{src/nodes → examples/jsm/tsl}/display/Lut3DNode.js +3 -5
  84. package/{src/nodes → examples/jsm/tsl}/display/MotionBlur.js +2 -3
  85. package/examples/jsm/tsl/display/OutlineNode.js +434 -0
  86. package/{src/nodes → examples/jsm/tsl}/display/ParallaxBarrierPassNode.js +2 -5
  87. package/{src/nodes → examples/jsm/tsl}/display/PixelationPassNode.js +5 -17
  88. package/{src/nodes → examples/jsm/tsl}/display/RGBShiftNode.js +2 -6
  89. package/examples/jsm/tsl/display/SMAANode.js +620 -0
  90. package/{src/nodes → examples/jsm/tsl}/display/SSAAPassNode.js +10 -25
  91. package/examples/jsm/tsl/display/SSRNode.js +366 -0
  92. package/{src/nodes → examples/jsm/tsl}/display/Sepia.js +1 -2
  93. package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +4 -12
  94. package/{src/nodes → examples/jsm/tsl}/display/StereoCompositePassNode.js +9 -11
  95. package/{src/nodes → examples/jsm/tsl}/display/StereoPassNode.js +10 -11
  96. package/examples/jsm/tsl/display/TRAAPassNode.js +355 -0
  97. package/{src/nodes → examples/jsm/tsl}/display/TransitionNode.js +3 -7
  98. package/examples/jsm/tsl/display/hashBlur.js +24 -0
  99. package/examples/jsm/tsl/lighting/TiledLightsNode.js +389 -0
  100. package/examples/jsm/utils/SceneOptimizer.js +410 -0
  101. package/examples/jsm/utils/UVsDebug.js +1 -1
  102. package/examples/jsm/utils/{TextureUtilsGPU.js → WebGPUTextureUtils.js} +2 -1
  103. package/examples/jsm/webxr/OculusHandPointerModel.js +21 -21
  104. package/examples/jsm/webxr/Text2D.js +6 -6
  105. package/package.json +4 -4
  106. package/src/Three.Core.js +178 -0
  107. package/src/Three.TSL.js +526 -0
  108. package/src/Three.WebGPU.Nodes.js +9 -186
  109. package/src/Three.WebGPU.js +8 -186
  110. package/src/Three.js +1 -177
  111. package/src/animation/AnimationClip.js +2 -2
  112. package/src/animation/AnimationObjectGroup.js +2 -2
  113. package/src/audio/Audio.js +38 -0
  114. package/src/cameras/PerspectiveCamera.js +6 -6
  115. package/src/cameras/StereoCamera.js +2 -2
  116. package/src/constants.js +1 -6
  117. package/src/core/BufferGeometry.js +48 -8
  118. package/src/core/InterleavedBuffer.js +4 -4
  119. package/src/core/Object3D.js +2 -2
  120. package/src/extras/core/Curve.js +3 -3
  121. package/src/extras/core/Shape.js +2 -2
  122. package/src/geometries/CylinderGeometry.js +2 -2
  123. package/src/geometries/EdgesGeometry.js +2 -2
  124. package/src/geometries/LatheGeometry.js +2 -2
  125. package/src/lights/SpotLightShadow.js +2 -2
  126. package/src/materials/LineDashedMaterial.js +0 -1
  127. package/src/materials/Material.js +2 -2
  128. package/src/materials/MeshPhongMaterial.js +1 -1
  129. package/src/materials/MeshPhysicalMaterial.js +2 -2
  130. package/src/materials/MeshStandardMaterial.js +2 -2
  131. package/src/materials/nodes/Line2NodeMaterial.js +32 -13
  132. package/src/materials/nodes/LineDashedNodeMaterial.js +4 -2
  133. package/src/materials/nodes/NodeMaterial.js +93 -23
  134. package/src/materials/nodes/SpriteNodeMaterial.js +11 -2
  135. package/src/materials/nodes/manager/NodeMaterialObserver.js +119 -7
  136. package/src/math/ColorManagement.js +143 -102
  137. package/src/math/Line3.js +2 -2
  138. package/src/math/Quaternion.js +2 -2
  139. package/src/math/Spherical.js +3 -3
  140. package/src/math/Vector2.js +7 -7
  141. package/src/math/Vector3.js +9 -9
  142. package/src/math/Vector4.js +22 -9
  143. package/src/nodes/Nodes.js +2 -21
  144. package/src/nodes/TSL.js +9 -25
  145. package/src/nodes/accessors/Arrays.js +27 -0
  146. package/src/nodes/accessors/BuiltinNode.js +26 -0
  147. package/src/nodes/accessors/Camera.js +0 -1
  148. package/src/nodes/accessors/ClippingNode.js +76 -42
  149. package/src/nodes/accessors/InstanceNode.js +17 -20
  150. package/src/nodes/accessors/InstancedMeshNode.js +26 -0
  151. package/src/nodes/accessors/Lights.js +32 -0
  152. package/src/nodes/accessors/SceneNode.js +35 -1
  153. package/src/nodes/accessors/StorageBufferNode.js +61 -19
  154. package/src/nodes/accessors/StorageTextureNode.js +10 -4
  155. package/src/nodes/accessors/TextureNode.js +1 -1
  156. package/src/nodes/accessors/VelocityNode.js +13 -3
  157. package/src/nodes/code/FunctionCallNode.js +16 -5
  158. package/src/nodes/code/ScriptableNode.js +4 -4
  159. package/src/nodes/core/Node.js +1 -0
  160. package/src/nodes/core/NodeBuilder.js +31 -14
  161. package/src/nodes/core/NodeUtils.js +28 -0
  162. package/src/nodes/core/VarNode.js +15 -3
  163. package/src/nodes/core/constants.js +6 -0
  164. package/src/nodes/display/BlendModes.js +99 -0
  165. package/src/nodes/display/ColorAdjustment.js +53 -4
  166. package/src/nodes/display/ColorSpaceFunctions.js +5 -5
  167. package/src/nodes/display/ColorSpaceNode.js +27 -39
  168. package/src/nodes/display/PassNode.js +6 -4
  169. package/src/nodes/display/ToneMappingNode.js +1 -1
  170. package/src/nodes/display/ToonOutlinePassNode.js +3 -3
  171. package/src/nodes/display/ViewportDepthNode.js +48 -1
  172. package/src/nodes/functions/PhysicalLightingModel.js +21 -15
  173. package/src/nodes/functions/material/getAlphaHashThreshold.js +70 -0
  174. package/src/nodes/functions/material/getGeometryRoughness.js +8 -2
  175. package/src/nodes/functions/material/getParallaxCorrectNormal.js +22 -0
  176. package/src/nodes/gpgpu/ComputeNode.js +9 -1
  177. package/src/nodes/lighting/AnalyticLightNode.js +23 -419
  178. package/src/nodes/lighting/LightsNode.js +24 -12
  179. package/src/nodes/lighting/PointLightNode.js +41 -22
  180. package/src/nodes/lighting/PointShadowNode.js +254 -0
  181. package/src/nodes/lighting/RectAreaLightNode.js +3 -0
  182. package/src/nodes/lighting/ShadowNode.js +593 -0
  183. package/src/nodes/lighting/SpotLightNode.js +14 -2
  184. package/src/nodes/utils/LoopNode.js +2 -2
  185. package/src/nodes/utils/Oscillators.js +6 -0
  186. package/src/nodes/utils/PostProcessingUtils.js +89 -0
  187. package/src/nodes/utils/RTTNode.js +9 -1
  188. package/src/nodes/utils/ReflectorNode.js +101 -15
  189. package/src/nodes/utils/StorageArrayElementNode.js +2 -2
  190. package/src/nodes/utils/Timer.js +29 -0
  191. package/src/objects/BatchedMesh.js +472 -296
  192. package/src/objects/ClippingGroup.js +19 -0
  193. package/src/objects/Skeleton.js +2 -2
  194. package/src/renderers/WebGLRenderer.js +183 -109
  195. package/src/renderers/common/Animation.js +23 -11
  196. package/src/renderers/common/Attributes.js +4 -0
  197. package/src/renderers/common/Backend.js +2 -0
  198. package/src/renderers/common/Background.js +15 -5
  199. package/src/renderers/common/Bindings.js +23 -6
  200. package/src/renderers/common/ClippingContext.js +77 -85
  201. package/src/renderers/common/Constants.js +2 -1
  202. package/src/renderers/common/Geometries.js +20 -0
  203. package/src/renderers/common/IndirectStorageBufferAttribute.js +15 -0
  204. package/src/renderers/common/Lighting.js +45 -0
  205. package/src/renderers/common/PostProcessingUtils.js +86 -0
  206. package/src/renderers/common/RenderList.js +48 -17
  207. package/src/renderers/common/RenderLists.js +4 -2
  208. package/src/renderers/common/RenderObject.js +45 -28
  209. package/src/renderers/common/RenderObjects.js +12 -6
  210. package/src/renderers/common/Renderer.js +222 -77
  211. package/src/renderers/common/Textures.js +41 -17
  212. package/src/renderers/common/UniformsGroup.js +16 -4
  213. package/src/renderers/common/extras/PMREMGenerator.js +89 -13
  214. package/src/renderers/common/nodes/NodeLibrary.js +2 -15
  215. package/src/renderers/common/nodes/NodeStorageBuffer.js +2 -3
  216. package/src/renderers/common/nodes/NodeUniform.js +42 -0
  217. package/src/renderers/common/nodes/Nodes.js +2 -2
  218. package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
  219. package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
  220. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
  221. package/src/renderers/webgl/WebGLBackground.js +20 -1
  222. package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
  223. package/src/renderers/webgl/WebGLCapabilities.js +0 -7
  224. package/src/renderers/webgl/WebGLGeometries.js +0 -28
  225. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
  226. package/src/renderers/webgl/WebGLProgram.js +24 -28
  227. package/src/renderers/webgl/WebGLPrograms.js +5 -2
  228. package/src/renderers/webgl/WebGLState.js +37 -1
  229. package/src/renderers/webgl/WebGLTextures.js +29 -12
  230. package/src/renderers/webgl-fallback/WebGLBackend.js +111 -37
  231. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +2 -7
  232. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +43 -12
  233. package/src/renderers/webgl-fallback/utils/WebGLState.js +26 -1
  234. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +37 -9
  235. package/src/renderers/webgpu/WebGPUBackend.js +152 -56
  236. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +1 -1
  237. package/src/renderers/webgpu/WebGPURenderer.js +1 -1
  238. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +0 -8
  239. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +13 -34
  240. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +192 -92
  241. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +12 -4
  242. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +15 -2
  243. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +72 -7
  244. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +29 -9
  245. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +29 -7
  246. package/src/renderers/webgpu/utils/WebGPUUtils.js +0 -1
  247. package/src/renderers/webxr/WebXRManager.js +4 -4
  248. package/src/textures/Source.js +2 -2
  249. package/src/textures/Texture.js +2 -2
  250. package/examples/jsm/cameras/CinematicCamera.js +0 -208
  251. package/src/nodes/display/BlendMode.js +0 -54
  252. package/src/nodes/display/FXAANode.js +0 -332
  253. package/src/nodes/utils/OscNode.js +0 -85
  254. package/src/nodes/utils/TimerNode.js +0 -97
  255. /package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +0 -0
@@ -0,0 +1,410 @@
1
+ import * as THREE from 'three';
2
+
3
+ class SceneOptimizer {
4
+
5
+ constructor( scene, options = {} ) {
6
+
7
+ this.scene = scene;
8
+ this.debug = options.debug || false;
9
+
10
+ }
11
+
12
+ bufferToHash( buffer ) {
13
+
14
+ let hash = 0;
15
+ if ( buffer.byteLength !== 0 ) {
16
+
17
+ let uintArray;
18
+ if ( buffer.buffer ) {
19
+
20
+ uintArray = new Uint8Array(
21
+ buffer.buffer,
22
+ buffer.byteOffset,
23
+ buffer.byteLength
24
+ );
25
+
26
+ } else {
27
+
28
+ uintArray = new Uint8Array( buffer );
29
+
30
+ }
31
+
32
+ for ( let i = 0; i < buffer.byteLength; i ++ ) {
33
+
34
+ const byte = uintArray[ i ];
35
+ hash = ( hash << 5 ) - hash + byte;
36
+ hash |= 0;
37
+
38
+ }
39
+
40
+ }
41
+
42
+ return hash;
43
+
44
+ }
45
+
46
+ getMaterialPropertiesHash( material ) {
47
+
48
+ const mapProps = [
49
+ 'map',
50
+ 'alphaMap',
51
+ 'aoMap',
52
+ 'bumpMap',
53
+ 'displacementMap',
54
+ 'emissiveMap',
55
+ 'envMap',
56
+ 'lightMap',
57
+ 'metalnessMap',
58
+ 'normalMap',
59
+ 'roughnessMap',
60
+ ];
61
+
62
+ const mapHash = mapProps
63
+ .map( ( prop ) => {
64
+
65
+ const map = material[ prop ];
66
+ if ( ! map ) return 0;
67
+ return `${map.uuid}_${map.offset.x}_${map.offset.y}_${map.repeat.x}_${map.repeat.y}_${map.rotation}`;
68
+
69
+ } )
70
+ .join( '|' );
71
+
72
+ const physicalProps = [
73
+ 'transparent',
74
+ 'opacity',
75
+ 'alphaTest',
76
+ 'alphaToCoverage',
77
+ 'side',
78
+ 'vertexColors',
79
+ 'visible',
80
+ 'blending',
81
+ 'wireframe',
82
+ 'flatShading',
83
+ 'premultipliedAlpha',
84
+ 'dithering',
85
+ 'toneMapped',
86
+ 'depthTest',
87
+ 'depthWrite',
88
+ 'metalness',
89
+ 'roughness',
90
+ 'clearcoat',
91
+ 'clearcoatRoughness',
92
+ 'sheen',
93
+ 'sheenRoughness',
94
+ 'transmission',
95
+ 'thickness',
96
+ 'attenuationDistance',
97
+ 'ior',
98
+ 'iridescence',
99
+ 'iridescenceIOR',
100
+ 'iridescenceThicknessRange',
101
+ 'reflectivity',
102
+ ]
103
+ .map( ( prop ) => {
104
+
105
+ if ( typeof material[ prop ] === 'undefined' ) return 0;
106
+ if ( material[ prop ] === null ) return 0;
107
+ return material[ prop ].toString();
108
+
109
+ } )
110
+ .join( '|' );
111
+
112
+ const emissiveHash = material.emissive ? material.emissive.getHexString() : 0;
113
+ const attenuationHash = material.attenuationColor
114
+ ? material.attenuationColor.getHexString()
115
+ : 0;
116
+ const sheenColorHash = material.sheenColor
117
+ ? material.sheenColor.getHexString()
118
+ : 0;
119
+
120
+ return [
121
+ material.type,
122
+ physicalProps,
123
+ mapHash,
124
+ emissiveHash,
125
+ attenuationHash,
126
+ sheenColorHash,
127
+ ].join( '_' );
128
+
129
+ }
130
+
131
+ getAttributesSignature( geometry ) {
132
+
133
+ return Object.keys( geometry.attributes )
134
+ .sort()
135
+ .map( ( name ) => {
136
+
137
+ const attribute = geometry.attributes[ name ];
138
+ return `${name}_${attribute.itemSize}_${attribute.normalized}`;
139
+
140
+ } )
141
+ .join( '|' );
142
+
143
+ }
144
+
145
+ getGeometryHash( geometry ) {
146
+
147
+ const indexHash = geometry.index
148
+ ? this.bufferToHash( geometry.index.array )
149
+ : 'noIndex';
150
+ const positionHash = this.bufferToHash( geometry.attributes.position.array );
151
+ const attributesSignature = this.getAttributesSignature( geometry );
152
+ return `${indexHash}_${positionHash}_${attributesSignature}`;
153
+
154
+ }
155
+
156
+ getBatchKey( materialProps, attributesSignature ) {
157
+
158
+ return `${materialProps}_${attributesSignature}`;
159
+
160
+ }
161
+
162
+ analyzeModel() {
163
+
164
+ const batchGroups = new Map();
165
+ const singleGroups = new Map();
166
+ const uniqueGeometries = new Set();
167
+
168
+ this.scene.updateMatrixWorld( true );
169
+ this.scene.traverse( ( node ) => {
170
+
171
+ if ( ! node.isMesh ) return;
172
+
173
+ const materialProps = this.getMaterialPropertiesHash( node.material );
174
+ const attributesSignature = this.getAttributesSignature( node.geometry );
175
+ const batchKey = this.getBatchKey( materialProps, attributesSignature );
176
+ const geometryHash = this.getGeometryHash( node.geometry );
177
+ uniqueGeometries.add( geometryHash );
178
+
179
+ if ( ! batchGroups.has( batchKey ) ) {
180
+
181
+ batchGroups.set( batchKey, {
182
+ meshes: [],
183
+ geometryStats: new Map(),
184
+ totalInstances: 0,
185
+ materialProps: node.material.clone(),
186
+ } );
187
+
188
+ }
189
+
190
+ const group = batchGroups.get( batchKey );
191
+ group.meshes.push( node );
192
+ group.totalInstances ++;
193
+
194
+ if ( ! group.geometryStats.has( geometryHash ) ) {
195
+
196
+ group.geometryStats.set( geometryHash, {
197
+ count: 0,
198
+ vertices: node.geometry.attributes.position.count,
199
+ indices: node.geometry.index ? node.geometry.index.count : 0,
200
+ geometry: node.geometry,
201
+ } );
202
+
203
+ }
204
+
205
+ group.geometryStats.get( geometryHash ).count ++;
206
+
207
+ } );
208
+
209
+ // Move single instance groups to singleGroups
210
+ for ( const [ batchKey, group ] of batchGroups ) {
211
+
212
+ if ( group.totalInstances === 1 ) {
213
+
214
+ singleGroups.set( batchKey, group );
215
+ batchGroups.delete( batchKey );
216
+
217
+ }
218
+
219
+ }
220
+
221
+ return { batchGroups, singleGroups, uniqueGeometries: uniqueGeometries.size };
222
+
223
+ }
224
+
225
+ createBatchedMeshes( batchGroups ) {
226
+
227
+ const meshesToRemove = new Set();
228
+
229
+ for ( const [ , group ] of batchGroups ) {
230
+
231
+ const maxGeometries = group.totalInstances;
232
+ const maxVertices = Array.from( group.geometryStats.values() ).reduce(
233
+ ( sum, stats ) => sum + stats.vertices,
234
+ 0
235
+ );
236
+ const maxIndices = Array.from( group.geometryStats.values() ).reduce(
237
+ ( sum, stats ) => sum + stats.indices,
238
+ 0
239
+ );
240
+
241
+ const batchedMaterial = new group.materialProps.constructor( group.materialProps );
242
+
243
+ if ( batchedMaterial.color !== undefined ) {
244
+
245
+ // Reset color to white, color will be set per instance
246
+ batchedMaterial.color.set( 1, 1, 1 );
247
+
248
+ }
249
+
250
+ const batchedMesh = new THREE.BatchedMesh(
251
+ maxGeometries,
252
+ maxVertices,
253
+ maxIndices,
254
+ batchedMaterial
255
+ );
256
+
257
+ const referenceMesh = group.meshes[ 0 ];
258
+ batchedMesh.name = `${referenceMesh.name}_batch`;
259
+
260
+ const geometryIds = new Map();
261
+ const inverseParentMatrix = new THREE.Matrix4();
262
+
263
+ if ( referenceMesh.parent ) {
264
+
265
+ referenceMesh.parent.updateWorldMatrix( true, false );
266
+ inverseParentMatrix.copy( referenceMesh.parent.matrixWorld ).invert();
267
+
268
+ }
269
+
270
+ for ( const mesh of group.meshes ) {
271
+
272
+ const geometryHash = this.getGeometryHash( mesh.geometry );
273
+
274
+ if ( ! geometryIds.has( geometryHash ) ) {
275
+
276
+ geometryIds.set( geometryHash, batchedMesh.addGeometry( mesh.geometry ) );
277
+
278
+ }
279
+
280
+ const geometryId = geometryIds.get( geometryHash );
281
+ const instanceId = batchedMesh.addInstance( geometryId );
282
+
283
+ const localMatrix = new THREE.Matrix4();
284
+ mesh.updateWorldMatrix( true, false );
285
+ localMatrix.copy( mesh.matrixWorld );
286
+ if ( referenceMesh.parent ) {
287
+
288
+ localMatrix.premultiply( inverseParentMatrix );
289
+
290
+ }
291
+
292
+ batchedMesh.setMatrixAt( instanceId, localMatrix );
293
+ batchedMesh.setColorAt( instanceId, mesh.material.color );
294
+
295
+ meshesToRemove.add( mesh );
296
+
297
+ }
298
+
299
+ if ( referenceMesh.parent ) {
300
+
301
+ referenceMesh.parent.add( batchedMesh );
302
+
303
+ }
304
+
305
+ }
306
+
307
+ return meshesToRemove;
308
+
309
+ }
310
+
311
+ removeEmptyNodes( object ) {
312
+
313
+ const children = [ ...object.children ];
314
+
315
+ for ( const child of children ) {
316
+
317
+ this.removeEmptyNodes( child );
318
+
319
+ if ( ( child instanceof THREE.Group || child.constructor === THREE.Object3D )
320
+ && child.children.length === 0 ) {
321
+
322
+ object.remove( child );
323
+
324
+ }
325
+
326
+ }
327
+
328
+ }
329
+
330
+ disposeMeshes( meshesToRemove ) {
331
+
332
+ meshesToRemove.forEach( ( mesh ) => {
333
+
334
+ if ( mesh.parent ) {
335
+
336
+ mesh.parent.remove( mesh );
337
+
338
+ }
339
+
340
+ if ( mesh.geometry ) mesh.geometry.dispose();
341
+ if ( mesh.material ) {
342
+
343
+ if ( Array.isArray( mesh.material ) ) {
344
+
345
+ mesh.material.forEach( ( m ) => m.dispose() );
346
+
347
+ } else {
348
+
349
+ mesh.material.dispose();
350
+
351
+ }
352
+
353
+ }
354
+
355
+ } );
356
+
357
+ }
358
+
359
+ logDebugInfo( stats ) {
360
+
361
+ console.group( 'Scene Optimization Results' );
362
+ console.log( `Original meshes: ${stats.originalMeshes}` );
363
+ console.log( `Batched into: ${stats.batchedMeshes} BatchedMesh` );
364
+ console.log( `Single meshes: ${stats.singleMeshes} Mesh` );
365
+ console.log( `Total draw calls: ${stats.drawCalls}` );
366
+ console.log( `Reduction Ratio: ${stats.reductionRatio}% fewer draw calls` );
367
+ console.groupEnd();
368
+
369
+ }
370
+
371
+ toBatchedMesh() {
372
+
373
+ const { batchGroups, singleGroups, uniqueGeometries } = this.analyzeModel();
374
+ const meshesToRemove = this.createBatchedMeshes( batchGroups );
375
+
376
+ this.disposeMeshes( meshesToRemove );
377
+ this.removeEmptyNodes( this.scene );
378
+
379
+ if ( this.debug ) {
380
+
381
+ const totalOriginalMeshes = meshesToRemove.size + singleGroups.size;
382
+ const totalFinalMeshes = batchGroups.size + singleGroups.size;
383
+
384
+ const stats = {
385
+ originalMeshes: totalOriginalMeshes,
386
+ batchedMeshes: batchGroups.size,
387
+ singleMeshes: singleGroups.size,
388
+ drawCalls: totalFinalMeshes,
389
+ uniqueGeometries: uniqueGeometries,
390
+ reductionRatio: ( ( 1 - totalFinalMeshes / totalOriginalMeshes ) * 100 ).toFixed( 1 ),
391
+ };
392
+
393
+ this.logDebugInfo( stats );
394
+
395
+ }
396
+
397
+ return this.scene;
398
+
399
+ }
400
+
401
+ // Placeholder for future implementation
402
+ toInstancingMesh() {
403
+
404
+ throw new Error( 'InstancedMesh optimization not implemented yet' );
405
+
406
+ }
407
+
408
+ }
409
+
410
+ export { SceneOptimizer };
@@ -6,7 +6,7 @@ import {
6
6
  * tool for "unwrapping" and debugging three.js geometries UV mapping
7
7
  *
8
8
  * Sample usage:
9
- * document.body.appendChild( UVsDebug( new THREE.SphereGeometry( 10, 10, 10, 10 ) );
9
+ * document.body.appendChild( UVsDebug( new THREE.SphereGeometry( 10, 10, 10, 10 ) ) );
10
10
  *
11
11
  */
12
12
 
@@ -19,7 +19,8 @@ export async function decompress( blitTexture, maxTextureSize = Infinity, render
19
19
  }
20
20
 
21
21
  const material = new NodeMaterial();
22
- material.fragmentNode = texture( blitTexture ).uv( uv().flipY() );
22
+
23
+ material.fragmentNode = texture( blitTexture, uv().flipY() );
23
24
 
24
25
  const width = Math.min( blitTexture.image.width, maxTextureSize );
25
26
  const height = Math.min( blitTexture.image.height, maxTextureSize );
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import { BufferGeometry, Float32BufferAttribute, Matrix4, Mesh, MeshBasicMaterial, Object3D, Raycaster, SphereGeometry, Vector3 } from 'three';
2
2
 
3
3
  const PINCH_MAX = 0.05;
4
4
  const PINCH_THRESHOLD = 0.02;
@@ -13,13 +13,13 @@ const POINTER_LENGTH = 0.035;
13
13
  const POINTER_SEGMENTS = 16;
14
14
  const POINTER_RINGS = 12;
15
15
  const POINTER_HEMISPHERE_ANGLE = 110;
16
- const YAXIS = /* @__PURE__ */ new THREE.Vector3( 0, 1, 0 );
17
- const ZAXIS = /* @__PURE__ */ new THREE.Vector3( 0, 0, 1 );
16
+ const YAXIS = /* @__PURE__ */ new Vector3( 0, 1, 0 );
17
+ const ZAXIS = /* @__PURE__ */ new Vector3( 0, 0, 1 );
18
18
 
19
19
  const CURSOR_RADIUS = 0.02;
20
20
  const CURSOR_MAX_DISTANCE = 1.5;
21
21
 
22
- class OculusHandPointerModel extends THREE.Object3D {
22
+ class OculusHandPointerModel extends Object3D {
23
23
 
24
24
  constructor( hand, controller ) {
25
25
 
@@ -96,7 +96,7 @@ class OculusHandPointerModel extends THREE.Object3D {
96
96
 
97
97
  const vertices = this.pointerGeometry.attributes.position.array;
98
98
  // first ring for front face
99
- const frontFaceBase = new THREE.Vector3(
99
+ const frontFaceBase = new Vector3(
100
100
  POINTER_FRONT_RADIUS,
101
101
  0,
102
102
  - 1 * ( POINTER_LENGTH - rearRadius )
@@ -104,7 +104,7 @@ class OculusHandPointerModel extends THREE.Object3D {
104
104
  this._drawVerticesRing( vertices, frontFaceBase, 0 );
105
105
 
106
106
  // rings for rear hemisphere
107
- const rearBase = new THREE.Vector3(
107
+ const rearBase = new Vector3(
108
108
  Math.sin( ( Math.PI * POINTER_HEMISPHERE_ANGLE ) / 180 ) * rearRadius,
109
109
  Math.cos( ( Math.PI * POINTER_HEMISPHERE_ANGLE ) / 180 ) * rearRadius,
110
110
  0
@@ -122,7 +122,7 @@ class OculusHandPointerModel extends THREE.Object3D {
122
122
  // front and rear face center vertices
123
123
  const frontCenterIndex = POINTER_SEGMENTS * ( 1 + POINTER_RINGS );
124
124
  const rearCenterIndex = POINTER_SEGMENTS * ( 1 + POINTER_RINGS ) + 1;
125
- const frontCenter = new THREE.Vector3(
125
+ const frontCenter = new Vector3(
126
126
  0,
127
127
  0,
128
128
  - 1 * ( POINTER_LENGTH - rearRadius )
@@ -130,14 +130,14 @@ class OculusHandPointerModel extends THREE.Object3D {
130
130
  vertices[ frontCenterIndex * 3 ] = frontCenter.x;
131
131
  vertices[ frontCenterIndex * 3 + 1 ] = frontCenter.y;
132
132
  vertices[ frontCenterIndex * 3 + 2 ] = frontCenter.z;
133
- const rearCenter = new THREE.Vector3( 0, 0, rearRadius );
133
+ const rearCenter = new Vector3( 0, 0, rearRadius );
134
134
  vertices[ rearCenterIndex * 3 ] = rearCenter.x;
135
135
  vertices[ rearCenterIndex * 3 + 1 ] = rearCenter.y;
136
136
  vertices[ rearCenterIndex * 3 + 2 ] = rearCenter.z;
137
137
 
138
138
  this.pointerGeometry.setAttribute(
139
139
  'position',
140
- new THREE.Float32BufferAttribute( vertices, 3 )
140
+ new Float32BufferAttribute( vertices, 3 )
141
141
  );
142
142
  // verticesNeedUpdate = true;
143
143
 
@@ -151,11 +151,11 @@ class OculusHandPointerModel extends THREE.Object3D {
151
151
  ).fill( 0 );
152
152
  // const vertices = [];
153
153
  const indices = [];
154
- this.pointerGeometry = new THREE.BufferGeometry();
154
+ this.pointerGeometry = new BufferGeometry();
155
155
 
156
156
  this.pointerGeometry.setAttribute(
157
157
  'position',
158
- new THREE.Float32BufferAttribute( vertices, 3 )
158
+ new Float32BufferAttribute( vertices, 3 )
159
159
  );
160
160
 
161
161
  this._updatePointerVertices( POINTER_REAR_RADIUS );
@@ -213,27 +213,27 @@ class OculusHandPointerModel extends THREE.Object3D {
213
213
  POINTER_SEGMENTS * POINTER_RINGS
214
214
  );
215
215
 
216
- const material = new THREE.MeshBasicMaterial();
216
+ const material = new MeshBasicMaterial();
217
217
  material.transparent = true;
218
218
  material.opacity = POINTER_OPACITY_MIN;
219
219
 
220
220
  this.pointerGeometry.setIndex( indices );
221
221
 
222
- this.pointerMesh = new THREE.Mesh( this.pointerGeometry, material );
222
+ this.pointerMesh = new Mesh( this.pointerGeometry, material );
223
223
 
224
224
  this.pointerMesh.position.set( 0, 0, - 1 * POINTER_REAR_RADIUS );
225
- this.pointerObject = new THREE.Object3D();
225
+ this.pointerObject = new Object3D();
226
226
  this.pointerObject.add( this.pointerMesh );
227
227
 
228
- this.raycaster = new THREE.Raycaster();
228
+ this.raycaster = new Raycaster();
229
229
 
230
230
  // create cursor
231
- const cursorGeometry = new THREE.SphereGeometry( CURSOR_RADIUS, 10, 10 );
232
- const cursorMaterial = new THREE.MeshBasicMaterial();
231
+ const cursorGeometry = new SphereGeometry( CURSOR_RADIUS, 10, 10 );
232
+ const cursorMaterial = new MeshBasicMaterial();
233
233
  cursorMaterial.transparent = true;
234
234
  cursorMaterial.opacity = POINTER_OPACITY_MIN;
235
235
 
236
- this.cursorObject = new THREE.Mesh( cursorGeometry, cursorMaterial );
236
+ this.cursorObject = new Mesh( cursorGeometry, cursorMaterial );
237
237
  this.pointerObject.add( this.cursorObject );
238
238
 
239
239
  this.add( this.pointerObject );
@@ -245,7 +245,7 @@ class OculusHandPointerModel extends THREE.Object3D {
245
245
  if ( this.raycaster ) {
246
246
 
247
247
  const pointerMatrix = this.pointerObject.matrixWorld;
248
- const tempMatrix = new THREE.Matrix4();
248
+ const tempMatrix = new Matrix4();
249
249
  tempMatrix.identity().extractRotation( pointerMatrix );
250
250
  this.raycaster.ray.origin.setFromMatrixPosition( pointerMatrix );
251
251
  this.raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
@@ -372,7 +372,7 @@ class OculusHandPointerModel extends THREE.Object3D {
372
372
  if ( this.raycaster && ! this.attached ) {
373
373
 
374
374
  const intersections = this.raycaster.intersectObjects( objects, recursive );
375
- const direction = new THREE.Vector3( 0, 0, - 1 );
375
+ const direction = new Vector3( 0, 0, - 1 );
376
376
  if ( intersections.length > 0 ) {
377
377
 
378
378
  const intersection = intersections[ 0 ];
@@ -391,7 +391,7 @@ class OculusHandPointerModel extends THREE.Object3D {
391
391
 
392
392
  setCursor( distance ) {
393
393
 
394
- const direction = new THREE.Vector3( 0, 0, - 1 );
394
+ const direction = new Vector3( 0, 0, - 1 );
395
395
  if ( this.raycaster && ! this.attached ) {
396
396
 
397
397
  this.cursorObject.position.copy( direction.multiplyScalar( distance ) );
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import { DoubleSide, Mesh, MeshBasicMaterial, PlaneGeometry, Texture } from 'three';
2
2
 
3
3
  function createText( message, height ) {
4
4
 
@@ -17,20 +17,20 @@ function createText( message, height ) {
17
17
  context.fillStyle = '#ffffff';
18
18
  context.fillText( message, textWidth / 2, textHeight / 2 );
19
19
 
20
- const texture = new THREE.Texture( canvas );
20
+ const texture = new Texture( canvas );
21
21
  texture.needsUpdate = true;
22
22
 
23
- const material = new THREE.MeshBasicMaterial( {
23
+ const material = new MeshBasicMaterial( {
24
24
  color: 0xffffff,
25
- side: THREE.DoubleSide,
25
+ side: DoubleSide,
26
26
  map: texture,
27
27
  transparent: true,
28
28
  } );
29
- const geometry = new THREE.PlaneGeometry(
29
+ const geometry = new PlaneGeometry(
30
30
  ( height * textWidth ) / textHeight,
31
31
  height
32
32
  );
33
- const plane = new THREE.Mesh( geometry, material );
33
+ const plane = new Mesh( geometry, material );
34
34
  return plane;
35
35
 
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "super-three",
3
- "version": "0.169.1",
3
+ "version": "0.170.1",
4
4
  "description": "JavaScript 3D library",
5
5
  "type": "module",
6
6
  "main": "./build/three.cjs",
@@ -16,7 +16,7 @@
16
16
  "./addons/*": "./examples/jsm/*",
17
17
  "./src/*": "./src/*",
18
18
  "./webgpu": "./build/three.webgpu.js",
19
- "./tsl": "./build/three.webgpu.js"
19
+ "./tsl": "./build/three.tsl.js"
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",
@@ -101,7 +101,7 @@
101
101
  "eslint-plugin-html": "^8.0.0",
102
102
  "eslint-plugin-import": "^2.27.5",
103
103
  "failonlyreporter": "^1.0.0",
104
- "jimp": "^0.22.7",
104
+ "jimp": "^1.6.0",
105
105
  "magic-string": "^0.30.0",
106
106
  "pixelmatch": "^6.0.0",
107
107
  "puppeteer": "^22.0.0",
@@ -109,7 +109,7 @@
109
109
  "rollup": "^4.6.0",
110
110
  "rollup-plugin-filesize": "^10.0.0",
111
111
  "rollup-plugin-visualizer": "^5.9.0",
112
- "servez": "^2.0.0"
112
+ "servez": "^2.2.4"
113
113
  },
114
114
  "overrides": {
115
115
  "jpeg-js": "^0.4.4"