@plastic-software/three 0.179.0 → 0.180.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 (173) hide show
  1. package/build/three.cjs +166 -106
  2. package/build/three.core.js +112 -20
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +55 -89
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +30 -5
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +2896 -1048
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +2896 -1048
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +1 -1
  13. package/examples/jsm/controls/ArcballControls.js +7 -7
  14. package/examples/jsm/controls/DragControls.js +6 -56
  15. package/examples/jsm/controls/FirstPersonControls.js +2 -2
  16. package/examples/jsm/controls/PointerLockControls.js +0 -8
  17. package/examples/jsm/exporters/GLTFExporter.js +30 -22
  18. package/examples/jsm/exporters/KTX2Exporter.js +4 -2
  19. package/examples/jsm/exporters/PLYExporter.js +1 -1
  20. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  21. package/examples/jsm/lines/Line2.js +3 -3
  22. package/examples/jsm/lines/LineGeometry.js +1 -1
  23. package/examples/jsm/lines/LineSegments2.js +2 -2
  24. package/examples/jsm/lines/Wireframe.js +2 -2
  25. package/examples/jsm/lines/WireframeGeometry2.js +1 -1
  26. package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
  27. package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
  28. package/examples/jsm/loaders/ColladaLoader.js +1 -1
  29. package/examples/jsm/loaders/EXRLoader.js +5 -5
  30. package/examples/jsm/loaders/GLTFLoader.js +9 -5
  31. package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
  32. package/examples/jsm/loaders/HDRLoader.js +486 -0
  33. package/examples/jsm/loaders/KTX2Loader.js +112 -32
  34. package/examples/jsm/loaders/RGBELoader.js +7 -473
  35. package/examples/jsm/loaders/TTFLoader.js +4 -4
  36. package/examples/jsm/loaders/UltraHDRLoader.js +1 -1
  37. package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
  38. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  39. package/examples/jsm/math/ColorSpaces.js +19 -1
  40. package/examples/jsm/math/ConvexHull.js +2 -2
  41. package/examples/jsm/math/Lut.js +2 -2
  42. package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
  43. package/examples/jsm/misc/ProgressiveLightMap.js +1 -1
  44. package/examples/jsm/misc/Volume.js +1 -1
  45. package/examples/jsm/postprocessing/OutlinePass.js +1 -1
  46. package/examples/jsm/postprocessing/SSRPass.js +37 -8
  47. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +1 -1
  48. package/examples/jsm/transpiler/GLSLDecoder.js +22 -19
  49. package/examples/jsm/transpiler/TSLEncoder.js +2 -10
  50. package/examples/jsm/transpiler/WGSLEncoder.js +24 -0
  51. package/examples/jsm/tsl/display/AnamorphicNode.js +27 -4
  52. package/examples/jsm/tsl/display/BloomNode.js +3 -3
  53. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +2 -1
  54. package/examples/jsm/tsl/display/DepthOfFieldNode.js +439 -90
  55. package/examples/jsm/tsl/display/GTAONode.js +8 -0
  56. package/examples/jsm/tsl/display/GaussianBlurNode.js +47 -35
  57. package/examples/jsm/tsl/display/OutlineNode.js +2 -2
  58. package/examples/jsm/tsl/display/SSRNode.js +180 -65
  59. package/examples/jsm/tsl/display/TRAANode.js +1 -1
  60. package/examples/jsm/tsl/display/boxBlur.js +64 -0
  61. package/examples/jsm/tsl/display/hashBlur.js +15 -18
  62. package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
  63. package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
  64. package/examples/jsm/webxr/OculusHandModel.js +1 -1
  65. package/package.json +1 -1
  66. package/src/Three.Core.js +1 -0
  67. package/src/Three.TSL.js +29 -4
  68. package/src/animation/AnimationClip.js +17 -2
  69. package/src/constants.js +11 -3
  70. package/src/core/BufferGeometry.js +2 -2
  71. package/src/extras/TextureUtils.js +2 -1
  72. package/src/extras/lib/earcut.js +1 -1
  73. package/src/lights/webgpu/ProjectorLight.js +1 -1
  74. package/src/materials/Material.js +12 -0
  75. package/src/materials/MeshDistanceMaterial.js +1 -1
  76. package/src/materials/nodes/PointsNodeMaterial.js +81 -28
  77. package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
  78. package/src/materials/nodes/manager/NodeMaterialObserver.js +1 -1
  79. package/src/math/ColorManagement.js +7 -1
  80. package/src/nodes/Nodes.js +3 -0
  81. package/src/nodes/TSL.js +3 -0
  82. package/src/nodes/accessors/BufferNode.js +1 -1
  83. package/src/nodes/accessors/Camera.js +133 -7
  84. package/src/nodes/accessors/ClippingNode.js +6 -5
  85. package/src/nodes/accessors/CubeTextureNode.js +2 -2
  86. package/src/nodes/accessors/InstanceNode.js +3 -1
  87. package/src/nodes/accessors/Object3DNode.js +1 -1
  88. package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
  89. package/src/nodes/accessors/ReferenceNode.js +1 -1
  90. package/src/nodes/accessors/Texture3DNode.js +13 -0
  91. package/src/nodes/accessors/TextureNode.js +71 -19
  92. package/src/nodes/code/FunctionCallNode.js +19 -0
  93. package/src/nodes/code/FunctionNode.js +23 -0
  94. package/src/nodes/core/AssignNode.js +4 -3
  95. package/src/nodes/core/ContextNode.js +24 -0
  96. package/src/nodes/core/Node.js +16 -20
  97. package/src/nodes/core/NodeBuilder.js +48 -14
  98. package/src/nodes/core/NodeFrame.js +1 -1
  99. package/src/nodes/core/NodeUniform.js +1 -1
  100. package/src/nodes/core/NodeUtils.js +1 -2
  101. package/src/nodes/core/StackNode.js +29 -4
  102. package/src/nodes/core/StructNode.js +5 -5
  103. package/src/nodes/core/StructTypeNode.js +1 -0
  104. package/src/nodes/core/SubBuildNode.js +2 -2
  105. package/src/nodes/core/UniformNode.js +16 -9
  106. package/src/nodes/core/VarNode.js +0 -21
  107. package/src/nodes/display/FrontFacingNode.js +4 -8
  108. package/src/nodes/display/PassNode.js +1 -1
  109. package/src/nodes/display/ScreenNode.js +42 -13
  110. package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
  111. package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
  112. package/src/nodes/display/ViewportTextureNode.js +42 -12
  113. package/src/nodes/gpgpu/SubgroupFunctionNode.js +430 -0
  114. package/src/nodes/lighting/LightsNode.js +1 -1
  115. package/src/nodes/math/BitcastNode.js +156 -0
  116. package/src/nodes/math/ConditionalNode.js +18 -2
  117. package/src/nodes/math/MathNode.js +3 -15
  118. package/src/nodes/math/OperatorNode.js +4 -3
  119. package/src/nodes/tsl/TSLCore.js +432 -152
  120. package/src/nodes/utils/JoinNode.js +3 -1
  121. package/src/nodes/utils/MemberNode.js +58 -7
  122. package/src/nodes/utils/RTTNode.js +1 -1
  123. package/src/nodes/utils/ReflectorNode.js +51 -7
  124. package/src/nodes/utils/SampleNode.js +12 -2
  125. package/src/nodes/utils/SplitNode.js +11 -0
  126. package/src/nodes/utils/Timer.js +0 -47
  127. package/src/objects/BatchedMesh.js +2 -2
  128. package/src/objects/LOD.js +1 -1
  129. package/src/objects/Sprite.js +2 -2
  130. package/src/renderers/WebGLRenderer.js +0 -9
  131. package/src/renderers/common/Attributes.js +1 -1
  132. package/src/renderers/common/Backend.js +19 -1
  133. package/src/renderers/common/Bindings.js +2 -0
  134. package/src/renderers/common/ChainMap.js +1 -1
  135. package/src/renderers/common/DataMap.js +1 -1
  136. package/src/renderers/common/Pipelines.js +1 -1
  137. package/src/renderers/common/RenderContext.js +2 -2
  138. package/src/renderers/common/RenderObject.js +14 -2
  139. package/src/renderers/common/Renderer.js +39 -19
  140. package/src/renderers/common/SampledTexture.js +1 -1
  141. package/src/renderers/common/Sampler.js +25 -13
  142. package/src/renderers/common/Textures.js +34 -12
  143. package/src/renderers/common/TimestampQueryPool.js +3 -3
  144. package/src/renderers/common/XRManager.js +35 -19
  145. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  146. package/src/renderers/common/nodes/NodeLibrary.js +5 -5
  147. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  148. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  149. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  150. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  151. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +7 -15
  152. package/src/renderers/shaders/ShaderLib/depth.glsl.js +1 -1
  153. package/src/renderers/webgl/WebGLProgram.js +4 -4
  154. package/src/renderers/webgl/WebGLShadowMap.js +1 -1
  155. package/src/renderers/webgl/WebGLTextures.js +1 -0
  156. package/src/renderers/webgl/WebGLUtils.js +3 -2
  157. package/src/renderers/webgl-fallback/WebGLBackend.js +186 -135
  158. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +110 -17
  159. package/src/renderers/webgl-fallback/utils/WebGLState.js +1 -1
  160. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -3
  161. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -10
  162. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
  163. package/src/renderers/webgpu/WebGPUBackend.js +35 -31
  164. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +124 -34
  165. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -2
  166. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +9 -18
  167. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +114 -25
  168. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +3 -3
  169. package/src/renderers/webxr/WebXRManager.js +39 -24
  170. package/src/textures/ExternalTexture.js +15 -4
  171. package/src/textures/Source.js +1 -1
  172. package/src/textures/VideoTexture.js +0 -3
  173. package/examples/jsm/loaders/RGBMLoader.js +0 -1148
