@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,5 +1,5 @@
|
|
|
1
1
|
import { TempNode } from '@gnsx/three/webgpu';
|
|
2
|
-
import { Fn, uv,
|
|
2
|
+
import { nodeObject, Fn, uv, vec2, sin, cos, vec4, convertToTexture } from '@gnsx/three/tsl';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Post processing node for shifting/splitting RGB color channels. The effect
|
|
@@ -20,8 +20,8 @@ class RGBShiftNode extends TempNode {
|
|
|
20
20
|
* Constructs a new RGB shift node.
|
|
21
21
|
*
|
|
22
22
|
* @param {TextureNode} textureNode - The texture node that represents the input of the effect.
|
|
23
|
-
* @param {number} [amount=0.005] - The amount of the RGB shift.
|
|
24
|
-
* @param {number} [angle=0] - Defines the orientation in which colors are shifted.
|
|
23
|
+
* @param {number|Node<float>} [amount=0.005] - The amount of the RGB shift.
|
|
24
|
+
* @param {number|Node<float>} [angle=0] - Defines the orientation in which colors are shifted.
|
|
25
25
|
*/
|
|
26
26
|
constructor( textureNode, amount = 0.005, angle = 0 ) {
|
|
27
27
|
|
|
@@ -37,16 +37,16 @@ class RGBShiftNode extends TempNode {
|
|
|
37
37
|
/**
|
|
38
38
|
* The amount of the RGB shift.
|
|
39
39
|
*
|
|
40
|
-
* @type {
|
|
40
|
+
* @type {Node<float>}
|
|
41
41
|
*/
|
|
42
|
-
this.amount =
|
|
42
|
+
this.amount = nodeObject( amount );
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Defines in which direction colors are shifted.
|
|
46
46
|
*
|
|
47
|
-
* @type {
|
|
47
|
+
* @type {Node<float>}
|
|
48
48
|
*/
|
|
49
|
-
this.angle =
|
|
49
|
+
this.angle = nodeObject( angle );
|
|
50
50
|
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -89,8 +89,8 @@ export default RGBShiftNode;
|
|
|
89
89
|
* @tsl
|
|
90
90
|
* @function
|
|
91
91
|
* @param {Node<vec4>} node - The node that represents the input of the effect.
|
|
92
|
-
* @param {number} [amount=0.005] - The amount of the RGB shift.
|
|
93
|
-
* @param {number} [angle=0] - Defines in which direction colors are shifted.
|
|
92
|
+
* @param {number|Node<float>} [amount=0.005] - The amount of the RGB shift.
|
|
93
|
+
* @param {number|Node<float>} [angle=0] - Defines in which direction colors are shifted.
|
|
94
94
|
* @returns {RGBShiftNode}
|
|
95
95
|
*/
|
|
96
96
|
export const rgbShift = ( node, amount, angle ) => new RGBShiftNode( convertToTexture( node ), amount, angle );
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { abs, atan, bool, convertToTexture, cos, cross, Discard, dot, EPSILON, exp, float, Fn, getScreenPosition, getViewPosition, If, int, log, Loop, luminance, mat2, max, mix, nodeObject, NodeUpdateType, normalize, passTexture, PI, property, reflect, sin, smoothstep, sqrt, tan, texture, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4 } from '@gnsx/three/tsl';
|
|
1
|
+
import { abs, atan, bool, convertToTexture, cos, cross, Discard, dot, EPSILON, exp, float, Fn, getScreenPosition, getViewPosition, If, int, log, Loop, luminance, mat2, max, mix, nodeObject, NodeUpdateType, normalize, passTexture, PI, property, reflect, sin, smoothstep, sqrt, tan, texture, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4, context } from '@gnsx/three/tsl';
|
|
2
2
|
import { HalfFloatType, MathUtils, Matrix4, NodeMaterial, QuadMesh, RendererUtils, RenderTarget, TempNode, Vector2 } from '@gnsx/three/webgpu';
|
|
3
3
|
import { bindAnalyticNoise } from '../utils/RNoise.js';
|
|
4
4
|
import { ENV_RAY_LENGTH_THRESHOLD } from '../utils/SpecularHelpers.js';
|
|
@@ -606,7 +606,7 @@ class RecurrentDenoiseNode extends TempNode {
|
|
|
606
606
|
const runDenoise = () => {
|
|
607
607
|
|
|
608
608
|
const viewNormal = sampleNormal( uvCoord ).toConst();
|
|
609
|
-
const worldNormal = viewNormal.
|
|
609
|
+
const worldNormal = viewNormal.transformNormalByInverseViewMatrix( this._viewMatrix ).toConst();
|
|
610
610
|
const texel = sampleTexture( uvCoord ).max( 0 ).toConst();
|
|
611
611
|
|
|
612
612
|
const viewPosition = getViewPosition( uvCoord, depth, this._cameraProjectionMatrixInverse ).toConst();
|
|
@@ -796,7 +796,7 @@ class RecurrentDenoiseNode extends TempNode {
|
|
|
796
796
|
if ( this.mode === 'specular' ) kernelDiff.addAssign( ( abs( roughness.sub( sampleRoughnessMetalness( sampleUv ).g ) ).mul( this.roughnessPhi ) ) );
|
|
797
797
|
|
|
798
798
|
const nViewNormal = sampleNormal( sampleUv );
|
|
799
|
-
const nWorldNormal = nViewNormal.
|
|
799
|
+
const nWorldNormal = nViewNormal.transformNormalByInverseViewMatrix( this._viewMatrix );
|
|
800
800
|
const distToPlane = planeDistance( viewPosition, nViewPosition, viewNormal );
|
|
801
801
|
|
|
802
802
|
// Geometric edge stopping (depth and normal)
|
|
@@ -880,7 +880,8 @@ class RecurrentDenoiseNode extends TempNode {
|
|
|
880
880
|
|
|
881
881
|
} );
|
|
882
882
|
|
|
883
|
-
this._material.
|
|
883
|
+
this._material.contextNode = context( builder.getSharedContext() );
|
|
884
|
+
this._material.fragmentNode = denoiseFn( uv() );
|
|
884
885
|
this._material.needsUpdate = true;
|
|
885
886
|
|
|
886
887
|
return this._textureNode;
|
|
@@ -889,6 +890,8 @@ class RecurrentDenoiseNode extends TempNode {
|
|
|
889
890
|
|
|
890
891
|
dispose() {
|
|
891
892
|
|
|
893
|
+
super.dispose();
|
|
894
|
+
|
|
892
895
|
this._renderTarget.dispose();
|
|
893
896
|
this._material.dispose();
|
|
894
897
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HalfFloatType, LinearFilter, NearestFilter, RenderTarget, Texture, Vector2, QuadMesh, NodeMaterial, TempNode, RendererUtils } from '@gnsx/three/webgpu';
|
|
2
|
-
import { abs, Fn, NodeUpdateType, uv, uniform, convertToTexture,
|
|
2
|
+
import { abs, Fn, NodeUpdateType, uv, uniform, convertToTexture, vec2, vec4, passTexture, max, step, dot, float, texture, If, Loop, int, Break, sqrt, sign, mix, context } from '@gnsx/three/tsl';
|
|
3
3
|
|
|
4
4
|
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
5
5
|
const _size = /*@__PURE__*/ new Vector2();
|
|
@@ -292,25 +292,11 @@ class SMAANode extends TempNode {
|
|
|
292
292
|
|
|
293
293
|
// edges
|
|
294
294
|
|
|
295
|
-
const
|
|
295
|
+
const SMAAEdgeDetection = Fn( () => {
|
|
296
296
|
|
|
297
|
-
const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 1.0, 0.0, 0.0, - 1.0 ) ) );
|
|
298
|
-
const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( 1.0, 0.0, 0.0, 1.0 ) ) );
|
|
299
|
-
const vOffset2 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 2.0, 0.0, 0.0, - 2.0 ) ) );
|
|
300
|
-
|
|
301
|
-
varyingProperty( 'vec4', 'vOffset0' ).assign( vOffset0 );
|
|
302
|
-
varyingProperty( 'vec4', 'vOffset1' ).assign( vOffset1 );
|
|
303
|
-
varyingProperty( 'vec4', 'vOffset2' ).assign( vOffset2 );
|
|
304
|
-
|
|
305
|
-
return modelViewProjection;
|
|
306
|
-
|
|
307
|
-
} );
|
|
308
|
-
|
|
309
|
-
const SMAAEdgeDetectionFS = Fn( () => {
|
|
310
|
-
|
|
311
|
-
const vOffset0 = varyingProperty( 'vec4', 'vOffset0' );
|
|
312
|
-
const vOffset1 = varyingProperty( 'vec4', 'vOffset1' );
|
|
313
|
-
const vOffset2 = varyingProperty( 'vec4', 'vOffset2' );
|
|
297
|
+
const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 1.0, 0.0, 0.0, - 1.0 ) ) ).toVertexStage();
|
|
298
|
+
const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( 1.0, 0.0, 0.0, 1.0 ) ) ).toVertexStage();
|
|
299
|
+
const vOffset2 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 2.0, 0.0, 0.0, - 2.0 ) ) ).toVertexStage();
|
|
314
300
|
|
|
315
301
|
const threshold = vec2( SMAA_THRESHOLD, SMAA_THRESHOLD );
|
|
316
302
|
|
|
@@ -513,32 +499,16 @@ class SMAANode extends TempNode {
|
|
|
513
499
|
|
|
514
500
|
} );
|
|
515
501
|
|
|
516
|
-
const
|
|
502
|
+
const SMAAWeights = Fn( () => {
|
|
517
503
|
|
|
518
|
-
const vPixcoord = uvNode.xy.div( this._invSize );
|
|
504
|
+
const vPixcoord = uvNode.xy.div( this._invSize ).toVertexStage();
|
|
519
505
|
|
|
520
506
|
// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
|
|
521
|
-
const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 0.25, - 0.125, 1.25, - 0.125 ) ) ).
|
|
522
|
-
const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 0.125, - 0.25, - 0.125, 1.25 ) ) ).
|
|
507
|
+
const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 0.25, - 0.125, 1.25, - 0.125 ) ) ).toVertexStage();
|
|
508
|
+
const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 0.125, - 0.25, - 0.125, 1.25 ) ) ).toVertexStage();
|
|
523
509
|
|
|
524
510
|
// And these for the searches, they indicate the ends of the loops:
|
|
525
|
-
const vOffset2 = vec4( vOffset0.xz, vOffset1.yw ).add( vec4( - 2.0, 2.0, - 2.0, 2.0 ).mul( vec4( this._invSize.xx, this._invSize.yy ) ).mul( float( SMAA_MAX_SEARCH_STEPS ) ) ).
|
|
526
|
-
|
|
527
|
-
varyingProperty( 'vec2', 'vPixcoord' ).assign( vPixcoord );
|
|
528
|
-
varyingProperty( 'vec4', 'vOffset0' ).assign( vOffset0 );
|
|
529
|
-
varyingProperty( 'vec4', 'vOffset1' ).assign( vOffset1 );
|
|
530
|
-
varyingProperty( 'vec4', 'vOffset2' ).assign( vOffset2 );
|
|
531
|
-
|
|
532
|
-
return modelViewProjection;
|
|
533
|
-
|
|
534
|
-
} );
|
|
535
|
-
|
|
536
|
-
const SMAAWeightsFS = Fn( () => {
|
|
537
|
-
|
|
538
|
-
const vPixcoord = varyingProperty( 'vec2', 'vPixcoord' );
|
|
539
|
-
const vOffset0 = varyingProperty( 'vec4', 'vOffset0' );
|
|
540
|
-
const vOffset1 = varyingProperty( 'vec4', 'vOffset1' );
|
|
541
|
-
const vOffset2 = varyingProperty( 'vec4', 'vOffset2' );
|
|
511
|
+
const vOffset2 = vec4( vOffset0.xz, vOffset1.yw ).add( vec4( - 2.0, 2.0, - 2.0, 2.0 ).mul( vec4( this._invSize.xx, this._invSize.yy ) ).mul( float( SMAA_MAX_SEARCH_STEPS ) ) ).toVertexStage();
|
|
542
512
|
|
|
543
513
|
const weights = vec4( 0.0, 0.0, 0.0, 0.0 ).toVar();
|
|
544
514
|
const subsampleIndices = vec4( 0.0, 0.0, 0.0, 0.0 ).toVar();
|
|
@@ -623,22 +593,9 @@ class SMAANode extends TempNode {
|
|
|
623
593
|
|
|
624
594
|
// blend
|
|
625
595
|
|
|
626
|
-
const
|
|
627
|
-
|
|
628
|
-
//const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 1.0, 0.0, 0.0, - 1.0 ) ) );
|
|
629
|
-
const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( 1.0, 0.0, 0.0, 1.0 ) ) );
|
|
630
|
-
|
|
631
|
-
//varyingProperty( 'vec4', 'vOffset0' ).assign( vOffset0 );
|
|
632
|
-
varyingProperty( 'vec4', 'vOffset1' ).assign( vOffset1 );
|
|
633
|
-
|
|
634
|
-
return modelViewProjection;
|
|
596
|
+
const SMAABlend = Fn( () => {
|
|
635
597
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
const SMAABlendFS = Fn( () => {
|
|
639
|
-
|
|
640
|
-
//const vOffset0 = varyingProperty( 'vec4', 'vOffset0' );
|
|
641
|
-
const vOffset1 = varyingProperty( 'vec4', 'vOffset1' );
|
|
598
|
+
const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( 1.0, 0.0, 0.0, 1.0 ) ) ).toVertexStage();
|
|
642
599
|
const result = vec4().toVar();
|
|
643
600
|
|
|
644
601
|
// Fetch the blending weights for current pixel:
|
|
@@ -694,16 +651,18 @@ class SMAANode extends TempNode {
|
|
|
694
651
|
|
|
695
652
|
} );
|
|
696
653
|
|
|
697
|
-
|
|
698
|
-
|
|
654
|
+
const sharedContext = context( builder.getSharedContext() );
|
|
655
|
+
|
|
656
|
+
this._materialEdges.contextNode = sharedContext;
|
|
657
|
+
this._materialEdges.fragmentNode = SMAAEdgeDetection();
|
|
699
658
|
this._materialEdges.needsUpdate = true;
|
|
700
659
|
|
|
701
|
-
this._materialWeights.
|
|
702
|
-
this._materialWeights.fragmentNode =
|
|
660
|
+
this._materialWeights.contextNode = sharedContext;
|
|
661
|
+
this._materialWeights.fragmentNode = SMAAWeights();
|
|
703
662
|
this._materialWeights.needsUpdate = true;
|
|
704
663
|
|
|
705
|
-
this._materialBlend.
|
|
706
|
-
this._materialBlend.fragmentNode =
|
|
664
|
+
this._materialBlend.contextNode = sharedContext;
|
|
665
|
+
this._materialBlend.fragmentNode = SMAABlend();
|
|
707
666
|
this._materialBlend.needsUpdate = true;
|
|
708
667
|
|
|
709
668
|
return this._textureNode;
|
|
@@ -716,6 +675,8 @@ class SMAANode extends TempNode {
|
|
|
716
675
|
*/
|
|
717
676
|
dispose() {
|
|
718
677
|
|
|
678
|
+
super.dispose();
|
|
679
|
+
|
|
719
680
|
this._renderTargetEdges.dispose();
|
|
720
681
|
this._renderTargetWeights.dispose();
|
|
721
682
|
this._renderTargetBlend.dispose();
|
|
@@ -32,7 +32,7 @@ class SSAAPassNode extends PassNode {
|
|
|
32
32
|
*/
|
|
33
33
|
constructor( scene, camera ) {
|
|
34
34
|
|
|
35
|
-
super( PassNode.COLOR, scene, camera );
|
|
35
|
+
super( PassNode.COLOR, scene, camera, { samples: 0 } );
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* This flag can be used for type testing.
|
|
@@ -99,9 +99,7 @@ class SSAAPassNode extends PassNode {
|
|
|
99
99
|
|
|
100
100
|
//
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const size = renderer.getSize( _size );
|
|
102
|
+
const size = renderer.getDrawingBufferSize( _size );
|
|
105
103
|
|
|
106
104
|
this.setSize( size.width, size.height );
|
|
107
105
|
this._sampleRenderTarget.setSize( this.renderTarget.width, this.renderTarget.height );
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import { RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, RendererUtils, RedFormat } from '@gnsx/three/webgpu';
|
|
2
|
+
import { reference, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getViewPosition, getScreenPositionFromClip, vogelDiskSample, interleavedGradientNoise, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, vec4, int, dot, max, clamp, length, screenCoordinate, PI2, texture, passTexture, context } from '@gnsx/three/tsl';
|
|
3
|
+
import { depthAwareBlur } from './depthAwareBlur.js';
|
|
4
|
+
|
|
5
|
+
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
6
|
+
const _size = /*@__PURE__*/ new Vector2();
|
|
7
|
+
|
|
8
|
+
let _rendererState;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Post processing node for a fast, screen-space ambient occlusion (SSAO).
|
|
12
|
+
*
|
|
13
|
+
* It point-samples a per-pixel rotated Vogel disk and estimates obscurance with a single depth tap
|
|
14
|
+
* per sample, trading the ground-truth accuracy of {@link GTAONode}'s horizon ray-marching for
|
|
15
|
+
* lower cost. A built-in separable, depth-aware blur denoises the result so it can be used without
|
|
16
|
+
* temporal accumulation.
|
|
17
|
+
* ```js
|
|
18
|
+
* const scenePass = pass( scene, camera );
|
|
19
|
+
* scenePass.setMRT( mrt( { output, normal: normalView } ) );
|
|
20
|
+
* const scenePassColor = scenePass.getTextureNode( 'output' );
|
|
21
|
+
* const scenePassDepth = scenePass.getTextureNode( 'depth' );
|
|
22
|
+
* const scenePassNormal = scenePass.getTextureNode( 'normal' );
|
|
23
|
+
*
|
|
24
|
+
* const aoPass = ssao( scenePassDepth, scenePassNormal, camera );
|
|
25
|
+
*
|
|
26
|
+
* renderPipeline.outputNode = scenePassColor.mul( aoPass.r );
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @augments TempNode
|
|
30
|
+
* @three_import import { ssao } from 'three/addons/tsl/display/SSAONode.js';
|
|
31
|
+
*/
|
|
32
|
+
class SSAONode extends TempNode {
|
|
33
|
+
|
|
34
|
+
static get type() {
|
|
35
|
+
|
|
36
|
+
return 'SSAONode';
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Constructs a new SSAO node.
|
|
42
|
+
*
|
|
43
|
+
* @param {Node<float>} depthNode - A node that represents the scene's depth.
|
|
44
|
+
* @param {Node<vec3>} normalNode - A node that represents the scene's normals.
|
|
45
|
+
* @param {Camera} camera - The camera the scene is rendered with.
|
|
46
|
+
*/
|
|
47
|
+
constructor( depthNode, normalNode, camera ) {
|
|
48
|
+
|
|
49
|
+
super( 'float' );
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* A node that represents the scene's depth.
|
|
53
|
+
*
|
|
54
|
+
* @type {Node<float>}
|
|
55
|
+
*/
|
|
56
|
+
this.depthNode = depthNode;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A node that represents the scene's normals.
|
|
60
|
+
*
|
|
61
|
+
* @type {Node<vec3>}
|
|
62
|
+
*/
|
|
63
|
+
this.normalNode = normalNode;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The resolution scale. The effect renders at a fraction of the drawing buffer
|
|
67
|
+
* for extra speed; `0.5` is a good default for a low-frequency signal like AO.
|
|
68
|
+
*
|
|
69
|
+
* @type {number}
|
|
70
|
+
* @default 0.5
|
|
71
|
+
*/
|
|
72
|
+
this.resolutionScale = 0.5;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
|
|
76
|
+
* its effect once per frame in `updateBefore()`.
|
|
77
|
+
*
|
|
78
|
+
* @type {string}
|
|
79
|
+
* @default 'frame'
|
|
80
|
+
*/
|
|
81
|
+
this.updateBeforeType = NodeUpdateType.FRAME;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The world-space radius the occlusion is gathered within.
|
|
85
|
+
*
|
|
86
|
+
* @type {UniformNode<float>}
|
|
87
|
+
*/
|
|
88
|
+
this.radius = uniform( 0.5 );
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The strength of the occlusion.
|
|
92
|
+
*
|
|
93
|
+
* @type {UniformNode<float>}
|
|
94
|
+
*/
|
|
95
|
+
this.intensity = uniform( 1 );
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* An angle bias that suppresses self-occlusion on near-flat surfaces.
|
|
99
|
+
*
|
|
100
|
+
* @type {UniformNode<float>}
|
|
101
|
+
*/
|
|
102
|
+
this.bias = uniform( 0.025 );
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* How many samples are used to estimate the occlusion. A higher value
|
|
106
|
+
* results in a smoother result at a higher runtime cost.
|
|
107
|
+
*
|
|
108
|
+
* @type {UniformNode<float>}
|
|
109
|
+
*/
|
|
110
|
+
this.samples = uniform( 16 );
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Whether the depth-aware blur that denoises the raw AO is applied or not.
|
|
114
|
+
*
|
|
115
|
+
* @type {boolean}
|
|
116
|
+
* @default true
|
|
117
|
+
*/
|
|
118
|
+
this.blurEnabled = true;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* How strongly the blur rejects samples across depth discontinuities,
|
|
122
|
+
* relative to the AO radius. A higher value keeps edges crisper.
|
|
123
|
+
*
|
|
124
|
+
* @type {UniformNode<float>}
|
|
125
|
+
*/
|
|
126
|
+
this.blurSharpness = uniform( 2 );
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The resolution of the effect. Set from the drawing buffer size and `resolutionScale`.
|
|
130
|
+
*
|
|
131
|
+
* @type {Vector2}
|
|
132
|
+
*/
|
|
133
|
+
this.resolution = new Vector2();
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The render target the raw ambient occlusion is rendered into. Also holds the
|
|
137
|
+
* final result after the separable blur has ping-ponged back into it.
|
|
138
|
+
*
|
|
139
|
+
* @private
|
|
140
|
+
* @type {RenderTarget}
|
|
141
|
+
*/
|
|
142
|
+
this._aoRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, format: RedFormat } );
|
|
143
|
+
this._aoRenderTarget.texture.name = 'SSAONode.AO';
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The render target the intermediate (horizontally blurred) result is rendered into.
|
|
147
|
+
*
|
|
148
|
+
* @private
|
|
149
|
+
* @type {RenderTarget}
|
|
150
|
+
*/
|
|
151
|
+
this._blurRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, format: RedFormat } );
|
|
152
|
+
this._blurRenderTarget.texture.name = 'SSAONode.Blur';
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Represents the projection matrix of the scene's camera.
|
|
156
|
+
*
|
|
157
|
+
* @private
|
|
158
|
+
* @type {UniformNode<mat4>}
|
|
159
|
+
*/
|
|
160
|
+
this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Represents the inverse projection matrix of the scene's camera.
|
|
164
|
+
*
|
|
165
|
+
* @private
|
|
166
|
+
* @type {UniformNode<mat4>}
|
|
167
|
+
*/
|
|
168
|
+
this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Represents the near value of the scene's camera.
|
|
172
|
+
*
|
|
173
|
+
* @private
|
|
174
|
+
* @type {ReferenceNode<float>}
|
|
175
|
+
*/
|
|
176
|
+
this._cameraNear = reference( 'near', 'float', camera );
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Represents the far value of the scene's camera.
|
|
180
|
+
*
|
|
181
|
+
* @private
|
|
182
|
+
* @type {ReferenceNode<float>}
|
|
183
|
+
*/
|
|
184
|
+
this._cameraFar = reference( 'far', 'float', camera );
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* The camera the scene is rendered with.
|
|
188
|
+
*
|
|
189
|
+
* @private
|
|
190
|
+
* @type {Camera}
|
|
191
|
+
*/
|
|
192
|
+
this._camera = camera;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* The input texture the blur material reads from. Swapped between the two render
|
|
196
|
+
* targets to run the horizontal and vertical passes with a single material.
|
|
197
|
+
*
|
|
198
|
+
* @private
|
|
199
|
+
* @type {TextureNode}
|
|
200
|
+
*/
|
|
201
|
+
this._blurInput = texture( this._aoRenderTarget.texture );
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* The blur direction (one texel along x or y).
|
|
205
|
+
*
|
|
206
|
+
* @private
|
|
207
|
+
* @type {UniformNode<vec2>}
|
|
208
|
+
*/
|
|
209
|
+
this._blurDirection = uniform( new Vector2() );
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* The material that computes the raw ambient occlusion.
|
|
213
|
+
*
|
|
214
|
+
* @private
|
|
215
|
+
* @type {NodeMaterial}
|
|
216
|
+
*/
|
|
217
|
+
this._aoMaterial = new NodeMaterial();
|
|
218
|
+
this._aoMaterial.name = 'SSAO.AO';
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The material that applies the separable, depth-aware blur.
|
|
222
|
+
*
|
|
223
|
+
* @private
|
|
224
|
+
* @type {NodeMaterial}
|
|
225
|
+
*/
|
|
226
|
+
this._blurMaterial = new NodeMaterial();
|
|
227
|
+
this._blurMaterial.name = 'SSAO.Blur';
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* The result of the effect is represented as a separate texture node.
|
|
231
|
+
*
|
|
232
|
+
* @private
|
|
233
|
+
* @type {PassTextureNode}
|
|
234
|
+
*/
|
|
235
|
+
this._textureNode = passTexture( this, this._aoRenderTarget.texture );
|
|
236
|
+
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Returns the result of the effect as a texture node.
|
|
241
|
+
*
|
|
242
|
+
* @return {PassTextureNode} A texture node that represents the result of the effect.
|
|
243
|
+
*/
|
|
244
|
+
getTextureNode() {
|
|
245
|
+
|
|
246
|
+
return this._textureNode;
|
|
247
|
+
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Sets the size of the effect.
|
|
252
|
+
*
|
|
253
|
+
* @param {number} width - The width of the effect.
|
|
254
|
+
* @param {number} height - The height of the effect.
|
|
255
|
+
*/
|
|
256
|
+
setSize( width, height ) {
|
|
257
|
+
|
|
258
|
+
width = Math.max( 1, Math.round( this.resolutionScale * width ) );
|
|
259
|
+
height = Math.max( 1, Math.round( this.resolutionScale * height ) );
|
|
260
|
+
|
|
261
|
+
this.resolution.set( width, height );
|
|
262
|
+
this._aoRenderTarget.setSize( width, height );
|
|
263
|
+
this._blurRenderTarget.setSize( width, height );
|
|
264
|
+
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* This method is used to render the effect once per frame.
|
|
269
|
+
*
|
|
270
|
+
* @param {NodeFrame} frame - The current node frame.
|
|
271
|
+
*/
|
|
272
|
+
updateBefore( frame ) {
|
|
273
|
+
|
|
274
|
+
const { renderer } = frame;
|
|
275
|
+
|
|
276
|
+
_rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
|
|
277
|
+
|
|
278
|
+
const size = renderer.getDrawingBufferSize( _size );
|
|
279
|
+
this.setSize( size.width, size.height );
|
|
280
|
+
|
|
281
|
+
renderer.setClearColor( 0xffffff, 1 );
|
|
282
|
+
|
|
283
|
+
// ambient occlusion
|
|
284
|
+
|
|
285
|
+
_quadMesh.material = this._aoMaterial;
|
|
286
|
+
_quadMesh.name = 'SSAO.AO';
|
|
287
|
+
renderer.setRenderTarget( this._aoRenderTarget );
|
|
288
|
+
_quadMesh.render( renderer );
|
|
289
|
+
|
|
290
|
+
// separable, depth-aware blur: horizontal ( AO -> blur ) then vertical ( blur -> AO )
|
|
291
|
+
|
|
292
|
+
if ( this.blurEnabled === true ) {
|
|
293
|
+
|
|
294
|
+
_quadMesh.material = this._blurMaterial;
|
|
295
|
+
_quadMesh.name = 'SSAO.Blur';
|
|
296
|
+
|
|
297
|
+
this._blurInput.value = this._aoRenderTarget.texture;
|
|
298
|
+
this._blurDirection.value.set( 1 / this.resolution.x, 0 );
|
|
299
|
+
renderer.setRenderTarget( this._blurRenderTarget );
|
|
300
|
+
_quadMesh.render( renderer );
|
|
301
|
+
|
|
302
|
+
this._blurInput.value = this._blurRenderTarget.texture;
|
|
303
|
+
this._blurDirection.value.set( 0, 1 / this.resolution.y );
|
|
304
|
+
renderer.setRenderTarget( this._aoRenderTarget );
|
|
305
|
+
_quadMesh.render( renderer );
|
|
306
|
+
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
RendererUtils.restoreRendererState( renderer, _rendererState );
|
|
310
|
+
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* This method is used to setup the effect's TSL code.
|
|
315
|
+
*
|
|
316
|
+
* @param {NodeBuilder} builder - The current node builder.
|
|
317
|
+
* @return {PassTextureNode}
|
|
318
|
+
*/
|
|
319
|
+
setup( builder ) {
|
|
320
|
+
|
|
321
|
+
const uvNode = uv();
|
|
322
|
+
|
|
323
|
+
const sampleDepth = ( uv ) => {
|
|
324
|
+
|
|
325
|
+
const depth = this.depthNode.sample( uv ).r;
|
|
326
|
+
|
|
327
|
+
if ( builder.renderer.logarithmicDepthBuffer === true ) {
|
|
328
|
+
|
|
329
|
+
const viewZ = logarithmicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
|
|
330
|
+
|
|
331
|
+
return viewZToPerspectiveDepth( viewZ, this._cameraNear, this._cameraFar );
|
|
332
|
+
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return depth;
|
|
336
|
+
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// ambient occlusion
|
|
340
|
+
|
|
341
|
+
const ao = Fn( () => {
|
|
342
|
+
|
|
343
|
+
const depth = sampleDepth( uvNode ).toVar();
|
|
344
|
+
|
|
345
|
+
depth.greaterThanEqual( 1.0 ).discard();
|
|
346
|
+
|
|
347
|
+
const viewPosition = getViewPosition( uvNode, depth, this._cameraProjectionMatrixInverse ).toVar();
|
|
348
|
+
const viewNormal = this.normalNode.sample( uvNode ).rgb.normalize().toVar();
|
|
349
|
+
|
|
350
|
+
// a low-discrepancy Vogel disk rotated per-pixel decorrelates the samples spatially,
|
|
351
|
+
// so a small blur is enough to hide the sampling pattern
|
|
352
|
+
|
|
353
|
+
const phi = interleavedGradientNoise( screenCoordinate ).mul( PI2 ).toVar();
|
|
354
|
+
const samples = this.samples;
|
|
355
|
+
|
|
356
|
+
// the fragment's clip position is loop-invariant; projection is linear, so each
|
|
357
|
+
// sample only has to project its (view-plane) offset and add it
|
|
358
|
+
|
|
359
|
+
const clipPosition = this._cameraProjectionMatrix.mul( vec4( viewPosition, 1.0 ) ).toVar();
|
|
360
|
+
|
|
361
|
+
const occlusion = float( 0 ).toVar();
|
|
362
|
+
|
|
363
|
+
Loop( { start: int( 0 ), end: samples, type: 'int', condition: '<' }, ( { i } ) => {
|
|
364
|
+
|
|
365
|
+
// disk offset in the view-aligned plane at the fragment's depth, then reprojected
|
|
366
|
+
|
|
367
|
+
const offset = vogelDiskSample( i, samples, phi ).mul( this.radius );
|
|
368
|
+
const clipOffset = this._cameraProjectionMatrix.mul( vec4( offset, 0.0, 0.0 ) );
|
|
369
|
+
const sampleUv = getScreenPositionFromClip( clipPosition.add( clipOffset ) );
|
|
370
|
+
|
|
371
|
+
const sampleViewPosition = getViewPosition( sampleUv, sampleDepth( sampleUv ), this._cameraProjectionMatrixInverse );
|
|
372
|
+
|
|
373
|
+
// normalized obscurance: only occluders above the tangent plane count, faded by distance
|
|
374
|
+
|
|
375
|
+
const v = sampleViewPosition.sub( viewPosition ).toVar();
|
|
376
|
+
const dist = length( v ).toVar();
|
|
377
|
+
const cosAngle = dot( v, viewNormal ).div( max( dist, float( 0.0001 ) ) );
|
|
378
|
+
const falloff = this.radius.div( this.radius.add( dist ) );
|
|
379
|
+
|
|
380
|
+
occlusion.addAssign( max( cosAngle.sub( this.bias ), 0.0 ).mul( falloff ) );
|
|
381
|
+
|
|
382
|
+
} );
|
|
383
|
+
|
|
384
|
+
return clamp( occlusion.div( samples ).mul( this.intensity ).oneMinus(), 0.0, 1.0 );
|
|
385
|
+
|
|
386
|
+
} );
|
|
387
|
+
|
|
388
|
+
const sharedContext = context( builder.getSharedContext() );
|
|
389
|
+
|
|
390
|
+
// compute ambient occlusion
|
|
391
|
+
|
|
392
|
+
this._aoMaterial.contextNode = sharedContext;
|
|
393
|
+
this._aoMaterial.fragmentNode = ao();
|
|
394
|
+
this._aoMaterial.needsUpdate = true;
|
|
395
|
+
|
|
396
|
+
// separable, depth-aware blur ( run horizontally then vertically via `_blurDirection` )
|
|
397
|
+
|
|
398
|
+
this._blurMaterial.contextNode = sharedContext;
|
|
399
|
+
this._blurMaterial.fragmentNode = depthAwareBlur( this._blurInput, this.depthNode, this._blurDirection, this._camera, this.blurSharpness, this.radius );
|
|
400
|
+
this._blurMaterial.needsUpdate = true;
|
|
401
|
+
|
|
402
|
+
return this._textureNode;
|
|
403
|
+
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Frees internal resources. This method should be called
|
|
408
|
+
* when the effect is no longer required.
|
|
409
|
+
*/
|
|
410
|
+
dispose() {
|
|
411
|
+
|
|
412
|
+
super.dispose();
|
|
413
|
+
|
|
414
|
+
this._aoRenderTarget.dispose();
|
|
415
|
+
this._blurRenderTarget.dispose();
|
|
416
|
+
|
|
417
|
+
this._aoMaterial.dispose();
|
|
418
|
+
this._blurMaterial.dispose();
|
|
419
|
+
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
export default SSAONode;
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* TSL function for creating a fast screen-space ambient occlusion (SSAO) effect.
|
|
428
|
+
*
|
|
429
|
+
* @tsl
|
|
430
|
+
* @function
|
|
431
|
+
* @param {Node<float>} depthNode - A node that represents the scene's depth.
|
|
432
|
+
* @param {Node<vec3>} normalNode - A node that represents the scene's normals.
|
|
433
|
+
* @param {Camera} camera - The camera the scene is rendered with.
|
|
434
|
+
* @returns {SSAONode}
|
|
435
|
+
*/
|
|
436
|
+
export const ssao = ( depthNode, normalNode, camera ) => new SSAONode( nodeObject( depthNode ), nodeObject( normalNode ), camera );
|