@gnsx/three 0.185.15 → 0.186.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/three.cjs +10 -82600
- package/build/three.core.js +1303 -728
- package/build/three.module.js +439 -338
- package/build/three.tsl.js +74 -44
- package/build/three.webgpu.js +6036 -2184
- package/build/three.webgpu.nodes.js +6020 -2184
- package/examples/jsm/Addons.js +6 -6
- package/examples/jsm/controls/ArcballControls.js +1 -1
- package/examples/jsm/controls/FirstPersonControls.js +44 -20
- package/examples/jsm/controls/OrbitControls.js +9 -0
- package/examples/jsm/controls/TrackballControls.js +109 -4
- package/examples/jsm/csm/CSMShadowNode.js +13 -0
- package/examples/jsm/exporters/GLTFExporter.js +23 -7
- package/examples/jsm/exporters/USDZExporter.js +2 -2
- package/examples/jsm/generators/CityGenerator.js +377 -45
- package/examples/jsm/generators/ForestGenerator.js +12 -12
- package/examples/jsm/generators/TerrainGenerator.js +49 -37
- package/examples/jsm/generators/TreeGenerator.js +70 -76
- package/examples/jsm/generators/city/BenchGenerator.js +127 -0
- package/examples/jsm/generators/city/CarGenerator.js +479 -0
- package/examples/jsm/generators/city/CityGeneratorUtils.js +31 -0
- package/examples/jsm/generators/city/HydrantGenerator.js +106 -0
- package/examples/jsm/generators/city/InstancedMeshGenerator.js +86 -0
- package/examples/jsm/generators/city/PersonGenerator.js +447 -0
- package/examples/jsm/generators/city/SidewalkGenerator.js +33 -38
- package/examples/jsm/generators/city/SkyscraperGenerator.js +448 -48
- package/examples/jsm/generators/city/StreetTreeGenerator.js +231 -0
- package/examples/jsm/generators/city/StreetlightGenerator.js +100 -0
- package/examples/jsm/generators/city/TrafficlightGenerator.js +106 -0
- package/examples/jsm/generators/city/TrashcanGenerator.js +100 -0
- package/examples/jsm/geometries/BoxLineGeometry.js +1 -1
- package/examples/jsm/geometries/ParametricGeometry.js +1 -1
- package/examples/jsm/geometries/RoundedBoxGeometry.js +1 -1
- package/examples/jsm/gpgpu/CountingSort.js +271 -0
- package/examples/jsm/helpers/LightProbeGridHelper.js +60 -239
- package/examples/jsm/helpers/LightProbeGridHelperWebGL.js +221 -0
- package/examples/jsm/inspector/Extension.js +94 -0
- package/examples/jsm/inspector/Inspector.js +145 -41
- package/examples/jsm/inspector/RendererInspector.js +100 -52
- package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +2609 -0
- package/examples/jsm/inspector/extensions/color-grading/ColorWheel.js +352 -0
- package/examples/jsm/inspector/extensions/color-grading/CurveEditor.js +599 -0
- package/examples/jsm/inspector/extensions/color-grading/LUT3DStyle.js +1201 -0
- package/examples/jsm/inspector/extensions/color-grading/LUTMath.js +788 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/BrightnessModule.js +72 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ColorWheelModule.js +112 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ContrastModule.js +82 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/CurvesModule.js +109 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ExposureHueModule.js +110 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ExposureModule.js +73 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/HueModule.js +78 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ImportedCubeModule.js +89 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/Module.js +285 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/OutputModule.js +101 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/RendererModule.js +225 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/SatVibranceModule.js +102 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/SaturationModule.js +76 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/VibranceModule.js +76 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/WhiteBalanceModule.js +86 -0
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +26 -31
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -0
- package/examples/jsm/inspector/tabs/Memory.js +0 -2
- package/examples/jsm/inspector/tabs/Settings.js +4 -0
- package/examples/jsm/inspector/tabs/Timeline.js +223 -171
- package/examples/jsm/inspector/tabs/Viewer.js +515 -21
- package/examples/jsm/inspector/ui/List.js +15 -9
- package/examples/jsm/inspector/ui/Profiler.js +170 -14
- package/examples/jsm/inspector/ui/Style.js +269 -23
- package/examples/jsm/inspector/ui/Tab.js +2 -0
- package/examples/jsm/inspector/ui/Values.js +14 -2
- package/examples/jsm/interactive/HTMLMesh.js +19 -3
- package/examples/jsm/lighting/LightProbeGrid.js +484 -889
- package/examples/jsm/lighting/LightProbeGridUtils.js +107 -0
- package/examples/jsm/lighting/LightProbeGridWebGL.js +841 -0
- package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +194 -0
- package/examples/jsm/lighting/vxgi/VXGINode.js +660 -0
- package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +478 -0
- package/examples/jsm/lighting/vxgi/VXGIVolume.js +1430 -0
- package/examples/jsm/lights/SunLight.js +95 -0
- package/examples/jsm/lights/SunLightNode.js +56 -0
- package/examples/jsm/lights/SunLightShadow.js +319 -0
- package/examples/jsm/lights/SunShadowNode.js +312 -0
- package/examples/jsm/loaders/3DMLoader.js +150 -49
- package/examples/jsm/loaders/3MFLoader.js +202 -1
- package/examples/jsm/loaders/FBXLoader.js +81 -5
- package/examples/jsm/loaders/GLTFGaussianSplatLoaderExtension.js +330 -0
- package/examples/jsm/loaders/GLTFLoader.js +79 -14
- package/examples/jsm/loaders/GaussianSplatPLYLoader.js +386 -0
- package/examples/jsm/loaders/KSPLATLoader.js +463 -0
- package/examples/jsm/loaders/MaterialXLoader.js +111 -1010
- package/examples/jsm/loaders/PCDLoader.js +1 -1
- package/examples/jsm/loaders/SPLATLoader.js +139 -0
- package/examples/jsm/loaders/SPZLoader.js +561 -0
- package/examples/jsm/loaders/materialx/MaterialXArchive.js +108 -0
- package/examples/jsm/loaders/materialx/MaterialXDocument.js +878 -0
- package/examples/jsm/loaders/materialx/MaterialXHextile.js +183 -0
- package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +376 -0
- package/examples/jsm/loaders/materialx/MaterialXLog.js +75 -0
- package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +4 -0
- package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +1021 -0
- package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +661 -0
- package/examples/jsm/loaders/materialx/MaterialXUtils.js +57 -0
- package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +997 -0
- package/examples/jsm/loaders/materialx/parse/MaterialXParser.js +28 -0
- package/examples/jsm/loaders/usd/USDAParser.js +15 -2
- package/examples/jsm/loaders/usd/USDCParser.js +1 -4
- package/examples/jsm/loaders/usd/USDComposer.js +80 -42
- package/examples/jsm/materials/WoodNodeMaterial.js +6 -108
- package/examples/jsm/misc/RollerCoaster.js +2 -2
- package/examples/jsm/misc/SculptGL.LICENSE.txt +21 -0
- package/examples/jsm/misc/Sculptor.js +1679 -0
- package/examples/jsm/misc/SculptorMesh.js +1504 -0
- package/examples/jsm/misc/SculptorTools.js +1180 -0
- package/examples/jsm/misc/SculptorUtils.js +345 -0
- package/examples/jsm/misc/TubePainter.js +28 -16
- package/examples/jsm/misc/VolumeSlice.js +24 -24
- package/examples/jsm/modifiers/SimplifyModifier.js +63 -556
- package/examples/jsm/objects/GaussianSplat.js +1039 -0
- package/examples/jsm/objects/Sky.js +66 -45
- package/examples/jsm/objects/SkyMesh.js +70 -51
- package/examples/jsm/physics/JoltPhysics.js +1 -1
- package/examples/jsm/postprocessing/AfterimagePass.js +4 -2
- package/examples/jsm/postprocessing/BloomPass.js +2 -2
- package/examples/jsm/postprocessing/GTAOPass.js +1 -1
- package/examples/jsm/postprocessing/OutlinePass.js +5 -5
- package/examples/jsm/postprocessing/SAOPass.js +1 -1
- package/examples/jsm/postprocessing/SSAOPass.js +1 -1
- package/examples/jsm/postprocessing/SSRPass.js +4 -2
- package/examples/jsm/postprocessing/SavePass.js +1 -1
- package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
- package/examples/jsm/postprocessing/UnrealBloomPass.js +30 -13
- package/examples/jsm/renderers/CSS2DRenderer.js +29 -5
- package/examples/jsm/shaders/DepthLimitedBlurShader.js +4 -1
- package/examples/jsm/shaders/ExposureShader.js +1 -1
- package/examples/jsm/shaders/FilmShader.js +2 -1
- package/examples/jsm/transpiler/AST.js +21 -2
- package/examples/jsm/transpiler/GLSLDecoder.js +498 -8
- package/examples/jsm/transpiler/TSLEncoder.js +82 -10
- package/examples/jsm/transpiler/WGSLEncoder.js +33 -4
- package/examples/jsm/tsl/WebGLNodesHandler.js +29 -39
- package/examples/jsm/tsl/display/AfterImageNode.js +2 -0
- package/examples/jsm/tsl/display/AnaglyphPassNode.js +3 -2
- package/examples/jsm/tsl/display/BilateralBlurNode.js +5 -2
- package/examples/jsm/tsl/display/BloomNode.js +55 -30
- package/examples/jsm/tsl/display/DenoiseNode.js +21 -1
- package/examples/jsm/tsl/display/DepthOfFieldNode.js +24 -6
- package/examples/jsm/tsl/display/DotScreenNode.js +11 -11
- package/examples/jsm/tsl/display/FSR1Node.js +8 -4
- package/examples/jsm/tsl/display/GTAONode.js +199 -86
- package/examples/jsm/tsl/display/GaussianBlurNode.js +65 -52
- package/examples/jsm/tsl/display/GodraysNode.js +5 -2
- package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +2 -2
- package/examples/jsm/tsl/display/LensflareNode.js +5 -2
- package/examples/jsm/tsl/display/OITPassNode.js +352 -0
- package/examples/jsm/tsl/display/OutlineNode.js +2 -0
- package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +3 -2
- package/examples/jsm/tsl/display/RGBShiftNode.js +9 -9
- package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +7 -4
- package/examples/jsm/tsl/display/RetroPassNode.js +1 -1
- package/examples/jsm/tsl/display/SMAANode.js +22 -61
- package/examples/jsm/tsl/display/SSAAPassNode.js +2 -4
- package/examples/jsm/tsl/display/SSAONode.js +436 -0
- package/examples/jsm/tsl/display/SSGINode.js +5 -2
- package/examples/jsm/tsl/display/SSRNode.js +7 -2
- package/examples/jsm/tsl/display/SSSNode.js +5 -2
- package/examples/jsm/tsl/display/SharpenNode.js +5 -4
- package/examples/jsm/tsl/display/StereoCompositePassNode.js +1 -3
- package/examples/jsm/tsl/display/StereoPassNode.js +1 -3
- package/examples/jsm/tsl/display/TAAUNode.js +22 -125
- package/examples/jsm/tsl/display/TRAANode.js +16 -142
- package/examples/jsm/tsl/display/TemporalReprojectNode.js +21 -15
- package/examples/jsm/tsl/display/depthAwareBlur.js +63 -0
- package/examples/jsm/tsl/display/hashBlur.js +3 -2
- package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +38 -27
- package/examples/jsm/tsl/lighting/LightProbeGridNode.js +136 -0
- package/examples/jsm/tsl/math/voronoiNoise.js +112 -0
- package/examples/jsm/tsl/shadows/TileShadowNode.js +4 -6
- package/examples/jsm/tsl/utils/Raymarching.js +5 -5
- package/examples/jsm/tsl/utils/SoftParticles.js +60 -0
- package/examples/jsm/tsl/utils/TAAUtils.js +195 -0
- package/examples/jsm/utils/BufferGeometryUtils.js +14 -14
- package/examples/jsm/utils/GaussianSplatUtils.js +229 -0
- package/examples/jsm/utils/WebGLTextureUtils.js +1 -1
- package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
- package/examples/jsm/webxr/WebGLXRFallback.js +2 -16
- package/examples/jsm/webxr/XRControllerModelFactory.js +16 -4
- package/package.json +9 -16
- package/src/Three.Core.js +2 -1
- package/src/Three.TSL.js +73 -43
- package/src/Three.WebGPU.Nodes.js +1 -0
- package/src/Three.WebGPU.js +1 -0
- package/src/animation/AnimationClip.js +15 -2
- package/src/animation/AnimationObjectGroup.js +18 -6
- package/src/animation/AnimationUtils.js +26 -0
- package/src/animation/KeyframeTrack.js +37 -0
- package/src/constants.js +23 -1
- package/src/core/BufferAttribute.js +3 -2
- package/src/core/BufferGeometry.js +1 -1
- package/src/core/InterleavedBuffer.js +5 -1
- package/src/core/Object3D.js +40 -12
- package/src/core/Raycaster.js +4 -0
- package/src/core/RenderTarget.js +99 -9
- package/src/core/RenderTarget3D.js +12 -8
- package/src/extras/Controls.js +0 -8
- package/src/extras/PMREMGenerator.js +99 -205
- package/src/geometries/TorusGeometry.js +1 -1
- package/src/helpers/ArrowHelper.js +2 -0
- package/src/helpers/AxesHelper.js +2 -0
- package/src/helpers/Box3Helper.js +2 -0
- package/src/helpers/BoxHelper.js +2 -0
- package/src/helpers/CameraHelper.js +2 -0
- package/src/helpers/DirectionalLightHelper.js +2 -0
- package/src/helpers/GridHelper.js +2 -0
- package/src/helpers/HemisphereLightHelper.js +2 -0
- package/src/helpers/PlaneHelper.js +2 -0
- package/src/helpers/PointLightHelper.js +2 -0
- package/src/helpers/PolarGridHelper.js +2 -0
- package/src/helpers/SkeletonHelper.js +2 -0
- package/src/helpers/SpotLightHelper.js +2 -0
- package/src/lights/Light.js +0 -10
- package/src/lights/LightShadow.js +43 -12
- package/src/lights/SpotLightShadow.js +18 -0
- package/src/loaders/BufferGeometryLoader.js +5 -0
- package/src/loaders/ImageBitmapLoader.js +3 -1
- package/src/loaders/ObjectLoader.js +8 -5
- package/src/materials/Material.js +80 -57
- package/src/materials/MeshPhysicalMaterial.js +32 -0
- package/src/materials/nodes/Line2NodeMaterial.js +17 -8
- package/src/materials/nodes/MeshPhysicalNodeMaterial.js +42 -5
- package/src/materials/nodes/NodeMaterial.js +19 -13
- package/src/materials/nodes/PointsNodeMaterial.js +2 -1
- package/src/materials/nodes/manager/NodeMaterialObserver.js +282 -55
- package/src/math/Frustum.js +9 -0
- package/src/math/FrustumArray.js +1 -1
- package/src/math/MathUtils.js +5 -3
- package/src/math/Matrix4.js +2 -9
- package/src/math/Plane.js +30 -1
- package/src/math/Quaternion.js +0 -10
- package/src/math/Ray.js +95 -45
- package/src/math/Triangle.js +0 -2
- package/src/math/Vector3.js +2 -2
- package/src/math/Vector4.js +0 -4
- package/src/math/interpolants/BezierInterpolant.js +36 -23
- package/src/nodes/Nodes.js +2 -0
- package/src/nodes/TSL.js +11 -3
- package/src/nodes/accessors/Batch.js +85 -13
- package/src/nodes/accessors/BufferAttributeNode.js +1 -1
- package/src/nodes/accessors/BuiltinNode.js +1 -1
- package/src/nodes/accessors/Instance.js +19 -18
- package/src/nodes/accessors/MaterialNode.js +9 -0
- package/src/nodes/accessors/ModelNode.js +85 -9
- package/src/nodes/accessors/ReferenceBaseNode.js +1 -70
- package/src/nodes/accessors/ReferenceElementNode.js +72 -0
- package/src/nodes/accessors/ReferenceNode.js +1 -70
- package/src/nodes/accessors/Skinning.js +124 -12
- package/src/nodes/accessors/StorageTextureNode.js +7 -3
- package/src/nodes/accessors/Texture3DNode.js +1 -1
- package/src/nodes/accessors/TextureNode.js +51 -21
- package/src/nodes/accessors/TextureSizeNode.js +4 -2
- package/src/nodes/accessors/UniformArrayNode.js +30 -5
- package/src/nodes/code/CodeNode.js +1 -1
- package/src/nodes/code/FunctionNode.js +12 -2
- package/src/nodes/core/ArrayNode.js +2 -2
- package/src/nodes/core/ContextNode.js +57 -4
- package/src/nodes/core/IndexNode.js +69 -4
- package/src/nodes/core/InspectorNode.js +2 -2
- package/src/nodes/core/MRTNode.js +44 -2
- package/src/nodes/core/Node.js +6 -3
- package/src/nodes/core/NodeBuilder.js +65 -50
- package/src/nodes/core/NodeFrame.js +11 -3
- package/src/nodes/core/NodeUtils.js +88 -0
- package/src/nodes/core/PropertyNode.js +8 -0
- package/src/nodes/core/StackNode.js +0 -1
- package/src/nodes/core/StructNode.js +4 -3
- package/src/nodes/core/UniformGroupNode.js +3 -2
- package/src/nodes/core/UniformNode.js +26 -12
- package/src/nodes/core/VarNode.js +0 -1
- package/src/nodes/display/BumpMapNode.js +2 -2
- package/src/nodes/display/ColorAdjustment.js +1 -1
- package/src/nodes/display/PassNode.js +76 -15
- package/src/nodes/display/ScreenNode.js +22 -65
- package/src/nodes/fog/Fog.js +4 -4
- package/src/nodes/functions/BSDF/BRDF_GGX.js +6 -6
- package/src/nodes/functions/BSDF/BRDF_Sheen.js +1 -1
- package/src/nodes/functions/BSDF/DFGLUT.js +2 -1
- package/src/nodes/functions/BSDF/LTC.js +1 -1
- package/src/nodes/functions/PhongLightingModel.js +1 -1
- package/src/nodes/functions/PhysicalLightingModel.js +83 -25
- package/src/nodes/functions/ToonLightingModel.js +2 -2
- package/src/nodes/functions/material/getParallaxCorrectNormal.js +3 -3
- package/src/nodes/gpgpu/AtomicFunctionNode.js +64 -13
- package/src/nodes/gpgpu/BarrierNode.js +13 -4
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
- package/src/nodes/gpgpu/ComputeNode.js +20 -17
- package/src/nodes/gpgpu/SubgroupFunctionNode.js +165 -37
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +44 -6
- package/src/nodes/lighting/EnvironmentNode.js +40 -4
- package/src/nodes/lighting/LightsNode.js +20 -4
- package/src/nodes/lighting/ShadowBaseNode.js +158 -1
- package/src/nodes/lighting/ShadowFilterNode.js +2 -106
- package/src/nodes/lighting/ShadowNode.js +22 -91
- package/src/nodes/materialx/{lib/mx_hsv.js → MaterialXColor.js} +3 -6
- package/src/nodes/materialx/{lib/mx_transform_color.js → MaterialXColorTransform.js} +3 -6
- package/src/nodes/materialx/MaterialXCore.js +37 -0
- package/src/nodes/materialx/MaterialXNodes.js +64 -72
- package/src/nodes/materialx/{lib/mx_noise.js → MaterialXNoise.js} +426 -197
- package/src/nodes/math/BitcountNode.js +24 -4
- package/src/nodes/math/MathNode.js +4 -4
- package/src/nodes/math/MathUtils.js +15 -4
- package/src/nodes/math/OperatorNode.js +2 -2
- package/src/nodes/math/PackFloatNode.js +29 -1
- package/src/nodes/math/Packed4x8IntegerNode.js +433 -0
- package/src/nodes/math/UnpackFloatNode.js +30 -2
- package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
- package/src/nodes/pmrem/PMREMNode.js +1 -1
- package/src/nodes/pmrem/PMREMUtils.js +31 -74
- package/src/nodes/shapes/Shapes.js +1 -1
- package/src/nodes/tsl/TSLCore.js +1 -31
- package/src/nodes/utils/EventNode.js +75 -0
- package/src/nodes/utils/LoopNode.js +54 -13
- package/src/nodes/utils/PostProcessingUtils.js +23 -2
- package/src/nodes/utils/RTTNode.js +97 -32
- package/src/nodes/utils/ReflectorNode.js +8 -4
- package/src/nodes/utils/RotateNode.js +85 -8
- package/src/nodes/utils/SpriteUtils.js +58 -23
- package/src/objects/BatchedMesh.js +6 -0
- package/src/objects/InstancedMesh.js +1 -1
- package/src/objects/LOD.js +1 -1
- package/src/objects/Line.js +12 -0
- package/src/objects/Mesh.js +12 -0
- package/src/objects/Points.js +12 -0
- package/src/objects/Sprite.js +12 -0
- package/src/renderers/WebGLRenderer.js +93 -27
- package/src/renderers/common/Animation.js +12 -2
- package/src/renderers/common/Backend.js +38 -10
- package/src/renderers/common/BindGroup.js +0 -1
- package/src/renderers/common/Bindings.js +50 -4
- package/src/renderers/common/BundleGroup.js +4 -0
- package/src/renderers/common/ClippingContext.js +11 -1
- package/src/renderers/common/Color4.js +9 -0
- package/src/renderers/common/Constants.js +0 -5
- package/src/renderers/common/DirectRenderPipeline.js +233 -0
- package/src/renderers/common/Geometries.js +24 -3
- package/src/renderers/common/Info.js +3 -3
- package/src/renderers/common/InspectorBase.js +37 -8
- package/src/renderers/common/Lighting.js +11 -4
- package/src/renderers/common/Pipelines.js +6 -4
- package/src/renderers/common/QuadMesh.js +16 -2
- package/src/renderers/common/RenderContext.js +8 -0
- package/src/renderers/common/RenderList.js +53 -19
- package/src/renderers/common/RenderLists.js +58 -11
- package/src/renderers/common/RenderObject.js +14 -0
- package/src/renderers/common/RenderObjects.js +14 -9
- package/src/renderers/common/RenderPipeline.js +52 -44
- package/src/renderers/common/Renderer.js +226 -55
- package/src/renderers/common/Storage3DTexture.js +16 -0
- package/src/renderers/common/Textures.js +3 -3
- package/src/renderers/common/XRManager.js +79 -72
- package/src/renderers/common/extras/PMREMGenerator.js +76 -144
- package/src/renderers/common/nodes/NodeManager.js +144 -6
- package/src/renderers/common/nodes/NodeStorageBuffer.js +3 -1
- package/src/renderers/common/nodes/NodeUniformBuffer.js +3 -1
- package/src/renderers/shaders/DFGLUTData.js +2 -1
- package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +4 -2
- package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +48 -0
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +53 -4
- package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +20 -2
- package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +20 -0
- package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +61 -57
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +82 -0
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +9 -0
- package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +8 -1
- package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +15 -0
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
- package/src/renderers/shaders/ShaderLib.js +1 -0
- package/src/renderers/shaders/UniformsLib.js +16 -0
- package/src/renderers/webgl/WebGLAnimation.js +2 -2
- package/src/renderers/webgl/WebGLCapabilities.js +2 -2
- package/src/renderers/webgl/WebGLLights.js +74 -4
- package/src/renderers/webgl/WebGLMaterials.js +6 -0
- package/src/renderers/webgl/WebGLOutput.js +36 -24
- package/src/renderers/webgl/WebGLProgram.js +3 -0
- package/src/renderers/webgl/WebGLPrograms.js +8 -0
- package/src/renderers/webgl/WebGLRenderLists.js +6 -10
- package/src/renderers/webgl/WebGLShadowMap.js +47 -44
- package/src/renderers/webgl/WebGLTextures.js +7 -7
- package/src/renderers/webgl-fallback/WebGLBackend.js +153 -45
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +83 -29
- package/src/renderers/webgl-fallback/utils/WebGLState.js +163 -17
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +32 -5
- package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +11 -4
- package/src/renderers/webgpu/WebGPUBackend.js +513 -145
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +99 -20
- package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -1
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +3 -12
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +24 -14
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +80 -14
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -7
- package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +9 -3
- package/src/renderers/webgpu/utils/WebGPUUtils.js +16 -4
- package/src/renderers/webxr/WebXRManager.js +25 -2
- package/src/scenes/Scene.js +3 -3
- package/src/textures/CompressedArrayTexture.js +16 -0
- package/src/textures/Data3DTexture.js +16 -0
- package/src/textures/DataArrayTexture.js +16 -0
- package/src/textures/DepthTexture.js +3 -3
- package/src/textures/Texture.js +3 -3
- package/src/textures/{Source.js → TextureSource.js} +39 -8
- package/build/three.core.min.js +0 -6
- package/build/three.module.min.js +0 -6
- package/build/three.tsl.min.js +0 -6
- package/build/three.webgpu.min.js +0 -6
- package/build/three.webgpu.nodes.min.js +0 -6
- package/examples/jsm/libs/ecsy.module.js +0 -1792
- package/examples/jsm/loaders/LottieLoader.js +0 -130
- 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
|
|
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
|
|
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
|
|
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 );
|