@plastic-software/three 0.179.0 → 0.181.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 +1108 -591
- package/build/three.core.js +616 -345
- package/build/three.core.min.js +1 -1
- package/build/three.module.js +488 -250
- package/build/three.module.min.js +1 -1
- package/build/three.tsl.js +37 -6
- package/build/three.tsl.min.js +1 -1
- package/build/three.webgpu.js +6576 -2152
- package/build/three.webgpu.min.js +1 -1
- package/build/three.webgpu.nodes.js +6575 -2151
- package/build/three.webgpu.nodes.min.js +1 -1
- package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
- package/examples/fonts/MPLUSRounded1c/OFL.txt +91 -0
- package/examples/jsm/Addons.js +1 -1
- package/examples/jsm/animation/CCDIKSolver.js +1 -1
- package/examples/jsm/controls/ArcballControls.js +8 -8
- package/examples/jsm/controls/DragControls.js +7 -57
- package/examples/jsm/controls/FirstPersonControls.js +3 -3
- package/examples/jsm/controls/FlyControls.js +1 -1
- package/examples/jsm/controls/OrbitControls.js +2 -2
- package/examples/jsm/controls/PointerLockControls.js +2 -10
- package/examples/jsm/controls/TrackballControls.js +1 -1
- package/examples/jsm/controls/TransformControls.js +1 -1
- package/examples/jsm/effects/AsciiEffect.js +8 -8
- package/examples/jsm/exporters/DRACOExporter.js +2 -2
- package/examples/jsm/exporters/EXRExporter.js +1 -1
- package/examples/jsm/exporters/GLTFExporter.js +33 -25
- package/examples/jsm/exporters/KTX2Exporter.js +4 -2
- package/examples/jsm/exporters/PLYExporter.js +1 -1
- package/examples/jsm/exporters/USDZExporter.js +9 -2
- package/examples/jsm/geometries/DecalGeometry.js +2 -2
- package/examples/jsm/geometries/ParametricGeometry.js +1 -1
- package/examples/jsm/geometries/TeapotGeometry.js +2 -2
- package/examples/jsm/geometries/TextGeometry.js +3 -2
- package/examples/jsm/gpgpu/BitonicSort.js +715 -0
- package/examples/jsm/helpers/ViewHelper.js +43 -5
- package/examples/jsm/inspector/Inspector.js +427 -0
- package/examples/jsm/inspector/RendererInspector.js +415 -0
- package/examples/jsm/inspector/tabs/Console.js +204 -0
- package/examples/jsm/inspector/tabs/Parameters.js +332 -0
- package/examples/jsm/inspector/tabs/Performance.js +268 -0
- package/examples/jsm/inspector/tabs/Viewer.js +166 -0
- package/examples/jsm/inspector/ui/Graph.js +95 -0
- package/examples/jsm/inspector/ui/Item.js +170 -0
- package/examples/jsm/inspector/ui/List.js +75 -0
- package/examples/jsm/inspector/ui/Profiler.js +170 -0
- package/examples/jsm/inspector/ui/Style.js +654 -0
- package/examples/jsm/inspector/ui/Tab.js +46 -0
- package/examples/jsm/inspector/ui/Values.js +423 -0
- package/examples/jsm/inspector/ui/utils.js +56 -0
- package/examples/jsm/interactive/HTMLMesh.js +6 -10
- package/examples/jsm/interactive/InteractiveGroup.js +1 -1
- package/examples/jsm/interactive/SelectionBox.js +30 -0
- package/examples/jsm/libs/ktx-parse.module.js +1 -1
- package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
- package/examples/jsm/lines/Line2.js +3 -3
- package/examples/jsm/lines/LineGeometry.js +1 -1
- package/examples/jsm/lines/LineSegments2.js +2 -2
- package/examples/jsm/lines/Wireframe.js +2 -2
- package/examples/jsm/lines/WireframeGeometry2.js +1 -1
- package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
- package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
- package/examples/jsm/loaders/3MFLoader.js +1 -1
- package/examples/jsm/loaders/ColladaLoader.js +3 -3
- package/examples/jsm/loaders/DDSLoader.js +1 -1
- package/examples/jsm/loaders/DRACOLoader.js +73 -22
- package/examples/jsm/loaders/EXRLoader.js +5 -5
- package/examples/jsm/loaders/FBXLoader.js +2 -2
- package/examples/jsm/loaders/FontLoader.js +23 -5
- package/examples/jsm/loaders/GLTFLoader.js +14 -8
- package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
- package/examples/jsm/loaders/HDRLoader.js +486 -0
- package/examples/jsm/loaders/KTX2Loader.js +136 -49
- package/examples/jsm/loaders/KTXLoader.js +2 -2
- package/examples/jsm/loaders/LDrawLoader.js +1 -1
- package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
- package/examples/jsm/loaders/LUTCubeLoader.js +1 -1
- package/examples/jsm/loaders/LWOLoader.js +2 -2
- package/examples/jsm/loaders/MaterialXLoader.js +22 -5
- package/examples/jsm/loaders/OBJLoader.js +1 -1
- package/examples/jsm/loaders/PDBLoader.js +1 -1
- package/examples/jsm/loaders/RGBELoader.js +7 -473
- package/examples/jsm/loaders/SVGLoader.js +2 -2
- package/examples/jsm/loaders/TTFLoader.js +4 -4
- package/examples/jsm/loaders/UltraHDRLoader.js +2 -2
- package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
- package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
- package/examples/jsm/math/ColorSpaces.js +19 -1
- package/examples/jsm/math/ConvexHull.js +3 -3
- package/examples/jsm/math/ImprovedNoise.js +1 -1
- package/examples/jsm/math/Lut.js +2 -2
- package/examples/jsm/math/SimplexNoise.js +1 -1
- package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
- package/examples/jsm/misc/ProgressiveLightMap.js +9 -3
- package/examples/jsm/misc/ProgressiveLightMapGPU.js +7 -1
- package/examples/jsm/misc/TubePainter.js +383 -40
- package/examples/jsm/misc/Volume.js +1 -1
- package/examples/jsm/modifiers/SimplifyModifier.js +1 -1
- package/examples/jsm/objects/ReflectorForSSRPass.js +1 -0
- package/examples/jsm/objects/Sky.js +1 -1
- package/examples/jsm/objects/SkyMesh.js +1 -1
- package/examples/jsm/objects/Water.js +3 -3
- package/examples/jsm/objects/WaterMesh.js +6 -6
- package/examples/jsm/postprocessing/GlitchPass.js +2 -2
- package/examples/jsm/postprocessing/OutlinePass.js +1 -1
- package/examples/jsm/postprocessing/SSRPass.js +37 -8
- package/examples/jsm/postprocessing/UnrealBloomPass.js +8 -6
- package/examples/jsm/renderers/CSS2DRenderer.js +16 -5
- package/examples/jsm/renderers/CSS3DRenderer.js +7 -6
- package/examples/jsm/renderers/SVGRenderer.js +1 -1
- package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +1 -1
- package/examples/jsm/shaders/AfterimageShader.js +1 -1
- package/examples/jsm/shaders/BleachBypassShader.js +1 -1
- package/examples/jsm/shaders/BokehShader.js +1 -1
- package/examples/jsm/shaders/BokehShader2.js +1 -1
- package/examples/jsm/shaders/DotScreenShader.js +1 -1
- package/examples/jsm/shaders/FocusShader.js +1 -1
- package/examples/jsm/shaders/GTAOShader.js +2 -2
- package/examples/jsm/shaders/GodRaysShader.js +1 -1
- package/examples/jsm/shaders/KaleidoShader.js +1 -1
- package/examples/jsm/shaders/PoissonDenoiseShader.js +2 -2
- package/examples/jsm/shaders/SSRShader.js +1 -1
- package/examples/jsm/shaders/SepiaShader.js +1 -1
- package/examples/jsm/shaders/SubsurfaceScatteringShader.js +1 -1
- package/examples/jsm/shaders/TriangleBlurShader.js +1 -1
- package/examples/jsm/shaders/UnpackDepthRGBAShader.js +1 -1
- package/examples/jsm/shaders/VignetteShader.js +1 -1
- package/examples/jsm/transpiler/GLSLDecoder.js +22 -19
- package/examples/jsm/transpiler/TSLEncoder.js +9 -10
- package/examples/jsm/transpiler/WGSLEncoder.js +24 -0
- package/examples/jsm/tsl/display/AfterImageNode.js +26 -24
- package/examples/jsm/tsl/display/AnamorphicNode.js +28 -4
- package/examples/jsm/tsl/display/BloomNode.js +7 -3
- package/examples/jsm/tsl/display/ChromaticAberrationNode.js +2 -1
- package/examples/jsm/tsl/display/DenoiseNode.js +2 -0
- package/examples/jsm/tsl/display/DepthOfFieldNode.js +446 -90
- package/examples/jsm/tsl/display/GTAONode.js +53 -5
- package/examples/jsm/tsl/display/GaussianBlurNode.js +49 -35
- package/examples/jsm/tsl/display/OutlineNode.js +13 -2
- package/examples/jsm/tsl/display/SSGINode.js +654 -0
- package/examples/jsm/tsl/display/SSRNode.js +182 -65
- package/examples/jsm/tsl/display/SSSNode.js +488 -0
- package/examples/jsm/tsl/display/TRAANode.js +124 -7
- package/examples/jsm/tsl/display/boxBlur.js +65 -0
- package/examples/jsm/tsl/display/hashBlur.js +16 -18
- package/examples/jsm/tsl/lighting/TiledLightsNode.js +21 -1
- package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
- package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
- package/examples/jsm/webxr/OculusHandModel.js +1 -1
- package/examples/jsm/webxr/XRControllerModelFactory.js +1 -1
- package/examples/jsm/webxr/XRHandModelFactory.js +2 -6
- package/package.json +5 -10
- package/src/Three.Core.js +4 -2
- package/src/Three.TSL.js +36 -5
- package/src/Three.WebGPU.Nodes.js +2 -0
- package/src/Three.WebGPU.js +2 -0
- package/src/animation/AnimationClip.js +20 -4
- package/src/animation/AnimationMixer.js +3 -3
- package/src/animation/AnimationObjectGroup.js +2 -1
- package/src/animation/KeyframeTrack.js +7 -6
- package/src/animation/PropertyBinding.js +12 -11
- package/src/audio/Audio.js +10 -9
- package/src/audio/PositionalAudio.js +1 -1
- package/src/cameras/OrthographicCamera.js +1 -1
- package/src/cameras/PerspectiveCamera.js +1 -1
- package/src/cameras/StereoCamera.js +2 -2
- package/src/constants.js +11 -3
- package/src/core/BufferGeometry.js +10 -10
- package/src/core/EventDispatcher.js +1 -1
- package/src/core/InterleavedBuffer.js +1 -1
- package/src/core/InterleavedBufferAttribute.js +3 -2
- package/src/core/Object3D.js +3 -2
- package/src/core/Raycaster.js +2 -1
- package/src/core/RenderTarget.js +10 -1
- package/src/extras/Controls.js +5 -4
- package/src/extras/DataUtils.js +2 -1
- package/src/extras/Earcut.js +6 -0
- package/src/extras/ImageUtils.js +2 -2
- package/src/extras/PMREMGenerator.js +268 -55
- package/src/extras/TextureUtils.js +2 -1
- package/src/extras/core/Curve.js +2 -1
- package/src/extras/core/Interpolations.js +7 -1
- package/src/extras/core/ShapePath.js +4 -4
- package/src/extras/lib/earcut.js +8 -8
- package/src/geometries/BoxGeometry.js +1 -0
- package/src/geometries/CapsuleGeometry.js +1 -0
- package/src/geometries/CircleGeometry.js +1 -0
- package/src/geometries/ConeGeometry.js +1 -0
- package/src/geometries/CylinderGeometry.js +1 -0
- package/src/geometries/DodecahedronGeometry.js +1 -0
- package/src/geometries/ExtrudeGeometry.js +8 -6
- package/src/geometries/IcosahedronGeometry.js +1 -0
- package/src/geometries/LatheGeometry.js +1 -0
- package/src/geometries/OctahedronGeometry.js +1 -0
- package/src/geometries/PlaneGeometry.js +1 -0
- package/src/geometries/RingGeometry.js +1 -0
- package/src/geometries/ShapeGeometry.js +1 -0
- package/src/geometries/SphereGeometry.js +1 -0
- package/src/geometries/TetrahedronGeometry.js +1 -0
- package/src/geometries/TorusGeometry.js +1 -0
- package/src/geometries/TorusKnotGeometry.js +1 -0
- package/src/geometries/TubeGeometry.js +1 -0
- package/src/helpers/CameraHelper.js +1 -1
- package/src/lights/webgpu/ProjectorLight.js +1 -1
- package/src/loaders/AnimationLoader.js +2 -1
- package/src/loaders/AudioLoader.js +2 -1
- package/src/loaders/BufferGeometryLoader.js +2 -2
- package/src/loaders/Cache.js +2 -2
- package/src/loaders/DataTextureLoader.js +1 -1
- package/src/loaders/FileLoader.js +3 -2
- package/src/loaders/ImageBitmapLoader.js +5 -4
- package/src/loaders/ImageLoader.js +1 -1
- package/src/loaders/Loader.js +3 -3
- package/src/loaders/LoadingManager.js +25 -3
- package/src/loaders/MaterialLoader.js +3 -2
- package/src/loaders/ObjectLoader.js +13 -13
- package/src/loaders/TextureLoader.js +1 -1
- package/src/loaders/nodes/NodeLoader.js +3 -2
- package/src/materials/Material.js +16 -3
- package/src/materials/MeshBasicMaterial.js +1 -0
- package/src/materials/MeshDepthMaterial.js +1 -0
- package/src/materials/MeshDistanceMaterial.js +1 -1
- package/src/materials/MeshLambertMaterial.js +2 -1
- package/src/materials/MeshMatcapMaterial.js +22 -0
- package/src/materials/MeshNormalMaterial.js +1 -0
- package/src/materials/MeshPhongMaterial.js +2 -1
- package/src/materials/MeshPhysicalMaterial.js +2 -1
- package/src/materials/MeshStandardMaterial.js +8 -7
- package/src/materials/MeshToonMaterial.js +1 -0
- package/src/materials/PointsMaterial.js +1 -1
- package/src/materials/ShaderMaterial.js +2 -2
- package/src/materials/nodes/Line2NodeMaterial.js +2 -2
- package/src/materials/nodes/MeshSSSNodeMaterial.js +1 -1
- package/src/materials/nodes/NodeMaterial.js +62 -22
- package/src/materials/nodes/PointsNodeMaterial.js +81 -28
- package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
- package/src/materials/nodes/manager/NodeMaterialObserver.js +3 -2
- package/src/math/Color.js +6 -5
- package/src/math/ColorManagement.js +9 -3
- package/src/math/Cylindrical.js +1 -1
- package/src/math/Euler.js +2 -1
- package/src/math/MathUtils.js +13 -11
- package/src/math/Matrix2.js +1 -1
- package/src/math/Matrix3.js +2 -2
- package/src/math/Matrix4.js +7 -7
- package/src/math/Plane.js +1 -1
- package/src/math/Quaternion.js +68 -66
- package/src/math/Spherical.js +1 -1
- package/src/nodes/Nodes.js +4 -1
- package/src/nodes/TSL.js +4 -1
- package/src/nodes/accessors/BufferNode.js +1 -1
- package/src/nodes/accessors/Camera.js +133 -7
- package/src/nodes/accessors/ClippingNode.js +6 -5
- package/src/nodes/accessors/CubeTextureNode.js +5 -4
- package/src/nodes/accessors/InstanceNode.js +25 -5
- package/src/nodes/accessors/Lights.js +10 -0
- package/src/nodes/accessors/Normal.js +5 -4
- package/src/nodes/accessors/Object3DNode.js +1 -1
- package/src/nodes/accessors/Position.js +18 -2
- package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
- package/src/nodes/accessors/ReferenceNode.js +3 -2
- package/src/nodes/accessors/SceneNode.js +2 -1
- package/src/nodes/accessors/StorageBufferNode.js +2 -1
- package/src/nodes/accessors/StorageTextureNode.js +22 -0
- package/src/nodes/accessors/Texture3DNode.js +14 -1
- package/src/nodes/accessors/TextureNode.js +130 -44
- package/src/nodes/code/FunctionCallNode.js +24 -4
- package/src/nodes/code/FunctionNode.js +23 -0
- package/src/nodes/core/ArrayNode.js +1 -0
- package/src/nodes/core/AssignNode.js +4 -3
- package/src/nodes/core/AttributeNode.js +2 -1
- package/src/nodes/core/ContextNode.js +29 -10
- package/src/nodes/core/IndexNode.js +2 -2
- package/src/nodes/core/InputNode.js +2 -1
- package/src/nodes/core/InspectorNode.js +128 -0
- package/src/nodes/core/{CacheNode.js → IsolateNode.js} +40 -7
- package/src/nodes/core/Node.js +152 -31
- package/src/nodes/core/NodeBuilder.js +183 -35
- package/src/nodes/core/NodeFrame.js +21 -21
- package/src/nodes/core/NodeFunction.js +2 -1
- package/src/nodes/core/NodeParser.js +2 -1
- package/src/nodes/core/NodeUniform.js +1 -1
- package/src/nodes/core/NodeUtils.js +17 -91
- package/src/nodes/core/ParameterNode.js +31 -0
- package/src/nodes/core/PropertyNode.js +7 -0
- package/src/nodes/core/StackNode.js +43 -16
- package/src/nodes/core/StructNode.js +5 -5
- package/src/nodes/core/StructTypeNode.js +1 -0
- package/src/nodes/core/SubBuildNode.js +2 -2
- package/src/nodes/core/UniformNode.js +18 -10
- package/src/nodes/core/VarNode.js +70 -33
- package/src/nodes/core/VaryingNode.js +3 -2
- package/src/nodes/display/BlendModes.js +5 -4
- package/src/nodes/display/BumpMapNode.js +1 -1
- package/src/nodes/display/ColorAdjustment.js +1 -1
- package/src/nodes/display/FrontFacingNode.js +4 -8
- package/src/nodes/display/NormalMapNode.js +2 -1
- package/src/nodes/display/PassNode.js +52 -11
- package/src/nodes/display/RenderOutputNode.js +28 -2
- package/src/nodes/display/ScreenNode.js +44 -14
- package/src/nodes/display/ToneMappingNode.js +31 -4
- package/src/nodes/display/ToonOutlinePassNode.js +8 -0
- package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
- package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
- package/src/nodes/display/ViewportTextureNode.js +42 -12
- package/src/nodes/fog/Fog.js +3 -2
- package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +52 -0
- package/src/nodes/functions/BSDF/DFGApprox.js +60 -19
- package/src/nodes/functions/BasicLightingModel.js +2 -1
- package/src/nodes/functions/PhysicalLightingModel.js +3 -2
- package/src/nodes/functions/VolumetricLightingModel.js +5 -5
- package/src/nodes/geometry/RangeNode.js +40 -4
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +2 -1
- package/src/nodes/gpgpu/ComputeNode.js +17 -5
- package/src/nodes/gpgpu/SubgroupFunctionNode.js +455 -0
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -1
- package/src/nodes/lighting/EnvironmentNode.js +6 -6
- package/src/nodes/lighting/LightsNode.js +3 -4
- package/src/nodes/lighting/PointShadowNode.js +6 -0
- package/src/nodes/lighting/ShadowFilterNode.js +2 -0
- package/src/nodes/lighting/ShadowNode.js +75 -8
- package/src/nodes/math/BitcastNode.js +156 -0
- package/src/nodes/math/ConditionalNode.js +24 -7
- package/src/nodes/math/MathNode.js +25 -19
- package/src/nodes/math/OperatorNode.js +7 -5
- package/src/nodes/pmrem/PMREMUtils.js +117 -2
- package/src/nodes/shapes/Shapes.js +1 -1
- package/src/nodes/tsl/TSLBase.js +5 -2
- package/src/nodes/tsl/TSLCore.js +460 -159
- package/src/nodes/utils/DebugNode.js +2 -1
- package/src/nodes/utils/EventNode.js +36 -0
- package/src/nodes/utils/FunctionOverloadingNode.js +37 -19
- package/src/nodes/utils/JoinNode.js +6 -3
- package/src/nodes/utils/LoopNode.js +20 -24
- package/src/nodes/utils/MemberNode.js +59 -7
- package/src/nodes/utils/PostProcessingUtils.js +28 -1
- package/src/nodes/utils/RTTNode.js +13 -3
- package/src/nodes/utils/ReflectorNode.js +58 -7
- package/src/nodes/utils/SampleNode.js +12 -2
- package/src/nodes/utils/SplitNode.js +11 -0
- package/src/nodes/utils/Timer.js +0 -47
- package/src/objects/BatchedMesh.js +2 -2
- package/src/objects/LOD.js +1 -1
- package/src/objects/Line.js +2 -1
- package/src/objects/LineSegments.js +2 -1
- package/src/objects/Skeleton.js +3 -2
- package/src/objects/SkinnedMesh.js +3 -1
- package/src/objects/Sprite.js +4 -3
- package/src/renderers/WebGLRenderer.js +48 -41
- package/src/renderers/common/Animation.js +13 -1
- package/src/renderers/common/Attributes.js +1 -1
- package/src/renderers/common/Backend.js +108 -27
- package/src/renderers/common/Background.js +2 -1
- package/src/renderers/common/Bindings.js +58 -2
- package/src/renderers/common/CanvasTarget.js +341 -0
- package/src/renderers/common/ChainMap.js +1 -1
- package/src/renderers/common/DataMap.js +1 -1
- package/src/renderers/common/Geometries.js +26 -0
- package/src/renderers/common/Info.js +4 -2
- package/src/renderers/common/InspectorBase.js +146 -0
- package/src/renderers/common/Pipelines.js +1 -1
- package/src/renderers/common/PostProcessing.js +6 -25
- package/src/renderers/common/QuadMesh.js +7 -1
- package/src/renderers/common/RenderContext.js +2 -2
- package/src/renderers/common/RenderList.js +7 -3
- package/src/renderers/common/RenderObject.js +16 -2
- package/src/renderers/common/RenderObjects.js +1 -1
- package/src/renderers/common/Renderer.js +473 -245
- package/src/renderers/common/RendererUtils.js +9 -0
- package/src/renderers/common/SampledTexture.js +9 -1
- package/src/renderers/common/Sampler.js +50 -12
- package/src/renderers/common/StorageTexture.js +9 -1
- package/src/renderers/common/Textures.js +121 -45
- package/src/renderers/common/TimestampQueryPool.js +65 -3
- package/src/renderers/common/UniformsGroup.js +2 -1
- package/src/renderers/common/XRManager.js +42 -22
- package/src/renderers/common/extras/PMREMGenerator.js +160 -65
- package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
- package/src/renderers/common/nodes/NodeLibrary.js +9 -7
- package/src/renderers/common/nodes/NodeSampler.js +13 -1
- package/src/renderers/common/nodes/Nodes.js +38 -16
- package/src/renderers/shaders/DFGLUTData.js +64 -0
- package/src/renderers/shaders/ShaderChunk/common.glsl.js +0 -12
- package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +52 -18
- package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +7 -15
- package/src/renderers/shaders/ShaderLib/depth.glsl.js +1 -1
- package/src/renderers/shaders/UniformsLib.js +1 -0
- package/src/renderers/shaders/UniformsUtils.js +25 -4
- package/src/renderers/webgl/WebGLCapabilities.js +2 -1
- package/src/renderers/webgl/WebGLExtensions.js +2 -25
- package/src/renderers/webgl/WebGLInfo.js +3 -1
- package/src/renderers/webgl/WebGLProgram.js +15 -14
- package/src/renderers/webgl/WebGLPrograms.js +2 -1
- package/src/renderers/webgl/WebGLShadowMap.js +3 -2
- package/src/renderers/webgl/WebGLState.js +15 -14
- package/src/renderers/webgl/WebGLTextures.js +19 -14
- package/src/renderers/webgl/WebGLUniformsGroups.js +5 -3
- package/src/renderers/webgl/WebGLUtils.js +3 -2
- package/src/renderers/webgl-fallback/WebGLBackend.js +199 -167
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +181 -25
- package/src/renderers/webgl-fallback/utils/WebGLConstants.js +2 -3
- package/src/renderers/webgl-fallback/utils/WebGLState.js +7 -6
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +169 -19
- package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +51 -22
- package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
- package/src/renderers/webgpu/WebGPUBackend.js +153 -123
- package/src/renderers/webgpu/WebGPURenderer.Nodes.js +2 -1
- package/src/renderers/webgpu/WebGPURenderer.js +3 -2
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +142 -50
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +2 -1
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +5 -3
- package/src/renderers/webgpu/utils/WebGPUConstants.js +7 -2
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +53 -34
- package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +6 -8
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +260 -99
- package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +32 -9
- package/src/renderers/webgpu/utils/WebGPUUtils.js +22 -2
- package/src/renderers/webxr/WebXRManager.js +42 -26
- package/src/textures/ExternalTexture.js +15 -4
- package/src/textures/Source.js +3 -2
- package/src/textures/Texture.js +3 -2
- package/src/textures/VideoTexture.js +2 -3
- package/src/utils.js +67 -3
- package/examples/jsm/loaders/RGBMLoader.js +0 -1148
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
import { RedFormat, RenderTarget, Vector2, RendererUtils, QuadMesh, TempNode, NodeMaterial, NodeUpdateType, UnsignedByteType } from 'three/webgpu';
|
|
2
|
+
import { reference, viewZToPerspectiveDepth, logarithmicDepthToViewZ, getScreenPosition, getViewPosition, float, Break, Loop, int, max, abs, If, interleavedGradientNoise, screenCoordinate, nodeObject, Fn, passTexture, uv, uniform, perspectiveDepthToViewZ, orthographicDepthToViewZ, vec2, lightPosition, lightTargetPosition, fract, rand, mix } from 'three/tsl';
|
|
3
|
+
|
|
4
|
+
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
5
|
+
const _size = /*@__PURE__*/ new Vector2();
|
|
6
|
+
|
|
7
|
+
const _spatialOffsets = [ 0, 0.5, 0.25, 0.75 ];
|
|
8
|
+
|
|
9
|
+
let _rendererState;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Post processing node for applying Screen-Space Shadows (SSS) to a scene.
|
|
13
|
+
*
|
|
14
|
+
* Screen-Space Shadows (also known as Contact Shadows) should ideally be used to complement
|
|
15
|
+
* traditional shadow maps. They are best suited for rendering detailed shadows of smaller
|
|
16
|
+
* objects at a closer scale like intricate shadowing on highly detailed models. In other words:
|
|
17
|
+
* Use Shadow Maps for the foundation and Screen-Space Shadows for the details.
|
|
18
|
+
*
|
|
19
|
+
* The shadows produced by this implementation might have too hard edges for certain use cases.
|
|
20
|
+
* Use a box, gaussian or hash blur to soften the edges before doing the composite with the
|
|
21
|
+
* beauty pass. Code example:
|
|
22
|
+
*
|
|
23
|
+
* ```js
|
|
24
|
+
* const sssPass = sss( scenePassDepth, camera, mainLight );
|
|
25
|
+
*
|
|
26
|
+
* const sssBlur = boxBlur( sssPass.r, { size: 2, separation: 1 } ); // optional blur
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* Limitations:
|
|
30
|
+
*
|
|
31
|
+
* - Ideally the maximum shadow length should not exceed `1` meter. Otherwise the effect gets
|
|
32
|
+
* computationally very expensive since more samples during the ray marching process are evaluated.
|
|
33
|
+
* You can mitigate this issue by reducing the `quality` paramter.
|
|
34
|
+
* - The effect can only be used with a single directional light, the main light of your scene.
|
|
35
|
+
* This main light usually represents the sun or daylight.
|
|
36
|
+
* - Like other Screen-Space techniques SSS can only honor objects in the shadowing computation that
|
|
37
|
+
* are currently visible within the camera's view.
|
|
38
|
+
*
|
|
39
|
+
* References:
|
|
40
|
+
* - {@link https://panoskarabelas.com/posts/screen_space_shadows/}.
|
|
41
|
+
* - {@link https://www.bendstudio.com/blog/inside-bend-screen-space-shadows/}.
|
|
42
|
+
*
|
|
43
|
+
* @augments TempNode
|
|
44
|
+
* @three_import import { sss } from 'three/addons/tsl/display/SSSNode.js';
|
|
45
|
+
*/
|
|
46
|
+
class SSSNode extends TempNode {
|
|
47
|
+
|
|
48
|
+
static get type() {
|
|
49
|
+
|
|
50
|
+
return 'SSSNode';
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Constructs a new SSS node.
|
|
56
|
+
*
|
|
57
|
+
* @param {TextureNode} depthNode - A texture node that represents the scene's depth.
|
|
58
|
+
* @param {Camera} camera - The camera the scene is rendered with.
|
|
59
|
+
* @param {DirectionalLight} mainLight - The main directional light of the scene.
|
|
60
|
+
*/
|
|
61
|
+
constructor( depthNode, camera, mainLight ) {
|
|
62
|
+
|
|
63
|
+
super( 'float' );
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A node that represents the beauty pass's depth.
|
|
67
|
+
*
|
|
68
|
+
* @type {TextureNode}
|
|
69
|
+
*/
|
|
70
|
+
this.depthNode = depthNode;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Maximum shadow length in world units. Longer shadows result in more computational
|
|
74
|
+
* overhead.
|
|
75
|
+
*
|
|
76
|
+
* @type {UniformNode<float>}
|
|
77
|
+
* @default 0.1
|
|
78
|
+
*/
|
|
79
|
+
this.maxDistance = uniform( 0.1, 'float' );
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Depth testing thickness.
|
|
83
|
+
*
|
|
84
|
+
* @type {UniformNode<float>}
|
|
85
|
+
* @default 0.01
|
|
86
|
+
*/
|
|
87
|
+
this.thickness = uniform( 0.01, 'float' );
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Shadow intensity. Must be in the range `[0, 1]`.
|
|
91
|
+
*
|
|
92
|
+
* @type {UniformNode<float>}
|
|
93
|
+
* @default 0.5
|
|
94
|
+
*/
|
|
95
|
+
this.shadowIntensity = uniform( 0.5, 'float' );
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* This parameter controls how detailed the raymarching process works.
|
|
99
|
+
* The value ranges is `[0,1]` where `1` means best quality (the maximum number
|
|
100
|
+
* of raymarching iterations/samples) and `0` means no samples at all.
|
|
101
|
+
*
|
|
102
|
+
* A quality of `0.5` is usually sufficient for most use cases. Try to keep
|
|
103
|
+
* this parameter as low as possible. Larger values result in noticeable more
|
|
104
|
+
* overhead.
|
|
105
|
+
*
|
|
106
|
+
* @type {UniformNode<float>}
|
|
107
|
+
* @default 0.5
|
|
108
|
+
*/
|
|
109
|
+
this.quality = uniform( 0.5 );
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The resolution scale. Valid values are in the range
|
|
113
|
+
* `[0,1]`. `1` means best quality but also results in
|
|
114
|
+
* more computational overhead. Setting to `0.5` means
|
|
115
|
+
* the effect is computed in half-resolution.
|
|
116
|
+
*
|
|
117
|
+
* @type {number}
|
|
118
|
+
* @default 1
|
|
119
|
+
*/
|
|
120
|
+
this.resolutionScale = 1;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Whether to use temporal filtering or not. Setting this property to
|
|
124
|
+
* `true` requires the usage of `TRAANode`. This will help to reduce noice
|
|
125
|
+
* although it introduces typical TAA artifacts like ghosting and temporal
|
|
126
|
+
* instabilities.
|
|
127
|
+
*
|
|
128
|
+
* @type {boolean}
|
|
129
|
+
* @default false
|
|
130
|
+
*/
|
|
131
|
+
this.useTemporalFiltering = false;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
|
|
135
|
+
* its effect once per frame in `updateBefore()`.
|
|
136
|
+
*
|
|
137
|
+
* @type {string}
|
|
138
|
+
* @default 'frame'
|
|
139
|
+
*/
|
|
140
|
+
this.updateBeforeType = NodeUpdateType.FRAME;
|
|
141
|
+
|
|
142
|
+
// private uniforms
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Represents the view matrix of the scene's camera.
|
|
146
|
+
*
|
|
147
|
+
* @private
|
|
148
|
+
* @type {UniformNode<mat4>}
|
|
149
|
+
*/
|
|
150
|
+
this._cameraViewMatrix = uniform( camera.matrixWorldInverse );
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Represents the projection matrix of the scene's camera.
|
|
154
|
+
*
|
|
155
|
+
* @private
|
|
156
|
+
* @type {UniformNode<mat4>}
|
|
157
|
+
*/
|
|
158
|
+
this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Represents the inverse projection matrix of the scene's camera.
|
|
162
|
+
*
|
|
163
|
+
* @private
|
|
164
|
+
* @type {UniformNode<mat4>}
|
|
165
|
+
*/
|
|
166
|
+
this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Represents the near value of the scene's camera.
|
|
170
|
+
*
|
|
171
|
+
* @private
|
|
172
|
+
* @type {ReferenceNode<float>}
|
|
173
|
+
*/
|
|
174
|
+
this._cameraNear = reference( 'near', 'float', camera );
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Represents the far value of the scene's camera.
|
|
178
|
+
*
|
|
179
|
+
* @private
|
|
180
|
+
* @type {ReferenceNode<float>}
|
|
181
|
+
*/
|
|
182
|
+
this._cameraFar = reference( 'far', 'float', camera );
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* The resolution of the pass.
|
|
186
|
+
*
|
|
187
|
+
* @private
|
|
188
|
+
* @type {UniformNode<vec2>}
|
|
189
|
+
*/
|
|
190
|
+
this._resolution = uniform( new Vector2() );
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Temporal offset added to the initial ray step.
|
|
194
|
+
*
|
|
195
|
+
* @type {UniformNode<float>}
|
|
196
|
+
*/
|
|
197
|
+
this._temporalOffset = uniform( 0 );
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* The frame ID use when temporal filtering is enabled.
|
|
201
|
+
*
|
|
202
|
+
* @type {UniformNode<uint>}
|
|
203
|
+
*/
|
|
204
|
+
this._frameId = uniform( 0 );
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* A reference to the scene's main light.
|
|
208
|
+
*
|
|
209
|
+
* @private
|
|
210
|
+
* @type {DirectionalLight}
|
|
211
|
+
*/
|
|
212
|
+
this._mainLight = mainLight;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* The camera the scene is rendered with.
|
|
216
|
+
*
|
|
217
|
+
* @private
|
|
218
|
+
* @type {Camera}
|
|
219
|
+
*/
|
|
220
|
+
this._camera = camera;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* The render target the SSS is rendered into.
|
|
224
|
+
*
|
|
225
|
+
* @private
|
|
226
|
+
* @type {RenderTarget}
|
|
227
|
+
*/
|
|
228
|
+
this._sssRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, format: RedFormat, type: UnsignedByteType } );
|
|
229
|
+
this._sssRenderTarget.texture.name = 'SSS';
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* The material that is used to render the effect.
|
|
233
|
+
*
|
|
234
|
+
* @private
|
|
235
|
+
* @type {NodeMaterial}
|
|
236
|
+
*/
|
|
237
|
+
this._material = new NodeMaterial();
|
|
238
|
+
this._material.name = 'SSS';
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* The result of the effect is represented as a separate texture node.
|
|
242
|
+
*
|
|
243
|
+
* @private
|
|
244
|
+
* @type {PassTextureNode}
|
|
245
|
+
*/
|
|
246
|
+
this._textureNode = passTexture( this, this._sssRenderTarget.texture );
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Returns the result of the effect as a texture node.
|
|
253
|
+
*
|
|
254
|
+
* @return {PassTextureNode} A texture node that represents the result of the effect.
|
|
255
|
+
*/
|
|
256
|
+
getTextureNode() {
|
|
257
|
+
|
|
258
|
+
return this._textureNode;
|
|
259
|
+
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Sets the size of the effect.
|
|
264
|
+
*
|
|
265
|
+
* @param {number} width - The width of the effect.
|
|
266
|
+
* @param {number} height - The height of the effect.
|
|
267
|
+
*/
|
|
268
|
+
setSize( width, height ) {
|
|
269
|
+
|
|
270
|
+
width = Math.round( this.resolutionScale * width );
|
|
271
|
+
height = Math.round( this.resolutionScale * height );
|
|
272
|
+
|
|
273
|
+
this._resolution.value.set( width, height );
|
|
274
|
+
this._sssRenderTarget.setSize( width, height );
|
|
275
|
+
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* This method is used to render the effect once per frame.
|
|
280
|
+
*
|
|
281
|
+
* @param {NodeFrame} frame - The current node frame.
|
|
282
|
+
*/
|
|
283
|
+
updateBefore( frame ) {
|
|
284
|
+
|
|
285
|
+
const { renderer } = frame;
|
|
286
|
+
|
|
287
|
+
_rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
|
|
288
|
+
|
|
289
|
+
//
|
|
290
|
+
|
|
291
|
+
const size = renderer.getDrawingBufferSize( _size );
|
|
292
|
+
this.setSize( size.width, size.height );
|
|
293
|
+
|
|
294
|
+
// update temporal uniforms
|
|
295
|
+
|
|
296
|
+
if ( this.useTemporalFiltering === true ) {
|
|
297
|
+
|
|
298
|
+
const frameId = frame.frameId;
|
|
299
|
+
|
|
300
|
+
this._temporalOffset.value = _spatialOffsets[ frameId % 4 ];
|
|
301
|
+
this._frameId = frame.frameId;
|
|
302
|
+
|
|
303
|
+
} else {
|
|
304
|
+
|
|
305
|
+
this._temporalOffset.value = 0;
|
|
306
|
+
this._frameId = 0;
|
|
307
|
+
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
//
|
|
311
|
+
|
|
312
|
+
_quadMesh.material = this._material;
|
|
313
|
+
_quadMesh.name = 'SSS';
|
|
314
|
+
|
|
315
|
+
// clear
|
|
316
|
+
|
|
317
|
+
renderer.setClearColor( 0xffffff, 1 );
|
|
318
|
+
|
|
319
|
+
// sss
|
|
320
|
+
|
|
321
|
+
renderer.setRenderTarget( this._sssRenderTarget );
|
|
322
|
+
_quadMesh.render( renderer );
|
|
323
|
+
|
|
324
|
+
// restore
|
|
325
|
+
|
|
326
|
+
RendererUtils.restoreRendererState( renderer, _rendererState );
|
|
327
|
+
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* This method is used to setup the effect's TSL code.
|
|
332
|
+
*
|
|
333
|
+
* @param {NodeBuilder} builder - The current node builder.
|
|
334
|
+
* @return {PassTextureNode}
|
|
335
|
+
*/
|
|
336
|
+
setup( builder ) {
|
|
337
|
+
|
|
338
|
+
const uvNode = uv();
|
|
339
|
+
|
|
340
|
+
const getViewZ = Fn( ( [ depth ] ) => {
|
|
341
|
+
|
|
342
|
+
let viewZNode;
|
|
343
|
+
|
|
344
|
+
if ( this._camera.isPerspectiveCamera ) {
|
|
345
|
+
|
|
346
|
+
viewZNode = perspectiveDepthToViewZ( depth, this._cameraNear, this._cameraFar );
|
|
347
|
+
|
|
348
|
+
} else {
|
|
349
|
+
|
|
350
|
+
viewZNode = orthographicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
|
|
351
|
+
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return viewZNode;
|
|
355
|
+
|
|
356
|
+
} );
|
|
357
|
+
|
|
358
|
+
const sampleDepth = ( uv ) => {
|
|
359
|
+
|
|
360
|
+
const depth = this.depthNode.sample( uv ).r;
|
|
361
|
+
|
|
362
|
+
if ( builder.renderer.logarithmicDepthBuffer === true ) {
|
|
363
|
+
|
|
364
|
+
const viewZ = logarithmicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
|
|
365
|
+
|
|
366
|
+
return viewZToPerspectiveDepth( viewZ, this._cameraNear, this._cameraFar );
|
|
367
|
+
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return depth;
|
|
371
|
+
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
const sss = Fn( () => {
|
|
375
|
+
|
|
376
|
+
const depth = sampleDepth( uvNode ).toVar();
|
|
377
|
+
depth.greaterThanEqual( 1.0 ).discard();
|
|
378
|
+
|
|
379
|
+
// compute ray position and direction (in view-space)
|
|
380
|
+
|
|
381
|
+
const rayStartPosition = getViewPosition( uvNode, depth, this._cameraProjectionMatrixInverse ).toVar( 'rayStartPosition' );
|
|
382
|
+
const rayDirection = this._cameraViewMatrix.transformDirection( lightPosition( this._mainLight ).sub( lightTargetPosition( this._mainLight ) ) ).toConst( 'rayDirection' );
|
|
383
|
+
const rayEndPosition = rayStartPosition.add( rayDirection.mul( this.maxDistance ) ).toConst( 'rayEndPosition' );
|
|
384
|
+
|
|
385
|
+
// d0 and d1 are the start and maximum points of the ray in screen space
|
|
386
|
+
const d0 = screenCoordinate.xy.toVar();
|
|
387
|
+
const d1 = getScreenPosition( rayEndPosition, this._cameraProjectionMatrix ).mul( this._resolution ).toVar();
|
|
388
|
+
|
|
389
|
+
// below variables are used to control the raymarching process
|
|
390
|
+
|
|
391
|
+
// total length of the ray
|
|
392
|
+
const totalLen = d1.sub( d0 ).length().toVar();
|
|
393
|
+
|
|
394
|
+
// offset in x and y direction
|
|
395
|
+
const xLen = d1.x.sub( d0.x ).toVar();
|
|
396
|
+
const yLen = d1.y.sub( d0.y ).toVar();
|
|
397
|
+
|
|
398
|
+
// determine the larger delta
|
|
399
|
+
// The larger difference will help to determine how much to travel in the X and Y direction each iteration and
|
|
400
|
+
// how many iterations are needed to travel the entire ray
|
|
401
|
+
const totalStep = int( max( abs( xLen ), abs( yLen ) ).mul( this.quality.clamp() ) ).toConst();
|
|
402
|
+
|
|
403
|
+
// step sizes in the x and y directions
|
|
404
|
+
const xSpan = xLen.div( totalStep ).toVar();
|
|
405
|
+
const ySpan = yLen.div( totalStep ).toVar();
|
|
406
|
+
|
|
407
|
+
// compute noise based ray offset
|
|
408
|
+
const noise = interleavedGradientNoise( screenCoordinate );
|
|
409
|
+
const offset = fract( noise.add( this._temporalOffset ) ).add( rand( uvNode.add( this._frameId ) ) ).toConst( 'offset' );
|
|
410
|
+
|
|
411
|
+
const occlusion = float( 0 ).toVar();
|
|
412
|
+
|
|
413
|
+
Loop( totalStep, ( { i } ) => {
|
|
414
|
+
|
|
415
|
+
// advance on the ray by computing a new position in screen coordinates
|
|
416
|
+
const xy = vec2( d0.x.add( xSpan.mul( float( i ).add( offset ) ) ), d0.y.add( ySpan.mul( float( i ).add( offset ) ) ) ).toVar();
|
|
417
|
+
|
|
418
|
+
// stop processing if the new position lies outside of the screen
|
|
419
|
+
If( xy.x.lessThan( 0 ).or( xy.x.greaterThan( this._resolution.x ) ).or( xy.y.lessThan( 0 ) ).or( xy.y.greaterThan( this._resolution.y ) ), () => {
|
|
420
|
+
|
|
421
|
+
Break();
|
|
422
|
+
|
|
423
|
+
} );
|
|
424
|
+
|
|
425
|
+
// compute new uv, depth and viewZ for the next fragment
|
|
426
|
+
|
|
427
|
+
const uvNode = xy.div( this._resolution );
|
|
428
|
+
const fragmentDepth = sampleDepth( uvNode ).toConst();
|
|
429
|
+
const fragmentViewZ = getViewZ( fragmentDepth ).toConst( 'fragmentViewZ' );
|
|
430
|
+
|
|
431
|
+
const s = xy.sub( d0 ).length().div( totalLen ).toVar();
|
|
432
|
+
const rayPosition = mix( rayStartPosition, rayEndPosition, s );
|
|
433
|
+
|
|
434
|
+
const depthDelta = rayPosition.z.sub( fragmentViewZ ).negate(); // Port note: viewZ values are negative in three
|
|
435
|
+
|
|
436
|
+
// check if the camera can't "see" the ray (ray depth must be larger than the camera depth, so positive depth_delta)
|
|
437
|
+
|
|
438
|
+
If( depthDelta.greaterThan( 0 ).and( depthDelta.lessThan( this.thickness ) ), () => {
|
|
439
|
+
|
|
440
|
+
// mark as occluded
|
|
441
|
+
|
|
442
|
+
occlusion.assign( this.shadowIntensity );
|
|
443
|
+
|
|
444
|
+
Break();
|
|
445
|
+
|
|
446
|
+
} );
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
} );
|
|
450
|
+
|
|
451
|
+
return occlusion.oneMinus();
|
|
452
|
+
|
|
453
|
+
} );
|
|
454
|
+
|
|
455
|
+
this._material.fragmentNode = sss().context( builder.getSharedContext() );
|
|
456
|
+
this._material.needsUpdate = true;
|
|
457
|
+
|
|
458
|
+
return this._textureNode;
|
|
459
|
+
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Frees internal resources. This method should be called
|
|
464
|
+
* when the effect is no longer required.
|
|
465
|
+
*/
|
|
466
|
+
dispose() {
|
|
467
|
+
|
|
468
|
+
this._sssRenderTarget.dispose();
|
|
469
|
+
|
|
470
|
+
this._material.dispose();
|
|
471
|
+
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
export default SSSNode;
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* TSL function for creating a SSS effect.
|
|
480
|
+
*
|
|
481
|
+
* @tsl
|
|
482
|
+
* @function
|
|
483
|
+
* @param {TextureNode} depthNode - A texture node that represents the scene's depth.
|
|
484
|
+
* @param {Camera} camera - The camera the scene is rendered with.
|
|
485
|
+
* @param {DirectionalLight} mainLight - The main directional light of the scene.
|
|
486
|
+
* @returns {SSSNode}
|
|
487
|
+
*/
|
|
488
|
+
export const sss = ( depthNode, camera, mainLight ) => nodeObject( new SSSNode( depthNode, camera, mainLight ) );
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HalfFloatType, Vector2, RenderTarget, RendererUtils, QuadMesh, NodeMaterial, TempNode, NodeUpdateType, Matrix4 } from 'three/webgpu';
|
|
2
|
-
import { add, float, If, Loop, int, Fn, min, max, clamp, nodeObject, texture, uniform, uv, vec2, vec4, luminance, convertToTexture, passTexture, velocity } from 'three/tsl';
|
|
1
|
+
import { HalfFloatType, Vector2, RenderTarget, RendererUtils, QuadMesh, NodeMaterial, TempNode, NodeUpdateType, Matrix4, DepthTexture } from 'three/webgpu';
|
|
2
|
+
import { add, float, If, Loop, int, Fn, min, max, clamp, nodeObject, texture, uniform, uv, vec2, vec4, luminance, convertToTexture, passTexture, velocity, getViewPosition, length } from 'three/tsl';
|
|
3
3
|
|
|
4
4
|
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
5
5
|
const _size = /*@__PURE__*/ new Vector2();
|
|
@@ -79,7 +79,7 @@ class TRAANode extends TempNode {
|
|
|
79
79
|
/**
|
|
80
80
|
* The camera the scene is rendered with.
|
|
81
81
|
*
|
|
82
|
-
* @type {
|
|
82
|
+
* @type {Camera}
|
|
83
83
|
*/
|
|
84
84
|
this.camera = camera;
|
|
85
85
|
|
|
@@ -100,13 +100,45 @@ class TRAANode extends TempNode {
|
|
|
100
100
|
*/
|
|
101
101
|
this._invSize = uniform( new Vector2() );
|
|
102
102
|
|
|
103
|
+
/**
|
|
104
|
+
* A uniform node holding the camera world matrix.
|
|
105
|
+
*
|
|
106
|
+
* @private
|
|
107
|
+
* @type {UniformNode<mat4>}
|
|
108
|
+
*/
|
|
109
|
+
this._cameraWorldMatrix = uniform( new Matrix4() );
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* A uniform node holding the camera projection matrix inverse.
|
|
113
|
+
*
|
|
114
|
+
* @private
|
|
115
|
+
* @type {UniformNode<mat4>}
|
|
116
|
+
*/
|
|
117
|
+
this._cameraProjectionMatrixInverse = uniform( new Matrix4() );
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* A uniform node holding the previous frame's view matrix.
|
|
121
|
+
*
|
|
122
|
+
* @private
|
|
123
|
+
* @type {UniformNode<mat4>}
|
|
124
|
+
*/
|
|
125
|
+
this._previousCameraWorldMatrix = uniform( new Matrix4() );
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* A uniform node holding the previous frame's projection matrix inverse.
|
|
129
|
+
*
|
|
130
|
+
* @private
|
|
131
|
+
* @type {UniformNode<mat4>}
|
|
132
|
+
*/
|
|
133
|
+
this._previousCameraProjectionMatrixInverse = uniform( new Matrix4() );
|
|
134
|
+
|
|
103
135
|
/**
|
|
104
136
|
* The render target that represents the history of frame data.
|
|
105
137
|
*
|
|
106
138
|
* @private
|
|
107
139
|
* @type {?RenderTarget}
|
|
108
140
|
*/
|
|
109
|
-
this._historyRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
|
|
141
|
+
this._historyRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType, depthTexture: new DepthTexture() } );
|
|
110
142
|
this._historyRenderTarget.texture.name = 'TRAANode.history';
|
|
111
143
|
|
|
112
144
|
/**
|
|
@@ -143,6 +175,14 @@ class TRAANode extends TempNode {
|
|
|
143
175
|
*/
|
|
144
176
|
this._originalProjectionMatrix = new Matrix4();
|
|
145
177
|
|
|
178
|
+
/**
|
|
179
|
+
* A texture node for the previous depth buffer.
|
|
180
|
+
*
|
|
181
|
+
* @private
|
|
182
|
+
* @type {TextureNode}
|
|
183
|
+
*/
|
|
184
|
+
this._previousDepthNode = texture( new DepthTexture( 1, 1 ) );
|
|
185
|
+
|
|
146
186
|
/**
|
|
147
187
|
* Sync the post processing stack with the TRAA node.
|
|
148
188
|
* @private
|
|
@@ -246,6 +286,16 @@ class TRAANode extends TempNode {
|
|
|
246
286
|
|
|
247
287
|
const { renderer } = frame;
|
|
248
288
|
|
|
289
|
+
// store previous frame matrices before updating current ones
|
|
290
|
+
|
|
291
|
+
this._previousCameraWorldMatrix.value.copy( this._cameraWorldMatrix.value );
|
|
292
|
+
this._previousCameraProjectionMatrixInverse.value.copy( this._cameraProjectionMatrixInverse.value );
|
|
293
|
+
|
|
294
|
+
// update camera matrices uniforms
|
|
295
|
+
|
|
296
|
+
this._cameraWorldMatrix.value.copy( this.camera.matrixWorld );
|
|
297
|
+
this._cameraProjectionMatrixInverse.value.copy( this.camera.projectionMatrixInverse );
|
|
298
|
+
|
|
249
299
|
// keep the TRAA in sync with the dimensions of the beauty node
|
|
250
300
|
|
|
251
301
|
const beautyRenderTarget = ( this.beautyNode.isRTTNode ) ? this.beautyNode.renderTarget : this.beautyNode.passNode.renderTarget;
|
|
@@ -293,6 +343,7 @@ class TRAANode extends TempNode {
|
|
|
293
343
|
|
|
294
344
|
renderer.setRenderTarget( this._resolveRenderTarget );
|
|
295
345
|
_quadMesh.material = this._resolveMaterial;
|
|
346
|
+
_quadMesh.name = 'TRAA';
|
|
296
347
|
_quadMesh.render( renderer );
|
|
297
348
|
renderer.setRenderTarget( null );
|
|
298
349
|
|
|
@@ -300,6 +351,23 @@ class TRAANode extends TempNode {
|
|
|
300
351
|
|
|
301
352
|
renderer.copyTextureToTexture( this._resolveRenderTarget.texture, this._historyRenderTarget.texture );
|
|
302
353
|
|
|
354
|
+
// Copy current depth to previous depth buffer
|
|
355
|
+
|
|
356
|
+
const size = renderer.getDrawingBufferSize( _size );
|
|
357
|
+
|
|
358
|
+
// only allow the depth copy if the dimensions of the history render target match with the drawing
|
|
359
|
+
// render buffer and thus the depth texture of the scene. For some reasons, there are timing issues
|
|
360
|
+
// with WebGPU resulting in different size of the drawing buffer and the beauty render target when
|
|
361
|
+
// resizing the browser window. This does not happen with the WebGL backend
|
|
362
|
+
|
|
363
|
+
if ( this._historyRenderTarget.height === size.height && this._historyRenderTarget.width === size.width ) {
|
|
364
|
+
|
|
365
|
+
const currentDepth = this.depthNode.value;
|
|
366
|
+
renderer.copyTextureToTexture( currentDepth, this._historyRenderTarget.depthTexture );
|
|
367
|
+
this._previousDepthNode.value = this._historyRenderTarget.depthTexture;
|
|
368
|
+
|
|
369
|
+
}
|
|
370
|
+
|
|
303
371
|
// restore
|
|
304
372
|
|
|
305
373
|
RendererUtils.restoreRendererState( renderer, _rendererState );
|
|
@@ -347,6 +415,7 @@ class TRAANode extends TempNode {
|
|
|
347
415
|
const minColor = vec4( 10000 ).toVar();
|
|
348
416
|
const maxColor = vec4( - 10000 ).toVar();
|
|
349
417
|
const closestDepth = float( 1 ).toVar();
|
|
418
|
+
const farthestDepth = float( 0 ).toVar();
|
|
350
419
|
const closestDepthPixelPosition = vec2( 0 ).toVar();
|
|
351
420
|
|
|
352
421
|
// sample a 3x3 neighborhood to create a box in color space
|
|
@@ -373,6 +442,14 @@ class TRAANode extends TempNode {
|
|
|
373
442
|
|
|
374
443
|
} );
|
|
375
444
|
|
|
445
|
+
// find the farthest depth in the neighborhood (used to preserve edge anti-aliasing)
|
|
446
|
+
|
|
447
|
+
If( currentDepth.greaterThan( farthestDepth ), () => {
|
|
448
|
+
|
|
449
|
+
farthestDepth.assign( currentDepth );
|
|
450
|
+
|
|
451
|
+
} );
|
|
452
|
+
|
|
376
453
|
} );
|
|
377
454
|
|
|
378
455
|
} );
|
|
@@ -388,11 +465,49 @@ class TRAANode extends TempNode {
|
|
|
388
465
|
|
|
389
466
|
const clampedHistoryColor = clamp( historyColor, minColor, maxColor );
|
|
390
467
|
|
|
391
|
-
//
|
|
468
|
+
// calculate current frame world position
|
|
469
|
+
|
|
470
|
+
const currentDepth = depthTexture.sample( uvNode ).r;
|
|
471
|
+
const currentViewPosition = getViewPosition( uvNode, currentDepth, this._cameraProjectionMatrixInverse );
|
|
472
|
+
const currentWorldPosition = this._cameraWorldMatrix.mul( vec4( currentViewPosition, 1.0 ) ).xyz;
|
|
392
473
|
|
|
393
|
-
|
|
474
|
+
// calculate previous frame world position from history UV and previous depth
|
|
475
|
+
|
|
476
|
+
const historyUV = uvNode.sub( offset );
|
|
477
|
+
const previousDepth = this._previousDepthNode.sample( historyUV ).r;
|
|
478
|
+
const previousViewPosition = getViewPosition( historyUV, previousDepth, this._previousCameraProjectionMatrixInverse );
|
|
479
|
+
const previousWorldPosition = this._previousCameraWorldMatrix.mul( vec4( previousViewPosition, 1.0 ) ).xyz;
|
|
480
|
+
|
|
481
|
+
// calculate difference in world positions
|
|
482
|
+
|
|
483
|
+
const worldPositionDifference = length( currentWorldPosition.sub( previousWorldPosition ) ).toVar();
|
|
484
|
+
worldPositionDifference.assign( min( max( worldPositionDifference.sub( 1.0 ), 0.0 ), 1.0 ) );
|
|
485
|
+
|
|
486
|
+
// Adaptive blend weights based on velocity magnitude suggested by CLAUDE in #32133
|
|
487
|
+
// Higher velocity or position difference = more weight on current frame to reduce ghosting
|
|
488
|
+
|
|
489
|
+
const velocityMagnitude = length( offset ).toConst();
|
|
490
|
+
const motionFactor = max( worldPositionDifference.mul( 0.5 ), velocityMagnitude.mul( 10.0 ) ).toVar();
|
|
491
|
+
motionFactor.assign( min( motionFactor, 1.0 ) );
|
|
492
|
+
|
|
493
|
+
const currentWeight = float( 0.05 ).add( motionFactor.mul( 0.25 ) ).toVar();
|
|
394
494
|
const historyWeight = currentWeight.oneMinus().toVar();
|
|
395
495
|
|
|
496
|
+
// zero out history weight if world positions are different (indicating motion) except on edges.
|
|
497
|
+
// note that the constants 0.00001 and 0.5 were suggested by CLAUDE in #32133
|
|
498
|
+
|
|
499
|
+
const isEdge = farthestDepth.sub( closestDepth ).greaterThan( 0.00001 );
|
|
500
|
+
const strongDisocclusion = worldPositionDifference.greaterThan( 0.5 ).and( isEdge.not() );
|
|
501
|
+
|
|
502
|
+
If( strongDisocclusion, () => {
|
|
503
|
+
|
|
504
|
+
currentWeight.assign( 1.0 );
|
|
505
|
+
historyWeight.assign( 0.0 );
|
|
506
|
+
|
|
507
|
+
} );
|
|
508
|
+
|
|
509
|
+
// flicker reduction based on luminance weighing
|
|
510
|
+
|
|
396
511
|
const compressedCurrent = currentColor.mul( float( 1 ).div( ( max( currentColor.r, currentColor.g, currentColor.b ).add( 1.0 ) ) ) );
|
|
397
512
|
const compressedHistory = clampedHistoryColor.mul( float( 1 ).div( ( max( clampedHistoryColor.r, clampedHistoryColor.g, clampedHistoryColor.b ).add( 1.0 ) ) ) );
|
|
398
513
|
|
|
@@ -402,7 +517,9 @@ class TRAANode extends TempNode {
|
|
|
402
517
|
currentWeight.mulAssign( float( 1.0 ).div( luminanceCurrent.add( 1 ) ) );
|
|
403
518
|
historyWeight.mulAssign( float( 1.0 ).div( luminanceHistory.add( 1 ) ) );
|
|
404
519
|
|
|
405
|
-
|
|
520
|
+
const smoothedOutput = add( currentColor.mul( currentWeight ), clampedHistoryColor.mul( historyWeight ) ).div( max( currentWeight.add( historyWeight ), 0.00001 ) ).toVar();
|
|
521
|
+
|
|
522
|
+
return smoothedOutput;
|
|
406
523
|
|
|
407
524
|
} );
|
|
408
525
|
|