super-three 0.160.1 → 0.162.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 (225) hide show
  1. package/LICENSE +1 -1
  2. package/build/three.cjs +867 -499
  3. package/build/three.module.js +867 -496
  4. package/build/three.module.min.js +1 -1
  5. package/examples/jsm/Addons.js +5 -1
  6. package/examples/jsm/capabilities/WebGPU.js +13 -9
  7. package/examples/jsm/controls/DragControls.js +91 -30
  8. package/examples/jsm/controls/OrbitControls.js +130 -15
  9. package/examples/jsm/controls/TransformControls.js +6 -6
  10. package/examples/jsm/curves/NURBSUtils.js +59 -4
  11. package/examples/jsm/curves/NURBSVolume.js +62 -0
  12. package/examples/jsm/exporters/GLTFExporter.js +11 -1
  13. package/examples/jsm/exporters/USDZExporter.js +8 -7
  14. package/examples/jsm/helpers/TextureHelper.js +3 -3
  15. package/examples/jsm/interactive/InteractiveGroup.js +15 -25
  16. package/examples/jsm/libs/rhino3dm/rhino3dm.js +1 -8723
  17. package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +1 -8734
  18. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  19. package/examples/jsm/libs/tween.module.js +32 -14
  20. package/examples/jsm/loaders/3DMLoader.js +57 -64
  21. package/examples/jsm/loaders/DDSLoader.js +1 -0
  22. package/examples/jsm/loaders/KTX2Loader.js +20 -5
  23. package/examples/jsm/loaders/LUT3dlLoader.js +78 -46
  24. package/examples/jsm/loaders/LUTCubeLoader.js +81 -67
  25. package/examples/jsm/loaders/LUTImageLoader.js +3 -2
  26. package/examples/jsm/loaders/MaterialXLoader.js +115 -16
  27. package/examples/jsm/loaders/SVGLoader.js +4 -3
  28. package/examples/jsm/loaders/VOXLoader.js +9 -2
  29. package/examples/jsm/loaders/VRMLLoader.js +7 -3
  30. package/examples/jsm/materials/MeshPostProcessingMaterial.js +144 -0
  31. package/examples/jsm/misc/ProgressiveLightMap.js +1 -0
  32. package/examples/jsm/misc/Timer.js +13 -4
  33. package/examples/jsm/nodes/Nodes.js +24 -11
  34. package/examples/jsm/nodes/accessors/AccessorsUtils.js +10 -0
  35. package/examples/jsm/nodes/accessors/BufferAttributeNode.js +5 -3
  36. package/examples/jsm/nodes/accessors/CameraNode.js +9 -4
  37. package/examples/jsm/nodes/accessors/ClippingNode.js +144 -0
  38. package/examples/jsm/nodes/accessors/CubeTextureNode.js +12 -1
  39. package/examples/jsm/nodes/accessors/MaterialNode.js +2 -2
  40. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +2 -12
  41. package/examples/jsm/nodes/accessors/MorphNode.js +8 -8
  42. package/examples/jsm/nodes/accessors/ReferenceNode.js +87 -29
  43. package/examples/jsm/nodes/accessors/SkinningNode.js +31 -10
  44. package/examples/jsm/nodes/accessors/StorageBufferNode.js +45 -0
  45. package/examples/jsm/nodes/accessors/TangentNode.js +8 -2
  46. package/examples/jsm/nodes/accessors/TextureNode.js +1 -1
  47. package/examples/jsm/nodes/accessors/TextureStoreNode.js +56 -3
  48. package/examples/jsm/nodes/accessors/UniformsNode.js +140 -0
  49. package/examples/jsm/nodes/accessors/VertexColorNode.js +70 -0
  50. package/examples/jsm/nodes/code/CodeNode.js +6 -0
  51. package/examples/jsm/nodes/core/AssignNode.js +68 -12
  52. package/examples/jsm/nodes/core/AttributeNode.js +1 -1
  53. package/examples/jsm/nodes/core/Node.js +14 -4
  54. package/examples/jsm/nodes/core/NodeBuilder.js +26 -27
  55. package/examples/jsm/nodes/core/NodeFrame.js +18 -10
  56. package/examples/jsm/nodes/core/TempNode.js +1 -1
  57. package/examples/jsm/nodes/core/constants.js +1 -0
  58. package/examples/jsm/nodes/display/AfterImageNode.js +148 -0
  59. package/examples/jsm/nodes/display/AnamorphicNode.js +148 -0
  60. package/examples/jsm/nodes/display/BlendModeNode.js +30 -1
  61. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +3 -0
  62. package/examples/jsm/nodes/display/GaussianBlurNode.js +33 -13
  63. package/examples/jsm/nodes/display/NormalMapNode.js +3 -5
  64. package/examples/jsm/nodes/display/PassNode.js +3 -2
  65. package/examples/jsm/nodes/display/ToneMappingNode.js +46 -3
  66. package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +1 -4
  67. package/examples/jsm/nodes/display/ViewportNode.js +0 -2
  68. package/examples/jsm/nodes/display/ViewportSharedTextureNode.js +4 -4
  69. package/examples/jsm/nodes/fog/FogNode.js +2 -1
  70. package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
  71. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +13 -5
  72. package/examples/jsm/nodes/lighting/LightingContextNode.js +1 -1
  73. package/examples/jsm/nodes/lighting/LightsNode.js +1 -1
  74. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +18 -30
  75. package/examples/jsm/nodes/materials/Materials.js +1 -0
  76. package/examples/jsm/nodes/materials/MeshSSSNodeMaterial.js +84 -0
  77. package/examples/jsm/nodes/materials/NodeMaterial.js +43 -10
  78. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +1 -7
  79. package/examples/jsm/nodes/math/CondNode.js +42 -7
  80. package/examples/jsm/nodes/math/MathNode.js +32 -2
  81. package/examples/jsm/nodes/math/MathUtils.js +15 -0
  82. package/examples/jsm/nodes/math/OperatorNode.js +13 -5
  83. package/examples/jsm/nodes/math/TriNoise3D.js +71 -0
  84. package/examples/jsm/nodes/shadernode/ShaderNode.js +10 -1
  85. package/examples/jsm/nodes/utils/JoinNode.js +2 -2
  86. package/examples/jsm/nodes/utils/LoopNode.js +5 -3
  87. package/examples/jsm/nodes/utils/ReflectorNode.js +227 -0
  88. package/examples/jsm/nodes/utils/RotateNode.js +68 -0
  89. package/examples/jsm/nodes/utils/RotateUVNode.js +1 -9
  90. package/examples/jsm/nodes/utils/SplitNode.js +4 -4
  91. package/examples/jsm/nodes/utils/StorageArrayElementNode.js +91 -0
  92. package/examples/jsm/objects/GroundedSkybox.js +50 -0
  93. package/examples/jsm/objects/QuadMesh.js +8 -2
  94. package/examples/jsm/objects/Water2.js +8 -8
  95. package/examples/jsm/postprocessing/GTAOPass.js +11 -1
  96. package/examples/jsm/postprocessing/OutputPass.js +2 -0
  97. package/examples/jsm/renderers/common/Backend.js +14 -0
  98. package/examples/jsm/renderers/common/Background.js +2 -2
  99. package/examples/jsm/renderers/common/Bindings.js +1 -1
  100. package/examples/jsm/renderers/common/ClippingContext.js +165 -0
  101. package/examples/jsm/renderers/common/DataMap.js +1 -1
  102. package/examples/jsm/renderers/common/Info.js +25 -1
  103. package/examples/jsm/renderers/common/Pipelines.js +8 -8
  104. package/examples/jsm/renderers/common/PostProcessing.js +2 -2
  105. package/examples/jsm/renderers/common/ProgrammableStage.js +3 -1
  106. package/examples/jsm/renderers/common/RenderContext.js +2 -0
  107. package/examples/jsm/renderers/common/RenderContexts.js +2 -13
  108. package/examples/jsm/renderers/common/RenderObject.js +46 -1
  109. package/examples/jsm/renderers/common/RenderObjects.js +3 -1
  110. package/examples/jsm/renderers/common/Renderer.js +290 -17
  111. package/examples/jsm/renderers/common/StorageBufferAttribute.js +17 -0
  112. package/examples/jsm/renderers/common/StorageInstancedBufferAttribute.js +17 -0
  113. package/examples/jsm/renderers/common/Textures.js +28 -18
  114. package/examples/jsm/renderers/common/UniformsGroup.js +6 -4
  115. package/examples/jsm/renderers/common/nodes/NodeBuilderState.js +2 -1
  116. package/examples/jsm/renderers/common/nodes/NodeStorageBuffer.js +23 -0
  117. package/examples/jsm/renderers/common/nodes/NodeUniformBuffer.js +23 -0
  118. package/examples/jsm/renderers/common/nodes/Nodes.js +5 -2
  119. package/examples/jsm/renderers/webgl/WebGLBackend.js +653 -272
  120. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +171 -39
  121. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +95 -8
  122. package/examples/jsm/renderers/webgl/utils/WebGLConstants.js +11 -0
  123. package/examples/jsm/renderers/webgl/utils/WebGLState.js +197 -0
  124. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +424 -11
  125. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +3 -2
  126. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +1 -21
  127. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +2 -2
  128. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +300 -112
  129. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +7 -2
  130. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +71 -79
  131. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +15 -1
  132. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +38 -4
  133. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +87 -14
  134. package/examples/jsm/shaders/OutputShader.js +4 -0
  135. package/examples/jsm/transpiler/AST.js +1 -1
  136. package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
  137. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  138. package/examples/jsm/transpiler/TSLEncoder.js +1 -1
  139. package/examples/jsm/utils/BufferGeometryUtils.js +23 -27
  140. package/examples/jsm/utils/SkeletonUtils.js +14 -3
  141. package/examples/jsm/utils/SortUtils.js +2 -0
  142. package/examples/jsm/webxr/ARButton.js +12 -2
  143. package/examples/jsm/webxr/VRButton.js +25 -7
  144. package/examples/jsm/webxr/XRButton.js +12 -3
  145. package/examples/jsm/webxr/XRControllerModelFactory.js +14 -1
  146. package/examples/jsm/webxr/XRHandMeshModel.js +3 -1
  147. package/package.json +5 -4
  148. package/src/Three.Legacy.js +20 -0
  149. package/src/Three.js +0 -1
  150. package/src/audio/Audio.js +1 -3
  151. package/src/cameras/PerspectiveCamera.js +35 -0
  152. package/src/constants.js +2 -6
  153. package/src/core/BufferAttribute.js +2 -12
  154. package/src/core/BufferGeometry.js +23 -29
  155. package/src/core/InterleavedBuffer.js +2 -1
  156. package/src/core/InterleavedBufferAttribute.js +20 -0
  157. package/src/core/Object3D.js +11 -0
  158. package/src/core/Raycaster.js +18 -4
  159. package/src/core/RenderTarget.js +44 -21
  160. package/src/extras/PMREMGenerator.js +2 -0
  161. package/src/extras/curves/EllipseCurve.js +2 -2
  162. package/src/helpers/SpotLightHelper.js +18 -1
  163. package/src/loaders/DataTextureLoader.js +0 -4
  164. package/src/loaders/MaterialLoader.js +1 -0
  165. package/src/loaders/ObjectLoader.js +2 -1
  166. package/src/materials/Material.js +2 -1
  167. package/src/materials/MeshBasicMaterial.js +3 -0
  168. package/src/materials/MeshLambertMaterial.js +3 -0
  169. package/src/materials/MeshPhongMaterial.js +3 -0
  170. package/src/materials/MeshStandardMaterial.js +3 -0
  171. package/src/materials/ShaderMaterial.js +2 -1
  172. package/src/math/Quaternion.js +13 -12
  173. package/src/math/Triangle.js +0 -30
  174. package/src/math/Vector3.js +7 -7
  175. package/src/objects/BatchedMesh.js +6 -7
  176. package/src/objects/InstancedMesh.js +53 -0
  177. package/src/objects/Mesh.js +0 -1
  178. package/src/objects/SkinnedMesh.js +0 -8
  179. package/src/renderers/WebGLCubeRenderTarget.js +1 -10
  180. package/src/renderers/WebGLRenderer.js +20 -23
  181. package/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl.js +9 -0
  182. package/src/renderers/shaders/ShaderChunk/clipping_planes_fragment.glsl.js +56 -11
  183. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -0
  184. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  185. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +2 -2
  186. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +1 -1
  187. package/src/renderers/shaders/ShaderChunk/morphinstance_vertex.glsl.js +14 -0
  188. package/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl.js +11 -2
  189. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +38 -7
  190. package/src/renderers/shaders/ShaderChunk.js +2 -0
  191. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +3 -2
  192. package/src/renderers/shaders/ShaderLib/depth.glsl.js +3 -2
  193. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +3 -2
  194. package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +2 -1
  195. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +2 -2
  196. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -1
  197. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +2 -2
  198. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +4 -1
  199. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -1
  200. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +2 -1
  201. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +2 -1
  202. package/src/renderers/shaders/ShaderLib/points.glsl.js +2 -1
  203. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -0
  204. package/src/renderers/shaders/ShaderLib/sprite.glsl.js +1 -1
  205. package/src/renderers/shaders/ShaderLib.js +2 -1
  206. package/src/renderers/shaders/UniformsLib.js +1 -0
  207. package/src/renderers/webgl/WebGLAttributes.js +2 -2
  208. package/src/renderers/webgl/WebGLBackground.js +18 -0
  209. package/src/renderers/webgl/WebGLCubeMaps.js +1 -1
  210. package/src/renderers/webgl/WebGLMaterials.js +24 -1
  211. package/src/renderers/webgl/WebGLMorphtargets.js +15 -8
  212. package/src/renderers/webgl/WebGLProgram.js +42 -4
  213. package/src/renderers/webgl/WebGLPrograms.js +38 -27
  214. package/src/renderers/webgl/WebGLState.js +11 -21
  215. package/src/renderers/webgl/WebGLTextures.js +170 -66
  216. package/src/renderers/webxr/WebXRDepthSensing.js +105 -0
  217. package/src/renderers/webxr/WebXRManager.js +46 -0
  218. package/src/scenes/Scene.js +8 -0
  219. package/src/textures/Source.js +1 -0
  220. package/src/textures/Texture.js +1 -29
  221. package/build/three.js +0 -54519
  222. package/build/three.min.js +0 -7
  223. package/examples/jsm/nodes/core/ArrayUniformNode.js +0 -26
  224. package/examples/jsm/objects/GroundProjectedSkybox.js +0 -172
  225. package/src/renderers/WebGLMultipleRenderTargets.js +0 -82
