super-three 0.157.1 → 0.158.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 (178) hide show
  1. package/README.md +6 -4
  2. package/build/three.cjs +1013 -790
  3. package/build/three.js +1013 -790
  4. package/build/three.min.js +1 -1
  5. package/build/three.module.js +1008 -791
  6. package/build/three.module.min.js +1 -1
  7. package/examples/jsm/Addons.js +290 -0
  8. package/examples/jsm/controls/FlyControls.js +26 -0
  9. package/examples/jsm/controls/OrbitControls.js +12 -1
  10. package/examples/jsm/controls/TransformControls.js +27 -11
  11. package/examples/jsm/csm/CSMShader.js +1 -1
  12. package/examples/jsm/exporters/GLTFExporter.js +72 -2
  13. package/examples/jsm/geometries/InstancedPointsGeometry.js +174 -0
  14. package/examples/jsm/geometries/SDFGeometryGenerator.js +144 -0
  15. package/examples/jsm/libs/lottie_canvas.module.js +6 -1
  16. package/examples/jsm/libs/opentype.module.js +13 -75
  17. package/examples/jsm/libs/surfaceNet.js +201 -0
  18. package/examples/jsm/loaders/GLTFLoader.js +12 -3
  19. package/examples/jsm/loaders/LUTImageLoader.js +162 -0
  20. package/examples/jsm/loaders/lwo/IFFParser.js +89 -93
  21. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
  22. package/examples/jsm/math/Capsule.js +0 -55
  23. package/examples/jsm/math/Octree.js +70 -3
  24. package/examples/jsm/modifiers/SimplifyModifier.js +103 -11
  25. package/examples/jsm/modifiers/TessellateModifier.js +3 -3
  26. package/examples/jsm/nodes/Nodes.js +6 -6
  27. package/examples/jsm/nodes/accessors/CubeTextureNode.js +3 -3
  28. package/examples/jsm/nodes/accessors/InstanceNode.js +3 -3
  29. package/examples/jsm/nodes/accessors/InstancedPointsMaterialNode.js +21 -0
  30. package/examples/jsm/nodes/accessors/MaterialNode.js +68 -31
  31. package/examples/jsm/nodes/accessors/ModelNode.js +1 -2
  32. package/examples/jsm/nodes/accessors/MorphNode.js +5 -5
  33. package/examples/jsm/nodes/accessors/NormalNode.js +1 -1
  34. package/examples/jsm/nodes/accessors/PositionNode.js +1 -1
  35. package/examples/jsm/nodes/accessors/SkinningNode.js +13 -3
  36. package/examples/jsm/nodes/accessors/TextureNode.js +3 -3
  37. package/examples/jsm/nodes/code/FunctionNode.js +1 -1
  38. package/examples/jsm/nodes/core/AssignNode.js +72 -0
  39. package/examples/jsm/nodes/core/LightingModel.js +3 -1
  40. package/examples/jsm/nodes/core/Node.js +7 -12
  41. package/examples/jsm/nodes/core/NodeBuilder.js +126 -16
  42. package/examples/jsm/nodes/core/NodeUtils.js +4 -2
  43. package/examples/jsm/nodes/core/OutputStructNode.js +1 -1
  44. package/examples/jsm/nodes/core/ParameterNode.js +33 -0
  45. package/examples/jsm/nodes/core/PropertyNode.js +4 -10
  46. package/examples/jsm/nodes/core/StackNode.js +7 -17
  47. package/examples/jsm/nodes/core/TempNode.js +1 -1
  48. package/examples/jsm/nodes/core/VarNode.js +6 -35
  49. package/examples/jsm/nodes/core/VaryingNode.js +2 -0
  50. package/examples/jsm/nodes/display/BumpMapNode.js +35 -13
  51. package/examples/jsm/nodes/display/NormalMapNode.js +3 -1
  52. package/examples/jsm/nodes/display/ViewportNode.js +14 -4
  53. package/examples/jsm/nodes/functions/BSDF/BRDF_Sheen.js +20 -6
  54. package/examples/jsm/nodes/functions/BSDF/DFGApprox.js +8 -7
  55. package/examples/jsm/nodes/functions/BSDF/D_GGX.js +8 -3
  56. package/examples/jsm/nodes/functions/BSDF/Schlick_to_F0.js +8 -0
  57. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +8 -0
  58. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +93 -43
  59. package/examples/jsm/nodes/gpgpu/ComputeNode.js +2 -2
  60. package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
  61. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +19 -5
  62. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +1 -1
  63. package/examples/jsm/nodes/lighting/EnvironmentNode.js +0 -6
  64. package/examples/jsm/nodes/lighting/LightingContextNode.js +21 -57
  65. package/examples/jsm/nodes/lighting/LightsNode.js +62 -4
  66. package/examples/jsm/nodes/lighting/PointLightNode.js +1 -1
  67. package/examples/jsm/nodes/lighting/SpotLightNode.js +1 -1
  68. package/examples/jsm/nodes/materials/InstancedPointsNodeMaterial.js +162 -0
  69. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +70 -71
  70. package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +5 -5
  71. package/examples/jsm/nodes/materials/Materials.js +1 -0
  72. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +2 -2
  73. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +3 -3
  74. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +47 -20
  75. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +6 -6
  76. package/examples/jsm/nodes/materials/NodeMaterial.js +17 -20
  77. package/examples/jsm/nodes/materialx/lib/mx_noise.js +5 -5
  78. package/examples/jsm/nodes/math/OperatorNode.js +5 -21
  79. package/examples/jsm/nodes/shadernode/ShaderNode.js +128 -9
  80. package/examples/jsm/nodes/utils/ArrayElementNode.js +2 -0
  81. package/examples/jsm/nodes/utils/DiscardNode.js +3 -2
  82. package/examples/jsm/nodes/utils/JoinNode.js +11 -1
  83. package/examples/jsm/nodes/utils/LoopNode.js +36 -24
  84. package/examples/jsm/nodes/utils/SplitNode.js +2 -0
  85. package/examples/jsm/objects/BatchedMesh.js +586 -0
  86. package/examples/jsm/objects/InstancedPoints.js +21 -0
  87. package/examples/jsm/objects/Lensflare.js +20 -0
  88. package/examples/jsm/objects/ReflectorForSSRPass.js +3 -0
  89. package/examples/jsm/objects/Refractor.js +3 -0
  90. package/examples/jsm/objects/Sky.js +5 -3
  91. package/examples/jsm/objects/Water.js +5 -2
  92. package/examples/jsm/objects/Water2.js +3 -0
  93. package/examples/jsm/physics/AmmoPhysics.js +21 -0
  94. package/examples/jsm/physics/RapierPhysics.js +21 -0
  95. package/examples/jsm/postprocessing/BokehPass.js +3 -2
  96. package/examples/jsm/postprocessing/LUTPass.js +2 -1
  97. package/examples/jsm/postprocessing/OutputPass.js +1 -0
  98. package/examples/jsm/postprocessing/Pass.js +14 -3
  99. package/examples/jsm/postprocessing/SAOPass.js +0 -1
  100. package/examples/jsm/postprocessing/SMAAPass.js +0 -2
  101. package/examples/jsm/postprocessing/TAARenderPass.js +1 -2
  102. package/examples/jsm/renderers/CSS3DRenderer.js +3 -9
  103. package/examples/jsm/renderers/SVGRenderer.js +9 -6
  104. package/examples/jsm/renderers/common/Bindings.js +1 -1
  105. package/examples/jsm/renderers/common/RenderObject.js +8 -1
  106. package/examples/jsm/renderers/common/RenderObjects.js +1 -1
  107. package/examples/jsm/renderers/common/Textures.js +4 -36
  108. package/examples/jsm/renderers/common/nodes/Nodes.js +53 -18
  109. package/examples/jsm/renderers/webgl/WebGLBackend.js +291 -50
  110. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +88 -12
  111. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +40 -5
  112. package/examples/jsm/renderers/webgl/utils/WebGLState.js +14 -2
  113. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +2 -0
  114. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +36 -4
  115. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +2 -0
  116. package/examples/jsm/shaders/AfterimageShader.js +2 -0
  117. package/examples/jsm/shaders/BasicShader.js +2 -0
  118. package/examples/jsm/shaders/BlendShader.js +2 -0
  119. package/examples/jsm/shaders/BokehShader.js +2 -0
  120. package/examples/jsm/shaders/BokehShader2.js +4 -0
  121. package/examples/jsm/shaders/BrightnessContrastShader.js +2 -0
  122. package/examples/jsm/shaders/ColorCorrectionShader.js +2 -0
  123. package/examples/jsm/shaders/DOFMipMapShader.js +2 -0
  124. package/examples/jsm/shaders/DepthLimitedBlurShader.js +5 -0
  125. package/examples/jsm/shaders/FXAAShader.js +2 -0
  126. package/examples/jsm/shaders/FilmShader.js +1 -1
  127. package/examples/jsm/shaders/FocusShader.js +2 -0
  128. package/examples/jsm/shaders/FreiChenShader.js +2 -0
  129. package/examples/jsm/shaders/GodRaysShader.js +8 -0
  130. package/examples/jsm/shaders/HalftoneShader.js +2 -0
  131. package/examples/jsm/shaders/HorizontalTiltShiftShader.js +2 -0
  132. package/examples/jsm/shaders/HueSaturationShader.js +2 -0
  133. package/examples/jsm/shaders/KaleidoShader.js +2 -0
  134. package/examples/jsm/shaders/LuminosityHighPassShader.js +2 -0
  135. package/examples/jsm/shaders/LuminosityShader.js +2 -0
  136. package/examples/jsm/shaders/MMDToonShader.js +2 -0
  137. package/examples/jsm/shaders/MirrorShader.js +2 -0
  138. package/examples/jsm/shaders/NormalMapShader.js +2 -0
  139. package/examples/jsm/shaders/OutputShader.js +4 -5
  140. package/examples/jsm/shaders/SAOShader.js +5 -0
  141. package/examples/jsm/shaders/SMAAShader.js +6 -0
  142. package/examples/jsm/shaders/SSAOShader.js +6 -0
  143. package/examples/jsm/shaders/SSRShader.js +6 -0
  144. package/examples/jsm/shaders/SobelOperatorShader.js +2 -0
  145. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +2 -0
  146. package/examples/jsm/shaders/TechnicolorShader.js +2 -0
  147. package/examples/jsm/shaders/TriangleBlurShader.js +2 -0
  148. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -0
  149. package/examples/jsm/shaders/VelocityShader.js +2 -0
  150. package/examples/jsm/shaders/VerticalTiltShiftShader.js +2 -0
  151. package/examples/jsm/shaders/WaterRefractionShader.js +2 -0
  152. package/examples/jsm/transpiler/AST.js +231 -0
  153. package/examples/jsm/transpiler/GLSLDecoder.js +899 -0
  154. package/examples/jsm/transpiler/ShaderToyDecoder.js +49 -0
  155. package/examples/jsm/transpiler/TSLEncoder.js +611 -0
  156. package/examples/jsm/transpiler/Transpiler.js +18 -0
  157. package/examples/jsm/webxr/VRButton.js +1 -1
  158. package/examples/jsm/webxr/XRButton.js +7 -5
  159. package/examples/jsm/webxr/XREstimatedLight.js +1 -1
  160. package/package.json +4 -1
  161. package/src/constants.js +7 -1
  162. package/src/extras/PMREMGenerator.js +7 -1
  163. package/src/loaders/MaterialLoader.js +10 -2
  164. package/src/materials/Material.js +27 -13
  165. package/src/math/Box3.js +35 -18
  166. package/src/math/Vector3.js +11 -12
  167. package/src/objects/SkinnedMesh.js +6 -7
  168. package/src/renderers/WebGLRenderer.js +142 -25
  169. package/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl.js +8 -0
  170. package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +3 -2
  171. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  172. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +8 -6
  173. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +2 -2
  174. package/src/renderers/webgl/WebGLProgram.js +80 -50
  175. package/src/renderers/webgl/WebGLPrograms.js +3 -0
  176. package/src/renderers/webgl/WebGLState.js +25 -4
  177. package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +0 -76
  178. package/examples/jsm/nodes/accessors/LineMaterialNode.js +0 -29
