@plastic-software/three 0.183.3 → 0.184.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 (280) hide show
  1. package/build/three.cjs +783 -290
  2. package/build/three.core.js +372 -110
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +436 -184
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +7 -1
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +2979 -1281
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +2942 -1281
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +11 -0
  13. package/examples/jsm/animation/CCDIKSolver.js +5 -1
  14. package/examples/jsm/controls/ArcballControls.js +4 -1
  15. package/examples/jsm/controls/DragControls.js +2 -2
  16. package/examples/jsm/controls/FirstPersonControls.js +58 -54
  17. package/examples/jsm/controls/FlyControls.js +4 -0
  18. package/examples/jsm/controls/OrbitControls.js +2 -2
  19. package/examples/jsm/controls/TrackballControls.js +2 -2
  20. package/examples/jsm/controls/TransformControls.js +34 -2
  21. package/examples/jsm/csm/CSMShadowNode.js +6 -2
  22. package/examples/jsm/exporters/GLTFExporter.js +21 -5
  23. package/examples/jsm/geometries/TextGeometry.js +18 -0
  24. package/examples/jsm/helpers/LightProbeGridHelper.js +221 -0
  25. package/examples/jsm/inspector/Extension.js +13 -0
  26. package/examples/jsm/inspector/Inspector.js +169 -114
  27. package/examples/jsm/inspector/RendererInspector.js +2 -2
  28. package/examples/jsm/inspector/extensions/extensions.json +6 -0
  29. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +916 -0
  30. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +281 -0
  31. package/examples/jsm/inspector/tabs/Memory.js +128 -0
  32. package/examples/jsm/inspector/tabs/Parameters.js +34 -2
  33. package/examples/jsm/inspector/tabs/Performance.js +2 -2
  34. package/examples/jsm/inspector/tabs/Settings.js +264 -0
  35. package/examples/jsm/inspector/tabs/Timeline.js +1611 -0
  36. package/examples/jsm/inspector/tabs/Viewer.js +105 -3
  37. package/examples/jsm/inspector/ui/Graph.js +2 -2
  38. package/examples/jsm/inspector/ui/List.js +1 -1
  39. package/examples/jsm/inspector/ui/Profiler.js +273 -176
  40. package/examples/jsm/inspector/ui/Style.js +64 -10
  41. package/examples/jsm/inspector/ui/Tab.js +39 -7
  42. package/examples/jsm/inspector/ui/Values.js +39 -2
  43. package/examples/jsm/inspector/ui/utils.js +13 -0
  44. package/examples/jsm/interaction/InteractionManager.js +226 -0
  45. package/examples/jsm/libs/meshopt_decoder.module.js +8 -8
  46. package/examples/jsm/lighting/DynamicLighting.js +82 -0
  47. package/examples/jsm/lighting/LightProbeGrid.js +651 -0
  48. package/examples/jsm/lines/LineMaterial.js +1 -1
  49. package/examples/jsm/loaders/EXRLoader.js +682 -43
  50. package/examples/jsm/loaders/FBXLoader.js +233 -33
  51. package/examples/jsm/loaders/GLTFLoader.js +24 -7
  52. package/examples/jsm/loaders/HDRLoader.js +1 -1
  53. package/examples/jsm/loaders/KTX2Loader.js +8 -2
  54. package/examples/jsm/loaders/LDrawLoader.js +39 -47
  55. package/examples/jsm/loaders/SVGLoader.js +1 -1
  56. package/examples/jsm/loaders/VTKLoader.js +5 -1
  57. package/examples/jsm/loaders/collada/ColladaComposer.js +101 -7
  58. package/examples/jsm/loaders/collada/ColladaParser.js +19 -4
  59. package/examples/jsm/loaders/usd/USDAParser.js +6 -0
  60. package/examples/jsm/loaders/usd/USDCParser.js +26 -0
  61. package/examples/jsm/loaders/usd/USDComposer.js +656 -103
  62. package/examples/jsm/misc/GPUComputationRenderer.js +2 -0
  63. package/examples/jsm/misc/RollerCoaster.js +42 -4
  64. package/examples/jsm/modifiers/TessellateModifier.js +1 -1
  65. package/examples/jsm/objects/Reflector.js +73 -25
  66. package/examples/jsm/objects/Sky.js +14 -2
  67. package/examples/jsm/objects/SkyMesh.js +23 -6
  68. package/examples/jsm/renderers/Projector.js +18 -38
  69. package/examples/jsm/renderers/SVGRenderer.js +6 -25
  70. package/examples/jsm/transpiler/GLSLDecoder.js +2 -2
  71. package/examples/jsm/tsl/WebGLNodesHandler.js +605 -0
  72. package/examples/jsm/tsl/display/AfterImageNode.js +10 -0
  73. package/examples/jsm/tsl/display/AnamorphicNode.js +11 -0
  74. package/examples/jsm/tsl/display/BilateralBlurNode.js +10 -0
  75. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +3 -36
  76. package/examples/jsm/tsl/display/FSR1Node.js +477 -0
  77. package/examples/jsm/tsl/display/GTAONode.js +2 -1
  78. package/examples/jsm/tsl/display/GaussianBlurNode.js +10 -0
  79. package/examples/jsm/tsl/display/GodraysNode.js +2 -11
  80. package/examples/jsm/tsl/display/OutlineNode.js +66 -16
  81. package/examples/jsm/tsl/display/SSGINode.js +0 -4
  82. package/examples/jsm/tsl/display/SharpenNode.js +283 -0
  83. package/examples/jsm/tsl/display/TAAUNode.js +835 -0
  84. package/examples/jsm/tsl/display/TRAANode.js +48 -7
  85. package/examples/jsm/tsl/lighting/DynamicLightsNode.js +300 -0
  86. package/examples/jsm/tsl/lighting/data/AmbientLightDataNode.js +61 -0
  87. package/examples/jsm/tsl/lighting/data/DirectionalLightDataNode.js +111 -0
  88. package/examples/jsm/tsl/lighting/data/HemisphereLightDataNode.js +99 -0
  89. package/examples/jsm/tsl/lighting/data/PointLightDataNode.js +134 -0
  90. package/examples/jsm/tsl/lighting/data/SpotLightDataNode.js +161 -0
  91. package/examples/jsm/tsl/math/Bayer.js +13 -2
  92. package/examples/jsm/utils/BufferGeometryUtils.js +2 -3
  93. package/examples/jsm/utils/ColorUtils.js +76 -0
  94. package/examples/jsm/utils/SkeletonUtils.js +14 -8
  95. package/examples/jsm/webxr/XRHandMeshModel.js +36 -10
  96. package/examples/jsm/webxr/XRHandModelFactory.js +2 -1
  97. package/package.json +4 -4
  98. package/src/Three.Core.js +1 -0
  99. package/src/Three.TSL.js +6 -0
  100. package/src/Three.WebGPU.Nodes.js +3 -0
  101. package/src/Three.WebGPU.js +6 -0
  102. package/src/animation/AnimationAction.js +11 -1
  103. package/src/audio/AudioContext.js +2 -2
  104. package/src/constants.js +1 -1
  105. package/src/core/BufferAttribute.js +13 -1
  106. package/src/core/Clock.js +1 -1
  107. package/src/core/Object3D.js +1 -5
  108. package/src/core/RenderTarget.js +1 -0
  109. package/src/extras/PMREMGenerator.js +1 -1
  110. package/src/extras/curves/CatmullRomCurve3.js +3 -2
  111. package/src/loaders/AudioLoader.js +11 -1
  112. package/src/loaders/DataTextureLoader.js +6 -4
  113. package/src/loaders/FileLoader.js +1 -2
  114. package/src/loaders/ImageBitmapLoader.js +4 -6
  115. package/src/loaders/MaterialLoader.js +1 -1
  116. package/src/loaders/ObjectLoader.js +25 -4
  117. package/src/loaders/nodes/NodeObjectLoader.js +18 -0
  118. package/src/materials/MeshToonMaterial.js +1 -1
  119. package/src/materials/nodes/Line2NodeMaterial.js +27 -0
  120. package/src/materials/nodes/NodeMaterial.js +0 -27
  121. package/src/materials/nodes/manager/NodeMaterialObserver.js +188 -89
  122. package/src/math/Line3.js +3 -0
  123. package/src/math/Matrix2.js +13 -9
  124. package/src/math/Matrix3.js +13 -9
  125. package/src/math/Matrix4.js +13 -9
  126. package/src/math/Plane.js +4 -3
  127. package/src/math/Triangle.js +1 -1
  128. package/src/math/Vector2.js +11 -7
  129. package/src/math/Vector3.js +12 -8
  130. package/src/math/Vector4.js +13 -9
  131. package/src/nodes/Nodes.js +0 -1
  132. package/src/nodes/TSL.js +1 -1
  133. package/src/nodes/accessors/BufferAttributeNode.js +9 -3
  134. package/src/nodes/accessors/CubeTextureNode.js +7 -1
  135. package/src/nodes/accessors/MaterialProperties.js +2 -5
  136. package/src/nodes/accessors/Object3DNode.js +1 -1
  137. package/src/nodes/accessors/ReferenceBaseNode.js +2 -2
  138. package/src/nodes/accessors/ReferenceNode.js +4 -4
  139. package/src/nodes/accessors/SceneProperties.js +2 -8
  140. package/src/nodes/accessors/StorageBufferNode.js +10 -4
  141. package/src/nodes/accessors/StorageTextureNode.js +4 -9
  142. package/src/nodes/accessors/TextureNode.js +10 -2
  143. package/src/nodes/accessors/UniformArrayNode.js +2 -2
  144. package/src/nodes/code/FunctionCallNode.js +1 -1
  145. package/src/nodes/code/FunctionNode.js +1 -1
  146. package/src/nodes/core/ArrayNode.js +1 -1
  147. package/src/nodes/core/AssignNode.js +1 -1
  148. package/src/nodes/core/AttributeNode.js +1 -1
  149. package/src/nodes/core/BypassNode.js +1 -1
  150. package/src/nodes/core/ContextNode.js +1 -1
  151. package/src/nodes/core/IndexNode.js +2 -1
  152. package/src/nodes/core/InputNode.js +1 -1
  153. package/src/nodes/core/InspectorNode.js +1 -1
  154. package/src/nodes/core/IsolateNode.js +1 -1
  155. package/src/nodes/core/Node.js +83 -12
  156. package/src/nodes/core/NodeBuilder.js +117 -16
  157. package/src/nodes/core/NodeUtils.js +1 -1
  158. package/src/nodes/core/OutputStructNode.js +1 -1
  159. package/src/nodes/core/ParameterNode.js +1 -1
  160. package/src/nodes/core/StackNode.js +1 -1
  161. package/src/nodes/core/StructNode.js +1 -1
  162. package/src/nodes/core/StructTypeNode.js +1 -1
  163. package/src/nodes/core/SubBuildNode.js +1 -1
  164. package/src/nodes/core/UniformGroupNode.js +36 -6
  165. package/src/nodes/core/VarNode.js +1 -1
  166. package/src/nodes/core/VaryingNode.js +1 -1
  167. package/src/nodes/display/NormalMapNode.js +2 -2
  168. package/src/nodes/display/PassNode.js +27 -7
  169. package/src/nodes/display/RenderOutputNode.js +4 -4
  170. package/src/nodes/display/ScreenNode.js +1 -1
  171. package/src/nodes/display/ViewportDepthTextureNode.js +11 -15
  172. package/src/nodes/display/ViewportTextureNode.js +18 -7
  173. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +2 -2
  174. package/src/nodes/geometry/RangeNode.js +1 -1
  175. package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
  176. package/src/nodes/gpgpu/BarrierNode.js +9 -0
  177. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
  178. package/src/nodes/gpgpu/ComputeNode.js +69 -44
  179. package/src/nodes/gpgpu/SubgroupFunctionNode.js +1 -1
  180. package/src/nodes/lighting/LightsNode.js +6 -27
  181. package/src/nodes/lighting/ShadowNode.js +24 -2
  182. package/src/nodes/math/BitcastNode.js +1 -1
  183. package/src/nodes/math/ConditionalNode.js +1 -1
  184. package/src/nodes/math/MathNode.js +73 -1
  185. package/src/nodes/math/OperatorNode.js +1 -1
  186. package/src/nodes/math/PackFloatNode.js +1 -1
  187. package/src/nodes/math/UnpackFloatNode.js +1 -1
  188. package/src/nodes/tsl/TSLBase.js +1 -1
  189. package/src/nodes/tsl/TSLCore.js +21 -3
  190. package/src/nodes/utils/ArrayElementNode.js +1 -1
  191. package/src/nodes/utils/ConvertNode.js +1 -1
  192. package/src/nodes/utils/DebugNode.js +1 -1
  193. package/src/nodes/utils/EventNode.js +30 -0
  194. package/src/nodes/utils/FlipNode.js +1 -1
  195. package/src/nodes/utils/FunctionOverloadingNode.js +1 -1
  196. package/src/nodes/utils/JoinNode.js +1 -1
  197. package/src/nodes/utils/MemberNode.js +1 -1
  198. package/src/nodes/utils/Remap.js +48 -0
  199. package/src/nodes/utils/RotateNode.js +1 -1
  200. package/src/nodes/utils/SetNode.js +1 -1
  201. package/src/nodes/utils/SplitNode.js +1 -1
  202. package/src/objects/BatchedMesh.js +17 -2
  203. package/src/objects/InstancedMesh.js +19 -3
  204. package/src/objects/SkinnedMesh.js +26 -9
  205. package/src/renderers/WebGLRenderer.js +148 -49
  206. package/src/renderers/common/Animation.js +3 -3
  207. package/src/renderers/common/Attributes.js +15 -1
  208. package/src/renderers/common/Backend.js +0 -8
  209. package/src/renderers/common/Background.js +2 -2
  210. package/src/renderers/common/BindGroup.js +1 -8
  211. package/src/renderers/common/Bindings.js +2 -2
  212. package/src/renderers/common/ComputePipeline.js +1 -1
  213. package/src/renderers/common/CubeRenderTarget.js +1 -1
  214. package/src/renderers/common/Info.js +333 -4
  215. package/src/renderers/common/InspectorBase.js +6 -1
  216. package/src/renderers/common/Pipelines.js +36 -3
  217. package/src/renderers/common/ReadbackBuffer.js +78 -0
  218. package/src/renderers/common/RenderBundle.js +3 -1
  219. package/src/renderers/common/RenderBundles.js +5 -2
  220. package/src/renderers/common/RenderObject.js +2 -2
  221. package/src/renderers/common/RenderObjects.js +3 -3
  222. package/src/renderers/common/RenderPipeline.js +35 -6
  223. package/src/renderers/common/Renderer.js +232 -53
  224. package/src/renderers/common/Textures.js +72 -3
  225. package/src/renderers/common/UniformsGroup.js +1 -1
  226. package/src/renderers/common/XRManager.js +34 -27
  227. package/src/renderers/common/extras/PMREMGenerator.js +23 -15
  228. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  229. package/src/renderers/common/nodes/NodeManager.js +230 -99
  230. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +20 -0
  231. package/src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl.js +9 -1
  232. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +0 -1
  233. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  234. package/src/renderers/shaders/ShaderChunk/lightprobes_pars_fragment.glsl.js +80 -0
  235. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +8 -0
  236. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +2 -0
  237. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +1 -3
  238. package/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js +7 -0
  239. package/src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl.js +0 -1
  240. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +12 -2
  241. package/src/renderers/shaders/ShaderChunk.js +2 -0
  242. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +1 -2
  243. package/src/renderers/shaders/ShaderLib.js +0 -1
  244. package/src/renderers/shaders/UniformsLib.js +7 -2
  245. package/src/renderers/shaders/UniformsUtils.js +27 -5
  246. package/src/renderers/webgl/WebGLAnimation.js +2 -1
  247. package/src/renderers/webgl/WebGLBackground.js +13 -13
  248. package/src/renderers/webgl/WebGLBufferRenderer.js +0 -32
  249. package/src/renderers/webgl/WebGLCapabilities.js +6 -0
  250. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +0 -32
  251. package/src/renderers/webgl/WebGLMaterials.js +12 -13
  252. package/src/renderers/webgl/WebGLOutput.js +4 -1
  253. package/src/renderers/webgl/WebGLProgram.js +5 -0
  254. package/src/renderers/webgl/WebGLPrograms.js +24 -3
  255. package/src/renderers/webgl/WebGLRenderStates.js +13 -2
  256. package/src/renderers/webgl/WebGLState.js +43 -0
  257. package/src/renderers/webgl/WebGLTextures.js +129 -26
  258. package/src/renderers/webgl/WebGLUniformsGroups.js +19 -0
  259. package/src/renderers/webgl-fallback/WebGLBackend.js +106 -65
  260. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +0 -41
  261. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +29 -51
  262. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +53 -19
  263. package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +25 -0
  264. package/src/renderers/webgl-fallback/utils/WebGLState.js +42 -1
  265. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +63 -50
  266. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +1 -1
  267. package/src/renderers/webgpu/WebGPUBackend.js +160 -146
  268. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +55 -33
  269. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +103 -17
  270. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +1 -1
  271. package/src/renderers/webgpu/utils/WebGPUCapabilities.js +48 -0
  272. package/src/renderers/webgpu/utils/WebGPUConstants.js +8 -0
  273. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +91 -17
  274. package/src/renderers/webgpu/utils/WebGPUUtils.js +18 -2
  275. package/src/renderers/webxr/WebXRController.js +12 -0
  276. package/src/textures/HTMLTexture.js +74 -0
  277. package/src/textures/Source.js +1 -1
  278. package/src/textures/Texture.js +13 -2
  279. package/src/utils.js +23 -1
  280. package/src/nodes/utils/RemapNode.js +0 -125
