@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.
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BufferAttribute,
|
|
2
3
|
BufferGeometry,
|
|
3
|
-
Float32BufferAttribute,
|
|
4
4
|
Group,
|
|
5
5
|
Mesh
|
|
6
6
|
} from '@gnsx/three';
|
|
@@ -11,22 +11,12 @@ import { cameraPosition, color, float, Fn, If, mix, mx_noise_float, normalView,
|
|
|
11
11
|
import { ImprovedNoise } from '../math/ImprovedNoise.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Bakes a procedural mountain range into a single
|
|
15
|
-
*
|
|
14
|
+
* Bakes a procedural mountain range into a single mesh, returned in a `THREE.Group`.
|
|
15
|
+
* Domain-warped, derivative-damped noise shapes the ridges; thermal erosion relaxes
|
|
16
|
+
* steep slopes. A TSL material shades grass, rock and snow from altitude and slope.
|
|
16
17
|
*
|
|
17
|
-
* The
|
|
18
|
-
*
|
|
19
|
-
* into weathered ridgelines, and a low-frequency domain warp makes those ridges
|
|
20
|
-
* meander. A few passes of thermal ( talus ) erosion then relax any slope past the
|
|
21
|
-
* angle of repose, settling the fractal's needle-spikes into real crests.
|
|
22
|
-
*
|
|
23
|
-
* The grid is triangulated with alternating quad diagonals ( a diamond pattern ), so a
|
|
24
|
-
* coarse mesh holds its silhouette without a one-way grain. The surface shades itself
|
|
25
|
-
* from altitude and slope in TSL — grass, forest, rock, scree and snow, with detail
|
|
26
|
-
* normals and aerial perspective — so no material or textures are needed.
|
|
27
|
-
*
|
|
28
|
-
* The baked height grid is exposed through {@link TerrainGenerator#sampleHeight} so a
|
|
29
|
-
* scattered forest ( or anything else ) can sit exactly on the surface.
|
|
18
|
+
* The baked grid is available through {@link TerrainGenerator#sampleHeight} for
|
|
19
|
+
* placing a forest or other objects on the terrain.
|
|
30
20
|
*
|
|
31
21
|
* ```js
|
|
32
22
|
* const terrain = new TerrainGenerator( { seed: 1 } );
|
|
@@ -82,6 +72,8 @@ class TerrainGenerator {
|
|
|
82
72
|
|
|
83
73
|
// lay the grid out flat in the XZ plane ( Y-up ) and find the height range
|
|
84
74
|
const positions = new Float32Array( N * N * 3 );
|
|
75
|
+
const normals = new Float32Array( N * N * 3 );
|
|
76
|
+
const cellSize = p.size / p.segments;
|
|
85
77
|
let min = Infinity, max = - Infinity;
|
|
86
78
|
|
|
87
79
|
for ( let iz = 0; iz < N; iz ++ ) {
|
|
@@ -95,6 +87,16 @@ class TerrainGenerator {
|
|
|
95
87
|
positions[ o * 3 + 1 ] = y;
|
|
96
88
|
positions[ o * 3 + 2 ] = coord[ iz ];
|
|
97
89
|
|
|
90
|
+
// Sample the grid's gradient so alternating triangle fans have equal weight.
|
|
91
|
+
const left = Math.max( 0, ix - 1 ), right = Math.min( N - 1, ix + 1 );
|
|
92
|
+
const back = Math.max( 0, iz - 1 ), front = Math.min( N - 1, iz + 1 );
|
|
93
|
+
const nx = ( heights[ iz * N + left ] - heights[ iz * N + right ] ) / ( ( right - left ) * cellSize );
|
|
94
|
+
const nz = ( heights[ back * N + ix ] - heights[ front * N + ix ] ) / ( ( front - back ) * cellSize );
|
|
95
|
+
const length = Math.hypot( nx, 1, nz );
|
|
96
|
+
normals[ o * 3 ] = nx / length;
|
|
97
|
+
normals[ o * 3 + 1 ] = 1 / length;
|
|
98
|
+
normals[ o * 3 + 2 ] = nz / length;
|
|
99
|
+
|
|
98
100
|
if ( y < min ) min = y;
|
|
99
101
|
if ( y > max ) max = y;
|
|
100
102
|
|
|
@@ -104,25 +106,32 @@ class TerrainGenerator {
|
|
|
104
106
|
|
|
105
107
|
// flip the quad diagonal on every other quad, so the mesh reads as diamonds
|
|
106
108
|
// rather than a one-way grain
|
|
107
|
-
const
|
|
109
|
+
const IndexArray = N * N > 65535 ? Uint32Array : Uint16Array;
|
|
110
|
+
const indices = new IndexArray( p.segments * p.segments * 6 );
|
|
111
|
+
let index = 0;
|
|
108
112
|
|
|
109
113
|
for ( let iz = 0; iz < p.segments; iz ++ ) {
|
|
110
114
|
|
|
111
115
|
for ( let ix = 0; ix < p.segments; ix ++ ) {
|
|
112
116
|
|
|
113
117
|
const a = iz * N + ix, b = a + 1, c = a + N, d = c + 1;
|
|
118
|
+
const even = ( ix + iz ) % 2 === 0;
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
indices[ index ++ ] = a;
|
|
121
|
+
indices[ index ++ ] = c;
|
|
122
|
+
indices[ index ++ ] = even ? b : d;
|
|
123
|
+
indices[ index ++ ] = even ? b : a;
|
|
124
|
+
indices[ index ++ ] = even ? c : d;
|
|
125
|
+
indices[ index ++ ] = even ? d : b;
|
|
117
126
|
|
|
118
127
|
}
|
|
119
128
|
|
|
120
129
|
}
|
|
121
130
|
|
|
122
131
|
const geometry = new BufferGeometry();
|
|
123
|
-
geometry.setAttribute( 'position', new
|
|
124
|
-
geometry.
|
|
125
|
-
geometry.
|
|
132
|
+
geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
|
|
133
|
+
geometry.setAttribute( 'normal', new BufferAttribute( normals, 3 ) );
|
|
134
|
+
geometry.setIndex( new BufferAttribute( indices, 1 ) );
|
|
126
135
|
|
|
127
136
|
this.heights = heights;
|
|
128
137
|
this.gridSize = N;
|
|
@@ -384,7 +393,7 @@ function thermalErode( h, N, cellSize, talus, passes ) {
|
|
|
384
393
|
// method. the built-in bumpMap reads height by offsetting the UV — a no-op for a
|
|
385
394
|
// world-keyed height — so the height's screen-space derivatives are fed in directly.
|
|
386
395
|
// returns a view-space normal.
|
|
387
|
-
function bumpNormal( height ) {
|
|
396
|
+
function bumpNormal( height, strength ) {
|
|
388
397
|
|
|
389
398
|
const dpdx = positionView.dFdx();
|
|
390
399
|
const dpdy = positionView.dFdy();
|
|
@@ -393,7 +402,7 @@ function bumpNormal( height ) {
|
|
|
393
402
|
const det = dpdx.dot( r1 );
|
|
394
403
|
const grad = det.sign().mul( height.dFdx().mul( r1 ).add( height.dFdy().mul( r2 ) ) );
|
|
395
404
|
|
|
396
|
-
return det.abs().mul( normalView ).sub( grad ).normalize();
|
|
405
|
+
return det.abs().mul( normalView ).sub( grad.mul( strength ) ).normalize();
|
|
397
406
|
|
|
398
407
|
}
|
|
399
408
|
|
|
@@ -420,7 +429,7 @@ function terrainMaterial( minHeight, maxHeight ) {
|
|
|
420
429
|
const grass = color( 0x6e7253 ); // dry sage-olive meadow ( not video-game green )
|
|
421
430
|
const dryGrass = color( 0x8a8550 );
|
|
422
431
|
const forest = color( 0x39402f ); // dark forested mid-slope band, under the trees
|
|
423
|
-
const rock = color(
|
|
432
|
+
const rock = color( 0x716e68 ); // weathered grey-brown rock
|
|
424
433
|
const scree = color( 0x837a6f ); // brighter broken rock below the cliffs
|
|
425
434
|
const lichen = color( 0x6c7355 ); // muted green-grey, patched onto lower rock
|
|
426
435
|
const snow = color( 0xe9ecf0 ); // fresh snow; warm-sun / cool-sky cast is from the lighting
|
|
@@ -428,13 +437,13 @@ function terrainMaterial( minHeight, maxHeight ) {
|
|
|
428
437
|
|
|
429
438
|
// two band frequencies of lighter / darker stone, wobbled by noise, so cliff faces
|
|
430
439
|
// read as layered bedding instead of flat grey
|
|
431
|
-
const bandA = positionWorld.y.mul( 0.5 ).add( detail.mul( 3 ) ).add( macro.mul( 4 ) ).sin();
|
|
440
|
+
const bandA = positionWorld.y.mul( 0.5 ).add( positionWorld.x.mul( 0.08 ) ).add( positionWorld.z.mul( 0.05 ) ).add( detail.mul( 3 ) ).add( macro.mul( 4 ) ).sin();
|
|
432
441
|
const bandB = positionWorld.y.mul( 1.4 ).add( grain.mul( 2 ) ).sin();
|
|
433
442
|
const strata = bandA.mul( 0.6 ).add( bandB.mul( 0.4 ) ).mul( 0.5 ).add( 0.5 );
|
|
434
443
|
|
|
435
444
|
// lichen creeps onto the lower, gentler rock; cliffs and high ground stay bare grey
|
|
436
445
|
const lichenMask = smoothstep( 0.45, 0.72, grain ).mul( smoothstep( 0.62, 0.32, steep ) ).mul( smoothstep( 0.66, 0.34, altitude ) );
|
|
437
|
-
const rockShade = mix( rock, lichen, lichenMask.mul( 0.45 ) ).mul( strata.mul( 0.36 ).add( 0.8 ) );
|
|
446
|
+
const rockShade = mix( rock, lichen, lichenMask.mul( 0.45 ) ).mul( strata.mul( 0.36 ).add( 0.8 ) ).mul( grain.mul( 0.18 ).add( 1 ) );
|
|
438
447
|
|
|
439
448
|
// meadow, drifting to dry grass in macro-noise patches over a mid band
|
|
440
449
|
let surface = mix( grass, dryGrass, smoothstep( 0.15, 0.75, macro ).mul( smoothstep( 0.22, 0.5, altitude ) ) );
|
|
@@ -452,7 +461,7 @@ function terrainMaterial( minHeight, maxHeight ) {
|
|
|
452
461
|
|
|
453
462
|
// snow on high, flat ground; the grain noise breaks the line so rock pokes through
|
|
454
463
|
// near the snowline instead of stopping on a clean contour
|
|
455
|
-
const snowMask = smoothstep( 0.56, 0.78, altitude.add( detail.mul( 0.08 ) ).add( grain.mul( 0.05 ) ) ).mul( smoothstep( 0.
|
|
464
|
+
const snowMask = smoothstep( 0.56, 0.78, altitude.add( detail.mul( 0.08 ) ).add( grain.mul( 0.05 ) ) ).mul( smoothstep( 0.45, 0.75, flatness ) );
|
|
456
465
|
const snowColor = mix( snow, snowDeep, smoothstep( 0.2, 0.7, grain ).mul( 0.6 ) ); // patchy, not a flat sheet
|
|
457
466
|
surface = mix( surface, snowColor, snowMask );
|
|
458
467
|
|
|
@@ -473,21 +482,23 @@ function terrainMaterial( minHeight, maxHeight ) {
|
|
|
473
482
|
material.colorNode = surface;
|
|
474
483
|
material.roughnessNode = mix( float( 0.95 ), float( 0.72 ), snowMask );
|
|
475
484
|
|
|
476
|
-
//
|
|
477
|
-
// they can't alias into fireflies in the haze. gating the noise behind the fade ( a
|
|
478
|
-
// real branch ) lets the far majority of this fragment-bound terrain skip the taps.
|
|
485
|
+
// Volumetric noise keeps relief consistent on cliffs. Skip fine grain in the distance.
|
|
479
486
|
const detailFade = smoothstep( 420, 60, distance );
|
|
480
|
-
const
|
|
487
|
+
const grainFade = smoothstep( 180, 40, distance );
|
|
488
|
+
const reliefStrength = mix( mix( float( 0.25 ), float( 0.55 ), steep ), float( 0.04 ), snowMask );
|
|
481
489
|
const relief = Fn( () => {
|
|
482
490
|
|
|
483
491
|
const r = float( 0 ).toVar();
|
|
484
492
|
|
|
485
493
|
If( detailFade.greaterThan( 0.01 ), () => {
|
|
486
494
|
|
|
487
|
-
r.assign( mx_noise_float( positionWorld.
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
495
|
+
r.assign( mx_noise_float( positionWorld.mul( 0.6 ) ) );
|
|
496
|
+
|
|
497
|
+
If( grainFade.greaterThan( 0.01 ), () => {
|
|
498
|
+
|
|
499
|
+
r.addAssign( mx_noise_float( positionWorld.mul( 1.7 ) ).mul( 0.5 ).mul( grainFade ) );
|
|
500
|
+
|
|
501
|
+
} );
|
|
491
502
|
|
|
492
503
|
} );
|
|
493
504
|
|
|
@@ -495,7 +506,8 @@ function terrainMaterial( minHeight, maxHeight ) {
|
|
|
495
506
|
|
|
496
507
|
} )();
|
|
497
508
|
|
|
498
|
-
|
|
509
|
+
// Apply strength after differentiating the noise; slope derivatives reveal triangles.
|
|
510
|
+
material.normalNode = bumpNormal( relief, reliefStrength.mul( detailFade ).mul( 0.25 ) );
|
|
499
511
|
|
|
500
512
|
return material;
|
|
501
513
|
|
|
@@ -17,12 +17,9 @@ const TAU = Math.PI * 2;
|
|
|
17
17
|
const UP = /*@__PURE__*/ new Vector3( 0, 1, 0 );
|
|
18
18
|
const _axis = /*@__PURE__*/ new Vector3();
|
|
19
19
|
|
|
20
|
-
// reusable scratch for one tube's ring vertices ( grows to the largest tube seen )
|
|
21
|
-
let _ring = new Float32Array( 0 );
|
|
22
|
-
|
|
23
20
|
/**
|
|
24
21
|
* Grows a procedural tree skeleton — trunk, branches and twigs, each swept as a tapered
|
|
25
|
-
* tube — and bakes it into one
|
|
22
|
+
* tube — and bakes it into one indexed {@link BufferGeometry} (position and normal
|
|
26
23
|
* only), ready to instance into a forest. It produces *branches only*; add foliage as a
|
|
27
24
|
* separate layer.
|
|
28
25
|
*
|
|
@@ -58,26 +55,10 @@ class TreeGenerator {
|
|
|
58
55
|
const p = Object.assign( {}, TreeGenerator.defaults, this.parameters );
|
|
59
56
|
const random = createRandom( p.seed );
|
|
60
57
|
|
|
61
|
-
// grow the skeleton into a flat list of tubes, then size and fill the geometry in
|
|
62
|
-
// one pass — no per-vertex objects, no array growth
|
|
63
|
-
|
|
64
58
|
const tubes = [];
|
|
65
59
|
growBranch( tubes, new Vector3(), UP, p.trunkLength, p.trunkRadius, 0, p, random );
|
|
66
60
|
|
|
67
|
-
|
|
68
|
-
for ( const tube of tubes ) vertexCount += ( tube.rings.length - 1 ) * tube.radial * 6;
|
|
69
|
-
|
|
70
|
-
const positions = new Float32Array( vertexCount * 3 );
|
|
71
|
-
const normals = new Float32Array( vertexCount * 3 );
|
|
72
|
-
|
|
73
|
-
let offset = 0;
|
|
74
|
-
for ( const tube of tubes ) offset = emitTube( positions, normals, offset, tube.rings, tube.radial );
|
|
75
|
-
|
|
76
|
-
const geometry = new BufferGeometry();
|
|
77
|
-
geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
|
|
78
|
-
geometry.setAttribute( 'normal', new BufferAttribute( normals, 3 ) );
|
|
79
|
-
geometry.computeBoundingSphere();
|
|
80
|
-
|
|
61
|
+
const geometry = createGeometry( tubes );
|
|
81
62
|
const mesh = new Mesh( geometry, this.material || createTreeMaterial() );
|
|
82
63
|
mesh.name = 'Tree';
|
|
83
64
|
|
|
@@ -94,6 +75,8 @@ TreeGenerator.defaults = {
|
|
|
94
75
|
branchAngle: [ 38, 50, 58 ], // degrees a child tilts off its parent axis, per level
|
|
95
76
|
angleVariance: 14, // degrees of random jitter on the branch angle, breaks fractal regularity
|
|
96
77
|
lengthRatio: 0.62, // child length / parent length
|
|
78
|
+
lengthVariance: 0, // fractional variation in child length
|
|
79
|
+
branchLengthFalloff: 0, // shorten children toward the tip of their parent
|
|
97
80
|
trunkLength: 9, // trunk length in world units; sets the tree's height
|
|
98
81
|
trunkRadius: 0.42, // base radius of the trunk
|
|
99
82
|
taper: 0.55, // a branch thins to ( 1 - taper ) of its base radius along its own length
|
|
@@ -162,7 +145,6 @@ function growBranch( tubes, base, dir, length, baseRadius, level, p, random ) {
|
|
|
162
145
|
pos: pos.clone(),
|
|
163
146
|
tangent: tangent.clone(),
|
|
164
147
|
normal: normal.clone(),
|
|
165
|
-
binormal: new Vector3().crossVectors( tangent, normal ),
|
|
166
148
|
radius
|
|
167
149
|
} );
|
|
168
150
|
|
|
@@ -212,7 +194,10 @@ function growBranch( tubes, base, dir, length, baseRadius, level, p, random ) {
|
|
|
212
194
|
// the pipe-model drop, but never fatter than the wood it leaves nor below the floor
|
|
213
195
|
const childBase = Math.max( p.minRadius, Math.min( baseRadius * pipeDrop, ring.radius ) );
|
|
214
196
|
|
|
215
|
-
|
|
197
|
+
let childLength = length * p.lengthRatio * ( 1 - p.branchLengthFalloff * t );
|
|
198
|
+
if ( p.lengthVariance > 0 ) childLength *= 1 + ( random() * 2 - 1 ) * p.lengthVariance;
|
|
199
|
+
|
|
200
|
+
growBranch( tubes, ring.pos, childDir, childLength, childBase, level + 1, p, random );
|
|
216
201
|
|
|
217
202
|
}
|
|
218
203
|
|
|
@@ -244,7 +229,7 @@ function ringAt( rings, t ) {
|
|
|
244
229
|
const i = Math.floor( f );
|
|
245
230
|
const frac = f - i;
|
|
246
231
|
const a = rings[ i ];
|
|
247
|
-
const b = rings[
|
|
232
|
+
const b = rings[ i + 1 ];
|
|
248
233
|
|
|
249
234
|
return {
|
|
250
235
|
pos: a.pos.clone().lerp( b.pos, frac ),
|
|
@@ -257,79 +242,87 @@ function ringAt( rings, t ) {
|
|
|
257
242
|
|
|
258
243
|
// --- geometry ------------------------------------------------------------
|
|
259
244
|
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
// Ring vertices are computed once into a reused scratch, then stitched straight into the
|
|
263
|
-
// preallocated geometry arrays — no per-vertex objects.
|
|
264
|
-
function emitTube( positions, normals, offset, rings, radial ) {
|
|
245
|
+
// Write each ring vertex once, then join adjacent rings with indexed triangles.
|
|
246
|
+
function createGeometry( tubes ) {
|
|
265
247
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if ( _ring.length < needed ) _ring = new Float32Array( needed );
|
|
248
|
+
let vertexCount = 0;
|
|
249
|
+
let indexCount = 0;
|
|
269
250
|
|
|
270
|
-
const
|
|
251
|
+
for ( const { rings, radial } of tubes ) {
|
|
271
252
|
|
|
272
|
-
|
|
253
|
+
vertexCount += rings.length * radial;
|
|
254
|
+
indexCount += ( rings.length - 1 ) * radial * 6;
|
|
273
255
|
|
|
274
|
-
|
|
275
|
-
let o = r * stride;
|
|
256
|
+
}
|
|
276
257
|
|
|
277
|
-
|
|
258
|
+
const positions = new Float32Array( vertexCount * 3 );
|
|
259
|
+
const normals = new Float32Array( vertexCount * 3 );
|
|
260
|
+
const indices = new ( vertexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );
|
|
261
|
+
const binormal = new Vector3();
|
|
278
262
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const s = Math.sin( a );
|
|
282
|
-
const nx = c * normal.x + s * binormal.x;
|
|
283
|
-
const ny = c * normal.y + s * binormal.y;
|
|
284
|
-
const nz = c * normal.z + s * binormal.z;
|
|
263
|
+
let vertexOffset = 0;
|
|
264
|
+
let indexOffset = 0;
|
|
285
265
|
|
|
286
|
-
|
|
287
|
-
ring[ o ++ ] = pos.y + ny * radius;
|
|
288
|
-
ring[ o ++ ] = pos.z + nz * radius;
|
|
289
|
-
ring[ o ++ ] = nx;
|
|
290
|
-
ring[ o ++ ] = ny;
|
|
291
|
-
ring[ o ++ ] = nz;
|
|
266
|
+
for ( const { rings, radial } of tubes ) {
|
|
292
267
|
|
|
293
|
-
|
|
268
|
+
let offset = vertexOffset * 3;
|
|
294
269
|
|
|
295
|
-
|
|
270
|
+
for ( const { pos, tangent, normal, radius } of rings ) {
|
|
296
271
|
|
|
297
|
-
|
|
272
|
+
binormal.crossVectors( tangent, normal );
|
|
298
273
|
|
|
299
|
-
|
|
274
|
+
for ( let j = 0; j < radial; j ++ ) {
|
|
300
275
|
|
|
301
|
-
|
|
302
|
-
|
|
276
|
+
const angle = j / radial * TAU;
|
|
277
|
+
const c = Math.cos( angle );
|
|
278
|
+
const s = Math.sin( angle );
|
|
279
|
+
const nx = c * normal.x + s * binormal.x;
|
|
280
|
+
const ny = c * normal.y + s * binormal.y;
|
|
281
|
+
const nz = c * normal.z + s * binormal.z;
|
|
303
282
|
|
|
304
|
-
|
|
283
|
+
positions[ offset ] = pos.x + nx * radius;
|
|
284
|
+
positions[ offset + 1 ] = pos.y + ny * radius;
|
|
285
|
+
positions[ offset + 2 ] = pos.z + nz * radius;
|
|
286
|
+
normals[ offset ] = nx;
|
|
287
|
+
normals[ offset + 1 ] = ny;
|
|
288
|
+
normals[ offset + 2 ] = nz;
|
|
289
|
+
offset += 3;
|
|
305
290
|
|
|
306
|
-
|
|
307
|
-
const bL = b + j * 6, bR = b + ( j + 1 ) * 6;
|
|
291
|
+
}
|
|
308
292
|
|
|
309
|
-
|
|
310
|
-
offset = copyVertex( positions, normals, offset, ring, bR );
|
|
311
|
-
offset = copyVertex( positions, normals, offset, ring, bL );
|
|
293
|
+
}
|
|
312
294
|
|
|
313
|
-
|
|
314
|
-
offset = copyVertex( positions, normals, offset, ring, aR );
|
|
315
|
-
offset = copyVertex( positions, normals, offset, ring, bR );
|
|
295
|
+
for ( let r = 0; r < rings.length - 1; r ++ ) {
|
|
316
296
|
|
|
317
|
-
|
|
297
|
+
const a = vertexOffset + r * radial;
|
|
298
|
+
const b = a + radial;
|
|
318
299
|
|
|
319
|
-
|
|
300
|
+
for ( let j = 0; j < radial; j ++ ) {
|
|
320
301
|
|
|
321
|
-
|
|
302
|
+
const next = ( j + 1 ) % radial; // wrap the seam back to the first vertex
|
|
322
303
|
|
|
323
|
-
|
|
304
|
+
indices[ indexOffset ++ ] = a + j;
|
|
305
|
+
indices[ indexOffset ++ ] = b + next;
|
|
306
|
+
indices[ indexOffset ++ ] = b + j;
|
|
307
|
+
indices[ indexOffset ++ ] = a + j;
|
|
308
|
+
indices[ indexOffset ++ ] = a + next;
|
|
309
|
+
indices[ indexOffset ++ ] = b + next;
|
|
310
|
+
|
|
311
|
+
}
|
|
324
312
|
|
|
325
|
-
|
|
326
|
-
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
vertexOffset += rings.length * radial;
|
|
316
|
+
|
|
317
|
+
}
|
|
327
318
|
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
319
|
+
const geometry = new BufferGeometry();
|
|
320
|
+
geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
|
|
321
|
+
geometry.setAttribute( 'normal', new BufferAttribute( normals, 3 ) );
|
|
322
|
+
geometry.setIndex( new BufferAttribute( indices, 1 ) );
|
|
323
|
+
geometry.computeBoundingSphere();
|
|
331
324
|
|
|
332
|
-
return
|
|
325
|
+
return geometry;
|
|
333
326
|
|
|
334
327
|
}
|
|
335
328
|
|
|
@@ -356,7 +349,7 @@ function createRandom( seed ) {
|
|
|
356
349
|
* A simple bark material for a {@link TreeGenerator} mesh: a low-saturation brown with a
|
|
357
350
|
* faint, vertically-stretched grain, so trunks read near-black against bright fog.
|
|
358
351
|
*
|
|
359
|
-
* @param {Object} [parameters] - `barkColor` ( a hex, THREE.Color or TSL node ).
|
|
352
|
+
* @param {Object} [parameters] - `barkColor` ( a hex, THREE.Color or TSL node ) and `barkScale` ( a THREE.Vector3 ).
|
|
360
353
|
* @return {MeshStandardNodeMaterial}
|
|
361
354
|
*/
|
|
362
355
|
function createTreeMaterial( parameters = {} ) {
|
|
@@ -365,7 +358,8 @@ function createTreeMaterial( parameters = {} ) {
|
|
|
365
358
|
const barkColor = c === undefined ? color( 0x4b3a2b ) : ( c.isColor || typeof c === 'number' ? color( c ) : c );
|
|
366
359
|
|
|
367
360
|
const material = new MeshStandardNodeMaterial();
|
|
368
|
-
const
|
|
361
|
+
const barkScale = parameters.barkScale ? vec3( parameters.barkScale ) : vec3( 2.5, 0.4, 2.5 );
|
|
362
|
+
const grain = mx_fractal_noise_float( positionLocal.mul( barkScale ), 3 ).mul( 0.18 );
|
|
369
363
|
material.colorNode = barkColor.mul( grain.add( 0.9 ) );
|
|
370
364
|
material.roughnessNode = float( 0.95 );
|
|
371
365
|
material.metalnessNode = float( 0 );
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BoxGeometry,
|
|
3
|
+
InterpolationSamplingMode,
|
|
4
|
+
InterpolationSamplingType
|
|
5
|
+
} from '@gnsx/three';
|
|
6
|
+
|
|
7
|
+
import { MeshStandardNodeMaterial } from '@gnsx/three/webgpu';
|
|
8
|
+
import { attribute, color, float, floor, fract, mix, mx_fractal_noise_float, positionGeometry, select, sin, varying, vec3 } from '@gnsx/three/tsl';
|
|
9
|
+
|
|
10
|
+
import { mergeGeometries } from '../../utils/BufferGeometryUtils.js';
|
|
11
|
+
|
|
12
|
+
import { InstancedMeshGenerator } from './InstancedMeshGenerator.js';
|
|
13
|
+
import { part } from './CityGeneratorUtils.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A public street bench: timber slats carried on two cast-iron end frames that
|
|
17
|
+
* curl into armrests, with a reclined slatted backrest. Built once and instanced
|
|
18
|
+
* across a list of placements, dressed with one cheap material that branches on a
|
|
19
|
+
* baked `partId` ( warm stained wood, dark iron ).
|
|
20
|
+
*
|
|
21
|
+
* The canonical model stands on `y = 0`, centred in X / Z, runs along X and seats
|
|
22
|
+
* toward `+Z`, so a placement whose local `+Z` faces the road sits a passer-by
|
|
23
|
+
* looking out over it.
|
|
24
|
+
*
|
|
25
|
+
* ```js
|
|
26
|
+
* const benches = new BenchGenerator();
|
|
27
|
+
* scene.add( benches.build( placements ) ); // placements: Matrix4[]
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
class BenchGenerator extends InstancedMeshGenerator {
|
|
31
|
+
|
|
32
|
+
constructor( parameters = {} ) {
|
|
33
|
+
|
|
34
|
+
super( parameters, buildBenchGeometry, createBenchMaterial, 'Benches' );
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
BenchGenerator.defaults = {
|
|
41
|
+
length: 1.8, // spans X
|
|
42
|
+
depth: 0.55, // front-to-back
|
|
43
|
+
seatHeight: 0.45,
|
|
44
|
+
backHeight: 0.85
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// material-zone codes baked per vertex
|
|
48
|
+
const WOOD = 0, IRON = 1;
|
|
49
|
+
|
|
50
|
+
function buildBenchGeometry( p ) {
|
|
51
|
+
|
|
52
|
+
const halfLength = p.length / 2;
|
|
53
|
+
const halfDepth = p.depth / 2;
|
|
54
|
+
const seatY = p.seatHeight;
|
|
55
|
+
const backY = p.backHeight;
|
|
56
|
+
|
|
57
|
+
const frontZ = halfDepth - 0.075; // legs set just inside the depth
|
|
58
|
+
const backZ = - frontZ;
|
|
59
|
+
|
|
60
|
+
const parts = [];
|
|
61
|
+
|
|
62
|
+
// two cast-iron end frames brace the slats and curl into armrests
|
|
63
|
+
for ( const side of [ - 1, 1 ] ) {
|
|
64
|
+
|
|
65
|
+
const x = side * ( halfLength - 0.07 );
|
|
66
|
+
|
|
67
|
+
const frontLeg = new BoxGeometry( 0.05, seatY, 0.06 ).translate( x, seatY / 2, frontZ );
|
|
68
|
+
const backLeg = new BoxGeometry( 0.05, backY, 0.06 ).translate( x, backY / 2, backZ ); // doubles as the backrest post
|
|
69
|
+
const seatRail = new BoxGeometry( 0.06, 0.05, frontZ - backZ + 0.1 ).translate( x, seatY - 0.04, 0 );
|
|
70
|
+
const armPost = new BoxGeometry( 0.05, 0.22, 0.05 ).translate( x, seatY + 0.11, frontZ );
|
|
71
|
+
const armRest = new BoxGeometry( 0.05, 0.05, frontZ - backZ + 0.06 ).translate( x, seatY + 0.22, 0 );
|
|
72
|
+
const armCurl = new BoxGeometry( 0.05, 0.16, 0.05 ).rotateX( - 0.6 ).translate( x, seatY + 0.18, frontZ + 0.07 ); // front scroll of the armrest
|
|
73
|
+
|
|
74
|
+
parts.push( part( frontLeg, IRON ), part( backLeg, IRON ), part( seatRail, IRON ), part( armPost, IRON ), part( armRest, IRON ), part( armCurl, IRON ) );
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// timber seat slats spaced front-to-back
|
|
79
|
+
const slatLength = p.length - 0.1;
|
|
80
|
+
const z0 = backZ + 0.02, z1 = frontZ - 0.02;
|
|
81
|
+
for ( let i = 0; i < 5; i ++ ) {
|
|
82
|
+
|
|
83
|
+
const z = z0 + ( z1 - z0 ) * ( i / 4 );
|
|
84
|
+
parts.push( part( new BoxGeometry( slatLength, 0.03, 0.07 ).translate( 0, seatY, z ), WOOD ) );
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// backrest slats climb the rear posts, reclined a touch
|
|
89
|
+
for ( let i = 0; i < 3; i ++ ) {
|
|
90
|
+
|
|
91
|
+
const t = i / 2;
|
|
92
|
+
const y = seatY + 0.13 + t * 0.27;
|
|
93
|
+
const z = backZ + 0.01 - t * 0.06;
|
|
94
|
+
parts.push( part( new BoxGeometry( slatLength, 0.09, 0.025 ).rotateX( 0.18 ).translate( 0, y, z ), WOOD ) );
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return mergeGeometries( parts );
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function createBenchMaterial() {
|
|
103
|
+
|
|
104
|
+
const partId = varying( attribute( 'partId', 'float' ) ).setInterpolation( InterpolationSamplingType.FLAT, InterpolationSamplingMode.EITHER );
|
|
105
|
+
const isWood = partId.equal( WOOD );
|
|
106
|
+
|
|
107
|
+
const p = positionGeometry;
|
|
108
|
+
|
|
109
|
+
// timber: grain streaks stretched along the slats, each slat cut from its own
|
|
110
|
+
// board ( a tone hashed from the slat's row position ) and greyed by weathering
|
|
111
|
+
const grain = mx_fractal_noise_float( p.mul( vec3( 3, 60, 60 ) ), 2 ).mul( 0.5 ).add( 0.5 );
|
|
112
|
+
const board = fract( sin( floor( p.z.mul( 10.5 ) ).add( floor( p.y.mul( 8.0 ) ).mul( 7.3 ) ).mul( 17.53 ) ).mul( 43758.5453 ) );
|
|
113
|
+
const weather = mx_fractal_noise_float( p.mul( 1.6 ), 2 ).mul( 0.5 ).add( 0.5 );
|
|
114
|
+
|
|
115
|
+
const stained = mix( color( 0x5e412a ), color( 0x8a6242 ), grain.mul( 0.7 ).add( board.mul( 0.3 ) ) );
|
|
116
|
+
const wood = mix( stained, color( 0x7c7468 ), weather.mul( 0.45 ) ); // sun-bleached grey where the stain has worn
|
|
117
|
+
|
|
118
|
+
const material = new MeshStandardNodeMaterial();
|
|
119
|
+
material.colorNode = select( isWood, wood, color( 0x232322 ) ); // weathered timber, dark cast iron
|
|
120
|
+
material.roughnessNode = select( isWood, grain.mul( 0.25 ).add( 0.65 ), float( 0.5 ) );
|
|
121
|
+
material.metalnessNode = select( isWood, float( 0 ), float( 0.6 ) );
|
|
122
|
+
|
|
123
|
+
return material;
|
|
124
|
+
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export { BenchGenerator };
|