@@ -12,7 +12,7 @@ import { GLFeatureName } from './utils/WebGLConstants.js';
12
12
  import { WebGLBufferRenderer } from './WebGLBufferRenderer.js';
13
13
 
14
14
  import { warnOnce } from '../../utils.js';
15
- import { WebGLCoordinateSystem } from '../../constants.js';
15
+ import { WebGLCoordinateSystem, TimestampQuery } from '../../constants.js';
16
16
  import WebGLTimestampQueryPool from './utils/WebGLTimestampQueryPool.js';
17
17
 
18
18
  /**
@@ -198,7 +198,7 @@ class WebGLBackend extends Backend {
198
198
  * the WebXR device API.
199
199
  *
200
200
  * @private
201
- * @type {WebGLFramebuffer}
201
+ * @type {?WebGLFramebuffer}
202
202
  * @default null
203
203
  */
204
204
  this._xrFramebuffer = null;
@@ -376,14 +376,13 @@ class WebGLBackend extends Backend {
376
376
  /**
377
377
  * Inits a time stamp query for the given render context.
378
378
  *
379
- * @param {RenderContext} renderContext - The render context.
379
+ * @param {string} type - The type of the timestamp query.
380
+ * @param {string} uid - A unique identifier for the timestamp query.
380
381
  */
381
- initTimestampQuery( renderContext ) {
382
+ initTimestampQuery( type, uid ) {
382
383
 
383
384
  if ( ! this.disjoint || ! this.trackTimestamp ) return;
384
385
 
385
- const type = renderContext.isComputeNode ? 'compute' : 'render';
386
-
387
386
  if ( ! this.timestampQueryPool[ type ] ) {
388
387
 
389
388
  // TODO: Variable maxQueries?
@@ -393,11 +392,11 @@ class WebGLBackend extends Backend {
393
392
 
394
393
  const timestampQueryPool = this.timestampQueryPool[ type ];
395
394
 
396
- const baseOffset = timestampQueryPool.allocateQueriesForContext( renderContext );
395
+ const baseOffset = timestampQueryPool.allocateQueriesForContext( uid );
397
396
 
398
397
  if ( baseOffset !== null ) {
399
398
 
400
- timestampQueryPool.beginQuery( renderContext );
399
+ timestampQueryPool.beginQuery( uid );
401
400
 
402
401
  }
403
402
 
@@ -408,16 +407,16 @@ class WebGLBackend extends Backend {
408
407
  /**
409
408
  * Prepares the timestamp buffer.
410
409
  *
411
- * @param {RenderContext} renderContext - The render context.
410
+ * @param {string} type - The type of the timestamp query.
411
+ * @param {string} uid - A unique identifier for the timestamp query.
412
412
  */
413
- prepareTimestampBuffer( renderContext ) {
413
+ prepareTimestampBuffer( type, uid ) {
414
414
 
415
415
  if ( ! this.disjoint || ! this.trackTimestamp ) return;
416
416
 
417
- const type = renderContext.isComputeNode ? 'compute' : 'render';
418
417
  const timestampQueryPool = this.timestampQueryPool[ type ];
419
418
 
420
- timestampQueryPool.endQuery( renderContext );
419
+ timestampQueryPool.endQuery( uid );
421
420
 
422
421
  }
423
422
 
@@ -446,6 +445,10 @@ class WebGLBackend extends Backend {
446
445
 
447
446
  //
448
447
 
448
+ renderContextData.frameCalls = this.renderer.info.render.frameCalls;
449
+
450
+ //
451
+
449
452
  if ( renderContext.viewport ) {
450
453
 
451
454
  this.updateViewport( renderContext );
@@ -467,7 +470,7 @@ class WebGLBackend extends Backend {
467
470
 
468
471
  //
469
472
 
470
- this.initTimestampQuery( renderContext );
473
+ this.initTimestampQuery( TimestampQuery.RENDER, this.getTimestampUID( renderContext ) );
471
474
 
472
475
  renderContextData.previousContext = this._currentContext;
473
476
  this._currentContext = renderContext;
@@ -540,107 +543,8 @@ class WebGLBackend extends Backend {
540
543
  }
541
544
 
542
545
  this._currentContext = previousContext;
543
- const renderTarget = renderContext.renderTarget;
544
-
545
- if ( renderContext.textures !== null && renderTarget ) {
546
-
547
- const renderTargetContextData = this.get( renderTarget );
548
-
549
- if ( renderTarget.samples > 0 && this._useMultisampledExtension( renderTarget ) === false ) {
550
-
551
- const fb = renderTargetContextData.framebuffers[ renderContext.getCacheKey() ];
552
546
 
553
- let mask = gl.COLOR_BUFFER_BIT;
554
-
555
- if ( renderTarget.resolveDepthBuffer ) {
556
-
557
- if ( renderTarget.depthBuffer ) mask |= gl.DEPTH_BUFFER_BIT;
558
- if ( renderTarget.stencilBuffer && renderTarget.resolveStencilBuffer ) mask |= gl.STENCIL_BUFFER_BIT;
559
-
560
- }
561
-
562
- const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer;
563
- const msaaRenderbuffers = renderTargetContextData.msaaRenderbuffers;
564
-
565
- const textures = renderContext.textures;
566
- const isMRT = textures.length > 1;
567
-
568
- state.bindFramebuffer( gl.READ_FRAMEBUFFER, msaaFrameBuffer );
569
- state.bindFramebuffer( gl.DRAW_FRAMEBUFFER, fb );
570
-
571
- if ( isMRT ) {
572
-
573
- // blitFramebuffer() can only copy/resolve the first color attachment of a framebuffer. When using MRT,
574
- // the engine temporarily removes all attachments and then configures each attachment for the resolve.
575
-
576
- for ( let i = 0; i < textures.length; i ++ ) {
577
-
578
- gl.framebufferRenderbuffer( gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.RENDERBUFFER, null );
579
- gl.framebufferTexture2D( gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, null, 0 );
580
-
581
- }
582
-
583
- }
584
-
585
- for ( let i = 0; i < textures.length; i ++ ) {
586
-
587
- if ( isMRT ) {
588
-
589
- // configure attachment for resolve
590
-
591
- const { textureGPU } = this.get( textures[ i ] );
592
-
593
- gl.framebufferRenderbuffer( gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msaaRenderbuffers[ i ] );
594
- gl.framebufferTexture2D( gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureGPU, 0 );
595
-
596
- }
597
-
598
- if ( renderContext.scissor ) {
599
-
600
- const { x, y, width, height } = renderContext.scissorValue;
601
-
602
- const viewY = renderContext.height - height - y;
603
-
604
- gl.blitFramebuffer( x, viewY, x + width, viewY + height, x, viewY, x + width, viewY + height, mask, gl.NEAREST );
605
-
606
- } else {
607
-
608
- gl.blitFramebuffer( 0, 0, renderContext.width, renderContext.height, 0, 0, renderContext.width, renderContext.height, mask, gl.NEAREST );
609
-
610
- }
611
-
612
- }
613
-
614
- if ( isMRT ) {
615
-
616
- // restore attachments
617
-
618
- for ( let i = 0; i < textures.length; i ++ ) {
619
-
620
- const { textureGPU } = this.get( textures[ i ] );
621
-
622
- gl.framebufferRenderbuffer( gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.RENDERBUFFER, msaaRenderbuffers[ i ] );
623
- gl.framebufferTexture2D( gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, textureGPU, 0 );
624
-
625
- }
626
-
627
- }
628
-
629
- if ( this._supportsInvalidateFramebuffer === true ) {
630
-
631
- gl.invalidateFramebuffer( gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray );
632
-
633
- }
634
-
635
- } else if ( renderTarget.resolveDepthBuffer === false && renderTargetContextData.framebuffers ) {
636
-
637
- const fb = renderTargetContextData.framebuffers[ renderContext.getCacheKey() ];
638
- state.bindFramebuffer( gl.DRAW_FRAMEBUFFER, fb );
639
- gl.invalidateFramebuffer( gl.DRAW_FRAMEBUFFER, renderTargetContextData.depthInvalidationArray );
640
-
641
- }
642
-
643
- }
547
+ this._resolveRenderTarget( renderContext );
644
548
 
645
549
  if ( previousContext !== null ) {
646
550
 
@@ -659,7 +563,7 @@ class WebGLBackend extends Backend {
659
563
 
660
564
  }
661
565
 
662
- this.prepareTimestampBuffer( renderContext );
566
+ this.prepareTimestampBuffer( TimestampQuery.RENDER, this.getTimestampUID( renderContext ) );
663
567
 
664
568
  }
665
569
 
@@ -799,9 +703,11 @@ class WebGLBackend extends Backend {
799
703
  * @param {boolean} depth - Whether the depth buffer should be cleared or not.
800
704
  * @param {boolean} stencil - Whether the stencil buffer should be cleared or not.
801
705
  * @param {?Object} [descriptor=null] - The render context of the current set render target.
802
- * @param {boolean} [setFrameBuffer=true] - TODO.
706
+ * @param {boolean} [setFrameBuffer=true] - Controls whether the intermediate framebuffer should be set or not.
707
+ * @param {boolean} [resolveRenderTarget=true] - Controls whether an active render target should be resolved
708
+ * or not. Only relevant for explicit clears.
803
709
  */
804
- clear( color, depth, stencil, descriptor = null, setFrameBuffer = true ) {
710
+ clear( color, depth, stencil, descriptor = null, setFrameBuffer = true, resolveRenderTarget = true ) {
805
711
 
806
712
  const { gl, renderer } = this;
807
713
 
@@ -884,6 +790,8 @@ class WebGLBackend extends Backend {
884
790
 
885
791
  }
886
792
 
793
+ if ( setFrameBuffer && resolveRenderTarget ) this._resolveRenderTarget( descriptor );
794
+
887
795
  }
888
796
 
889
797
  }
@@ -899,9 +807,16 @@ class WebGLBackend extends Backend {
899
807
  beginCompute( computeGroup ) {
900
808
 
901
809
  const { state, gl } = this;
810
+ const computeGroupData = this.get( computeGroup );
811
+
812
+ //
813
+
814
+ computeGroupData.frameCalls = this.renderer.info.compute.frameCalls;
815
+
816
+ //
902
817
 
903
818
  state.bindFramebuffer( gl.FRAMEBUFFER, null );
904
- this.initTimestampQuery( computeGroup );
819
+ this.initTimestampQuery( TimestampQuery.COMPUTE, this.getTimestampUID( computeGroup ) );
905
820
 
906
821
  }
907
822
 
@@ -912,7 +827,7 @@ class WebGLBackend extends Backend {
912
827
  * @param {Node} computeNode - The compute node.
913
828
  * @param {Array<BindGroup>} bindings - The bindings.
914
829
  * @param {ComputePipeline} pipeline - The compute pipeline.
915
- * @param {number|null} [count=null] - The count of compute invocations. If `null`, the count is determined by the compute node.
830
+ * @param {?number} [count=null] - The count of compute invocations. If `null`, the count is determined by the compute node.
916
831
  */
917
832
  compute( computeGroup, computeNode, bindings, pipeline, count = null ) {
918
833
 
@@ -1007,7 +922,7 @@ class WebGLBackend extends Backend {
1007
922
 
1008
923
  gl.disable( gl.RASTERIZER_DISCARD );
1009
924
 
1010
- this.prepareTimestampBuffer( computeGroup );
925
+ this.prepareTimestampBuffer( TimestampQuery.COMPUTE, this.getTimestampUID( computeGroup ) );
1011
926
 
1012
927
  if ( this._currentContext ) {
1013
928
 
@@ -1246,7 +1161,7 @@ class WebGLBackend extends Backend {
1246
1161
  this._currentContext.activeCubeFace = i;
1247
1162
 
1248
1163
  this._setFramebuffer( this._currentContext );
1249
- this.clear( false, true, stencilBuffer, this._currentContext, false );
1164
+ this.clear( false, true, stencilBuffer, this._currentContext, false, false );
1250
1165
 
1251
1166
  }
1252
1167
 
@@ -1845,28 +1760,46 @@ class WebGLBackend extends Backend {
1845
1760
 
1846
1761
  for ( const binding of bindGroup.bindings ) {
1847
1762
 
1763
+ const map = this.get( binding );
1764
+
1848
1765
  if ( binding.isUniformsGroup || binding.isUniformBuffer ) {
1849
1766
 
1850
1767
  const data = binding.buffer;
1851
- const bufferGPU = gl.createBuffer();
1768
+ let { bufferGPU } = this.get( data );
1852
1769
 
1853
- gl.bindBuffer( gl.UNIFORM_BUFFER, bufferGPU );
1854
- gl.bufferData( gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW );
1770
+ if ( bufferGPU === undefined ) {
1855
1771
 
1856
- this.set( binding, {
1857
- index: i ++,
1858
- bufferGPU
1859
- } );
1772
+ // create
1773
+
1774
+ bufferGPU = gl.createBuffer();
1775
+ gl.bindBuffer( gl.UNIFORM_BUFFER, bufferGPU );
1776
+ gl.bufferData( gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW );
1777
+
1778
+ this.set( data, { bufferGPU } );
1779
+
1780
+ } else {
1781
+
1782
+ // update
1783
+
1784
+ gl.bindBuffer( gl.UNIFORM_BUFFER, bufferGPU );
1785
+ gl.bufferSubData( gl.UNIFORM_BUFFER, 0, data );
1786
+
1787
+ }
1788
+
1789
+ map.index = i ++;
1790
+ map.bufferGPU = bufferGPU;
1791
+
1792
+ this.set( binding, map );
1860
1793
 
1861
1794
  } else if ( binding.isSampledTexture ) {
1862
1795
 
1863
1796
  const { textureGPU, glTextureType } = this.get( binding.texture );
1864
1797
 
1865
- this.set( binding, {
1866
- index: t ++,
1867
- textureGPU,
1868
- glTextureType
1869
- } );
1798
+ map.index = t ++;
1799
+ map.textureGPU = textureGPU;
1800
+ map.glTextureType = glTextureType;
1801
+
1802
+ this.set( binding, map );
1870
1803
 
1871
1804
  }
1872
1805
 
@@ -2092,8 +2025,9 @@ class WebGLBackend extends Backend {
2092
2025
  const { textureGPU } = this.get( textures[ 0 ] );
2093
2026
 
2094
2027
  const cubeFace = this.renderer._activeCubeFace;
2028
+ const mipLevel = this.renderer._activeMipmapLevel;
2095
2029
 
2096
- gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, textureGPU, 0 );
2030
+ gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, textureGPU, mipLevel );
2097
2031
 
2098
2032
  } else {
2099
2033
 
@@ -2115,8 +2049,9 @@ class WebGLBackend extends Backend {
2115
2049
  } else if ( isRenderTarget3D || isRenderTargetArray ) {
2116
2050
 
2117
2051
  const layer = this.renderer._activeCubeFace;
2052
+ const mipLevel = this.renderer._activeMipmapLevel;
2118
2053
 
2119
- gl.framebufferTextureLayer( gl.FRAMEBUFFER, attachment, textureData.textureGPU, 0, layer );
2054
+ gl.framebufferTextureLayer( gl.FRAMEBUFFER, attachment, textureData.textureGPU, mipLevel, layer );
2120
2055
 
2121
2056
  } else {
2122
2057
 
@@ -2126,7 +2061,9 @@ class WebGLBackend extends Backend {
2126
2061
 
2127
2062
  } else {
2128
2063
 
2129
- gl.framebufferTexture2D( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0 );
2064
+ const mipLevel = this.renderer._activeMipmapLevel;
2065
+
2066
+ gl.framebufferTexture2D( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, mipLevel );
2130
2067
 
2131
2068
  }
2132
2069
 
@@ -2543,6 +2480,120 @@ class WebGLBackend extends Backend {
2543
2480
 
2544
2481
  }
2545
2482
 
2483
+ /**
2484
+ * The method ensures multisampled render targets are resolved.
2485
+ *
2486
+ * @private
2487
+ * @param {RenderContext} renderContext - The render context.
2488
+ */
2489
+ _resolveRenderTarget( renderContext ) {
2490
+
2491
+ const { gl, state } = this;
2492
+
2493
+ const renderTarget = renderContext.renderTarget;
2494
+
2495
+ if ( renderContext.textures !== null && renderTarget ) {
2496
+
2497
+ const renderTargetContextData = this.get( renderTarget );
2498
+
2499
+ if ( renderTarget.samples > 0 && this._useMultisampledExtension( renderTarget ) === false ) {
2500
+
2501
+ const fb = renderTargetContextData.framebuffers[ renderContext.getCacheKey() ];
2502
+
2503
+ let mask = gl.COLOR_BUFFER_BIT;
2504
+
2505
+ if ( renderTarget.resolveDepthBuffer ) {
2506
+
2507
+ if ( renderTarget.depthBuffer ) mask |= gl.DEPTH_BUFFER_BIT;
2508
+ if ( renderTarget.stencilBuffer && renderTarget.resolveStencilBuffer ) mask |= gl.STENCIL_BUFFER_BIT;
2509
+
2510
+ }
2511
+
2512
+ const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer;
2513
+ const msaaRenderbuffers = renderTargetContextData.msaaRenderbuffers;
2514
+
2515
+ const textures = renderContext.textures;
2516
+ const isMRT = textures.length > 1;
2517
+
2518
+ state.bindFramebuffer( gl.READ_FRAMEBUFFER, msaaFrameBuffer );
2519
+ state.bindFramebuffer( gl.DRAW_FRAMEBUFFER, fb );
2520
+
2521
+ if ( isMRT ) {
2522
+
2523
+ // blitFramebuffer() can only copy/resolve the first color attachment of a framebuffer. When using MRT,
2524
+ // the engine temporarily removes all attachments and then configures each attachment for the resolve.
2525
+
2526
+ for ( let i = 0; i < textures.length; i ++ ) {
2527
+
2528
+ gl.framebufferRenderbuffer( gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.RENDERBUFFER, null );
2529
+ gl.framebufferTexture2D( gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, null, 0 );
2530
+
2531
+ }
2532
+
2533
+ }
2534
+
2535
+ for ( let i = 0; i < textures.length; i ++ ) {
2536
+
2537
+ if ( isMRT ) {
2538
+
2539
+ // configure attachment for resolve
2540
+
2541
+ const { textureGPU } = this.get( textures[ i ] );
2542
+
2543
+ gl.framebufferRenderbuffer( gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msaaRenderbuffers[ i ] );
2544
+ gl.framebufferTexture2D( gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureGPU, 0 );
2545
+
2546
+ }
2547
+
2548
+ if ( renderContext.scissor ) {
2549
+
2550
+ const { x, y, width, height } = renderContext.scissorValue;
2551
+
2552
+ const viewY = renderContext.height - height - y;
2553
+
2554
+ gl.blitFramebuffer( x, viewY, x + width, viewY + height, x, viewY, x + width, viewY + height, mask, gl.NEAREST );
2555
+
2556
+ } else {
2557
+
2558
+ gl.blitFramebuffer( 0, 0, renderContext.width, renderContext.height, 0, 0, renderContext.width, renderContext.height, mask, gl.NEAREST );
2559
+
2560
+ }
2561
+
2562
+ }
2563
+
2564
+ if ( isMRT ) {
2565
+
2566
+ // restore attachments
2567
+
2568
+ for ( let i = 0; i < textures.length; i ++ ) {
2569
+
2570
+ const { textureGPU } = this.get( textures[ i ] );
2571
+
2572
+ gl.framebufferRenderbuffer( gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.RENDERBUFFER, msaaRenderbuffers[ i ] );
2573
+ gl.framebufferTexture2D( gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, textureGPU, 0 );
2574
+
2575
+ }
2576
+
2577
+ }
2578
+
2579
+ if ( this._supportsInvalidateFramebuffer === true ) {
2580
+
2581
+ gl.invalidateFramebuffer( gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray );
2582
+
2583
+ }
2584
+
2585
+ } else if ( renderTarget.resolveDepthBuffer === false && renderTargetContextData.framebuffers ) {
2586
+
2587
+ const fb = renderTargetContextData.framebuffers[ renderContext.getCacheKey() ];
2588
+ state.bindFramebuffer( gl.DRAW_FRAMEBUFFER, fb );
2589
+ gl.invalidateFramebuffer( gl.DRAW_FRAMEBUFFER, renderTargetContextData.depthInvalidationArray );
2590
+
2591
+ }
2592
+
2593
+ }
2594
+
2595
+ }
2596
+
2546
2597
  /**
2547
2598
  * Returns `true` if the `WEBGL_multisampled_render_to_texture` extension
2548
2599
  * should be used when MSAA is enabled.