@@ -11,16 +11,17 @@ import { AddEquation, BackSide, CustomBlending, DepthFormat, DepthStencilFormat,
11
11
  import { DepthTexture } from '../../textures/DepthTexture.js';
12
12
  import { XRRenderTarget } from './XRRenderTarget.js';
13
13
  import { CylinderGeometry } from '../../geometries/CylinderGeometry.js';
14
- import QuadMesh from './QuadMesh.js';
15
- import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
16
14
  import { PlaneGeometry } from '../../geometries/PlaneGeometry.js';
17
15
  import { MeshBasicMaterial } from '../../materials/MeshBasicMaterial.js';
18
16
  import { Mesh } from '../../objects/Mesh.js';
19
17
  import { warn } from '../../utils.js';
18
+ import { renderOutput } from '../../nodes/display/RenderOutputNode.js';
20
19
 
21
20
  const _cameraLPos = /*@__PURE__*/ new Vector3();
22
21
  const _cameraRPos = /*@__PURE__*/ new Vector3();
23
22
 
23
+ const _contextNodeLib = /*@__PURE__*/ new WeakMap();
24
+
24
25
  /**
25
26
  * The XR manager is built on top of the WebXR Device API to
26
27
  * manage XR sessions with `WebGPURenderer`.
@@ -182,8 +183,6 @@ class XRManager extends EventDispatcher {
182
183
  */
183
184
  this._supportsGlBinding = typeof XRWebGLBinding !== 'undefined';
184
185
 
185
- this._frameBufferTargets = null;
186
-
187
186
  /**
188
187
  * Helper function to create native WebXR Layer.
189
188
  *
@@ -830,19 +829,23 @@ class XRManager extends EventDispatcher {
830
829
  const renderer = this._renderer;
831
830
 
832
831
  const wasPresenting = this.isPresenting;
833
- const rendererOutputTarget = renderer.getOutputRenderTarget();
834
- const rendererFramebufferTarget = renderer._frameBufferTarget;
832
+
835
833
  this.isPresenting = false;
836
834
 
837
835
  const rendererSize = new Vector2();
838
836
  renderer.getSize( rendererSize );
839
- const rendererQuad = renderer._quad;
837
+
838
+ const currentRenderTarget = renderer.getRenderTarget();
840
839
 
841
840
  for ( const layer of this._layers ) {
842
841
 
843
842
  layer.renderTarget.isXRRenderTarget = this._session !== null;
844
843
  layer.renderTarget._hasExternalTextures = layer.renderTarget.isXRRenderTarget;
845
844
 
845
+ const currentContextNode = renderer.contextNode;
846
+
847
+ let contextNode;
848
+
846
849
  if ( layer.renderTarget.isXRRenderTarget && this._sessionUsesLayers ) {
847
850
 
848
851
  layer.xrlayer.transform = new XRRigidTransform( layer.plane.getWorldPosition( translationObject ), layer.plane.getWorldQuaternion( quaternionObject ) );
@@ -854,42 +857,46 @@ class XRManager extends EventDispatcher {
854
857
  undefined );
855
858
 
856
859
  renderer._setXRLayerSize( layer.renderTarget.width, layer.renderTarget.height );
857
- renderer.setOutputRenderTarget( layer.renderTarget );
858
- renderer.setRenderTarget( null );
859
- renderer._frameBufferTarget = null;
860
860
 
861
- this._frameBufferTargets || ( this._frameBufferTargets = new WeakMap() );
862
- const { frameBufferTarget, quad } = this._frameBufferTargets.get( layer.renderTarget ) || { frameBufferTarget: null, quad: null };
863
- if ( ! frameBufferTarget ) {
861
+ contextNode = _contextNodeLib.get( currentContextNode );
864
862
 
865
- renderer._quad = new QuadMesh( new NodeMaterial() );
866
- this._frameBufferTargets.set( layer.renderTarget, { frameBufferTarget: renderer._getFrameBufferTarget(), quad: renderer._quad } );
863
+ if ( contextNode === undefined ) {
867
864
 
868
- } else {
865
+ // Apply ToneMapping and OutputColorSpace directly in the material shader
869
866
 
870
- renderer._frameBufferTarget = frameBufferTarget;
871
- renderer._quad = quad;
867
+ contextNode = currentContextNode.context( {
872
868
 
873
- }
869
+ getOutput: ( outputNode ) => {
874
870
 
875
- layer.rendercall();
871
+ return renderOutput( outputNode, renderer.toneMapping, renderer.outputColorSpace );
876
872
 
877
- renderer._frameBufferTarget = null;
873
+ }
874
+
875
+ } );
876
+
877
+ _contextNodeLib.set( currentContextNode, contextNode );
878
+
879
+ }
878
880
 
879
881
  } else {
880
882
 
881
- renderer.setRenderTarget( layer.renderTarget );
882
- layer.rendercall();
883
+ contextNode = currentContextNode;
883
884
 
884
885
  }
885
886
 
887
+ renderer.contextNode = contextNode;
888
+
889
+ renderer.setRenderTarget( layer.renderTarget );
890
+
891
+ layer.rendercall();
892
+
893
+ renderer.contextNode = currentContextNode;
894
+
886
895
  }
887
896
 
888
- renderer.setRenderTarget( null );
889
- renderer.setOutputRenderTarget( rendererOutputTarget );
890
- renderer._frameBufferTarget = rendererFramebufferTarget;
897
+ renderer.setRenderTarget( currentRenderTarget );
891
898
  renderer._setXRLayerSize( rendererSize.x, rendererSize.y );
892
- renderer._quad = rendererQuad;
899
+
893
900
  this.isPresenting = wasPresenting;
894
901
 
895
902
  }
@@ -410,7 +410,7 @@ class PMREMGenerator {
410
410
 
411
411
  this._renderer.setRenderTarget( _oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel );
412
412
  outputTarget.scissorTest = false;
413
- _setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height );
413
+ this._setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height );
414
414
 
415
415
  }
416
416
 
@@ -566,7 +566,7 @@ class PMREMGenerator {
566
566
 
567
567
  const size = this._cubeSize;
568
568
 
569
- _setViewport( cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size );
569
+ this._setViewport( cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size );
570
570
 
571
571
  renderer.render( scene, cubeCamera );
572
572
 
@@ -608,9 +608,7 @@ class PMREMGenerator {
608
608
  mesh.material = material;
609
609
 
610
610
  const size = this._cubeSize;
611
-
612
- _setViewport( cubeUVRenderTarget, 0, 0, 3 * size, 2 * size );
613
-
611
+ this._setViewport( cubeUVRenderTarget, 0, 0, 3 * size, 2 * size );
614
612
  renderer.setRenderTarget( cubeUVRenderTarget );
615
613
  renderer.render( mesh, _flatCamera );
616
614
 
@@ -678,7 +676,7 @@ class PMREMGenerator {
678
676
  ggxUniforms.roughness.value = adjustedRoughness;
679
677
  ggxUniforms.mipInt.value = _lodMax - lodIn; // Sample from input LOD
680
678
 
681
- _setViewport( pingPongRenderTarget, x, y, 3 * outputSize, 2 * outputSize );
679
+ this._setViewport( pingPongRenderTarget, x, y, 3 * outputSize, 2 * outputSize );
682
680
  renderer.setRenderTarget( pingPongRenderTarget );
683
681
  renderer.render( ggxMesh, _flatCamera );
684
682
 
@@ -688,7 +686,7 @@ class PMREMGenerator {
688
686
  ggxUniforms.roughness.value = 0.0; // Direct copy
689
687
  ggxUniforms.mipInt.value = _lodMax - lodOut; // Read from the level we just wrote
690
688
 
691
- _setViewport( cubeUVRenderTarget, x, y, 3 * outputSize, 2 * outputSize );
689
+ this._setViewport( cubeUVRenderTarget, x, y, 3 * outputSize, 2 * outputSize );
692
690
  renderer.setRenderTarget( cubeUVRenderTarget );
693
691
  renderer.render( ggxMesh, _flatCamera );
694
692
 
@@ -814,12 +812,29 @@ class PMREMGenerator {
814
812
  const x = 3 * outputSize * ( lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0 );
815
813
  const y = 4 * ( this._cubeSize - outputSize );
816
814
 
817
- _setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize );
815
+ this._setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize );
818
816
  renderer.setRenderTarget( targetOut );
819
817
  renderer.render( blurMesh, _flatCamera );
820
818
 
821
819
  }
822
820
 
821
+ _setViewport( target, x, y, width, height ) {
822
+
823
+ if ( this._renderer.isWebGLRenderer ) {
824
+
825
+ target.viewport.set( x, target.height - height - y, width, height );
826
+ target.scissor.set( x, target.height - height - y, width, height );
827
+
828
+ } else {
829
+
830
+ target.viewport.set( x, y, width, height );
831
+ target.scissor.set( x, y, width, height );
832
+
833
+ }
834
+
835
+ }
836
+
837
+
823
838
  }
824
839
 
825
840
  function _createPlanes( lodMax ) {
@@ -925,13 +940,6 @@ function _createRenderTarget( width, height ) {
925
940
 
926
941
  }
927
942
 
928
- function _setViewport( target, x, y, width, height ) {
929
-
930
- target.viewport.set( x, y, width, height );
931
- target.scissor.set( x, y, width, height );
932
-
933
- }
934
-
935
943
  function _getMaterial( type ) {
936
944
 
937
945
  const material = new NodeMaterial();
@@ -126,7 +126,7 @@ class NodeBuilderState {
126
126
 
127
127
  if ( shared !== true ) {
128
128
 
129
- const bindingsGroup = new BindGroup( instanceGroup.name, [], instanceGroup.index );
129
+ const bindingsGroup = new BindGroup( instanceGroup.name, [] );
130
130
  bindings.push( bindingsGroup );
131
131
 
132
132
  for ( const instanceBinding of instanceGroup.bindings ) {
@@ -4,14 +4,13 @@ import NodeBuilderState from './NodeBuilderState.js';
4
4
  import NodeMaterial from '../../../materials/nodes/NodeMaterial.js';
5
5
  import { cubeMapNode } from '../../../nodes/utils/CubeMapNode.js';
6
6
  import { NodeFrame, StackTrace } from '../../../nodes/Nodes.js';
7
- import { objectGroup, renderGroup, frameGroup, cubeTexture, texture, texture3D, vec3, fog, rangeFogFactor, densityFogFactor, reference, pmremTexture, screenUV } from '../../../nodes/TSL.js';
7
+ import { renderGroup, cubeTexture, texture, fog, rangeFogFactor, densityFogFactor, reference, pmremTexture, screenUV } from '../../../nodes/TSL.js';
8
8
  import { builtin } from '../../../nodes/accessors/BuiltinNode.js';
9
9
 
10
10
  import { CubeUVReflectionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from '../../../constants.js';
11
11
  import { hashArray } from '../../../nodes/core/NodeUtils.js';
12
12
  import { error } from '../../../utils.js';
13
13
 
14
- const _outputNodeMap = new WeakMap();
15
14
  const _chainKeys = [];
16
15
  const _cacheKeyValues = [];
17
16
 
@@ -76,6 +75,22 @@ class NodeManager extends DataMap {
76
75
  */
77
76
  this.groupsData = new ChainMap();
78
77
 
78
+ /**
79
+ * Queue for pending async builds to limit concurrent compilation.
80
+ *
81
+ * @private
82
+ * @type {Array<Function>}
83
+ */
84
+ this._buildQueue = [];
85
+
86
+ /**
87
+ * Whether an async build is currently in progress.
88
+ *
89
+ * @private
90
+ * @type {boolean}
91
+ */
92
+ this._buildInProgress = false;
93
+
79
94
  /**
80
95
  * A cache for managing node objects of
81
96
  * scene properties like fog or environments.
@@ -95,51 +110,6 @@ class NodeManager extends DataMap {
95
110
  updateGroup( nodeUniformsGroup ) {
96
111
 
97
112
  const groupNode = nodeUniformsGroup.groupNode;
98
- const name = groupNode.name;
99
-
100
- // objectGroup is always updated
101
-
102
- if ( name === objectGroup.name ) return true;
103
-
104
- // renderGroup is updated once per render/compute call
105
-
106
- if ( name === renderGroup.name ) {
107
-
108
- const uniformsGroupData = this.get( nodeUniformsGroup );
109
- const renderId = this.nodeFrame.renderId;
110
-
111
- if ( uniformsGroupData.renderId !== renderId ) {
112
-
113
- uniformsGroupData.renderId = renderId;
114
-
115
- return true;
116
-
117
- }
118
-
119
- return false;
120
-
121
- }
122
-
123
- // frameGroup is updated once per frame
124
-
125
- if ( name === frameGroup.name ) {
126
-
127
- const uniformsGroupData = this.get( nodeUniformsGroup );
128
- const frameId = this.nodeFrame.frameId;
129
-
130
- if ( uniformsGroupData.frameId !== frameId ) {
131
-
132
- uniformsGroupData.frameId = frameId;
133
-
134
- return true;
135
-
136
- }
137
-
138
- return false;
139
-
140
- }
141
-
142
- // other groups are updated just when groupNode.needsUpdate is true
143
113
 
144
114
  _chainKeys[ 0 ] = groupNode;
145
115
  _chainKeys[ 1 ] = nodeUniformsGroup;
@@ -174,13 +144,44 @@ class NodeManager extends DataMap {
174
144
 
175
145
  }
176
146
 
147
+ /**
148
+ * Creates a node builder configured for the given render object and material.
149
+ *
150
+ * @private
151
+ * @param {RenderObject} renderObject - The render object.
152
+ * @param {Material} material - The material to use.
153
+ * @return {NodeBuilder} The configured node builder.
154
+ */
155
+ _createNodeBuilder( renderObject, material ) {
156
+
157
+ const nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer );
158
+ nodeBuilder.scene = renderObject.scene;
159
+ nodeBuilder.material = material;
160
+ nodeBuilder.camera = renderObject.camera;
161
+ nodeBuilder.context.material = material;
162
+ nodeBuilder.lightsNode = renderObject.lightsNode;
163
+ nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );
164
+ nodeBuilder.fogNode = this.getFogNode( renderObject.scene );
165
+ nodeBuilder.clippingContext = renderObject.clippingContext;
166
+
167
+ if ( this.renderer.getOutputRenderTarget() ? this.renderer.getOutputRenderTarget().multiview : false ) {
168
+
169
+ nodeBuilder.enableMultiview();
170
+
171
+ }
172
+
173
+ return nodeBuilder;
174
+
175
+ }
176
+
177
177
  /**
178
178
  * Returns a node builder state for the given render object.
179
179
  *
180
180
  * @param {RenderObject} renderObject - The render object.
181
- * @return {NodeBuilderState} The node builder state.
181
+ * @param {boolean} [useAsync=false] - Whether to use async build with yielding.
182
+ * @return {NodeBuilderState|Promise<NodeBuilderState>} The node builder state (or Promise if async).
182
183
  */
