super-three 0.169.0 → 0.170.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 (195) hide show
  1. package/build/three.cjs +989 -1131
  2. package/build/three.module.js +990 -1128
  3. package/build/three.module.min.js +1 -1
  4. package/build/three.webgpu.js +8398 -9842
  5. package/build/three.webgpu.min.js +1 -1
  6. package/build/three.webgpu.nodes.js +8398 -9842
  7. package/build/three.webgpu.nodes.min.js +1 -1
  8. package/examples/jsm/Addons.js +3 -3
  9. package/examples/jsm/animation/MMDAnimationHelper.js +2 -0
  10. package/examples/jsm/animation/MMDPhysics.js +2 -0
  11. package/examples/jsm/controls/TransformControls.js +22 -6
  12. package/examples/jsm/csm/CSM.js +2 -2
  13. package/examples/jsm/csm/CSMFrustum.js +7 -4
  14. package/examples/jsm/csm/CSMHelper.js +2 -0
  15. package/examples/jsm/csm/CSMShadowNode.js +435 -0
  16. package/examples/jsm/curves/NURBSCurve.js +34 -3
  17. package/examples/jsm/exporters/GLTFExporter.js +138 -71
  18. package/examples/jsm/exporters/KTX2Exporter.js +35 -12
  19. package/examples/jsm/exporters/MMDExporter.js +6 -0
  20. package/examples/jsm/exporters/USDZExporter.js +21 -3
  21. package/examples/jsm/geometries/DecalGeometry.js +65 -20
  22. package/examples/jsm/geometries/InstancedPointsGeometry.js +2 -0
  23. package/examples/jsm/helpers/TextureHelperGPU.js +175 -0
  24. package/examples/jsm/interactive/HTMLMesh.js +1 -0
  25. package/examples/jsm/lighting/TiledLighting.js +18 -0
  26. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  27. package/examples/jsm/lines/LineMaterial.js +7 -2
  28. package/examples/jsm/lines/LineSegmentsGeometry.js +2 -0
  29. package/examples/jsm/lines/webgpu/LineSegments2.js +0 -15
  30. package/examples/jsm/lines/webgpu/Wireframe.js +56 -0
  31. package/examples/jsm/loaders/3DMLoader.js +1 -0
  32. package/examples/jsm/loaders/3MFLoader.js +91 -0
  33. package/examples/jsm/loaders/FBXLoader.js +12 -2
  34. package/examples/jsm/loaders/GLTFLoader.js +2 -0
  35. package/examples/jsm/loaders/KTX2Loader.js +140 -49
  36. package/examples/jsm/loaders/LDrawLoader.js +22 -136
  37. package/examples/jsm/loaders/LottieLoader.js +1 -0
  38. package/examples/jsm/loaders/MMDLoader.js +9 -2
  39. package/examples/jsm/materials/LDrawConditionalLineMaterial.js +143 -0
  40. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +114 -0
  41. package/examples/jsm/materials/MeshGouraudMaterial.js +6 -2
  42. package/examples/jsm/math/ColorSpaces.js +76 -0
  43. package/examples/jsm/misc/ProgressiveLightMap.js +52 -40
  44. package/examples/jsm/misc/ProgressiveLightMapGPU.js +293 -0
  45. package/examples/jsm/misc/VolumeSlice.js +1 -0
  46. package/examples/jsm/objects/WaterMesh.js +8 -8
  47. package/examples/jsm/postprocessing/AfterimagePass.js +14 -3
  48. package/examples/jsm/postprocessing/SSRPass.js +6 -0
  49. package/examples/jsm/renderers/CSS2DRenderer.js +6 -3
  50. package/examples/jsm/renderers/CSS3DRenderer.js +7 -4
  51. package/examples/jsm/shaders/FXAAShader.js +225 -224
  52. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  53. package/{src/nodes → examples/jsm/tsl}/display/AfterImageNode.js +17 -20
  54. package/{src/nodes → examples/jsm/tsl}/display/AnaglyphPassNode.js +2 -6
  55. package/{src/nodes → examples/jsm/tsl}/display/AnamorphicNode.js +12 -18
  56. package/{src/nodes → examples/jsm/tsl}/display/BleachBypass.js +1 -3
  57. package/{src/nodes → examples/jsm/tsl}/display/BloomNode.js +11 -40
  58. package/{src/nodes → examples/jsm/tsl}/display/DenoiseNode.js +18 -41
  59. package/{src/nodes → examples/jsm/tsl}/display/DepthOfFieldNode.js +2 -8
  60. package/{src/nodes → examples/jsm/tsl}/display/DotScreenNode.js +2 -9
  61. package/examples/jsm/tsl/display/FXAANode.js +316 -0
  62. package/{src/nodes → examples/jsm/tsl}/display/FilmNode.js +2 -6
  63. package/{src/nodes → examples/jsm/tsl}/display/GTAONode.js +30 -70
  64. package/{src/nodes → examples/jsm/tsl}/display/GaussianBlurNode.js +74 -36
  65. package/examples/jsm/tsl/display/LensflareNode.js +161 -0
  66. package/{src/nodes → examples/jsm/tsl}/display/Lut3DNode.js +1 -4
  67. package/{src/nodes → examples/jsm/tsl}/display/MotionBlur.js +2 -3
  68. package/examples/jsm/tsl/display/OutlineNode.js +434 -0
  69. package/{src/nodes → examples/jsm/tsl}/display/ParallaxBarrierPassNode.js +1 -5
  70. package/{src/nodes → examples/jsm/tsl}/display/PixelationPassNode.js +3 -15
  71. package/{src/nodes → examples/jsm/tsl}/display/RGBShiftNode.js +1 -6
  72. package/examples/jsm/tsl/display/SMAANode.js +620 -0
  73. package/{src/nodes → examples/jsm/tsl}/display/SSAAPassNode.js +10 -25
  74. package/examples/jsm/tsl/display/SSRNode.js +343 -0
  75. package/{src/nodes → examples/jsm/tsl}/display/Sepia.js +1 -2
  76. package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +3 -11
  77. package/{src/nodes → examples/jsm/tsl}/display/StereoCompositePassNode.js +9 -11
  78. package/{src/nodes → examples/jsm/tsl}/display/StereoPassNode.js +10 -11
  79. package/examples/jsm/tsl/display/TRAAPassNode.js +355 -0
  80. package/{src/nodes → examples/jsm/tsl}/display/TransitionNode.js +1 -6
  81. package/examples/jsm/tsl/display/hashBlur.js +24 -0
  82. package/examples/jsm/tsl/lighting/TiledLightsNode.js +392 -0
  83. package/examples/jsm/utils/{TextureUtilsGPU.js → WebGPUTextureUtils.js} +2 -1
  84. package/examples/jsm/webxr/OculusHandPointerModel.js +21 -21
  85. package/examples/jsm/webxr/Text2D.js +6 -6
  86. package/package.json +2 -2
  87. package/src/Three.WebGPU.Nodes.js +4 -0
  88. package/src/Three.WebGPU.js +4 -0
  89. package/src/constants.js +1 -6
  90. package/src/core/BufferGeometry.js +44 -6
  91. package/src/geometries/CylinderGeometry.js +2 -2
  92. package/src/materials/LineBasicMaterial.js +6 -2
  93. package/src/materials/LineDashedMaterial.js +6 -2
  94. package/src/materials/Material.js +14 -1
  95. package/src/materials/MeshBasicMaterial.js +6 -2
  96. package/src/materials/MeshDepthMaterial.js +6 -2
  97. package/src/materials/MeshDistanceMaterial.js +6 -2
  98. package/src/materials/MeshLambertMaterial.js +6 -2
  99. package/src/materials/MeshMatcapMaterial.js +6 -2
  100. package/src/materials/MeshNormalMaterial.js +6 -2
  101. package/src/materials/MeshPhongMaterial.js +6 -2
  102. package/src/materials/MeshPhysicalMaterial.js +6 -2
  103. package/src/materials/MeshStandardMaterial.js +6 -2
  104. package/src/materials/MeshToonMaterial.js +6 -2
  105. package/src/materials/PointsMaterial.js +6 -2
  106. package/src/materials/RawShaderMaterial.js +6 -2
  107. package/src/materials/ShaderMaterial.js +6 -2
  108. package/src/materials/ShadowMaterial.js +6 -2
  109. package/src/materials/SpriteMaterial.js +6 -2
  110. package/src/materials/nodes/NodeMaterial.js +31 -9
  111. package/src/materials/nodes/SpriteNodeMaterial.js +11 -2
  112. package/src/materials/nodes/manager/NodeMaterialObserver.js +111 -2
  113. package/src/math/ColorManagement.js +118 -85
  114. package/src/math/Vector4.js +11 -0
  115. package/src/nodes/Nodes.js +1 -21
  116. package/src/nodes/TSL.js +6 -24
  117. package/src/nodes/accessors/Camera.js +0 -1
  118. package/src/nodes/accessors/SceneNode.js +35 -1
  119. package/src/nodes/accessors/StorageBufferNode.js +32 -10
  120. package/src/nodes/accessors/VelocityNode.js +13 -3
  121. package/src/nodes/code/FunctionCallNode.js +16 -5
  122. package/src/nodes/code/ScriptableNode.js +4 -4
  123. package/src/nodes/core/Node.js +1 -0
  124. package/src/nodes/core/NodeBuilder.js +29 -5
  125. package/src/nodes/core/VarNode.js +15 -3
  126. package/src/nodes/display/ColorAdjustment.js +53 -4
  127. package/src/nodes/display/ColorSpaceFunctions.js +5 -5
  128. package/src/nodes/display/ColorSpaceNode.js +27 -39
  129. package/src/nodes/display/PassNode.js +6 -4
  130. package/src/nodes/display/ToneMappingNode.js +1 -1
  131. package/src/nodes/display/ViewportDepthNode.js +33 -1
  132. package/src/nodes/functions/PhysicalLightingModel.js +21 -15
  133. package/src/nodes/functions/material/getAlphaHashThreshold.js +64 -0
  134. package/src/nodes/functions/material/getGeometryRoughness.js +8 -2
  135. package/src/nodes/functions/material/getParallaxCorrectNormal.js +22 -0
  136. package/src/nodes/gpgpu/ComputeNode.js +9 -1
  137. package/src/nodes/lighting/AnalyticLightNode.js +12 -416
  138. package/src/nodes/lighting/LightsNode.js +24 -12
  139. package/src/nodes/lighting/PointLightNode.js +36 -26
  140. package/src/nodes/lighting/RectAreaLightNode.js +3 -0
  141. package/src/nodes/lighting/ShadowNode.js +484 -0
  142. package/src/nodes/utils/LoopNode.js +2 -2
  143. package/src/nodes/utils/Oscillators.js +6 -0
  144. package/src/nodes/utils/PostProcessingUtils.js +89 -0
  145. package/src/nodes/utils/ReflectorNode.js +101 -15
  146. package/src/nodes/utils/Timer.js +29 -0
  147. package/src/objects/BatchedMesh.js +458 -241
  148. package/src/renderers/WebGLRenderer.js +121 -126
  149. package/src/renderers/common/Attributes.js +4 -0
  150. package/src/renderers/common/Backend.js +2 -0
  151. package/src/renderers/common/Background.js +14 -4
  152. package/src/renderers/common/Bindings.js +3 -2
  153. package/src/renderers/common/Constants.js +2 -1
  154. package/src/renderers/common/Geometries.js +20 -0
  155. package/src/renderers/common/IndirectStorageBufferAttribute.js +15 -0
  156. package/src/renderers/common/Lighting.js +45 -0
  157. package/src/renderers/common/PostProcessingUtils.js +86 -0
  158. package/src/renderers/common/RenderList.js +39 -11
  159. package/src/renderers/common/RenderLists.js +4 -2
  160. package/src/renderers/common/RenderObject.js +18 -1
  161. package/src/renderers/common/Renderer.js +165 -26
  162. package/src/renderers/common/Textures.js +30 -14
  163. package/src/renderers/common/nodes/NodeLibrary.js +1 -14
  164. package/src/renderers/common/nodes/Nodes.js +2 -2
  165. package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
  166. package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
  167. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
  168. package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
  169. package/src/renderers/webgl/WebGLCapabilities.js +0 -7
  170. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
  171. package/src/renderers/webgl/WebGLProgram.js +24 -28
  172. package/src/renderers/webgl/WebGLPrograms.js +5 -2
  173. package/src/renderers/webgl/WebGLState.js +37 -1
  174. package/src/renderers/webgl/WebGLTextures.js +29 -12
  175. package/src/renderers/webgl-fallback/WebGLBackend.js +98 -31
  176. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +2 -7
  177. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +33 -8
  178. package/src/renderers/webgpu/WebGPUBackend.js +105 -25
  179. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +1 -1
  180. package/src/renderers/webgpu/WebGPURenderer.js +1 -1
  181. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +0 -8
  182. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +0 -8
  183. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +10 -20
  184. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +12 -4
  185. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +29 -9
  186. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +24 -6
  187. package/src/renderers/webgpu/utils/WebGPUUtils.js +0 -1
  188. package/src/renderers/webxr/WebXRManager.js +4 -4
  189. package/examples/jsm/cameras/CinematicCamera.js +0 -208
  190. package/src/nodes/display/FXAANode.js +0 -332
  191. package/src/nodes/utils/OscNode.js +0 -85
  192. package/src/nodes/utils/TimerNode.js +0 -97
  193. package/src/renderers/webvr/WebVRManager.js +0 -495
  194. package/src/renderers/webvr/WebVRUtils.js +0 -66
  195. /package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +0 -0
