@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,4 +1,4 @@
|
|
|
1
|
-
import { EPSILON, Fn, If, abs, convertToTexture, dFdx, dFdy, dot, exp, float, floor, fwidth, getViewPosition, ivec2, luminance, max, min, mix, nodeObject, normalize, passTexture, screenCoordinate, select, smoothstep, sqrt, struct, texture, textureLoad, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4, velocity } from '@gnsx/three/tsl';
|
|
1
|
+
import { EPSILON, Fn, If, abs, convertToTexture, dFdx, dFdy, dot, exp, float, floor, fwidth, getViewPosition, ivec2, luminance, max, min, mix, nodeObject, normalize, passTexture, screenCoordinate, select, smoothstep, sqrt, struct, texture, textureLoad, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4, velocity, context, OnBeforeRenderPipeline, OnAfterRenderPipeline } from '@gnsx/three/tsl';
|
|
2
2
|
import { DepthTexture, HalfFloatType, Matrix4, NodeMaterial, NodeUpdateType, QuadMesh, RenderTarget, RendererUtils, TempNode, Vector2, Vector3 } from '@gnsx/three/webgpu';
|
|
3
3
|
import { ENV_RAY_LENGTH, ENV_RAY_LENGTH_THRESHOLD } from '../utils/SpecularHelpers.js';
|
|
4
4
|
|
|
@@ -256,7 +256,7 @@ const sampleBilinearTap = Fn( ( [
|
|
|
256
256
|
const reprojDepth = textureLoad( previousDepthNode, tapCoord ).r;
|
|
257
257
|
const reprojViewPos = getViewPosition( vec2( tapCoord ).add( 0.5 ).div( resolution ), reprojDepth, previousProjectionMatrixInverse );
|
|
258
258
|
const reprojWorldPos = previousCameraWorldMatrix.mul( vec4( reprojViewPos, 1.0 ) ).xyz;
|
|
259
|
-
const reprojWorldNorm = unpackRGBToNormal( textureLoad( previousNormalNode, tapCoord ).rgb ).
|
|
259
|
+
const reprojWorldNorm = unpackRGBToNormal( textureLoad( previousNormalNode, tapCoord ).rgb ).transformNormalByInverseViewMatrix( previousCameraViewMatrix );
|
|
260
260
|
|
|
261
261
|
const planeDiff = abs( dot( reprojWorldPos.sub( worldPosition ), worldNormal ) ).toVar();
|
|
262
262
|
planeDiff.divAssign( abs( reprojViewPos.z ) );
|
|
@@ -727,36 +727,39 @@ class TemporalReprojectNode extends TempNode {
|
|
|
727
727
|
|
|
728
728
|
setup( builder ) {
|
|
729
729
|
|
|
730
|
-
const
|
|
730
|
+
const sharedContext = context( builder.getSharedContext() );
|
|
731
731
|
|
|
732
|
-
if ( renderPipeline ) {
|
|
732
|
+
if ( builder.renderPipeline && ! builder.context.renderPipelineState.viewOffsetOwner ) {
|
|
733
|
+
|
|
734
|
+
builder.context.renderPipelineState.viewOffsetOwner = this;
|
|
733
735
|
|
|
734
736
|
this._needsPostProcessingSync = true;
|
|
735
737
|
|
|
736
|
-
|
|
738
|
+
OnBeforeRenderPipeline( () => {
|
|
737
739
|
|
|
738
740
|
this.setViewOffset();
|
|
739
741
|
|
|
740
|
-
};
|
|
742
|
+
} );
|
|
741
743
|
|
|
742
|
-
|
|
744
|
+
OnAfterRenderPipeline( () => {
|
|
743
745
|
|
|
744
746
|
this.clearViewOffset();
|
|
745
747
|
|
|
746
|
-
};
|
|
748
|
+
} );
|
|
747
749
|
|
|
748
750
|
}
|
|
749
751
|
|
|
750
|
-
this._resolveMaterial.
|
|
752
|
+
this._resolveMaterial.contextNode = sharedContext;
|
|
753
|
+
this._resolveMaterial.fragmentNode = this._buildResolve();
|
|
751
754
|
this._resolveMaterial.needsUpdate = true;
|
|
752
755
|
|
|
753
|
-
this._buildSeed(
|
|
756
|
+
this._buildSeed( sharedContext );
|
|
754
757
|
|
|
755
758
|
return this._textureNode;
|
|
756
759
|
|
|
757
760
|
}
|
|
758
761
|
|
|
759
|
-
_buildSeed(
|
|
762
|
+
_buildSeed( sharedContext ) {
|
|
760
763
|
|
|
761
764
|
const seed = Fn( () => {
|
|
762
765
|
|
|
@@ -768,12 +771,13 @@ class TemporalReprojectNode extends TempNode {
|
|
|
768
771
|
|
|
769
772
|
} );
|
|
770
773
|
|
|
771
|
-
this._seedMaterial.
|
|
774
|
+
this._seedMaterial.contextNode = sharedContext;
|
|
775
|
+
this._seedMaterial.fragmentNode = seed();
|
|
772
776
|
this._seedMaterial.needsUpdate = true;
|
|
773
777
|
|
|
774
778
|
}
|
|
775
779
|
|
|
776
|
-
_buildResolve(
|
|
780
|
+
_buildResolve() {
|
|
777
781
|
|
|
778
782
|
const isSpecular = this.mode === 'specular';
|
|
779
783
|
const cameraUniforms = this._cameraUniforms;
|
|
@@ -794,7 +798,7 @@ class TemporalReprojectNode extends TempNode {
|
|
|
794
798
|
|
|
795
799
|
// Shared 3×3 beauty fetch: feeds both the variance-clip box and the SSR ray-length stats.
|
|
796
800
|
const neighborhood = collectNeighborhood( this.beautyNode, beautyTexel, inputColor, this.flickerSuppression );
|
|
797
|
-
const worldNormal = viewNormal.
|
|
801
|
+
const worldNormal = viewNormal.transformNormalByInverseViewMatrix( cameraUniforms.viewMatrix ).toVar();
|
|
798
802
|
|
|
799
803
|
const viewPosition = getViewPosition( uvNode, depth, cameraUniforms.projectionMatrixInverse ).toVar();
|
|
800
804
|
const worldPosition = cameraUniforms.worldMatrix.mul( vec4( viewPosition, 1.0 ) ).xyz.toVar();
|
|
@@ -944,7 +948,7 @@ class TemporalReprojectNode extends TempNode {
|
|
|
944
948
|
|
|
945
949
|
} );
|
|
946
950
|
|
|
947
|
-
return resolve()
|
|
951
|
+
return resolve();
|
|
948
952
|
|
|
949
953
|
}
|
|
950
954
|
|
|
@@ -979,6 +983,8 @@ class TemporalReprojectNode extends TempNode {
|
|
|
979
983
|
|
|
980
984
|
dispose() {
|
|
981
985
|
|
|
986
|
+
super.dispose();
|
|
987
|
+
|
|
982
988
|
this._previousNormalTexture.dispose();
|
|
983
989
|
|
|
984
990
|
if ( this._previousDepthNode.value !== this._historyRenderTarget.depthTexture ) {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { abs, exp, float, Fn, int, logarithmicDepthToViewZ, Loop, max, perspectiveDepthToViewZ, reference, uv } from '@gnsx/three/tsl';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Applies one pass of a separable, depth-aware (bilateral) blur to a screen-space signal.
|
|
5
|
+
*
|
|
6
|
+
* The spatial term is a fixed 5-tap gaussian along `directionNode`; the edge-stopping term
|
|
7
|
+
* rejects neighbours whose view-space depth differs from the center, so the signal is smoothed
|
|
8
|
+
* across surfaces but not across silhouettes. Depth rejection is measured relative to `radius`,
|
|
9
|
+
* which keeps it scale invariant. Run it twice (horizontal then vertical) for a full separable
|
|
10
|
+
* blur. Handy for denoising a half-resolution effect such as ambient occlusion.
|
|
11
|
+
*
|
|
12
|
+
* @tsl
|
|
13
|
+
* @function
|
|
14
|
+
* @param {Node<vec4>} inputNode - The texture node to blur; its red channel is filtered.
|
|
15
|
+
* @param {Node<float>} depthNode - The scene depth texture node.
|
|
16
|
+
* @param {Node<vec2>} directionNode - One texel step along the blur axis, e.g. `vec2( 1 / width, 0 )`.
|
|
17
|
+
* @param {Camera} camera - The camera the scene is rendered with.
|
|
18
|
+
* @param {Node<float> | number} [sharpness=2] - How strongly a depth difference rejects a neighbour.
|
|
19
|
+
* @param {Node<float> | number} [radius=1] - The world-space scale the depth rejection is relative to.
|
|
20
|
+
* @returns {Node<float>} The blurred value.
|
|
21
|
+
*/
|
|
22
|
+
export const depthAwareBlur = /*#__PURE__*/ Fn( ( [ inputNode, depthNode, directionNode, camera, sharpness = 2, radius = 1 ], builder ) => {
|
|
23
|
+
|
|
24
|
+
const cameraNear = reference( 'near', 'float', camera );
|
|
25
|
+
const cameraFar = reference( 'far', 'float', camera );
|
|
26
|
+
|
|
27
|
+
const viewZ = ( uvNode ) => {
|
|
28
|
+
|
|
29
|
+
const depth = depthNode.sample( uvNode ).r;
|
|
30
|
+
|
|
31
|
+
if ( builder.renderer.logarithmicDepthBuffer === true ) {
|
|
32
|
+
|
|
33
|
+
return logarithmicDepthToViewZ( depth, cameraNear, cameraFar );
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
|
|
38
|
+
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const uvNode = uv();
|
|
42
|
+
const centerViewZ = viewZ( uvNode ).toVar();
|
|
43
|
+
|
|
44
|
+
const sum = float( 0 ).toVar();
|
|
45
|
+
const weightSum = float( 0 ).toVar();
|
|
46
|
+
|
|
47
|
+
Loop( { start: int( - 2 ), end: int( 3 ), type: 'int', condition: '<' }, ( { i } ) => {
|
|
48
|
+
|
|
49
|
+
const fi = float( i );
|
|
50
|
+
const sampleUv = uvNode.add( directionNode.mul( fi ) );
|
|
51
|
+
|
|
52
|
+
const spatialWeight = exp( fi.mul( fi ).mul( - 0.5 ) );
|
|
53
|
+
const depthWeight = exp( abs( viewZ( sampleUv ).sub( centerViewZ ) ).div( radius ).mul( sharpness ).negate() );
|
|
54
|
+
const weight = spatialWeight.mul( depthWeight );
|
|
55
|
+
|
|
56
|
+
sum.addAssign( inputNode.sample( sampleUv ).r.mul( weight ) );
|
|
57
|
+
weightSum.addAssign( weight );
|
|
58
|
+
|
|
59
|
+
} );
|
|
60
|
+
|
|
61
|
+
return sum.div( max( weightSum, float( 0.0001 ) ) );
|
|
62
|
+
|
|
63
|
+
} );
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { float, Fn, vec2, uv, sin, rand,
|
|
1
|
+
import { float, Fn, vec2, uv, sin, rand, TWO_PI, cos, Loop, vec4, premultiplyAlpha, unpremultiplyAlpha, convertToTexture, nodeObject } from '@gnsx/three/tsl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Applies a hash blur effect to the given texture node.
|
|
@@ -41,7 +41,8 @@ export const hashBlur = /*#__PURE__*/ Fn( ( [ textureNode, bluramount = float( 0
|
|
|
41
41
|
|
|
42
42
|
Loop( { start: 0., end: repeats, type: 'float' }, ( { i } ) => {
|
|
43
43
|
|
|
44
|
-
const
|
|
44
|
+
const angle = i.div( repeats ).mul( TWO_PI ).toConst();
|
|
45
|
+
const q = vec2( cos( angle ), sin( angle ) ).mul( rand( vec2( i, targetUV.x.add( targetUV.y ) ) ).add( bluramount ) );
|
|
45
46
|
const uv2 = vec2( targetUV.add( q.mul( bluramount ) ) );
|
|
46
47
|
blurred_image.addAssign( tap( uv2 ) );
|
|
47
48
|
|
|
@@ -44,7 +44,6 @@ class ClusteredLightsNode extends LightsNode {
|
|
|
44
44
|
|
|
45
45
|
this.materialLights = [];
|
|
46
46
|
this.clusteredLights = [];
|
|
47
|
-
this._allLights = [];
|
|
48
47
|
|
|
49
48
|
this.maxLights = maxLights;
|
|
50
49
|
this.tileSize = tileSize;
|
|
@@ -57,9 +56,15 @@ class ClusteredLightsNode extends LightsNode {
|
|
|
57
56
|
this._lightIndexes = null;
|
|
58
57
|
this._screenClusterIndex = null;
|
|
59
58
|
this._compute = null;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.
|
|
59
|
+
|
|
60
|
+
const lightsData = new Float32Array( maxLights * 4 * 2 );
|
|
61
|
+
this._lightsTexture = new DataTexture( lightsData, lightsData.length / 8, 2, RGBAFormat, FloatType );
|
|
62
|
+
|
|
63
|
+
// Per Z-slice light range for Z-culling (CPU-sorted, uploaded each frame)
|
|
64
|
+
|
|
65
|
+
this._zSliceRangesData = new Float32Array( zSlices * 4 );
|
|
66
|
+
this._zSliceRangesTexture = new DataTexture( this._zSliceRangesData, zSlices, 1, RGBAFormat, FloatType );
|
|
67
|
+
|
|
63
68
|
this._lightViewZ = new Float32Array( maxLights );
|
|
64
69
|
this._lightSortOrder = [];
|
|
65
70
|
|
|
@@ -139,8 +144,6 @@ class ClusteredLightsNode extends LightsNode {
|
|
|
139
144
|
|
|
140
145
|
const zRanges = this._zSliceRangesData;
|
|
141
146
|
|
|
142
|
-
if ( zRanges === null ) return;
|
|
143
|
-
|
|
144
147
|
const near = camera.near;
|
|
145
148
|
const far = camera.far;
|
|
146
149
|
const NZ = this.zSlices;
|
|
@@ -206,8 +209,6 @@ class ClusteredLightsNode extends LightsNode {
|
|
|
206
209
|
|
|
207
210
|
setLights( lights ) {
|
|
208
211
|
|
|
209
|
-
this._allLights = lights;
|
|
210
|
-
|
|
211
212
|
const { clusteredLights, materialLights } = this;
|
|
212
213
|
|
|
213
214
|
let materialIndex = 0;
|
|
@@ -230,13 +231,13 @@ class ClusteredLightsNode extends LightsNode {
|
|
|
230
231
|
materialLights.length = materialIndex;
|
|
231
232
|
clusteredLights.length = clusteredIndex;
|
|
232
233
|
|
|
233
|
-
return super.setLights(
|
|
234
|
+
return super.setLights( lights );
|
|
234
235
|
|
|
235
236
|
}
|
|
236
237
|
|
|
237
|
-
|
|
238
|
+
getBuiltinLights() {
|
|
238
239
|
|
|
239
|
-
return this.
|
|
240
|
+
return this.materialLights;
|
|
240
241
|
|
|
241
242
|
}
|
|
242
243
|
|
|
@@ -421,7 +422,7 @@ class ClusteredLightsNode extends LightsNode {
|
|
|
421
422
|
|
|
422
423
|
create( width, height ) {
|
|
423
424
|
|
|
424
|
-
const { tileSize,
|
|
425
|
+
const { tileSize, zSlices, maxLightsPerCluster, _chunksPerCluster: chunksPerCluster } = this;
|
|
425
426
|
|
|
426
427
|
const bufferSize = new Vector2( width, height );
|
|
427
428
|
|
|
@@ -432,20 +433,25 @@ class ClusteredLightsNode extends LightsNode {
|
|
|
432
433
|
|
|
433
434
|
this._gridDimensions.value.set( NX, NY );
|
|
434
435
|
|
|
435
|
-
//
|
|
436
|
+
// release the compute pipeline and bindings built for the previous grid
|
|
436
437
|
|
|
437
|
-
|
|
438
|
-
const lightsTexture = new DataTexture( lightsData, lightsData.length / 8, 2, RGBAFormat, FloatType );
|
|
438
|
+
if ( this._compute !== null ) this._compute.dispose();
|
|
439
439
|
|
|
440
|
-
// Per
|
|
440
|
+
// Per-cluster light-index storage (ivec4 chunks).
|
|
441
|
+
|
|
442
|
+
const lightIndexesLength = clusterCount * chunksPerCluster * 4;
|
|
443
|
+
|
|
444
|
+
let lightIndexes = this._lightIndexes;
|
|
441
445
|
|
|
442
|
-
|
|
443
|
-
const zSliceRangesTexture = new DataTexture( zSliceRangesData, NZ, 1, RGBAFormat, FloatType );
|
|
446
|
+
if ( lightIndexes === null || lightIndexes.value.array.length < lightIndexesLength ) {
|
|
444
447
|
|
|
445
|
-
|
|
448
|
+
// TODO: Free the outgoing buffer once the renderer destroys the GPU resources of
|
|
449
|
+
// standalone storage attributes (`Bindings._destroyBindings()` skips storage buffers).
|
|
446
450
|
|
|
447
|
-
|
|
448
|
-
|
|
451
|
+
const lightIndexesArray = new Int32Array( lightIndexesLength );
|
|
452
|
+
lightIndexes = attributeArray( lightIndexesArray, 'ivec4' ).setName( 'lightIndexes' );
|
|
453
|
+
|
|
454
|
+
}
|
|
449
455
|
|
|
450
456
|
// compute-side accessors (use instanceIndex)
|
|
451
457
|
|
|
@@ -531,7 +537,7 @@ class ClusteredLightsNode extends LightsNode {
|
|
|
531
537
|
const index = int( 0 ).toVar();
|
|
532
538
|
|
|
533
539
|
// Z-culling: only test lights that can reach this cluster's Z-slice
|
|
534
|
-
const zRange = textureLoad(
|
|
540
|
+
const zRange = textureLoad( this._zSliceRangesTexture, ivec2( cz, 0 ) );
|
|
535
541
|
const rangeStart = int( zRange.x );
|
|
536
542
|
const rangeEnd = int( zRange.y );
|
|
537
543
|
|
|
@@ -592,15 +598,20 @@ class ClusteredLightsNode extends LightsNode {
|
|
|
592
598
|
this._lightIndexes = lightIndexes;
|
|
593
599
|
this._screenClusterIndex = screenClusterIndex;
|
|
594
600
|
this._compute = compute;
|
|
595
|
-
this._lightsTexture = lightsTexture;
|
|
596
|
-
this._zSliceRangesTexture = zSliceRangesTexture;
|
|
597
|
-
this._zSliceRangesData = zSliceRangesData;
|
|
598
601
|
|
|
599
602
|
}
|
|
600
603
|
|
|
601
|
-
|
|
604
|
+
/**
|
|
605
|
+
* Frees the GPU resources allocated by this node.
|
|
606
|
+
*/
|
|
607
|
+
dispose() {
|
|
608
|
+
|
|
609
|
+
if ( this._compute !== null ) this._compute.dispose();
|
|
610
|
+
|
|
611
|
+
this._lightsTexture.dispose();
|
|
612
|
+
this._zSliceRangesTexture.dispose();
|
|
602
613
|
|
|
603
|
-
|
|
614
|
+
super.dispose();
|
|
604
615
|
|
|
605
616
|
}
|
|
606
617
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { AnalyticLightNode, Vector3 } from '@gnsx/three/webgpu';
|
|
2
|
+
import { array, getShIrradianceAt, normalWorld, positionWorld, texture3D, uniform, vec3 } from '@gnsx/three/tsl';
|
|
3
|
+
|
|
4
|
+
// Padding texels at each boundary of every atlas sub-volume.
|
|
5
|
+
export const ATLAS_PADDING = 1;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Samples the packed SH atlas and evaluates L2 irradiance for the given normal.
|
|
9
|
+
*
|
|
10
|
+
* The atlas stores the seven RGBA sub-volumes stacked along Z, each occupying
|
|
11
|
+
* `( nz + 2 )` slices: one padding slice (a copy of the nearest edge slice) at
|
|
12
|
+
* each end to prevent color bleeding when the hardware trilinear filter reads
|
|
13
|
+
* across a sub-volume boundary.
|
|
14
|
+
*
|
|
15
|
+
* @private
|
|
16
|
+
* @param {Texture3DNode} atlas - The atlas texture node.
|
|
17
|
+
* @param {Node<vec3>} uvw - The probe-grid sample coordinate (texel centers).
|
|
18
|
+
* @param {Node<vec3>} res - The probe resolution.
|
|
19
|
+
* @param {Node<vec3>} normal - The world-space normal.
|
|
20
|
+
* @return {Node<vec3>} The non-negative irradiance.
|
|
21
|
+
*/
|
|
22
|
+
function evaluateGridIrradiance( atlas, uvw, res, normal ) {
|
|
23
|
+
|
|
24
|
+
const nz = res.z;
|
|
25
|
+
const paddedSlices = nz.add( 2.0 * ATLAS_PADDING );
|
|
26
|
+
const atlasDepth = paddedSlices.mul( 7.0 );
|
|
27
|
+
const uvZBase = uvw.z.mul( nz ).add( ATLAS_PADDING );
|
|
28
|
+
|
|
29
|
+
const slice = ( t ) => atlas.sample( vec3( uvw.xy, uvZBase.add( paddedSlices.mul( t ) ).div( atlasDepth ) ) );
|
|
30
|
+
|
|
31
|
+
const s0 = slice( 0 ), s1 = slice( 1 ), s2 = slice( 2 ), s3 = slice( 3 );
|
|
32
|
+
const s4 = slice( 4 ), s5 = slice( 5 ), s6 = slice( 6 );
|
|
33
|
+
|
|
34
|
+
// Unpack 9 vec3 L2 SH coefficients and evaluate irradiance.
|
|
35
|
+
|
|
36
|
+
const sh = array( [
|
|
37
|
+
s0.xyz,
|
|
38
|
+
vec3( s0.w, s1.xy ),
|
|
39
|
+
vec3( s1.zw, s2.x ),
|
|
40
|
+
s2.yzw,
|
|
41
|
+
s3.xyz,
|
|
42
|
+
vec3( s3.w, s4.xy ),
|
|
43
|
+
vec3( s4.zw, s5.x ),
|
|
44
|
+
s5.yzw,
|
|
45
|
+
s6.xyz
|
|
46
|
+
] );
|
|
47
|
+
|
|
48
|
+
return getShIrradianceAt( normal, sh ).max( vec3( 0.0 ) );
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The light node that applies a {@link LightProbeGrid} to the scene. It samples
|
|
54
|
+
* the baked L2 spherical-harmonic atlas at the surface position and adds the
|
|
55
|
+
* resulting irradiance to the lighting context, so every standard node material
|
|
56
|
+
* picks up the grid automatically (same role as the WebGL `lights_fragment_begin`
|
|
57
|
+
* integration).
|
|
58
|
+
*
|
|
59
|
+
* @private
|
|
60
|
+
* @augments AnalyticLightNode
|
|
61
|
+
*/
|
|
62
|
+
class LightProbeGridNode extends AnalyticLightNode {
|
|
63
|
+
|
|
64
|
+
static get type() {
|
|
65
|
+
|
|
66
|
+
return 'LightProbeGridNode';
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
constructor( light = null ) {
|
|
71
|
+
|
|
72
|
+
super( light );
|
|
73
|
+
|
|
74
|
+
this._min = uniform( new Vector3() );
|
|
75
|
+
this._max = uniform( new Vector3() );
|
|
76
|
+
this._resolution = uniform( new Vector3() );
|
|
77
|
+
this._intensity = uniform( 1 );
|
|
78
|
+
this._falloff = uniform( 0 );
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
update( /* frame */ ) {
|
|
83
|
+
|
|
84
|
+
const light = this.light;
|
|
85
|
+
|
|
86
|
+
this._min.value.copy( light.boundingBox.min );
|
|
87
|
+
this._max.value.copy( light.boundingBox.max );
|
|
88
|
+
this._resolution.value.copy( light.resolution );
|
|
89
|
+
this._intensity.value = light.intensity;
|
|
90
|
+
this._falloff.value = light.falloff;
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
setup( builder ) {
|
|
95
|
+
|
|
96
|
+
const light = this.light;
|
|
97
|
+
|
|
98
|
+
// No baked data yet: contribute nothing.
|
|
99
|
+
|
|
100
|
+
if ( light.texture === null ) return;
|
|
101
|
+
|
|
102
|
+
const min = this._min;
|
|
103
|
+
const max = this._max;
|
|
104
|
+
const res = this._resolution;
|
|
105
|
+
|
|
106
|
+
const range = max.sub( min );
|
|
107
|
+
const resMinusOne = res.sub( 1.0 );
|
|
108
|
+
const spacing = range.div( resMinusOne );
|
|
109
|
+
|
|
110
|
+
// Offset along the normal by half a probe spacing, then remap to texel centers.
|
|
111
|
+
|
|
112
|
+
const samplePos = positionWorld.add( normalWorld.mul( spacing ).mul( 0.5 ) );
|
|
113
|
+
const uvw = samplePos.sub( min ).div( range ).clamp( 0.0, 1.0 ).mul( resMinusOne ).div( res ).add( vec3( 0.5 ).div( res ) );
|
|
114
|
+
|
|
115
|
+
const result = evaluateGridIrradiance( texture3D( light.texture ), uvw, res, normalWorld );
|
|
116
|
+
|
|
117
|
+
let irradiance = result.mul( this._intensity );
|
|
118
|
+
|
|
119
|
+
// Optional smooth boundary for blending grids; falloff 0 applies everywhere.
|
|
120
|
+
|
|
121
|
+
if ( light.falloff > 0 ) {
|
|
122
|
+
|
|
123
|
+
const outside = min.sub( positionWorld ).max( 0.0 ).add( positionWorld.sub( max ).max( 0.0 ) );
|
|
124
|
+
const weight = outside.length().smoothstep( 0.0, this._falloff ).oneMinus();
|
|
125
|
+
|
|
126
|
+
irradiance = irradiance.mul( weight );
|
|
127
|
+
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
builder.context.irradiance.addAssign( irradiance );
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { LightProbeGridNode };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Fn, Loop, dot, float, fract, int, min, sin, vec2, vec3, TWO_PI } from '@gnsx/three/tsl';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module VoronoiNoise
|
|
5
|
+
* @three_import import { voronoi2d, voronoi3d } from 'three/addons/tsl/math/voronoiNoise.js';
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generates a pseudo-random vec2 from the given coordinate.
|
|
10
|
+
*
|
|
11
|
+
* Reference: {@link https://www.shadertoy.com/view/MslGD8}.
|
|
12
|
+
*
|
|
13
|
+
* @tsl
|
|
14
|
+
* @function
|
|
15
|
+
* @param {Node<vec2>} p - The input coordinate.
|
|
16
|
+
* @return {Node<vec2>} A pseudo-random value in the range `[0, 1]`.
|
|
17
|
+
*/
|
|
18
|
+
export const hash2d = /*@__PURE__*/ Fn( ( [ p ] ) => {
|
|
19
|
+
|
|
20
|
+
return fract( sin( vec2( dot( p, vec2( 127.1, 311.7 ) ), dot( p, vec2( 269.5, 183.3 ) ) ) ).mul( 18.5453 ) );
|
|
21
|
+
|
|
22
|
+
}, { p: 'vec2', return: 'vec2' } );
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Animated 2D Voronoi noise. The feature points orbit inside their cells so the
|
|
26
|
+
* resulting pattern morphs over time.
|
|
27
|
+
*
|
|
28
|
+
* Reference: {@link https://www.shadertoy.com/view/MslGD8}.
|
|
29
|
+
*
|
|
30
|
+
* @tsl
|
|
31
|
+
* @function
|
|
32
|
+
* @param {Node<vec2>} p - The input coordinate.
|
|
33
|
+
* @param {Node<float>} time - The animation time.
|
|
34
|
+
* @return {Node<float>} The squared distance to the closest feature point, roughly in the range `[0, 1]`.
|
|
35
|
+
*/
|
|
36
|
+
export const voronoi2d = /*@__PURE__*/ Fn( ( [ p, time ] ) => {
|
|
37
|
+
|
|
38
|
+
const n = p.floor().toConst();
|
|
39
|
+
const f = p.fract().toConst();
|
|
40
|
+
const minDist = float( 8 ).toVar();
|
|
41
|
+
|
|
42
|
+
Loop( { start: int( - 1 ), end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => {
|
|
43
|
+
|
|
44
|
+
Loop( { start: int( - 1 ), end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => {
|
|
45
|
+
|
|
46
|
+
const g = vec2( float( x ), float( y ) ).toConst();
|
|
47
|
+
const o = hash2d( n.add( g ) ).toConst();
|
|
48
|
+
const r = g.sub( f ).add( sin( time.add( o.mul( TWO_PI ) ) ).mul( 0.5 ).add( 0.5 ) );
|
|
49
|
+
|
|
50
|
+
minDist.assign( min( minDist, dot( r, r ) ) );
|
|
51
|
+
|
|
52
|
+
} );
|
|
53
|
+
|
|
54
|
+
} );
|
|
55
|
+
|
|
56
|
+
return minDist;
|
|
57
|
+
|
|
58
|
+
}, { p: 'vec2', time: 'float', return: 'float' } );
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Generates a pseudo-random vec3 from the given coordinate.
|
|
62
|
+
*
|
|
63
|
+
* @tsl
|
|
64
|
+
* @function
|
|
65
|
+
* @param {Node<vec3>} p - The input coordinate.
|
|
66
|
+
* @return {Node<vec3>} A pseudo-random value in the range `[0, 1]`.
|
|
67
|
+
*/
|
|
68
|
+
export const hash3d = /*@__PURE__*/ Fn( ( [ p ] ) => {
|
|
69
|
+
|
|
70
|
+
return fract( sin( vec3( dot( p, vec3( 127.1, 311.7, 74.7 ) ), dot( p, vec3( 269.5, 183.3, 246.1 ) ), dot( p, vec3( 113.5, 271.9, 124.6 ) ) ) ).mul( 18.5453 ) );
|
|
71
|
+
|
|
72
|
+
}, { p: 'vec3', return: 'vec3' } );
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Animated 3D Voronoi noise. Like {@link voronoi2d} but with a volumetric input
|
|
76
|
+
* coordinate so the pattern can be applied to arbitrary surfaces without
|
|
77
|
+
* projection artifacts. Evaluates 27 cells instead of 9 and is therefore
|
|
78
|
+
* considerably more expensive than the 2D version.
|
|
79
|
+
*
|
|
80
|
+
* @tsl
|
|
81
|
+
* @function
|
|
82
|
+
* @param {Node<vec3>} p - The input coordinate.
|
|
83
|
+
* @param {Node<float>} time - The animation time.
|
|
84
|
+
* @return {Node<float>} The squared distance to the closest feature point, roughly in the range `[0, 1]`.
|
|
85
|
+
*/
|
|
86
|
+
export const voronoi3d = /*@__PURE__*/ Fn( ( [ p, time ] ) => {
|
|
87
|
+
|
|
88
|
+
const n = p.floor().toConst();
|
|
89
|
+
const f = p.fract().toConst();
|
|
90
|
+
const minDist = float( 8 ).toVar();
|
|
91
|
+
|
|
92
|
+
Loop( { start: int( - 1 ), end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => {
|
|
93
|
+
|
|
94
|
+
Loop( { start: int( - 1 ), end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => {
|
|
95
|
+
|
|
96
|
+
Loop( { start: int( - 1 ), end: int( 1 ), name: 'z', condition: '<=' }, ( { z } ) => {
|
|
97
|
+
|
|
98
|
+
const g = vec3( float( x ), float( y ), float( z ) ).toConst();
|
|
99
|
+
const o = hash3d( n.add( g ) ).toConst();
|
|
100
|
+
const r = g.sub( f ).add( sin( time.add( o.mul( TWO_PI ) ) ).mul( 0.5 ).add( 0.5 ) );
|
|
101
|
+
|
|
102
|
+
minDist.assign( min( minDist, dot( r, r ) ) );
|
|
103
|
+
|
|
104
|
+
} );
|
|
105
|
+
|
|
106
|
+
} );
|
|
107
|
+
|
|
108
|
+
} );
|
|
109
|
+
|
|
110
|
+
return minDist;
|
|
111
|
+
|
|
112
|
+
}, { p: 'vec3', time: 'float', return: 'float' } );
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
Quaternion
|
|
15
15
|
} from '@gnsx/three/webgpu';
|
|
16
16
|
|
|
17
|
-
import { min, Fn, shadow, NodeUpdateType
|
|
17
|
+
import { min, Fn, shadow, NodeUpdateType } from '@gnsx/three/tsl';
|
|
18
18
|
|
|
19
19
|
const { resetRendererAndSceneState, restoreRendererAndSceneState } = RendererUtils;
|
|
20
20
|
let _rendererState;
|
|
@@ -273,14 +273,11 @@ class TileShadowNode extends ShadowBaseNode {
|
|
|
273
273
|
const depthVersion = shadowMap.depthTexture.version;
|
|
274
274
|
this._depthVersionCached = depthVersion;
|
|
275
275
|
const currentRenderObjectFunction = renderer.getRenderObjectFunction();
|
|
276
|
-
const currentMRT = renderer.getMRT();
|
|
277
|
-
const useVelocity = currentMRT ? currentMRT.has( 'velocity' ) : false;
|
|
278
276
|
|
|
279
277
|
_rendererState = resetRendererAndSceneState( renderer, scene, _rendererState );
|
|
280
|
-
scene.overrideMaterial = getShadowMaterial(
|
|
278
|
+
scene.overrideMaterial = this.getShadowMaterial();
|
|
281
279
|
renderer.setRenderTarget( this.shadowMap );
|
|
282
280
|
|
|
283
|
-
|
|
284
281
|
for ( let index = 0; index < this.lights.length; index ++ ) {
|
|
285
282
|
|
|
286
283
|
const light = this.lights[ index ];
|
|
@@ -297,7 +294,7 @@ class TileShadowNode extends ShadowBaseNode {
|
|
|
297
294
|
|
|
298
295
|
shadow.updateMatrices( light );
|
|
299
296
|
|
|
300
|
-
renderer.setRenderObjectFunction( getShadowRenderObjectFunction( renderer, shadow
|
|
297
|
+
renderer.setRenderObjectFunction( this.getShadowRenderObjectFunction( renderer, shadow ) );
|
|
301
298
|
this.shadowMap.setSize( shadow.mapSize.width, shadow.mapSize.height, shadowMap.depth );
|
|
302
299
|
|
|
303
300
|
}
|
|
@@ -447,6 +444,7 @@ class TileShadowNode extends ShadowBaseNode {
|
|
|
447
444
|
|
|
448
445
|
// Dispose lights, nodes, and shadow map
|
|
449
446
|
this.disposeLightsAndNodes();
|
|
447
|
+
this.disposeShadowMaterial();
|
|
450
448
|
super.dispose();
|
|
451
449
|
|
|
452
450
|
}
|
|
@@ -53,17 +53,17 @@ export const RaymarchingBox = ( steps, callback ) => {
|
|
|
53
53
|
bounds.assign( vec2( max( bounds.x, 0.0 ), bounds.y ) );
|
|
54
54
|
|
|
55
55
|
const inc = vec3( rayDir.abs().reciprocal() ).toVar();
|
|
56
|
-
const
|
|
56
|
+
const stepSize = float( min( inc.x, min( inc.y, inc.z ) ) ).toVar();
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
stepSize.divAssign( float( steps ) );
|
|
59
59
|
|
|
60
60
|
const positionRay = vec3( vOrigin.add( bounds.x.mul( rayDir ) ) ).toVar();
|
|
61
61
|
|
|
62
|
-
Loop( { type: 'float', start: bounds.x, end: bounds.y, update:
|
|
62
|
+
Loop( { type: 'float', start: bounds.x, end: bounds.y, update: stepSize }, () => {
|
|
63
63
|
|
|
64
|
-
callback( { positionRay } );
|
|
64
|
+
callback( { positionRay, stepSize } );
|
|
65
65
|
|
|
66
|
-
positionRay.addAssign( rayDir.mul(
|
|
66
|
+
positionRay.addAssign( rayDir.mul( stepSize ) );
|
|
67
67
|
|
|
68
68
|
} );
|
|
69
69
|
|