@plastic-software/three 0.180.0 → 0.181.2

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 (357) hide show
  1. package/build/three.cjs +944 -487
  2. package/build/three.core.js +506 -327
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +436 -164
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +8 -2
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +3753 -1177
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +3752 -1176
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
  13. package/examples/fonts/MPLUSRounded1c/OFL.txt +91 -0
  14. package/examples/jsm/animation/CCDIKSolver.js +1 -1
  15. package/examples/jsm/controls/ArcballControls.js +1 -1
  16. package/examples/jsm/controls/DragControls.js +1 -1
  17. package/examples/jsm/controls/FirstPersonControls.js +1 -1
  18. package/examples/jsm/controls/FlyControls.js +1 -1
  19. package/examples/jsm/controls/OrbitControls.js +2 -2
  20. package/examples/jsm/controls/PointerLockControls.js +2 -2
  21. package/examples/jsm/controls/TrackballControls.js +1 -1
  22. package/examples/jsm/controls/TransformControls.js +1 -1
  23. package/examples/jsm/effects/AsciiEffect.js +8 -8
  24. package/examples/jsm/exporters/DRACOExporter.js +2 -2
  25. package/examples/jsm/exporters/EXRExporter.js +1 -1
  26. package/examples/jsm/exporters/GLTFExporter.js +3 -3
  27. package/examples/jsm/exporters/USDZExporter.js +9 -2
  28. package/examples/jsm/geometries/DecalGeometry.js +2 -2
  29. package/examples/jsm/geometries/ParametricGeometry.js +1 -1
  30. package/examples/jsm/geometries/TeapotGeometry.js +2 -2
  31. package/examples/jsm/geometries/TextGeometry.js +3 -2
  32. package/examples/jsm/gpgpu/BitonicSort.js +715 -0
  33. package/examples/jsm/helpers/ViewHelper.js +43 -5
  34. package/examples/jsm/inspector/Inspector.js +427 -0
  35. package/examples/jsm/inspector/RendererInspector.js +415 -0
  36. package/examples/jsm/inspector/tabs/Console.js +204 -0
  37. package/examples/jsm/inspector/tabs/Parameters.js +332 -0
  38. package/examples/jsm/inspector/tabs/Performance.js +268 -0
  39. package/examples/jsm/inspector/tabs/Viewer.js +166 -0
  40. package/examples/jsm/inspector/ui/Graph.js +95 -0
  41. package/examples/jsm/inspector/ui/Item.js +170 -0
  42. package/examples/jsm/inspector/ui/List.js +75 -0
  43. package/examples/jsm/inspector/ui/Profiler.js +170 -0
  44. package/examples/jsm/inspector/ui/Style.js +654 -0
  45. package/examples/jsm/inspector/ui/Tab.js +46 -0
  46. package/examples/jsm/inspector/ui/Values.js +423 -0
  47. package/examples/jsm/inspector/ui/utils.js +56 -0
  48. package/examples/jsm/interactive/HTMLMesh.js +6 -10
  49. package/examples/jsm/interactive/InteractiveGroup.js +1 -1
  50. package/examples/jsm/interactive/SelectionBox.js +30 -0
  51. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  52. package/examples/jsm/loaders/3MFLoader.js +1 -1
  53. package/examples/jsm/loaders/ColladaLoader.js +2 -2
  54. package/examples/jsm/loaders/DDSLoader.js +1 -1
  55. package/examples/jsm/loaders/DRACOLoader.js +73 -22
  56. package/examples/jsm/loaders/FBXLoader.js +2 -2
  57. package/examples/jsm/loaders/FontLoader.js +23 -5
  58. package/examples/jsm/loaders/GLTFLoader.js +5 -3
  59. package/examples/jsm/loaders/KTX2Loader.js +28 -21
  60. package/examples/jsm/loaders/KTXLoader.js +2 -2
  61. package/examples/jsm/loaders/LDrawLoader.js +1 -1
  62. package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
  63. package/examples/jsm/loaders/LUTCubeLoader.js +1 -1
  64. package/examples/jsm/loaders/LWOLoader.js +2 -2
  65. package/examples/jsm/loaders/MaterialXLoader.js +22 -5
  66. package/examples/jsm/loaders/OBJLoader.js +1 -1
  67. package/examples/jsm/loaders/PDBLoader.js +1 -1
  68. package/examples/jsm/loaders/SVGLoader.js +2 -2
  69. package/examples/jsm/loaders/UltraHDRLoader.js +1 -1
  70. package/examples/jsm/math/ConvexHull.js +1 -1
  71. package/examples/jsm/math/ImprovedNoise.js +1 -1
  72. package/examples/jsm/math/SimplexNoise.js +1 -1
  73. package/examples/jsm/misc/ProgressiveLightMap.js +9 -3
  74. package/examples/jsm/misc/ProgressiveLightMapGPU.js +7 -1
  75. package/examples/jsm/misc/TubePainter.js +383 -40
  76. package/examples/jsm/modifiers/SimplifyModifier.js +1 -1
  77. package/examples/jsm/objects/ReflectorForSSRPass.js +1 -0
  78. package/examples/jsm/objects/Sky.js +1 -1
  79. package/examples/jsm/objects/SkyMesh.js +1 -1
  80. package/examples/jsm/objects/Water.js +3 -3
  81. package/examples/jsm/objects/WaterMesh.js +6 -6
  82. package/examples/jsm/postprocessing/GlitchPass.js +2 -2
  83. package/examples/jsm/postprocessing/UnrealBloomPass.js +8 -6
  84. package/examples/jsm/renderers/CSS2DRenderer.js +16 -5
  85. package/examples/jsm/renderers/CSS3DRenderer.js +7 -6
  86. package/examples/jsm/renderers/SVGRenderer.js +1 -1
  87. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +1 -1
  88. package/examples/jsm/shaders/AfterimageShader.js +1 -1
  89. package/examples/jsm/shaders/BleachBypassShader.js +1 -1
  90. package/examples/jsm/shaders/BokehShader.js +1 -1
  91. package/examples/jsm/shaders/BokehShader2.js +1 -1
  92. package/examples/jsm/shaders/DotScreenShader.js +1 -1
  93. package/examples/jsm/shaders/FocusShader.js +1 -1
  94. package/examples/jsm/shaders/GTAOShader.js +2 -2
  95. package/examples/jsm/shaders/GodRaysShader.js +1 -1
  96. package/examples/jsm/shaders/KaleidoShader.js +1 -1
  97. package/examples/jsm/shaders/PoissonDenoiseShader.js +2 -2
  98. package/examples/jsm/shaders/SSRShader.js +1 -1
  99. package/examples/jsm/shaders/SepiaShader.js +1 -1
  100. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +1 -1
  101. package/examples/jsm/shaders/TriangleBlurShader.js +1 -1
  102. package/examples/jsm/shaders/VignetteShader.js +1 -1
  103. package/examples/jsm/transpiler/TSLEncoder.js +7 -0
  104. package/examples/jsm/tsl/display/AfterImageNode.js +26 -24
  105. package/examples/jsm/tsl/display/AnamorphicNode.js +2 -1
  106. package/examples/jsm/tsl/display/BloomNode.js +4 -0
  107. package/examples/jsm/tsl/display/DenoiseNode.js +2 -0
  108. package/examples/jsm/tsl/display/DepthOfFieldNode.js +7 -0
  109. package/examples/jsm/tsl/display/GTAONode.js +45 -5
  110. package/examples/jsm/tsl/display/GaussianBlurNode.js +5 -3
  111. package/examples/jsm/tsl/display/OutlineNode.js +11 -0
  112. package/examples/jsm/tsl/display/SSGINode.js +654 -0
  113. package/examples/jsm/tsl/display/SSRNode.js +2 -0
  114. package/examples/jsm/tsl/display/SSSNode.js +488 -0
  115. package/examples/jsm/tsl/display/TRAANode.js +123 -6
  116. package/examples/jsm/tsl/display/boxBlur.js +1 -0
  117. package/examples/jsm/tsl/display/hashBlur.js +1 -0
  118. package/examples/jsm/tsl/lighting/TiledLightsNode.js +21 -1
  119. package/examples/jsm/webxr/XRControllerModelFactory.js +1 -1
  120. package/examples/jsm/webxr/XRHandModelFactory.js +2 -6
  121. package/package.json +5 -10
  122. package/src/Three.Core.js +3 -2
  123. package/src/Three.TSL.js +7 -1
  124. package/src/Three.WebGPU.Nodes.js +2 -0
  125. package/src/Three.WebGPU.js +2 -0
  126. package/src/animation/AnimationClip.js +3 -2
  127. package/src/animation/AnimationMixer.js +3 -3
  128. package/src/animation/AnimationObjectGroup.js +2 -1
  129. package/src/animation/KeyframeTrack.js +7 -6
  130. package/src/animation/PropertyBinding.js +12 -11
  131. package/src/audio/Audio.js +10 -9
  132. package/src/audio/PositionalAudio.js +1 -1
  133. package/src/cameras/OrthographicCamera.js +1 -1
  134. package/src/cameras/PerspectiveCamera.js +1 -1
  135. package/src/cameras/StereoCamera.js +2 -2
  136. package/src/constants.js +1 -1
  137. package/src/core/BufferGeometry.js +8 -8
  138. package/src/core/EventDispatcher.js +1 -1
  139. package/src/core/InterleavedBuffer.js +1 -1
  140. package/src/core/InterleavedBufferAttribute.js +3 -2
  141. package/src/core/Object3D.js +3 -2
  142. package/src/core/Raycaster.js +2 -1
  143. package/src/core/RenderTarget.js +10 -1
  144. package/src/extras/Controls.js +5 -4
  145. package/src/extras/DataUtils.js +2 -1
  146. package/src/extras/Earcut.js +6 -0
  147. package/src/extras/ImageUtils.js +2 -2
  148. package/src/extras/PMREMGenerator.js +268 -55
  149. package/src/extras/core/Curve.js +2 -1
  150. package/src/extras/core/Interpolations.js +7 -1
  151. package/src/extras/core/ShapePath.js +4 -4
  152. package/src/extras/lib/earcut.js +7 -7
  153. package/src/geometries/BoxGeometry.js +1 -0
  154. package/src/geometries/CapsuleGeometry.js +1 -0
  155. package/src/geometries/CircleGeometry.js +1 -0
  156. package/src/geometries/ConeGeometry.js +1 -0
  157. package/src/geometries/CylinderGeometry.js +1 -0
  158. package/src/geometries/DodecahedronGeometry.js +1 -0
  159. package/src/geometries/ExtrudeGeometry.js +8 -6
  160. package/src/geometries/IcosahedronGeometry.js +1 -0
  161. package/src/geometries/LatheGeometry.js +1 -0
  162. package/src/geometries/OctahedronGeometry.js +1 -0
  163. package/src/geometries/PlaneGeometry.js +1 -0
  164. package/src/geometries/RingGeometry.js +1 -0
  165. package/src/geometries/ShapeGeometry.js +1 -0
  166. package/src/geometries/SphereGeometry.js +1 -0
  167. package/src/geometries/TetrahedronGeometry.js +1 -0
  168. package/src/geometries/TorusGeometry.js +1 -0
  169. package/src/geometries/TorusKnotGeometry.js +1 -0
  170. package/src/geometries/TubeGeometry.js +1 -0
  171. package/src/helpers/CameraHelper.js +1 -1
  172. package/src/loaders/AnimationLoader.js +2 -1
  173. package/src/loaders/AudioLoader.js +2 -1
  174. package/src/loaders/BufferGeometryLoader.js +2 -2
  175. package/src/loaders/Cache.js +2 -2
  176. package/src/loaders/DataTextureLoader.js +1 -1
  177. package/src/loaders/FileLoader.js +3 -2
  178. package/src/loaders/ImageBitmapLoader.js +5 -4
  179. package/src/loaders/ImageLoader.js +1 -1
  180. package/src/loaders/Loader.js +3 -3
  181. package/src/loaders/LoadingManager.js +25 -3
  182. package/src/loaders/MaterialLoader.js +3 -2
  183. package/src/loaders/ObjectLoader.js +13 -13
  184. package/src/loaders/TextureLoader.js +1 -1
  185. package/src/loaders/nodes/NodeLoader.js +3 -2
  186. package/src/materials/Material.js +4 -3
  187. package/src/materials/MeshBasicMaterial.js +1 -0
  188. package/src/materials/MeshDepthMaterial.js +1 -0
  189. package/src/materials/MeshLambertMaterial.js +2 -1
  190. package/src/materials/MeshMatcapMaterial.js +22 -0
  191. package/src/materials/MeshNormalMaterial.js +1 -0
  192. package/src/materials/MeshPhongMaterial.js +2 -1
  193. package/src/materials/MeshPhysicalMaterial.js +2 -1
  194. package/src/materials/MeshStandardMaterial.js +8 -7
  195. package/src/materials/MeshToonMaterial.js +1 -0
  196. package/src/materials/PointsMaterial.js +1 -1
  197. package/src/materials/ShaderMaterial.js +2 -2
  198. package/src/materials/nodes/Line2NodeMaterial.js +2 -2
  199. package/src/materials/nodes/MeshSSSNodeMaterial.js +1 -1
  200. package/src/materials/nodes/NodeMaterial.js +62 -22
  201. package/src/materials/nodes/manager/NodeMaterialObserver.js +2 -1
  202. package/src/math/Color.js +6 -5
  203. package/src/math/ColorManagement.js +2 -2
  204. package/src/math/Cylindrical.js +1 -1
  205. package/src/math/Euler.js +2 -1
  206. package/src/math/MathUtils.js +13 -11
  207. package/src/math/Matrix2.js +1 -1
  208. package/src/math/Matrix3.js +2 -2
  209. package/src/math/Matrix4.js +7 -7
  210. package/src/math/Plane.js +1 -1
  211. package/src/math/Quaternion.js +68 -66
  212. package/src/math/Spherical.js +1 -1
  213. package/src/nodes/Nodes.js +1 -1
  214. package/src/nodes/TSL.js +1 -1
  215. package/src/nodes/accessors/CubeTextureNode.js +3 -2
  216. package/src/nodes/accessors/InstanceNode.js +22 -4
  217. package/src/nodes/accessors/Lights.js +10 -0
  218. package/src/nodes/accessors/Normal.js +5 -4
  219. package/src/nodes/accessors/Position.js +18 -2
  220. package/src/nodes/accessors/ReferenceNode.js +2 -1
  221. package/src/nodes/accessors/SceneNode.js +2 -1
  222. package/src/nodes/accessors/StorageBufferNode.js +2 -1
  223. package/src/nodes/accessors/StorageTextureNode.js +22 -0
  224. package/src/nodes/accessors/Texture3DNode.js +1 -1
  225. package/src/nodes/accessors/TextureNode.js +61 -27
  226. package/src/nodes/code/FunctionCallNode.js +5 -4
  227. package/src/nodes/core/ArrayNode.js +1 -0
  228. package/src/nodes/core/AttributeNode.js +2 -1
  229. package/src/nodes/core/ContextNode.js +5 -10
  230. package/src/nodes/core/IndexNode.js +2 -2
  231. package/src/nodes/core/InputNode.js +2 -1
  232. package/src/nodes/core/InspectorNode.js +128 -0
  233. package/src/nodes/core/{CacheNode.js → IsolateNode.js} +40 -7
  234. package/src/nodes/core/Node.js +137 -12
  235. package/src/nodes/core/NodeBuilder.js +135 -21
  236. package/src/nodes/core/NodeFrame.js +20 -20
  237. package/src/nodes/core/NodeFunction.js +2 -1
  238. package/src/nodes/core/NodeParser.js +2 -1
  239. package/src/nodes/core/NodeUtils.js +17 -90
  240. package/src/nodes/core/ParameterNode.js +31 -0
  241. package/src/nodes/core/PropertyNode.js +7 -0
  242. package/src/nodes/core/StackNode.js +16 -14
  243. package/src/nodes/core/UniformNode.js +2 -1
  244. package/src/nodes/core/VarNode.js +70 -12
  245. package/src/nodes/core/VaryingNode.js +3 -2
  246. package/src/nodes/display/BlendModes.js +5 -4
  247. package/src/nodes/display/BumpMapNode.js +1 -1
  248. package/src/nodes/display/ColorAdjustment.js +1 -1
  249. package/src/nodes/display/NormalMapNode.js +2 -1
  250. package/src/nodes/display/PassNode.js +51 -10
  251. package/src/nodes/display/RenderOutputNode.js +28 -2
  252. package/src/nodes/display/ScreenNode.js +2 -1
  253. package/src/nodes/display/ToneMappingNode.js +31 -4
  254. package/src/nodes/display/ToonOutlinePassNode.js +8 -0
  255. package/src/nodes/fog/Fog.js +3 -2
  256. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +52 -0
  257. package/src/nodes/functions/BSDF/DFGApprox.js +60 -19
  258. package/src/nodes/functions/BasicLightingModel.js +2 -1
  259. package/src/nodes/functions/PhysicalLightingModel.js +3 -2
  260. package/src/nodes/functions/VolumetricLightingModel.js +5 -5
  261. package/src/nodes/geometry/RangeNode.js +40 -4
  262. package/src/nodes/gpgpu/ComputeBuiltinNode.js +2 -1
  263. package/src/nodes/gpgpu/ComputeNode.js +17 -5
  264. package/src/nodes/gpgpu/SubgroupFunctionNode.js +25 -0
  265. package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -1
  266. package/src/nodes/lighting/EnvironmentNode.js +6 -6
  267. package/src/nodes/lighting/LightsNode.js +2 -3
  268. package/src/nodes/lighting/PointShadowNode.js +6 -0
  269. package/src/nodes/lighting/ShadowFilterNode.js +2 -0
  270. package/src/nodes/lighting/ShadowNode.js +75 -8
  271. package/src/nodes/math/ConditionalNode.js +6 -5
  272. package/src/nodes/math/MathNode.js +22 -4
  273. package/src/nodes/math/OperatorNode.js +3 -2
  274. package/src/nodes/pmrem/PMREMUtils.js +117 -2
  275. package/src/nodes/shapes/Shapes.js +1 -1
  276. package/src/nodes/tsl/TSLBase.js +5 -2
  277. package/src/nodes/tsl/TSLCore.js +36 -15
  278. package/src/nodes/utils/DebugNode.js +2 -1
  279. package/src/nodes/utils/EventNode.js +36 -0
  280. package/src/nodes/utils/FunctionOverloadingNode.js +37 -19
  281. package/src/nodes/utils/JoinNode.js +3 -2
  282. package/src/nodes/utils/LoopNode.js +20 -24
  283. package/src/nodes/utils/MemberNode.js +2 -1
  284. package/src/nodes/utils/PostProcessingUtils.js +28 -1
  285. package/src/nodes/utils/RTTNode.js +12 -2
  286. package/src/nodes/utils/ReflectorNode.js +10 -3
  287. package/src/objects/Line.js +2 -1
  288. package/src/objects/LineSegments.js +2 -1
  289. package/src/objects/Skeleton.js +3 -2
  290. package/src/objects/SkinnedMesh.js +3 -1
  291. package/src/objects/Sprite.js +2 -1
  292. package/src/renderers/WebGLRenderer.js +49 -33
  293. package/src/renderers/common/Animation.js +13 -1
  294. package/src/renderers/common/Backend.js +93 -30
  295. package/src/renderers/common/Background.js +2 -1
  296. package/src/renderers/common/Bindings.js +56 -2
  297. package/src/renderers/common/CanvasTarget.js +341 -0
  298. package/src/renderers/common/Geometries.js +26 -0
  299. package/src/renderers/common/Info.js +4 -2
  300. package/src/renderers/common/InspectorBase.js +146 -0
  301. package/src/renderers/common/PostProcessing.js +6 -25
  302. package/src/renderers/common/QuadMesh.js +7 -1
  303. package/src/renderers/common/RenderList.js +7 -3
  304. package/src/renderers/common/RenderObject.js +3 -1
  305. package/src/renderers/common/RenderObjects.js +1 -1
  306. package/src/renderers/common/Renderer.js +436 -228
  307. package/src/renderers/common/RendererUtils.js +9 -0
  308. package/src/renderers/common/SampledTexture.js +8 -0
  309. package/src/renderers/common/Sampler.js +37 -11
  310. package/src/renderers/common/StorageTexture.js +9 -1
  311. package/src/renderers/common/Textures.js +89 -35
  312. package/src/renderers/common/TimestampQueryPool.js +63 -1
  313. package/src/renderers/common/UniformsGroup.js +2 -1
  314. package/src/renderers/common/XRManager.js +7 -3
  315. package/src/renderers/common/extras/PMREMGenerator.js +160 -65
  316. package/src/renderers/common/nodes/NodeLibrary.js +4 -2
  317. package/src/renderers/common/nodes/NodeSampler.js +13 -1
  318. package/src/renderers/common/nodes/Nodes.js +38 -16
  319. package/src/renderers/shaders/DFGLUTData.js +64 -0
  320. package/src/renderers/shaders/ShaderChunk/common.glsl.js +0 -12
  321. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -1
  322. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +1 -1
  323. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +52 -18
  324. package/src/renderers/shaders/UniformsLib.js +1 -0
  325. package/src/renderers/shaders/UniformsUtils.js +25 -4
  326. package/src/renderers/webgl/WebGLCapabilities.js +2 -1
  327. package/src/renderers/webgl/WebGLExtensions.js +2 -25
  328. package/src/renderers/webgl/WebGLInfo.js +3 -1
  329. package/src/renderers/webgl/WebGLProgram.js +11 -10
  330. package/src/renderers/webgl/WebGLPrograms.js +2 -1
  331. package/src/renderers/webgl/WebGLShadowMap.js +2 -1
  332. package/src/renderers/webgl/WebGLState.js +15 -14
  333. package/src/renderers/webgl/WebGLTextures.js +18 -14
  334. package/src/renderers/webgl/WebGLUniformsGroups.js +5 -3
  335. package/src/renderers/webgl-fallback/WebGLBackend.js +22 -41
  336. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +74 -11
  337. package/src/renderers/webgl-fallback/utils/WebGLConstants.js +2 -3
  338. package/src/renderers/webgl-fallback/utils/WebGLState.js +6 -5
  339. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +117 -16
  340. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +42 -12
  341. package/src/renderers/webgpu/WebGPUBackend.js +134 -108
  342. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +2 -1
  343. package/src/renderers/webgpu/WebGPURenderer.js +3 -2
  344. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +21 -19
  345. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +2 -1
  346. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +5 -3
  347. package/src/renderers/webgpu/utils/WebGPUConstants.js +5 -0
  348. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +44 -16
  349. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +6 -8
  350. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +146 -74
  351. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +29 -6
  352. package/src/renderers/webgpu/utils/WebGPUUtils.js +22 -2
  353. package/src/renderers/webxr/WebXRManager.js +3 -2
  354. package/src/textures/Source.js +2 -1
  355. package/src/textures/Texture.js +3 -2
  356. package/src/textures/VideoTexture.js +2 -0
  357. package/src/utils.js +67 -3
