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
@@ -15,6 +15,7 @@ import ClippingContext from './ClippingContext.js';
15
15
  import QuadMesh from './QuadMesh.js';
16
16
  import RenderBundles from './RenderBundles.js';
17
17
  import NodeLibrary from './nodes/NodeLibrary.js';
18
+ import Lighting from './Lighting.js';
18
19
 
19
20
  import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
20
21
 
@@ -77,16 +78,16 @@ class Renderer {
77
78
  this.depth = depth;
78
79
  this.stencil = stencil;
79
80
 
80
- this.clippingPlanes = [];
81
-
82
81
  this.info = new Info();
83
82
 
84
83
  this.nodes = {
85
- library: new NodeLibrary(),
86
84
  modelViewMatrix: null,
87
85
  modelNormalViewMatrix: null
88
86
  };
89
87
 
88
+ this.library = new NodeLibrary();
89
+ this.lighting = new Lighting();
90
+
90
91
  // internals
91
92
 
92
93
  this._getFallback = getFallback;
@@ -140,6 +141,9 @@ class Renderer {
140
141
 
141
142
  this._handleObjectFunction = this._renderObjectDirect;
142
143
 
144
+ this._isDeviceLost = false;
145
+ this.onDeviceLost = this._onDeviceLost;
146
+
143
147
  this._initialized = false;
144
148
  this._initPromise = null;
145
149
 
@@ -169,7 +173,7 @@ class Renderer {
169
173
 
170
174
  const material = scene.overrideMaterial || object.material;
171
175
 
172
- const renderObject = this._objects.get( object, material, scene, camera, renderList.lightsNode, renderContext );
176
+ const renderObject = this._objects.get( object, material, scene, camera, renderList.lightsNode, renderContext, renderContext.clippingContext );
173
177
 
174
178
  const { fragmentShader, vertexShader } = renderObject.getNodeBuilderState();
175
179
 
@@ -238,12 +242,13 @@ class Renderer {
238
242
  this._pipelines = new Pipelines( backend, this._nodes );
239
243
  this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info );
240
244
  this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info );
241
- this._renderLists = new RenderLists();
245
+ this._renderLists = new RenderLists( this.lighting );
242
246
  this._bundles = new RenderBundles();
243
247
  this._renderContexts = new RenderContexts();
244
248
 
245
249
  //
246
250
 
251
+ this._animation.start();
247
252
  this._initialized = true;
248
253
 
249
254
  resolve();
@@ -262,6 +267,8 @@ class Renderer {
262
267
 
263
268
  async compileAsync( scene, camera, targetScene = null ) {
264
269
 
270
+ if ( this._isDeviceLost === true ) return;
271
+
265
272
  if ( this._initialized === false ) await this.init();
266
273
 
267
274
  // preserve render tree
@@ -304,7 +311,7 @@ class Renderer {
304
311
  renderContext.stencil = this.stencil;
305
312
 
306
313
  if ( ! renderContext.clippingContext ) renderContext.clippingContext = new ClippingContext();
307
- renderContext.clippingContext.updateGlobal( this, camera );
314
+ renderContext.clippingContext.updateGlobal( sceneRef, camera );
308
315
 
309
316
  //
310
317
 
@@ -315,7 +322,7 @@ class Renderer {
315
322
  const renderList = this._renderLists.get( scene, camera );
316
323
  renderList.begin();
317
324
 
318
- this._projectObject( scene, camera, 0, renderList );
325
+ this._projectObject( scene, camera, 0, renderList, renderContext.clippingContext );
319
326
 
320
327
  // include lights from target scene
321
328
  if ( targetScene !== scene ) {
@@ -364,10 +371,11 @@ class Renderer {
364
371
 
365
372
  const opaqueObjects = renderList.opaque;
366
373
  const transparentObjects = renderList.transparent;
374
+ const transparentDoublePassObjects = renderList.transparentDoublePass;
367
375
  const lightsNode = renderList.lightsNode;
368
376
 
369
377
  if ( this.opaque === true && opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
370
- if ( this.transparent === true && transparentObjects.length > 0 ) this._renderObjects( transparentObjects, camera, sceneRef, lightsNode );
378
+ if ( this.transparent === true && transparentObjects.length > 0 ) this._renderTransparents( transparentObjects, transparentDoublePassObjects, camera, sceneRef, lightsNode );
371
379
 
372
380
  // restore render tree
373
381
 
@@ -395,6 +403,12 @@ class Renderer {
395
403
 
396
404
  }
397
405
 
406
+ async waitForGPU() {
407
+
408
+ await this.backend.waitForGPU();
409
+
410
+ }
411
+
398
412
  setMRT( mrt ) {
399
413
 
400
414
  this._mrt = mrt;
@@ -409,6 +423,23 @@ class Renderer {
409
423
 
410
424
  }
411
425
 
426
+ _onDeviceLost( info ) {
427
+
428
+ let errorMessage = `THREE.WebGPURenderer: ${info.api} Device Lost:\n\nMessage: ${info.message}`;
429
+
430
+ if ( info.reason ) {
431
+
432
+ errorMessage += `\nReason: ${info.reason}`;
433
+
434
+ }
435
+
436
+ console.error( errorMessage );
437
+
438
+ this._isDeviceLost = true;
439
+
440
+ }
441
+
442
+
412
443
  _renderBundle( bundle, sceneRef, lightsNode ) {
413
444
 
414
445
  const { bundleGroup, camera, renderList } = bundle;
@@ -443,7 +474,7 @@ class Renderer {
443
474
 
444
475
  const opaqueObjects = renderList.opaque;
445
476
 
446
- if ( opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
477
+ if ( this.opaque === true && opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
447
478
 
448
479
  this._currentRenderBundle = null;
449
480
 
@@ -543,6 +574,8 @@ class Renderer {
543
574
 
544
575
  _renderScene( scene, camera, useFrameBufferTarget = true ) {
545
576
 
577
+ if ( this._isDeviceLost === true ) return;
578
+
546
579
  const frameBufferTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : null;
547
580
 
548
581
  // preserve render tree
@@ -645,7 +678,7 @@ class Renderer {
645
678
  renderContext.scissorValue.height >>= activeMipmapLevel;
646
679
 
647
680
  if ( ! renderContext.clippingContext ) renderContext.clippingContext = new ClippingContext();
648
- renderContext.clippingContext.updateGlobal( this, camera );
681
+ renderContext.clippingContext.updateGlobal( sceneRef, camera );
649
682
 
650
683
  //
651
684
 
@@ -659,7 +692,7 @@ class Renderer {
659
692
  const renderList = this._renderLists.get( scene, camera );
660
693
  renderList.begin();
661
694
 
662
- this._projectObject( scene, camera, 0, renderList );
695
+ this._projectObject( scene, camera, 0, renderList, renderContext.clippingContext );
663
696
 
664
697
  renderList.finish();
665
698
 
@@ -719,13 +752,14 @@ class Renderer {
719
752
  const {
720
753
  bundles,
721
754
  lightsNode,
755
+ transparentDoublePass: transparentDoublePassObjects,
722
756
  transparent: transparentObjects,
723
757
  opaque: opaqueObjects
724
758
  } = renderList;
725
759
 
726
760
  if ( bundles.length > 0 ) this._renderBundles( bundles, sceneRef, lightsNode );
727
761
  if ( this.opaque === true && opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
728
- if ( this.transparent === true && transparentObjects.length > 0 ) this._renderObjects( transparentObjects, camera, sceneRef, lightsNode );
762
+ if ( this.transparent === true && transparentObjects.length > 0 ) this._renderTransparents( transparentObjects, transparentDoublePassObjects, camera, sceneRef, lightsNode );
729
763
 
730
764
  // finish render pass
731
765
 
@@ -825,6 +859,8 @@ class Renderer {
825
859
 
826
860
  setPixelRatio( value = 1 ) {
827
861
 
862
+ if ( this._pixelRatio === value ) return;
863
+
828
864
  this._pixelRatio = value;
829
865
 
830
866
  this.setSize( this._width, this._height, false );
@@ -1108,6 +1144,7 @@ class Renderer {
1108
1144
  dispose() {
1109
1145
 
1110
1146
  this.info.dispose();
1147
+ this.backend.dispose();
1111
1148
 
1112
1149
  this._animation.dispose();
1113
1150
  this._objects.dispose();
@@ -1149,9 +1186,19 @@ class Renderer {
1149
1186
 
1150
1187
  }
1151
1188
 
1152
- async computeAsync( computeNodes ) {
1189
+ compute( computeNodes ) {
1153
1190
 
1154
- if ( this._initialized === false ) await this.init();
1191
+ if ( this.isDeviceLost === true ) return;
1192
+
1193
+ if ( this._initialized === false ) {
1194
+
1195
+ console.warn( 'THREE.Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead.' );
1196
+
1197
+ return this.computeAsync( computeNodes );
1198
+
1199
+ }
1200
+
1201
+ //
1155
1202
 
1156
1203
  const nodeFrame = this._nodes.nodeFrame;
1157
1204
 
@@ -1202,7 +1249,13 @@ class Renderer {
1202
1249
 
1203
1250
  //
1204
1251
 
1205
- computeNode.onInit( { renderer: this } );
1252
+ const onInitFn = computeNode.onInitFunction;
1253
+
1254
+ if ( onInitFn !== null ) {
1255
+
1256
+ onInitFn.call( computeNode, { renderer: this } );
1257
+
1258
+ }
1206
1259
 
1207
1260
  }
1208
1261
 
@@ -1218,14 +1271,22 @@ class Renderer {
1218
1271
 
1219
1272
  backend.finishCompute( computeNodes );
1220
1273
 
1221
- await this.backend.resolveTimestampAsync( computeNodes, 'compute' );
1222
-
1223
1274
  //
1224
1275
 
1225
1276
  nodeFrame.renderId = previousRenderId;
1226
1277
 
1227
1278
  }
1228
1279
 
1280
+ async computeAsync( computeNodes ) {
1281
+
1282
+ if ( this._initialized === false ) await this.init();
1283
+
1284
+ this.compute( computeNodes );
1285
+
1286
+ await this.backend.resolveTimestampAsync( computeNodes, 'compute' );
1287
+
1288
+ }
1289
+
1229
1290
  async hasFeatureAsync( name ) {
1230
1291
 
1231
1292
  if ( this._initialized === false ) await this.init();
@@ -1248,13 +1309,86 @@ class Renderer {
1248
1309
 
1249
1310
  }
1250
1311
 
1312
+ hasInitialized() {
1313
+
1314
+ return this._initialized;
1315
+
1316
+ }
1317
+
1318
+ async initTextureAsync( texture ) {
1319
+
1320
+ if ( this._initialized === false ) await this.init();
1321
+
1322
+ this._textures.updateTexture( texture );
1323
+
1324
+ }
1325
+
1326
+ initTexture( texture ) {
1327
+
1328
+ if ( this._initialized === false ) {
1329
+
1330
+ console.warn( 'THREE.Renderer: .initTexture() called before the backend is initialized. Try using .initTextureAsync() instead.' );
1331
+
1332
+ return false;
1333
+
1334
+ }
1335
+
1336
+ this._textures.updateTexture( texture );
1337
+
1338
+ }
1339
+
1251
1340
  copyFramebufferToTexture( framebufferTexture, rectangle = null ) {
1252
1341
 
1253
- const renderContext = this._currentRenderContext;
1342
+ if ( rectangle !== null ) {
1343
+
1344
+ if ( rectangle.isVector2 ) {
1345
+
1346
+ rectangle = _vector4.set( rectangle.x, rectangle.y, framebufferTexture.image.width, framebufferTexture.image.height ).floor();
1347
+
1348
+ } else if ( rectangle.isVector4 ) {
1349
+
1350
+ rectangle = _vector4.copy( rectangle ).floor();
1351
+
1352
+ } else {
1353
+
1354
+ console.error( 'THREE.Renderer.copyFramebufferToTexture: Invalid rectangle.' );
1254
1355
 
1255
- this._textures.updateTexture( framebufferTexture );
1356
+ return;
1256
1357
 
1257
- rectangle = rectangle === null ? _vector4.set( 0, 0, framebufferTexture.image.width, framebufferTexture.image.height ) : rectangle;
1358
+ }
1359
+
1360
+ } else {
1361
+
1362
+ rectangle = _vector4.set( 0, 0, framebufferTexture.image.width, framebufferTexture.image.height );
1363
+
1364
+ }
1365
+
1366
+ //
1367
+
1368
+ let renderContext = this._currentRenderContext;
1369
+ let renderTarget;
1370
+
1371
+ if ( renderContext !== null ) {
1372
+
1373
+ renderTarget = renderContext.renderTarget;
1374
+
1375
+ } else {
1376
+
1377
+ renderTarget = this._renderTarget || this._getFrameBufferTarget();
1378
+
1379
+ if ( renderTarget !== null ) {
1380
+
1381
+ this._textures.updateRenderTarget( renderTarget );
1382
+
1383
+ renderContext = this._textures.get( renderTarget );
1384
+
1385
+ }
1386
+
1387
+ }
1388
+
1389
+ //
1390
+
1391
+ this._textures.updateTexture( framebufferTexture, { renderTarget } );
1258
1392
 
1259
1393
  this.backend.copyFramebufferToTexture( framebufferTexture, renderContext, rectangle );
1260
1394
 
@@ -1269,14 +1403,13 @@ class Renderer {
1269
1403
 
1270
1404
  }
1271
1405
 
1272
-
1273
1406
  readRenderTargetPixelsAsync( renderTarget, x, y, width, height, index = 0, faceIndex = 0 ) {
1274
1407
 
1275
1408
  return this.backend.copyTextureToBuffer( renderTarget.textures[ index ], x, y, width, height, faceIndex );
1276
1409
 
1277
1410
  }
1278
1411
 
1279
- _projectObject( object, camera, groupOrder, renderList ) {
1412
+ _projectObject( object, camera, groupOrder, renderList, clippingContext ) {
1280
1413
 
1281
1414
  if ( object.visible === false ) return;
1282
1415
 
@@ -1288,6 +1421,8 @@ class Renderer {
1288
1421
 
1289
1422
  groupOrder = object.renderOrder;
1290
1423
 
1424
+ if ( object.isClippingGroup && object.enabled ) clippingContext = clippingContext.getGroupContext( object );
1425
+
1291
1426
  } else if ( object.isLOD ) {
1292
1427
 
1293
1428
  if ( object.autoUpdate === true ) object.update( camera );
@@ -1310,7 +1445,7 @@ class Renderer {
1310
1445
 
1311
1446
  if ( material.visible ) {
1312
1447
 
1313
- renderList.push( object, geometry, material, groupOrder, _vector4.z, null );
1448
+ renderList.push( object, geometry, material, groupOrder, _vector4.z, null, clippingContext );
1314
1449
 
1315
1450
  }
1316
1451
 
@@ -1348,7 +1483,7 @@ class Renderer {
1348
1483
 
1349
1484
  if ( groupMaterial && groupMaterial.visible ) {
1350
1485
 
1351
- renderList.push( object, geometry, groupMaterial, groupOrder, _vector4.z, group );
1486
+ renderList.push( object, geometry, groupMaterial, groupOrder, _vector4.z, group, clippingContext );
1352
1487
 
1353
1488
  }
1354
1489
 
@@ -1356,7 +1491,7 @@ class Renderer {
1356
1491
 
1357
1492
  } else if ( material.visible ) {
1358
1493
 
1359
- renderList.push( object, geometry, material, groupOrder, _vector4.z, null );
1494
+ renderList.push( object, geometry, material, groupOrder, _vector4.z, null, clippingContext );
1360
1495
 
1361
1496
  }
1362
1497
 
@@ -1389,7 +1524,7 @@ class Renderer {
1389
1524
 
1390
1525
  for ( let i = 0, l = children.length; i < l; i ++ ) {
1391
1526
 
1392
- this._projectObject( children[ i ], camera, groupOrder, renderList );
1527
+ this._projectObject( children[ i ], camera, groupOrder, renderList, clippingContext );
1393
1528
 
1394
1529
  }
1395
1530
 
@@ -1405,7 +1540,47 @@ class Renderer {
1405
1540
 
1406
1541
  }
1407
1542
 
1408
- _renderObjects( renderList, camera, scene, lightsNode ) {
1543
+ _renderTransparents( renderList, doublePassList, camera, scene, lightsNode ) {
1544
+
1545
+ if ( doublePassList.length > 0 ) {
1546
+
1547
+ // render back side
1548
+
1549
+ for ( const { material } of doublePassList ) {
1550
+
1551
+ material.side = BackSide;
1552
+
1553
+ }
1554
+
1555
+ this._renderObjects( doublePassList, camera, scene, lightsNode, 'backSide' );
1556
+
1557
+ // render front side
1558
+
1559
+ for ( const { material } of doublePassList ) {
1560
+
1561
+ material.side = FrontSide;
1562
+
1563
+ }
1564
+
1565
+ this._renderObjects( renderList, camera, scene, lightsNode );
1566
+
1567
+ // restore
1568
+
1569
+ for ( const { material } of doublePassList ) {
1570
+
1571
+ material.side = DoubleSide;
1572
+
1573
+ }
1574
+
1575
+ } else {
1576
+
1577
+ this._renderObjects( renderList, camera, scene, lightsNode );
1578
+
1579
+ }
1580
+
1581
+ }
1582
+
1583
+ _renderObjects( renderList, camera, scene, lightsNode, passId = null ) {
1409
1584
 
1410
1585
  // process renderable objects
1411
1586
 
@@ -1416,7 +1591,7 @@ class Renderer {
1416
1591
  // @TODO: Add support for multiple materials per object. This will require to extract
1417
1592
  // the material from the renderItem object and pass it with its group data to renderObject().
1418
1593
 
1419
- const { object, geometry, material, group } = renderItem;
1594
+ const { object, geometry, material, group, clippingContext } = renderItem;
1420
1595
 
1421
1596
  if ( camera.isArrayCamera ) {
1422
1597
 
@@ -1439,7 +1614,7 @@ class Renderer {
1439
1614
 
1440
1615
  this.backend.updateViewport( this._currentRenderContext );
1441
1616
 
1442
- this._currentRenderObjectFunction( object, scene, camera2, geometry, material, group, lightsNode );
1617
+ this._currentRenderObjectFunction( object, scene, camera2, geometry, material, group, lightsNode, clippingContext, passId );
1443
1618
 
1444
1619
  }
1445
1620
 
@@ -1447,7 +1622,7 @@ class Renderer {
1447
1622
 
1448
1623
  } else {
1449
1624
 
1450
- this._currentRenderObjectFunction( object, scene, camera, geometry, material, group, lightsNode );
1625
+ this._currentRenderObjectFunction( object, scene, camera, geometry, material, group, lightsNode, clippingContext, passId );
1451
1626
 
1452
1627
  }
1453
1628
 
@@ -1455,10 +1630,10 @@ class Renderer {
1455
1630
 
1456
1631
  }
1457
1632
 
1458
- renderObject( object, scene, camera, geometry, material, group, lightsNode ) {
1633
+ renderObject( object, scene, camera, geometry, material, group, lightsNode, clippingContext = null, passId = null ) {
1459
1634
 
1460
1635
  let overridePositionNode;
1461
- let overrideFragmentNode;
1636
+ let overrideColorNode;
1462
1637
  let overrideDepthNode;
1463
1638
 
1464
1639
  //
@@ -1478,6 +1653,9 @@ class Renderer {
1478
1653
 
1479
1654
  }
1480
1655
 
1656
+ overrideMaterial.alphaTest = material.alphaTest;
1657
+ overrideMaterial.alphaMap = material.alphaMap;
1658
+
1481
1659
  if ( overrideMaterial.isShadowNodeMaterial ) {
1482
1660
 
1483
1661
  overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide;
@@ -1489,37 +1667,10 @@ class Renderer {
1489
1667
 
1490
1668
  }
1491
1669
 
1670
+ if ( material.castShadowNode && material.castShadowNode.isNode ) {
1492
1671
 
1493
- if ( material.shadowNode && material.shadowNode.isNode ) {
1494
-
1495
- overrideFragmentNode = overrideMaterial.fragmentNode;
1496
- overrideMaterial.fragmentNode = material.shadowNode;
1497
-
1498
- }
1499
-
1500
- if ( this.localClippingEnabled ) {
1501
-
1502
- if ( material.clipShadows ) {
1503
-
1504
- if ( overrideMaterial.clippingPlanes !== material.clippingPlanes ) {
1505
-
1506
- overrideMaterial.clippingPlanes = material.clippingPlanes;
1507
- overrideMaterial.needsUpdate = true;
1508
-
1509
- }
1510
-
1511
- if ( overrideMaterial.clipIntersection !== material.clipIntersection ) {
1512
-
1513
- overrideMaterial.clipIntersection = material.clipIntersection;
1514
-
1515
- }
1516
-
1517
- } else if ( Array.isArray( overrideMaterial.clippingPlanes ) ) {
1518
-
1519
- overrideMaterial.clippingPlanes = null;
1520
- overrideMaterial.needsUpdate = true;
1521
-
1522
- }
1672
+ overrideColorNode = overrideMaterial.colorNode;
1673
+ overrideMaterial.colorNode = material.castShadowNode;
1523
1674
 
1524
1675
  }
1525
1676
 
@@ -1534,16 +1685,16 @@ class Renderer {
1534
1685
  if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
1535
1686
 
1536
1687
  material.side = BackSide;
1537
- this._handleObjectFunction( object, material, scene, camera, lightsNode, group, 'backSide' ); // create backSide pass id
1688
+ this._handleObjectFunction( object, material, scene, camera, lightsNode, group, clippingContext, 'backSide' ); // create backSide pass id
1538
1689
 
1539
1690
  material.side = FrontSide;
1540
- this._handleObjectFunction( object, material, scene, camera, lightsNode, group ); // use default pass id
1691
+ this._handleObjectFunction( object, material, scene, camera, lightsNode, group, clippingContext, passId ); // use default pass id
1541
1692
 
1542
1693
  material.side = DoubleSide;
1543
1694
 
1544
1695
  } else {
1545
1696
 
1546
- this._handleObjectFunction( object, material, scene, camera, lightsNode, group );
1697
+ this._handleObjectFunction( object, material, scene, camera, lightsNode, group, clippingContext, passId );
1547
1698
 
1548
1699
  }
1549
1700
 
@@ -1561,9 +1712,9 @@ class Renderer {
1561
1712
 
1562
1713
  }
1563
1714
 
1564
- if ( overrideFragmentNode !== undefined ) {
1715
+ if ( overrideColorNode !== undefined ) {
1565
1716
 
1566
- scene.overrideMaterial.fragmentNode = overrideFragmentNode;
1717
+ scene.overrideMaterial.colorNode = overrideColorNode;
1567
1718
 
1568
1719
  }
1569
1720
 
@@ -1573,9 +1724,9 @@ class Renderer {
1573
1724
 
1574
1725
  }
1575
1726
 
1576
- _renderObjectDirect( object, material, scene, camera, lightsNode, group, passId ) {
1727
+ _renderObjectDirect( object, material, scene, camera, lightsNode, group, clippingContext, passId ) {
1577
1728
 
1578
- const renderObject = this._objects.get( object, material, scene, camera, lightsNode, this._currentRenderContext, passId );
1729
+ const renderObject = this._objects.get( object, material, scene, camera, lightsNode, this._currentRenderContext, clippingContext, passId );
1579
1730
  renderObject.drawRange = object.geometry.drawRange;
1580
1731
  renderObject.group = group;
1581
1732
 
@@ -1614,9 +1765,9 @@ class Renderer {
1614
1765
 
1615
1766
  }
1616
1767
 
1617
- _createObjectPipeline( object, material, scene, camera, lightsNode, passId ) {
1768
+ _createObjectPipeline( object, material, scene, camera, lightsNode, clippingContext, passId ) {
1618
1769
 
1619
- const renderObject = this._objects.get( object, material, scene, camera, lightsNode, this._currentRenderContext, passId );
1770
+ const renderObject = this._objects.get( object, material, scene, camera, lightsNode, this._currentRenderContext, clippingContext, passId );
1620
1771
 
1621
1772
  //
1622
1773
 
@@ -1633,12 +1784,6 @@ class Renderer {
1633
1784
 
1634
1785
  }
1635
1786
 
1636
- get compute() {
1637
-
1638
- return this.computeAsync;
1639
-
1640
- }
1641
-
1642
1787
  get compile() {
1643
1788
 
1644
1789
  return this.compileAsync;