@@ -0,0 +1,86 @@
1
+ import { Color } from '../../math/Color.js';
2
+
3
+ // renderer state
4
+
5
+ export function saveRendererState( renderer, state = {} ) {
6
+
7
+ state.toneMapping = renderer.toneMapping;
8
+ state.toneMappingExposure = renderer.toneMappingExposure;
9
+ state.outputColorSpace = renderer.outputColorSpace;
10
+ state.renderTarget = renderer.getRenderTarget();
11
+ state.activeCubeFace = renderer.getActiveCubeFace();
12
+ state.activeMipmapLevel = renderer.getActiveMipmapLevel();
13
+ state.renderObjectFunction = renderer.getRenderObjectFunction();
14
+ state.pixelRatio = renderer.getPixelRatio();
15
+ state.mrt = renderer.getMRT();
16
+ state.clearColor = renderer.getClearColor( state.clearColor || new Color() );
17
+ state.clearAlpha = renderer.getClearAlpha();
18
+ state.autoClear = renderer.autoClear;
19
+ state.scissorTest = renderer.getScissorTest();
20
+
21
+ return state;
22
+
23
+ }
24
+
25
+ export function resetRendererState( renderer, state ) {
26
+
27
+ state = saveRendererState( renderer, state );
28
+
29
+ renderer.setMRT( null );
30
+ renderer.setRenderObjectFunction( null );
31
+ renderer.setClearColor( 0x000000, 1 );
32
+ renderer.autoClear = true;
33
+
34
+ return state;
35
+
36
+ }
37
+
38
+ export function restoreRendererState( renderer, state ) {
39
+
40
+ renderer.toneMapping = state.toneMapping;
41
+ renderer.toneMappingExposure = state.toneMappingExposure;
42
+ renderer.outputColorSpace = state.outputColorSpace;
43
+ renderer.setRenderTarget( state.renderTarget, state.activeCubeFace, state.activeMipmapLevel );
44
+ renderer.setRenderObjectFunction( state.renderObjectFunction );
45
+ renderer.setPixelRatio( state.pixelRatio );
46
+ renderer.setMRT( state.mrt );
47
+ renderer.setClearColor( state.clearColor, state.clearAlpha );
48
+ renderer.autoClear = state.autoClear;
49
+ renderer.setScissorTest( state.scissorTest );
50
+
51
+ }
52
+
53
+ // renderer and scene state
54
+
55
+ export function saveRendererAndSceneState( renderer, scene, state = {} ) {
56
+
57
+ state = saveRendererState( renderer, state );
58
+ state.background = scene.background;
59
+ state.backgroundNode = scene.backgroundNode;
60
+ state.overrideMaterial = scene.overrideMaterial;
61
+
62
+ return state;
63
+
64
+ }
65
+
66
+ export function resetRendererAndSceneState( renderer, scene, state ) {
67
+
68
+ state = saveRendererAndSceneState( renderer, scene, state );
69
+
70
+ scene.background = null;
71
+ scene.backgroundNode = null;
72
+ scene.overrideMaterial = null;
73
+
74
+ return state;
75
+
76
+ }
77
+
78
+ export function restoreRendererAndSceneState( renderer, scene, state ) {
79
+
80
+ restoreRendererState( renderer, state );
81
+
82
+ scene.background = state.background;
83
+ scene.backgroundNode = state.backgroundNode;
84
+ scene.overrideMaterial = state.overrideMaterial;
85
+
86
+ }
@@ -1,4 +1,4 @@
1
- import { LightsNode } from '../../nodes/Nodes.js';
1
+ import { DoubleSide } from '../../constants.js';
2
2
 