@@ -1,11 +1,11 @@
1
1
  import NodeMaterial from '../../../materials/nodes/NodeMaterial.js';
2
- import { getDirection, blur } from '../../../nodes/pmrem/PMREMUtils.js';
2
+ import { getDirection, blur, ggxConvolution } from '../../../nodes/pmrem/PMREMUtils.js';
3
3
  import { equirectUV } from '../../../nodes/utils/EquirectUV.js';
4
4
  import { uniform } from '../../../nodes/core/UniformNode.js';
5
5
  import { uniformArray } from '../../../nodes/accessors/UniformArrayNode.js';
6
6
  import { texture } from '../../../nodes/accessors/TextureNode.js';
7
7
  import { cubeTexture } from '../../../nodes/accessors/CubeTextureNode.js';
8
- import { float, vec3 } from '../../../nodes/tsl/TSLBase.js';
8
+ import { float, uint, vec3 } from '../../../nodes/tsl/TSLBase.js';
9
9
  import { uv } from '../../../nodes/accessors/UV.js';
10
10
  import { attribute } from '../../../nodes/core/AttributeNode.js';
11
11
 
@@ -30,19 +30,22 @@ import {
30
30
  BackSide,
31
31
  LinearSRGBColorSpace
32
32
  } from '../../../constants.js';