@@ -9,6 +9,7 @@ import WebGLUtils from './utils/WebGLUtils.js';
9
9
  import WebGLTextureUtils from './utils/WebGLTextureUtils.js';
10
10
  import WebGLExtensions from './utils/WebGLExtensions.js';
11
11
  import WebGLCapabilities from './utils/WebGLCapabilities.js';
12
+ import { GLFeatureName } from './utils/WebGLConstants.js';
12
13
 
13
14
  //
14
15
 
@@ -22,9 +23,9 @@ class WebGLBackend extends Backend {
22
23
 
23
24
  }
24
25
 
25
- async init( renderer ) {
26
+ init( renderer ) {
26
27
 
27
- await super.init( renderer );
28
+ super.init( renderer );
28
29
 
29
30
  //
30
31
 
@@ -40,9 +41,13 @@ class WebGLBackend extends Backend {
40
41
  this.textureUtils = new WebGLTextureUtils( this );
41
42
  this.state = new WebGLState( this );
42
43
  this.utils = new WebGLUtils( this );
43
- this.defaultTextures = {};
44
+
45
+ this.vaoCache = {};
46
+ this.transformFeedbackCache = {};
47
+ this.discard = false;
44
48
 
45
49
  this.extensions.get( 'EXT_color_buffer_float' );
50
+ this.parallel = this.extensions.get( 'KHR_parallel_shader_compile' );
46
51
  this._currentContext = null;
47
52
 
48
53
  }
@@ -59,6 +64,12 @@ class WebGLBackend extends Backend {
59
64
 
60
65
  }
61
66
 
67
+ getContext() {
68
+
69
+ return this.gl;
70
+
71
+ }
72
+
62
73
  beginRender( renderContext ) {
63
74
 
64
75
  const { gl } = this;
@@ -66,15 +77,16 @@ class WebGLBackend extends Backend {
66
77
 
67
78
  //
68
79
 
80
+ //
81
+
69
82
  renderContextData.previousContext = this._currentContext;
70
83
  this._currentContext = renderContext;
71
84
 
72
85
  this._setFramebuffer( renderContext );
73
86
 
74
- this.clear( renderContext.clearColor, renderContext.clearDepth, renderContext.clearStencil, renderContext );
87
+ this.clear( renderContext.clearColor, renderContext.clearDepth, renderContext.clearStencil, renderContext, false );
75
88
 
76
89
  //
77
-
78
90
  if ( renderContext.viewport ) {
79
91
 
80
92
  this.updateViewport( renderContext );
@@ -85,6 +97,14 @@ class WebGLBackend extends Backend {
85
97
 
86
98
  }
87
99
 
100
+ if ( renderContext.scissor ) {
101
+
102
+ const { x, y, width, height } = renderContext.scissorValue;
103
+
104
+ gl.scissor( x, y, width, height );
105
+
106
+ }
107
+
88
108
  const occlusionQueryCount = renderContext.occlusionQueryCount;
89
109
 
90
110
  if ( occlusionQueryCount > 0 ) {
@@ -105,11 +125,64 @@ class WebGLBackend extends Backend {
105
125
 
106
126
  finishRender( renderContext ) {
107
127
 
128
+ const { gl, state } = this;
108
129
  const renderContextData = this.get( renderContext );
109
130
  const previousContext = renderContextData.previousContext;
110
131
 
132
+ const textures = renderContext.textures;
133
+
134
+ if ( textures !== null ) {
135
+
136
+ for ( let i = 0; i < textures.length; i ++ ) {
137
+
138
+ const texture = textures[ i ];
139
+
140
+ if ( texture.generateMipmaps ) {
141
+
142
+ this.generateMipmaps( texture );
143
+
144
+ }
145
+
146
+ }
147
+
148
+ }
149
+
111
150
  this._currentContext = previousContext;
112
151
 
152
+
153
+ if ( renderContext.textures !== null && renderContext.renderTarget ) {
154
+
155
+ const renderTargetContextData = this.get( renderContext.renderTarget );
156
+
157
+ const { samples } = renderContext.renderTarget;
158
+ const fb = renderTargetContextData.framebuffer;
159
+
160
+ const mask = gl.COLOR_BUFFER_BIT;
161
+
162
+ if ( samples > 0 ) {
163
+
164
+ const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer;
165
+
166
+ const textures = renderContext.textures;
167
+
168
+ state.bindFramebuffer( gl.READ_FRAMEBUFFER, msaaFrameBuffer );
169
+ state.bindFramebuffer( gl.DRAW_FRAMEBUFFER, fb );
170
+
171
+ for ( let i = 0; i < textures.length; i ++ ) {
172
+
173
+ // TODO Add support for MRT
174
+
175
+ gl.blitFramebuffer( 0, 0, renderContext.width, renderContext.height, 0, 0, renderContext.width, renderContext.height, mask, gl.NEAREST );
176
+
177
+ gl.invalidateFramebuffer( gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray );
178
+
179
+ }
180
+
181
+ }
182
+
183
+
184
+ }
185
+
113
186
  if ( previousContext !== null ) {
114
187
 
115
188
  this._setFramebuffer( previousContext );
@@ -146,6 +219,7 @@ class WebGLBackend extends Backend {
146
219
 
147
220
  }
148
221
 
222
+
149
223
  }
150
224
 
151
225
  resolveOccludedAsync( renderContext ) {
@@ -223,7 +297,23 @@ class WebGLBackend extends Backend {
223
297
 
224
298
  }
225
299
 
226
- clear( color, depth, stencil, descriptor = null ) {
300
+ setScissorTest( boolean ) {
301
+
302
+ const gl = this.gl;
303
+
304
+ if ( boolean ) {
305
+
306
+ gl.enable( gl.SCISSOR_TEST );
307
+
308
+ } else {
309
+
310
+ gl.disable( gl.SCISSOR_TEST );
311
+
312
+ }
313
+
314
+ }
315
+
316
+ clear( color, depth, stencil, descriptor = null, setFrameBuffer = true ) {
227
317
 
228
318
  const { gl } = this;
229
319
 
@@ -246,7 +336,7 @@ class WebGLBackend extends Backend {
246
336
 
247
337
  if ( clear !== 0 ) {
248
338
 
249
- const clearColor = descriptor.clearColorValue;
339
+ const clearColor = descriptor.clearColorValue || this.getClearColor();
250
340
 
251
341
  if ( depth ) this.state.setDepthMask( true );
252
342
 
@@ -257,6 +347,8 @@ class WebGLBackend extends Backend {
257
347
 
258
348
  } else {
259
349
 
350
+ if ( setFrameBuffer ) this._setFramebuffer( descriptor );
351
+
260
352
  if ( color ) {
261
353
 
262
354
  for ( let i = 0; i < descriptor.textures.length; i ++ ) {
@@ -289,26 +381,95 @@ class WebGLBackend extends Backend {
289
381
 
290
382
  beginCompute( /*computeGroup*/ ) {
291
383
 
292
- console.warn( 'Abstract class.' );
384
+ const gl = this.gl;
385
+
386
+ gl.bindFramebuffer( gl.FRAMEBUFFER, null );
293
387
 
294
388
  }
295
389
 
296
- compute( /*computeGroup, computeNode, bindings, pipeline*/ ) {
390
+ compute( computeGroup, computeNode, bindings, pipeline ) {
297
391
 
298
- console.warn( 'Abstract class.' );
392
+ const gl = this.gl;
393
+
394
+ if ( ! this.discard ) {
395
+
396
+ // required here to handle async behaviour of render.compute()
397
+ gl.enable( gl.RASTERIZER_DISCARD );
398
+ this.discard = true;
399
+
400
+ }
401
+
402
+ const { programGPU, transformBuffers, attributes } = this.get( pipeline );
403
+
404
+ const vaoKey = this._getVaoKey( null, attributes );
405
+
406
+ const vaoGPU = this.vaoCache[ vaoKey ];
407
+
408
+ if ( vaoGPU === undefined ) {
409
+
410
+ this._createVao( null, attributes );
411
+
412
+ } else {
413
+
414
+ gl.bindVertexArray( vaoGPU );
415
+
416
+ }
417
+
418
+ gl.useProgram( programGPU );
419
+
420
+ this._bindUniforms( bindings );
421
+
422
+ const transformFeedbackGPU = this._getTransformFeedback( transformBuffers );
423
+
424
+ gl.bindTransformFeedback( gl.TRANSFORM_FEEDBACK, transformFeedbackGPU );
425
+ gl.beginTransformFeedback( gl.POINTS );
426
+
427
+ if ( attributes[ 0 ].isStorageInstancedBufferAttribute ) {
428
+
429
+ gl.drawArraysInstanced( gl.POINTS, 0, 1, computeNode.count );
430
+
431
+ } else {
432
+
433
+ gl.drawArrays( gl.POINTS, 0, computeNode.count );
434
+
435
+ }
436
+
437
+ gl.endTransformFeedback();
438
+ gl.bindTransformFeedback( gl.TRANSFORM_FEEDBACK, null );
439
+
440
+ // switch active buffers
441
+
442
+ for ( let i = 0; i < transformBuffers.length; i ++ ) {
443
+
444
+ const dualAttributeData = transformBuffers[ i ];
445
+
446
+ if ( dualAttributeData.pbo ) {
447
+
448
+ this.textureUtils.copyBufferToTexture( dualAttributeData.transformBuffer, dualAttributeData.pbo );
449
+
450
+ }
451
+
452
+ dualAttributeData.switchBuffers();
453
+
454
+
455
+ }
299
456
 
300
457
  }
301
458
 
302
459
  finishCompute( /*computeGroup*/ ) {
303
460
 
304
- console.warn( 'Abstract class.' );
461
+ const gl = this.gl;
462
+
463
+ this.discard = false;
464
+
465
+ gl.disable( gl.RASTERIZER_DISCARD );
305
466
 
306
467
  }
307
468
 
308
469
  draw( renderObject, info ) {
309
470
 
310
471
  const { pipeline, material, context } = renderObject;
311
- const { programGPU, vaoGPU } = this.get( pipeline );
472
+ const { programGPU } = this.get( pipeline );
312
473
 
313
474
  const { gl, state } = this;
314
475
 
@@ -316,29 +477,34 @@ class WebGLBackend extends Backend {
316
477
 
317
478
  //
318
479
 
319
- const bindings = renderObject.getBindings();
480
+ this._bindUniforms( renderObject.getBindings() );
320
481
 
321
- for ( const binding of bindings ) {
482
+ state.setMaterial( material );
322
483
 
323
- const bindingData = this.get( binding );
324
- const index = bindingData.index;
484
+ gl.useProgram( programGPU );
325
485
 
326
- if ( binding.isUniformsGroup || binding.isUniformBuffer ) {
486
+ //
327
487
 
328
- gl.bindBufferBase( gl.UNIFORM_BUFFER, index, bindingData.bufferGPU );
488
+ let vaoGPU = renderObject.staticVao;
329
489
 
330
- } else if ( binding.isSampledTexture ) {
490
+ if ( vaoGPU === undefined ) {
491
+
492
+ const vaoKey = this._getVaoKey( renderObject.getIndex(), renderObject.getAttributes() );
493
+
494
+ vaoGPU = this.vaoCache[ vaoKey ];
331
495
 
332
- gl.activeTexture( gl.TEXTURE0 + index );
333
- gl.bindTexture( bindingData.glTextureType, bindingData.textureGPU );
496
+ if ( vaoGPU === undefined ) {
497
+
498
+ let staticVao;
499
+
500
+ ( { vaoGPU, staticVao } = this._createVao( renderObject.getIndex(), renderObject.getAttributes() ) );
501
+
502
+ if ( staticVao ) renderObject.staticVao = vaoGPU;
334
503
 
335
504
  }
336
505
 
337
506
  }
338
507
 
339
- state.setMaterial( material );
340
-
341
- gl.useProgram( programGPU );
342
508
  gl.bindVertexArray( vaoGPU );
343
509
 
344
510
  //
@@ -386,7 +552,20 @@ class WebGLBackend extends Backend {
386
552
  else if ( object.isLineSegments ) mode = gl.LINES;
387
553
  else if ( object.isLine ) mode = gl.LINE_STRIP;
388
554
  else if ( object.isLineLoop ) mode = gl.LINE_LOOP;
389
- else mode = gl.TRIANGLES;
555
+ else {
556
+
557
+ if ( material.wireframe === true ) {
558
+
559
+ state.setLineWidth( material.wireframeLinewidth * this.renderer.getPixelRatio() );
560
+ mode = gl.LINES;
561
+
562
+ } else {
563
+
564
+ mode = gl.TRIANGLES;
565
+
566
+ }
567
+
568
+ }
390
569
 
391
570
  //
392
571
 
@@ -407,7 +586,6 @@ class WebGLBackend extends Backend {
407
586
 
408
587
  }
409
588
 
410
-
411
589
  info.update( object, indexCount, 1 );
412
590
 
413
591
  } else {
@@ -431,15 +609,13 @@ class WebGLBackend extends Backend {
431
609
 
432
610
  }
433
611
 
434
-
435
-
436
612
  //
437
613
 
438
614
  gl.bindVertexArray( null );
439
615
 
440
616
  }
441
617
 
442
- needsRenderUpdate( renderObject ) {
618
+ needsRenderUpdate( /*renderObject*/ ) {
443
619
 
444
620
  return false;
445
621
 
@@ -453,173 +629,51 @@ class WebGLBackend extends Backend {
453
629
 
454
630
  // textures
455
631
 
456
- createSampler( /*texture*/ ) {
457
-
458
- //console.warn( 'Abstract class.' );
459
-
460
- }
461
-
462
632
  createDefaultTexture( texture ) {
463
633
 
464
- const { gl, textureUtils, defaultTextures } = this;
465
-
466
- const glTextureType = textureUtils.getGLTextureType( texture );
467
-
468
- let textureGPU = defaultTextures[ glTextureType ];
469
-
470
- if ( textureGPU === undefined ) {
471
-
472
- textureGPU = gl.createTexture();
473
-
474
- gl.bindTexture( glTextureType, textureGPU );
475
- gl.texParameteri( glTextureType, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
476
- gl.texParameteri( glTextureType, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
477
-
478
- //gl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );
479
-
480
- defaultTextures[ glTextureType ] = textureGPU;
481
-
482
- }
483
-
484
- this.set( texture, {
485
- textureGPU,
486
- glTextureType,
487
- isDefault: true
488
- } );
634
+ this.textureUtils.createDefaultTexture( texture );
489
635
 
490
636
  }
491
637
 
492
638
  createTexture( texture, options ) {
493
639
 
494
- const { gl, utils, textureUtils } = this;
495
- const { levels, width, height, depth } = options;
496
-
497
- const glFormat = utils.convert( texture.format, texture.colorSpace );
498
- const glType = utils.convert( texture.type );
499
- const glInternalFormat = textureUtils.getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace, texture.isVideoTexture );
500
-
501
- const textureGPU = gl.createTexture();
502
- const glTextureType = textureUtils.getGLTextureType( texture );
503
-
504
- gl.bindTexture( glTextureType, textureGPU );
505
-
506
- gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
507
- gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
508
- gl.pixelStorei( gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
509
- gl.pixelStorei( gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE );
510
-
511
- textureUtils.setTextureParameters( glTextureType, texture );
512
-
513
- gl.bindTexture( glTextureType, textureGPU );
514
-
515
- if ( texture.isDataArrayTexture ) {
516
-
517
- gl.texStorage3D( gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, width, height, depth );
518
-
519
- } else if ( ! texture.isVideoTexture ) {
520
-
521
- gl.texStorage2D( glTextureType, levels, glInternalFormat, width, height );
522
-
523
- }
524
-
525
- this.set( texture, {
526
- textureGPU,
527
- glTextureType,
528
- glFormat,
529
- glType,
530
- glInternalFormat
531
- } );
640
+ this.textureUtils.createTexture( texture, options );
532
641
 
533
642
  }
534
643
 
535
644
  updateTexture( texture, options ) {
536
645
 
537
- const { gl } = this;
538
- const { width, height } = options;
539
- const { textureGPU, glTextureType, glFormat, glType, glInternalFormat } = this.get( texture );
540
-
541
- const getImage = ( source ) => {
542
-
543
- if ( source.isDataTexture ) {
544
-
545
- return source.image.data;
546
-
547
- } else if ( source instanceof ImageBitmap || source instanceof OffscreenCanvas || source instanceof HTMLImageElement || source instanceof HTMLCanvasElement ) {
548
-
549
- return source;
550
-
551
- }
552
-
553
- return source.data;
554
-
555
- };
556
-
557
- gl.bindTexture( glTextureType, textureGPU );
558
-
559
- if ( texture.isCubeTexture ) {
560
-
561
- const images = options.images;
562
-
563
- for ( let i = 0; i < 6; i ++ ) {
564
-
565
- const image = getImage( images[ i ] );
566
-
567
- gl.texSubImage2D( gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, width, height, glFormat, glType, image );
568
-
569
- }
570
-
571
- } else if ( texture.isDataArrayTexture ) {
572
-
573
- const image = options.image;
574
-
575
- gl.texSubImage3D( gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
576
-
577
- } else if ( texture.isVideoTexture ) {
646
+ this.textureUtils.updateTexture( texture, options );
578
647
 
579
- texture.update();
648
+ }
580
649
 
581
- gl.texImage2D( glTextureType, 0, glInternalFormat, glFormat, glType, options.image );
650
+ generateMipmaps( texture ) {
582
651
 
652
+ this.textureUtils.generateMipmaps( texture );
583
653
 
584
- } else {
654
+ }
585
655
 
586
- const image = getImage( options.image );
587
656
 
588
- gl.texSubImage2D( glTextureType, 0, 0, 0, width, height, glFormat, glType, image );
657
+ destroyTexture( texture ) {
589
658
 
590
- }
659
+ this.textureUtils.destroyTexture( texture );
591
660
 
592
661
  }
593
662
 
594
- generateMipmaps( texture ) {
595
-
596
- const { gl } = this;
597
- const { textureGPU, glTextureType } = this.get( texture );
663
+ copyTextureToBuffer( texture, x, y, width, height ) {
598
664
 
599
- gl.bindTexture( glTextureType, textureGPU );
600
- gl.generateMipmap( glTextureType );
665
+ return this.textureUtils.copyTextureToBuffer( texture, x, y, width, height );
601
666
 
602
667
  }
603
668
 
604
- destroyTexture( texture ) {
605
-
606
- const { gl } = this;
607
- const { textureGPU } = this.get( texture );
608
-
609
- gl.deleteTexture( textureGPU );
669
+ createSampler( /*texture*/ ) {
610
670
 
611
- this.delete( texture );
671
+ //console.warn( 'Abstract class.' );
612
672
 
613
673
  }
614
674
 
615
675
  destroySampler() {}
616
676
 
617
- copyTextureToBuffer( texture, x, y, width, height ) {
618
-
619
- return this.textureUtils.copyTextureToBuffer( texture, x, y, width, height );
620
-
621
- }
622
-
623
677
  // node builder
624
678
 
625
679
  createNodeBuilder( object, renderer, scene = null ) {
@@ -635,7 +689,7 @@ class WebGLBackend extends Backend {
635
689
  const gl = this.gl;
636
690
  const { stage, code } = program;
637
691
 
638
- const shader = stage === 'vertex' ? gl.createShader( gl.VERTEX_SHADER ) : gl.createShader( gl.FRAGMENT_SHADER );
692
+ const shader = stage === 'fragment' ? gl.createShader( gl.FRAGMENT_SHADER ) : gl.createShader( gl.VERTEX_SHADER );
639
693
 
640
694
  gl.shaderSource( shader, code );
641
695
  gl.compileShader( shader );
@@ -652,7 +706,7 @@ class WebGLBackend extends Backend {
652
706
 
653
707
  }
654
708
 
655
- createRenderPipeline( renderObject ) {
709
+ createRenderPipeline( renderObject, promises ) {
656
710
 
657
711
  const gl = this.gl;
658
712
  const pipeline = renderObject.pipeline;
@@ -670,115 +724,170 @@ class WebGLBackend extends Backend {
670
724
  gl.attachShader( programGPU, vertexShader );
671
725
  gl.linkProgram( programGPU );
672
726
 
673
- if ( gl.getProgramParameter( programGPU, gl.LINK_STATUS ) === false ) {
727
+ this.set( pipeline, {
728
+ programGPU,
729
+ fragmentShader,
730
+ vertexShader
731
+ } );
674
732
 
675
- console.error( 'THREE.WebGLBackend:', gl.getProgramInfoLog( programGPU ) );
733
+ if ( promises !== null && this.parallel ) {
676
734
 
677
- console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( fragmentShader ) );
678
- console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( vertexShader ) );
735
+ const p = new Promise( ( resolve /*, reject*/ ) => {
679
736
 
680
- }
737
+ const parallel = this.parallel;
738
+ const checkStatus = () => {
681
739
 
682
- gl.useProgram( programGPU );
740
+ if ( gl.getProgramParameter( programGPU, parallel.COMPLETION_STATUS_KHR ) ) {
683
741
 
684
- // Bindings
742
+ this._completeCompile( renderObject, pipeline );
743
+ resolve();
685
744
 
686
- const bindings = renderObject.getBindings();
745
+ } else {
687
746
 
688
- for ( const binding of bindings ) {
747
+ requestAnimationFrame( checkStatus );
689
748
 
690
- const bindingData = this.get( binding );
691
- const index = bindingData.index;
749
+ }
692
750
 
693
- if ( binding.isUniformsGroup || binding.isUniformBuffer ) {
751
+ };
694
752
 
695
- const location = gl.getUniformBlockIndex( programGPU, binding.name );
696
- gl.uniformBlockBinding( programGPU, location, index );
753
+ checkStatus();
697
754
 
698
- } else if ( binding.isSampledTexture ) {
755
+ } );
699
756
 
700
- const location = gl.getUniformLocation( programGPU, binding.name );
701
- gl.uniform1i( location, index );
757
+ promises.push( p );
702
758
 
703
- }
759
+ return;
704
760
 
705
761
  }
706
762
 
707
- // VAO
763
+ this._completeCompile( renderObject, pipeline );
708
764
 
709
- const vaoGPU = gl.createVertexArray();
765
+ }
710
766
 
711
- const index = renderObject.getIndex();
712
- const attributes = renderObject.getAttributes();
767
+ _completeCompile( renderObject, pipeline ) {
713
768
 
714
- gl.bindVertexArray( vaoGPU );
769
+ const gl = this.gl;
770
+ const pipelineData = this.get( pipeline );
771
+ const { programGPU, fragmentShader, vertexShader } = pipelineData;
715
772
 
716
- if ( index !== null ) {
773
+ if ( gl.getProgramParameter( programGPU, gl.LINK_STATUS ) === false ) {
717
774
 
718
- const indexData = this.get( index );
775
+ console.error( 'THREE.WebGLBackend:', gl.getProgramInfoLog( programGPU ) );
719
776
 
720
- gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, indexData.bufferGPU );
777
+ console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( fragmentShader ) );
778
+ console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( vertexShader ) );
721
779
 
722
780
  }
723
781
 
724
- for ( let i = 0; i < attributes.length; i ++ ) {
782
+ gl.useProgram( programGPU );
725
783
 
726
- const attribute = attributes[ i ];
727
- const attributeData = this.get( attribute );
784
+ // Bindings
728
785
 
729
- gl.bindBuffer( gl.ARRAY_BUFFER, attributeData.bufferGPU );
730
- gl.enableVertexAttribArray( i );
786
+ this._setupBindings( renderObject.getBindings(), programGPU );
731
787
 
732
- let stride, offset;
788
+ //
733
789
 
734
- if ( attribute.isInterleavedBufferAttribute === true ) {
790
+ this.set( pipeline, {
791
+ programGPU
792
+ } );
735
793
 
736
- stride = attribute.data.stride * attributeData.bytesPerElement;
737
- offset = attribute.offset * attributeData.bytesPerElement;
794
+ }
738
795
 
739
- } else {
796
+ createComputePipeline( computePipeline, bindings ) {
740
797
 
741
- stride = 0;
742
- offset = 0;
798
+ const gl = this.gl;
743
799
 
744
- }
800
+ // Program
745
801
 
746
- if ( attributeData.isInteger ) {
802
+ const fragmentProgram = {
803
+ stage: 'fragment',
804
+ code: '#version 300 es\nprecision highp float;\nvoid main() {}'
805
+ };
747
806
 
748
- gl.vertexAttribIPointer( i, attribute.itemSize, attributeData.type, stride, offset );
807
+ this.createProgram( fragmentProgram );
749
808
 
750
- } else {
809
+ const { computeProgram } = computePipeline;
751
810
 
752
- gl.vertexAttribPointer( i, attribute.itemSize, attributeData.type, attribute.normalized, stride, offset );
811
+ const programGPU = gl.createProgram();
753
812
 
754
- }
813
+ const fragmentShader = this.get( fragmentProgram ).shaderGPU;
814
+ const vertexShader = this.get( computeProgram ).shaderGPU;
755
815
 
756
- if ( attribute.isInstancedBufferAttribute && ! attribute.isInterleavedBufferAttribute ) {
816
+ const transforms = computeProgram.transforms;
757
817
 
758
- gl.vertexAttribDivisor( i, attribute.meshPerAttribute );
818
+ const transformVaryingNames = [];
819
+ const transformAttributeNodes = [];
759
820
 
760
- } else if ( attribute.isInterleavedBufferAttribute && attribute.data.isInstancedInterleavedBuffer ) {
821
+ for ( let i = 0; i < transforms.length; i ++ ) {
761
822
 
762
- gl.vertexAttribDivisor( i, attribute.data.meshPerAttribute );
823
+ const transform = transforms[ i ];
763
824
 
764
- }
825
+ transformVaryingNames.push( transform.varyingName );
826
+ transformAttributeNodes.push( transform.attributeNode );
765
827
 
766
828
  }
767
829
 
768
- gl.bindVertexArray( null );
769
-
770
- //
830
+ gl.attachShader( programGPU, fragmentShader );
831
+ gl.attachShader( programGPU, vertexShader );
771
832
 
772
- this.set( pipeline, {
833
+ gl.transformFeedbackVaryings(
773
834
  programGPU,
774
- vaoGPU
775
- } );
835
+ transformVaryingNames,
836
+ gl.SEPARATE_ATTRIBS,
837
+ );
776
838
 
777
- }
839
+ gl.linkProgram( programGPU );
778
840
 
779
- createComputePipeline( /*computePipeline, bindings*/ ) {
841
+ if ( gl.getProgramParameter( programGPU, gl.LINK_STATUS ) === false ) {
780
842
 
781
- console.warn( 'Abstract class.' );
843
+ console.error( 'THREE.WebGLBackend:', gl.getProgramInfoLog( programGPU ) );
844
+
845
+ console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( fragmentShader ) );
846
+ console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( vertexShader ) );
847
+
848
+ }
849
+
850
+ gl.useProgram( programGPU );
851
+
852
+ // Bindings
853
+
854
+ this.createBindings( bindings );
855
+
856
+ this._setupBindings( bindings, programGPU );
857
+
858
+ const attributeNodes = computeProgram.attributes;
859
+ const attributes = [];
860
+ const transformBuffers = [];
861
+
862
+ for ( let i = 0; i < attributeNodes.length; i ++ ) {
863
+
864
+ const attribute = attributeNodes[ i ].node.attribute;
865
+
866
+ attributes.push( attribute );
867
+
868
+ if ( ! this.has( attribute ) ) this.attributeUtils.createAttribute( attribute, gl.ARRAY_BUFFER );
869
+
870
+ }
871
+
872
+ for ( let i = 0; i < transformAttributeNodes.length; i ++ ) {
873
+
874
+ const attribute = transformAttributeNodes[ i ].attribute;
875
+
876
+ if ( ! this.has( attribute ) ) this.attributeUtils.createAttribute( attribute, gl.ARRAY_BUFFER );
877
+
878
+ const attributeData = this.get( attribute );
879
+
880
+ transformBuffers.push( attributeData );
881
+
882
+ }
883
+
884
+ //
885
+
886
+ this.set( computePipeline, {
887
+ programGPU,
888
+ transformBuffers,
889
+ attributes
890
+ } );
782
891
 
783
892
  }
784
893
 
@@ -856,15 +965,17 @@ class WebGLBackend extends Backend {
856
965
 
857
966
  createAttribute( attribute ) {
858
967
 
968
+ if ( this.has( attribute ) ) return;
969
+
859
970
  const gl = this.gl;
860
971
 
861
972
  this.attributeUtils.createAttribute( attribute, gl.ARRAY_BUFFER );
862
973
 
863
974
  }
864
975
 
865
- createStorageAttribute( /*attribute*/ ) {
976
+ createStorageAttribute( attribute ) {
866
977
 
867
- console.warn( 'Abstract class.' );
978
+ //console.warn( 'Abstract class.' );
868
979
 
869
980
  }
870
981
 
@@ -874,9 +985,9 @@ class WebGLBackend extends Backend {
874
985
 
875
986
  }
876
987
 
877
- destroyAttribute( /*attribute*/ ) {
988
+ destroyAttribute( attribute ) {
878
989
 
879
- console.warn( 'Abstract class.' );
990
+ this.attributeUtils.destroyAttribute( attribute );
880
991
 
881
992
  }
882
993
 
@@ -886,12 +997,30 @@ class WebGLBackend extends Backend {
886
997
 
887
998
  }
888
999
 
889
- hasFeature( /*name*/ ) {
1000
+ async hasFeatureAsync( name ) {
890
1001
 
891
- return true;
1002
+ return this.hasFeature( name );
892
1003
 
893
1004
  }
894
1005
 
1006
+ hasFeature( name ) {
1007
+
1008
+ const keysMatching = Object.keys( GLFeatureName ).filter( key => GLFeatureName[ key ] === name );
1009
+
1010
+ const extensions = this.extensions;
1011
+
1012
+ for ( let i = 0; i < keysMatching.length; i ++ ) {
1013
+
1014
+
1015
+ if ( extensions.has( keysMatching[ i ] ) ) return true;
1016
+
1017
+ }
1018
+
1019
+ return false;
1020
+
1021
+ }
1022
+
1023
+
895
1024
  getMaxAnisotropy() {
896
1025
 
897
1026
  return this.capabilities.getMaxAnisotropy();
@@ -900,97 +1029,349 @@ class WebGLBackend extends Backend {
900
1029
 
901
1030
  copyFramebufferToTexture( texture, renderContext ) {
902
1031
 
903
- const { gl } = this;
1032
+ this.textureUtils.copyFramebufferToTexture( texture, renderContext );
904
1033
 
905
- const { textureGPU } = this.get( texture );
1034
+ }
906
1035
 
907
- const width = texture.image.width;
908
- const height = texture.image.height;
1036
+ _setFramebuffer( renderContext ) {
909
1037
 
910
- gl.bindFramebuffer( gl.READ_FRAMEBUFFER, null );
1038
+ const { gl, state } = this;
911
1039
 
912
- if ( texture.isDepthTexture ) {
1040
+ let currentFrameBuffer = null;
913
1041
 
914
- const fb = gl.createFramebuffer();
1042
+ if ( renderContext.textures !== null ) {
915
1043
 
916
- gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, fb );
1044
+ const renderTarget = renderContext.renderTarget;
1045
+ const renderTargetContextData = this.get( renderTarget );
1046
+ const { samples, depthBuffer, stencilBuffer } = renderTarget;
1047
+ const cubeFace = this.renderer._activeCubeFace;
1048
+ const isCube = renderTarget.isWebGLCubeRenderTarget === true;
917
1049
 
918
- gl.framebufferTexture2D( gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, textureGPU, 0 );
1050
+ let msaaFb = renderTargetContextData.msaaFrameBuffer;
1051
+ let depthRenderbuffer = renderTargetContextData.depthRenderbuffer;
919
1052
 
920
- gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, gl.DEPTH_BUFFER_BIT, gl.NEAREST );
1053
+ let fb;
921
1054
 
922
- gl.deleteFramebuffer( fb );
1055
+ if ( isCube ) {
923
1056
 
1057
+ if ( renderTargetContextData.cubeFramebuffers === undefined ) {
924
1058
 
925
- } else {
1059
+ renderTargetContextData.cubeFramebuffers = [];
1060
+
1061
+ }
1062
+
1063
+ fb = renderTargetContextData.cubeFramebuffers[ cubeFace ];
1064
+
1065
+ } else {
1066
+
1067
+ fb = renderTargetContextData.framebuffer;
1068
+
1069
+ }
1070
+
1071
+ if ( fb === undefined ) {
1072
+
1073
+ fb = gl.createFramebuffer();
1074
+
1075
+ state.bindFramebuffer( gl.FRAMEBUFFER, fb );
1076
+
1077
+ const textures = renderContext.textures;
1078
+
1079
+ if ( isCube ) {
1080
+
1081
+ renderTargetContextData.cubeFramebuffers[ cubeFace ] = fb;
1082
+ const { textureGPU } = this.get( textures[ 0 ] );
1083
+
1084
+ gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, textureGPU, 0 );
1085
+
1086
+ } else {
1087
+
1088
+ for ( let i = 0; i < textures.length; i ++ ) {
1089
+
1090
+ const texture = textures[ i ];
1091
+ const textureData = this.get( texture );
1092
+ textureData.renderTarget = renderContext.renderTarget;
1093
+
1094
+ const attachment = gl.COLOR_ATTACHMENT0 + i;
1095
+
1096
+ gl.framebufferTexture2D( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0 );
1097
+
1098
+ }
1099
+
1100
+ renderTargetContextData.framebuffer = fb;
1101
+
1102
+ state.drawBuffers( renderContext, fb );
1103
+
1104
+ }
1105
+
1106
+ if ( renderContext.depthTexture !== null ) {
1107
+
1108
+ const textureData = this.get( renderContext.depthTexture );
1109
+ const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
1110
+
1111
+ gl.framebufferTexture2D( gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0 );
1112
+
1113
+ }
1114
+
1115
+ }
1116
+
1117
+ if ( samples > 0 ) {
1118
+
1119
+ if ( msaaFb === undefined ) {
1120
+
1121
+ const invalidationArray = [];
1122
+
1123
+ msaaFb = gl.createFramebuffer();
1124
+
1125
+ state.bindFramebuffer( gl.FRAMEBUFFER, msaaFb );
1126
+
1127
+ const msaaRenderbuffers = [];
1128
+
1129
+ const textures = renderContext.textures;
1130
+
1131
+ for ( let i = 0; i < textures.length; i ++ ) {
1132
+
1133
+
1134
+ msaaRenderbuffers[ i ] = gl.createRenderbuffer();
1135
+
1136
+ gl.bindRenderbuffer( gl.RENDERBUFFER, msaaRenderbuffers[ i ] );
1137
+
1138
+ invalidationArray.push( gl.COLOR_ATTACHMENT0 + i );
1139
+
1140
+ if ( depthBuffer ) {
1141
+
1142
+ const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
1143
+ invalidationArray.push( depthStyle );
1144
+
1145
+ }
1146
+
1147
+ const texture = renderContext.textures[ i ];
1148
+ const textureData = this.get( texture );
1149
+
1150
+ gl.renderbufferStorageMultisample( gl.RENDERBUFFER, samples, textureData.glInternalFormat, renderContext.width, renderContext.height );
1151
+ gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.RENDERBUFFER, msaaRenderbuffers[ i ] );
1152
+
1153
+
1154
+ }
1155
+
1156
+ renderTargetContextData.msaaFrameBuffer = msaaFb;
1157
+ renderTargetContextData.msaaRenderbuffers = msaaRenderbuffers;
1158
+
1159
+ if ( depthRenderbuffer === undefined ) {
1160
+
1161
+ depthRenderbuffer = gl.createRenderbuffer();
1162
+ this.textureUtils.setupRenderBufferStorage( depthRenderbuffer, renderContext );
1163
+
1164
+ renderTargetContextData.depthRenderbuffer = depthRenderbuffer;
926
1165
 
927
- gl.bindTexture( gl.TEXTURE_2D, textureGPU );
928
- gl.copyTexSubImage2D( gl.TEXTURE_2D, 0, 0, 0, 0, 0, width, height );
1166
+ const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
1167
+ invalidationArray.push( depthStyle );
1168
+
1169
+ }
1170
+
1171
+ renderTargetContextData.invalidationArray = invalidationArray;
1172
+
1173
+ }
929
1174
 
930
- gl.bindTexture( gl.TEXTURE_2D, null );
1175
+ currentFrameBuffer = renderTargetContextData.msaaFrameBuffer;
1176
+
1177
+ } else {
1178
+
1179
+ currentFrameBuffer = fb;
1180
+
1181
+ }
931
1182
 
932
1183
  }
933
1184
 
934
- if ( texture.generateMipmaps ) this.generateMipmaps( texture );
1185
+ state.bindFramebuffer( gl.FRAMEBUFFER, currentFrameBuffer );
935
1186
 
936
- this._setFramebuffer( renderContext );
1187
+ }
1188
+
1189
+
1190
+ _getVaoKey( index, attributes ) {
1191
+
1192
+ let key = [];
1193
+
1194
+ if ( index !== null ) {
1195
+
1196
+ const indexData = this.get( index );
1197
+
1198
+ key += ':' + indexData.id;
1199
+
1200
+ }
1201
+
1202
+ for ( let i = 0; i < attributes.length; i ++ ) {
1203
+
1204
+ const attributeData = this.get( attributes[ i ] );
1205
+
1206
+ key += ':' + attributeData.id;
1207
+
1208
+ }
1209
+
1210
+ return key;
937
1211
 
938
1212
  }
939
1213
 
940
- _setFramebuffer( renderContext ) {
1214
+ _createVao( index, attributes ) {
941
1215
 
942
1216
  const { gl } = this;
943
1217
 
944
- if ( renderContext.textures !== null ) {
1218
+ const vaoGPU = gl.createVertexArray();
1219
+ let key = '';
945
1220
 
946
- const renderContextData = this.get( renderContext.renderTarget );
1221
+ let staticVao = true;
947
1222
 
948
- let fb = renderContextData.framebuffer;
1223
+ gl.bindVertexArray( vaoGPU );
949
1224
 
950
- if ( fb === undefined ) {
1225
+ if ( index !== null ) {
951
1226
 
952
- fb = gl.createFramebuffer();
1227
+ const indexData = this.get( index );
953
1228
 
954
- gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
1229
+ gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, indexData.bufferGPU );
955
1230
 
956
- const textures = renderContext.textures;
1231
+ key += ':' + indexData.id;
957
1232
 
958
- const drawBuffers = [];
1233
+ }
959
1234
 
960
- for ( let i = 0; i < textures.length; i ++ ) {
1235
+ for ( let i = 0; i < attributes.length; i ++ ) {
961
1236
 
962
- const texture = textures[ i ];
963
- const { textureGPU } = this.get( texture );
1237
+ const attribute = attributes[ i ];
1238
+ const attributeData = this.get( attribute );
964
1239
 
965
- const attachment = gl.COLOR_ATTACHMENT0 + i;
1240
+ key += ':' + attributeData.id;
966
1241
 
967
- gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, textureGPU, 0 );
1242
+ gl.bindBuffer( gl.ARRAY_BUFFER, attributeData.bufferGPU );
1243
+ gl.enableVertexAttribArray( i );
968
1244
 
969
- drawBuffers.push( attachment );
1245
+ if ( attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute ) staticVao = false;
970
1246
 
971
- }
1247
+ let stride, offset;
972
1248
 
973
- gl.drawBuffers( drawBuffers );
1249
+ if ( attribute.isInterleavedBufferAttribute === true ) {
974
1250
 
975
- if ( renderContext.depthTexture !== null ) {
1251
+ stride = attribute.data.stride * attributeData.bytesPerElement;
1252
+ offset = attribute.offset * attributeData.bytesPerElement;
976
1253
 
977
- const { textureGPU } = this.get( renderContext.depthTexture );
1254
+ } else {
978
1255
 
979
- gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, textureGPU, 0 );
1256
+ stride = 0;
1257
+ offset = 0;
980
1258
 
981
- }
1259
+ }
982
1260
 
983
- renderContextData.framebuffer = fb;
1261
+ if ( attributeData.isInteger ) {
1262
+
1263
+ gl.vertexAttribIPointer( i, attribute.itemSize, attributeData.type, stride, offset );
984
1264
 
985
1265
  } else {
986
1266
 
987
- gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
1267
+ gl.vertexAttribPointer( i, attribute.itemSize, attributeData.type, attribute.normalized, stride, offset );
988
1268
 
989
1269
  }
990
1270
 
991
- } else {
1271
+ if ( attribute.isInstancedBufferAttribute && ! attribute.isInterleavedBufferAttribute ) {
992
1272
 
993
- gl.bindFramebuffer( gl.FRAMEBUFFER, null );
1273
+ gl.vertexAttribDivisor( i, attribute.meshPerAttribute );
1274
+
1275
+ } else if ( attribute.isInterleavedBufferAttribute && attribute.data.isInstancedInterleavedBuffer ) {
1276
+
1277
+ gl.vertexAttribDivisor( i, attribute.data.meshPerAttribute );
1278
+
1279
+ }
1280
+
1281
+ }
1282
+
1283
+ gl.bindBuffer( gl.ARRAY_BUFFER, null );
1284
+
1285
+ this.vaoCache[ key ] = vaoGPU;
1286
+
1287
+ return { vaoGPU, staticVao };
1288
+
1289
+ }
1290
+
1291
+ _getTransformFeedback( transformBuffers ) {
1292
+
1293
+ let key = '';
1294
+
1295
+ for ( let i = 0; i < transformBuffers.length; i ++ ) {
1296
+
1297
+ key += ':' + transformBuffers[ i ].id;
1298
+
1299
+ }
1300
+
1301
+ let transformFeedbackGPU = this.transformFeedbackCache[ key ];
1302
+
1303
+ if ( transformFeedbackGPU !== undefined ) {
1304
+
1305
+ return transformFeedbackGPU;
1306
+
1307
+ }
1308
+
1309
+ const gl = this.gl;
1310
+
1311
+ transformFeedbackGPU = gl.createTransformFeedback();
1312
+
1313
+ gl.bindTransformFeedback( gl.TRANSFORM_FEEDBACK, transformFeedbackGPU );
1314
+
1315
+ for ( let i = 0; i < transformBuffers.length; i ++ ) {
1316
+
1317
+ const attributeData = transformBuffers[ i ];
1318
+
1319
+ gl.bindBufferBase( gl.TRANSFORM_FEEDBACK_BUFFER, i, attributeData.transformBuffer );
1320
+
1321
+ }
1322
+
1323
+ gl.bindTransformFeedback( gl.TRANSFORM_FEEDBACK, null );
1324
+
1325
+ this.transformFeedbackCache[ key ] = transformFeedbackGPU;
1326
+
1327
+ return transformFeedbackGPU;
1328
+
1329
+ }
1330
+
1331
+
1332
+ _setupBindings( bindings, programGPU ) {
1333
+
1334
+ const gl = this.gl;
1335
+
1336
+ for ( const binding of bindings ) {
1337
+
1338
+ const bindingData = this.get( binding );
1339
+ const index = bindingData.index;
1340
+
1341
+ if ( binding.isUniformsGroup || binding.isUniformBuffer ) {
1342
+
1343
+ const location = gl.getUniformBlockIndex( programGPU, binding.name );
1344
+ gl.uniformBlockBinding( programGPU, location, index );
1345
+
1346
+ } else if ( binding.isSampledTexture ) {
1347
+
1348
+ const location = gl.getUniformLocation( programGPU, binding.name );
1349
+ gl.uniform1i( location, index );
1350
+
1351
+ }
1352
+
1353
+ }
1354
+
1355
+ }
1356
+
1357
+ _bindUniforms( bindings ) {
1358
+
1359
+ const { gl, state } = this;
1360
+
1361
+ for ( const binding of bindings ) {
1362
+
1363
+ const bindingData = this.get( binding );
1364
+ const index = bindingData.index;
1365
+
1366
+ if ( binding.isUniformsGroup || binding.isUniformBuffer ) {
1367
+
1368
+ gl.bindBufferBase( gl.UNIFORM_BUFFER, index, bindingData.bufferGPU );
1369
+
1370
+ } else if ( binding.isSampledTexture ) {
1371
+
1372
+ state.bindTexture( bindingData.glTextureType, bindingData.textureGPU, gl.TEXTURE0 + index );
1373
+
1374
+ }
994
1375
 
995
1376
  }
996
1377