@unikia/upe-renderer 0.186.110 → 0.187.11

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 (506) hide show
  1. package/README.md +5 -7
  2. package/UPSTREAM.md +4 -4
  3. package/build/three.core.js +853 -277
  4. package/build/three.module.js +1098 -1280
  5. package/build/three.tsl.js +41938 -686
  6. package/build/three.webgpu.js +10604 -49055
  7. package/build/three.webgpu.nodes.js +9249 -5788
  8. package/examples/jsm/Addons.js +2 -0
  9. package/examples/jsm/animation/CCDIKSolver.js +17 -5
  10. package/examples/jsm/controls/FirstPersonControls.js +1 -1
  11. package/examples/jsm/controls/OrbitControls.js +27 -14
  12. package/examples/jsm/csm/CSMShader.js +74 -3
  13. package/examples/jsm/curves/CurveExtras.js +4 -4
  14. package/examples/jsm/curves/NURBSCurve.js +14 -0
  15. package/examples/jsm/exporters/EXRExporter.js +673 -16
  16. package/examples/jsm/exporters/GLTFExporter.js +4 -4
  17. package/examples/jsm/exporters/KTX2Exporter.js +1 -1
  18. package/examples/jsm/exporters/OBJExporter.js +48 -5
  19. package/examples/jsm/exporters/PLYExporter.js +22 -11
  20. package/examples/jsm/generators/CityGenerator.js +3 -2
  21. package/examples/jsm/generators/city/SkyscraperGenerator.js +63 -21
  22. package/examples/jsm/gpgpu/BitonicSort.js +30 -23
  23. package/examples/jsm/helpers/VertexTangentsHelper.js +1 -1
  24. package/examples/jsm/inspector/Extension.js +1 -1
  25. package/examples/jsm/inspector/Inspector.js +6 -46
  26. package/examples/jsm/inspector/RendererInspector.js +43 -8
  27. package/examples/jsm/inspector/Storage.js +49 -0
  28. package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +32 -27
  29. package/examples/jsm/inspector/tabs/Parameters.js +5 -1
  30. package/examples/jsm/inspector/tabs/Performance.js +22 -7
  31. package/examples/jsm/inspector/tabs/Settings.js +1 -1
  32. package/examples/jsm/inspector/tabs/Timeline.js +83 -7
  33. package/examples/jsm/inspector/tabs/Viewer.js +25 -10
  34. package/examples/jsm/inspector/ui/Profiler.js +1 -1
  35. package/examples/jsm/inspector/ui/Style.js +21 -53
  36. package/examples/jsm/inspector/ui/Values.js +28 -3
  37. package/examples/jsm/libs/fflate.module.js +83 -56
  38. package/examples/jsm/libs/mikktspace.README.md +27 -0
  39. package/examples/jsm/libs/mikktspace.module.js +721 -109
  40. package/examples/jsm/lighting/ClusteredLighting.js +100 -2
  41. package/examples/jsm/lighting/LightMapper.js +295 -0
  42. package/examples/jsm/lighting/LightProbeGrid.js +242 -139
  43. package/examples/jsm/lighting/LightProbeGridWebGL.js +30 -14
  44. package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +54 -5
  45. package/examples/jsm/lighting/vxgi/VXGIIrradiance.js +43 -0
  46. package/examples/jsm/lighting/vxgi/VXGINode.js +13 -56
  47. package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +316 -1
  48. package/examples/jsm/lighting/vxgi/VXGIVolume.js +69 -59
  49. package/examples/jsm/lights/SunLight.js +9 -4
  50. package/examples/jsm/lights/SunLightNode.js +3 -3
  51. package/examples/jsm/lines/LineMaterial.js +26 -10
  52. package/examples/jsm/loaders/3DMLoader.js +10 -1
  53. package/examples/jsm/loaders/3MFLoader.js +5 -1
  54. package/examples/jsm/loaders/AMFLoader.js +2 -0
  55. package/examples/jsm/loaders/BVHLoader.js +2 -0
  56. package/examples/jsm/loaders/ColladaLoader.js +8 -0
  57. package/examples/jsm/loaders/DDSLoader.js +1 -1
  58. package/examples/jsm/loaders/DRACOLoader.js +5 -1
  59. package/examples/jsm/loaders/EXRLoader.js +120 -104
  60. package/examples/jsm/loaders/FBXLoader.js +4 -0
  61. package/examples/jsm/loaders/FontLoader.js +2 -0
  62. package/examples/jsm/loaders/GCodeLoader.js +5 -9
  63. package/examples/jsm/loaders/GLTFLoader.js +112 -31
  64. package/examples/jsm/loaders/GaussianSplatPLYLoader.js +2 -0
  65. package/examples/jsm/loaders/HDRCubeTextureLoader.js +3 -0
  66. package/examples/jsm/loaders/IESLoader.js +46 -12
  67. package/examples/jsm/loaders/JXLLoader.js +159 -0
  68. package/examples/jsm/loaders/KMZLoader.js +6 -0
  69. package/examples/jsm/loaders/KSPLATLoader.js +2 -0
  70. package/examples/jsm/loaders/KTX2Loader.js +49 -4
  71. package/examples/jsm/loaders/KTXLoader.js +5 -3
  72. package/examples/jsm/loaders/LDrawLoader.js +15 -22
  73. package/examples/jsm/loaders/LUT3dlLoader.js +5 -1
  74. package/examples/jsm/loaders/LUTCubeLoader.js +6 -2
  75. package/examples/jsm/loaders/LUTImageLoader.js +2 -0
  76. package/examples/jsm/loaders/LWOLoader.js +6 -0
  77. package/examples/jsm/loaders/MD2Loader.js +2 -0
  78. package/examples/jsm/loaders/MDDLoader.js +4 -0
  79. package/examples/jsm/loaders/MTLLoader.js +8 -0
  80. package/examples/jsm/loaders/MaterialXLoader.js +57 -5
  81. package/examples/jsm/loaders/NRRDLoader.js +4 -2
  82. package/examples/jsm/loaders/OBJLoader.js +10 -4
  83. package/examples/jsm/loaders/PCDLoader.js +6 -2
  84. package/examples/jsm/loaders/PDBLoader.js +5 -3
  85. package/examples/jsm/loaders/PLYLoader.js +39 -15
  86. package/examples/jsm/loaders/PVRLoader.js +2 -2
  87. package/examples/jsm/loaders/SPLATLoader.js +2 -0
  88. package/examples/jsm/loaders/SPZLoader.js +2 -0
  89. package/examples/jsm/loaders/STLLoader.js +3 -1
  90. package/examples/jsm/loaders/SVGLoader.js +27 -49
  91. package/examples/jsm/loaders/TDSLoader.js +4 -0
  92. package/examples/jsm/loaders/TGALoader.js +6 -5
  93. package/examples/jsm/loaders/TTFLoader.js +2 -0
  94. package/examples/jsm/loaders/USDLoader.js +14 -0
  95. package/examples/jsm/loaders/UltraHDRLoader.js +2 -0
  96. package/examples/jsm/loaders/VOXLoader.js +3 -0
  97. package/examples/jsm/loaders/VRMLLoader.js +4 -0
  98. package/examples/jsm/loaders/VTKLoader.js +2 -0
  99. package/examples/jsm/loaders/XYZLoader.js +2 -0
  100. package/examples/jsm/loaders/collada/ColladaComposer.js +15 -8
  101. package/examples/jsm/loaders/materialx/MaterialXDocument.js +610 -138
  102. package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +12 -95
  103. package/examples/jsm/loaders/materialx/MaterialXLog.js +4 -0
  104. package/examples/jsm/loaders/materialx/MaterialXNodeDefs.js +99 -0
  105. package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +760 -1
  106. package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +222 -372
  107. package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +163 -259
  108. package/examples/jsm/loaders/materialx/MaterialXUtils.js +25 -0
  109. package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +161 -159
  110. package/examples/jsm/loaders/usd/USDAParser.js +56 -47
  111. package/examples/jsm/loaders/usd/USDComposer.js +25 -30
  112. package/examples/jsm/math/ColorConverter.js +7 -3
  113. package/examples/jsm/math/Lut.js +2 -2
  114. package/examples/jsm/math/OBB.js +3 -3
  115. package/examples/jsm/math/Octree.js +20 -17
  116. package/examples/jsm/objects/GaussianSplat.js +5 -4
  117. package/examples/jsm/objects/Reflector.js +5 -0
  118. package/examples/jsm/objects/SkyMesh.js +14 -7
  119. package/examples/jsm/objects/Water2Mesh.js +2 -2
  120. package/examples/jsm/physics/RapierPhysics.js +2 -2
  121. package/examples/jsm/pipelines/MeshletDrawingPipeline.js +5571 -0
  122. package/examples/jsm/pipelines/VisibilityBufferDrawingPipeline.js +954 -0
  123. package/examples/jsm/postprocessing/BokehPass.js +1 -1
  124. package/examples/jsm/postprocessing/GTAOPass.js +26 -18
  125. package/examples/jsm/renderers/SVGRenderer.js +3 -2
  126. package/examples/jsm/shaders/GTAOShader.js +7 -4
  127. package/examples/jsm/shaders/PoissonDenoiseShader.js +1 -10
  128. package/examples/jsm/tsl/WebGLNodesHandler.js +21 -9
  129. package/examples/jsm/tsl/display/AfterImageNode.js +3 -3
  130. package/examples/jsm/tsl/display/BilateralBlurNode.js +3 -3
  131. package/examples/jsm/tsl/display/BloomNode.js +3 -3
  132. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +8 -19
  133. package/examples/jsm/tsl/display/DenoiseNode.js +5 -5
  134. package/examples/jsm/tsl/display/DepthOfFieldNode.js +3 -3
  135. package/examples/jsm/tsl/display/DotScreenNode.js +3 -3
  136. package/examples/jsm/tsl/display/FSR1Node.js +3 -3
  137. package/examples/jsm/tsl/display/FXAANode.js +3 -10
  138. package/examples/jsm/tsl/display/FilmNode.js +3 -3
  139. package/examples/jsm/tsl/display/GTAONode.js +33 -25
  140. package/examples/jsm/tsl/display/GaussianBlurNode.js +3 -3
  141. package/examples/jsm/tsl/display/GodraysNode.js +5 -19
  142. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +8 -4
  143. package/examples/jsm/tsl/display/LensflareNode.js +3 -3
  144. package/examples/jsm/tsl/display/Lut3DNode.js +3 -3
  145. package/examples/jsm/tsl/display/OITPassNode.js +0 -11
  146. package/examples/jsm/tsl/display/OutlineNode.js +107 -5
  147. package/examples/jsm/tsl/display/PixelationPassNode.js +85 -193
  148. package/examples/jsm/tsl/display/RGBShiftNode.js +3 -3
  149. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +23 -126
  150. package/examples/jsm/tsl/display/SMAANode.js +3 -3
  151. package/examples/jsm/tsl/display/SSAONode.js +6 -20
  152. package/examples/jsm/tsl/display/SSGINode.js +36 -29
  153. package/examples/jsm/tsl/display/SSRNode.js +135 -63
  154. package/examples/jsm/tsl/display/SSSNode.js +6 -20
  155. package/examples/jsm/tsl/display/SharpenNode.js +3 -3
  156. package/examples/jsm/tsl/display/SobelOperatorNode.js +3 -3
  157. package/examples/jsm/tsl/display/TAAUNode.js +10 -42
  158. package/examples/jsm/tsl/display/TRAANode.js +11 -43
  159. package/examples/jsm/tsl/display/TemporalReprojectNode.js +42 -47
  160. package/examples/jsm/tsl/display/TransitionNode.js +3 -3
  161. package/examples/jsm/tsl/display/lensDirt.js +30 -0
  162. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +482 -121
  163. package/examples/jsm/tsl/lighting/DynamicLightsNode.js +41 -140
  164. package/examples/jsm/tsl/lighting/LightProbeGridNode.js +72 -25
  165. package/examples/jsm/tsl/lighting/data/AmbientLightDataNode.js +6 -0
  166. package/examples/jsm/tsl/lighting/data/DirectionalLightDataNode.js +6 -0
  167. package/examples/jsm/tsl/lighting/data/HemisphereLightDataNode.js +6 -0
  168. package/examples/jsm/tsl/lighting/data/PointLightDataNode.js +6 -0
  169. package/examples/jsm/tsl/lighting/data/SpotLightDataNode.js +6 -0
  170. package/examples/jsm/tsl/shadows/TileShadowNode.js +102 -14
  171. package/examples/jsm/tsl/utils/Raymarching.js +1 -1
  172. package/examples/jsm/tsl/utils/SoftParticles.js +5 -12
  173. package/examples/jsm/tsl/utils/SpecularHelpers.js +47 -70
  174. package/examples/jsm/tsl/utils/TAAUtils.js +6 -17
  175. package/examples/jsm/utils/BufferGeometryUtils.js +110 -88
  176. package/examples/jsm/utils/MeshletGeometryUtils.js +417 -0
  177. package/examples/jsm/utils/SceneOptimizer.js +2 -1
  178. package/examples/jsm/utils/SceneUtils.js +1 -1
  179. package/examples/jsm/utils/unwrapUVs.js +865 -0
  180. package/examples/jsm/webxr/XREstimatedLight.js +11 -4
  181. package/package.json +3 -3
  182. package/src/Three.TSL.js +2 -683
  183. package/src/Three.WebGPU.Nodes.js +2 -1
  184. package/src/Three.WebGPU.js +2 -1
  185. package/src/animation/AnimationAction.js +1 -1
  186. package/src/animation/AnimationUtils.js +1 -3
  187. package/src/animation/KeyframeTrack.js +19 -0
  188. package/src/cameras/ArrayCamera.js +12 -0
  189. package/src/cameras/CubeCamera.js +3 -3
  190. package/src/constants.js +1 -9
  191. package/src/core/BufferAttribute.js +57 -21
  192. package/src/core/BufferGeometry.js +5 -13
  193. package/src/core/Clock.js +1 -1
  194. package/src/core/InterleavedBuffer.js +28 -18
  195. package/src/core/InterleavedBufferAttribute.js +54 -20
  196. package/src/core/Object3D.js +19 -9
  197. package/src/core/Raycaster.js +2 -0
  198. package/src/core/RenderTarget.js +11 -5
  199. package/src/core/UniformsGroup.js +7 -3
  200. package/src/extras/PMREMGenerator.js +392 -685
  201. package/src/extras/core/Curve.js +4 -0
  202. package/src/extras/core/CurvePath.js +13 -0
  203. package/src/extras/core/ShapePath.js +1 -1
  204. package/src/geometries/EdgesGeometry.js +12 -10
  205. package/src/geometries/LatheGeometry.js +2 -0
  206. package/src/helpers/PolarGridHelper.js +1 -1
  207. package/src/lights/Light.js +11 -0
  208. package/src/lights/LightProbe.js +2 -0
  209. package/src/lights/LightShadow.js +2 -0
  210. package/src/loaders/AnimationLoader.js +2 -0
  211. package/src/loaders/AudioLoader.js +2 -0
  212. package/src/loaders/BufferGeometryLoader.js +2 -0
  213. package/src/loaders/CompressedTextureLoader.js +2 -0
  214. package/src/loaders/CubeTextureLoader.js +2 -0
  215. package/src/loaders/DataTextureLoader.js +2 -0
  216. package/src/loaders/FileLoader.js +2 -0
  217. package/src/loaders/ImageBitmapLoader.js +3 -1
  218. package/src/loaders/ImageLoader.js +1 -0
  219. package/src/loaders/Loader.js +47 -0
  220. package/src/loaders/MaterialLoader.js +2 -0
  221. package/src/loaders/ObjectLoader.js +27 -8
  222. package/src/loaders/TextureLoader.js +5 -3
  223. package/src/loaders/nodes/NodeLoader.js +2 -0
  224. package/src/materials/Material.js +21 -2
  225. package/src/materials/MeshDepthMaterial.js +1 -1
  226. package/src/materials/MeshDistanceMaterial.js +1 -1
  227. package/src/materials/MeshLambertMaterial.js +1 -1
  228. package/src/materials/MeshMatcapMaterial.js +1 -1
  229. package/src/materials/MeshNormalMaterial.js +1 -1
  230. package/src/materials/MeshPhongMaterial.js +1 -1
  231. package/src/materials/MeshPhysicalMaterial.js +90 -11
  232. package/src/materials/MeshStandardMaterial.js +1 -1
  233. package/src/materials/MeshToonMaterial.js +1 -1
  234. package/src/materials/nodes/Line2NodeMaterial.js +32 -10
  235. package/src/materials/nodes/MeshLambertNodeMaterial.js +13 -0
  236. package/src/materials/nodes/MeshPhongNodeMaterial.js +13 -0
  237. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +40 -5
  238. package/src/materials/nodes/MeshToonNodeMaterial.js +13 -0
  239. package/src/materials/nodes/NodeMaterial.js +36 -16
  240. package/src/materials/nodes/NodeMaterialInstance.js +193 -0
  241. package/src/materials/nodes/NodeMaterials.js +1 -0
  242. package/src/materials/nodes/PointsNodeMaterial.js +1 -1
  243. package/src/materials/nodes/SpriteNodeMaterial.js +3 -3
  244. package/src/materials/nodes/manager/NodeMaterialObserver.js +191 -22
  245. package/src/math/Box3.js +2 -2
  246. package/src/math/Color.js +8 -8
  247. package/src/math/ColorManagement.js +2 -21
  248. package/src/math/FrustumArray.js +12 -0
  249. package/src/math/Interpolant.js +1 -1
  250. package/src/math/Line3.js +2 -4
  251. package/src/math/MathUtils.js +33 -46
  252. package/src/math/Matrix2.js +1 -1
  253. package/src/math/Matrix3.js +1 -1
  254. package/src/math/Matrix4.js +1 -1
  255. package/src/math/Triangle.js +2 -1
  256. package/src/math/Vector2.js +1 -1
  257. package/src/math/Vector3.js +1 -1
  258. package/src/math/Vector4.js +1 -1
  259. package/src/nodes/Nodes.js +1 -0
  260. package/src/nodes/TSL.js +2 -0
  261. package/src/nodes/accessors/Arrays.js +1 -1
  262. package/src/nodes/accessors/Batch.js +29 -23
  263. package/src/nodes/accessors/BufferAttributeNode.js +21 -1
  264. package/src/nodes/accessors/BuiltinNode.js +6 -0
  265. package/src/nodes/accessors/Camera.js +100 -93
  266. package/src/nodes/accessors/ClippingNode.js +17 -6
  267. package/src/nodes/accessors/CubeTextureNode.js +12 -24
  268. package/src/nodes/accessors/Instance.js +198 -160
  269. package/src/nodes/accessors/Lights.js +19 -6
  270. package/src/nodes/accessors/MaterialNode.js +33 -4
  271. package/src/nodes/accessors/Morph.js +81 -22
  272. package/src/nodes/accessors/Normal.js +0 -42
  273. package/src/nodes/accessors/Object3DNode.js +6 -0
  274. package/src/nodes/accessors/PointUVNode.js +6 -0
  275. package/src/nodes/accessors/ReferenceAttributeNode.js +279 -0
  276. package/src/nodes/accessors/ReferenceBaseNode.js +6 -0
  277. package/src/nodes/accessors/ReferenceNode.js +6 -0
  278. package/src/nodes/accessors/Skinning.js +57 -52
  279. package/src/nodes/accessors/StorageBufferNode.js +3 -12
  280. package/src/nodes/accessors/TextureBicubic.js +30 -27
  281. package/src/nodes/accessors/TextureNode.js +164 -78
  282. package/src/nodes/accessors/TextureSizeNode.js +6 -0
  283. package/src/nodes/accessors/UniformArrayNode.js +8 -15
  284. package/src/nodes/accessors/VelocityNode.js +13 -8
  285. package/src/nodes/code/CodeNode.js +6 -0
  286. package/src/nodes/code/ExpressionNode.js +6 -0
  287. package/src/nodes/code/FunctionCallNode.js +3 -3
  288. package/src/nodes/code/FunctionNode.js +15 -13
  289. package/src/nodes/core/ArrayNode.js +3 -3
  290. package/src/nodes/core/AssignNode.js +10 -9
  291. package/src/nodes/core/AttributeNode.js +39 -0
  292. package/src/nodes/core/BypassNode.js +6 -0
  293. package/src/nodes/core/ConstNode.js +31 -1
  294. package/src/nodes/core/ContextNode.js +11 -6
  295. package/src/nodes/core/IndexNode.js +6 -0
  296. package/src/nodes/core/InputNode.js +6 -0
  297. package/src/nodes/core/InspectorNode.js +17 -31
  298. package/src/nodes/core/IsolateNode.js +8 -0
  299. package/src/nodes/core/Node.js +367 -67
  300. package/src/nodes/core/NodeBuilder.js +664 -222
  301. package/src/nodes/core/NodeUtils.js +25 -0
  302. package/src/nodes/core/NodeVar.js +10 -1
  303. package/src/nodes/core/OutputStructNode.js +6 -0
  304. package/src/nodes/core/OverrideContextNode.js +38 -37
  305. package/src/nodes/core/PropertyNode.js +14 -0
  306. package/src/nodes/core/StackNode.js +33 -21
  307. package/src/nodes/core/StructNode.js +6 -0
  308. package/src/nodes/core/StructTypeNode.js +6 -0
  309. package/src/nodes/core/SubBuildNode.js +8 -0
  310. package/src/nodes/core/TempNode.js +10 -35
  311. package/src/nodes/core/UniformGroupNode.js +6 -0
  312. package/src/nodes/core/VarNode.js +43 -135
  313. package/src/nodes/core/VaryingNode.js +33 -2
  314. package/src/nodes/display/BlendModes.js +5 -40
  315. package/src/nodes/display/BumpMapNode.js +17 -7
  316. package/src/nodes/display/ColorAdjustment.js +22 -10
  317. package/src/nodes/display/ColorSpaceFunctions.js +2 -14
  318. package/src/nodes/display/ColorSpaceNode.js +3 -3
  319. package/src/nodes/display/FrontFacingNode.js +6 -0
  320. package/src/nodes/display/NormalMapNode.js +3 -3
  321. package/src/nodes/display/PassNode.js +75 -16
  322. package/src/nodes/display/RenderOutputNode.js +22 -5
  323. package/src/nodes/display/ScreenNode.js +6 -0
  324. package/src/nodes/display/ToneMappingFunctions.js +9 -51
  325. package/src/nodes/display/ToneMappingNode.js +3 -3
  326. package/src/nodes/display/ToonOutlinePassNode.js +66 -2
  327. package/src/nodes/display/ViewportDepthNode.js +34 -4
  328. package/src/nodes/functions/BSDF/BRDF_EON.js +65 -0
  329. package/src/nodes/functions/BSDF/BRDF_GGX.js +5 -3
  330. package/src/nodes/functions/BSDF/BRDF_Sheen.js +2 -16
  331. package/src/nodes/functions/BSDF/D_GGX.js +1 -8
  332. package/src/nodes/functions/BSDF/D_GGX_Anisotropic.js +7 -10
  333. package/src/nodes/functions/BSDF/LTC.js +20 -47
  334. package/src/nodes/functions/BSDF/Schlick_to_F0.js +1 -9
  335. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +1 -9
  336. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +10 -13
  337. package/src/nodes/functions/PhysicalLightingModel.js +84 -51
  338. package/src/nodes/functions/VolumetricLightingModel.js +1 -1
  339. package/src/nodes/functions/material/getAlphaHashThreshold.js +3 -9
  340. package/src/nodes/functions/material/getParallaxCorrectNormal.js +10 -11
  341. package/src/nodes/functions/material/getRoughness.js +3 -1
  342. package/src/nodes/geometry/RangeNode.js +52 -69
  343. package/src/nodes/gpgpu/AtomicFunctionNode.js +11 -6
  344. package/src/nodes/gpgpu/BarrierNode.js +6 -0
  345. package/src/nodes/gpgpu/ComputeBuiltinNode.js +6 -0
  346. package/src/nodes/gpgpu/ComputeNode.js +6 -0
  347. package/src/nodes/gpgpu/SubgroupFunctionNode.js +38 -29
  348. package/src/nodes/gpgpu/WorkgroupInfoNode.js +6 -0
  349. package/src/nodes/lighting/AnalyticLightNode.js +7 -14
  350. package/src/nodes/lighting/BasicEnvironmentNode.js +5 -1
  351. package/src/nodes/lighting/EnvironmentNode.js +58 -8
  352. package/src/nodes/lighting/IESSpotLightNode.js +19 -4
  353. package/src/nodes/lighting/LightProbeNode.js +2 -1
  354. package/src/nodes/lighting/LightUtils.js +2 -2
  355. package/src/nodes/lighting/LightingNode.js +6 -0
  356. package/src/nodes/lighting/LightsNode.js +26 -32
  357. package/src/nodes/lighting/PointShadowNode.js +92 -48
  358. package/src/nodes/lighting/ProjectorLightNode.js +1 -1
  359. package/src/nodes/lighting/RectAreaLightNode.js +13 -14
  360. package/src/nodes/lighting/ShadowBaseNode.js +9 -17
  361. package/src/nodes/lighting/ShadowFilterNode.js +26 -3
  362. package/src/nodes/lighting/ShadowNode.js +13 -11
  363. package/src/nodes/materialx/MaterialXColor.js +2 -14
  364. package/src/nodes/materialx/MaterialXColorTransform.js +1 -7
  365. package/src/nodes/materialx/MaterialXNodes.js +8 -11
  366. package/src/nodes/materialx/MaterialXNoise.js +195 -454
  367. package/src/nodes/math/BitcastNode.js +5 -5
  368. package/src/nodes/math/BitcountNode.js +18 -46
  369. package/src/nodes/math/ConditionalNode.js +92 -22
  370. package/src/nodes/math/Hash.js +1 -1
  371. package/src/nodes/math/MathNode.js +86 -64
  372. package/src/nodes/math/MathUtils.js +2 -2
  373. package/src/nodes/math/OperatorNode.js +42 -59
  374. package/src/nodes/math/PackFloatNode.js +9 -9
  375. package/src/nodes/math/Packed4x8IntegerNode.js +20 -52
  376. package/src/nodes/math/TriNoise3D.js +3 -23
  377. package/src/nodes/math/UnpackFloatNode.js +9 -9
  378. package/src/nodes/pmrem/PMREMNode.js +38 -75
  379. package/src/nodes/pmrem/PMREMUtils.js +108 -272
  380. package/src/nodes/procedural/Checker.js +1 -1
  381. package/src/nodes/tsl/TSLCore.js +199 -74
  382. package/src/nodes/utils/ArrayElementNode.js +19 -1
  383. package/src/nodes/utils/CubeMapNode.js +3 -3
  384. package/src/nodes/utils/DebugNode.js +2 -2
  385. package/src/nodes/utils/EventNode.js +6 -0
  386. package/src/nodes/utils/FlipNode.js +3 -3
  387. package/src/nodes/utils/FunctionOverloadingNode.js +7 -1
  388. package/src/nodes/utils/JoinNode.js +3 -3
  389. package/src/nodes/utils/LoopNode.js +14 -9
  390. package/src/nodes/utils/MemberNode.js +18 -0
  391. package/src/nodes/utils/PostProcessingUtils.js +20 -25
  392. package/src/nodes/utils/RTTNode.js +2 -0
  393. package/src/nodes/utils/ReflectorNode.js +24 -0
  394. package/src/nodes/utils/RotateNode.js +3 -3
  395. package/src/nodes/utils/SampleNode.js +6 -0
  396. package/src/nodes/utils/SetNode.js +3 -3
  397. package/src/nodes/utils/SplitNode.js +6 -0
  398. package/src/nodes/utils/UVUtils.js +2 -2
  399. package/src/objects/BatchedMesh.js +146 -15
  400. package/src/objects/InstancedMesh.js +12 -4
  401. package/src/objects/Line.js +20 -0
  402. package/src/objects/Mesh.js +8 -0
  403. package/src/objects/Points.js +20 -0
  404. package/src/objects/Skeleton.js +26 -0
  405. package/src/objects/SkinnedMesh.js +3 -3
  406. package/src/objects/Sprite.js +10 -0
  407. package/src/renderers/WebGLRenderer.js +104 -70
  408. package/src/renderers/common/Animation.js +5 -1
  409. package/src/renderers/common/Attributes.js +67 -57
  410. package/src/renderers/common/Backend.js +78 -3
  411. package/src/renderers/common/BindGroup.js +11 -0
  412. package/src/renderers/common/Binding.js +0 -11
  413. package/src/renderers/common/Bindings.js +116 -10
  414. package/src/renderers/common/Buffer.js +1 -1
  415. package/src/renderers/common/ClippingContext.js +12 -1
  416. package/src/renderers/common/ComputePipeline.js +17 -1
  417. package/src/renderers/common/DirectRenderPipeline.js +7 -3
  418. package/src/renderers/common/Geometries.js +170 -132
  419. package/src/renderers/common/Info.js +1 -1
  420. package/src/renderers/common/InspectorBase.js +5 -5
  421. package/src/renderers/common/Lighting.js +59 -0
  422. package/src/renderers/common/Pipelines.js +26 -12
  423. package/src/renderers/common/ProgrammableStage.js +1 -17
  424. package/src/renderers/common/RenderContext.js +21 -0
  425. package/src/renderers/common/RenderContexts.js +13 -4
  426. package/src/renderers/common/RenderObject.js +111 -35
  427. package/src/renderers/common/RenderObjects.js +37 -19
  428. package/src/renderers/common/Renderer.js +537 -295
  429. package/src/renderers/common/RendererUtils.js +15 -0
  430. package/src/renderers/common/StandardDrawingPipeline.js +343 -0
  431. package/src/renderers/common/Storage3DTexture.js +11 -0
  432. package/src/renderers/common/StorageArrayTexture.js +10 -0
  433. package/src/renderers/common/StorageTexture.js +0 -9
  434. package/src/renderers/common/Textures.js +144 -37
  435. package/src/renderers/common/UniformsGroup.js +19 -0
  436. package/src/renderers/common/XRManager.js +10 -91
  437. package/src/renderers/common/extras/PMREMGenerator.js +298 -576
  438. package/src/renderers/common/nodes/NodeBuilderState.js +7 -5
  439. package/src/renderers/common/nodes/NodeLibrary.js +11 -35
  440. package/src/renderers/common/nodes/NodeManager.js +80 -31
  441. package/src/renderers/common/nodes/NodeSampledTexture.js +14 -0
  442. package/src/renderers/common/nodes/NodeSampler.js +14 -0
  443. package/src/renderers/common/nodes/NodeStorageBuffer.js +1 -1
  444. package/src/renderers/common/nodes/NodeUniformBuffer.js +1 -14
  445. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +13 -4
  446. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +8 -8
  447. package/src/renderers/shaders/ShaderChunk/lightprobes_pars_fragment.glsl.js +23 -11
  448. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +21 -2
  449. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +1 -1
  450. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +18 -2
  451. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +104 -7
  452. package/src/renderers/shaders/ShaderChunk/morphcolor_vertex.glsl.js +11 -2
  453. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +36 -20
  454. package/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl.js +5 -0
  455. package/src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl.js +6 -0
  456. package/src/renderers/shaders/ShaderChunk/uv_vertex.glsl.js +5 -0
  457. package/src/renderers/shaders/ShaderChunk.js +0 -2
  458. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +4 -18
  459. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +0 -1
  460. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +0 -1
  461. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +8 -1
  462. package/src/renderers/shaders/ShaderLib.js +3 -0
  463. package/src/renderers/shaders/UniformsLib.js +4 -5
  464. package/src/renderers/webgl/WebGLBackground.js +3 -3
  465. package/src/renderers/webgl/WebGLBindingStates.js +4 -2
  466. package/src/renderers/webgl/WebGLCapabilities.js +7 -1
  467. package/src/renderers/webgl/WebGLEnvironments.js +2 -2
  468. package/src/renderers/webgl/WebGLGeometries.js +42 -14
  469. package/src/renderers/webgl/WebGLMaterials.js +15 -2
  470. package/src/renderers/webgl/WebGLOutput.js +37 -1
  471. package/src/renderers/webgl/WebGLProgram.js +13 -54
  472. package/src/renderers/webgl/WebGLPrograms.js +22 -8
  473. package/src/renderers/webgl/WebGLRenderStates.js +11 -8
  474. package/src/renderers/webgl/WebGLShadowMap.js +6 -4
  475. package/src/renderers/webgl/WebGLState.js +10 -6
  476. package/src/renderers/webgl/WebGLTextures.js +129 -77
  477. package/src/renderers/webgl/WebGLUniforms.js +44 -6
  478. package/src/renderers/webgl/WebGLUniformsGroups.js +75 -69
  479. package/src/renderers/webgl-fallback/WebGLBackend.js +206 -278
  480. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +154 -20
  481. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +45 -42
  482. package/src/renderers/webgl-fallback/utils/WebGLState.js +29 -4
  483. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +129 -49
  484. package/src/renderers/webgl-fallback/utils/WebGLVertexArrayUtils.js +346 -0
  485. package/src/renderers/webgpu/WebGPUBackend.js +140 -82
  486. package/src/renderers/webgpu/WebGPURenderer.js +1 -1
  487. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +10 -10
  488. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +10 -10
  489. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +135 -60
  490. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +128 -55
  491. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +1 -1
  492. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +15 -12
  493. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +55 -19
  494. package/src/renderers/webgpu/utils/WebGPUUtils.js +20 -3
  495. package/src/renderers/webxr/WebXRController.js +3 -3
  496. package/src/renderers/webxr/WebXRManager.js +5 -90
  497. package/src/scenes/Scene.js +4 -4
  498. package/src/textures/CompressedTexture.js +2 -2
  499. package/src/textures/DepthTexture.js +2 -2
  500. package/src/textures/FramebufferTexture.js +11 -0
  501. package/src/textures/Texture.js +29 -1
  502. package/src/textures/TextureSource.js +1 -1
  503. package/src/upe.js +1 -1
  504. package/src/utils.js +4 -4
  505. package/examples/jsm/libs/surfaceNet.js +0 -201
  506. package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +0 -186