33
+ import { warn, error, warnOnce } from '../../../utils.js';
33
34
 
34
35
  const LOD_MIN = 4;
35
36
 
36
- // The standard deviations (radians) associated with the extra mips. These are
37
- // chosen to approximate a Trowbridge-Reitz distribution function times the
38
- // geometric shadowing function. These sigma values squared must match the
39
- // variance #defines in cube_uv_reflection_fragment.glsl.js.
37
+ // The standard deviations (radians) associated with the extra mips.
38
+ // Used for scene blur in fromScene() method.
40
39
  const EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ];
41
40
 
42
41
  // The maximum length of the blur for loop. Smaller sigmas will use fewer
43
42
  // samples and exit early, but not recompile the shader.
43
+ // Used for scene blur in fromScene() method.
44
44
  const MAX_SAMPLES = 20;
45
45
 
46
+ // GGX VNDF importance sampling configuration
47
+ const GGX_SAMPLES = 512;
48
+
46
49
  const _flatCamera = /*@__PURE__*/ new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
47
50
  const _cubeCamera = /*@__PURE__*/ new PerspectiveCamera( 90, 1 );
48
51
  const _clearColor = /*@__PURE__*/ new Color();
@@ -50,25 +53,6 @@ let _oldTarget = null;
50
53
  let _oldActiveCubeFace = 0;