183
- getForRender( renderObject ) {
184
+ getForRender( renderObject, useAsync = false ) {
184
185
 
185
186
  const renderObjectData = this.get( renderObject );
186
187
 
@@ -196,20 +197,37 @@ class NodeManager extends DataMap {
196
197
 
197
198
  if ( nodeBuilderState === undefined ) {
198
199
 
199
- const createNodeBuilder = ( material ) => {
200
+ const buildNodeBuilder = async () => {
201
+
202
+ let nodeBuilder = this._createNodeBuilder( renderObject, renderObject.material );
203
+
204
+ try {
205
+
206
+ if ( useAsync ) {
207
+
208
+ await nodeBuilder.buildAsync();
209
+
210
+ } else {
211
+
212
+ nodeBuilder.build();
213
+
214
+ }
215
+
216
+ } catch ( e ) {
217
+
218
+ nodeBuilder = this._createNodeBuilder( renderObject, new NodeMaterial() );
200
219
 
201
- const nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer );
202
- nodeBuilder.scene = renderObject.scene;
203
- nodeBuilder.material = material;
204
- nodeBuilder.camera = renderObject.camera;
205
- nodeBuilder.context.material = material;
206
- nodeBuilder.lightsNode = renderObject.lightsNode;
207
- nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );
208
- nodeBuilder.fogNode = this.getFogNode( renderObject.scene );
209
- nodeBuilder.clippingContext = renderObject.clippingContext;
210
- if ( this.renderer.getOutputRenderTarget() ? this.renderer.getOutputRenderTarget().multiview : false ) {
220
+ if ( useAsync ) {
211
221
 
212
- nodeBuilder.enableMultiview();
222
+ await nodeBuilder.buildAsync();
223
+
224
+ } else {
225
+
226
+ nodeBuilder.build();
227
+
228
+ }
229
+
230
+ error( 'TSL: ' + e );
213
231
 
214
232
  }
215
233
 
@@ -217,34 +235,52 @@ class NodeManager extends DataMap {
217
235
 
218
236
  };
219
237
 
220
- let nodeBuilder = createNodeBuilder( renderObject.material );
238
+ if ( useAsync ) {
221
239
 
222
- try {
240
+ return buildNodeBuilder().then( ( nodeBuilder ) => {
223
241
 
224
- nodeBuilder.build();
242
+ nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
243
+ nodeBuilderCache.set( cacheKey, nodeBuilderState );
244
+ nodeBuilderState.usedTimes ++;
245
+ renderObjectData.nodeBuilderState = nodeBuilderState;
225
246
 
226
- } catch ( e ) {
247
+ return nodeBuilderState;
227
248
 
228
- nodeBuilder = createNodeBuilder( new NodeMaterial() );
229
- nodeBuilder.build();
249
+ } );
230
250
 
231
- let stackTrace = e.stackTrace;
251
+ } else {
232
252
 
233
- if ( ! stackTrace && e.stack ) {
253
+ // Synchronous path - call buildNodeBuilder but don't await
254
+ let nodeBuilder = this._createNodeBuilder( renderObject, renderObject.material );
234
255
 
235
- // Capture stack trace for JavaScript errors
256
+ try {
236
257
 
237
- stackTrace = new StackTrace( e.stack );
258
+ nodeBuilder.build();
238
259
 
239
- }
260
+ } catch ( e ) {
240
261
 
241
- error( 'TSL: ' + e, stackTrace );
262
+ nodeBuilder = this._createNodeBuilder( renderObject, new NodeMaterial() );
263
+ nodeBuilder.build();
242
264
 
243
- }
265
+ let stackTrace = e.stackTrace;
244
266
 
245
- nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
267
+ if ( ! stackTrace && e.stack ) {
246
268
 
247
- nodeBuilderCache.set( cacheKey, nodeBuilderState );
269
+ // Capture stack trace for JavaScript errors
270
+
271
+ stackTrace = new StackTrace( e.stack );
272
+
273
+ }
274
+
275
+ error( 'TSL: ' + e, stackTrace );
276
+
277
+ }
278
+
279
+ nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
280
+
281
+ nodeBuilderCache.set( cacheKey, nodeBuilderState );
282
+
283
+ }
248
284
 
249
285
  }
250
286
 
@@ -258,6 +294,114 @@ class NodeManager extends DataMap {
258
294
 
259
295
  }
260
296
 
297
+ /**
298
+ * Async version of getForRender() that yields to main thread during build.
299
+ * Use this in compileAsync() to prevent blocking the main thread.
300
+ *
301
+ * @param {RenderObject} renderObject - The render object.
302
+ * @return {Promise<NodeBuilderState>} A promise that resolves to the node builder state.
303
+ */
304
+ getForRenderAsync( renderObject ) {
305
+
306
+ const result = this.getForRender( renderObject, true );
307
+
308
+ // Ensure we always return a Promise (cache hit returns nodeBuilderState directly)
309
+ if ( result.then ) {
310
+
311
+ return result;
312
+
313
+ }
314
+
315
+ return Promise.resolve( result );
316
+
317
+ }
318
+
319
+ /**
320
+ * Returns nodeBuilderState if ready, null if pending async build.
321
+ * Queues async build on first call for cache miss.
322
+ * Use this in render() path to enable non-blocking compilation.
323
+ *
324
+ * @param {RenderObject} renderObject - The render object.
325
+ * @return {?NodeBuilderState} The node builder state, or null if still building.
326
+ */
327
+ getForRenderDeferred( renderObject ) {
328
+
329
+ const renderObjectData = this.get( renderObject );
330
+
331
+ // Already built for this renderObject
332
+ if ( renderObjectData.nodeBuilderState !== undefined ) {
333
+
334
+ return renderObjectData.nodeBuilderState;
335
+
336
+ }
337
+
338
+ // Check cache with stable key
339
+ const cacheKey = this.getForRenderCacheKey( renderObject );
340
+ const nodeBuilderState = this.nodeBuilderCache.get( cacheKey );
341
+
342
+ if ( nodeBuilderState !== undefined ) {
343
+
344
+ // Cache hit - use it
345
+ nodeBuilderState.usedTimes ++;
346
+ renderObjectData.nodeBuilderState = nodeBuilderState;
347
+ return nodeBuilderState;
348
+
349
+ }
350
+
351
+ // Cache miss - check if async build already queued
352
+ if ( renderObjectData.pendingBuild !== true ) {
353
+
354
+ // Mark as pending and add to build queue
355
+ renderObjectData.pendingBuild = true;
356
+
357
+ this._buildQueue.push( () => {
358
+
359
+ return this.getForRenderAsync( renderObject ).then( () => {
360
+
361
+ renderObjectData.pendingBuild = false;
362
+
363
+ } );
364
+
365
+ } );
366
+
367
+ // Start processing queue if not already running
368
+ this._processBuildQueue();
369
+
370
+ }
371
+
372
+ return null; // Not ready
373
+
374
+ }
375
+
376
+ /**
377
+ * Processes the build queue one item at a time.
378
+ * This ensures builds don't all run simultaneously and freeze the main thread.
379
+ *
380
+ * @private
381
+ */
382
+ _processBuildQueue() {
383
+
384
+ if ( this._buildInProgress || this._buildQueue.length === 0 ) {
385
+
386
+ return;
387
+
388
+ }
389
+
390
+ this._buildInProgress = true;
391
+
392
+ const buildFn = this._buildQueue.shift();
393
+
394
+ buildFn().then( () => {
395
+
396
+ this._buildInProgress = false;
397
+
398
+ // Process next item in queue
399
+ this._processBuildQueue();
400
+
401
+ } );
402
+
403
+ }
404
+
261
405
  /**
262
406
  * Deletes the given object from the internal data map
263
407
  *
@@ -269,11 +413,16 @@ class NodeManager extends DataMap {
269
413
  if ( object.isRenderObject ) {
270
414
 
271
415
  const nodeBuilderState = this.get( object ).nodeBuilderState;
272
- nodeBuilderState.usedTimes --;
273
416
 
274
- if ( nodeBuilderState.usedTimes === 0 ) {
417
+ if ( nodeBuilderState !== undefined ) {
418
+
419
+ nodeBuilderState.usedTimes --;
420
+
421
+ if ( nodeBuilderState.usedTimes === 0 ) {
275
422
 
276
- this.nodeBuilderCache.delete( this.getForRenderCacheKey( object ) );
423
+ this.nodeBuilderCache.delete( this.getForRenderCacheKey( object ) );
424
+
425
+ }
277
426
 
278
427
  }
279
428
 
@@ -704,21 +853,6 @@ class NodeManager extends DataMap {
704
853
 
705
854
  }
706
855
 
707
- /**
708
- * Checks if the output configuration (tone mapping and color space) for
709
- * the given target has changed.
710
- *
711
- * @param {Texture} outputTarget - The output target.
712
- * @return {boolean} Whether the output configuration has changed or not.
713
- */
714
- hasOutputChange( outputTarget ) {
715
-
716
- const cacheKey = _outputNodeMap.get( outputTarget );
717
-
718
- return cacheKey !== this.getOutputCacheKey();
719
-
720
- }
721
-
722
856
  /**
723
857
  * Returns a node that represents the output configuration (tone mapping and
724
858
  * color space) for the current target.
@@ -729,14 +863,11 @@ class NodeManager extends DataMap {
729
863
  getOutputNode( outputTarget ) {
730
864
 
731
865
  const renderer = this.renderer;
732
- const cacheKey = this.getOutputCacheKey();
733
866
 
734
867
  const output = outputTarget.isArrayTexture ?
735
- texture3D( outputTarget, vec3( screenUV, builtin( 'gl_ViewID_OVR' ) ) ).renderOutput( renderer.toneMapping, renderer.currentColorSpace ) :
868
+ texture( outputTarget, screenUV ).depth( builtin( 'gl_ViewID_OVR' ) ).renderOutput( renderer.toneMapping, renderer.currentColorSpace ) :
736
869
  texture( outputTarget, screenUV ).renderOutput( renderer.toneMapping, renderer.currentColorSpace );
737
870
 
738
- _outputNodeMap.set( outputTarget, cacheKey );
739
-
740
871
  return output;
741
872
 
742
873
  }
@@ -802,7 +933,7 @@ class NodeManager extends DataMap {
802
933
 
803
934
  /**
804
935
  * Triggers the call of `update()` methods
805
- * for all nodes of the given compute node.
936
+ * for all nodes of the given render object.
806
937
  *
807
938
  * @param {RenderObject} renderObject - The render object.
808
939
  */
@@ -1,4 +1,24 @@
1
1
  export default /* glsl */`
2
+ #ifdef USE_OCTAHEDRAL_NORMALS
3
+
4
+ attribute vec2 normalOctahedral;
5
+
6
+ vec3 decodeOctahedralNormal( vec2 value ) {
7
+
8
+ vec3 normal = vec3( value, 1.0 - abs( value.x ) - abs( value.y ) );
9
+
10
+ if ( normal.z < 0.0 ) {
11
+
12
+ normal.xy = ( 1.0 - abs( normal.yx ) ) * vec2( normal.x >= 0.0 ? 1.0 : - 1.0, normal.y >= 0.0 ? 1.0 : - 1.0 );
13
+
14
+ }
15
+
16
+ return normalize( normal );
17
+
18
+ }
19
+
20
+ #endif
21
+
2
22
  #ifdef USE_BATCHING_MATRIX
3
23
  #if ! defined( GL_ANGLE_multi_draw )
4
24
  #define gl_DrawID _gl_DrawID
@@ -1,5 +1,13 @@
1
1
  export default /* glsl */`
2
- vec3 objectNormal = vec3( normal );
2
+ #ifdef USE_OCTAHEDRAL_NORMALS
3
+
4
+ vec3 objectNormal = decodeOctahedralNormal( normalOctahedral );
5
+
6
+ #else
7
+
8
+ vec3 objectNormal = vec3( normal );
9
+
10
+ #endif
3
11
 
4
12
  #ifdef USE_TANGENT
5
13