@gnsx/three 0.185.16 → 0.186.1

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 (417) hide show
  1. package/build/three.cjs +10 -82600
  2. package/build/three.core.js +1303 -728
  3. package/build/three.module.js +439 -338
  4. package/build/three.tsl.js +74 -44
  5. package/build/three.webgpu.js +6036 -2184
  6. package/build/three.webgpu.nodes.js +6020 -2184
  7. package/examples/jsm/Addons.js +6 -6
  8. package/examples/jsm/controls/ArcballControls.js +1 -1
  9. package/examples/jsm/controls/FirstPersonControls.js +44 -20
  10. package/examples/jsm/controls/OrbitControls.js +9 -0
  11. package/examples/jsm/controls/TrackballControls.js +109 -4
  12. package/examples/jsm/csm/CSMShadowNode.js +13 -0
  13. package/examples/jsm/exporters/GLTFExporter.js +23 -7
  14. package/examples/jsm/exporters/USDZExporter.js +2 -2
  15. package/examples/jsm/generators/CityGenerator.js +377 -45
  16. package/examples/jsm/generators/ForestGenerator.js +12 -12
  17. package/examples/jsm/generators/TerrainGenerator.js +49 -37
  18. package/examples/jsm/generators/TreeGenerator.js +70 -76
  19. package/examples/jsm/generators/city/BenchGenerator.js +127 -0
  20. package/examples/jsm/generators/city/CarGenerator.js +479 -0
  21. package/examples/jsm/generators/city/CityGeneratorUtils.js +31 -0
  22. package/examples/jsm/generators/city/HydrantGenerator.js +106 -0
  23. package/examples/jsm/generators/city/InstancedMeshGenerator.js +86 -0
  24. package/examples/jsm/generators/city/PersonGenerator.js +447 -0
  25. package/examples/jsm/generators/city/SidewalkGenerator.js +33 -38
  26. package/examples/jsm/generators/city/SkyscraperGenerator.js +448 -48
  27. package/examples/jsm/generators/city/StreetTreeGenerator.js +231 -0
  28. package/examples/jsm/generators/city/StreetlightGenerator.js +100 -0
  29. package/examples/jsm/generators/city/TrafficlightGenerator.js +106 -0
  30. package/examples/jsm/generators/city/TrashcanGenerator.js +100 -0
  31. package/examples/jsm/geometries/BoxLineGeometry.js +1 -1
  32. package/examples/jsm/geometries/ParametricGeometry.js +1 -1
  33. package/examples/jsm/geometries/RoundedBoxGeometry.js +1 -1
  34. package/examples/jsm/gpgpu/CountingSort.js +271 -0
  35. package/examples/jsm/helpers/LightProbeGridHelper.js +60 -239
  36. package/examples/jsm/helpers/LightProbeGridHelperWebGL.js +221 -0
  37. package/examples/jsm/inspector/Extension.js +94 -0
  38. package/examples/jsm/inspector/Inspector.js +145 -41
  39. package/examples/jsm/inspector/RendererInspector.js +100 -52
  40. package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +2609 -0
  41. package/examples/jsm/inspector/extensions/color-grading/ColorWheel.js +352 -0
  42. package/examples/jsm/inspector/extensions/color-grading/CurveEditor.js +599 -0
  43. package/examples/jsm/inspector/extensions/color-grading/LUT3DStyle.js +1201 -0
  44. package/examples/jsm/inspector/extensions/color-grading/LUTMath.js +788 -0
  45. package/examples/jsm/inspector/extensions/color-grading/modules/BrightnessModule.js +72 -0
  46. package/examples/jsm/inspector/extensions/color-grading/modules/ColorWheelModule.js +112 -0
  47. package/examples/jsm/inspector/extensions/color-grading/modules/ContrastModule.js +82 -0
  48. package/examples/jsm/inspector/extensions/color-grading/modules/CurvesModule.js +109 -0
  49. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureHueModule.js +110 -0
  50. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureModule.js +73 -0
  51. package/examples/jsm/inspector/extensions/color-grading/modules/HueModule.js +78 -0
  52. package/examples/jsm/inspector/extensions/color-grading/modules/ImportedCubeModule.js +89 -0
  53. package/examples/jsm/inspector/extensions/color-grading/modules/Module.js +285 -0
  54. package/examples/jsm/inspector/extensions/color-grading/modules/OutputModule.js +101 -0
  55. package/examples/jsm/inspector/extensions/color-grading/modules/RendererModule.js +225 -0
  56. package/examples/jsm/inspector/extensions/color-grading/modules/SatVibranceModule.js +102 -0
  57. package/examples/jsm/inspector/extensions/color-grading/modules/SaturationModule.js +76 -0
  58. package/examples/jsm/inspector/extensions/color-grading/modules/VibranceModule.js +76 -0
  59. package/examples/jsm/inspector/extensions/color-grading/modules/WhiteBalanceModule.js +86 -0
  60. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +26 -31
  61. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -0
  62. package/examples/jsm/inspector/tabs/Memory.js +0 -2
  63. package/examples/jsm/inspector/tabs/Settings.js +4 -0
  64. package/examples/jsm/inspector/tabs/Timeline.js +223 -171
  65. package/examples/jsm/inspector/tabs/Viewer.js +515 -21
  66. package/examples/jsm/inspector/ui/List.js +15 -9
  67. package/examples/jsm/inspector/ui/Profiler.js +170 -14
  68. package/examples/jsm/inspector/ui/Style.js +269 -23
  69. package/examples/jsm/inspector/ui/Tab.js +2 -0
  70. package/examples/jsm/inspector/ui/Values.js +14 -2
  71. package/examples/jsm/interactive/HTMLMesh.js +19 -3
  72. package/examples/jsm/lighting/LightProbeGrid.js +484 -889
  73. package/examples/jsm/lighting/LightProbeGridUtils.js +107 -0
  74. package/examples/jsm/lighting/LightProbeGridWebGL.js +841 -0
  75. package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +194 -0
  76. package/examples/jsm/lighting/vxgi/VXGINode.js +660 -0
  77. package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +478 -0
  78. package/examples/jsm/lighting/vxgi/VXGIVolume.js +1430 -0
  79. package/examples/jsm/lights/SunLight.js +95 -0
  80. package/examples/jsm/lights/SunLightNode.js +56 -0
  81. package/examples/jsm/lights/SunLightShadow.js +319 -0
  82. package/examples/jsm/lights/SunShadowNode.js +312 -0
  83. package/examples/jsm/loaders/3DMLoader.js +150 -49
  84. package/examples/jsm/loaders/3MFLoader.js +202 -1
  85. package/examples/jsm/loaders/FBXLoader.js +81 -5
  86. package/examples/jsm/loaders/GLTFGaussianSplatLoaderExtension.js +330 -0
  87. package/examples/jsm/loaders/GLTFLoader.js +79 -14
  88. package/examples/jsm/loaders/GaussianSplatPLYLoader.js +386 -0
  89. package/examples/jsm/loaders/KSPLATLoader.js +463 -0
  90. package/examples/jsm/loaders/MaterialXLoader.js +111 -1010
  91. package/examples/jsm/loaders/PCDLoader.js +1 -1
  92. package/examples/jsm/loaders/SPLATLoader.js +139 -0
  93. package/examples/jsm/loaders/SPZLoader.js +561 -0
  94. package/examples/jsm/loaders/materialx/MaterialXArchive.js +108 -0
  95. package/examples/jsm/loaders/materialx/MaterialXDocument.js +878 -0
  96. package/examples/jsm/loaders/materialx/MaterialXHextile.js +183 -0
  97. package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +376 -0
  98. package/examples/jsm/loaders/materialx/MaterialXLog.js +75 -0
  99. package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +4 -0
  100. package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +1021 -0
  101. package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +661 -0
  102. package/examples/jsm/loaders/materialx/MaterialXUtils.js +57 -0
  103. package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +997 -0
  104. package/examples/jsm/loaders/materialx/parse/MaterialXParser.js +28 -0
  105. package/examples/jsm/loaders/usd/USDAParser.js +15 -2
  106. package/examples/jsm/loaders/usd/USDCParser.js +1 -4
  107. package/examples/jsm/loaders/usd/USDComposer.js +80 -42
  108. package/examples/jsm/materials/WoodNodeMaterial.js +6 -108
  109. package/examples/jsm/misc/RollerCoaster.js +2 -2
  110. package/examples/jsm/misc/SculptGL.LICENSE.txt +21 -0
  111. package/examples/jsm/misc/Sculptor.js +1679 -0
  112. package/examples/jsm/misc/SculptorMesh.js +1504 -0
  113. package/examples/jsm/misc/SculptorTools.js +1180 -0
  114. package/examples/jsm/misc/SculptorUtils.js +345 -0
  115. package/examples/jsm/misc/TubePainter.js +28 -16
  116. package/examples/jsm/misc/VolumeSlice.js +24 -24
  117. package/examples/jsm/modifiers/SimplifyModifier.js +63 -556
  118. package/examples/jsm/objects/GaussianSplat.js +1039 -0
  119. package/examples/jsm/objects/Sky.js +66 -45
  120. package/examples/jsm/objects/SkyMesh.js +70 -51
  121. package/examples/jsm/physics/JoltPhysics.js +1 -1
  122. package/examples/jsm/postprocessing/AfterimagePass.js +4 -2
  123. package/examples/jsm/postprocessing/BloomPass.js +2 -2
  124. package/examples/jsm/postprocessing/GTAOPass.js +1 -1
  125. package/examples/jsm/postprocessing/OutlinePass.js +5 -5
  126. package/examples/jsm/postprocessing/SAOPass.js +1 -1
  127. package/examples/jsm/postprocessing/SSAOPass.js +1 -1
  128. package/examples/jsm/postprocessing/SSRPass.js +4 -2
  129. package/examples/jsm/postprocessing/SavePass.js +1 -1
  130. package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
  131. package/examples/jsm/postprocessing/UnrealBloomPass.js +30 -13
  132. package/examples/jsm/renderers/CSS2DRenderer.js +29 -5
  133. package/examples/jsm/shaders/DepthLimitedBlurShader.js +4 -1
  134. package/examples/jsm/shaders/ExposureShader.js +1 -1
  135. package/examples/jsm/shaders/FilmShader.js +2 -1
  136. package/examples/jsm/transpiler/AST.js +21 -2
  137. package/examples/jsm/transpiler/GLSLDecoder.js +498 -8
  138. package/examples/jsm/transpiler/TSLEncoder.js +82 -10
  139. package/examples/jsm/transpiler/WGSLEncoder.js +33 -4
  140. package/examples/jsm/tsl/WebGLNodesHandler.js +29 -39
  141. package/examples/jsm/tsl/display/AfterImageNode.js +2 -0
  142. package/examples/jsm/tsl/display/AnaglyphPassNode.js +3 -2
  143. package/examples/jsm/tsl/display/BilateralBlurNode.js +5 -2
  144. package/examples/jsm/tsl/display/BloomNode.js +55 -30
  145. package/examples/jsm/tsl/display/DenoiseNode.js +21 -1
  146. package/examples/jsm/tsl/display/DepthOfFieldNode.js +24 -6
  147. package/examples/jsm/tsl/display/DotScreenNode.js +11 -11
  148. package/examples/jsm/tsl/display/FSR1Node.js +8 -4
  149. package/examples/jsm/tsl/display/GTAONode.js +199 -86
  150. package/examples/jsm/tsl/display/GaussianBlurNode.js +65 -52
  151. package/examples/jsm/tsl/display/GodraysNode.js +5 -2
  152. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +2 -2
  153. package/examples/jsm/tsl/display/LensflareNode.js +5 -2
  154. package/examples/jsm/tsl/display/OITPassNode.js +352 -0
  155. package/examples/jsm/tsl/display/OutlineNode.js +2 -0
  156. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +3 -2
  157. package/examples/jsm/tsl/display/RGBShiftNode.js +9 -9
  158. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +7 -4
  159. package/examples/jsm/tsl/display/RetroPassNode.js +1 -1
  160. package/examples/jsm/tsl/display/SMAANode.js +22 -61
  161. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -4
  162. package/examples/jsm/tsl/display/SSAONode.js +436 -0
  163. package/examples/jsm/tsl/display/SSGINode.js +5 -2
  164. package/examples/jsm/tsl/display/SSRNode.js +7 -2
  165. package/examples/jsm/tsl/display/SSSNode.js +5 -2
  166. package/examples/jsm/tsl/display/SharpenNode.js +5 -4
  167. package/examples/jsm/tsl/display/StereoCompositePassNode.js +1 -3
  168. package/examples/jsm/tsl/display/StereoPassNode.js +1 -3
  169. package/examples/jsm/tsl/display/TAAUNode.js +22 -125
  170. package/examples/jsm/tsl/display/TRAANode.js +16 -142
  171. package/examples/jsm/tsl/display/TemporalReprojectNode.js +21 -15
  172. package/examples/jsm/tsl/display/depthAwareBlur.js +63 -0
  173. package/examples/jsm/tsl/display/hashBlur.js +3 -2
  174. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +38 -27
  175. package/examples/jsm/tsl/lighting/LightProbeGridNode.js +136 -0
  176. package/examples/jsm/tsl/math/voronoiNoise.js +112 -0
  177. package/examples/jsm/tsl/shadows/TileShadowNode.js +4 -6
  178. package/examples/jsm/tsl/utils/Raymarching.js +5 -5
  179. package/examples/jsm/tsl/utils/SoftParticles.js +60 -0
  180. package/examples/jsm/tsl/utils/TAAUtils.js +195 -0
  181. package/examples/jsm/utils/BufferGeometryUtils.js +14 -14
  182. package/examples/jsm/utils/GaussianSplatUtils.js +229 -0
  183. package/examples/jsm/utils/WebGLTextureUtils.js +1 -1
  184. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  185. package/examples/jsm/webxr/WebGLXRFallback.js +2 -16
  186. package/examples/jsm/webxr/XRControllerModelFactory.js +16 -4
  187. package/package.json +9 -16
  188. package/src/Three.Core.js +2 -1
  189. package/src/Three.TSL.js +73 -43
  190. package/src/Three.WebGPU.Nodes.js +1 -0
  191. package/src/Three.WebGPU.js +1 -0
  192. package/src/animation/AnimationClip.js +15 -2
  193. package/src/animation/AnimationObjectGroup.js +18 -6
  194. package/src/animation/AnimationUtils.js +26 -0
  195. package/src/animation/KeyframeTrack.js +37 -0
  196. package/src/constants.js +23 -1
  197. package/src/core/BufferAttribute.js +3 -2
  198. package/src/core/BufferGeometry.js +1 -1
  199. package/src/core/InterleavedBuffer.js +5 -1
  200. package/src/core/Object3D.js +40 -12
  201. package/src/core/Raycaster.js +4 -0
  202. package/src/core/RenderTarget.js +99 -9
  203. package/src/core/RenderTarget3D.js +12 -8
  204. package/src/extras/Controls.js +0 -8
  205. package/src/extras/PMREMGenerator.js +99 -205
  206. package/src/geometries/TorusGeometry.js +1 -1
  207. package/src/helpers/ArrowHelper.js +2 -0
  208. package/src/helpers/AxesHelper.js +2 -0
  209. package/src/helpers/Box3Helper.js +2 -0
  210. package/src/helpers/BoxHelper.js +2 -0
  211. package/src/helpers/CameraHelper.js +2 -0
  212. package/src/helpers/DirectionalLightHelper.js +2 -0
  213. package/src/helpers/GridHelper.js +2 -0
  214. package/src/helpers/HemisphereLightHelper.js +2 -0
  215. package/src/helpers/PlaneHelper.js +2 -0
  216. package/src/helpers/PointLightHelper.js +2 -0
  217. package/src/helpers/PolarGridHelper.js +2 -0
  218. package/src/helpers/SkeletonHelper.js +2 -0
  219. package/src/helpers/SpotLightHelper.js +2 -0
  220. package/src/lights/Light.js +0 -10
  221. package/src/lights/LightShadow.js +43 -12
  222. package/src/lights/SpotLightShadow.js +18 -0
  223. package/src/loaders/BufferGeometryLoader.js +5 -0
  224. package/src/loaders/ImageBitmapLoader.js +3 -1
  225. package/src/loaders/ObjectLoader.js +8 -5
  226. package/src/materials/Material.js +80 -57
  227. package/src/materials/MeshPhysicalMaterial.js +32 -0
  228. package/src/materials/nodes/Line2NodeMaterial.js +17 -8
  229. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +42 -5
  230. package/src/materials/nodes/NodeMaterial.js +19 -13
  231. package/src/materials/nodes/PointsNodeMaterial.js +2 -1
  232. package/src/materials/nodes/manager/NodeMaterialObserver.js +282 -55
  233. package/src/math/Frustum.js +9 -0
  234. package/src/math/FrustumArray.js +1 -1
  235. package/src/math/MathUtils.js +5 -3
  236. package/src/math/Matrix4.js +2 -9
  237. package/src/math/Plane.js +30 -1
  238. package/src/math/Quaternion.js +0 -10
  239. package/src/math/Ray.js +95 -45
  240. package/src/math/Triangle.js +0 -2
  241. package/src/math/Vector3.js +2 -2
  242. package/src/math/Vector4.js +0 -4
  243. package/src/math/interpolants/BezierInterpolant.js +36 -23
  244. package/src/nodes/Nodes.js +2 -0
  245. package/src/nodes/TSL.js +11 -3
  246. package/src/nodes/accessors/Batch.js +85 -13
  247. package/src/nodes/accessors/BufferAttributeNode.js +1 -1
  248. package/src/nodes/accessors/BuiltinNode.js +1 -1
  249. package/src/nodes/accessors/Instance.js +19 -18
  250. package/src/nodes/accessors/MaterialNode.js +9 -0
  251. package/src/nodes/accessors/ModelNode.js +85 -9
  252. package/src/nodes/accessors/ReferenceBaseNode.js +1 -70
  253. package/src/nodes/accessors/ReferenceElementNode.js +72 -0
  254. package/src/nodes/accessors/ReferenceNode.js +1 -70
  255. package/src/nodes/accessors/Skinning.js +124 -12
  256. package/src/nodes/accessors/StorageTextureNode.js +7 -3
  257. package/src/nodes/accessors/Texture3DNode.js +1 -1
  258. package/src/nodes/accessors/TextureNode.js +51 -21
  259. package/src/nodes/accessors/TextureSizeNode.js +4 -2
  260. package/src/nodes/accessors/UniformArrayNode.js +30 -5
  261. package/src/nodes/code/CodeNode.js +1 -1
  262. package/src/nodes/code/FunctionNode.js +12 -2
  263. package/src/nodes/core/ArrayNode.js +2 -2
  264. package/src/nodes/core/ContextNode.js +57 -4
  265. package/src/nodes/core/IndexNode.js +69 -4
  266. package/src/nodes/core/InspectorNode.js +2 -2
  267. package/src/nodes/core/MRTNode.js +44 -2
  268. package/src/nodes/core/Node.js +6 -3
  269. package/src/nodes/core/NodeBuilder.js +65 -50
  270. package/src/nodes/core/NodeFrame.js +11 -3
  271. package/src/nodes/core/NodeUtils.js +88 -0
  272. package/src/nodes/core/PropertyNode.js +8 -0
  273. package/src/nodes/core/StackNode.js +0 -1
  274. package/src/nodes/core/StructNode.js +4 -3
  275. package/src/nodes/core/UniformGroupNode.js +3 -2
  276. package/src/nodes/core/UniformNode.js +26 -12
  277. package/src/nodes/core/VarNode.js +0 -1
  278. package/src/nodes/display/BumpMapNode.js +2 -2
  279. package/src/nodes/display/ColorAdjustment.js +1 -1
  280. package/src/nodes/display/PassNode.js +76 -15
  281. package/src/nodes/display/ScreenNode.js +22 -65
  282. package/src/nodes/fog/Fog.js +4 -4
  283. package/src/nodes/functions/BSDF/BRDF_GGX.js +6 -6
  284. package/src/nodes/functions/BSDF/BRDF_Sheen.js +1 -1
  285. package/src/nodes/functions/BSDF/DFGLUT.js +2 -1
  286. package/src/nodes/functions/BSDF/LTC.js +1 -1
  287. package/src/nodes/functions/PhongLightingModel.js +1 -1
  288. package/src/nodes/functions/PhysicalLightingModel.js +83 -25
  289. package/src/nodes/functions/ToonLightingModel.js +2 -2
  290. package/src/nodes/functions/material/getParallaxCorrectNormal.js +3 -3
  291. package/src/nodes/gpgpu/AtomicFunctionNode.js +64 -13
  292. package/src/nodes/gpgpu/BarrierNode.js +13 -4
  293. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
  294. package/src/nodes/gpgpu/ComputeNode.js +20 -17
  295. package/src/nodes/gpgpu/SubgroupFunctionNode.js +165 -37
  296. package/src/nodes/gpgpu/WorkgroupInfoNode.js +44 -6
  297. package/src/nodes/lighting/EnvironmentNode.js +40 -4
  298. package/src/nodes/lighting/LightsNode.js +20 -4
  299. package/src/nodes/lighting/ShadowBaseNode.js +158 -1
  300. package/src/nodes/lighting/ShadowFilterNode.js +2 -106
  301. package/src/nodes/lighting/ShadowNode.js +22 -91
  302. package/src/nodes/materialx/{lib/mx_hsv.js → MaterialXColor.js} +3 -6
  303. package/src/nodes/materialx/{lib/mx_transform_color.js → MaterialXColorTransform.js} +3 -6
  304. package/src/nodes/materialx/MaterialXCore.js +37 -0
  305. package/src/nodes/materialx/MaterialXNodes.js +64 -72
  306. package/src/nodes/materialx/{lib/mx_noise.js → MaterialXNoise.js} +426 -197
  307. package/src/nodes/math/BitcountNode.js +24 -4
  308. package/src/nodes/math/MathNode.js +4 -4
  309. package/src/nodes/math/MathUtils.js +15 -4
  310. package/src/nodes/math/OperatorNode.js +2 -2
  311. package/src/nodes/math/PackFloatNode.js +29 -1
  312. package/src/nodes/math/Packed4x8IntegerNode.js +433 -0
  313. package/src/nodes/math/UnpackFloatNode.js +30 -2
  314. package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
  315. package/src/nodes/pmrem/PMREMNode.js +1 -1
  316. package/src/nodes/pmrem/PMREMUtils.js +31 -74
  317. package/src/nodes/shapes/Shapes.js +1 -1
  318. package/src/nodes/tsl/TSLCore.js +1 -31
  319. package/src/nodes/utils/EventNode.js +75 -0
  320. package/src/nodes/utils/LoopNode.js +54 -13
  321. package/src/nodes/utils/PostProcessingUtils.js +23 -2
  322. package/src/nodes/utils/RTTNode.js +97 -32
  323. package/src/nodes/utils/ReflectorNode.js +8 -4
  324. package/src/nodes/utils/RotateNode.js +85 -8
  325. package/src/nodes/utils/SpriteUtils.js +58 -23
  326. package/src/objects/BatchedMesh.js +6 -0
  327. package/src/objects/InstancedMesh.js +1 -1
  328. package/src/objects/LOD.js +1 -1
  329. package/src/objects/Line.js +12 -0
  330. package/src/objects/Mesh.js +12 -0
  331. package/src/objects/Points.js +12 -0
  332. package/src/objects/Sprite.js +12 -0
  333. package/src/renderers/WebGLRenderer.js +93 -27
  334. package/src/renderers/common/Animation.js +12 -2
  335. package/src/renderers/common/Backend.js +38 -10
  336. package/src/renderers/common/BindGroup.js +0 -1
  337. package/src/renderers/common/Bindings.js +50 -4
  338. package/src/renderers/common/BundleGroup.js +4 -0
  339. package/src/renderers/common/ClippingContext.js +11 -1
  340. package/src/renderers/common/Color4.js +9 -0
  341. package/src/renderers/common/Constants.js +0 -5
  342. package/src/renderers/common/DirectRenderPipeline.js +233 -0
  343. package/src/renderers/common/Geometries.js +24 -3
  344. package/src/renderers/common/Info.js +3 -3
  345. package/src/renderers/common/InspectorBase.js +37 -8
  346. package/src/renderers/common/Lighting.js +11 -4
  347. package/src/renderers/common/Pipelines.js +6 -4
  348. package/src/renderers/common/QuadMesh.js +16 -2
  349. package/src/renderers/common/RenderContext.js +8 -0
  350. package/src/renderers/common/RenderList.js +53 -19
  351. package/src/renderers/common/RenderLists.js +58 -11
  352. package/src/renderers/common/RenderObject.js +14 -0
  353. package/src/renderers/common/RenderObjects.js +14 -9
  354. package/src/renderers/common/RenderPipeline.js +52 -44
  355. package/src/renderers/common/Renderer.js +226 -55
  356. package/src/renderers/common/Storage3DTexture.js +16 -0
  357. package/src/renderers/common/Textures.js +3 -3
  358. package/src/renderers/common/XRManager.js +79 -72
  359. package/src/renderers/common/extras/PMREMGenerator.js +76 -144
  360. package/src/renderers/common/nodes/NodeManager.js +144 -6
  361. package/src/renderers/common/nodes/NodeStorageBuffer.js +3 -1
  362. package/src/renderers/common/nodes/NodeUniformBuffer.js +3 -1
  363. package/src/renderers/shaders/DFGLUTData.js +2 -1
  364. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +4 -2
  365. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +48 -0
  366. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +53 -4
  367. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +20 -2
  368. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +20 -0
  369. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  370. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +61 -57
  371. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +82 -0
  372. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +9 -0
  373. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +8 -1
  374. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +15 -0
  375. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  376. package/src/renderers/shaders/ShaderLib.js +1 -0
  377. package/src/renderers/shaders/UniformsLib.js +16 -0
  378. package/src/renderers/webgl/WebGLAnimation.js +2 -2
  379. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  380. package/src/renderers/webgl/WebGLLights.js +74 -4
  381. package/src/renderers/webgl/WebGLMaterials.js +6 -0
  382. package/src/renderers/webgl/WebGLOutput.js +36 -24
  383. package/src/renderers/webgl/WebGLProgram.js +3 -0
  384. package/src/renderers/webgl/WebGLPrograms.js +8 -0
  385. package/src/renderers/webgl/WebGLRenderLists.js +6 -10
  386. package/src/renderers/webgl/WebGLShadowMap.js +47 -44
  387. package/src/renderers/webgl/WebGLTextures.js +7 -7
  388. package/src/renderers/webgl-fallback/WebGLBackend.js +153 -45
  389. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +83 -29
  390. package/src/renderers/webgl-fallback/utils/WebGLState.js +163 -17
  391. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +32 -5
  392. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +11 -4
  393. package/src/renderers/webgpu/WebGPUBackend.js +513 -145
  394. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +99 -20
  395. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -1
  396. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +3 -12
  397. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +24 -14
  398. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +80 -14
  399. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -7
  400. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +9 -3
  401. package/src/renderers/webgpu/utils/WebGPUUtils.js +16 -4
  402. package/src/renderers/webxr/WebXRManager.js +25 -2
  403. package/src/scenes/Scene.js +3 -3
  404. package/src/textures/CompressedArrayTexture.js +16 -0
  405. package/src/textures/Data3DTexture.js +16 -0
  406. package/src/textures/DataArrayTexture.js +16 -0
  407. package/src/textures/DepthTexture.js +3 -3
  408. package/src/textures/Texture.js +3 -3
  409. package/src/textures/{Source.js → TextureSource.js} +39 -8
  410. package/build/three.core.min.js +0 -6
  411. package/build/three.module.min.js +0 -6
  412. package/build/three.tsl.min.js +0 -6
  413. package/build/three.webgpu.min.js +0 -6
  414. package/build/three.webgpu.nodes.min.js +0 -6
  415. package/examples/jsm/libs/ecsy.module.js +0 -1792
  416. package/examples/jsm/loaders/LottieLoader.js +0 -130
  417. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +0 -52