@@ -0,0 +1,586 @@
1
+ import {
2
+ BufferAttribute,
3
+ BufferGeometry,
4
+ DataTexture,
5
+ FloatType,
6
+ MathUtils,
7
+ Matrix4,
8
+ Mesh,
9
+ RGBAFormat
10
+ } from 'three';
11
+
12
+ const ID_ATTR_NAME = '_batch_id_';
13
+ const _identityMatrix = new Matrix4();
14
+ const _zeroScaleMatrix = new Matrix4().set(
15
+ 0, 0, 0, 0,
16
+ 0, 0, 0, 0,
17
+ 0, 0, 0, 0,
18
+ 0, 0, 0, 1,
19
+ );
20
+
21
+ // Custom shaders
22
+ const batchingParsVertex = /* glsl */`
23
+ #ifdef BATCHING
24
+ attribute float ${ ID_ATTR_NAME };
25
+ uniform highp sampler2D batchingTexture;
26
+ uniform int batchingTextureSize;
27
+ mat4 getBatchingMatrix( const in float i ) {
28
+ float j = i * 4.0;
29
+ float x = mod( j, float( batchingTextureSize ) );
30
+ float y = floor( j / float( batchingTextureSize ) );
31
+ float dx = 1.0 / float( batchingTextureSize );
32
+ float dy = 1.0 / float( batchingTextureSize );
33
+ y = dy * ( y + 0.5 );
34
+ vec4 v1 = texture2D( batchingTexture, vec2( dx * ( x + 0.5 ), y ) );
35
+ vec4 v2 = texture2D( batchingTexture, vec2( dx * ( x + 1.5 ), y ) );
36
+ vec4 v3 = texture2D( batchingTexture, vec2( dx * ( x + 2.5 ), y ) );
37
+ vec4 v4 = texture2D( batchingTexture, vec2( dx * ( x + 3.5 ), y ) );
38
+ return mat4( v1, v2, v3, v4 );
39
+ }
40
+ #endif
41
+ `;
42
+
43
+ const batchingbaseVertex = /* glsl */`
44
+ #ifdef BATCHING
45
+ mat4 batchingMatrix = getBatchingMatrix( ${ ID_ATTR_NAME } );
46
+ #endif
47
+ `;
48
+
49
+ const batchingnormalVertex = /* glsl */`
50
+ #ifdef BATCHING
51
+ objectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;
52
+ #ifdef USE_TANGENT
53
+ objectTangent = vec4( batchingMatrix * vec4( objectTangent, 0.0 ) ).xyz;
54
+ #endif
55
+ #endif
56
+ `;
57
+
58
+ const batchingVertex = /* glsl */`
59
+ #ifdef BATCHING
60
+ transformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;
61
+ #endif
62
+ `;
63
+
64
+ // @TODO: SkinnedMesh support?
65
+ // @TODO: Future work if needed. Move into the core. Can be optimized more with WEBGL_multi_draw.
66
+
67
+ // copies data from attribute "src" into "target" starting at "targetOffset"
68
+ function copyAttributeData( src, target, targetOffset = 0 ) {
69
+
70
+ const itemSize = target.itemSize;
71
+ if ( src.isInterleavedBufferAttribute || src.array.constructor !== target.array.constructor ) {
72
+
73
+ // use the component getters and setters if the array data cannot
74
+ // be copied directly
75
+ const vertexCount = src.count;
76
+ for ( let i = 0; i < vertexCount; i ++ ) {
77
+
78
+ for ( let c = 0; c < itemSize; c ++ ) {
79
+
80
+ target.setComponent( i + targetOffset, c, src.getComponent( i, c ) );
81
+
82
+ }
83
+
84
+ }
85
+
86
+ } else {
87
+
88
+ // faster copy approach using typed array set function
89
+ target.array.set( src.array, targetOffset * itemSize );
90
+
91
+ }
92
+
93
+ target.needsUpdate = true;
94
+
95
+ }
96
+
97
+ class BatchedMesh extends Mesh {
98
+
99
+ constructor( maxGeometryCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material ) {
100
+
101
+ super( new BufferGeometry(), material );
102
+
103
+ this._vertexStarts = [];
104
+ this._vertexCounts = [];
105
+ this._indexStarts = [];
106
+ this._indexCounts = [];
107
+
108
+ this._visible = [];
109
+ this._active = [];
110
+
111
+ this._maxGeometryCount = maxGeometryCount;
112
+ this._maxVertexCount = maxVertexCount;
113
+ this._maxIndexCount = maxIndexCount;
114
+
115
+ this._geometryInitialized = false;
116
+ this._geometryCount = 0;
117
+ this._vertexCount = 0;
118
+ this._indexCount = 0;
119
+
120
+ // Local matrix per geometry by using data texture
121
+ // @TODO: Support uniform parameter per geometry
122
+
123
+ this._matrices = [];
124
+ this._matricesTexture = null;
125
+
126
+ // @TODO: Calculate the entire binding box and make frustumCulled true
127
+ this.frustumCulled = false;
128
+
129
+ this._customUniforms = {
130
+ batchingTexture: { value: null },
131
+ batchingTextureSize: { value: 0 }
132
+ };
133
+
134
+ this._initMatricesTexture();
135
+ this._initShader();
136
+
137
+ }
138
+
139
+ _initMatricesTexture() {
140
+
141
+ // layout (1 matrix = 4 pixels)
142
+ // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
143
+ // with 8x8 pixel texture max 16 matrices * 4 pixels = (8 * 8)
144
+ // 16x16 pixel texture max 64 matrices * 4 pixels = (16 * 16)
145
+ // 32x32 pixel texture max 256 matrices * 4 pixels = (32 * 32)
146
+ // 64x64 pixel texture max 1024 matrices * 4 pixels = (64 * 64)
147
+
148
+ let size = Math.sqrt( this._maxGeometryCount * 4 ); // 4 pixels needed for 1 matrix
149
+ size = MathUtils.ceilPowerOfTwo( size );
150
+ size = Math.max( size, 4 );
151
+
152
+ const matricesArray = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
153
+ const matricesTexture = new DataTexture( matricesArray, size, size, RGBAFormat, FloatType );
154
+
155
+ this._matricesTexture = matricesTexture;
156
+ this._customUniforms.batchingTexture.value = this._matricesTexture;
157
+ this._customUniforms.batchingTextureSize.value = size;
158
+
159
+ }
160
+
161
+ _initShader() {
162
+
163
+ const material = this.material;
164
+ const currentOnBeforeCompile = material.onBeforeCompile;
165
+ const customUniforms = this._customUniforms;
166
+
167
+ material.onBeforeCompile = function onBeforeCompile( parameters, renderer ) {
168
+
169
+ // Is this replacement stable across any materials?
170
+ parameters.vertexShader = parameters.vertexShader
171
+ .replace(
172
+ '#include <skinning_pars_vertex>',
173
+ '#include <skinning_pars_vertex>\n'
174
+ + batchingParsVertex
175
+ )
176
+ .replace(
177
+ '#include <skinnormal_vertex>',
178
+ '#include <skinnormal_vertex>\n'
179
+ + batchingbaseVertex
180
+ + batchingnormalVertex
181
+ )
182
+ .replace(
183
+ '#include <skinning_vertex>',
184
+ '#include <skinning_vertex>\n'
185
+ + batchingVertex
186
+ );
187
+
188
+ for ( const uniformName in customUniforms ) {
189
+
190
+ parameters.uniforms[ uniformName ] = customUniforms[ uniformName ];
191
+
192
+ }
193
+
194
+ currentOnBeforeCompile.call( this, parameters, renderer );
195
+
196
+ };
197
+
198
+ material.defines = material.defines || {};
199
+ material.defines.BATCHING = false;
200
+
201
+ }
202
+
203
+ _initializeGeometry( reference ) {
204
+
205
+ // @TODO: geometry.groups support?
206
+ // @TODO: geometry.drawRange support?
207
+ // @TODO: geometry.morphAttributes support?
208
+
209
+ const geometry = this.geometry;
210
+ const maxVertexCount = this._maxVertexCount;
211
+ const maxGeometryCount = this._maxGeometryCount;
212
+ const maxIndexCount = this._maxIndexCount;
213
+ if ( this._geometryInitialized === false ) {
214
+
215
+ for ( const attributeName in reference.attributes ) {
216
+
217
+ const srcAttribute = reference.getAttribute( attributeName );
218
+ const { array, itemSize, normalized } = srcAttribute;
219
+
220
+ const dstArray = new array.constructor( maxVertexCount * itemSize );
221
+ const dstAttribute = new srcAttribute.constructor( dstArray, itemSize, normalized );
222
+ dstAttribute.setUsage( srcAttribute.usage );
223
+
224
+ geometry.setAttribute( attributeName, dstAttribute );
225
+
226
+ }
227
+
228
+ if ( reference.getIndex() !== null ) {
229
+
230
+ const indexArray = maxVertexCount > 65536
231
+ ? new Uint32Array( maxIndexCount )
232
+ : new Uint16Array( maxIndexCount );
233
+
234
+ geometry.setIndex( new BufferAttribute( indexArray, 1 ) );
235
+
236
+ }
237
+
238
+ const idArray = maxGeometryCount > 65536
239
+ ? new Uint32Array( maxVertexCount )
240
+ : new Uint16Array( maxVertexCount );
241
+ geometry.setAttribute( ID_ATTR_NAME, new BufferAttribute( idArray, 1 ) );
242
+
243
+ this._geometryInitialized = true;
244
+
245
+ }
246
+
247
+ }
248
+
249
+ getGeometryCount() {
250
+
251
+ return this._geometryCount;
252
+
253
+ }
254
+
255
+ getVertexCount() {
256
+
257
+ return this._vertexCount;
258
+
259
+ }
260
+
261
+ getIndexCount() {
262
+
263
+ return this._indexCount;
264
+
265
+ }
266
+
267
+ applyGeometry( geometry ) {
268
+
269
+ this._initializeGeometry( geometry );
270
+
271
+ // ensure we're not over geometry
272
+ if ( this._geometryCount >= this._maxGeometryCount ) {
273
+
274
+ throw new Error( 'BatchedMesh: Maximum geometry count reached.' );
275
+
276
+ }
277
+
278
+ // check that the geometry doesn't have a version of our reserved id attribute
279
+ if ( geometry.getAttribute( ID_ATTR_NAME ) ) {
280
+
281
+ throw new Error( `BatchedMesh: Geometry cannot use attribute "${ ID_ATTR_NAME }"` );
282
+
283
+ }
284
+
285
+ // check to ensure the geometries are using consistent attributes and indices
286
+ const batchGeometry = this.geometry;
287
+ if ( Boolean( geometry.getIndex() ) !== Boolean( batchGeometry.getIndex() ) ) {
288
+
289
+ throw new Error( 'BatchedMesh: All geometries must consistently have "index".' );
290
+
291
+ }
292
+
293
+ for ( const attributeName in batchGeometry.attributes ) {
294
+
295
+ if ( attributeName === ID_ATTR_NAME ) {
296
+
297
+ continue;
298
+
299
+ }
300
+
301
+ if ( ! geometry.hasAttribute( attributeName ) ) {
302
+
303
+ throw new Error( `BatchedMesh: Added geometry missing "${ attributeName }". All geometries must have consistent attributes.` );
304
+
305
+ }
306
+
307
+ const srcAttribute = geometry.getAttribute( attributeName );
308
+ const dstAttribute = batchGeometry.getAttribute( attributeName );
309
+ if ( srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized ) {
310
+
311
+ throw new Error( 'BatchedMesh: All attributes must have a consistent itemSize and normalized value.' );
312
+
313
+ }
314
+
315
+ }
316
+
317
+ // Assuming geometry has position attribute
318
+ const srcPositionAttribute = geometry.getAttribute( 'position' );
319
+ const vertexCount = this._vertexCount;
320
+ const indexCount = this._indexCount;
321
+ const maxVertexCount = this._maxVertexCount;
322
+ const maxIndexCount = this._maxIndexCount;
323
+
324
+ // check if we're going over our maximum buffer capacity
325
+ if (
326
+ geometry.getIndex() !== null &&
327
+ indexCount + geometry.getIndex().count > maxIndexCount ||
328
+ vertexCount + srcPositionAttribute.count > maxVertexCount
329
+ ) {
330
+
331
+ throw new Error( 'BatchedMesh: Added geometry is larger than available buffer capacity.' );
332
+
333
+ }
334
+
335
+ const visible = this._visible;
336
+ const active = this._active;
337
+ const matricesTexture = this._matricesTexture;
338
+ const matrices = this._matrices;
339
+ const matricesArray = this._matricesTexture.image.data;
340
+
341
+ const indexCounts = this._indexCounts;
342
+ const indexStarts = this._indexStarts;
343
+ const vertexCounts = this._vertexCounts;
344
+ const vertexStarts = this._vertexStarts;
345
+
346
+ const hasIndex = batchGeometry.getIndex() !== null;
347
+ const dstIndex = batchGeometry.getIndex();
348
+ const srcIndex = geometry.getIndex();
349
+
350
+ // push new geometry data range
351
+ vertexStarts.push( vertexCount );
352
+ vertexCounts.push( srcPositionAttribute.count );
353
+
354
+ // copy attribute data over
355
+ for ( const attributeName in batchGeometry.attributes ) {
356
+
357
+ if ( attributeName === ID_ATTR_NAME ) {
358
+
359
+ continue;
360
+
361
+ }
362
+
363
+ const srcAttribute = geometry.getAttribute( attributeName );
364
+ const dstAttribute = batchGeometry.getAttribute( attributeName );
365
+ copyAttributeData( srcAttribute, dstAttribute, vertexCount );
366
+
367
+ }
368
+
369
+ if ( hasIndex ) {
370
+
371
+ // push new index range
372
+ indexStarts.push( indexCount );
373
+ indexCounts.push( srcIndex.count );
374
+
375
+ // copy index data over
376
+ for ( let i = 0; i < srcIndex.count; i ++ ) {
377
+
378
+ dstIndex.setX( indexCount + i, vertexCount + srcIndex.getX( i ) );
379
+
380
+ }
381
+
382
+ this._indexCount += srcIndex.count;
383
+ dstIndex.needsUpdate = true;
384
+
385
+ }
386
+
387
+ // fill in the geometry ids
388
+ const geometryId = this._geometryCount;
389
+ this._geometryCount ++;
390
+
391
+ const idAttribute = batchGeometry.getAttribute( ID_ATTR_NAME );
392
+ for ( let i = 0; i < srcPositionAttribute.count; i ++ ) {
393
+
394
+ idAttribute.setX( this._vertexCount + i, geometryId );
395
+
396
+ }
397
+
398
+ idAttribute.needsUpdate = true;
399
+
400
+ // extend new range
401
+ this._vertexCount += srcPositionAttribute.count;
402
+
403
+ // push new visibility states
404
+ visible.push( true );
405
+ active.push( true );
406
+
407
+ // initialize matrix information
408
+ matrices.push( new Matrix4() );
409
+ _identityMatrix.toArray( matricesArray, geometryId * 16 );
410
+ matricesTexture.needsUpdate = true;
411
+
412
+ return geometryId;
413
+
414
+ }
415
+
416
+ deleteGeometry( geometryId ) {
417
+
418
+ // Note: User needs to call optimize() afterward to pack the data.
419
+
420
+ const active = this._active;
421
+ const matricesArray = this._matricesTexture.image.data;
422
+ const matricesTexture = this._matricesTexture;
423
+ if ( geometryId >= active.length || active[ geometryId ] === false ) {
424
+
425
+ return this;
426
+
427
+ }
428
+
429
+ active[ geometryId ] = false;
430
+ _zeroScaleMatrix.toArray( matricesArray, geometryId * 16 );
431
+ matricesTexture.needsUpdate = true;
432
+
433
+ return this;
434
+
435
+ }
436
+
437
+ optimize() {
438
+
439
+ throw new Error( 'BatchedMesh: Optimize function not implemented.' );
440
+
441
+ }
442
+
443
+ setMatrixAt( geometryId, matrix ) {
444
+
445
+ // @TODO: Map geometryId to index of the arrays because
446
+ // optimize() can make geometryId mismatch the index
447
+
448
+ const visible = this._visible;
449
+ const active = this._active;
450
+ const matricesTexture = this._matricesTexture;
451
+ const matrices = this._matrices;
452
+ const matricesArray = this._matricesTexture.image.data;
453
+ if ( geometryId >= matrices.length || active[ geometryId ] === false ) {
454
+
455
+ return this;
456
+
457
+ }
458
+
459
+ if ( visible[ geometryId ] === true ) {
460
+
461
+ matrix.toArray( matricesArray, geometryId * 16 );
462
+ matricesTexture.needsUpdate = true;
463
+
464
+ }
465
+
466
+ matrices[ geometryId ].copy( matrix );
467
+
468
+ return this;
469
+
470
+ }
471
+
472
+ getMatrixAt( geometryId, matrix ) {
473
+
474
+ const matrices = this._matrices;
475
+ const active = this._active;
476
+ if ( geometryId >= matrices.length || active[ geometryId ] === false ) {
477
+
478
+ return matrix;
479
+
480
+ }
481
+
482
+ return matrix.copy( matrices[ geometryId ] );
483
+
484
+ }
485
+
486
+ setVisibleAt( geometryId, value ) {
487
+
488
+ const visible = this._visible;
489
+ const active = this._active;
490
+ const matricesTexture = this._matricesTexture;
491
+ const matrices = this._matrices;
492
+ const matricesArray = this._matricesTexture.image.data;
493
+
494
+ // if the geometry is out of range, not active, or visibility state
495
+ // does not change then return early
496
+ if (
497
+ geometryId >= visible.length ||
498
+ active[ geometryId ] === false ||
499
+ visible[ geometryId ] === value
500
+ ) {
501
+
502
+ return this;
503
+
504
+ }
505
+
506
+ // scale the matrix to zero if it's hidden
507
+ if ( value === true ) {
508
+
509
+ matrices[ geometryId ].toArray( matricesArray, geometryId * 16 );
510
+
511
+ } else {
512
+
513
+ _zeroScaleMatrix.toArray( matricesArray, geometryId * 16 );
514
+
515
+ }
516
+
517
+ matricesTexture.needsUpdate = true;
518
+ visible[ geometryId ] = value;
519
+ return this;
520
+
521
+ }
522
+
523
+ getVisibleAt( geometryId ) {
524
+
525
+ const visible = this._visible;
526
+ const active = this._active;
527
+
528
+ // return early if the geometry is out of range or not active
529
+ if ( geometryId >= visible.length || active[ geometryId ] === false ) {
530
+
531
+ return false;
532
+
533
+ }
534
+
535
+ return visible[ geometryId ];
536
+
537
+ }
538
+
539
+ raycast() {
540
+
541
+ console.warn( 'BatchedMesh: Raycast function not implemented.' );
542
+
543
+ }
544
+
545
+ copy() {
546
+
547
+ // super.copy( source );
548
+
549
+ throw new Error( 'BatchedMesh: Copy function not implemented.' );
550
+
551
+ }
552
+
553
+ toJSON() {
554
+
555
+ throw new Error( 'BatchedMesh: toJSON function not implemented.' );
556
+
557
+ }
558
+
559
+ dispose() {
560
+
561
+ // Assuming the geometry is not shared with other meshes
562
+ this.geometry.dispose();
563
+
564
+ this._matricesTexture.dispose();
565
+ this._matricesTexture = null;
566
+ return this;
567
+
568
+ }
569
+
570
+ onBeforeRender( _renderer, _scene, _camera, _geometry, material/*, _group*/ ) {
571
+
572
+ material.defines.BATCHING = true;
573
+
574
+ // @TODO: Implement frustum culling for each geometry
575
+
576
+ }
577
+
578
+ onAfterRender( _renderer, _scene, _camera, _geometry, material/*, _group*/ ) {
579
+
580
+ material.defines.BATCHING = false;
581
+
582
+ }
583
+
584
+ }
585
+
586
+ export { BatchedMesh };
@@ -0,0 +1,21 @@
1
+ import {
2
+ Mesh
3
+ } from 'three';
4
+ import InstancedPointsGeometry from '../geometries/InstancedPointsGeometry.js';
5
+ import InstancedPointsNodeMaterial from '../nodes/materials/InstancedPointsNodeMaterial.js';
6
+
7
+ class InstancedPoints extends Mesh {
8
+
9
+ constructor( geometry = new InstancedPointsGeometry(), material = new InstancedPointsNodeMaterial() ) {
10
+
11
+ super( geometry, material );
12
+
13
+ this.isInstancedPoints = true;
14
+
15
+ this.type = 'InstancedPoints';
16
+
17
+ }
18
+
19
+ }
20
+
21
+ export default InstancedPoints;
@@ -9,6 +9,7 @@ import {
9
9
  Mesh,
10
10
  MeshBasicMaterial,
11
11
  RawShaderMaterial,
12
+ UnsignedByteType,
12
13
  Vector2,
13
14
  Vector3,
14
15
  Vector4
@@ -36,6 +37,8 @@ class Lensflare extends Mesh {
36
37
  const tempMap = new FramebufferTexture( 16, 16 );
37
38
  const occlusionMap = new FramebufferTexture( 16, 16 );
38
39
 
40
+ let currentType = UnsignedByteType;
41
+
39
42
  // material
40
43
 
41
44
  const geometry = Lensflare.Geometry;
@@ -129,6 +132,7 @@ class Lensflare extends Mesh {
129
132
  const shader = LensflareElement.Shader;
130
133
 
131
134
  const material2 = new RawShaderMaterial( {
135
+ name: shader.name,
132
136
  uniforms: {
133
137
  'map': { value: null },
134
138
  'occlusionMap': { value: occlusionMap },
@@ -162,6 +166,20 @@ class Lensflare extends Mesh {
162
166
 
163
167
  renderer.getCurrentViewport( viewport );
164
168
 
169
+ const renderTarget = renderer.getRenderTarget();
170
+ const type = ( renderTarget !== null ) ? renderTarget.texture.type : UnsignedByteType;
171
+
172
+ if ( currentType !== type ) {
173
+
174
+ tempMap.dispose();
175
+ occlusionMap.dispose();
176
+
177
+ tempMap.type = occlusionMap.type = type;
178
+
179
+ currentType = type;
180
+
181
+ }
182
+
165
183
  const invAspect = viewport.w / viewport.z;
166
184
  const halfViewportWidth = viewport.z / 2.0;
167
185
  const halfViewportHeight = viewport.w / 2.0;
@@ -283,6 +301,8 @@ class LensflareElement {
283
301
 
284
302
  LensflareElement.Shader = {
285
303
 
304
+ name: 'LensflareElementShader',
305
+
286
306
  uniforms: {
287
307
 
288
308
  'map': { value: null },
@@ -111,6 +111,7 @@ class ReflectorForSSRPass extends Mesh {
111
111
  const renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, parameters );
112
112
 
113
113
  const material = new ShaderMaterial( {
114
+ name: ( shader.name !== undefined ) ? shader.name : 'unspecified',
114
115
  transparent: useDepthTexture,
115
116
  defines: Object.assign( {}, ReflectorForSSRPass.ReflectorShader.defines, {
116
117
  useDepthTexture
@@ -251,6 +252,8 @@ class ReflectorForSSRPass extends Mesh {
251
252
 
252
253
  ReflectorForSSRPass.ReflectorShader = {
253
254
 
255
+ name: 'ReflectorShader',
256
+
254
257
  defines: {
255
258
  DISTANCE_ATTENUATION: true,
256
259
  FRESNEL: true,
@@ -51,6 +51,7 @@ class Refractor extends Mesh {
51
51
  // material
52
52
 
53
53
  this.material = new ShaderMaterial( {
54
+ name: ( shader.name !== undefined ) ? shader.name : 'unspecified',
54
55
  uniforms: UniformsUtils.clone( shader.uniforms ),
55
56
  vertexShader: shader.vertexShader,
56
57
  fragmentShader: shader.fragmentShader,
@@ -261,6 +262,8 @@ class Refractor extends Mesh {
261
262
 
262
263
  Refractor.RefractorShader = {
263
264
 
265
+ name: 'RefractorShader',
266
+
264
267
  uniforms: {
265
268
 
266
269
  'color': {
@@ -28,10 +28,10 @@ class Sky extends Mesh {
28
28
  const shader = Sky.SkyShader;
29
29
 
30
30
  const material = new ShaderMaterial( {
31
- name: 'SkyShader',
32
- fragmentShader: shader.fragmentShader,
33
- vertexShader: shader.vertexShader,
31
+ name: shader.name,
34
32
  uniforms: UniformsUtils.clone( shader.uniforms ),
33
+ vertexShader: shader.vertexShader,
34
+ fragmentShader: shader.fragmentShader,
35
35
  side: BackSide,
36
36
  depthWrite: false
37
37
  } );
@@ -46,6 +46,8 @@ class Sky extends Mesh {
46
46
 
47
47
  Sky.SkyShader = {
48
48
 
49
+ name: 'SkyShader',
50
+
49
51
  uniforms: {
50
52
  'turbidity': { value: 2 },
51
53
  'rayleigh': { value: 1 },