@@ -1,6 +1,6 @@
1
- import { DoubleSide } from 'three/webgpu';
1
+ import { AddEquation, CustomBlending, DoubleSide, OneFactor, OneMinusSrcAlphaFactor } from 'three/webgpu';
2
2
  import { MaterialXLogCodes } from './MaterialXLog.js';
3
- import { float, color, mul, clamp, vec2, cos, sin, pow, mix, element, transformNormalToView } from 'three/tsl';
3
+ import { Fn, float, vec3, mul, sub, dot, clamp, vec2, cos, sin, pow, mix, element, transformNormalToView, positionLocal, normalLocal, tangentLocal, bitangentLocal } from 'three/tsl';
4
4
 
5
5
  const mappedStandardSurfaceInputs = new Set( [
6
6
  'base',
@@ -129,6 +129,7 @@ function getConstNumber( node ) {
129
129
  if ( visited.has( cursor ) ) break;
130
130
  visited.add( cursor );
131
131
  if ( typeof cursor.value === 'number' ) return cursor.value;
132
+ if ( cursor.value && cursor.value.isColor && cursor.value.r === cursor.value.g && cursor.value.g === cursor.value.b ) return cursor.value.r;
132
133
  cursor = cursor.node;
133
134
 
134
135
  }
@@ -151,16 +152,17 @@ function isEffectivelyZero( node, epsilon = 1e-6 ) {
151
152
 
152
153
  }
153
154
 
154
- function isEffectivelyOne( node, epsilon = 1e-6 ) {
155
+ // True when `node` has an authored value that differs from `target` (default 0),
156
+ // i.e. it's worth wiring into the material instead of relying on the default.
157
+ function isMeaningfulNode( node, target = 0 ) {
155
158
 
156
- return isConstNear( node, 1, epsilon );
159
+ return hasNodeValue( node ) && isConstNear( node, target ) === false;
157
160
 
158
161
  }
159
162
 
160
163
  function isEnabledWeightNode( node ) {
161
164
 
162
- if ( hasNodeValue( node ) === false ) return false;
163
- return isEffectivelyZero( node ) === false;
165
+ return isMeaningfulNode( node );
164
166
 
165
167
  }
166
168
 
@@ -177,7 +179,7 @@ function setAnisotropy( material, strengthNode, rotationNode ) {
177
179
 
178
180
  function setTransmissionFlags( material, transmissionNode, opacityNode, allowOpacityTransparency = true ) {
179
181
 
180
- if ( allowOpacityTransparency && hasNodeValue( opacityNode ) && isEffectivelyOne( opacityNode ) === false ) {
182
+ if ( allowOpacityTransparency && isMeaningfulNode( opacityNode, 1 ) ) {
181
183
 
182
184
  material.transparent = true;
183
185
 
@@ -201,95 +203,43 @@ function toAttenuationDistance( distanceNode, hasAttenuationColorInput ) {
201
203
 
202
204
  }
203
205
 
204
- function buildGltfOpacityNode( alphaNode, alphaModeNode ) {
206
+ // `inputs` includes the nodedef defaults, `authored` only the inputs present in the document.
207
+ function applyStandardSurface( material, inputs, log, nodeName, authored ) {
205
208
 
206
- const alphaMode = getConstNumber( alphaModeNode );
207
- const roundedMode = alphaMode === null ? 2 : Math.round( alphaMode );
208
- const alpha = alphaNode ?? float( 1 );
209
-
210
- if ( roundedMode === 0 ) return float( 1 );
211
- if ( roundedMode === 1 ) return alpha;
212
- return alpha;
213
-
214
- }
215
-
216
- function applyStandardSurface( material, inputs, log, nodeName ) {
217
-
218
- let colorNode = null;
219
- if ( inputs.base && inputs.base_color ) colorNode = mul( inputs.base, inputs.base_color );
220
- else if ( inputs.base ) colorNode = inputs.base;
221
- else if ( inputs.base_color ) colorNode = inputs.base_color;
222
-
223
- if ( inputs.coat_color ) {
224
-
225
- colorNode = colorNode ? mul( colorNode, inputs.coat_color ) : colorNode;
226
-
227
- }
228
-
229
- const roughnessNode = inputs.specular_roughness;
230
- const opacityNode = hasNodeValue( inputs.opacity ) ? element( inputs.opacity, 0 ) : undefined;
231
- const transmissionNode = inputs.transmission;
232
- const transmissionColorNode = inputs.transmission_color;
233
- const transmissionEnabled = isEnabledWeightNode( transmissionNode );
209
+ const coatEnabled = isEnabledWeightNode( inputs.coat );
234
210
  const sheenEnabled = isEnabledWeightNode( inputs.sheen );
235
- const clearcoatEnabled = isEnabledWeightNode( inputs.coat );
236
-
237
- let emissiveNode = inputs.emission;
238
- const emissionColorNode = inputs.emission_color;
239
- if ( hasNodeValue( emissionColorNode ) ) {
240
-
241
- emissiveNode = emissiveNode ? mul( emissiveNode, emissionColorNode ) : emissionColorNode;
242
-
243
- }
211
+ const transmissionEnabled = isEnabledWeightNode( inputs.transmission );
212
+ const thinFilmEnabled = isEnabledWeightNode( inputs.thin_film_thickness );
244
213
 
245
- const thinFilmThicknessNode = inputs.thin_film_thickness;
246
- const thinFilmIorNode = clamp( inputs.thin_film_IOR || float( 1.5 ), float( 1.0 ), float( 2.333 ) );
247
- const thinFilmEnabled = isEnabledWeightNode( thinFilmThicknessNode );
248
- const transmissionTintNode = hasNodeValue( transmissionColorNode ) ? transmissionColorNode : color( 1, 1, 1 );
214
+ let colorNode = mul( inputs.base, inputs.base_color );
215
+ if ( coatEnabled ) colorNode = mul( colorNode, inputs.coat_color );
249
216
 
250
217
  if ( transmissionEnabled ) {
251
218
 
252
- const baseForTransmissionMix = colorNode || color( 0.8, 0.8, 0.8 );
253
219
  // Suppress diffuse/base tint as transmission ramps up.
254
- colorNode = mix( baseForTransmissionMix, transmissionTintNode, transmissionNode );
220
+ colorNode = mix( colorNode, inputs.transmission_color, inputs.transmission );
255
221
 
256
222
  }
257
223
 
258
- material.colorNode = colorNode || color( 0.8, 0.8, 0.8 );
259
- if ( hasNodeValue( opacityNode ) && isEffectivelyOne( opacityNode ) === false ) {
224
+ const opacityNode = element( inputs.opacity, 0 );
260
225
 
261
- material.opacityNode = opacityNode;
226
+ material.colorNode = colorNode;
227
+ material.roughnessNode = inputs.specular_roughness;
228
+ material.specularColorNode = inputs.specular_color;
262
229
 
263
- }
264
-
265
- material.roughnessNode = roughnessNode || float( 0.2 );
266
- if ( hasNodeValue( inputs.metalness ) && isEffectivelyZero( inputs.metalness ) === false ) {
267
-
268
- material.metalnessNode = inputs.metalness;
269
-
270
- }
271
-
272
- if ( hasNodeValue( inputs.specular ) && isEffectivelyOne( inputs.specular ) === false ) {
273
-
274
- material.specularIntensityNode = inputs.specular;
275
-
276
- }
277
-
278
- material.specularColorNode = inputs.specular_color || color( 1, 1, 1 );
279
- const iorNode = inputs.specular_IOR;
280
- if ( hasNodeValue( iorNode ) && isConstNear( iorNode, 1.5 ) === false ) {
281
-
282
- material.iorNode = iorNode;
283
-
284
- }
230
+ if ( isMeaningfulNode( opacityNode, 1 ) ) material.opacityNode = opacityNode;
231
+ if ( isMeaningfulNode( inputs.metalness ) ) material.metalnessNode = inputs.metalness;
232
+ if ( isMeaningfulNode( inputs.specular, 1 ) ) material.specularIntensityNode = inputs.specular;
233
+ if ( isMeaningfulNode( inputs.specular_IOR, 1.5 ) ) material.iorNode = inputs.specular_IOR;
285
234
 
286
235
  setAnisotropy( material, inputs.specular_anisotropy, inputs.specular_rotation );
287
236
 
288
237
  if ( transmissionEnabled ) {
289
238
 
290
- material.transmissionNode = transmissionNode;
291
- if ( hasNodeValue( transmissionColorNode ) ) material.transmissionColorNode = transmissionColorNode;
292
- if ( hasNodeValue( inputs.transmission_depth ) && isEffectivelyZero( inputs.transmission_depth ) === false ) {
239
+ material.transmissionNode = inputs.transmission;
240
+ material.transmissionColorNode = inputs.transmission_color;
241
+
242
+ if ( isMeaningfulNode( inputs.transmission_depth ) ) {
293
243
 
294
244
  material.thicknessNode = inputs.transmission_depth;
295
245
 
@@ -305,143 +255,97 @@ function applyStandardSurface( material, inputs, log, nodeName ) {
305
255
 
306
256
  if ( thinFilmEnabled ) {
307
257
 
308
- material.iridescenceThicknessNode = thinFilmThicknessNode;
309
- material.iridescenceIORNode = thinFilmIorNode;
310
258
  material.iridescenceNode = float( 1 );
259
+ material.iridescenceThicknessNode = inputs.thin_film_thickness;
260
+ material.iridescenceIORNode = clamp( inputs.thin_film_IOR, float( 1.0 ), float( 2.333 ) );
311
261
 
312
262
  }
313
263
 
314
- const sheenColor = inputs.sheen_color || color( 1, 1, 1 );
315
264
  if ( sheenEnabled ) {
316
265
 
317
- const sheenRoughness = hasNodeValue( inputs.sheen_roughness ) ? inputs.sheen_roughness : float( 0.3 );
318
- material.sheenNode = mul( inputs.sheen, sheenColor );
319
- material.sheenRoughnessNode = sheenRoughness;
266
+ material.sheenNode = mul( inputs.sheen, inputs.sheen_color );
267
+ material.sheenRoughnessNode = inputs.sheen_roughness;
320
268
 
321
269
  }
322
270
 
323
- if ( clearcoatEnabled ) {
271
+ if ( coatEnabled ) {
324
272
 
325
273
  material.clearcoatNode = inputs.coat;
326
- if ( hasNodeValue( inputs.coat_roughness ) ) {
327
-
328
- material.clearcoatRoughnessNode = inputs.coat_roughness;
329
-
330
- }
331
-
332
- }
333
-
334
- if ( clearcoatEnabled && hasNodeValue( inputs.coat_normal ) ) {
335
-
336
- material.clearcoatNormalNode = transformNormalToView( inputs.coat_normal );
274
+ material.clearcoatRoughnessNode = inputs.coat_roughness;
275
+ if ( hasNodeValue( inputs.coat_normal ) ) material.clearcoatNormalNode = transformNormalToView( inputs.coat_normal );
337
276
 
338
277
  }
339
278
 
340
279
  if ( hasNodeValue( inputs.normal ) ) material.normalNode = transformNormalToView( inputs.normal );
341
- if ( hasNodeValue( emissiveNode ) ) material.emissiveNode = emissiveNode;
280
+ if ( isEffectivelyZero( inputs.emission ) === false ) material.emissiveNode = mul( inputs.emission, inputs.emission_color );
342
281
 
343
- setTransmissionFlags( material, transmissionNode, opacityNode );
344
- warnIgnoredInputs( inputs, mappedStandardSurfaceInputs, log, 'standard_surface', nodeName );
282
+ setTransmissionFlags( material, inputs.transmission, opacityNode );
283
+ warnIgnoredInputs( authored, mappedStandardSurfaceInputs, log, 'standard_surface', nodeName );
345
284
 
346
285
  }
347
286
 
348
- function applyGltfPbrSurface( material, inputs, log, nodeName ) {
287
+ function applyGltfPbrSurface( material, inputs, log, nodeName, authored ) {
349
288
 
289
+ // alpha_mode: 0 = OPAQUE, 1 = MASK, 2 = BLEND. A connected alpha_mode is treated as BLEND.
350
290
  const alphaModeLiteral = getConstNumber( inputs.alpha_mode );
351
291
  const alphaMode = alphaModeLiteral === null ? 2 : Math.round( alphaModeLiteral );
352
292
  const isAlphaMaskMode = alphaMode === 1;
353
293
  const isAlphaBlendMode = alphaMode === 2;
354
- const opacityNode = buildGltfOpacityNode( inputs.alpha, inputs.alpha_mode );
355
- const alphaCutoffNode = inputs.alpha_cutoff ?? float( 0.5 );
356
- const hasAttenuationColorInput = Object.prototype.hasOwnProperty.call( inputs, 'attenuation_color' );
294
+ const opacityNode = alphaMode === 0 ? float( 1 ) : inputs.alpha;
295
+ const hasAttenuationColorInput = hasNodeValue( authored.attenuation_color );
357
296
  const transmissionEnabled = isEnabledWeightNode( inputs.transmission );
358
297
  const clearcoatEnabled = isEnabledWeightNode( inputs.clearcoat );
359
- const sheenEnabled = hasNodeValue( inputs.sheen_color ) || isEnabledWeightNode( inputs.sheen_roughness );
298
+ const sheenEnabled = isMeaningfulNode( inputs.sheen_color ) || isEnabledWeightNode( inputs.sheen_roughness );
360
299
  const iridescenceEnabled = isEnabledWeightNode( inputs.iridescence );
361
300
 
362
- material.colorNode = inputs.base_color || color( 1, 1, 1 );
363
- if ( hasNodeValue( inputs.occlusion ) ) material.aoNode = inputs.occlusion;
364
- material.roughnessNode = inputs.roughness || float( 1 );
365
- material.metalnessNode = inputs.metallic || float( 1 );
366
- if ( hasNodeValue( inputs.specular ) && isEffectivelyOne( inputs.specular ) === false ) {
367
-
368
- material.specularIntensityNode = inputs.specular;
369
-
370
- }
371
-
372
- material.specularColorNode = inputs.specular_color || color( 1, 1, 1 );
373
- if ( hasNodeValue( inputs.ior ) && isConstNear( inputs.ior, 1.5 ) === false ) {
374
-
375
- material.iorNode = inputs.ior;
376
-
377
- }
378
-
379
- if ( hasNodeValue( opacityNode ) && isEffectivelyOne( opacityNode ) === false ) {
301
+ material.colorNode = inputs.base_color;
302
+ material.roughnessNode = inputs.roughness;
303
+ material.metalnessNode = inputs.metallic;
304
+ material.specularColorNode = inputs.specular_color;
305
+ material.attenuationColorNode = inputs.attenuation_color;
306
+ material.attenuationDistanceNode = toAttenuationDistance( inputs.attenuation_distance, hasAttenuationColorInput );
380
307
 
381
- material.opacityNode = opacityNode;
382
-
383
- }
308
+ if ( isMeaningfulNode( inputs.occlusion, 1 ) ) material.aoNode = inputs.occlusion;
309
+ if ( isMeaningfulNode( inputs.specular, 1 ) ) material.specularIntensityNode = inputs.specular;
310
+ if ( isMeaningfulNode( inputs.ior, 1.5 ) ) material.iorNode = inputs.ior;
311
+ if ( isMeaningfulNode( opacityNode, 1 ) ) material.opacityNode = opacityNode;
384
312
 
385
313
  if ( isAlphaMaskMode ) {
386
314
 
387
- material.alphaTestNode = alphaCutoffNode;
388
- const alphaCutoff = getConstNumber( alphaCutoffNode );
315
+ material.alphaTestNode = inputs.alpha_cutoff;
316
+ const alphaCutoff = getConstNumber( inputs.alpha_cutoff );
389
317
  if ( alphaCutoff !== null ) material.alphaTest = alphaCutoff;
390
318
 
391
319
  }
392
320
 
393
- if ( transmissionEnabled ) {
394
-
395
- material.transmissionNode = inputs.transmission;
396
-
397
- }
321
+ if ( transmissionEnabled ) material.transmissionNode = inputs.transmission;
398
322
 
399
323
  if ( clearcoatEnabled ) {
400
324
 
401
325
  material.clearcoatNode = inputs.clearcoat;
402
- if ( hasNodeValue( inputs.clearcoat_roughness ) && isEffectivelyZero( inputs.clearcoat_roughness ) === false ) {
403
-
404
- material.clearcoatRoughnessNode = inputs.clearcoat_roughness;
405
-
406
- }
326
+ material.clearcoatRoughnessNode = inputs.clearcoat_roughness;
327
+ if ( hasNodeValue( inputs.clearcoat_normal ) ) material.clearcoatNormalNode = transformNormalToView( inputs.clearcoat_normal );
407
328
 
408
329
  }
409
330
 
410
331
  if ( sheenEnabled ) {
411
332
 
412
- const sheenColor = hasNodeValue( inputs.sheen_color ) ? inputs.sheen_color : color( 0, 0, 0 );
413
- const sheenRoughness = hasNodeValue( inputs.sheen_roughness ) ? inputs.sheen_roughness : float( 0 );
414
- material.sheenRoughnessNode = sheenRoughness;
415
- material.sheenNode = sheenColor;
333
+ material.sheenNode = inputs.sheen_color;
334
+ material.sheenRoughnessNode = inputs.sheen_roughness;
416
335
 
417
336
  }
418
337
 
419
338
  if ( iridescenceEnabled ) {
420
339
 
421
340
  material.iridescenceNode = inputs.iridescence;
422
- if ( hasNodeValue( inputs.iridescence_ior ) && isConstNear( inputs.iridescence_ior, 1.3 ) === false ) {
423
-
424
- material.iridescenceIORNode = inputs.iridescence_ior;
425
-
426
- }
427
-
428
- if ( hasNodeValue( inputs.iridescence_thickness ) && isConstNear( inputs.iridescence_thickness, 100 ) === false ) {
429
-
430
- material.iridescenceThicknessNode = inputs.iridescence_thickness;
431
-
432
- }
341
+ material.iridescenceIORNode = inputs.iridescence_ior;
342
+ material.iridescenceThicknessNode = inputs.iridescence_thickness;
433
343
 
434
344
  }
435
345
 
436
- material.attenuationDistanceNode = toAttenuationDistance( inputs.attenuation_distance, hasAttenuationColorInput );
437
- material.attenuationColorNode = inputs.attenuation_color || color( 1, 1, 1 );
438
- if ( hasNodeValue( inputs.thickness ) ) {
439
-
440
- if ( isEffectivelyZero( inputs.thickness ) === false ) {
346
+ if ( isMeaningfulNode( inputs.thickness ) ) {
441
347
 
442
- material.thicknessNode = inputs.thickness;
443
-
444
- }
348
+ material.thicknessNode = inputs.thickness;
445
349
 
446
350
  } else if ( transmissionEnabled ) {
447
351
 
@@ -450,184 +354,182 @@ function applyGltfPbrSurface( material, inputs, log, nodeName ) {
450
354
 
451
355
  }
452
356
 
453
- if ( hasNodeValue( inputs.dispersion ) && isEffectivelyZero( inputs.dispersion ) === false ) {
357
+ if ( isMeaningfulNode( inputs.dispersion ) ) material.dispersionNode = inputs.dispersion;
454
358
 
455
- material.dispersionNode = inputs.dispersion;
456
-
457
- }
458
-
459
- const anisotropyStrength = inputs.anisotropy_strength;
460
- const anisotropyRotation = inputs.anisotropy_rotation;
461
- setAnisotropy( material, anisotropyStrength, anisotropyRotation );
359
+ setAnisotropy( material, inputs.anisotropy_strength, inputs.anisotropy_rotation );
462
360
 
463
361
  if ( hasNodeValue( inputs.normal ) ) material.normalNode = transformNormalToView( inputs.normal );
464
- if ( hasNodeValue( inputs.clearcoat_normal ) ) {
465
-
466
- material.clearcoatNormalNode = transformNormalToView( inputs.clearcoat_normal );
467
-
468
- }
469
-
470
- if ( hasNodeValue( inputs.emissive ) && hasNodeValue( inputs.emissive_strength ) )
471
- material.emissiveNode = mul( inputs.emissive, inputs.emissive_strength );
472
- else if ( hasNodeValue( inputs.emissive ) ) material.emissiveNode = inputs.emissive;
362
+ if ( isEffectivelyZero( inputs.emissive ) === false ) material.emissiveNode = mul( inputs.emissive, inputs.emissive_strength );
473
363
 
474
364
  setTransmissionFlags( material, inputs.transmission, opacityNode, isAlphaBlendMode );
475
- warnIgnoredInputs( inputs, mappedGltfPbrInputs, log, 'gltf_pbr', nodeName );
365
+ warnIgnoredInputs( authored, mappedGltfPbrInputs, log, 'gltf_pbr', nodeName );
476
366
 
477
367
  }
478
368
 
479
- function applyOpenPbrSurface( material, inputs, log, nodeName ) {
369
+ function applyOpenPbrSurface( material, inputs, log, nodeName, authored ) {
480
370
 
481
- const baseWeight = inputs.base_weight || float( 1 );
482
- const baseColor = inputs.base_color || color( 0.8, 0.8, 0.8 );
483
371
  const coatEnabled = isEnabledWeightNode( inputs.coat_weight );
484
372
  const fuzzEnabled = isEnabledWeightNode( inputs.fuzz_weight );
485
373
  const transmissionEnabled = isEnabledWeightNode( inputs.transmission_weight );
486
374
  const thinFilmEnabled = isEnabledWeightNode( inputs.thin_film_weight );
487
- material.colorNode = mul( baseWeight, baseColor );
488
375
 
489
- if ( hasNodeValue( inputs.base_metalness ) && isEffectivelyZero( inputs.base_metalness ) === false ) {
376
+ material.colorNode = mul( inputs.base_weight, inputs.base_color );
377
+ material.roughnessNode = inputs.specular_roughness;
378
+ material.specularColorNode = inputs.specular_color;
490
379
 
491
- material.metalnessNode = inputs.base_metalness;
380
+ if ( isMeaningfulNode( inputs.base_metalness ) ) material.metalnessNode = inputs.base_metalness;
381
+ if ( isMeaningfulNode( inputs.specular_weight, 1 ) ) material.specularIntensityNode = inputs.specular_weight;
382
+ if ( isMeaningfulNode( inputs.specular_ior, 1.5 ) ) material.iorNode = inputs.specular_ior;
492
383
 
493
- }
384
+ setAnisotropy( material, inputs.specular_roughness_anisotropy, float( 0 ) );
494
385
 
495
- material.roughnessNode = inputs.specular_roughness || float( 0.3 );
496
- if ( hasNodeValue( inputs.specular_weight ) && isEffectivelyOne( inputs.specular_weight ) === false ) {
386
+ if ( coatEnabled ) {
497
387
 
498
- material.specularIntensityNode = inputs.specular_weight;
388
+ // Scale the coat weight by the coat's Fresnel reflectance at normal incidence relative
389
+ // to the fixed F0 of 0.04 that the three.js clearcoat model assumes.
390
+ const coatF0Node = inputs.coat_ior.sub( float( 1 ) ).div( inputs.coat_ior.add( float( 1 ) ) );
391
+ const normalizedClearcoatNode = coatF0Node.mul( coatF0Node ).div( float( 0.04 ) );
392
+ material.clearcoatNode = clamp( inputs.coat_weight.mul( normalizedClearcoatNode ), float( 0 ), float( 1 ) );
393
+ material.clearcoatRoughnessNode = inputs.coat_roughness;
394
+ if ( hasNodeValue( inputs.geometry_coat_normal ) ) material.clearcoatNormalNode = transformNormalToView( inputs.geometry_coat_normal );
499
395
 
500
396
  }
501
397
 
502
- material.specularColorNode = inputs.specular_color || color( 1, 1, 1 );
503
- const openPbrIorNode = inputs.specular_ior;
504
- if ( hasNodeValue( openPbrIorNode ) && isConstNear( openPbrIorNode, 1.5 ) === false ) {
398
+ if ( fuzzEnabled ) {
505
399
 
506
- material.iorNode = openPbrIorNode;
400
+ material.sheenNode = mul( inputs.fuzz_weight, inputs.fuzz_color );
401
+ material.sheenRoughnessNode = pow( inputs.fuzz_roughness, float( 1.5 ) );
507
402
 
508
403
  }
509
404
 
510
- setAnisotropy( material, inputs.specular_roughness_anisotropy, float( 0 ) );
405
+ if ( transmissionEnabled ) {
511
406
 
512
- if ( coatEnabled ) {
407
+ material.transmissionNode = inputs.transmission_weight;
408
+ material.attenuationColorNode = inputs.transmission_color;
513
409
 
514
- const coatWeightNode = inputs.coat_weight || float( 0 );
515
- if ( hasNodeValue( inputs.coat_ior ) ) {
410
+ if ( isMeaningfulNode( inputs.transmission_depth ) ) {
516
411
 
517
- const coatIorNode = inputs.coat_ior;
518
- const coatIorMinusOne = coatIorNode.sub( float( 1 ) );
519
- const coatIorPlusOne = coatIorNode.add( float( 1 ) );
520
- const coatF0Node = coatIorMinusOne.div( coatIorPlusOne );
521
- const normalizedClearcoatNode = coatF0Node.mul( coatF0Node ).div( float( 0.04 ) );
522
- material.clearcoatNode = clamp( coatWeightNode.mul( normalizedClearcoatNode ), float( 0 ), float( 1 ) );
412
+ material.thicknessNode = hasNodeValue( inputs.geometry_thin_walled )
413
+ ? inputs.geometry_thin_walled.select( float( 0 ), inputs.transmission_depth )
414
+ : inputs.transmission_depth;
415
+ material.attenuationDistanceNode = inputs.transmission_depth;
523
416
 
524
417
  } else {
525
418
 
526
- material.clearcoatNode = coatWeightNode;
419
+ // Keep transmissive OpenPBR materials volumetric even when depth is omitted.
420
+ material.thickness = 1;
527
421
 
528
422
  }
529
423
 
530
- if ( hasNodeValue( inputs.coat_roughness ) && isEffectivelyZero( inputs.coat_roughness ) === false ) {
424
+ if ( isMeaningfulNode( inputs.transmission_dispersion_scale ) ) {
531
425
 
532
- material.clearcoatRoughnessNode = inputs.coat_roughness;
426
+ material.dispersionNode = inputs.transmission_dispersion_scale.mul( float( 20 ) ).div( inputs.transmission_dispersion_abbe_number );
533
427
 
534
428
  }
535
429
 
536
- if ( hasNodeValue( inputs.geometry_coat_normal ) ) {
430
+ }
537
431
 
538
- material.clearcoatNormalNode = transformNormalToView( inputs.geometry_coat_normal );
432
+ if ( isMeaningfulNode( inputs.geometry_opacity, 1 ) ) material.opacityNode = inputs.geometry_opacity;
433
+ if ( hasNodeValue( inputs.geometry_normal ) ) material.normalNode = transformNormalToView( inputs.geometry_normal );
539
434
 
540
- }
435
+ if ( thinFilmEnabled ) {
436
+
437
+ material.iridescenceNode = inputs.thin_film_weight;
438
+ // OpenPBR thin film thickness is in micrometers, three.js expects nanometers.
439
+ material.iridescenceThicknessNode = inputs.thin_film_thickness.mul( float( 1000 ) );
440
+ material.iridescenceIORNode = inputs.thin_film_ior;
541
441
 
542
442
  }
543
443
 
544
- const fuzzWeight = inputs.fuzz_weight || float( 0 );
545
- const fuzzColor = inputs.fuzz_color || color( 1, 1, 1 );
546
- if ( fuzzEnabled ) {
444
+ if ( isEffectivelyZero( inputs.emission_luminance ) === false ) material.emissiveNode = mul( inputs.emission_color, inputs.emission_luminance );
547
445
 
548
- material.sheenNode = mul( fuzzWeight, fuzzColor );
549
- if ( hasNodeValue( inputs.fuzz_roughness ) ) {
446
+ if ( isMeaningfulNode( inputs.geometry_opacity, 1 ) ) material.transparent = true;
447
+ if ( transmissionEnabled ) material.transparent = true;
550
448
 
551
- material.sheenRoughnessNode = pow( inputs.fuzz_roughness, float( 1.5 ) );
449
+ setTransmissionFlags( material, inputs.transmission_weight, inputs.geometry_opacity );
450
+ warnIgnoredInputs( authored, mappedOpenPbrInputs, log, 'open_pbr_surface', nodeName );
552
451
 
553
- }
452
+ }
554
453
 
555
- }
454
+ // <displacement> maps onto vertex displacement like MeshStandardMaterial.displacementMap:
455
+ // scalar displacement moves along the normal, vector displacement is authored in
456
+ // (dPdu, dPdv, N) tangent space. `inputTypes` tells the two nodedefs apart.
457
+ function applyDisplacement( material, inputs, log, nodeName, authored, inputTypes = {} ) {
556
458
 
557
- if ( transmissionEnabled ) {
459
+ const displacementNode = inputs.displacement;
460
+ if ( ! hasNodeValue( displacementNode ) || isEffectivelyZero( displacementNode ) ) return;
558
461
 
559
- material.transmissionNode = inputs.transmission_weight;
560
- if ( hasNodeValue( inputs.transmission_color ) ) material.attenuationColorNode = inputs.transmission_color;
462
+ const scaleNode = hasNodeValue( inputs.scale ) ? inputs.scale : float( 1 );
463
+ let offsetNode;
561
464
 
562
- }
465
+ if ( inputTypes.displacement === 'vector3' ) {
563
466
 
564
- const transmissionDepthNode = inputs.transmission_depth;
565
- if ( transmissionEnabled && hasNodeValue( transmissionDepthNode ) && isEffectivelyZero( transmissionDepthNode ) === false ) {
467
+ const vector = vec3( displacementNode ).mul( scaleNode );
566
468
 
567
- material.thicknessNode = hasNodeValue( inputs.geometry_thin_walled )
568
- ? inputs.geometry_thin_walled.select( float( 0 ), transmissionDepthNode )
569
- : transmissionDepthNode;
570
- material.attenuationDistanceNode = transmissionDepthNode;
469
+ // tangentLocal/bitangentLocal need a tangent attribute; without one the
470
+ // bitangent is NaN, so fall back to displacing along the normal only.
471
+ offsetNode = Fn( ( builder ) => {
571
472
 
572
- } else if ( transmissionEnabled ) {
473
+ if ( builder.geometry.hasAttribute( 'tangent' ) ) {
573
474
 
574
- // Keep transmissive OpenPBR materials volumetric even when depth is omitted.
575
- material.thickness = 1;
475
+ return tangentLocal.mul( vector.x ).add( bitangentLocal.mul( vector.y ) ).add( normalLocal.mul( vector.z ) );
576
476
 
577
- }
477
+ }
578
478
 
579
- const transmissionDispersionAbbe = inputs.transmission_dispersion_abbe_number || float( 20 );
580
- if ( transmissionEnabled && hasNodeValue( inputs.transmission_dispersion_scale ) && isEffectivelyZero( inputs.transmission_dispersion_scale ) === false ) {
479
+ return normalLocal.normalize().mul( vector.z );
581
480
 
582
- material.dispersionNode = inputs.transmission_dispersion_scale.mul( float( 20 ) ).div( transmissionDispersionAbbe );
481
+ } )();
583
482
 
584
- }
483
+ } else {
585
484
 
586
- if ( hasNodeValue( inputs.geometry_opacity ) && isEffectivelyOne( inputs.geometry_opacity ) === false ) {
587
-
588
- material.opacityNode = inputs.geometry_opacity;
485
+ offsetNode = normalLocal.normalize().mul( float( displacementNode ).mul( scaleNode ) );
589
486
 
590
487
  }
591
488
 
592
- if ( hasNodeValue( inputs.geometry_normal ) ) material.normalNode = transformNormalToView( inputs.geometry_normal );
593
-
594
- if ( thinFilmEnabled ) {
489
+ material.positionNode = positionLocal.add( offsetNode );
595
490
 
596
- material.iridescenceNode = inputs.thin_film_weight;
597
- if ( hasNodeValue( inputs.thin_film_thickness ) && isConstNear( inputs.thin_film_thickness, 0.5 ) === false ) {
598
-
599
- material.iridescenceThicknessNode = inputs.thin_film_thickness.mul( float( 1000 ) );
491
+ }
600
492
 
601
- }
493
+ const mappedSurfaceUnlitInputs = new Set( [ 'emission', 'emission_color', 'transmission', 'transmission_color', 'opacity' ] );
602
494
 
603
- if ( hasNodeValue( inputs.thin_film_ior ) && isConstNear( inputs.thin_film_ior, 1.4 ) === false ) {
495
+ // <surface_unlit> renders without lighting (MeshBasicNodeMaterial). MaterialX computes
496
+ // color = emission * emission_color * opacity and transparency = mix( 1, transmission * transmission_color, opacity ),
497
+ // and the result is color + transparency * background: blending ( One, OneMinusSrcAlpha ) with
498
+ // alpha = 1 - transparency. A colored transmission becomes grey, since blending has one alpha.
499
+ function applySurfaceUnlit( material, inputs, log, nodeName, authored ) {
604
500
 
605
- material.iridescenceIORNode = inputs.thin_film_ior;
501
+ const emission = inputs.emission;
502
+ const emissionColor = inputs.emission_color;
503
+ const opacity = inputs.opacity;
606
504
 
607
- }
505
+ material.colorNode = mul( mul( emissionColor, emission ), opacity );
608
506
 
609
- }
507
+ if ( isMeaningfulNode( inputs.opacity, 1 ) || isEnabledWeightNode( inputs.transmission ) ) {
610
508
 
611
- const emissionColor = hasNodeValue( inputs.emission_color ) ? inputs.emission_color : color( 1, 1, 1 );
612
- const emissionLuminance = hasNodeValue( inputs.emission_luminance ) ? inputs.emission_luminance : float( 0 );
613
- if ( isEffectivelyZero( emissionLuminance ) === false ) {
509
+ const transmission = inputs.transmission;
510
+ const transmissionColor = inputs.transmission_color;
511
+ const transparency = mix( vec3( 1, 1, 1 ), mul( transmissionColor, transmission ), opacity );
614
512
 
615
- material.emissiveNode = mul( emissionColor, emissionLuminance );
513
+ material.opacityNode = sub( 1, dot( transparency, vec3( 1 / 3, 1 / 3, 1 / 3 ) ) );
514
+ material.transparent = true;
515
+ // The color is already multiplied by the opacity.
516
+ material.blending = CustomBlending;
517
+ material.blendEquation = AddEquation;
518
+ material.blendSrc = OneFactor;
519
+ material.blendDst = OneMinusSrcAlphaFactor;
616
520
 
617
521
  }
618
522
 
619
- if ( hasNodeValue( inputs.geometry_opacity ) && isEffectivelyOne( inputs.geometry_opacity ) === false ) material.transparent = true;
620
- if ( transmissionEnabled ) material.transparent = true;
621
-
622
- setTransmissionFlags( material, inputs.transmission_weight, inputs.geometry_opacity );
623
- warnIgnoredInputs( inputs, mappedOpenPbrInputs, log, 'open_pbr_surface', nodeName );
523
+ warnIgnoredInputs( authored, mappedSurfaceUnlitInputs, log, 'surface_unlit', nodeName );
624
524
 
625
525
  }
626
526
 
627
527
  const MaterialXSurfaceMappings = {
528
+ surface_unlit: applySurfaceUnlit,
628
529
  standard_surface: applyStandardSurface,
629
530
  gltf_pbr: applyGltfPbrSurface,
630
531
  open_pbr_surface: applyOpenPbrSurface,
532
+ displacement: applyDisplacement,
631
533
  };
632
534
 
633
535
  const surfaceMapperRegistry = new Map( Object.entries( MaterialXSurfaceMappings ).map( ( [ category, apply ] ) => [
@@ -655,6 +557,8 @@ export {
655
557
  applyStandardSurface,
656
558
  applyGltfPbrSurface,
657
559
  applyOpenPbrSurface,
560
+ applyDisplacement,
561
+ applySurfaceUnlit,
658
562
  mappedStandardSurfaceInputs,
659
563
  mappedGltfPbrInputs,
660
564
  mappedOpenPbrInputs,