@@ -0,0 +1,231 @@
1
+ import {
2
+ CylinderGeometry,
3
+ IcosahedronGeometry,
4
+ InterpolationSamplingMode,
5
+ InterpolationSamplingType,
6
+ RingGeometry,
7
+ Vector3
8
+ } from '@gnsx/three';
9
+
10
+ import { MeshStandardNodeMaterial } from '@gnsx/three/webgpu';
11
+ import { attribute, color, float, fract, instanceIndex, mix, mx_fractal_noise_float, mx_noise_float, normalView, normalWorldGeometry, positionGeometry, positionLocal, positionViewDirection, positionWorld, select, sin, smoothstep, time, varying, vec3 } from '@gnsx/three/tsl';
12
+
13
+ import { mergeGeometries, mergeVertices } from '../../utils/BufferGeometryUtils.js';
14
+
15
+ import { InstancedMeshGenerator } from './InstancedMeshGenerator.js';
16
+ import { part, bumpNormal } from './CityGeneratorUtils.js';
17
+
18
+ /**
19
+ * A young street tree set in a curbside pit: a flared bark trunk rising through a
20
+ * cast-iron pit grate, branching into a canopy of vertex-jittered leaf clumps. The
21
+ * clump normals are blended toward a shared crown sphere so the clumps shade as one
22
+ * irregular crown rather than separate balls, and the material adds interior
23
+ * self-shadowing and patchy colour so the foliage reads as leaf mass. Built once
24
+ * and instanced across a list of placements, dressed with one cheap material that
25
+ * branches on a baked `partId`.
26
+ *
27
+ * The canopy is near rotationally symmetric, so the canonical model stands on
28
+ * `y = 0`, centred in X / Z, with its slight lean toward `+Z` matching the other
29
+ * pieces of street furniture.
30
+ *
31
+ * ```js
32
+ * const trees = new StreetTreeGenerator();
33
+ * scene.add( trees.build( placements ) ); // placements: Matrix4[]
34
+ * ```
35
+ */
36
+ class StreetTreeGenerator extends InstancedMeshGenerator {
37
+
38
+ constructor( parameters = {} ) {
39
+
40
+ super( parameters, buildStreetTreeGeometry, createStreetTreeMaterial, 'StreetTrees' );
41
+
42
+ }
43
+
44
+ }
45
+
46
+ StreetTreeGenerator.defaults = {
47
+ trunkHeight: 2.6, // clear trunk below the canopy
48
+ trunkRadius: 0.18 // bark radius at the base
49
+ };
50
+
51
+ const TRUNK = 0, LEAF = 1, GRATE = 2;
52
+
53
+ // the crown sphere the clump normals blend toward; the material reuses it for
54
+ // the interior-shadow falloff
55
+ const CROWN_CENTER = new Vector3( 0, 3.9, 0.1 );
56
+ const CROWN_RADIUS = 3.1;
57
+
58
+ // deterministic position hash for the clump jitter
59
+ function hash( x, y, z ) {
60
+
61
+ const s = Math.sin( x * 127.1 + y * 311.7 + z * 74.7 ) * 43758.5453;
62
+ return s - Math.floor( s );
63
+
64
+ }
65
+
66
+ // a leaf clump: an icosahedron with its vertices pushed in and out radially so the
67
+ // silhouette breaks into lobes, its normals pulled toward the shared crown sphere
68
+ function leafClump( radius, x, y, z ) {
69
+
70
+ // polyhedron geometries come non-indexed; weld them so the jittered surface
71
+ // gets smooth vertex normals instead of hard facets
72
+ const g = mergeVertices( new IcosahedronGeometry( radius, 1 ).scale( 1, 0.82, 1 ) );
73
+
74
+ const position = g.attributes.position;
75
+ const v = new Vector3();
76
+
77
+ for ( let i = 0; i < position.count; i ++ ) {
78
+
79
+ v.fromBufferAttribute( position, i );
80
+ const n = hash( v.x, v.y, v.z );
81
+ v.multiplyScalar( 0.86 + n * 0.3 );
82
+ position.setXYZ( i, v.x, v.y, v.z );
83
+
84
+ }
85
+
86
+ g.translate( x, y, z );
87
+ g.computeVertexNormals();
88
+
89
+ // blend the faceted normals toward the crown sphere so all the clumps light
90
+ // as one continuous canopy instead of a cluster of separate balls
91
+ const normal = g.attributes.normal;
92
+
93
+ for ( let i = 0; i < normal.count; i ++ ) {
94
+
95
+ v.fromBufferAttribute( position, i ).sub( CROWN_CENTER ).normalize();
96
+ normal.setXYZ(
97
+ i,
98
+ normal.getX( i ) * 0.45 + v.x * 0.55,
99
+ normal.getY( i ) * 0.45 + v.y * 0.55,
100
+ normal.getZ( i ) * 0.45 + v.z * 0.55
101
+ );
102
+
103
+ }
104
+
105
+ g.normalizeNormals();
106
+
107
+ return g;
108
+
109
+ }
110
+
111
+ function buildStreetTreeGeometry( p ) {
112
+
113
+ const r = p.trunkRadius, h = p.trunkHeight;
114
+
115
+ // tree pit: dark soil sunk inside a cast-iron grate ring flush with the pavement
116
+ const soil = new CylinderGeometry( 0.24, 0.3, 0.05, 10 ).translate( 0, 0.025, 0 );
117
+ const grate = new RingGeometry( 0.24, 0.62, 16, 4 ).rotateX( - Math.PI / 2 ).translate( 0, 0.045, 0 );
118
+
119
+ // the trunk flares at the root collar and tapers toward the crown
120
+ const rootFlare = new CylinderGeometry( r * 1.15, r * 1.6, 0.22, 8 ).translate( 0, 0.11, 0 );
121
+ const trunk = new CylinderGeometry( r * 0.55, r * 1.1, h, 8 ).translate( 0, h / 2, 0 );
122
+
123
+ // a few bare limbs fan from the trunk top into the clumps, so the canopy
124
+ // visibly grows out of the tree instead of hovering over it
125
+ const limbs = [];
126
+ for ( const [ rx, rz, len ] of [[ 0.5, 0.2, 1.5 ], [ - 0.45, - 0.3, 1.4 ], [ 0.1, - 0.55, 1.2 ], [ - 0.15, 0.5, 1.3 ]] ) {
127
+
128
+ limbs.push(
129
+ new CylinderGeometry( 0.03, 0.07, len, 5 )
130
+ .translate( 0, len / 2, 0 )
131
+ .rotateX( rx ).rotateZ( rz )
132
+ .translate( 0, h - 0.15, 0 )
133
+ );
134
+
135
+ }
136
+
137
+ // overlapping jittered clumps, one dominant mass with satellites tucked
138
+ // around it so the crown reads irregular rather than as a single ball
139
+ const clumps = [
140
+ leafClump( 2.15, 0, 3.9, 0.1 ),
141
+ leafClump( 1.5, 1.15, 4.35, 0.5 ),
142
+ leafClump( 1.45, - 1.05, 3.55, - 0.5 ),
143
+ leafClump( 1.3, 0.35, 4.75, - 0.65 ),
144
+ leafClump( 1.25, - 0.35, 4.5, 0.9 ),
145
+ leafClump( 1.1, 0.9, 3.3, - 0.85 )
146
+ ];
147
+
148
+ return mergeGeometries( [
149
+ part( soil, TRUNK ),
150
+ part( grate, GRATE ),
151
+ part( mergeGeometries( [ rootFlare, trunk, ...limbs ] ), TRUNK ),
152
+ ...clumps.map( c => part( c, LEAF ) )
153
+ ] );
154
+
155
+ }
156
+
157
+ function createStreetTreeMaterial() {
158
+
159
+ const partId = varying( attribute( 'partId', 'float' ) ).setInterpolation( InterpolationSamplingType.FLAT, InterpolationSamplingMode.EITHER );
160
+ const isLeaf = partId.equal( LEAF );
161
+ const isGrate = partId.equal( GRATE );
162
+
163
+ const p = positionGeometry;
164
+
165
+ // smooth world-space noise: large patches shift the green so no two trees
166
+ // ( or two sides of one crown ) read as the same flat colour
167
+ const patch = mx_fractal_noise_float( positionWorld.mul( 0.55 ), 2 ).mul( 0.5 ).add( 0.5 );
168
+
169
+ // leaf detail field: tuft-scale clumps and a leaf-scale sparkle. the same
170
+ // heights drive the colour break-up and the derivative bump, so the crown
171
+ // catches light like packed foliage instead of a smooth shell
172
+ const tufts = mx_fractal_noise_float( positionWorld.mul( 2.2 ), 2 ).mul( 0.5 ).add( 0.5 );
173
+ const sparkle = mx_noise_float( positionWorld.mul( 9 ) ).mul( 0.5 ).add( 0.5 );
174
+
175
+ // interior shadow: leaves darken toward the crown core, where a real canopy
176
+ // swallows the light, and brighten toward the sun-fed rim
177
+ const crownDist = p.sub( vec3( CROWN_CENTER.x, CROWN_CENTER.y, CROWN_CENTER.z ) ).length().div( CROWN_RADIUS );
178
+ const interiorAO = smoothstep( 0.1, 1.05, crownDist ).mul( 0.5 ).add( 0.5 );
179
+
180
+ // every tree draws its own tint: some paler, some warm as if turning early
181
+ const treeLane = fract( sin( float( instanceIndex ).mul( 12.9898 ) ).mul( 43758.5453 ) );
182
+
183
+ // sky-facing lift plus patchy hue drift between deep and warm greens
184
+ const skyLift = normalWorldGeometry.y.mul( 0.5 ).add( 0.5 );
185
+ const leafBase = mix( color( 0x33511f ), color( 0x5d7c33 ), skyLift );
186
+ const leafVaried = mix( leafBase, color( 0x77822f ), patch.mul( 0.55 ) );
187
+ const leafTinted = mix( leafVaried, color( 0x7d7c2c ), treeLane.mul( 0.3 ) );
188
+ const leafLit = leafTinted.mul( tufts.mul( 0.35 ).add( 0.75 ) ).mul( sparkle.mul( 0.24 ).add( 0.88 ) );
189
+ const leaf = leafLit.mul( interiorAO );
190
+
191
+ // bark: ridges running up the trunk, their crevices darker and rougher
192
+ const ridge = mx_fractal_noise_float( vec3( p.x.mul( 9 ), p.y.mul( 1.4 ), p.z.mul( 9 ) ), 2 ).abs().oneMinus();
193
+ const bark = mix( color( 0x4a3a2a ), color( 0x6f5e46 ), smoothstep( 0.55, 1.0, ridge ).mul( 0.7 ) );
194
+
195
+ // cast-iron pit grate: concentric slots cut by a radial stripe pattern
196
+ const gr = p.xz.length();
197
+ const slots = smoothstep( 0.35, 0.5, fract( gr.mul( 11.0 ) ) );
198
+ const grate = mix( color( 0x121110 ), color( 0x3a3835 ), slots );
199
+
200
+ const material = new MeshStandardNodeMaterial();
201
+ material.colorNode = select( isLeaf, leaf, select( isGrate, grate, bark ) );
202
+ material.roughnessNode = select( isGrate, float( 0.7 ), select( isLeaf, sparkle.mul( 0.15 ).add( 0.8 ), ridge.mul( 0.12 ).add( 0.82 ) ) );
203
+ material.metalnessNode = select( isGrate, float( 0.4 ), float( 0 ) );
204
+
205
+ // the same detail heights feed the screen-space bump, so tufts and bark
206
+ // ridges self-shade under the sun
207
+ // tufts only: leaf-scale noise in the bump turns to moire at grazing light,
208
+ // and the bump itself fades out at grazing view angles for the same reason
209
+ const grazingFade = smoothstep( 0.08, 0.35, normalView.dot( positionViewDirection ).abs() );
210
+ const detailHeight = select( isLeaf, tufts.mul( 0.07 ), select( isGrate, float( 0 ), ridge.mul( 0.02 ) ) ).mul( grazingFade );
211
+ material.normalNode = bumpNormal( detailHeight );
212
+
213
+ // a gentle breeze: the canopy leans and flutters, rising with height so the
214
+ // trunk stays planted. per-instance phase keeps neighbouring trees out of step
215
+ const isLeafVertex = attribute( 'partId', 'float' ).equal( LEAF );
216
+ const phase = float( instanceIndex ).mul( 1.7 );
217
+ const heightGate = smoothstep( 2.0, 5.0, p.y );
218
+ const lean = vec3(
219
+ sin( time.mul( 0.8 ).add( phase ) ).mul( 0.05 ),
220
+ 0,
221
+ sin( time.mul( 0.61 ).add( phase.mul( 1.3 ) ) ).mul( 0.04 )
222
+ );
223
+ const flutter = sin( time.mul( 3.1 ).add( p.y.mul( 2.4 ) ).add( p.x.mul( 1.9 ) ) ).mul( 0.015 );
224
+ const sway = lean.add( vec3( flutter, flutter.negate(), 0 ) ).mul( heightGate );
225
+ material.positionNode = positionLocal.add( select( isLeafVertex, sway, vec3( 0 ) ) ); // on top of positionLocal, which already carries the instance transform
226
+
227
+ return material;
228
+
229
+ }
230
+
231
+ export { StreetTreeGenerator };
@@ -0,0 +1,100 @@
1
+ import {
2
+ BoxGeometry,
3
+ CylinderGeometry,
4
+ InterpolationSamplingMode,
5
+ InterpolationSamplingType,
6
+ Quaternion,
7
+ Vector3
8
+ } from '@gnsx/three';
9
+
10
+ import { MeshStandardNodeMaterial } from '@gnsx/three/webgpu';
11
+ import { attribute, color, float, select, varying } from '@gnsx/three/tsl';
12
+
13
+ import { mergeGeometries } from '../../utils/BufferGeometryUtils.js';
14
+
15
+ import { InstancedMeshGenerator } from './InstancedMeshGenerator.js';
16
+ import { part } from './CityGeneratorUtils.js';
17
+
18
+ /**
19
+ * A NYC cobra-head streetlight: a tall tapered mast standing at the curb with a
20
+ * curved arm reaching out over the roadway to a drop luminaire. Built once and
21
+ * instanced across a list of placements, dressed with one cheap material that
22
+ * branches on a baked `partId` ( dark metal pole, pale lamp lens ).
23
+ *
24
+ * The canonical model stands on `y = 0`, centred in X / Z, with the arm reaching
25
+ * toward `+Z`, so a placement whose local `+Z` faces the road throws the lamp
26
+ * over it.
27
+ *
28
+ * ```js
29
+ * const lights = new StreetlightGenerator();
30
+ * scene.add( lights.build( placements ) ); // placements: Matrix4[]
31
+ * ```
32
+ */
33
+ class StreetlightGenerator extends InstancedMeshGenerator {
34
+
35
+ constructor( parameters = {} ) {
36
+
37
+ super( parameters, buildStreetlightGeometry, createStreetlightMaterial, 'Streetlights', false );
38
+
39
+ }
40
+
41
+ }
42
+
43
+ StreetlightGenerator.defaults = {
44
+ height: 9, // mast height ( NYC arterial standard ~9 m )
45
+ reach: 2.4, // how far the arm reaches out over the road
46
+ radius: 0.1 // mast radius at the top
47
+ };
48
+
49
+ // material-zone codes baked per vertex
50
+ const METAL = 0, LENS = 1;
51
+
52
+ // a capsule-less strut: a cylinder spanning two points, oriented from +Y
53
+ function strut( a, b, radius, segments = 6 ) {
54
+
55
+ const dir = new Vector3().subVectors( b, a );
56
+ const length = dir.length();
57
+ const geometry = new CylinderGeometry( radius, radius, length, segments );
58
+ geometry.applyQuaternion( new Quaternion().setFromUnitVectors( new Vector3( 0, 1, 0 ), dir.normalize() ) );
59
+ geometry.translate( ( a.x + b.x ) / 2, ( a.y + b.y ) / 2, ( a.z + b.z ) / 2 );
60
+ return geometry;
61
+
62
+ }
63
+
64
+ function buildStreetlightGeometry( p ) {
65
+
66
+ const h = p.height;
67
+
68
+ const base = new CylinderGeometry( 0.18, 0.22, 0.6, 8 ).translate( 0, 0.3, 0 );
69
+ const pole = new CylinderGeometry( p.radius, p.radius * 1.7, h, 8 ).translate( 0, h / 2, 0 );
70
+
71
+ // the arm rises off the mast then sweeps out over the road to the luminaire
72
+ const armBase = new Vector3( 0, h - 0.4, 0 );
73
+ const armKnee = new Vector3( 0, h + 0.5, p.reach * 0.35 );
74
+ const armEnd = new Vector3( 0, h + 0.2, p.reach );
75
+ const arm = mergeGeometries( [ strut( armBase, armKnee, 0.07 ), strut( armKnee, armEnd, 0.06 ) ] );
76
+
77
+ // a tapering cobra-head luminaire at the arm end, with a pale lens underneath
78
+ const head = new BoxGeometry( 0.26, 0.16, 0.7 ).translate( armEnd.x, armEnd.y - 0.05, armEnd.z + 0.2 );
79
+ const lens = new BoxGeometry( 0.2, 0.05, 0.5 ).translate( armEnd.x, armEnd.y - 0.14, armEnd.z + 0.2 );
80
+
81
+ return mergeGeometries( [ part( base, METAL ), part( pole, METAL ), part( arm, METAL ), part( head, METAL ), part( lens, LENS ) ] );
82
+
83
+ }
84
+
85
+ function createStreetlightMaterial() {
86
+
87
+ const partId = varying( attribute( 'partId', 'float' ) ).setInterpolation( InterpolationSamplingType.FLAT, InterpolationSamplingMode.EITHER );
88
+ const isLens = partId.equal( LENS );
89
+
90
+ const material = new MeshStandardNodeMaterial();
91
+ material.colorNode = select( isLens, color( 0xfff0cc ), color( 0x40433d ) ); // warm lit lens, dark olive-grey metal
92
+ material.roughnessNode = select( isLens, float( 0.3 ), float( 0.5 ) );
93
+ material.metalnessNode = select( isLens, float( 0 ), float( 0.7 ) );
94
+ material.emissiveNode = select( isLens, color( 0xffe2a6 ).mul( 60 ), color( 0x000000 ) ); // luminaire lens at ~2x a sunlit white wall, as a real cobra head reads
95
+
96
+ return material;
97
+
98
+ }
99
+
100
+ export { StreetlightGenerator };
@@ -0,0 +1,106 @@
1
+ import {
2
+ BoxGeometry,
3
+ CylinderGeometry,
4
+ InterpolationSamplingMode,
5
+ InterpolationSamplingType
6
+ } from '@gnsx/three';
7
+
8
+ import { MeshStandardNodeMaterial } from '@gnsx/three/webgpu';
9
+ import { attribute, color, float, select, varying } from '@gnsx/three/tsl';
10
+
11
+ import { mergeGeometries } from '../../utils/BufferGeometryUtils.js';
12
+
13
+ import { InstancedMeshGenerator } from './InstancedMeshGenerator.js';
14
+ import { part } from './CityGeneratorUtils.js';
15
+
16
+ /**
17
+ * A NYC traffic signal: a round pole at the curb with a horizontal mast arm
18
+ * reaching out over the roadway to a vertical three-section signal head, plus a
19
+ * pedestrian-signal box on the pole. Built once and instanced across a list of
20
+ * placements, dressed with one cheap material that branches on a baked `partId`
21
+ * ( dark metal, three coloured lenses ).
22
+ *
23
+ * The canonical model stands on `y = 0`, centred in X / Z, with the arm reaching
24
+ * toward `+Z`, so a placement whose local `+Z` faces the road throws the head
25
+ * over it with its lenses aimed back at oncoming traffic.
26
+ *
27
+ * ```js
28
+ * const lights = new TrafficlightGenerator();
29
+ * scene.add( lights.build( placements ) ); // placements: Matrix4[]
30
+ * ```
31
+ */
32
+ class TrafficlightGenerator extends InstancedMeshGenerator {
33
+
34
+ constructor( parameters = {} ) {
35
+
36
+ super( parameters, buildTrafficlightGeometry, createTrafficlightMaterial, 'Trafficlights' );
37
+
38
+ }
39
+
40
+ }
41
+
42
+ TrafficlightGenerator.defaults = {
43
+ height: 6.5, // pole height at the curb, so the mast arm clears traffic
44
+ reach: 5.5, // how far the mast arm reaches out over the road
45
+ radius: 0.14 // pole radius
46
+ };
47
+
48
+ // material-zone codes baked per vertex
49
+ const METAL = 0, RED = 1, AMBER = 2, GREEN = 3;
50
+
51
+ // a short lens disc on the front of the signal head, facing back down the arm
52
+ function lensDisc( y, z, id ) {
53
+
54
+ return part( new CylinderGeometry( 0.13, 0.13, 0.08, 12 ).rotateX( Math.PI / 2 ).translate( 0, y, z ), id );
55
+
56
+ }
57
+
58
+ function buildTrafficlightGeometry( p ) {
59
+
60
+ const h = p.height, reach = p.reach;
61
+ const armY = h - 0.3; // the arm rides just below the pole top
62
+
63
+ const base = new CylinderGeometry( 0.2, 0.26, 0.5, 8 ).translate( 0, 0.25, 0 );
64
+ const pole = new CylinderGeometry( p.radius, p.radius * 1.2, h, 8 ).translate( 0, h / 2, 0 );
65
+
66
+ // horizontal, slightly tapered mast arm out over the roadway toward +Z
67
+ const arm = new CylinderGeometry( 0.07, 0.1, reach, 8 ).rotateX( Math.PI / 2 ).translate( 0, armY, reach / 2 );
68
+
69
+ // pedestrian-signal box clamped to the pole at eye level, facing the crossing
70
+ const pedBox = new BoxGeometry( 0.4, 0.42, 0.2 ).translate( 0, 2.6, p.radius + 0.1 );
71
+
72
+ // the three-section head hangs from the arm's far end, its bottom ~4.7 m over
73
+ // the road for truck clearance, lenses aimed back at oncoming traffic
74
+ const headZ = reach - 0.6, headY = armY - 1.05;
75
+ const housing = new BoxGeometry( 0.36, 0.95, 0.32 ).translate( 0, headY, headZ );
76
+ const dropLen = armY - ( headY + 0.475 );
77
+ const drop = new CylinderGeometry( 0.05, 0.05, dropLen, 6 ).translate( 0, headY + 0.475 + dropLen / 2, headZ ); // bracket hanging the head off the arm
78
+ const lensZ = headZ - 0.19; // discs stand proud of the housing's -Z face
79
+
80
+ return mergeGeometries( [
81
+ part( base, METAL ), part( pole, METAL ), part( arm, METAL ), part( drop, METAL ),
82
+ part( pedBox, METAL ), part( housing, METAL ),
83
+ lensDisc( headY + 0.28, lensZ, RED ),
84
+ lensDisc( headY, lensZ, AMBER ),
85
+ lensDisc( headY - 0.28, lensZ, GREEN )
86
+ ] );
87
+
88
+ }
89
+
90
+ function createTrafficlightMaterial() {
91
+
92
+ const partId = varying( attribute( 'partId', 'float' ) ).setInterpolation( InterpolationSamplingType.FLAT, InterpolationSamplingMode.EITHER );
93
+ const isGreen = partId.equal( GREEN );
94
+ const isLens = partId.greaterThan( 0.5 ); // any coloured lens, never the metal
95
+
96
+ const material = new MeshStandardNodeMaterial();
97
+ material.colorNode = select( partId.equal( RED ), color( 0x3a0a06 ), select( partId.equal( AMBER ), color( 0x402608 ), select( isGreen, color( 0x2bd24b ), color( 0x233029 ) ) ) ); // dark glass, lit green, dark olive metal
98
+ material.roughnessNode = select( isLens, float( 0.3 ), float( 0.5 ) );
99
+ material.metalnessNode = select( isLens, float( 0 ), float( 0.7 ) );
100
+ material.emissiveNode = select( isGreen, color( 0x2bd24b ).mul( 18 ), color( 0x000000 ) ); // only the go signal glows, at LED-aspect radiance that still reads in full sun
101
+
102
+ return material;
103
+
104
+ }
105
+
106
+ export { TrafficlightGenerator };
@@ -0,0 +1,100 @@
1
+ import {
2
+ CylinderGeometry,
3
+ IcosahedronGeometry,
4
+ InterpolationSamplingMode,
5
+ InterpolationSamplingType
6
+ } from '@gnsx/three';
7
+
8
+ import { MeshStandardNodeMaterial } from '@gnsx/three/webgpu';
9
+ import { attribute, color, float, Fn, fract, mix, mx_fractal_noise_float, positionGeometry, select, smoothstep, step, uv, varying } from '@gnsx/three/tsl';
10
+
11
+ import { mergeGeometries } from '../../utils/BufferGeometryUtils.js';
12
+
13
+ import { InstancedMeshGenerator } from './InstancedMeshGenerator.js';
14
+ import { part } from './CityGeneratorUtils.js';
15
+
16
+ /**
17
+ * The NYC green wire-mesh litter basket: a slightly tapered drum with a heavy top
18
+ * rim, a foot ring and a dark bag of trash inside. Built once and instanced across
19
+ * a list of placements; one cheap material branches on a baked `partId`, drawing
20
+ * the mesh weave procedurally from the drum's own UVs so no alpha or extra geometry
21
+ * is needed. Canonical model stands on `y = 0`, centred in X / Z.
22
+ *
23
+ * ```js
24
+ * const cans = new TrashcanGenerator();
25
+ * scene.add( cans.build( placements ) ); // placements: Matrix4[]
26
+ * ```
27
+ */
28
+ class TrashcanGenerator extends InstancedMeshGenerator {
29
+
30
+ constructor( parameters = {} ) {
31
+
32
+ super( parameters, buildTrashcanGeometry, createTrashcanMaterial, 'Trashcans' );
33
+
34
+ }
35
+
36
+ }
37
+
38
+ TrashcanGenerator.defaults = {
39
+ radius: 0.28, // ~0.55 m diameter basket
40
+ height: 0.8
41
+ };
42
+
43
+ const MESH = 0, RIM = 1, TRASH = 2;
44
+
45
+ function buildTrashcanGeometry( p ) {
46
+
47
+ const r = p.radius, h = p.height;
48
+
49
+ const drum = new CylinderGeometry( r, r * 0.92, h, 16, 1, true ).translate( 0, h / 2, 0 ); // open-ended weave drum
50
+ const rim = new CylinderGeometry( r + 0.03, r + 0.03, 0.07, 16 ).translate( 0, h, 0 );
51
+ const foot = new CylinderGeometry( r * 0.92, r * 0.86, 0.06, 16 ).translate( 0, 0.03, 0 );
52
+ const bag = new CylinderGeometry( r * 0.86, r * 0.7, h * 0.9, 12 ).translate( 0, h * 0.5, 0 ); // dark refuse, just inside
53
+
54
+ // the basket never quite closes: a lumpy mound of refuse crests over the rim
55
+ const mound = new IcosahedronGeometry( r * 0.82, 1 ).scale( 1, 0.55, 1 ).translate( 0.02, h + 0.02, - 0.01 );
56
+
57
+ return mergeGeometries( [ part( drum, MESH ), part( rim, RIM ), part( foot, RIM ), part( bag, TRASH ), part( mound, TRASH ) ] );
58
+
59
+ }
60
+
61
+ function createTrashcanMaterial() {
62
+
63
+ const partId = varying( attribute( 'partId', 'float' ) ).setInterpolation( InterpolationSamplingType.FLAT, InterpolationSamplingMode.EITHER );
64
+ const isRim = partId.equal( RIM );
65
+ const isTrash = partId.equal( TRASH );
66
+
67
+ // expanded-metal weave on the drum, drawn from its UV so the mesh reads as
68
+ // open without alpha: thin crossing diagonal wires around dark diamond holes
69
+ const weave = Fn( () => {
70
+
71
+ const u = uv().x.mul( 26 );
72
+ const v = uv().y.mul( 9 );
73
+ const a = fract( u.add( v ) ).sub( 0.5 ).abs();
74
+ const b = fract( u.sub( v ) ).sub( 0.5 ).abs();
75
+ return smoothstep( 0.3, 0.2, a.min( b ) ); // 1 on the wires, 0 in the diamond holes
76
+
77
+ } )();
78
+
79
+ const p = positionGeometry;
80
+
81
+ // street grime creeps up from the foot of the basket
82
+ const grime = smoothstep( 0.45, 0.05, p.y ).mul( 0.5 ).oneMinus();
83
+
84
+ const green = color( 0x39543a ).mul( grime );
85
+ const drumColor = mix( color( 0x101210 ), green, weave ); // holes fall into the dark interior
86
+
87
+ // the mound of refuse: dark bags flecked with scraps of paper and litter
88
+ const fleck = step( 0.82, mx_fractal_noise_float( p.mul( 34 ), 2 ).mul( 0.5 ).add( 0.5 ) );
89
+ const trash = mix( color( 0x24221d ), color( 0xa89e88 ), fleck.mul( smoothstep( 0.6, 0.75, p.y ) ) );
90
+
91
+ const material = new MeshStandardNodeMaterial();
92
+ material.colorNode = select( isTrash, trash, select( isRim, green.mul( 1.15 ), drumColor ) );
93
+ material.roughnessNode = select( isTrash, float( 0.9 ), float( 0.55 ) );
94
+ material.metalnessNode = select( isTrash, float( 0 ), float( 0.5 ) );
95
+
96
+ return material;
97
+
98
+ }
99
+
100
+ export { TrashcanGenerator };
@@ -7,7 +7,7 @@ import {
7
7
  * A special type of box geometry intended for {@link LineSegments}.
8
8
  *
9
9
  * ```js
10
- * const geometry = new THREE.BoxLineGeometry();
10
+ * const geometry = new BoxLineGeometry();
11
11
  * const material = new THREE.LineBasicMaterial( { color: 0x00ff00 } );
12
12
  * const lines = new THREE.LineSegments( geometry, material );
13
13
  * scene.add( lines );
@@ -10,7 +10,7 @@ import {
10
10
  * Reference: [Mesh Generation with Python](https://prideout.net/blog/old/blog/index.html@p=44.html)
11
11
  *
12
12
  * ```js
13
- * const geometry = new THREE.ParametricGeometry( klein, 25, 25 );
13
+ * const geometry = new ParametricGeometry( klein, 25, 25 );
14
14
  * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
15
15
  * const klein = new THREE.Mesh( geometry, material );
16
16
  * scene.add( klein );
@@ -42,7 +42,7 @@ function getUv( faceDirVector, normal, uvAxis, projectionAxis, radius, sideLengt
42
42
  * A special type of box geometry with rounded corners and edges.
43
43
  *
44
44
  * ```js
45
- * const geometry = new THREE.RoundedBoxGeometry();
45
+ * const geometry = new RoundedBoxGeometry();
46
46
  * const material = new THREE.MeshStandardMaterial( { color: 0x00ff00 } );
47
47
  * const cube = new THREE.Mesh( geometry, material );
48
48
  * scene.add( cube );