super-three 0.181.0 → 0.185.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +3 -4
- package/build/three.cjs +21332 -19201
- package/build/three.core.js +20908 -19853
- package/build/three.core.min.js +2 -2
- package/build/three.module.js +1947 -862
- package/build/three.module.min.js +2 -2
- package/build/three.tsl.js +37 -16
- package/build/three.tsl.min.js +2 -2
- package/build/three.webgpu.js +33628 -25197
- package/build/three.webgpu.min.js +2 -2
- package/build/three.webgpu.nodes.js +33394 -25000
- package/build/three.webgpu.nodes.min.js +2 -2
- package/examples/jsm/Addons.js +14 -3
- package/examples/jsm/animation/CCDIKSolver.js +7 -3
- package/examples/jsm/controls/ArcballControls.js +13 -6
- package/examples/jsm/controls/DragControls.js +2 -2
- package/examples/jsm/controls/FirstPersonControls.js +127 -86
- package/examples/jsm/controls/FlyControls.js +4 -0
- package/examples/jsm/controls/MapControls.js +55 -1
- package/examples/jsm/controls/OrbitControls.js +111 -8
- package/examples/jsm/controls/TrackballControls.js +8 -8
- package/examples/jsm/controls/TransformControls.js +102 -17
- package/examples/jsm/csm/CSM.js +2 -1
- package/examples/jsm/csm/CSMFrustum.js +31 -6
- package/examples/jsm/csm/CSMShadowNode.js +10 -3
- package/examples/jsm/effects/AnaglyphEffect.js +102 -7
- package/examples/jsm/effects/AsciiEffect.js +14 -1
- package/examples/jsm/environments/ColorEnvironment.js +59 -0
- package/examples/jsm/environments/RoomEnvironment.js +3 -0
- package/examples/jsm/exporters/DRACOExporter.js +27 -6
- package/examples/jsm/exporters/EXRExporter.js +1 -1
- package/examples/jsm/exporters/GLTFExporter.js +266 -21
- package/examples/jsm/exporters/PLYExporter.js +286 -73
- package/examples/jsm/exporters/USDZExporter.js +353 -99
- package/examples/jsm/generators/CityGenerator.js +346 -0
- package/examples/jsm/generators/ForestGenerator.js +347 -0
- package/examples/jsm/generators/TerrainGenerator.js +504 -0
- package/examples/jsm/generators/TreeGenerator.js +377 -0
- package/examples/jsm/generators/city/SidewalkGenerator.js +253 -0
- package/examples/jsm/generators/city/SkyscraperGenerator.js +1357 -0
- package/examples/jsm/geometries/DecalGeometry.js +1 -1
- package/examples/jsm/geometries/LoftGeometry.js +355 -0
- package/examples/jsm/geometries/TextGeometry.js +18 -0
- package/examples/jsm/helpers/AnimationPathHelper.js +302 -0
- package/examples/jsm/helpers/LightProbeGridHelper.js +221 -0
- package/examples/jsm/helpers/LightProbeHelper.js +5 -4
- package/examples/jsm/helpers/LightProbeHelperGPU.js +1 -1
- package/examples/jsm/helpers/TextureHelperGPU.js +1 -1
- package/examples/jsm/helpers/ViewHelper.js +83 -14
- package/examples/jsm/inspector/Extension.js +13 -0
- package/examples/jsm/inspector/Inspector.js +244 -91
- package/examples/jsm/inspector/RendererInspector.js +165 -39
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +916 -0
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +281 -0
- package/examples/jsm/inspector/tabs/Console.js +241 -25
- package/examples/jsm/inspector/tabs/Memory.js +136 -0
- package/examples/jsm/inspector/tabs/Parameters.js +115 -7
- package/examples/jsm/inspector/tabs/Performance.js +24 -9
- package/examples/jsm/inspector/tabs/Settings.js +306 -0
- package/examples/jsm/inspector/tabs/Timeline.js +1696 -0
- package/examples/jsm/inspector/tabs/Viewer.js +723 -9
- package/examples/jsm/inspector/ui/Graph.js +162 -25
- package/examples/jsm/inspector/ui/Item.js +92 -13
- package/examples/jsm/inspector/ui/List.js +2 -2
- package/examples/jsm/inspector/ui/Profiler.js +1991 -44
- package/examples/jsm/inspector/ui/Style.js +1943 -543
- package/examples/jsm/inspector/ui/Tab.js +226 -5
- package/examples/jsm/inspector/ui/Values.js +126 -8
- package/examples/jsm/inspector/ui/utils.js +143 -10
- package/examples/jsm/interaction/InteractionManager.js +226 -0
- package/examples/jsm/libs/basis/README.md +0 -1
- package/examples/jsm/libs/demuxer_mp4.js +3 -3
- package/examples/jsm/libs/draco/README.md +0 -1
- package/examples/jsm/libs/meshopt_clusterizer.module.js +421 -0
- package/examples/jsm/libs/meshopt_decoder.module.js +9 -8
- package/examples/jsm/libs/meshopt_simplifier.module.js +627 -0
- package/examples/jsm/libs/mikktspace.module.js +34 -9
- package/examples/jsm/lighting/ClusteredLighting.js +55 -0
- package/examples/jsm/lighting/DynamicLighting.js +82 -0
- package/examples/jsm/lighting/LightProbeGrid.js +681 -0
- package/examples/jsm/lines/LineMaterial.js +45 -16
- package/examples/jsm/lines/LineSegments2.js +8 -0
- package/examples/jsm/lines/webgpu/LineSegments2.js +8 -0
- package/examples/jsm/loaders/3DMLoader.js +6 -5
- package/examples/jsm/loaders/3MFLoader.js +2 -2
- package/examples/jsm/loaders/AMFLoader.js +2 -2
- package/examples/jsm/loaders/ColladaLoader.js +24 -4026
- package/examples/jsm/loaders/DRACOLoader.js +51 -18
- package/examples/jsm/loaders/EXRLoader.js +701 -90
- package/examples/jsm/loaders/FBXLoader.js +235 -37
- package/examples/jsm/loaders/GCodeLoader.js +34 -8
- package/examples/jsm/loaders/GLTFLoader.js +146 -178
- package/examples/jsm/loaders/HDRLoader.js +7 -30
- package/examples/jsm/loaders/KMZLoader.js +5 -5
- package/examples/jsm/loaders/KTX2Loader.js +58 -17
- package/examples/jsm/loaders/LDrawLoader.js +49 -58
- package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
- package/examples/jsm/loaders/LUTCubeLoader.js +2 -2
- package/examples/jsm/loaders/LWOLoader.js +11 -39
- package/examples/jsm/loaders/LottieLoader.js +1 -1
- package/examples/jsm/loaders/MaterialXLoader.js +31 -9
- package/examples/jsm/loaders/NRRDLoader.js +5 -5
- package/examples/jsm/loaders/PCDLoader.js +11 -9
- package/examples/jsm/loaders/PLYLoader.js +218 -55
- package/examples/jsm/loaders/SVGLoader.js +549 -497
- package/examples/jsm/loaders/TDSLoader.js +0 -2
- package/examples/jsm/loaders/TGALoader.js +0 -2
- package/examples/jsm/loaders/TTFLoader.js +1 -1
- package/examples/jsm/loaders/USDLoader.js +127 -43
- package/examples/jsm/loaders/UltraHDRLoader.js +285 -160
- package/examples/jsm/loaders/VOXLoader.js +660 -117
- package/examples/jsm/loaders/VRMLLoader.js +80 -3
- package/examples/jsm/loaders/VTKLoader.js +42 -25
- package/examples/jsm/loaders/collada/ColladaComposer.js +3044 -0
- package/examples/jsm/loaders/collada/ColladaParser.js +1977 -0
- package/examples/jsm/loaders/usd/USDAParser.js +504 -344
- package/examples/jsm/loaders/usd/USDCParser.js +1867 -6
- package/examples/jsm/loaders/usd/USDComposer.js +4627 -0
- package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +2 -2
- package/examples/jsm/materials/WoodNodeMaterial.js +11 -11
- package/examples/jsm/math/Octree.js +131 -1
- package/examples/jsm/misc/GPUComputationRenderer.js +2 -0
- package/examples/jsm/misc/RollerCoaster.js +42 -4
- package/examples/jsm/misc/TileCreasedNormalsPlugin.js +270 -0
- package/examples/jsm/misc/Volume.js +2 -3
- package/examples/jsm/misc/VolumeSlice.js +0 -1
- package/examples/jsm/modifiers/TessellateModifier.js +1 -1
- package/examples/jsm/objects/GroundedSkybox.js +1 -1
- package/examples/jsm/objects/LensflareMesh.js +1 -1
- package/examples/jsm/objects/Reflector.js +72 -25
- package/examples/jsm/objects/Sky.js +90 -6
- package/examples/jsm/objects/SkyMesh.js +150 -16
- package/examples/jsm/objects/Water.js +4 -3
- package/examples/jsm/objects/Water2.js +5 -3
- package/examples/jsm/objects/Water2Mesh.js +1 -1
- package/examples/jsm/objects/WaterMesh.js +5 -7
- package/examples/jsm/physics/AmmoPhysics.js +27 -15
- package/examples/jsm/physics/JoltPhysics.js +10 -6
- package/examples/jsm/physics/RapierPhysics.js +36 -7
- package/examples/jsm/postprocessing/EffectComposer.js +7 -5
- package/examples/jsm/postprocessing/OutputPass.js +9 -0
- package/examples/jsm/postprocessing/RenderPass.js +10 -0
- package/examples/jsm/postprocessing/RenderTransitionPass.js +1 -1
- package/examples/jsm/postprocessing/UnrealBloomPass.js +48 -18
- package/examples/jsm/renderers/CSS3DRenderer.js +1 -1
- package/examples/jsm/renderers/Projector.js +246 -28
- package/examples/jsm/renderers/SVGRenderer.js +174 -60
- package/examples/jsm/shaders/GTAOShader.js +19 -6
- package/examples/jsm/shaders/HalftoneShader.js +12 -1
- package/examples/jsm/shaders/PoissonDenoiseShader.js +6 -2
- package/examples/jsm/shaders/SAOShader.js +17 -4
- package/examples/jsm/shaders/SSAOShader.js +11 -1
- package/examples/jsm/shaders/SSRShader.js +6 -5
- package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -4
- package/examples/jsm/shaders/VignetteShader.js +1 -1
- package/examples/jsm/shaders/VolumeShader.js +31 -44
- package/examples/jsm/transpiler/AST.js +44 -0
- package/examples/jsm/transpiler/GLSLDecoder.js +65 -8
- package/examples/jsm/transpiler/Linker.js +1 -1
- package/examples/jsm/transpiler/ShaderToyDecoder.js +2 -0
- package/examples/jsm/transpiler/TSLEncoder.js +46 -3
- package/examples/jsm/transpiler/TranspilerUtils.js +3 -3
- package/examples/jsm/transpiler/WGSLEncoder.js +27 -0
- package/examples/jsm/tsl/WebGLNodesHandler.js +605 -0
- package/examples/jsm/tsl/display/AfterImageNode.js +11 -1
- package/examples/jsm/tsl/display/AnaglyphPassNode.js +458 -16
- package/examples/jsm/tsl/display/BilateralBlurNode.js +374 -0
- package/examples/jsm/tsl/display/BloomNode.js +75 -25
- package/examples/jsm/tsl/display/CRT.js +150 -0
- package/examples/jsm/tsl/display/ChromaticAberrationNode.js +3 -36
- package/examples/jsm/tsl/display/DenoiseNode.js +1 -1
- package/examples/jsm/tsl/display/DepthOfFieldNode.js +3 -3
- package/examples/jsm/tsl/display/DotScreenNode.js +1 -1
- package/examples/jsm/tsl/display/FSR1Node.js +477 -0
- package/examples/jsm/tsl/display/FXAANode.js +13 -14
- package/examples/jsm/tsl/display/GTAONode.js +40 -17
- package/examples/jsm/tsl/display/GaussianBlurNode.js +21 -2
- package/examples/jsm/tsl/display/GodraysNode.js +615 -0
- package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +560 -0
- package/examples/jsm/tsl/display/LensflareNode.js +1 -1
- package/examples/jsm/tsl/display/Lut3DNode.js +1 -1
- package/examples/jsm/tsl/display/OutlineNode.js +69 -19
- package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +2 -2
- package/examples/jsm/tsl/display/PixelationPassNode.js +9 -8
- package/examples/jsm/tsl/display/RGBShiftNode.js +2 -2
- package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +912 -0
- package/examples/jsm/tsl/display/RetroPassNode.js +263 -0
- package/examples/jsm/tsl/display/SMAANode.js +2 -2
- package/examples/jsm/tsl/display/SSAAPassNode.js +15 -27
- package/examples/jsm/tsl/display/SSGINode.js +96 -62
- package/examples/jsm/tsl/display/SSRNode.js +831 -134
- package/examples/jsm/tsl/display/SSSNode.js +8 -6
- package/examples/jsm/tsl/display/Shape.js +29 -0
- package/examples/jsm/tsl/display/SharpenNode.js +283 -0
- package/examples/jsm/tsl/display/SobelOperatorNode.js +2 -2
- package/examples/jsm/tsl/display/StereoCompositePassNode.js +8 -1
- package/examples/jsm/tsl/display/StereoPassNode.js +1 -2
- package/examples/jsm/tsl/display/TAAUNode.js +835 -0
- package/examples/jsm/tsl/display/TRAANode.js +315 -126
- package/examples/jsm/tsl/display/TemporalReprojectNode.js +1023 -0
- package/examples/jsm/tsl/display/TransitionNode.js +1 -1
- package/examples/jsm/tsl/display/depthAwareBlend.js +80 -0
- package/examples/jsm/tsl/display/radialBlur.js +68 -0
- package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +622 -0
- package/examples/jsm/tsl/lighting/DynamicLightsNode.js +300 -0
- package/examples/jsm/tsl/lighting/data/AmbientLightDataNode.js +61 -0
- package/examples/jsm/tsl/lighting/data/DirectionalLightDataNode.js +111 -0
- package/examples/jsm/tsl/lighting/data/HemisphereLightDataNode.js +99 -0
- package/examples/jsm/tsl/lighting/data/PointLightDataNode.js +134 -0
- package/examples/jsm/tsl/lighting/data/SpotLightDataNode.js +161 -0
- package/examples/jsm/tsl/math/Bayer.js +53 -3
- package/examples/jsm/tsl/math/curlNoise.js +107 -0
- package/examples/jsm/tsl/shadows/TileShadowNode.js +1 -1
- package/examples/jsm/tsl/shadows/TileShadowNodeHelper.js +3 -3
- package/examples/jsm/tsl/utils/GroundedSkybox.js +62 -0
- package/examples/jsm/tsl/utils/RNoise.js +51 -0
- package/examples/jsm/tsl/utils/SpecularHelpers.js +325 -0
- package/examples/jsm/utils/BufferGeometryUtils.js +128 -62
- package/examples/jsm/utils/ColorUtils.js +76 -0
- package/examples/jsm/utils/GeometryCompressionUtils.js +1 -1
- package/examples/jsm/utils/LDrawUtils.js +1 -1
- package/examples/jsm/utils/SceneOptimizer.js +1 -1
- package/examples/jsm/utils/ShadowMapViewer.js +24 -10
- package/examples/jsm/utils/ShadowMapViewerGPU.js +1 -1
- package/examples/jsm/utils/SkeletonUtils.js +14 -8
- package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
- package/examples/jsm/webxr/ARButton.js +1 -1
- package/examples/jsm/webxr/WebGLXRFallback.js +89 -0
- package/examples/jsm/webxr/XRControllerModelFactory.js +2 -2
- package/examples/jsm/webxr/XRHandMeshModel.js +36 -10
- package/examples/jsm/webxr/XRHandModelFactory.js +2 -1
- package/package.json +28 -34
- package/src/Three.Core.js +3 -1
- package/src/Three.TSL.js +35 -14
- package/src/Three.WebGPU.Nodes.js +5 -0
- package/src/Three.WebGPU.js +13 -0
- package/src/Three.js +1 -0
- package/src/animation/AnimationAction.js +18 -4
- package/src/animation/AnimationClip.js +0 -139
- package/src/animation/AnimationMixer.js +6 -0
- package/src/animation/AnimationUtils.js +1 -12
- package/src/animation/KeyframeTrack.js +47 -8
- package/src/animation/PropertyBinding.js +2 -2
- package/src/animation/PropertyMixer.js +4 -4
- package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
- package/src/animation/tracks/ColorKeyframeTrack.js +1 -1
- package/src/animation/tracks/NumberKeyframeTrack.js +1 -1
- package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -1
- package/src/animation/tracks/StringKeyframeTrack.js +1 -1
- package/src/animation/tracks/VectorKeyframeTrack.js +1 -1
- package/src/audio/Audio.js +1 -1
- package/src/audio/AudioContext.js +2 -2
- package/src/audio/AudioListener.js +5 -3
- package/src/cameras/Camera.js +34 -4
- package/src/cameras/CubeCamera.js +20 -0
- package/src/cameras/StereoCamera.js +5 -2
- package/src/constants.js +90 -5
- package/src/core/BufferAttribute.js +13 -1
- package/src/core/BufferGeometry.js +43 -9
- package/src/core/Clock.js +7 -0
- package/src/core/Object3D.js +69 -11
- package/src/core/Raycaster.js +3 -3
- package/src/core/RenderTarget.js +19 -6
- package/src/extras/PMREMGenerator.js +13 -22
- package/src/extras/TextureUtils.js +6 -2
- package/src/extras/core/ShapePath.js +149 -160
- package/src/extras/curves/CatmullRomCurve3.js +3 -2
- package/src/geometries/ExtrudeGeometry.js +2 -2
- package/src/geometries/PolyhedronGeometry.js +1 -1
- package/src/geometries/SphereGeometry.js +8 -3
- package/src/geometries/TorusGeometry.js +8 -3
- package/src/helpers/CameraHelper.js +3 -0
- package/src/helpers/DirectionalLightHelper.js +6 -1
- package/src/helpers/HemisphereLightHelper.js +5 -0
- package/src/helpers/PointLightHelper.js +3 -25
- package/src/helpers/SpotLightHelper.js +4 -1
- package/src/lights/DirectionalLight.js +13 -0
- package/src/lights/HemisphereLight.js +10 -0
- package/src/lights/Light.js +1 -11
- package/src/lights/LightProbe.js +0 -15
- package/src/lights/LightShadow.js +15 -6
- package/src/lights/PointLight.js +15 -0
- package/src/lights/PointLightShadow.js +0 -86
- package/src/lights/SpotLight.js +22 -1
- package/src/lights/webgpu/IESSpotLight.js +2 -1
- package/src/loaders/AudioLoader.js +11 -1
- package/src/loaders/Cache.js +28 -0
- package/src/loaders/DataTextureLoader.js +75 -42
- package/src/loaders/FileLoader.js +2 -3
- package/src/loaders/ImageBitmapLoader.js +12 -9
- package/src/loaders/Loader.js +6 -0
- package/src/loaders/LoadingManager.js +5 -0
- package/src/loaders/MaterialLoader.js +37 -266
- package/src/loaders/ObjectLoader.js +48 -6
- package/src/loaders/nodes/NodeLoader.js +2 -2
- package/src/loaders/nodes/NodeObjectLoader.js +18 -0
- package/src/materials/LineBasicMaterial.js +4 -0
- package/src/materials/Material.js +198 -1
- package/src/materials/MeshBasicMaterial.js +24 -0
- package/src/materials/MeshDepthMaterial.js +10 -0
- package/src/materials/MeshDistanceMaterial.js +10 -0
- package/src/materials/MeshLambertMaterial.js +49 -1
- package/src/materials/MeshMatcapMaterial.js +25 -1
- package/src/materials/MeshNormalMaterial.js +9 -1
- package/src/materials/MeshPhongMaterial.js +49 -1
- package/src/materials/MeshPhysicalMaterial.js +38 -0
- package/src/materials/MeshStandardMaterial.js +42 -1
- package/src/materials/MeshToonMaterial.js +35 -2
- package/src/materials/PointsMaterial.js +7 -0
- package/src/materials/ShaderMaterial.js +106 -1
- package/src/materials/SpriteMaterial.js +7 -0
- package/src/materials/nodes/Line2NodeMaterial.js +380 -297
- package/src/materials/nodes/MeshBasicNodeMaterial.js +2 -2
- package/src/materials/nodes/MeshNormalNodeMaterial.js +2 -2
- package/src/materials/nodes/MeshPhongNodeMaterial.js +0 -9
- package/src/materials/nodes/MeshPhysicalNodeMaterial.js +3 -30
- package/src/materials/nodes/MeshSSSNodeMaterial.js +0 -13
- package/src/materials/nodes/MeshStandardNodeMaterial.js +5 -15
- package/src/materials/nodes/NodeMaterial.js +153 -89
- package/src/materials/nodes/SpriteNodeMaterial.js +0 -10
- package/src/materials/nodes/manager/NodeMaterialObserver.js +234 -100
- package/src/math/Box3.js +5 -0
- package/src/math/FrustumArray.js +103 -133
- package/src/math/Interpolant.js +1 -1
- package/src/math/Line3.js +6 -5
- package/src/math/MathUtils.js +12 -12
- package/src/math/Matrix2.js +13 -9
- package/src/math/Matrix3.js +24 -9
- package/src/math/Matrix4.js +112 -74
- package/src/math/Plane.js +4 -3
- package/src/math/Quaternion.js +3 -29
- package/src/math/Sphere.js +1 -1
- package/src/math/Triangle.js +1 -1
- package/src/math/Vector2.js +13 -9
- package/src/math/Vector3.js +17 -15
- package/src/math/Vector4.js +15 -11
- package/src/math/interpolants/BezierInterpolant.js +106 -0
- package/src/nodes/Nodes.js +86 -71
- package/src/nodes/TSL.js +15 -13
- package/src/nodes/accessors/Arrays.js +5 -5
- package/src/nodes/accessors/Batch.js +108 -0
- package/src/nodes/accessors/Bitangent.js +7 -7
- package/src/nodes/accessors/BufferAttributeNode.js +120 -17
- package/src/nodes/accessors/BufferNode.js +29 -2
- package/src/nodes/accessors/Camera.js +149 -28
- package/src/nodes/accessors/ClippingNode.js +5 -5
- package/src/nodes/accessors/CubeTextureNode.js +27 -2
- package/src/nodes/accessors/Instance.js +264 -0
- package/src/nodes/accessors/MaterialNode.js +27 -3
- package/src/nodes/accessors/MaterialProperties.js +6 -8
- package/src/nodes/accessors/MaterialReferenceNode.js +1 -2
- package/src/nodes/accessors/ModelNode.js +1 -1
- package/src/nodes/accessors/{MorphNode.js → Morph.js} +99 -112
- package/src/nodes/accessors/Normal.js +24 -24
- package/src/nodes/accessors/Object3DNode.js +1 -1
- package/src/nodes/accessors/Position.js +39 -3
- package/src/nodes/accessors/ReferenceBaseNode.js +6 -6
- package/src/nodes/accessors/ReferenceNode.js +9 -8
- package/src/nodes/accessors/ReflectVector.js +3 -3
- package/src/nodes/accessors/RendererReferenceNode.js +1 -2
- package/src/nodes/accessors/SceneProperties.js +47 -0
- package/src/nodes/accessors/Skinning.js +263 -0
- package/src/nodes/accessors/StorageBufferNode.js +16 -27
- package/src/nodes/accessors/StorageTexture3DNode.js +100 -0
- package/src/nodes/accessors/StorageTextureNode.js +74 -11
- package/src/nodes/accessors/Tangent.js +8 -18
- package/src/nodes/accessors/Texture3DNode.js +32 -35
- package/src/nodes/accessors/TextureNode.js +124 -25
- package/src/nodes/accessors/UniformArrayNode.js +6 -4
- package/src/nodes/accessors/UserDataNode.js +1 -2
- package/src/nodes/accessors/VertexColorNode.js +1 -2
- package/src/nodes/code/FunctionCallNode.js +1 -1
- package/src/nodes/code/FunctionNode.js +4 -19
- package/src/nodes/core/ArrayNode.js +21 -2
- package/src/nodes/core/AssignNode.js +3 -3
- package/src/nodes/core/AttributeNode.js +3 -3
- package/src/nodes/core/BypassNode.js +1 -1
- package/src/nodes/core/ContextNode.js +104 -5
- package/src/nodes/core/IndexNode.js +2 -1
- package/src/nodes/core/InputNode.js +1 -1
- package/src/nodes/core/InspectorNode.js +1 -1
- package/src/nodes/core/IsolateNode.js +1 -1
- package/src/nodes/core/MRTNode.js +55 -4
- package/src/nodes/core/Node.js +151 -17
- package/src/nodes/core/NodeBuilder.js +479 -101
- package/src/nodes/core/NodeError.js +28 -0
- package/src/nodes/core/NodeFrame.js +12 -4
- package/src/nodes/core/NodeUtils.js +20 -18
- package/src/nodes/core/OutputStructNode.js +13 -11
- package/src/nodes/core/OverrideContextNode.js +153 -0
- package/src/nodes/core/ParameterNode.js +4 -4
- package/src/nodes/core/PropertyNode.js +66 -4
- package/src/nodes/core/StackNode.js +91 -20
- package/src/nodes/core/StackTrace.js +139 -0
- package/src/nodes/core/StructNode.js +20 -8
- package/src/nodes/core/StructTypeNode.js +17 -23
- package/src/nodes/core/SubBuildNode.js +2 -2
- package/src/nodes/core/UniformGroupNode.js +36 -6
- package/src/nodes/core/UniformNode.js +21 -5
- package/src/nodes/core/VarNode.js +56 -23
- package/src/nodes/core/VaryingNode.js +14 -21
- package/src/nodes/display/BlendModes.js +1 -105
- package/src/nodes/display/BumpMapNode.js +6 -1
- package/src/nodes/display/ColorAdjustment.js +27 -9
- package/src/nodes/display/ColorSpaceNode.js +3 -3
- package/src/nodes/display/FrontFacingNode.js +38 -9
- package/src/nodes/display/NormalMapNode.js +41 -6
- package/src/nodes/display/PassNode.js +157 -56
- package/src/nodes/display/PremultiplyAlphaFunctions.js +39 -0
- package/src/nodes/display/RenderOutputNode.js +19 -10
- package/src/nodes/display/ScreenNode.js +4 -2
- package/src/nodes/display/ToneMappingNode.js +1 -1
- package/src/nodes/display/ToonOutlinePassNode.js +2 -2
- package/src/nodes/display/ViewportDepthNode.js +52 -4
- package/src/nodes/display/ViewportDepthTextureNode.js +11 -15
- package/src/nodes/display/ViewportTextureNode.js +39 -11
- package/src/nodes/fog/Fog.js +18 -35
- package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +3 -3
- package/src/nodes/functions/BSDF/DFGLUT.js +56 -0
- package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
- package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +2 -2
- package/src/nodes/functions/PhysicalLightingModel.js +126 -45
- package/src/nodes/functions/VolumetricLightingModel.js +40 -7
- package/src/nodes/geometry/RangeNode.js +5 -3
- package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
- package/src/nodes/gpgpu/BarrierNode.js +9 -0
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +2 -3
- package/src/nodes/gpgpu/ComputeNode.js +74 -48
- package/src/nodes/gpgpu/SubgroupFunctionNode.js +2 -2
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +5 -5
- package/src/nodes/lighting/AnalyticLightNode.js +53 -0
- package/src/nodes/lighting/EnvironmentNode.js +30 -5
- package/src/nodes/lighting/IESSpotLightNode.js +40 -2
- package/src/nodes/lighting/LightingContextNode.js +10 -2
- package/src/nodes/lighting/LightsNode.js +97 -65
- package/src/nodes/lighting/PointShadowNode.js +166 -148
- package/src/nodes/lighting/ShadowFilterNode.js +74 -117
- package/src/nodes/lighting/ShadowNode.js +149 -51
- package/src/nodes/materialx/lib/mx_noise.js +2 -2
- package/src/nodes/math/BitcastNode.js +1 -1
- package/src/nodes/math/BitcountNode.js +433 -0
- package/src/nodes/math/ConditionalNode.js +6 -6
- package/src/nodes/math/MathNode.js +115 -52
- package/src/nodes/math/OperatorNode.js +24 -23
- package/src/nodes/math/PackFloatNode.js +98 -0
- package/src/nodes/math/UnpackFloatNode.js +96 -0
- package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
- package/src/nodes/pmrem/PMREMNode.js +34 -3
- package/src/nodes/pmrem/PMREMUtils.js +9 -15
- package/src/nodes/tsl/TSLBase.js +1 -1
- package/src/nodes/tsl/TSLCore.js +99 -33
- package/src/nodes/utils/ArrayElementNode.js +14 -1
- package/src/nodes/utils/ConvertNode.js +1 -1
- package/src/nodes/utils/DebugNode.js +12 -12
- package/src/nodes/utils/EquirectUV.js +30 -5
- package/src/nodes/utils/EventNode.js +31 -2
- package/src/nodes/utils/FlipNode.js +1 -1
- package/src/nodes/utils/FunctionOverloadingNode.js +2 -2
- package/src/nodes/utils/JoinNode.js +3 -3
- package/src/nodes/utils/LoopNode.js +1 -1
- package/src/nodes/utils/MemberNode.js +2 -2
- package/src/nodes/utils/Packing.js +48 -5
- package/src/nodes/utils/PostProcessingUtils.js +33 -1
- package/src/nodes/utils/RTTNode.js +41 -25
- package/src/nodes/utils/ReflectorNode.js +4 -4
- package/src/nodes/utils/Remap.js +48 -0
- package/src/nodes/utils/RotateNode.js +1 -1
- package/src/nodes/utils/SampleNode.js +1 -1
- package/src/nodes/utils/SetNode.js +1 -1
- package/src/nodes/utils/SplitNode.js +1 -1
- package/src/nodes/utils/SpriteSheetUV.js +35 -0
- package/src/nodes/utils/StorageArrayElementNode.js +1 -1
- package/src/nodes/utils/UVUtils.js +28 -0
- package/src/objects/BatchedMesh.js +66 -30
- package/src/objects/InstancedMesh.js +19 -3
- package/src/objects/Line.js +1 -1
- package/src/objects/Mesh.js +1 -1
- package/src/objects/Points.js +1 -1
- package/src/objects/SkinnedMesh.js +26 -9
- package/src/renderers/WebGLRenderer.js +344 -156
- package/src/renderers/common/Animation.js +3 -3
- package/src/renderers/common/Attributes.js +15 -1
- package/src/renderers/common/Backend.js +78 -13
- package/src/renderers/common/Background.js +26 -13
- package/src/renderers/common/BindGroup.js +1 -16
- package/src/renderers/common/Binding.js +11 -0
- package/src/renderers/common/Bindings.js +141 -57
- package/src/renderers/common/BlendMode.js +143 -0
- package/src/renderers/common/Buffer.js +49 -0
- package/src/renderers/common/BundleGroup.js +1 -1
- package/src/renderers/common/ChainMap.js +30 -6
- package/src/renderers/common/ClippingContext.js +10 -2
- package/src/renderers/common/ComputePipeline.js +1 -1
- package/src/renderers/common/CubeRenderTarget.js +51 -7
- package/src/renderers/common/Geometries.js +29 -3
- package/src/renderers/common/Info.js +374 -4
- package/src/renderers/common/InspectorBase.js +6 -1
- package/src/renderers/common/Lighting.js +51 -19
- package/src/renderers/common/Pipelines.js +40 -7
- package/src/renderers/common/PostProcessing.js +8 -206
- package/src/renderers/common/ReadbackBuffer.js +78 -0
- package/src/renderers/common/RenderBundle.js +3 -1
- package/src/renderers/common/RenderBundles.js +7 -3
- package/src/renderers/common/RenderContext.js +16 -0
- package/src/renderers/common/RenderContexts.js +33 -49
- package/src/renderers/common/RenderList.js +41 -4
- package/src/renderers/common/RenderLists.js +2 -1
- package/src/renderers/common/RenderObject.js +88 -16
- package/src/renderers/common/RenderObjectPipeline.js +40 -0
- package/src/renderers/common/RenderObjects.js +21 -5
- package/src/renderers/common/RenderPipeline.js +232 -17
- package/src/renderers/common/Renderer.js +700 -163
- package/src/renderers/common/Sampler.js +16 -48
- package/src/renderers/common/StorageBuffer.js +13 -1
- package/src/renderers/common/Textures.js +121 -9
- package/src/renderers/common/TimestampQueryPool.js +6 -4
- package/src/renderers/common/Uniform.js +8 -0
- package/src/renderers/common/UniformsGroup.js +84 -1
- package/src/renderers/common/XRManager.js +377 -51
- package/src/renderers/common/extras/PMREMGenerator.js +40 -61
- package/src/renderers/common/nodes/NodeBuilderState.js +10 -2
- package/src/renderers/common/nodes/NodeLibrary.js +4 -4
- package/src/renderers/common/nodes/{Nodes.js → NodeManager.js} +298 -106
- package/src/renderers/common/nodes/NodeStorageBuffer.js +13 -2
- package/src/renderers/common/nodes/NodeUniformBuffer.js +65 -0
- package/src/renderers/shaders/DFGLUTData.js +19 -34
- package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk/color_fragment.glsl.js +1 -5
- package/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js +1 -5
- package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -5
- package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +8 -10
- package/src/renderers/shaders/ShaderChunk/common.glsl.js +13 -4
- package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +0 -6
- package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +0 -1
- package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +9 -13
- package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lightprobes_pars_fragment.glsl.js +80 -0
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +13 -2
- package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +6 -0
- package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +6 -2
- package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +3 -1
- package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +8 -4
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +112 -53
- package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js +7 -0
- package/src/renderers/shaders/ShaderChunk/normal_vertex.glsl.js +6 -0
- package/src/renderers/shaders/ShaderChunk/packing.glsl.js +20 -4
- package/src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl.js +0 -1
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +225 -186
- package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +12 -2
- package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk.js +5 -3
- package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +1 -2
- package/src/renderers/shaders/ShaderLib/depth.glsl.js +3 -0
- package/src/renderers/shaders/ShaderLib/{distanceRGBA.glsl.js → distance.glsl.js} +2 -3
- package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -1
- package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -2
- package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -1
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -9
- package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +0 -1
- package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/vsm.glsl.js +4 -6
- package/src/renderers/shaders/ShaderLib.js +7 -6
- package/src/renderers/shaders/UniformsLib.js +7 -5
- package/src/renderers/shaders/UniformsUtils.js +27 -5
- package/src/renderers/webgl/WebGLAnimation.js +2 -1
- package/src/renderers/webgl/WebGLBackground.js +15 -15
- package/src/renderers/webgl/WebGLBindingStates.js +99 -27
- package/src/renderers/webgl/WebGLBufferRenderer.js +0 -32
- package/src/renderers/webgl/WebGLCapabilities.js +9 -4
- package/src/renderers/webgl/WebGLEnvironments.js +228 -0
- package/src/renderers/webgl/WebGLGeometries.js +10 -7
- package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +0 -32
- package/src/renderers/webgl/WebGLLights.js +18 -1
- package/src/renderers/webgl/WebGLMaterials.js +24 -13
- package/src/renderers/webgl/WebGLObjects.js +3 -1
- package/src/renderers/webgl/WebGLOutput.js +271 -0
- package/src/renderers/webgl/WebGLProgram.js +54 -113
- package/src/renderers/webgl/WebGLPrograms.js +74 -55
- package/src/renderers/webgl/WebGLRenderLists.js +24 -1
- package/src/renderers/webgl/WebGLRenderStates.js +13 -2
- package/src/renderers/webgl/WebGLShaderCache.js +5 -11
- package/src/renderers/webgl/WebGLShadowMap.js +188 -24
- package/src/renderers/webgl/WebGLState.js +75 -37
- package/src/renderers/webgl/WebGLTextures.js +230 -56
- package/src/renderers/webgl/WebGLUniforms.js +40 -3
- package/src/renderers/webgl/WebGLUniformsGroups.js +82 -35
- package/src/renderers/webgl/WebGLUtils.js +6 -2
- package/src/renderers/webgl-fallback/WebGLBackend.js +322 -92
- package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +0 -41
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +295 -66
- package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +53 -19
- package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +25 -0
- package/src/renderers/webgl-fallback/utils/WebGLState.js +223 -6
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +118 -73
- package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +10 -10
- package/src/renderers/webgl-fallback/utils/WebGLUtils.js +9 -3
- package/src/renderers/webgpu/WebGPUBackend.js +733 -302
- package/src/renderers/webgpu/WebGPURenderer.js +2 -1
- package/src/renderers/webgpu/descriptors/GPUBindGroupDescriptor.js +48 -0
- package/src/renderers/webgpu/descriptors/GPUBufferDescriptor.js +57 -0
- package/src/renderers/webgpu/descriptors/GPUCommandEncoderDescriptor.js +30 -0
- package/src/renderers/webgpu/descriptors/GPUComputePassDescriptor.js +38 -0
- package/src/renderers/webgpu/descriptors/GPUComputePipelineDescriptor.js +48 -0
- package/src/renderers/webgpu/descriptors/GPUCopyExternalImageDestInfo.js +47 -0
- package/src/renderers/webgpu/descriptors/GPUCopyExternalImageSourceInfo.js +50 -0
- package/src/renderers/webgpu/descriptors/GPUExtent3D.js +51 -0
- package/src/renderers/webgpu/descriptors/GPUPipelineLayoutDescriptor.js +39 -0
- package/src/renderers/webgpu/descriptors/GPUQuerySetDescriptor.js +47 -0
- package/src/renderers/webgpu/descriptors/GPURenderBundleEncoderDescriptor.js +74 -0
- package/src/renderers/webgpu/descriptors/GPURenderPassColorAttachment.js +72 -0
- package/src/renderers/webgpu/descriptors/GPURenderPassDepthStencilAttachment.js +99 -0
- package/src/renderers/webgpu/descriptors/GPURenderPassDescriptor.js +72 -0
- package/src/renderers/webgpu/descriptors/GPURenderPassTimestampWrites.js +49 -0
- package/src/renderers/webgpu/descriptors/GPURenderPipelineDescriptor.js +130 -0
- package/src/renderers/webgpu/descriptors/GPUSamplerDescriptor.js +119 -0
- package/src/renderers/webgpu/descriptors/GPUShaderModuleDescriptor.js +46 -0
- package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferInfo.js +57 -0
- package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferLayout.js +48 -0
- package/src/renderers/webgpu/descriptors/GPUTexelCopyTextureInfo.js +61 -0
- package/src/renderers/webgpu/descriptors/GPUTextureDescriptor.js +99 -0
- package/src/renderers/webgpu/descriptors/GPUTextureViewDescriptor.js +108 -0
- package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +0 -1
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +526 -93
- package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +1 -1
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +194 -61
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +395 -234
- package/src/renderers/webgpu/utils/WebGPUCapabilities.js +48 -0
- package/src/renderers/webgpu/utils/WebGPUConstants.js +10 -0
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +224 -91
- package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +228 -213
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +428 -175
- package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +40 -25
- package/src/renderers/webgpu/utils/WebGPUUtils.js +70 -13
- package/src/renderers/webxr/WebXRController.js +12 -0
- package/src/renderers/webxr/WebXRManager.js +4 -2
- package/src/textures/CubeDepthTexture.js +76 -0
- package/src/textures/DepthTexture.js +1 -1
- package/src/textures/ExternalTexture.js +0 -3
- package/src/textures/HTMLTexture.js +74 -0
- package/src/textures/Source.js +2 -2
- package/src/textures/Texture.js +16 -5
- package/src/utils.js +280 -3
- package/examples/fonts/LICENSE +0 -13
- package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
- package/examples/fonts/MPLUSRounded1c/OFL.txt +0 -91
- package/examples/fonts/README.md +0 -11
- package/examples/fonts/droid/NOTICE +0 -190
- package/examples/fonts/droid/README.txt +0 -18
- package/examples/fonts/droid/droid_sans_bold.typeface.json +0 -1
- package/examples/fonts/droid/droid_sans_mono_regular.typeface.json +0 -1
- package/examples/fonts/droid/droid_sans_regular.typeface.json +0 -1
- package/examples/fonts/droid/droid_serif_bold.typeface.json +0 -1
- package/examples/fonts/droid/droid_serif_regular.typeface.json +0 -1
- package/examples/fonts/gentilis_bold.typeface.json +0 -1
- package/examples/fonts/gentilis_regular.typeface.json +0 -1
- package/examples/fonts/helvetiker_bold.typeface.json +0 -1
- package/examples/fonts/helvetiker_regular.typeface.json +0 -1
- package/examples/fonts/optimer_bold.typeface.json +0 -1
- package/examples/fonts/optimer_regular.typeface.json +0 -1
- package/examples/fonts/ttf/README.md +0 -9
- package/examples/fonts/ttf/kenpixel.ttf +0 -0
- package/examples/jsm/libs/ammo.wasm.js +0 -822
- package/examples/jsm/libs/ammo.wasm.wasm +0 -0
- package/examples/jsm/libs/draco/draco_encoder.js +0 -33
- package/examples/jsm/libs/draco/gltf/draco_encoder.js +0 -33
- package/examples/jsm/libs/lottie_canvas.module.js +0 -14849
- package/examples/jsm/libs/opentype.module.js +0 -14506
- package/examples/jsm/libs/rhino3dm/rhino3dm.js +0 -21
- package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +0 -16
- package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
- package/examples/jsm/lighting/TiledLighting.js +0 -42
- package/examples/jsm/materials/MeshGouraudMaterial.js +0 -434
- package/examples/jsm/materials/MeshPostProcessingMaterial.js +0 -167
- package/examples/jsm/shaders/GodRaysShader.js +0 -333
- package/examples/jsm/tsl/display/AnamorphicNode.js +0 -282
- package/examples/jsm/tsl/lighting/TiledLightsNode.js +0 -442
- package/src/nodes/accessors/BatchNode.js +0 -163
- package/src/nodes/accessors/InstanceNode.js +0 -244
- package/src/nodes/accessors/InstancedMeshNode.js +0 -50
- package/src/nodes/accessors/SceneNode.js +0 -145
- package/src/nodes/accessors/SkinningNode.js +0 -327
- package/src/nodes/code/ScriptableNode.js +0 -726
- package/src/nodes/code/ScriptableValueNode.js +0 -253
- package/src/nodes/display/PosterizeNode.js +0 -65
- package/src/nodes/functions/BSDF/DFGApprox.js +0 -71
- package/src/nodes/utils/RemapNode.js +0 -125
- package/src/nodes/utils/SpriteSheetUVNode.js +0 -90
- package/src/renderers/webgl/WebGLCubeMaps.js +0 -99
- package/src/renderers/webgl/WebGLCubeUVMaps.js +0 -134
|
@@ -0,0 +1,1023 @@
|
|
|
1
|
+
import { EPSILON, Fn, If, abs, convertToTexture, dFdx, dFdy, dot, exp, float, floor, fwidth, getViewPosition, ivec2, luminance, max, min, mix, nodeObject, normalize, passTexture, screenCoordinate, select, smoothstep, sqrt, struct, texture, textureLoad, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4, velocity } from 'three/tsl';
|
|
2
|
+
import { DepthTexture, HalfFloatType, Matrix4, NodeMaterial, NodeUpdateType, QuadMesh, RenderTarget, RendererUtils, TempNode, Vector2, Vector3 } from 'three/webgpu';
|
|
3
|
+
import { ENV_RAY_LENGTH, ENV_RAY_LENGTH_THRESHOLD } from '../utils/SpecularHelpers.js';
|
|
4
|
+
|
|
5
|
+
// Reprojection helpers
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Maps a resolve (screen) texel to the corresponding beauty-input texel when resolutions differ.
|
|
9
|
+
*
|
|
10
|
+
* @tsl
|
|
11
|
+
*/
|
|
12
|
+
const beautyTexelFromScreen = Fn( ( [ screenTexel, beautySize, resolveSize ] ) => {
|
|
13
|
+
|
|
14
|
+
return ivec2( floor( vec2( screenTexel ).mul( beautySize ).div( resolveSize ) ) );
|
|
15
|
+
|
|
16
|
+
} ).setLayout( {
|
|
17
|
+
name: 'beautyTexelFromScreen',
|
|
18
|
+
type: 'ivec2',
|
|
19
|
+
inputs: [
|
|
20
|
+
{ name: 'screenTexel', type: 'ivec2' },
|
|
21
|
+
{ name: 'beautySize', type: 'vec2' },
|
|
22
|
+
{ name: 'resolveSize', type: 'vec2' }
|
|
23
|
+
]
|
|
24
|
+
} );
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Projects a world-space position into previous-frame UV coordinates.
|
|
28
|
+
*
|
|
29
|
+
* @tsl
|
|
30
|
+
*/
|
|
31
|
+
const projectWorldToUV = Fn( ( [ worldPos, previousViewMatrix, previousProjectionMatrix ] ) => {
|
|
32
|
+
|
|
33
|
+
const resultUV = vec2( - 1 ).toVar();
|
|
34
|
+
const viewSpace = previousViewMatrix.mul( vec4( worldPos, 1.0 ) );
|
|
35
|
+
const clipSpace = previousProjectionMatrix.mul( viewSpace ).toVar();
|
|
36
|
+
const clipW = clipSpace.w.toVar();
|
|
37
|
+
|
|
38
|
+
If( abs( clipW ).greaterThan( float( 1e-5 ) ), () => {
|
|
39
|
+
|
|
40
|
+
const ndc = clipSpace.xyz.div( clipW );
|
|
41
|
+
resultUV.assign( ndc.xy.mul( 0.5 ).add( 0.5 ) );
|
|
42
|
+
resultUV.y.assign( resultUV.y.oneMinus() );
|
|
43
|
+
|
|
44
|
+
} );
|
|
45
|
+
|
|
46
|
+
return resultUV;
|
|
47
|
+
|
|
48
|
+
} ).setLayout( {
|
|
49
|
+
name: 'projectWorldToUV',
|
|
50
|
+
type: 'vec2',
|
|
51
|
+
inputs: [
|
|
52
|
+
{ name: 'worldPos', type: 'vec3' },
|
|
53
|
+
{ name: 'previousViewMatrix', type: 'mat4' },
|
|
54
|
+
{ name: 'previousProjectionMatrix', type: 'mat4' }
|
|
55
|
+
]
|
|
56
|
+
} );
|
|
57
|
+
|
|
58
|
+
// YCoCg variance clipping
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {Node<vec3>} c
|
|
62
|
+
* @returns {Node<vec3>}
|
|
63
|
+
*/
|
|
64
|
+
const rgbToYCoCg = ( c ) => vec3(
|
|
65
|
+
dot( c, vec3( 0.25, 0.5, 0.25 ) ),
|
|
66
|
+
dot( c, vec3( 0.5, 0.0, - 0.5 ) ),
|
|
67
|
+
dot( c, vec3( - 0.25, 0.5, - 0.25 ) )
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @param {Node<vec3>} c
|
|
72
|
+
* @returns {Node<vec3>}
|
|
73
|
+
*/
|
|
74
|
+
const ycocgToRGB = ( c ) => vec3(
|
|
75
|
+
c.x.add( c.y ).sub( c.z ),
|
|
76
|
+
c.x.add( c.z ),
|
|
77
|
+
c.x.sub( c.y ).sub( c.z )
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const VARIANCE_CLIP_LUMA_SCALE = 10;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Inverse-luminance compression for HDR variance clipping (Karis-style).
|
|
84
|
+
* Bright samples contribute less to neighbourhood moments so sun pixels do not
|
|
85
|
+
* inflate the YCoCg AABB and cause aggressive clipping flicker.
|
|
86
|
+
*
|
|
87
|
+
* @param {Node<vec3>} rgb
|
|
88
|
+
* @param {Node<float>} flickerSuppression
|
|
89
|
+
* @returns {Node<vec3>}
|
|
90
|
+
*/
|
|
91
|
+
const dampenForVarianceClip = ( rgb, flickerSuppression ) => {
|
|
92
|
+
|
|
93
|
+
const scale = luminance( rgb ).mul( flickerSuppression ).mul( VARIANCE_CLIP_LUMA_SCALE ).add( 1 );
|
|
94
|
+
return rgb.div( scale );
|
|
95
|
+
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Clips the history sample to the neighbourhood AABB by projecting it toward the box centre.
|
|
100
|
+
* Reference: https://github.com/playdeadgames/temporal
|
|
101
|
+
*
|
|
102
|
+
* @tsl
|
|
103
|
+
*/
|
|
104
|
+
const clipToAABB = Fn( ( [ history, boxMin, boxMax ] ) => {
|
|
105
|
+
|
|
106
|
+
const pClip = boxMax.add( boxMin ).mul( 0.5 );
|
|
107
|
+
const eClip = boxMax.sub( boxMin ).mul( 0.5 ).add( 1e-7 );
|
|
108
|
+
const vClip = history.sub( pClip );
|
|
109
|
+
const vUnit = vClip.div( eClip );
|
|
110
|
+
const absUnit = vUnit.abs();
|
|
111
|
+
const maxUnit = max( absUnit.x, absUnit.y, absUnit.z );
|
|
112
|
+
|
|
113
|
+
return maxUnit.greaterThan( 1 ).select( pClip.add( vClip.div( maxUnit ) ), history );
|
|
114
|
+
|
|
115
|
+
} ).setLayout( {
|
|
116
|
+
name: 'clipToAABB',
|
|
117
|
+
type: 'vec3',
|
|
118
|
+
inputs: [
|
|
119
|
+
{ name: 'history', type: 'vec3' },
|
|
120
|
+
{ name: 'boxMin', type: 'vec3' },
|
|
121
|
+
{ name: 'boxMax', type: 'vec3' }
|
|
122
|
+
]
|
|
123
|
+
} );
|
|
124
|
+
|
|
125
|
+
const neighborhoodStruct = struct( {
|
|
126
|
+
mean: 'vec3',
|
|
127
|
+
stdColor: 'vec3',
|
|
128
|
+
rayLength: 'float',
|
|
129
|
+
envProbability: 'float',
|
|
130
|
+
stdDevRayLength: 'float'
|
|
131
|
+
} );
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Single 3×3 neighbourhood pass over the beauty buffer. One textureLoad per tap feeds both the
|
|
135
|
+
* YCoCg variance-clipping box (colour) and the SSR ray-length statistics (alpha), which previously
|
|
136
|
+
* required two separate 3×3 fetches of the same texture.
|
|
137
|
+
*
|
|
138
|
+
* Sampling is done on the beauty-texel grid (`beautyTexel + offset`), so the taps are distinct
|
|
139
|
+
* source texels even when the beauty buffer is lower resolution than the resolve pass (upscaling).
|
|
140
|
+
*
|
|
141
|
+
* @tsl
|
|
142
|
+
*/
|
|
143
|
+
const collectNeighborhood = Fn( ( [ beautyTexture, beautyTexel, inputColor, flickerSuppression ] ) => {
|
|
144
|
+
|
|
145
|
+
const offsets = [
|
|
146
|
+
[ - 1, - 1 ],
|
|
147
|
+
[ - 1, 1 ],
|
|
148
|
+
[ 1, - 1 ],
|
|
149
|
+
[ 1, 1 ],
|
|
150
|
+
[ 1, 0 ],
|
|
151
|
+
[ 0, - 1 ],
|
|
152
|
+
[ 0, 1 ],
|
|
153
|
+
[ - 1, 0 ],
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
// Colour moments (YCoCg) — centre reuses the already-fetched inputColor.
|
|
157
|
+
const center = rgbToYCoCg( dampenForVarianceClip( inputColor.rgb, flickerSuppression ) );
|
|
158
|
+
const moment1 = center.toVar();
|
|
159
|
+
const moment2 = center.pow2().toVar();
|
|
160
|
+
|
|
161
|
+
// Ray-length statistics (Welford) over screen-space hits only.
|
|
162
|
+
const rayLengthSum = float( 0 ).toVar();
|
|
163
|
+
const rayLengthCount = float( 0 ).toVar();
|
|
164
|
+
const meanRayLength = float( 0 ).toVar();
|
|
165
|
+
const m2RayLength = float( 0 ).toVar();
|
|
166
|
+
|
|
167
|
+
const accumulateRayLength = ( alpha ) => {
|
|
168
|
+
|
|
169
|
+
If( alpha.lessThan( ENV_RAY_LENGTH_THRESHOLD ), () => {
|
|
170
|
+
|
|
171
|
+
rayLengthSum.addAssign( alpha );
|
|
172
|
+
rayLengthCount.addAssign( 1 );
|
|
173
|
+
|
|
174
|
+
const delta = alpha.sub( meanRayLength ).toVar();
|
|
175
|
+
meanRayLength.addAssign( delta.div( rayLengthCount ) );
|
|
176
|
+
m2RayLength.addAssign( delta.mul( alpha.sub( meanRayLength ) ) );
|
|
177
|
+
|
|
178
|
+
} );
|
|
179
|
+
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
accumulateRayLength( inputColor.a );
|
|
183
|
+
|
|
184
|
+
for ( const [ x, y ] of offsets ) {
|
|
185
|
+
|
|
186
|
+
const neighbor = textureLoad( beautyTexture, beautyTexel.add( ivec2( x, y ) ) ).max( 0 ).toVar();
|
|
187
|
+
|
|
188
|
+
const c = rgbToYCoCg( dampenForVarianceClip( neighbor.rgb, flickerSuppression ) );
|
|
189
|
+
moment1.addAssign( c );
|
|
190
|
+
moment2.addAssign( c.pow2() );
|
|
191
|
+
|
|
192
|
+
accumulateRayLength( neighbor.a );
|
|
193
|
+
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const N = float( offsets.length + 1 );
|
|
197
|
+
const mean = moment1.div( N );
|
|
198
|
+
const stdColor = moment2.div( N ).sub( mean.pow2() ).max( 0 ).sqrt();
|
|
199
|
+
|
|
200
|
+
// Continuous environment probability: fraction of the 3×3 neighbourhood that missed in screen space
|
|
201
|
+
// and fell back to env (0 = all hits, 1 = all env), for smooth reflection/environment transitions.
|
|
202
|
+
const envProbability = rayLengthCount.div( float( 9 ) ).oneMinus();
|
|
203
|
+
const rayLength = rayLengthCount.lessThan( 0.5 ).select( float( ENV_RAY_LENGTH ), rayLengthSum.div( max( rayLengthCount, float( 1e-4 ) ) ) );
|
|
204
|
+
const stdDevRayLength = sqrt( m2RayLength.div( max( rayLengthCount, float( 1.0 ) ) ) ).max( 1e-3 );
|
|
205
|
+
|
|
206
|
+
return neighborhoodStruct( mean, stdColor, rayLength, envProbability, stdDevRayLength );
|
|
207
|
+
|
|
208
|
+
} );
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Variance clipping in YCoCg space (Salvi, GDC 2016). Uses the colour moments gathered by
|
|
212
|
+
* {@link collectNeighborhood}; `gamma` widens the AABB and is kept out of the gather so the
|
|
213
|
+
* neighbourhood pass stays independent of the per-pixel motion factor.
|
|
214
|
+
*
|
|
215
|
+
* @tsl
|
|
216
|
+
*/
|
|
217
|
+
const applyVarianceClipping = Fn( ( [ historyColor, mean, stdColor, gamma, flickerSuppression ] ) => {
|
|
218
|
+
|
|
219
|
+
const stddev = stdColor.mul( gamma );
|
|
220
|
+
const boxMin = mean.sub( stddev );
|
|
221
|
+
const boxMax = mean.add( stddev );
|
|
222
|
+
|
|
223
|
+
const historyRGB = historyColor.rgb.toVar();
|
|
224
|
+
const historyScale = luminance( historyRGB ).mul( flickerSuppression ).mul( VARIANCE_CLIP_LUMA_SCALE ).add( 1 );
|
|
225
|
+
const clipped = clipToAABB( rgbToYCoCg( historyRGB.div( historyScale ) ), boxMin, boxMax );
|
|
226
|
+
|
|
227
|
+
return ycocgToRGB( clipped ).mul( historyScale );
|
|
228
|
+
|
|
229
|
+
} );
|
|
230
|
+
|
|
231
|
+
// History sampling
|
|
232
|
+
|
|
233
|
+
const bilinearTapStruct = struct( { color: 'vec4', weight: 'float', confidence: 'float' } );
|
|
234
|
+
const historyResultStruct = struct( { color: 'vec4', tapConfidence: 'float', minConfidence: 'float' } );
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Single bilinear history tap with plane-distance and normal confidence.
|
|
238
|
+
*
|
|
239
|
+
* @tsl
|
|
240
|
+
*/
|
|
241
|
+
const sampleBilinearTap = Fn( ( [
|
|
242
|
+
historyTexture,
|
|
243
|
+
previousDepthNode,
|
|
244
|
+
previousNormalNode,
|
|
245
|
+
resolution,
|
|
246
|
+
previousProjectionMatrixInverse,
|
|
247
|
+
previousCameraWorldMatrix,
|
|
248
|
+
previousCameraViewMatrix,
|
|
249
|
+
tapCoord,
|
|
250
|
+
bilinearWeight,
|
|
251
|
+
worldPosition,
|
|
252
|
+
worldNormal
|
|
253
|
+
] ) => {
|
|
254
|
+
|
|
255
|
+
const color = textureLoad( historyTexture, tapCoord ).max( 0 );
|
|
256
|
+
const reprojDepth = textureLoad( previousDepthNode, tapCoord ).r;
|
|
257
|
+
const reprojViewPos = getViewPosition( vec2( tapCoord ).add( 0.5 ).div( resolution ), reprojDepth, previousProjectionMatrixInverse );
|
|
258
|
+
const reprojWorldPos = previousCameraWorldMatrix.mul( vec4( reprojViewPos, 1.0 ) ).xyz;
|
|
259
|
+
const reprojWorldNorm = unpackRGBToNormal( textureLoad( previousNormalNode, tapCoord ).rgb ).transformDirection( previousCameraViewMatrix );
|
|
260
|
+
|
|
261
|
+
const planeDiff = abs( dot( reprojWorldPos.sub( worldPosition ), worldNormal ) ).toVar();
|
|
262
|
+
planeDiff.divAssign( abs( reprojViewPos.z ) );
|
|
263
|
+
const normalConfidence = smoothstep( 0.95, 0.999, reprojWorldNorm.dot( worldNormal ) );
|
|
264
|
+
const confidence = smoothstep( 0, 0.01, planeDiff ).oneMinus().mul( normalConfidence );
|
|
265
|
+
const weight = bilinearWeight.mul( confidence );
|
|
266
|
+
|
|
267
|
+
return bilinearTapStruct( color.mul( weight ), weight, confidence );
|
|
268
|
+
|
|
269
|
+
} );
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* @param {Object} ctx - Shared {@link sampleBilinearTap} inputs plus `reprojICoord`.
|
|
273
|
+
* @param {Node<ivec2>} tapOffset
|
|
274
|
+
* @param {Node<float>} bilinearWeight
|
|
275
|
+
*/
|
|
276
|
+
function bilinearHistoryTap( ctx, tapOffset, bilinearWeight ) {
|
|
277
|
+
|
|
278
|
+
return sampleBilinearTap(
|
|
279
|
+
ctx.historyTexture,
|
|
280
|
+
ctx.previousDepthNode,
|
|
281
|
+
ctx.previousNormalNode,
|
|
282
|
+
ctx.resolution,
|
|
283
|
+
ctx.previousProjectionMatrixInverse,
|
|
284
|
+
ctx.previousCameraWorldMatrix,
|
|
285
|
+
ctx.previousCameraViewMatrix,
|
|
286
|
+
ctx.reprojICoord.add( tapOffset ),
|
|
287
|
+
bilinearWeight,
|
|
288
|
+
ctx.worldPosition,
|
|
289
|
+
ctx.worldNormal
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Geometrically-weighted 4-tap bilinear history sample.
|
|
296
|
+
*
|
|
297
|
+
* @tsl
|
|
298
|
+
*/
|
|
299
|
+
const sampleHistory4Tap = Fn( ( [
|
|
300
|
+
historyTexture,
|
|
301
|
+
previousDepthNode,
|
|
302
|
+
previousNormalNode,
|
|
303
|
+
resolution,
|
|
304
|
+
previousProjectionMatrixInverse,
|
|
305
|
+
previousCameraWorldMatrix,
|
|
306
|
+
previousCameraViewMatrix,
|
|
307
|
+
reprojUV,
|
|
308
|
+
worldPosition,
|
|
309
|
+
worldNormal,
|
|
310
|
+
inputColor
|
|
311
|
+
] ) => {
|
|
312
|
+
|
|
313
|
+
const reprojPixelCoord = reprojUV.mul( resolution ).sub( 0.5 ).toVar();
|
|
314
|
+
const reprojICoord = ivec2( floor( reprojPixelCoord ) );
|
|
315
|
+
const fCoord = reprojPixelCoord.fract();
|
|
316
|
+
|
|
317
|
+
const fx = fCoord.x;
|
|
318
|
+
const fy = fCoord.y;
|
|
319
|
+
const f00 = float( 1 ).sub( fx ).mul( float( 1 ).sub( fy ) );
|
|
320
|
+
const f10 = fx.mul( float( 1 ).sub( fy ) );
|
|
321
|
+
const f01 = float( 1 ).sub( fx ).mul( fy );
|
|
322
|
+
const f11 = fx.mul( fy );
|
|
323
|
+
|
|
324
|
+
const tapCtx = {
|
|
325
|
+
historyTexture,
|
|
326
|
+
previousDepthNode,
|
|
327
|
+
previousNormalNode,
|
|
328
|
+
resolution,
|
|
329
|
+
previousProjectionMatrixInverse,
|
|
330
|
+
previousCameraWorldMatrix,
|
|
331
|
+
previousCameraViewMatrix,
|
|
332
|
+
reprojICoord,
|
|
333
|
+
worldPosition,
|
|
334
|
+
worldNormal
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
const tap00 = bilinearHistoryTap( tapCtx, ivec2( 0, 0 ), f00 );
|
|
338
|
+
const tap10 = bilinearHistoryTap( tapCtx, ivec2( 1, 0 ), f10 );
|
|
339
|
+
const tap01 = bilinearHistoryTap( tapCtx, ivec2( 0, 1 ), f01 );
|
|
340
|
+
const tap11 = bilinearHistoryTap( tapCtx, ivec2( 1, 1 ), f11 );
|
|
341
|
+
|
|
342
|
+
const colorSum = tap00.get( 'color' ).add( tap10.get( 'color' ) ).add( tap01.get( 'color' ) ).add( tap11.get( 'color' ) );
|
|
343
|
+
const weightSum = tap00.get( 'weight' ).add( tap10.get( 'weight' ) ).add( tap01.get( 'weight' ) ).add( tap11.get( 'weight' ) );
|
|
344
|
+
const maxConf = max( max( tap00.get( 'confidence' ), tap10.get( 'confidence' ) ), max( tap01.get( 'confidence' ), tap11.get( 'confidence' ) ) );
|
|
345
|
+
const minConf = min( min( tap00.get( 'confidence' ), tap10.get( 'confidence' ) ), min( tap01.get( 'confidence' ), tap11.get( 'confidence' ) ) );
|
|
346
|
+
|
|
347
|
+
return historyResultStruct(
|
|
348
|
+
select( weightSum.greaterThan( 0.01 ), colorSum.div( weightSum ), vec4( inputColor.rgb, float( 1 ) ) ),
|
|
349
|
+
maxConf,
|
|
350
|
+
minConf
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
} );
|
|
354
|
+
|
|
355
|
+
// Diffuse reprojection
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Reprojection-stretch confidence — detects history magnification (surface stretching).
|
|
359
|
+
*
|
|
360
|
+
* Differentiates the per-pixel history UV with hardware screen-space derivatives to form the
|
|
361
|
+
* reprojection Jacobian `J = ∂(historyPixel)/∂(screenPixel)`, then returns its **minimum
|
|
362
|
+
* singular value**, clamped to `[0,1]`.
|
|
363
|
+
*
|
|
364
|
+
* `σ_min < 1` means the most-stretched axis magnifies history — a few history pixels are smeared
|
|
365
|
+
* over many current pixels (e.g. a surface seen at grazing in the previous frame, face-on now), so
|
|
366
|
+
* history is undersampled and its confidence should be reduced. `σ_min ≥ 1` (history minified) is
|
|
367
|
+
* safe and clamps to 1. Using the minimum singular value rather than the Jacobian determinant
|
|
368
|
+
* catches anisotropic 1-D stretch that an area-only measure would smear out.
|
|
369
|
+
*
|
|
370
|
+
* Works for any reprojection (surface-velocity or parallax hit-point) since it differentiates the
|
|
371
|
+
* final history UV, so the same factor applies to both the diffuse and specular paths.
|
|
372
|
+
*
|
|
373
|
+
* @tsl
|
|
374
|
+
*/
|
|
375
|
+
const reprojectionStretchConfidence = Fn( ( [ historyUV, resolution ] ) => {
|
|
376
|
+
|
|
377
|
+
// Jacobian columns in pixels: how the history sample position moves per screen pixel.
|
|
378
|
+
const jx = dFdx( historyUV ).mul( resolution ).toVar();
|
|
379
|
+
const jy = dFdy( historyUV ).mul( resolution ).toVar();
|
|
380
|
+
|
|
381
|
+
// Singular values of the 2×2 J are sqrt( eigenvalues of JᵀJ ), with
|
|
382
|
+
// trace( JᵀJ ) = ‖J‖²_F and det( JᵀJ ) = det( J )².
|
|
383
|
+
const det = jx.x.mul( jy.y ).sub( jx.y.mul( jy.x ) );
|
|
384
|
+
const fro2 = dot( jx, jx ).add( dot( jy, jy ) );
|
|
385
|
+
const disc = fro2.mul( fro2 ).mul( 0.25 ).sub( det.mul( det ) ).max( 0 ).sqrt();
|
|
386
|
+
const sigMin = fro2.mul( 0.5 ).sub( disc ).max( 0 ).sqrt();
|
|
387
|
+
|
|
388
|
+
return sigMin.saturate();
|
|
389
|
+
|
|
390
|
+
} );
|
|
391
|
+
|
|
392
|
+
// Specular reprojection
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Parallax-corrected hit-point reprojection into previous-frame UVs.
|
|
396
|
+
*
|
|
397
|
+
* @tsl
|
|
398
|
+
*/
|
|
399
|
+
const reprojectHitPoint = Fn( ( [
|
|
400
|
+
rayOrig,
|
|
401
|
+
rayLength,
|
|
402
|
+
cameraWorldPosition,
|
|
403
|
+
previousViewMatrix,
|
|
404
|
+
previousProjectionMatrix
|
|
405
|
+
] ) => {
|
|
406
|
+
|
|
407
|
+
const cameraRay = normalize( rayOrig.sub( cameraWorldPosition ) ).toVar();
|
|
408
|
+
const parallaxHitPoint = rayOrig.add( cameraRay.mul( rayLength ) );
|
|
409
|
+
|
|
410
|
+
return projectWorldToUV( parallaxHitPoint, previousViewMatrix, previousProjectionMatrix );
|
|
411
|
+
|
|
412
|
+
} );
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Converts screen-space velocity (NDC derivative) to a UV reprojection offset.
|
|
416
|
+
*
|
|
417
|
+
* @tsl
|
|
418
|
+
*/
|
|
419
|
+
const velocityToUVOffset = Fn( ( [ velocity ] ) => {
|
|
420
|
+
|
|
421
|
+
return velocity.mul( vec2( 0.5, - 0.5 ) );
|
|
422
|
+
|
|
423
|
+
} ).setLayout( {
|
|
424
|
+
name: 'velocityToUVOffset',
|
|
425
|
+
type: 'vec2',
|
|
426
|
+
inputs: [ { name: 'velocity', type: 'vec2' } ]
|
|
427
|
+
} );
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Current and previous-frame camera matrices for temporal reprojection passes.
|
|
431
|
+
*
|
|
432
|
+
* @param {Camera} camera
|
|
433
|
+
*/
|
|
434
|
+
function bindTemporalCameraUniforms( camera ) {
|
|
435
|
+
|
|
436
|
+
const worldMatrix = uniform( new Matrix4().copy( camera.matrixWorld ) );
|
|
437
|
+
const viewMatrix = uniform( new Matrix4().copy( camera.matrixWorldInverse ) );
|
|
438
|
+
const projectionMatrix = uniform( new Matrix4().copy( camera.projectionMatrix ) );
|
|
439
|
+
const projectionMatrixInverse = uniform( new Matrix4().copy( camera.projectionMatrixInverse ) );
|
|
440
|
+
const worldPosition = uniform( new Vector3().copy( camera.position ) );
|
|
441
|
+
|
|
442
|
+
const previousWorldMatrix = uniform( new Matrix4().copy( camera.matrixWorld ) );
|
|
443
|
+
const previousViewMatrix = uniform( new Matrix4().copy( camera.matrixWorldInverse ) );
|
|
444
|
+
const previousProjectionMatrix = uniform( new Matrix4().copy( camera.projectionMatrix ) );
|
|
445
|
+
const previousProjectionMatrixInverse = uniform( new Matrix4().copy( camera.projectionMatrixInverse ) );
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* @param {Camera} cam
|
|
449
|
+
*/
|
|
450
|
+
function updateFromCamera( cam ) {
|
|
451
|
+
|
|
452
|
+
previousWorldMatrix.value.copy( worldMatrix.value );
|
|
453
|
+
previousViewMatrix.value.copy( viewMatrix.value );
|
|
454
|
+
previousProjectionMatrix.value.copy( projectionMatrix.value );
|
|
455
|
+
previousProjectionMatrixInverse.value.copy( projectionMatrixInverse.value );
|
|
456
|
+
|
|
457
|
+
worldMatrix.value.copy( cam.matrixWorld );
|
|
458
|
+
viewMatrix.value.copy( cam.matrixWorldInverse );
|
|
459
|
+
projectionMatrix.value.copy( cam.projectionMatrix );
|
|
460
|
+
projectionMatrixInverse.value.copy( cam.projectionMatrixInverse );
|
|
461
|
+
worldPosition.value.copy( cam.position );
|
|
462
|
+
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return {
|
|
466
|
+
worldMatrix,
|
|
467
|
+
viewMatrix,
|
|
468
|
+
projectionMatrix,
|
|
469
|
+
projectionMatrixInverse,
|
|
470
|
+
worldPosition,
|
|
471
|
+
previousWorldMatrix,
|
|
472
|
+
previousViewMatrix,
|
|
473
|
+
previousProjectionMatrix,
|
|
474
|
+
previousProjectionMatrixInverse,
|
|
475
|
+
updateFromCamera
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
481
|
+
const _size = /*@__PURE__*/ new Vector2();
|
|
482
|
+
|
|
483
|
+
let _rendererState;
|
|
484
|
+
|
|
485
|
+
const DEFAULT_MAX_VELOCITY_LENGTH = 128;
|
|
486
|
+
const VARIANCE_GAMMA_MIN = 0.5;
|
|
487
|
+
const VARIANCE_GAMMA_MAX = 1;
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* @typedef {'diffuse' | 'specular'} TemporalReprojectMode
|
|
491
|
+
*/
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* @typedef {Object} TemporalReprojectNodeOptions
|
|
495
|
+
* @property {TemporalReprojectMode} [mode='diffuse'] - `diffuse` for SSGI/scene colour; `specular` for SSR reflections.
|
|
496
|
+
* @property {boolean} [hitPointReprojection] - Parallax hit-point reprojection (specular mode only). Defaults to `true` in specular mode.
|
|
497
|
+
* @property {boolean} [accumulate=false] - When `true`, history is stored in this pass (classic temporal resolve). When `false`,
|
|
498
|
+
* use {@link TemporalReprojectNode#setHistoryTexture} to read history from another pass (e.g. denoise output).
|
|
499
|
+
*/
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Temporal reprojection pass for denoising screen-space effects (SSGI, SSR, etc.).
|
|
503
|
+
*
|
|
504
|
+
* Both modes share geometrically-weighted 4-tap bilinear history sampling and YCoCg variance clipping.
|
|
505
|
+
* Surface velocity reprojection is always sampled first. Specular mode then blends in
|
|
506
|
+
* hit-point parallax history on top of that surface result.
|
|
507
|
+
* Diffuse mode applies velocity-field divergence to detect surface stretching.
|
|
508
|
+
*
|
|
509
|
+
* Unlike jitter-based TAA/TAAU, this node does not apply camera sub-pixel jitter — it only
|
|
510
|
+
* reprojects and accumulates history using motion vectors.
|
|
511
|
+
*
|
|
512
|
+
* References:
|
|
513
|
+
* - {@link https://alextardif.com/TAA.html}
|
|
514
|
+
* - {@link https://www.elopezr.com/temporal-aa-and-the-quest-for-the-holy-trail/}
|
|
515
|
+
*
|
|
516
|
+
* @augments TempNode
|
|
517
|
+
* @three_import import { temporalReproject } from 'three/addons/tsl/display/TemporalReprojectNode.js';
|
|
518
|
+
*/
|
|
519
|
+
class TemporalReprojectNode extends TempNode {
|
|
520
|
+
|
|
521
|
+
static get type() {
|
|
522
|
+
|
|
523
|
+
return 'TemporalReprojectNode';
|
|
524
|
+
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* @param {TextureNode} beautyNode
|
|
529
|
+
* @param {TextureNode} depthNode
|
|
530
|
+
* @param {TextureNode} normalNode
|
|
531
|
+
* @param {TextureNode} velocityNode
|
|
532
|
+
* @param {Camera} camera
|
|
533
|
+
* @param {TemporalReprojectNodeOptions} [options]
|
|
534
|
+
*/
|
|
535
|
+
constructor( beautyNode, depthNode, normalNode, velocityNode, camera, options = {} ) {
|
|
536
|
+
|
|
537
|
+
super( 'vec4' );
|
|
538
|
+
|
|
539
|
+
const {
|
|
540
|
+
mode = 'diffuse',
|
|
541
|
+
hitPointReprojection = mode === 'specular',
|
|
542
|
+
accumulate = false
|
|
543
|
+
} = options;
|
|
544
|
+
|
|
545
|
+
if ( mode !== 'specular' && mode !== 'diffuse' ) {
|
|
546
|
+
|
|
547
|
+
throw new Error( 'TemporalReprojectNode: `mode` must be `diffuse` or `specular`.' );
|
|
548
|
+
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
this.isTemporalReprojectNode = true;
|
|
552
|
+
this.updateBeforeType = NodeUpdateType.FRAME;
|
|
553
|
+
|
|
554
|
+
this.beautyNode = beautyNode;
|
|
555
|
+
this.depthNode = depthNode;
|
|
556
|
+
this.normalNode = normalNode;
|
|
557
|
+
this.velocityNode = velocityNode;
|
|
558
|
+
this.camera = camera;
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* @type {TemporalReprojectMode}
|
|
562
|
+
*/
|
|
563
|
+
this.mode = mode;
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* When `true`, resolve output is copied into the internal history buffer each frame.
|
|
567
|
+
* When `false`, history is supplied externally via {@link TemporalReprojectNode#setHistoryTexture}.
|
|
568
|
+
*
|
|
569
|
+
* @type {boolean}
|
|
570
|
+
*/
|
|
571
|
+
this.accumulate = accumulate;
|
|
572
|
+
|
|
573
|
+
this.maxVelocityLength = DEFAULT_MAX_VELOCITY_LENGTH;
|
|
574
|
+
|
|
575
|
+
this._resolution = uniform( new Vector2() );
|
|
576
|
+
|
|
577
|
+
this._cameraUniforms = bindTemporalCameraUniforms( camera );
|
|
578
|
+
|
|
579
|
+
this.maxFrames = uniform( 32 );
|
|
580
|
+
this.hitPointReprojection = uniform( hitPointReprojection, 'bool' );
|
|
581
|
+
this.clampIntensity = uniform( 1 );
|
|
582
|
+
this.flickerSuppression = uniform( 1 );
|
|
583
|
+
|
|
584
|
+
this._historyRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType, depthTexture: new DepthTexture() } );
|
|
585
|
+
this._historyRenderTarget.texture.name = 'TemporalReprojectNode.history';
|
|
586
|
+
this._historyTextureNode = texture( this._historyRenderTarget.texture );
|
|
587
|
+
|
|
588
|
+
this._resolveRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
|
|
589
|
+
this._resolveRenderTarget.texture.name = 'TemporalReprojectNode.resolve';
|
|
590
|
+
|
|
591
|
+
this._resolveMaterial = new NodeMaterial();
|
|
592
|
+
this._resolveMaterial.name = 'TemporalReproject.resolve';
|
|
593
|
+
|
|
594
|
+
this._seedMaterial = new NodeMaterial();
|
|
595
|
+
this._seedMaterial.name = 'TemporalReproject.seed';
|
|
596
|
+
|
|
597
|
+
this._textureNode = passTexture( this, this._resolveRenderTarget.texture );
|
|
598
|
+
|
|
599
|
+
this._originalProjectionMatrix = new Matrix4();
|
|
600
|
+
|
|
601
|
+
this._placeholderPreviousDepthTexture = new DepthTexture( 1, 1 );
|
|
602
|
+
this._previousDepthNode = texture( this._placeholderPreviousDepthTexture );
|
|
603
|
+
this._previousNormalTexture = normalNode.value.clone();
|
|
604
|
+
this._previousNormalNode = texture( this._previousNormalTexture );
|
|
605
|
+
|
|
606
|
+
this._needsPostProcessingSync = false;
|
|
607
|
+
this._externalHistoryTexture = null;
|
|
608
|
+
|
|
609
|
+
this._syncHistoryTextureBinding();
|
|
610
|
+
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
getTextureNode() {
|
|
614
|
+
|
|
615
|
+
return this._textureNode;
|
|
616
|
+
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
setSize( width, height ) {
|
|
620
|
+
|
|
621
|
+
if ( width === null || height === null ) return;
|
|
622
|
+
|
|
623
|
+
this._historyRenderTarget.setSize( width, height );
|
|
624
|
+
this._resolveRenderTarget.setSize( width, height );
|
|
625
|
+
|
|
626
|
+
this._resolution.value.set( width, height );
|
|
627
|
+
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
setViewOffset() {
|
|
631
|
+
|
|
632
|
+
this.camera.updateProjectionMatrix();
|
|
633
|
+
this._originalProjectionMatrix.copy( this.camera.projectionMatrix );
|
|
634
|
+
velocity.setProjectionMatrix( this._originalProjectionMatrix );
|
|
635
|
+
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
clearViewOffset() {
|
|
639
|
+
|
|
640
|
+
velocity.setProjectionMatrix( null );
|
|
641
|
+
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
updateBefore( frame ) {
|
|
645
|
+
|
|
646
|
+
const { renderer } = frame;
|
|
647
|
+
|
|
648
|
+
this._cameraUniforms.updateFromCamera( this.camera );
|
|
649
|
+
|
|
650
|
+
const drawingBufferSize = renderer.getDrawingBufferSize( _size );
|
|
651
|
+
const width = drawingBufferSize.width;
|
|
652
|
+
const height = drawingBufferSize.height;
|
|
653
|
+
|
|
654
|
+
if ( this._needsPostProcessingSync === true ) {
|
|
655
|
+
|
|
656
|
+
this.setViewOffset();
|
|
657
|
+
this._needsPostProcessingSync = false;
|
|
658
|
+
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
_rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
|
|
662
|
+
|
|
663
|
+
const needsRestart = this._historyRenderTarget.width !== width || this._historyRenderTarget.height !== height;
|
|
664
|
+
this.setSize( width, height );
|
|
665
|
+
|
|
666
|
+
let historySwappedForRestart = false;
|
|
667
|
+
|
|
668
|
+
if ( needsRestart === true ) {
|
|
669
|
+
|
|
670
|
+
renderer.initRenderTarget( this._historyRenderTarget );
|
|
671
|
+
renderer.initRenderTarget( this._resolveRenderTarget );
|
|
672
|
+
|
|
673
|
+
this._previousNormalTexture.dispose();
|
|
674
|
+
this._previousNormalTexture = this.normalNode.value.clone();
|
|
675
|
+
this._previousNormalNode.value = this._previousNormalTexture;
|
|
676
|
+
|
|
677
|
+
// External history (e.g. denoise feedback) is stale at the old resolution — use
|
|
678
|
+
// freshly seeded internal history for this frame instead.
|
|
679
|
+
if ( this.accumulate === false && this._externalHistoryTexture !== null ) {
|
|
680
|
+
|
|
681
|
+
this._historyTextureNode.value = this._historyRenderTarget.texture;
|
|
682
|
+
historySwappedForRestart = true;
|
|
683
|
+
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
renderer.setRenderTarget( this._historyRenderTarget );
|
|
687
|
+
_quadMesh.material = this._seedMaterial;
|
|
688
|
+
_quadMesh.name = 'TemporalReproject.seed';
|
|
689
|
+
_quadMesh.render( renderer );
|
|
690
|
+
renderer.setRenderTarget( null );
|
|
691
|
+
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
renderer.setRenderTarget( this._resolveRenderTarget );
|
|
695
|
+
|
|
696
|
+
_quadMesh.material = this._resolveMaterial;
|
|
697
|
+
_quadMesh.name = 'TemporalReproject';
|
|
698
|
+
_quadMesh.render( renderer );
|
|
699
|
+
renderer.setRenderTarget( null );
|
|
700
|
+
|
|
701
|
+
if ( historySwappedForRestart === true ) {
|
|
702
|
+
|
|
703
|
+
this._syncHistoryTextureBinding();
|
|
704
|
+
|
|
705
|
+
} else if ( this.accumulate === true ) {
|
|
706
|
+
|
|
707
|
+
renderer.copyTextureToTexture( this._resolveRenderTarget.texture, this._historyRenderTarget.texture );
|
|
708
|
+
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
const currentDepth = this.depthNode.value;
|
|
712
|
+
const srcW = currentDepth.image !== null && currentDepth.image !== undefined ? currentDepth.image.width : 0;
|
|
713
|
+
const srcH = currentDepth.image !== null && currentDepth.image !== undefined ? currentDepth.image.height : 0;
|
|
714
|
+
|
|
715
|
+
if ( srcW > 0 && srcH > 0 ) {
|
|
716
|
+
|
|
717
|
+
renderer.copyTextureToTexture( currentDepth, this._historyRenderTarget.depthTexture );
|
|
718
|
+
renderer.copyTextureToTexture( this.normalNode.value, this._previousNormalTexture );
|
|
719
|
+
|
|
720
|
+
this._previousDepthNode.value = this._historyRenderTarget.depthTexture;
|
|
721
|
+
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
RendererUtils.restoreRendererState( renderer, _rendererState );
|
|
725
|
+
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
setup( builder ) {
|
|
729
|
+
|
|
730
|
+
const renderPipeline = builder.context.renderPipeline;
|
|
731
|
+
|
|
732
|
+
if ( renderPipeline ) {
|
|
733
|
+
|
|
734
|
+
this._needsPostProcessingSync = true;
|
|
735
|
+
|
|
736
|
+
renderPipeline.context.onBeforeRenderPipeline = () => {
|
|
737
|
+
|
|
738
|
+
this.setViewOffset();
|
|
739
|
+
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
renderPipeline.context.onAfterRenderPipeline = () => {
|
|
743
|
+
|
|
744
|
+
this.clearViewOffset();
|
|
745
|
+
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
this._resolveMaterial.fragmentNode = this._buildResolve( builder );
|
|
751
|
+
this._resolveMaterial.needsUpdate = true;
|
|
752
|
+
|
|
753
|
+
this._buildSeed( builder );
|
|
754
|
+
|
|
755
|
+
return this._textureNode;
|
|
756
|
+
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
_buildSeed( builder ) {
|
|
760
|
+
|
|
761
|
+
const seed = Fn( () => {
|
|
762
|
+
|
|
763
|
+
const screenTexel = ivec2( floor( screenCoordinate.xy.sub( 0.5 ) ) );
|
|
764
|
+
const beautySize = this.beautyNode.size();
|
|
765
|
+
const beautyTexel = beautyTexelFromScreen( screenTexel, beautySize, this._resolution );
|
|
766
|
+
|
|
767
|
+
return textureLoad( this.beautyNode, beautyTexel ).max( 0 );
|
|
768
|
+
|
|
769
|
+
} );
|
|
770
|
+
|
|
771
|
+
this._seedMaterial.fragmentNode = seed().context( builder.getSharedContext() );
|
|
772
|
+
this._seedMaterial.needsUpdate = true;
|
|
773
|
+
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
_buildResolve( builder ) {
|
|
777
|
+
|
|
778
|
+
const isSpecular = this.mode === 'specular';
|
|
779
|
+
const cameraUniforms = this._cameraUniforms;
|
|
780
|
+
|
|
781
|
+
const resolve = Fn( () => {
|
|
782
|
+
|
|
783
|
+
const uvNode = uv();
|
|
784
|
+
|
|
785
|
+
const screenTexel = ivec2( floor( screenCoordinate.xy.sub( 0.5 ) ) );
|
|
786
|
+
const depth = textureLoad( this.depthNode, screenTexel ).r.toVar();
|
|
787
|
+
depth.greaterThanEqual( 1.0 ).discard();
|
|
788
|
+
|
|
789
|
+
const beautySize = this.beautyNode.size();
|
|
790
|
+
const beautyTexel = beautyTexelFromScreen( screenTexel, beautySize, this._resolution );
|
|
791
|
+
|
|
792
|
+
const inputColor = textureLoad( this.beautyNode, beautyTexel ).max( 0 ).toVar();
|
|
793
|
+
const viewNormal = unpackRGBToNormal( textureLoad( this.normalNode, screenTexel ).rgb ).toVar();
|
|
794
|
+
|
|
795
|
+
// Shared 3×3 beauty fetch: feeds both the variance-clip box and the SSR ray-length stats.
|
|
796
|
+
const neighborhood = collectNeighborhood( this.beautyNode, beautyTexel, inputColor, this.flickerSuppression );
|
|
797
|
+
const worldNormal = viewNormal.transformDirection( cameraUniforms.viewMatrix ).toVar();
|
|
798
|
+
|
|
799
|
+
const viewPosition = getViewPosition( uvNode, depth, cameraUniforms.projectionMatrixInverse ).toVar();
|
|
800
|
+
const worldPosition = cameraUniforms.worldMatrix.mul( vec4( viewPosition, 1.0 ) ).xyz.toVar();
|
|
801
|
+
|
|
802
|
+
const sampleHistory = ( reprojUV ) => sampleHistory4Tap(
|
|
803
|
+
this._historyTextureNode,
|
|
804
|
+
this._previousDepthNode,
|
|
805
|
+
this._previousNormalNode,
|
|
806
|
+
this._resolution,
|
|
807
|
+
cameraUniforms.previousProjectionMatrixInverse,
|
|
808
|
+
cameraUniforms.previousWorldMatrix,
|
|
809
|
+
cameraUniforms.previousViewMatrix,
|
|
810
|
+
reprojUV,
|
|
811
|
+
worldPosition,
|
|
812
|
+
worldNormal,
|
|
813
|
+
inputColor.rgb
|
|
814
|
+
);
|
|
815
|
+
|
|
816
|
+
// Surface-velocity reprojection — the base history for both modes. `historyUV` is
|
|
817
|
+
// reused below for the stretch guard, so it is computed once here.
|
|
818
|
+
const velocityOff = velocityToUVOffset( textureLoad( this.velocityNode, screenTexel ).xy ).toVar();
|
|
819
|
+
const motionFactor = velocityOff.mul( this._resolution ).length().div( float( this.maxVelocityLength ) ).saturate();
|
|
820
|
+
|
|
821
|
+
const historyUV = uvNode.sub( velocityOff ).toVar();
|
|
822
|
+
const surf = sampleHistory( historyUV );
|
|
823
|
+
|
|
824
|
+
const historyColor = surf.get( 'color' ).toVar();
|
|
825
|
+
const totalConfidence = float( 1 ).toVar();
|
|
826
|
+
const historyTrust = float( 0 ).toVar();
|
|
827
|
+
|
|
828
|
+
// Specular: blend parallax hit-point history on top of the surface result. Returns the resolved
|
|
829
|
+
// color (rgb from the blend, alpha from the surface tap), its confidence, and the hit-vs-surface trust.
|
|
830
|
+
const resolveSpecularHistory = () => {
|
|
831
|
+
|
|
832
|
+
const surfValid = historyUV.x.greaterThanEqual( 0 ).and( historyUV.x.lessThanEqual( 1 ) )
|
|
833
|
+
.and( historyUV.y.greaterThanEqual( 0 ) ).and( historyUV.y.lessThanEqual( 1 ) );
|
|
834
|
+
|
|
835
|
+
const historyUV_hit = reprojectHitPoint(
|
|
836
|
+
worldPosition,
|
|
837
|
+
neighborhood.get( 'rayLength' ),
|
|
838
|
+
cameraUniforms.worldPosition,
|
|
839
|
+
cameraUniforms.previousViewMatrix,
|
|
840
|
+
cameraUniforms.previousProjectionMatrix
|
|
841
|
+
).toVar();
|
|
842
|
+
|
|
843
|
+
const hitValid = historyUV_hit.x.greaterThanEqual( 0 ).and( historyUV_hit.x.lessThanEqual( 1 ) )
|
|
844
|
+
.and( historyUV_hit.y.greaterThanEqual( 0 ) ).and( historyUV_hit.y.lessThanEqual( 1 ) )
|
|
845
|
+
.and( this.hitPointReprojection );
|
|
846
|
+
|
|
847
|
+
const hit = sampleHistory( historyUV_hit );
|
|
848
|
+
|
|
849
|
+
const hcHit = hit.get( 'color' ).rgb.max( 0 );
|
|
850
|
+
const hcSurf = surf.get( 'color' ).rgb.max( 0 );
|
|
851
|
+
|
|
852
|
+
const confHit = hitValid.select( hit.get( 'tapConfidence' ), float( 0 ) );
|
|
853
|
+
const confSurf = surfValid.select( surf.get( 'tapConfidence' ), float( 0 ) );
|
|
854
|
+
const minConfHit = hit.get( 'minConfidence' );
|
|
855
|
+
|
|
856
|
+
const reflectionEdgeFactor = neighborhood.get( 'stdDevRayLength' );
|
|
857
|
+
reflectionEdgeFactor.assign( reflectionEdgeFactor.mul( motionFactor.mul( 100 ).min( 1 ) ).mul( 3.5 ).min( 1 ).oneMinus() );
|
|
858
|
+
|
|
859
|
+
const curvatureFactor = fwidth( worldNormal.xyz ).length().mul( 50 ).clamp();
|
|
860
|
+
|
|
861
|
+
const envProbability = neighborhood.get( 'envProbability' );
|
|
862
|
+
|
|
863
|
+
const wHitRaw = minConfHit
|
|
864
|
+
.mul( reflectionEdgeFactor )
|
|
865
|
+
.mul( curvatureFactor.oneMinus() )
|
|
866
|
+
.mul( confHit ).toConst();
|
|
867
|
+
|
|
868
|
+
const wHit = wHitRaw.mul( envProbability.pow2().oneMinus() );
|
|
869
|
+
const wSurf = wHit.oneMinus().mul( confSurf );
|
|
870
|
+
const wSum = max( wHit.add( wSurf ), float( EPSILON ) );
|
|
871
|
+
|
|
872
|
+
const color = vec4(
|
|
873
|
+
hcHit.mul( wHit ).add( hcSurf.mul( wSurf ) ).div( wSum ),
|
|
874
|
+
surf.get( 'color' ).a
|
|
875
|
+
).toVar();
|
|
876
|
+
const confidence = confHit.mul( wHit ).add( confSurf.mul( wSurf ) ).div( wSum );
|
|
877
|
+
|
|
878
|
+
// Near-black blend means neither tap was usable — fall back to the current frame.
|
|
879
|
+
If( color.rgb.length().lessThan( EPSILON ), () => {
|
|
880
|
+
|
|
881
|
+
color.assign( vec4( inputColor.rgb, 1 ) );
|
|
882
|
+
|
|
883
|
+
} );
|
|
884
|
+
|
|
885
|
+
return { color, confidence, trust: wHitRaw }; // without env probability
|
|
886
|
+
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
if ( isSpecular ) {
|
|
890
|
+
|
|
891
|
+
const spec = resolveSpecularHistory();
|
|
892
|
+
historyColor.assign( spec.color );
|
|
893
|
+
totalConfidence.assign( spec.confidence );
|
|
894
|
+
historyTrust.assign( spec.trust );
|
|
895
|
+
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
const a = historyColor.a.max( EPSILON );
|
|
899
|
+
|
|
900
|
+
// Universal stretch guard: reduce confidence where a "small area" is projected over a "large area".
|
|
901
|
+
const stretchConfidence = reprojectionStretchConfidence( historyUV, this._resolution );
|
|
902
|
+
totalConfidence.mulAssign( stretchConfidence.pow( 2 ) );
|
|
903
|
+
|
|
904
|
+
const varianceGamma = mix( float( VARIANCE_GAMMA_MIN ), float( VARIANCE_GAMMA_MAX ), motionFactor.oneMinus().pow2() );
|
|
905
|
+
|
|
906
|
+
const clippedRGB = applyVarianceClipping(
|
|
907
|
+
historyColor,
|
|
908
|
+
neighborhood.get( 'mean' ),
|
|
909
|
+
neighborhood.get( 'stdColor' ),
|
|
910
|
+
varianceGamma,
|
|
911
|
+
this.flickerSuppression
|
|
912
|
+
).toVar();
|
|
913
|
+
|
|
914
|
+
const clampIntensity = this.clampIntensity.mul( max( motionFactor.mul( 10 ).min( 1 ), 0.25 ) ).mul(
|
|
915
|
+
float( 1 ).add( stretchConfidence.oneMinus().add( historyTrust.oneMinus() ).clamp() )
|
|
916
|
+
);
|
|
917
|
+
const originalHistoryColor = vec3( historyColor.rgb );
|
|
918
|
+
historyColor.rgb.assign( mix( historyColor.rgb, clippedRGB, clampIntensity ) );
|
|
919
|
+
|
|
920
|
+
totalConfidence.mulAssign( exp( originalHistoryColor.sub( clippedRGB ).length().mul( clampIntensity ).mul( 30 ).negate() ) );
|
|
921
|
+
totalConfidence.mulAssign( mix( float( 1 ), historyTrust.mul( 0.05 ).add( 0.95 ), motionFactor.mul( 100 ).clamp() ) );
|
|
922
|
+
|
|
923
|
+
If( totalConfidence.lessThan( EPSILON ), () => {
|
|
924
|
+
|
|
925
|
+
historyColor.assign( vec4( inputColor.rgb, 1 ) );
|
|
926
|
+
|
|
927
|
+
} );
|
|
928
|
+
|
|
929
|
+
const currentFrameCount = float( 1 ).div( a ).mul( totalConfidence ).add( 1 ).min( this.maxFrames ).toVar();
|
|
930
|
+
|
|
931
|
+
if ( isSpecular ) {
|
|
932
|
+
|
|
933
|
+
// A black current sample means no reflection was found this frame (a miss, not dark).
|
|
934
|
+
// Since no valid sample was found, decrement the frame count (as the next accumulating pass will increase it).
|
|
935
|
+
If( inputColor.rgb.length().lessThan( EPSILON ), () => {
|
|
936
|
+
|
|
937
|
+
currentFrameCount.assign( currentFrameCount.sub( 1 ).max( 1 ) );
|
|
938
|
+
|
|
939
|
+
} );
|
|
940
|
+
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
return vec4( historyColor.rgb, float( 1 ).div( currentFrameCount ) );
|
|
944
|
+
|
|
945
|
+
} );
|
|
946
|
+
|
|
947
|
+
return resolve().context( builder.getSharedContext() );
|
|
948
|
+
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
_syncHistoryTextureBinding() {
|
|
952
|
+
|
|
953
|
+
if ( this.accumulate === true || this._externalHistoryTexture === null ) {
|
|
954
|
+
|
|
955
|
+
this._historyTextureNode.value = this._historyRenderTarget.texture;
|
|
956
|
+
|
|
957
|
+
} else {
|
|
958
|
+
|
|
959
|
+
this._historyTextureNode.value = this._externalHistoryTexture;
|
|
960
|
+
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Supplies an external history source (e.g. a {@link RecurrentDenoiseNode} or its
|
|
967
|
+
* texture). Only used when {@link TemporalReprojectNode#accumulate} is `false`.
|
|
968
|
+
*
|
|
969
|
+
* @param {?(Object|Texture)} source
|
|
970
|
+
*/
|
|
971
|
+
setHistoryTexture( source ) {
|
|
972
|
+
|
|
973
|
+
this._externalHistoryTexture = ( source && typeof source.getRenderTarget === 'function' )
|
|
974
|
+
? source.getRenderTarget().texture
|
|
975
|
+
: source;
|
|
976
|
+
this._syncHistoryTextureBinding();
|
|
977
|
+
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
dispose() {
|
|
981
|
+
|
|
982
|
+
this._previousNormalTexture.dispose();
|
|
983
|
+
|
|
984
|
+
if ( this._previousDepthNode.value !== this._historyRenderTarget.depthTexture ) {
|
|
985
|
+
|
|
986
|
+
this._previousDepthNode.value.dispose();
|
|
987
|
+
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
if ( this._placeholderPreviousDepthTexture !== this._historyRenderTarget.depthTexture ) {
|
|
991
|
+
|
|
992
|
+
this._placeholderPreviousDepthTexture.dispose();
|
|
993
|
+
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
this._historyRenderTarget.dispose();
|
|
997
|
+
this._resolveRenderTarget.dispose();
|
|
998
|
+
this._resolveMaterial.dispose();
|
|
999
|
+
this._seedMaterial.dispose();
|
|
1000
|
+
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
export default TemporalReprojectNode;
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* @param {TextureNode} beautyNode
|
|
1009
|
+
* @param {TextureNode} depthNode
|
|
1010
|
+
* @param {TextureNode} normalNode
|
|
1011
|
+
* @param {TextureNode} velocityNode
|
|
1012
|
+
* @param {Camera} camera
|
|
1013
|
+
* @param {TemporalReprojectNodeOptions} [options]
|
|
1014
|
+
* @returns {TemporalReprojectNode}
|
|
1015
|
+
*/
|
|
1016
|
+
export const temporalReproject = ( beautyNode, depthNode, normalNode, velocityNode, camera, options = {} ) => nodeObject( new TemporalReprojectNode(
|
|
1017
|
+
convertToTexture( beautyNode ),
|
|
1018
|
+
nodeObject( depthNode ),
|
|
1019
|
+
nodeObject( normalNode ),
|
|
1020
|
+
nodeObject( velocityNode ),
|
|
1021
|
+
camera,
|
|
1022
|
+
options
|
|
1023
|
+
) );
|