51
54
  let _oldActiveMipmapLevel = 0;
52
55
 
53
- // Golden Ratio
54
- const PHI = ( 1 + Math.sqrt( 5 ) ) / 2;
55
- const INV_PHI = 1 / PHI;
56
-
57
- // Vertices of a dodecahedron (except the opposites, which represent the
58
- // same axis), used as axis directions evenly spread on a sphere.
59
- const _axisDirections = [
60
- /*@__PURE__*/ new Vector3( - PHI, INV_PHI, 0 ),
61
- /*@__PURE__*/ new Vector3( PHI, INV_PHI, 0 ),
62
- /*@__PURE__*/ new Vector3( - INV_PHI, 0, PHI ),
63
- /*@__PURE__*/ new Vector3( INV_PHI, 0, PHI ),
64
- /*@__PURE__*/ new Vector3( 0, PHI, - INV_PHI ),
65
- /*@__PURE__*/ new Vector3( 0, PHI, INV_PHI ),
66
- /*@__PURE__*/ new Vector3( - 1, 1, - 1 ),
67
- /*@__PURE__*/ new Vector3( 1, 1, - 1 ),
68
- /*@__PURE__*/ new Vector3( - 1, 1, 1 ),
69
- /*@__PURE__*/ new Vector3( 1, 1, 1 )
70
- ];
71
-
72
56
  const _origin = /*@__PURE__*/ new Vector3();