3
3
  function painterSortStable( a, b ) {
4
4
 
@@ -48,20 +48,32 @@ function reversePainterSortStable( a, b ) {
48
48
 
49
49
  }
50
50
 
51
+ function needsDoublePass( material ) {
52
+
53
+ const hasTransmission = material.transmission > 0 || material.transmissionNode;
54
+
55
+ return hasTransmission && material.side === DoubleSide && material.forceSinglePass === false;
56
+
57
+ }
58
+
51
59
  class RenderList {
52
60
 
53
- constructor() {
61
+ constructor( lighting, scene, camera ) {
54
62
 
55
63
  this.renderItems = [];
56
64
  this.renderItemsIndex = 0;
57
65
 
58
66
  this.opaque = [];
67
+ this.transparentDoublePass = [];
59
68
  this.transparent = [];
60
69
  this.bundles = [];
61
70
 
62
- this.lightsNode = new LightsNode( [] );
71
+ this.lightsNode = lighting.getNode( scene, camera );
63
72
  this.lightsArray = [];
64
73
 
74
+ this.scene = scene;
75
+ this.camera = camera;
76
+
65
77
  this.occlusionQueryCount = 0;
66
78
 
67
79
  }
@@ -71,6 +83,7 @@ class RenderList {
71
83
  this.renderItemsIndex = 0;
72
84
 
73
85
  this.opaque.length = 0;
86
+ this.transparentDoublePass.length = 0;
74
87
  this.transparent.length = 0;
75
88
  this.bundles.length = 0;
76
89
 
@@ -126,7 +139,17 @@ class RenderList {
126
139
 
127
140
  if ( object.occlusionTest === true ) this.occlusionQueryCount ++;
128
141
 
129
- ( material.transparent === true || material.transmission > 0 ? this.transparent : this.opaque ).push( renderItem );
142
+ if ( material.transparent === true || material.transmission > 0 ) {
143
+
144
+ if ( needsDoublePass( material ) ) this.transparentDoublePass.push( renderItem );
145
+
146
+ this.transparent.push( renderItem );
147
+
148
+ } else {
149
+
150
+ this.opaque.push( renderItem );
151
+
152
+ }
130
153
 
131
154
  }
132
155
 
@@ -134,7 +157,17 @@ class RenderList {
134
157
 
135
158
  const renderItem = this.getNextRenderItem( object, geometry, material, groupOrder, z, group );
136
159
 
137
- ( material.transparent === true ? this.transparent : this.opaque ).unshift( renderItem );
160
+ if ( material.transparent === true || material.transmission > 0 ) {
161
+
162
+ if ( needsDoublePass( material ) ) this.transparentDoublePass.unshift( renderItem );
163
+
164
+ this.transparent.unshift( renderItem );
165
+
166
+ } else {
167
+
168
+ this.opaque.unshift( renderItem );
169
+
170
+ }
138
171
 
139
172
  }
140
173
 
@@ -150,15 +183,10 @@ class RenderList {
150
183
 
151
184
  }
152
185
 
153
- getLightsNode() {
154
-
155
- return this.lightsNode.fromLights( this.lightsArray );
156
-
157
- }
158
-
159
186
  sort( customOpaqueSort, customTransparentSort ) {
160
187
 
161
188
  if ( this.opaque.length > 1 ) this.opaque.sort( customOpaqueSort || painterSortStable );
189
+ if ( this.transparentDoublePass.length > 1 ) this.transparentDoublePass.sort( customTransparentSort || reversePainterSortStable );
162
190
  if ( this.transparent.length > 1 ) this.transparent.sort( customTransparentSort || reversePainterSortStable );
163
191
 
164
192
  }
@@ -3,7 +3,9 @@ import RenderList from './RenderList.js';
3
3
 
4
4
  class RenderLists {
5
5
 
6
- constructor() {
6
+ constructor( lighting ) {
7
+
8
+ this.lighting = lighting;
7
9
 
8
10
  this.lists = new ChainMap();
9
11
 
@@ -18,7 +20,7 @@ class RenderLists {
18
20
 
19
21
  if ( list === undefined ) {
20
22
 
21
- list = new RenderList();
23
+ list = new RenderList( this.lighting, scene, camera );
22
24
  lists.set( keys, list );
23
25
 
24
26
  }
@@ -150,6 +150,12 @@ export default class RenderObject {
150
150
 
151
151
  }
152
152
 
153
+ getIndirect() {
154
+
155
+ return this._geometries.getIndirect( this );
156
+
157
+ }
158
+
153
159
  getChainArray() {
154
160
 
155
161
  return [ this.object, this.material, this.context, this.lightsNode ];
@@ -233,7 +239,18 @@ export default class RenderObject {
233
239
 
234
240
  }
235
241
 
236
- const itemCount = hasIndex === true ? index.count : geometry.attributes.position.count;
242
+ const position = geometry.attributes.position;
243
+ let itemCount = Infinity;
244
+
245
+ if ( hasIndex ) {
246
+
247
+ itemCount = index.count;
248
+
249
+ } else if ( position !== undefined && position !== null ) {
250
+
251
+ itemCount = position.count;
252
+
253
+ }
237
254
 
238
255
  firstVertex = Math.max( firstVertex, 0 );
239
256
  lastVertex = Math.min( lastVertex, itemCount );
@@ -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
 
@@ -82,11 +83,13 @@ class Renderer {
82
83
  this.info = new Info();
83
84
 
84
85
  this.nodes = {
85
- library: new NodeLibrary(),
86
86
  modelViewMatrix: null,
87
87
  modelNormalViewMatrix: null
88
88
  };
89
89
 
90
+ this.library = new NodeLibrary();
91
+ this.lighting = new Lighting();
92
+
90
93
  // internals
91
94
 
92
95
  this._getFallback = getFallback;
@@ -140,6 +143,9 @@ class Renderer {
140
143
 
141
144
  this._handleObjectFunction = this._renderObjectDirect;
142
145
 
146
+ this._isDeviceLost = false;
147
+ this.onDeviceLost = this._onDeviceLost;
148
+
143
149
  this._initialized = false;
144
150
  this._initPromise = null;
145
151
 
@@ -238,7 +244,7 @@ class Renderer {
238
244
  this._pipelines = new Pipelines( backend, this._nodes );
239
245
  this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info );
240
246
  this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info );
241
- this._renderLists = new RenderLists();
247
+ this._renderLists = new RenderLists( this.lighting );
242
248
  this._bundles = new RenderBundles();
243
249
  this._renderContexts = new RenderContexts();
244
250
 
@@ -262,6 +268,8 @@ class Renderer {
262
268
 
263
269
  async compileAsync( scene, camera, targetScene = null ) {
264
270
 
271
+ if ( this._isDeviceLost === true ) return;
272
+
265
273
  if ( this._initialized === false ) await this.init();
266
274
 
267
275
  // preserve render tree
@@ -367,7 +375,7 @@ class Renderer {
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, 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
@@ -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();
@@ -1250,11 +1311,56 @@ class Renderer {
1250
1311
 
1251
1312
  copyFramebufferToTexture( framebufferTexture, rectangle = null ) {
1252
1313
 
1253
- const renderContext = this._currentRenderContext;
1314
+ if ( rectangle !== null ) {
1254
1315
 
1255
- this._textures.updateTexture( framebufferTexture );
1316
+ if ( rectangle.isVector2 ) {
1256
1317
 
1257
- rectangle = rectangle === null ? _vector4.set( 0, 0, framebufferTexture.image.width, framebufferTexture.image.height ) : rectangle;
1318
+ rectangle = _vector4.set( rectangle.x, rectangle.y, framebufferTexture.image.width, framebufferTexture.image.height ).floor();
1319
+
1320
+ } else if ( rectangle.isVector4 ) {
1321
+
1322
+ rectangle = _vector4.copy( rectangle ).floor();
1323
+
1324
+ } else {
1325
+
1326
+ console.error( 'THREE.Renderer.copyFramebufferToTexture: Invalid rectangle.' );
1327
+
1328
+ return;
1329
+
1330
+ }
1331
+
1332
+ } else {
1333
+
1334
+ rectangle = _vector4.set( 0, 0, framebufferTexture.image.width, framebufferTexture.image.height );
1335
+
1336
+ }
1337
+
1338
+ //
1339
+
1340
+ let renderContext = this._currentRenderContext;
1341
+ let renderTarget;
1342
+
1343
+ if ( renderContext !== null ) {
1344
+
1345
+ renderTarget = renderContext.renderTarget;
1346
+
1347
+ } else {
1348
+
1349
+ renderTarget = this._renderTarget || this._getFrameBufferTarget();
1350
+
1351
+ if ( renderTarget !== null ) {
1352
+
1353
+ this._textures.updateRenderTarget( renderTarget );
1354
+
1355
+ renderContext = this._textures.get( renderTarget );
1356
+
1357
+ }
1358
+
1359
+ }
1360
+
1361
+ //
1362
+
1363
+ this._textures.updateTexture( framebufferTexture, { renderTarget } );
1258
1364
 
1259
1365
  this.backend.copyFramebufferToTexture( framebufferTexture, renderContext, rectangle );
1260
1366
 
@@ -1269,7 +1375,6 @@ class Renderer {
1269
1375
 
1270
1376
  }
1271
1377
 
1272
-
1273
1378
  readRenderTargetPixelsAsync( renderTarget, x, y, width, height, index = 0, faceIndex = 0 ) {
1274
1379
 
1275
1380
  return this.backend.copyTextureToBuffer( renderTarget.textures[ index ], x, y, width, height, faceIndex );
@@ -1405,7 +1510,47 @@ class Renderer {
1405
1510
 
1406
1511
  }
1407
1512
 
1408
- _renderObjects( renderList, camera, scene, lightsNode ) {
1513
+ _renderTransparents( renderList, doublePassList, camera, scene, lightsNode ) {
1514
+
1515
+ if ( doublePassList.length > 0 ) {
1516
+
1517
+ // render back side
1518
+
1519
+ for ( const { material } of doublePassList ) {
1520
+
1521
+ material.side = BackSide;
1522
+
1523
+ }
1524
+
1525
+ this._renderObjects( doublePassList, camera, scene, lightsNode, 'backSide' );
1526
+
1527
+ // render front side
1528
+
1529
+ for ( const { material } of doublePassList ) {
1530
+
1531
+ material.side = FrontSide;
1532
+
1533
+ }
1534
+
1535
+ this._renderObjects( renderList, camera, scene, lightsNode );
1536
+
1537
+ // restore
1538
+
1539
+ for ( const { material } of doublePassList ) {
1540
+
1541
+ material.side = DoubleSide;
1542
+
1543
+ }
1544
+
1545
+ } else {
1546
+
1547
+ this._renderObjects( renderList, camera, scene, lightsNode );
1548
+
1549
+ }
1550
+
1551
+ }
1552
+
1553
+ _renderObjects( renderList, camera, scene, lightsNode, passId = null ) {
1409
1554
 
1410
1555
  // process renderable objects
1411
1556
 
@@ -1439,7 +1584,7 @@ class Renderer {
1439
1584
 
1440
1585
  this.backend.updateViewport( this._currentRenderContext );
1441
1586
 
1442
- this._currentRenderObjectFunction( object, scene, camera2, geometry, material, group, lightsNode );
1587
+ this._currentRenderObjectFunction( object, scene, camera2, geometry, material, group, lightsNode, passId );
1443
1588
 
1444
1589
  }
1445
1590
 
@@ -1447,7 +1592,7 @@ class Renderer {
1447
1592
 
1448
1593
  } else {
1449
1594
 
1450
- this._currentRenderObjectFunction( object, scene, camera, geometry, material, group, lightsNode );
1595
+ this._currentRenderObjectFunction( object, scene, camera, geometry, material, group, lightsNode, passId );
1451
1596
 
1452
1597
  }
1453
1598
 
@@ -1455,7 +1600,7 @@ class Renderer {
1455
1600
 
1456
1601
  }
1457
1602
 
1458
- renderObject( object, scene, camera, geometry, material, group, lightsNode ) {
1603
+ renderObject( object, scene, camera, geometry, material, group, lightsNode, passId = null ) {
1459
1604
 
1460
1605
  let overridePositionNode;
1461
1606
  let overrideFragmentNode;
@@ -1537,13 +1682,13 @@ class Renderer {
1537
1682
  this._handleObjectFunction( object, material, scene, camera, lightsNode, group, 'backSide' ); // create backSide pass id
1538
1683
 
1539
1684
  material.side = FrontSide;
1540
- this._handleObjectFunction( object, material, scene, camera, lightsNode, group ); // use default pass id
1685
+ this._handleObjectFunction( object, material, scene, camera, lightsNode, group, passId ); // use default pass id
1541
1686
 
1542
1687
  material.side = DoubleSide;
1543
1688
 
1544
1689
  } else {
1545
1690
 
1546
- this._handleObjectFunction( object, material, scene, camera, lightsNode, group );
1691
+ this._handleObjectFunction( object, material, scene, camera, lightsNode, group, passId );
1547
1692
 
1548
1693
  }
1549
1694
 
@@ -1633,12 +1778,6 @@ class Renderer {
1633
1778
 
1634
1779
  }
1635
1780
 
1636
- get compute() {
1637
-
1638
- return this.computeAsync;
1639
-
1640
- }
1641
-
1642
1781
  get compile() {
1643
1782
 
1644
1783
  return this.compileAsync;