73
57
 
74
58
  // maps blur materials to their uniforms dictionary
@@ -95,9 +79,11 @@ const _outputDirection = /*@__PURE__*/ vec3( _direction.x, _direction.y, _direct
95
79
  * higher roughness levels. In this way we maintain resolution to smoothly
96
80
  * interpolate diffuse lighting while limiting sampling computation.
97
81
  *
98
- * Paper: Fast, Accurate Image-Based Lighting:
99
- * {@link https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view}
100
- */
82
+ * The prefiltering uses GGX VNDF (Visible Normal Distribution Function)
83
+ * importance sampling based on "Sampling the GGX Distribution of Visible Normals"
84
+ * (Heitz, 2018) to generate environment maps that accurately match the GGX BRDF
85
+ * used in material rendering for physically-based image-based lighting.
86
+ */
101
87
  class PMREMGenerator {
102
88
 
103
89
  /**
@@ -112,12 +98,13 @@ class PMREMGenerator {
112
98
 
113
99
  this._lodMax = 0;
114
100
  this._cubeSize = 0;
115
- this._lodPlanes = [];
116
101
  this._sizeLods = [];
117
102
  this._sigmas = [];
118
103
  this._lodMeshes = [];
119
104
 
120
105
  this._blurMaterial = null;
106
+ this._ggxMaterial = null;
107
+
121
108
  this._cubemapMaterial = null;
122
109
  this._equirectMaterial = null;
123
110
  this._backgroundBox = null;
@@ -145,7 +132,7 @@ class PMREMGenerator {
145
132
  * @param {Vector3} [options.renderTarget=origin] - The position of the internal cube camera that renders the scene.
146
133
  * @param {?RenderTarget} [options.renderTarget=null] - The render target to use.
147
134
  * @return {RenderTarget} The resulting PMREM.
148
- * @see {@link PMREMGenerator#fromSceneAsync}
135
+ * @see {@link PMREMGenerator#fromScene}
149
136
  */
150
137
  fromScene( scene, sigma = 0, near = 0.1, far = 100, options = {} ) {
151
138
 
@@ -159,7 +146,7 @@ class PMREMGenerator {
159
146
 
160
147
  if ( this._hasInitialized === false ) {
161
148
 
162
- console.warn( 'THREE.PMREMGenerator: .fromScene() called before the backend is initialized. Try using .fromSceneAsync() instead.' );
149
+ warn( 'PMREMGenerator: ".fromScene()" called before the backend is initialized. Try using "await renderer.init()" instead.' );
163
150
 
164
151
  const cubeUVRenderTarget = renderTarget || this._allocateTarget();
165
152
 
@@ -203,6 +190,7 @@ class PMREMGenerator {
203
190
  * and far planes ensure the scene is rendered in its entirety (the cubeCamera
204
191
  * is placed at the origin).
205
192
  *
193
+ * @deprecated
206
194
  * @param {Scene} scene - The scene to be captured.
207
195
  * @param {number} [sigma=0] - The blur radius in radians.
208
196
  * @param {number} [near=0.1] - The near plane distance.
@@ -216,7 +204,9 @@ class PMREMGenerator {
216
204
  */
217
205
  async fromSceneAsync( scene, sigma = 0, near = 0.1, far = 100, options = {} ) {
218
206
 
219
- if ( this._hasInitialized === false ) await this._renderer.init();
207
+ warnOnce( 'PMREMGenerator: ".fromSceneAsync()" is deprecated. Use "await renderer.init()" instead.' ); // @deprecated r181
208
+
209
+ await this._renderer.init();
220
210
 
221
211
  return this.fromScene( scene, sigma, near, far, options );
222
212
 
@@ -236,7 +226,7 @@ class PMREMGenerator {
236
226
 
237
227
  if ( this._hasInitialized === false ) {
238
228
 
239
- console.warn( 'THREE.PMREMGenerator: .fromEquirectangular() called before the backend is initialized. Try using .fromEquirectangularAsync() instead.' );
229
+ warn( 'PMREMGenerator: .fromEquirectangular() called before the backend is initialized. Try using "await renderer.init()" instead.' );
240
230
 
241
231
  this._setSizeFromTexture( equirectangular );
242
232
 
@@ -257,6 +247,7 @@ class PMREMGenerator {
257
247
  * or HDR. The ideal input image size is 1k (1024 x 512),
258
248
  * as this matches best with the 256 x 256 cubemap output.
259
249
  *
250
+ * @deprecated
260
251
  * @param {Texture} equirectangular - The equirectangular texture to be converted.
261
252
  * @param {?RenderTarget} [renderTarget=null] - The render target to use.
262
253
  * @return {Promise<RenderTarget>} The resulting PMREM.
@@ -264,7 +255,9 @@ class PMREMGenerator {
264
255
  */
265
256
  async fromEquirectangularAsync( equirectangular, renderTarget = null ) {
266
257
 
267
- if ( this._hasInitialized === false ) await this._renderer.init();
258
+ warnOnce( 'PMREMGenerator: ".fromEquirectangularAsync()" is deprecated. Use "await renderer.init()" instead.' ); // @deprecated r181
259
+
260
+ await this._renderer.init();
268
261
 
269
262
  return this._fromTexture( equirectangular, renderTarget );
270
263
 
@@ -284,7 +277,7 @@ class PMREMGenerator {
284
277
 
285
278
  if ( this._hasInitialized === false ) {
286
279
 
287
- console.warn( 'THREE.PMREMGenerator: .fromCubemap() called before the backend is initialized. Try using .fromCubemapAsync() instead.' );
280
+ warn( 'PMREMGenerator: .fromCubemap() called before the backend is initialized. Try using .fromCubemapAsync() instead.' );
288
281
 
289
282
  this._setSizeFromTexture( cubemap );
290
283
 
@@ -305,6 +298,7 @@ class PMREMGenerator {
305
298
  * or HDR. The ideal input cube size is 256 x 256,
306
299
  * with the 256 x 256 cubemap output.
307
300
  *
301
+ * @deprecated
308
302
  * @param {Texture} cubemap - The cubemap texture to be converted.
309
303
  * @param {?RenderTarget} [renderTarget=null] - The render target to use.
310
304
  * @return {Promise<RenderTarget>} The resulting PMREM.
@@ -312,7 +306,9 @@ class PMREMGenerator {
312
306
  */
313
307
  async fromCubemapAsync( cubemap, renderTarget = null ) {
314
308
 
315
- if ( this._hasInitialized === false ) await this._renderer.init();
309
+ warnOnce( 'PMREMGenerator: ".fromCubemapAsync()" is deprecated. Use "await renderer.init()" instead.' ); // @deprecated r181
310
+
311
+ await this._renderer.init();
316
312
 
317
313
  return this._fromTexture( cubemap, renderTarget );
318
314
 
@@ -398,12 +394,13 @@ class PMREMGenerator {
398
394
  _dispose() {
399
395
 
400
396
  if ( this._blurMaterial !== null ) this._blurMaterial.dispose();
397
+ if ( this._ggxMaterial !== null ) this._ggxMaterial.dispose();
401
398
 
402
399
  if ( this._pingPongRenderTarget !== null ) this._pingPongRenderTarget.dispose();
403
400
 
404
- for ( let i = 0; i < this._lodPlanes.length; i ++ ) {
401
+ for ( let i = 0; i < this._lodMeshes.length; i ++ ) {
405
402
 
406
- this._lodPlanes[ i ].dispose();
403
+ this._lodMeshes[ i ].geometry.dispose();
407
404
 
408
405
  }
409
406
 
@@ -459,7 +456,7 @@ class PMREMGenerator {
459
456
  this._pingPongRenderTarget = _createRenderTarget( renderTarget.width, renderTarget.height );
460
457
 
461
458
  const { _lodMax } = this;
462
- ( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas, lodMeshes: this._lodMeshes } = _createPlanes( _lodMax ) );
459
+ ( { lodMeshes: this._lodMeshes, sizeLods: this._sizeLods, sigmas: this._sigmas } = _createPlanes( _lodMax ) );
463
460
 
464
461
  this._blurMaterial = _getBlurShader( _lodMax, renderTarget.width, renderTarget.height );
465
462
 
@@ -469,8 +466,8 @@ class PMREMGenerator {
469
466
 
470
467
  async _compileMaterial( material ) {
471
468
 
472
- const tmpMesh = new Mesh( this._lodPlanes[ 0 ], material );
473
- await this._renderer.compile( tmpMesh, _flatCamera );
469
+ const mesh = new Mesh( new BufferGeometry(), material );
470
+ await this._renderer.compile( mesh, _flatCamera );
474
471
 
475
472
  }
476
473
 
@@ -492,29 +489,32 @@ class PMREMGenerator {
492
489
 
493
490
  renderer.autoClear = false;
494
491
 
495
- let backgroundBox = this._backgroundBox;
492
+ if ( this._backgroundBox === null ) {
496
493
 
497
- if ( backgroundBox === null ) {
498
-
499
- const backgroundMaterial = new MeshBasicMaterial( {
500
- name: 'PMREM.Background',
501
- side: BackSide,
502
- depthWrite: false,
503
- depthTest: false
504
- } );
505
-
506
- backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial );
494
+ this._backgroundBox = new Mesh(
495
+ new BoxGeometry(),
496
+ new MeshBasicMaterial( {
497
+ name: 'PMREM.Background',
498
+ side: BackSide,
499
+ depthWrite: false,
500
+ depthTest: false,
501
+ } )
502
+ );
507
503
 
508
504
  }
509
505
 
506
+ const backgroundBox = this._backgroundBox;
507
+ const backgroundMaterial = backgroundBox.material;
508
+
510
509
  let useSolidColor = false;
510
+
511
511
  const background = scene.background;
512
512
 
513
513
  if ( background ) {
514
514
 
515
515
  if ( background.isColor ) {
516
516
 
517
- backgroundBox.material.color.copy( background );
517
+ backgroundMaterial.color.copy( background );
518
518
  scene.background = null;
519
519
  useSolidColor = true;
520
520
 
@@ -522,7 +522,7 @@ class PMREMGenerator {
522
522
 
523
523
  } else {
524
524
 
525
- backgroundBox.material.color.copy( _clearColor );
525
+ backgroundMaterial.color.copy( _clearColor );
526
526
  useSolidColor = true;
527
527
 
528
528
  }
@@ -620,19 +620,83 @@ class PMREMGenerator {
620
620
  const renderer = this._renderer;
621
621
  const autoClear = renderer.autoClear;
622
622
  renderer.autoClear = false;
623
- const n = this._lodPlanes.length;
624
623
 
624
+ const n = this._lodMeshes.length;
625
+
626
+ // Use GGX VNDF importance sampling
625
627
  for ( let i = 1; i < n; i ++ ) {
626
628
 
627
- const sigma = Math.sqrt( this._sigmas[ i ] * this._sigmas[ i ] - this._sigmas[ i - 1 ] * this._sigmas[ i - 1 ] );
629
+ this._applyGGXFilter( cubeUVRenderTarget, i - 1, i );
628
630
 
629
- const poleAxis = _axisDirections[ ( n - i - 1 ) % _axisDirections.length ];
631
+ }
630
632
 
631
- this._blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis );
633
+ renderer.autoClear = autoClear;
634
+
635
+ }
636
+
637
+ /**
638
+ * Applies GGX VNDF importance sampling filter to generate a prefiltered environment map.
639
+ * Uses Monte Carlo integration with VNDF importance sampling to accurately represent the
640
+ * GGX BRDF for physically-based rendering. Reads from the previous LOD level and
641
+ * applies incremental roughness filtering to avoid over-blurring.
642
+ *
643
+ * @private
644
+ * @param {RenderTarget} cubeUVRenderTarget
645
+ * @param {number} lodIn - Source LOD level to read from
646
+ * @param {number} lodOut - Target LOD level to write to
647
+ */
648
+ _applyGGXFilter( cubeUVRenderTarget, lodIn, lodOut ) {
649
+
650
+ const renderer = this._renderer;
651
+ const pingPongRenderTarget = this._pingPongRenderTarget;
652
+
653
+ // Lazy create GGX material only when first used
654
+ if ( this._ggxMaterial === null ) {
655
+
656
+ this._ggxMaterial = _getGGXShader( this._lodMax, this._pingPongRenderTarget.width, this._pingPongRenderTarget.height );
632
657
 
633
658
  }
634
659
 
635
- renderer.autoClear = autoClear;
660
+ const ggxMaterial = this._ggxMaterial;
661
+ const ggxMesh = this._lodMeshes[ lodOut ];
662
+ ggxMesh.material = ggxMaterial;
663
+
664
+ const ggxUniforms = _uniformsMap.get( ggxMaterial );
665
+
666
+ // Calculate incremental roughness between LOD levels
667
+ const targetRoughness = lodOut / ( this._lodMeshes.length - 1 );
668
+ const sourceRoughness = lodIn / ( this._lodMeshes.length - 1 );
669
+ const incrementalRoughness = Math.sqrt( targetRoughness * targetRoughness - sourceRoughness * sourceRoughness );
670
+
671
+ // Apply blur strength mapping for better quality across the roughness range
672
+ const blurStrength = 0.05 + targetRoughness * 0.95;
673
+ const adjustedRoughness = incrementalRoughness * blurStrength;
674
+
675
+ // Calculate viewport position based on output LOD level
676
+ const { _lodMax } = this;
677
+ const outputSize = this._sizeLods[ lodOut ];
678
+ const x = 3 * outputSize * ( lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0 );
679
+ const y = 4 * ( this._cubeSize - outputSize );
680
+
681
+ // Read from previous LOD with incremental roughness
682
+ cubeUVRenderTarget.texture.frame = ( cubeUVRenderTarget.texture.frame || 0 ) + 1;
683
+ ggxUniforms.envMap.value = cubeUVRenderTarget.texture;
684
+ ggxUniforms.roughness.value = adjustedRoughness;
685
+ ggxUniforms.mipInt.value = _lodMax - lodIn; // Sample from input LOD
686
+
687
+ _setViewport( pingPongRenderTarget, x, y, 3 * outputSize, 2 * outputSize );
688
+ renderer.setRenderTarget( pingPongRenderTarget );
689
+ renderer.render( ggxMesh, _flatCamera );
690
+
691
+ // Copy from pingPong back to cubeUV (simple direct copy)
692
+ pingPongRenderTarget.texture.frame = ( pingPongRenderTarget.texture.frame || 0 ) + 1;
693
+ ggxUniforms.envMap.value = pingPongRenderTarget.texture;
694
+ ggxUniforms.roughness.value = 0.0; // Direct copy
695
+ ggxUniforms.mipInt.value = _lodMax - lodOut; // Read from the level we just wrote
696
+
697
+ _setViewport( cubeUVRenderTarget, x, y, 3 * outputSize, 2 * outputSize );
698
+ renderer.setRenderTarget( cubeUVRenderTarget );
699
+ renderer.render( ggxMesh, _flatCamera );
636
700
 
637
701
  }
638
702
 
@@ -643,6 +707,8 @@ class PMREMGenerator {
643
707
  * the poles) to approximate the orthogonally-separable blur. It is least
644
708
  * accurate at the poles, but still does a decent job.
645
709
  *
710
+ * Used for initial scene blur in fromScene() method when sigma > 0.
711
+ *
646
712
  * @private
647
713
  * @param {RenderTarget} cubeUVRenderTarget - The cubemap render target.
648
714
  * @param {number} lodIn - The input level-of-detail.
@@ -681,7 +747,7 @@ class PMREMGenerator {
681
747
 
682
748
  if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) {
683
749
 
684
- console.error( 'blur direction must be either latitudinal or longitudinal!' );
750
+ error( 'blur direction must be either latitudinal or longitudinal!' );
685
751
 
686
752
  }
687
753
 
@@ -700,7 +766,7 @@ class PMREMGenerator {
700
766
 
701
767
  if ( samples > MAX_SAMPLES ) {
702
768
 
703
- console.warn( `sigmaRadians, ${
769
+ warn( `sigmaRadians, ${
704
770
  sigmaRadians}, is too large and will clip, as it requested ${
705
771
  samples} samples when the maximum is set to ${MAX_SAMPLES}` );
706
772
 
@@ -764,7 +830,6 @@ class PMREMGenerator {
764
830
 
765
831
  function _createPlanes( lodMax ) {
766
832
 
767
- const lodPlanes = [];
768
833
  const sizeLods = [];
769
834
  const sigmas = [];
770
835
  const lodMeshes = [];
@@ -831,7 +896,6 @@ function _createPlanes( lodMax ) {
831
896
  planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) );
832
897
  planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) );
833
898
  planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) );
834
- lodPlanes.push( planes );
835
899
  lodMeshes.push( new Mesh( planes, null ) );
836
900
 
837
901
  if ( lod > LOD_MIN ) {
@@ -842,7 +906,7 @@ function _createPlanes( lodMax ) {
842
906
 
843
907
  }
844
908
 
845
- return { lodPlanes, sizeLods, sigmas, lodMeshes };
909
+ return { lodMeshes, sizeLods, sigmas };
846
910
 
847
911
  }
848
912
 
@@ -894,7 +958,7 @@ function _getBlurShader( lodMax, width, height ) {
894
958
  const n = float( MAX_SAMPLES );
895
959
  const latitudinal = uniform( 0 ); // false, bool
896
960
  const samples = uniform( 1 ); // int
897
- const envMap = texture( null );
961
+ const envMap = texture();
898
962
  const mipInt = uniform( 0 ); // int
899
963
  const CUBEUV_TEXEL_WIDTH = float( 1 / width );
900
964
  const CUBEUV_TEXEL_HEIGHT = float( 1 / height );
@@ -924,6 +988,37 @@ function _getBlurShader( lodMax, width, height ) {
924
988
 
925
989
  }
926
990
 
991
+ function _getGGXShader( lodMax, width, height ) {
992
+
993
+ const envMap = texture();
994
+ const roughness = uniform( 0 );
995
+ const mipInt = uniform( 0 );
996
+ const CUBEUV_TEXEL_WIDTH = float( 1 / width );
997
+ const CUBEUV_TEXEL_HEIGHT = float( 1 / height );
998
+ const CUBEUV_MAX_MIP = float( lodMax );
999
+
1000
+ const materialUniforms = {
1001
+ envMap,
1002
+ roughness,
1003
+ mipInt,
1004
+ CUBEUV_TEXEL_WIDTH,
1005
+ CUBEUV_TEXEL_HEIGHT,
1006
+ CUBEUV_MAX_MIP
1007
+ };
1008
+
1009
+ const material = _getMaterial( 'ggx' );
1010
+ material.fragmentNode = ggxConvolution( {
1011
+ ...materialUniforms,
1012
+ N_immutable: _outputDirection,
1013
+ GGX_SAMPLES: uint( GGX_SAMPLES )
1014
+ } );
1015
+
1016
+ _uniformsMap.set( material, materialUniforms );
1017
+
1018
+ return material;
1019
+
1020
+ }
1021
+
927
1022
  function _getCubemapMaterial( envTexture ) {
928
1023
 
929
1024
  const material = _getMaterial( 'cubemap' );
@@ -1,3 +1,5 @@
1
+ import { warn } from '../../../utils.js';
2
+
1
3
  /**
2
4
  * The purpose of a node library is to assign node implementations
3
5
  * to existing library features. In `WebGPURenderer` lights, materials
@@ -154,7 +156,7 @@ class NodeLibrary {
154
156
 
155
157
  if ( library.has( type ) ) {
156
158
 
157
- console.warn( `Redefinition of node ${ type }` );
159
+ warn( `Redefinition of node ${ type }` );
158
160
  return;
159
161
 
160
162
  }
@@ -177,7 +179,7 @@ class NodeLibrary {
177
179
 
178
180
  if ( library.has( baseClass ) ) {
179
181
 
180
- console.warn( `Redefinition of node ${ baseClass.name }` );
182
+ warn( `Redefinition of node ${ baseClass.name }` );
181
183
  return;
182
184
 
183
185
  }
@@ -38,10 +38,22 @@ class NodeSampler extends Sampler {
38
38
 
39
39
  /**
40
40
  * Updates the texture value of this sampler.
41
+ *
42
+ * @return {boolean} Whether the sampler needs an update or not.
41
43
  */
42
44
  update() {
43
45
 
44
- this.texture = this.textureNode.value;
46
+ const { textureNode } = this;
47
+
48
+ if ( this.texture !== textureNode.value ) {
49
+
50
+ this.texture = textureNode.value;
51
+
52
+ return true;
53
+
54
+ }
55
+
56
+ return super.update();
45
57
 
46
58
  }
47
59
 
@@ -1,6 +1,7 @@
1
1
  import DataMap from '../DataMap.js';
2
2
  import ChainMap from '../ChainMap.js';
3
3
  import NodeBuilderState from './NodeBuilderState.js';
4
+ import NodeMaterial from '../../../materials/nodes/NodeMaterial.js';
4
5
  import { cubeMapNode } from '../../../nodes/utils/CubeMapNode.js';
5
6
  import { NodeFrame } from '../../../nodes/Nodes.js';
6
7
  import { objectGroup, renderGroup, frameGroup, cubeTexture, texture, texture3D, vec3, fog, rangeFogFactor, densityFogFactor, reference, pmremTexture, screenUV } from '../../../nodes/TSL.js';
@@ -8,6 +9,7 @@ import { builtin } from '../../../nodes/accessors/BuiltinNode.js';
8
9
 
9
10
  import { CubeUVReflectionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from '../../../constants.js';
10
11
  import { hashArray } from '../../../nodes/core/NodeUtils.js';
12
+ import { error } from '../../../utils.js';
11
13
 
12
14
  const _outputNodeMap = new WeakMap();
13
15
  const _chainKeys = [];
@@ -193,22 +195,41 @@ class Nodes extends DataMap {
193
195
 
194
196
  if ( nodeBuilderState === undefined ) {
195
197
 
196
- const nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer );
197
- nodeBuilder.scene = renderObject.scene;
198
- nodeBuilder.material = renderObject.material;
199
- nodeBuilder.camera = renderObject.camera;
200
- nodeBuilder.context.material = renderObject.material;
201
- nodeBuilder.lightsNode = renderObject.lightsNode;
202
- nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );
203
- nodeBuilder.fogNode = this.getFogNode( renderObject.scene );
204
- nodeBuilder.clippingContext = renderObject.clippingContext;
205
- if ( this.renderer.getOutputRenderTarget() ? this.renderer.getOutputRenderTarget().multiview : false ) {
198
+ const createNodeBuilder = ( material ) => {
206
199
 
207
- nodeBuilder.enableMultiview();
200
+ const nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer );
201
+ nodeBuilder.scene = renderObject.scene;
202
+ nodeBuilder.material = material;
203
+ nodeBuilder.camera = renderObject.camera;
204
+ nodeBuilder.context.material = material;
205
+ nodeBuilder.lightsNode = renderObject.lightsNode;
206
+ nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );
207
+ nodeBuilder.fogNode = this.getFogNode( renderObject.scene );
208
+ nodeBuilder.clippingContext = renderObject.clippingContext;
209
+ if ( this.renderer.getOutputRenderTarget() ? this.renderer.getOutputRenderTarget().multiview : false ) {
208
210
 
209
- }
211
+ nodeBuilder.enableMultiview();
212
+
213
+ }
214
+
215
+ return nodeBuilder;
216
+
217
+ };
218
+
219
+ let nodeBuilder = createNodeBuilder( renderObject.material );
210
220
 
211
- nodeBuilder.build();
221
+ try {
222
+
223
+ nodeBuilder.build();
224
+
225
+ } catch ( e ) {
226
+
227
+ nodeBuilder = createNodeBuilder( new NodeMaterial() );
228
+ nodeBuilder.build();
229
+
230
+ error( 'TSL: ' + e );
231
+
232
+ }
212
233
 
213
234
  nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
214
235
 
@@ -412,6 +433,7 @@ class Nodes extends DataMap {
412
433
 
413
434
  _cacheKeyValues.push( this.renderer.getOutputRenderTarget() && this.renderer.getOutputRenderTarget().multiview ? 1 : 0 );
414
435
  _cacheKeyValues.push( this.renderer.shadowMap.enabled ? 1 : 0 );
436
+ _cacheKeyValues.push( this.renderer.shadowMap.type );
415
437
 
416
438
  cacheKeyData.callId = callId;
417
439
  cacheKeyData.cacheKey = hashArray( _cacheKeyValues );
@@ -489,7 +511,7 @@ class Nodes extends DataMap {
489
511
 
490
512
  } else if ( background.isColor !== true ) {
491
513
 
492
- console.error( 'WebGPUNodes: Unsupported background configuration.', background );
514
+ error( 'WebGPUNodes: Unsupported background configuration.', background );
493
515
 
494
516
  }
495
517
 
@@ -571,7 +593,7 @@ class Nodes extends DataMap {
571
593
 
572
594
  } else {
573
595
 
574
- console.error( 'THREE.Renderer: Unsupported fog configuration.', sceneFog );
596
+ error( 'Renderer: Unsupported fog configuration.', sceneFog );
575
597
 
576
598
  }
577
599
 
@@ -618,7 +640,7 @@ class Nodes extends DataMap {
618
640
 
619
641
  } else {
620
642
 
621
- console.error( 'Nodes: Unsupported environment configuration.', environment );
643
+ error( 'Nodes: Unsupported environment configuration.', environment );
622
644
 
623
645
  }
624
646