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,912 @@
|
|
|
1
|
+
import { abs, atan, bool, convertToTexture, cos, cross, Discard, dot, EPSILON, exp, float, Fn, getScreenPosition, getViewPosition, If, int, log, Loop, luminance, mat2, max, mix, nodeObject, NodeUpdateType, normalize, passTexture, PI, property, reflect, sin, smoothstep, sqrt, tan, texture, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4 } from 'three/tsl';
|
|
2
|
+
import { HalfFloatType, MathUtils, Matrix4, NodeMaterial, QuadMesh, RendererUtils, RenderTarget, TempNode, Vector2 } from 'three/webgpu';
|
|
3
|
+
import { bindAnalyticNoise } from '../utils/RNoise.js';
|
|
4
|
+
import { ENV_RAY_LENGTH_THRESHOLD } from '../utils/SpecularHelpers.js';
|
|
5
|
+
|
|
6
|
+
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
7
|
+
const _size = /*@__PURE__*/ new Vector2();
|
|
8
|
+
|
|
9
|
+
let _rendererState;
|
|
10
|
+
|
|
11
|
+
const KERNEL_SAMPLES = 8;
|
|
12
|
+
const NOISE_ROTATION_SEED = 83;
|
|
13
|
+
const WORLD_RADIUS_SCALE = 0.1;
|
|
14
|
+
|
|
15
|
+
const AO_EDGE_STOPPING_BIAS = 0.05;
|
|
16
|
+
const AGGRESSIVITY_RADIUS_MIN = 0.001;
|
|
17
|
+
const DIFFUSE_CHROMA_WEIGHT = 2.0;
|
|
18
|
+
// Neighborhood luma coefficient-of-variation thresholds for gating the temporal inverse-luminance
|
|
19
|
+
// (firefly) suppression: below MIN the region is treated as flicker-free, above MAX as noisy.
|
|
20
|
+
const FLICKER_COV_GATE_MIN = 0.1;
|
|
21
|
+
const FLICKER_COV_GATE_MAX = 2;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Golden-angle Vogel disk offset.
|
|
25
|
+
*
|
|
26
|
+
* @tsl
|
|
27
|
+
*/
|
|
28
|
+
const vogelDisk = Fn( ( [ i, radius ] ) => {
|
|
29
|
+
|
|
30
|
+
const sampleCount = 8;
|
|
31
|
+
const theta = i.add( 0.5 ).mul( 2.399827721492203 );
|
|
32
|
+
const r = radius.mul( sqrt( i.add( 0.5 ).div( sampleCount ) ) );
|
|
33
|
+
return vec2( cos( theta ), sin( theta ) ).mul( r );
|
|
34
|
+
|
|
35
|
+
} ).setLayout( {
|
|
36
|
+
name: 'vogelDisk',
|
|
37
|
+
type: 'vec2',
|
|
38
|
+
inputs: [
|
|
39
|
+
{ name: 'i', type: 'float' },
|
|
40
|
+
{ name: 'radius', type: 'float' }
|
|
41
|
+
]
|
|
42
|
+
} );
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Chromatic color-similarity distance between two linear base colors (albedo).
|
|
46
|
+
*
|
|
47
|
+
* @tsl
|
|
48
|
+
*/
|
|
49
|
+
const diffuseColorDistance = Fn( ( [ a, b, compressLuma ] ) => {
|
|
50
|
+
|
|
51
|
+
const toYCoCg = ( c ) => vec3(
|
|
52
|
+
dot( c, vec3( 0.25, 0.5, 0.25 ) ),
|
|
53
|
+
c.r.sub( c.b ),
|
|
54
|
+
c.g.sub( c.r.add( c.b ).mul( 0.5 ) )
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const ya = toYCoCg( a );
|
|
58
|
+
const yb = toYCoCg( b );
|
|
59
|
+
|
|
60
|
+
// `compressLuma` (0/1) range-compresses the luma term with log(1+L) so a fixed lumaPhi gives
|
|
61
|
+
// scale-invariant differences across the HDR range. 0 leaves luma linear (used for LDR albedo).
|
|
62
|
+
const compress = ( L ) => mix( L, log( L.add( 1 ) ), compressLuma );
|
|
63
|
+
|
|
64
|
+
const dLuma = abs( compress( ya.x ).sub( compress( yb.x ) ) );
|
|
65
|
+
const dChroma = vec2( ya.y.sub( yb.y ), ya.z.sub( yb.z ) ).length();
|
|
66
|
+
|
|
67
|
+
return dLuma.add( dChroma.mul( DIFFUSE_CHROMA_WEIGHT ) );
|
|
68
|
+
|
|
69
|
+
} ).setLayout( {
|
|
70
|
+
name: 'diffuseColorDistance',
|
|
71
|
+
type: 'float',
|
|
72
|
+
inputs: [
|
|
73
|
+
{ name: 'a', type: 'vec3' },
|
|
74
|
+
{ name: 'b', type: 'vec3' },
|
|
75
|
+
{ name: 'compressLuma', type: 'float' }
|
|
76
|
+
]
|
|
77
|
+
} );
|
|
78
|
+
|
|
79
|
+
const _temporalWeight = Fn( ( [ x, strength ] ) => float( 1 ).div( x.pow( strength ) ) ).setLayout( {
|
|
80
|
+
name: 'temporalWeight',
|
|
81
|
+
type: 'float',
|
|
82
|
+
inputs: [
|
|
83
|
+
{ name: 'x', type: 'float' },
|
|
84
|
+
{ name: 'strength', type: 'float' }
|
|
85
|
+
]
|
|
86
|
+
} );
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Temporal accumulation variance factor in `[0, 1]`. Higher values mean more history confidence.
|
|
90
|
+
*
|
|
91
|
+
* @tsl
|
|
92
|
+
*/
|
|
93
|
+
const getTemporalVarianceFactor = Fn( ( [ frameNum, strength ] ) => {
|
|
94
|
+
|
|
95
|
+
return _temporalWeight( frameNum, strength ).max( 0.05 );
|
|
96
|
+
|
|
97
|
+
} ).setLayout( {
|
|
98
|
+
name: 'getTemporalVarianceFactor',
|
|
99
|
+
type: 'float',
|
|
100
|
+
inputs: [
|
|
101
|
+
{ name: 'frameNum', type: 'float' },
|
|
102
|
+
{ name: 'strength', type: 'float' }
|
|
103
|
+
]
|
|
104
|
+
} );
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* World-space frustum height at `viewZ`. Algorithm originally from REBLUR (NRD).
|
|
108
|
+
* `tanHalfFovY` is `tan( verticalFov / 2 )`, hoisted by the caller since it is loop-invariant.
|
|
109
|
+
*
|
|
110
|
+
* @tsl
|
|
111
|
+
*/
|
|
112
|
+
const computeFrustumSize = Fn( ( [ viewZ, tanHalfFovY ] ) => {
|
|
113
|
+
|
|
114
|
+
return float( 2 ).mul( viewZ ).mul( tanHalfFovY );
|
|
115
|
+
|
|
116
|
+
} ).setLayout( {
|
|
117
|
+
name: 'computeFrustumSize',
|
|
118
|
+
type: 'float',
|
|
119
|
+
inputs: [
|
|
120
|
+
{ name: 'viewZ', type: 'float' },
|
|
121
|
+
{ name: 'tanHalfFovY', type: 'float' }
|
|
122
|
+
]
|
|
123
|
+
} );
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Maps world-space SSR ray length to `[0, 1]`. Environment rays (`worldRayLength == 0`) map to `1`.
|
|
127
|
+
* Algorithm originally from REBLUR (NRD).
|
|
128
|
+
*
|
|
129
|
+
* @tsl
|
|
130
|
+
*/
|
|
131
|
+
const computeHitDistFactor = Fn( ( [ worldRayLength, viewZ, tanHalfFovY ] ) => {
|
|
132
|
+
|
|
133
|
+
const frustumSize = computeFrustumSize( viewZ, tanHalfFovY );
|
|
134
|
+
const factor = worldRayLength.div( frustumSize.max( 1e-6 ) ).clamp( 0, 1 );
|
|
135
|
+
|
|
136
|
+
return factor;
|
|
137
|
+
|
|
138
|
+
} ).setLayout( {
|
|
139
|
+
name: 'computeHitDistFactor',
|
|
140
|
+
type: 'float',
|
|
141
|
+
inputs: [
|
|
142
|
+
{ name: 'worldRayLength', type: 'float' },
|
|
143
|
+
{ name: 'viewZ', type: 'float' },
|
|
144
|
+
{ name: 'tanHalfFovY', type: 'float' }
|
|
145
|
+
]
|
|
146
|
+
} );
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Maps an AO factor for edge-stopping comparisons.
|
|
150
|
+
*
|
|
151
|
+
* @tsl
|
|
152
|
+
*/
|
|
153
|
+
const mapAo = Fn( ( [ aoVal ] ) => aoVal.pow( 0.1 ) );
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Specular dominant direction — smooth surfaces lean toward reflection, rough toward normal.
|
|
157
|
+
*
|
|
158
|
+
* @tsl
|
|
159
|
+
*/
|
|
160
|
+
const getSpecularDominantDirection = Fn( ( [ N, V, roughness ] ) => {
|
|
161
|
+
|
|
162
|
+
return normalize( mix( N, reflect( V.negate(), N ), roughness.oneMinus() ) );
|
|
163
|
+
|
|
164
|
+
} ).setLayout( {
|
|
165
|
+
name: 'getSpecularDominantDirection',
|
|
166
|
+
type: 'vec3',
|
|
167
|
+
inputs: [
|
|
168
|
+
{ name: 'N', type: 'vec3' },
|
|
169
|
+
{ name: 'V', type: 'vec3' },
|
|
170
|
+
{ name: 'roughness', type: 'float' }
|
|
171
|
+
]
|
|
172
|
+
} );
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* GGX inverse-CDF: half-angle tangent enclosing `percent` of the specular lobe volume.
|
|
176
|
+
* `roughness` is perceptual (alpha = roughness²).
|
|
177
|
+
*
|
|
178
|
+
* @tsl
|
|
179
|
+
*/
|
|
180
|
+
const specularLobeTanHalfAngle = Fn( ( [ roughness, percent ] ) => {
|
|
181
|
+
|
|
182
|
+
const alpha = roughness.mul( roughness );
|
|
183
|
+
return alpha.mul( sqrt( percent.div( float( 1 ).sub( percent ).max( 1e-6 ) ) ) );
|
|
184
|
+
|
|
185
|
+
} ).setLayout( {
|
|
186
|
+
name: 'specularLobeTanHalfAngle',
|
|
187
|
+
type: 'float',
|
|
188
|
+
inputs: [
|
|
189
|
+
{ name: 'roughness', type: 'float' },
|
|
190
|
+
{ name: 'percent', type: 'float' }
|
|
191
|
+
]
|
|
192
|
+
} );
|
|
193
|
+
|
|
194
|
+
const EXP_WEIGHT_SCALE = 4;
|
|
195
|
+
const NORMAL_ENCODING_ERROR = 1.5 / 255;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Loop-invariant part of the adaptive normal edge-stopping weight: the Gaussian falloff
|
|
199
|
+
* constant `2·EXP_WEIGHT_SCALE / lobeHalfAngle²`. `roughness`/`aggressivity`/`invNormalPhi`
|
|
200
|
+
* are constant across the kernel, so this is hoisted out of the tap loop and evaluated once
|
|
201
|
+
* per pixel. Lobe half-angle from REBLUR (NRD).
|
|
202
|
+
*
|
|
203
|
+
* @tsl
|
|
204
|
+
*/
|
|
205
|
+
const lobeNormalFalloff = Fn( ( [ roughness, aggressivity, invNormalPhi ] ) => {
|
|
206
|
+
|
|
207
|
+
const percent = mix( invNormalPhi.pow2(), float( 0 ), aggressivity.sqrt() ).clamp( 0.1, 0.99 );
|
|
208
|
+
const tanHalfAngle = specularLobeTanHalfAngle( roughness, percent );
|
|
209
|
+
const lobeHalfAngle = max( atan( tanHalfAngle ), float( NORMAL_ENCODING_ERROR ) );
|
|
210
|
+
|
|
211
|
+
const invHalfAngle = float( 1 ).div( lobeHalfAngle );
|
|
212
|
+
return invHalfAngle.mul( invHalfAngle ).mul( 2 * EXP_WEIGHT_SCALE );
|
|
213
|
+
|
|
214
|
+
} ).setLayout( {
|
|
215
|
+
name: 'lobeNormalFalloff',
|
|
216
|
+
type: 'float',
|
|
217
|
+
inputs: [
|
|
218
|
+
{ name: 'roughness', type: 'float' },
|
|
219
|
+
{ name: 'aggressivity', type: 'float' },
|
|
220
|
+
{ name: 'invNormalPhi', type: 'float' }
|
|
221
|
+
]
|
|
222
|
+
} );
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Adaptive lobe normal edge-stopping weight
|
|
226
|
+
*
|
|
227
|
+
* Evaluated entirely in cosine space: with `angle² ≈ 2(1 − cosθ)`, the original
|
|
228
|
+
* `exp( −SCALE·angle/halfAngle )` becomes a Gaussian `exp( falloff·(cosθ − 1) )`, so a
|
|
229
|
+
* single `exp` replaces the per-tap `acos`. Matches the original at the half-angle for
|
|
230
|
+
* narrow lobes and is slightly more permissive for wide (diffuse) ones.
|
|
231
|
+
*
|
|
232
|
+
* @tsl
|
|
233
|
+
*/
|
|
234
|
+
const lobeNormalWeight = Fn( ( [ viewNormal, nNormalV, lobeFalloff ] ) => {
|
|
235
|
+
|
|
236
|
+
const cosA = dot( viewNormal, nNormalV );
|
|
237
|
+
|
|
238
|
+
return exp( cosA.sub( 1 ).mul( lobeFalloff ) );
|
|
239
|
+
|
|
240
|
+
} ).setLayout( {
|
|
241
|
+
name: 'lobeNormalWeight',
|
|
242
|
+
type: 'float',
|
|
243
|
+
inputs: [
|
|
244
|
+
{ name: 'viewNormal', type: 'vec3' },
|
|
245
|
+
{ name: 'nNormalV', type: 'vec3' },
|
|
246
|
+
{ name: 'lobeFalloff', type: 'float' }
|
|
247
|
+
]
|
|
248
|
+
} );
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* View-space plane distance between two surface points (edge-stopping geometry term).
|
|
252
|
+
*
|
|
253
|
+
* @tsl
|
|
254
|
+
*/
|
|
255
|
+
const planeDistance = Fn( ( [ position, nPosition, normal ] ) => {
|
|
256
|
+
|
|
257
|
+
return abs( dot( position.sub( nPosition ), normal ) );
|
|
258
|
+
|
|
259
|
+
} ).setLayout( {
|
|
260
|
+
name: 'planeDistance',
|
|
261
|
+
type: 'float',
|
|
262
|
+
inputs: [
|
|
263
|
+
{ name: 'position', type: 'vec3' },
|
|
264
|
+
{ name: 'nPosition', type: 'vec3' },
|
|
265
|
+
{ name: 'normal', type: 'vec3' },
|
|
266
|
+
]
|
|
267
|
+
} );
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Inverse-luminance temporal blend with optional adaptive trust (Karis-style).
|
|
271
|
+
*
|
|
272
|
+
* @tsl
|
|
273
|
+
*/
|
|
274
|
+
const karisTemporalBlend = Fn( ( [ denoisedRgb, denoisedRaw, a, flickerSuppression, adaptiveTrust, nbhdMeanLuma, nbhdStddevLuma ] ) => {
|
|
275
|
+
|
|
276
|
+
const localCoV = nbhdStddevLuma.div( nbhdMeanLuma.max( 1e-4 ) );
|
|
277
|
+
const trustSuppress = localCoV.mul( adaptiveTrust ).mul( a.oneMinus() ).clamp( 0, 0.9 );
|
|
278
|
+
const aTrust = a.mul( trustSuppress.oneMinus() );
|
|
279
|
+
|
|
280
|
+
// In flicker-free neighborhoods, back off the inverse-luminance weighting so valid bright highlights
|
|
281
|
+
// keep their energy. Scaled by adaptiveTrust so the default (0) path is unchanged.
|
|
282
|
+
const noisy = smoothstep( FLICKER_COV_GATE_MIN, FLICKER_COV_GATE_MAX, localCoV );
|
|
283
|
+
const effFlicker = flickerSuppression.mul( mix( adaptiveTrust.oneMinus(), float( 1 ), noisy ) );
|
|
284
|
+
|
|
285
|
+
const wHist = float( 1 ).sub( aTrust ).div( luminance( denoisedRgb ).mul( effFlicker ).mul( 10 ).add( 1 ) );
|
|
286
|
+
const wRaw = aTrust.div( luminance( denoisedRaw ).mul( effFlicker ).mul( 10 ).add( 1 ) );
|
|
287
|
+
return denoisedRgb.mul( wHist ).add( denoisedRaw.mul( wRaw ) ).div( wHist.add( wRaw ).max( EPSILON ) );
|
|
288
|
+
|
|
289
|
+
} ).setLayout( {
|
|
290
|
+
name: 'karisTemporalBlend',
|
|
291
|
+
type: 'vec3',
|
|
292
|
+
inputs: [
|
|
293
|
+
{ name: 'denoisedRgb', type: 'vec3' },
|
|
294
|
+
{ name: 'denoisedRaw', type: 'vec3' },
|
|
295
|
+
{ name: 'a', type: 'float' },
|
|
296
|
+
{ name: 'flickerSuppression', type: 'float' },
|
|
297
|
+
{ name: 'adaptiveTrust', type: 'float' },
|
|
298
|
+
{ name: 'nbhdMeanLuma', type: 'float' },
|
|
299
|
+
{ name: 'nbhdStddevLuma', type: 'float' }
|
|
300
|
+
]
|
|
301
|
+
} );
|
|
302
|
+
|
|
303
|
+
const toTextureNode = ( value ) => {
|
|
304
|
+
|
|
305
|
+
if ( value === null ) return null;
|
|
306
|
+
|
|
307
|
+
if ( value.isTexture === true ) return texture( value );
|
|
308
|
+
|
|
309
|
+
return convertToTexture( value.getTextureNode?.() ?? value );
|
|
310
|
+
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* @typedef {'diffuse'|'specular'} DenoiseMode
|
|
315
|
+
*/
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* @typedef {'raylength'|'ao'|'none'} DenoiseAlphaSource
|
|
319
|
+
*/
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* @typedef {Object} RecurrentDenoiseNodeOptions
|
|
323
|
+
* @property {?Node<float>} [depth=null] - Scene depth buffer for view-space edge stopping.
|
|
324
|
+
* @property {?Node<vec3>} [normal=null] - View-space normals for geometric edge stopping.
|
|
325
|
+
* @property {?Node<vec4>} [metalRoughness=null] - Roughness/metalness G-buffer for specular edge stopping.
|
|
326
|
+
* @property {?Node<vec4>} [diffuse=null] - Scene base color (albedo) G-buffer for chromatic edge stopping.
|
|
327
|
+
* @property {?Node<vec4>} [raw=null] - Unfiltered input (e.g. raw SSR/SSGI) for secondary sampling and temporal blend.
|
|
328
|
+
* @property {DenoiseMode} [mode='diffuse'] - Denoising kernel type.
|
|
329
|
+
* @property {boolean} [accumulate=true] - When `true`, temporally blend the spatially-denoised result
|
|
330
|
+
* (Karis-style) and write frame weight to alpha for feedback loops. When `false`, only spatial filtering is applied.
|
|
331
|
+
*/
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Post processing node for denoising temporally-accumulated screen-space effects
|
|
335
|
+
* such as SSGI (ambient occlusion / indirect diffuse) and SSR (specular reflections).
|
|
336
|
+
*
|
|
337
|
+
* The denoising kernel is selected at construction time via `mode`:
|
|
338
|
+
* `'diffuse'` (SSGI) or `'specular'` (SSR). The kernel uses a fixed 8-sample Vogel disk.
|
|
339
|
+
*
|
|
340
|
+
* @augments TempNode
|
|
341
|
+
* @three_import import { recurrentDenoise } from 'three/addons/tsl/display/RecurrentDenoiseNode.js';
|
|
342
|
+
*/
|
|
343
|
+
class RecurrentDenoiseNode extends TempNode {
|
|
344
|
+
|
|
345
|
+
static get type() {
|
|
346
|
+
|
|
347
|
+
return 'RecurrentDenoiseNode';
|
|
348
|
+
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* @param {TextureNode} inputTexture - Temporally filtered input to denoise (e.g. TRAA output).
|
|
353
|
+
* @param {Camera} camera
|
|
354
|
+
* @param {RecurrentDenoiseNodeOptions} [options={}]
|
|
355
|
+
*/
|
|
356
|
+
constructor( inputTexture, camera, options = {} ) {
|
|
357
|
+
|
|
358
|
+
super( 'vec4' );
|
|
359
|
+
|
|
360
|
+
const {
|
|
361
|
+
depth = null,
|
|
362
|
+
normal = null,
|
|
363
|
+
metalRoughness = null,
|
|
364
|
+
diffuse = null,
|
|
365
|
+
raw = null,
|
|
366
|
+
mode = 'diffuse',
|
|
367
|
+
accumulate = true,
|
|
368
|
+
} = options;
|
|
369
|
+
|
|
370
|
+
this.isRecurrentDenoiseNode = true;
|
|
371
|
+
this.camera = camera;
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Denoising kernel type.
|
|
375
|
+
*
|
|
376
|
+
* @type {DenoiseMode}
|
|
377
|
+
*/
|
|
378
|
+
this.mode = mode;
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* When `true`, apply temporal blending after spatial denoising. When `false`, output spatially
|
|
382
|
+
* filtered colour only (alpha is passed through from the input temporal pass).
|
|
383
|
+
*
|
|
384
|
+
* @type {boolean}
|
|
385
|
+
*/
|
|
386
|
+
this.accumulate = accumulate;
|
|
387
|
+
|
|
388
|
+
this.textureNode = inputTexture;
|
|
389
|
+
this.depthNode = depth !== null ? nodeObject( depth ) : null;
|
|
390
|
+
this.normalNode = normal !== null ? nodeObject( normal ) : null;
|
|
391
|
+
this.rawNode = toTextureNode( raw );
|
|
392
|
+
this.roughnessMetalnessNode = metalRoughness !== null ? nodeObject( metalRoughness ) : null;
|
|
393
|
+
this.diffuseNode = diffuse !== null ? nodeObject( diffuse ) : null;
|
|
394
|
+
|
|
395
|
+
this._noiseIndex = uniform( 0 );
|
|
396
|
+
|
|
397
|
+
this.lumaPhi = uniform( 5 );
|
|
398
|
+
this.depthPhi = uniform( 5 );
|
|
399
|
+
this.normalPhi = uniform( 5 );
|
|
400
|
+
this.radius = uniform( 5 );
|
|
401
|
+
this.alphaPhi = uniform( 1 );
|
|
402
|
+
this.roughnessPhi = uniform( 100 );
|
|
403
|
+
this.diffusePhi = uniform( 100 );
|
|
404
|
+
this.adapt = uniform( 0.5 );
|
|
405
|
+
this.smoothDisocclusions = uniform( true, 'bool' );
|
|
406
|
+
this.strength = uniform( 0.25 );
|
|
407
|
+
this.maxFrames = uniform( 32 );
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Which channel of the raw texture drives alpha-based edge stopping.
|
|
411
|
+
* `'raylength'` — alpha encodes SSR ray length; `'ao'` — alpha encodes AO factor;
|
|
412
|
+
* `'none'` — skip alpha-based edge stopping.
|
|
413
|
+
*
|
|
414
|
+
* @type {DenoiseAlphaSource}
|
|
415
|
+
* @default 'raylength'
|
|
416
|
+
*/
|
|
417
|
+
this.alphaSource = 'raylength';
|
|
418
|
+
|
|
419
|
+
this.flickerSuppression = uniform( 1 );
|
|
420
|
+
this.adaptiveTrust = uniform( 0 );
|
|
421
|
+
|
|
422
|
+
this.updateBeforeType = NodeUpdateType.FRAME;
|
|
423
|
+
|
|
424
|
+
this._resolution = uniform( new Vector2() );
|
|
425
|
+
this._fovY = uniform( MathUtils.degToRad( camera.fov ) );
|
|
426
|
+
this._cameraProjectionMatrixInverse = uniform( new Matrix4().copy( camera.projectionMatrixInverse ) );
|
|
427
|
+
this._cameraProjectionMatrix = uniform( new Matrix4().copy( camera.projectionMatrix ) );
|
|
428
|
+
this._viewMatrix = uniform( new Matrix4().copy( camera.matrixWorldInverse ) );
|
|
429
|
+
|
|
430
|
+
this._renderTarget = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
|
|
431
|
+
this._renderTarget.texture.name = 'RecurrentDenoiseNode.output';
|
|
432
|
+
|
|
433
|
+
this._material = new NodeMaterial();
|
|
434
|
+
this._material.name = 'RecurrentDenoise';
|
|
435
|
+
|
|
436
|
+
this._textureNode = passTexture( this, this._renderTarget.texture );
|
|
437
|
+
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
setSize( width, height ) {
|
|
441
|
+
|
|
442
|
+
if ( width === null || height === null ) return;
|
|
443
|
+
|
|
444
|
+
this._renderTarget.setSize( width, height );
|
|
445
|
+
this._resolution.value.set( width, height );
|
|
446
|
+
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
getTextureNode() {
|
|
450
|
+
|
|
451
|
+
return this._textureNode;
|
|
452
|
+
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Returns the internal output render target (e.g. for temporal reprojection/SSGI temporal feedback loops).
|
|
457
|
+
*
|
|
458
|
+
* @returns {RenderTarget}
|
|
459
|
+
*/
|
|
460
|
+
getRenderTarget() {
|
|
461
|
+
|
|
462
|
+
return this._renderTarget;
|
|
463
|
+
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
updateBefore( frame ) {
|
|
467
|
+
|
|
468
|
+
const { renderer } = frame;
|
|
469
|
+
|
|
470
|
+
const drawingBufferSize = renderer.getDrawingBufferSize( _size );
|
|
471
|
+
const width = drawingBufferSize.width;
|
|
472
|
+
const height = drawingBufferSize.height;
|
|
473
|
+
|
|
474
|
+
const needsRestart = this._renderTarget.width !== width || this._renderTarget.height !== height;
|
|
475
|
+
this.setSize( width, height );
|
|
476
|
+
|
|
477
|
+
this._cameraProjectionMatrix.value.copy( this.camera.projectionMatrix );
|
|
478
|
+
this._cameraProjectionMatrixInverse.value.copy( this.camera.projectionMatrixInverse );
|
|
479
|
+
this._viewMatrix.value.copy( this.camera.matrixWorldInverse );
|
|
480
|
+
|
|
481
|
+
if ( this.camera.isPerspectiveCamera ) {
|
|
482
|
+
|
|
483
|
+
this._fovY.value = MathUtils.degToRad( this.camera.fov );
|
|
484
|
+
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if ( frame.frameId !== undefined ) this._noiseIndex.value = frame.frameId;
|
|
488
|
+
|
|
489
|
+
// Denoise renders via an internal _quadMesh, not through the RenderPipeline output graph.
|
|
490
|
+
// Upstream passes (e.g. TemporalReprojectNode) referenced by a PassTextureNode input are
|
|
491
|
+
// otherwise never scheduled, their updateBefore() would not run and this pass would sample
|
|
492
|
+
// a stale/empty render target.
|
|
493
|
+
if ( this.textureNode.isPassTextureNode === true ) frame.updateBeforeNode( this.textureNode.passNode );
|
|
494
|
+
|
|
495
|
+
_rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
|
|
496
|
+
|
|
497
|
+
if ( needsRestart === true ) {
|
|
498
|
+
|
|
499
|
+
renderer.initRenderTarget( this._renderTarget );
|
|
500
|
+
renderer.setRenderTarget( this._renderTarget );
|
|
501
|
+
renderer.clear();
|
|
502
|
+
renderer.setRenderTarget( null );
|
|
503
|
+
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
renderer.setRenderTarget( this._renderTarget );
|
|
507
|
+
_quadMesh.material = this._material;
|
|
508
|
+
_quadMesh.name = 'RecurrentDenoise';
|
|
509
|
+
_quadMesh.render( renderer );
|
|
510
|
+
renderer.setRenderTarget( null );
|
|
511
|
+
|
|
512
|
+
RendererUtils.restoreRendererState( renderer, _rendererState );
|
|
513
|
+
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
setup( builder ) {
|
|
517
|
+
|
|
518
|
+
const sampleAnalyticNoise = bindAnalyticNoise( this._resolution, NOISE_ROTATION_SEED );
|
|
519
|
+
|
|
520
|
+
const noiseRotationMatrix = Fn( ( [ r ] ) => {
|
|
521
|
+
|
|
522
|
+
const angle = r.mul( 2 ).mul( PI );
|
|
523
|
+
return mat2( cos( angle ), sin( angle ).negate(), sin( angle ), cos( angle ) );
|
|
524
|
+
|
|
525
|
+
} );
|
|
526
|
+
|
|
527
|
+
const sampleTexture = ( uvCoord ) => texture( this.textureNode, uvCoord ).max( 0 );
|
|
528
|
+
const sampleRaw = ( uvCoord ) => this.rawNode?.sample( uvCoord )?.max( 0 ) ?? vec3( 0 ).max( 0 );
|
|
529
|
+
const sampleDepth = ( uvCoord ) => this.depthNode?.sample( uvCoord )?.x ?? float( 0.5 );
|
|
530
|
+
const sampleNormal = ( uvCoord ) => unpackRGBToNormal( this.normalNode?.sample( uvCoord )?.rgb ?? vec3( 0, 0, 1 ) );
|
|
531
|
+
const sampleRoughnessMetalness = ( uvCoord ) => this.roughnessMetalnessNode?.sample( uvCoord )?.rg ?? vec2( 0, 1 );
|
|
532
|
+
const sampleDiffuse = ( uvCoord ) => this.diffuseNode?.sample( uvCoord )?.rgb ?? vec3( 0 );
|
|
533
|
+
|
|
534
|
+
// Neighborhood luma moments for the adaptive-trust (firefly) gating of the temporal blend.
|
|
535
|
+
const getNeighborhoodStats = Fn( ( [ uvCoord, centerSample ] ) => {
|
|
536
|
+
|
|
537
|
+
const rlSum = float( 0 ).toVar();
|
|
538
|
+
const rlSumW = float( 0 ).toVar();
|
|
539
|
+
const meanLuma = float( 0 ).toVar();
|
|
540
|
+
const m2Luma = float( 0 ).toVar();
|
|
541
|
+
const lumaCount = float( 0 ).toVar();
|
|
542
|
+
const hasEnvRay = bool( false ).toVar();
|
|
543
|
+
|
|
544
|
+
// 4-tap cross (pre-sampled center + 4 axis neighbors) instead of a full 3×3 — about half the fetches.
|
|
545
|
+
// The center tap reuses the caller's already-sampled raw texel.
|
|
546
|
+
const accumulate = ( dx, dy, sample ) => {
|
|
547
|
+
|
|
548
|
+
const neighbor = sample !== undefined
|
|
549
|
+
? sample
|
|
550
|
+
: texture( this.rawNode, uvCoord.add( vec2( dx, dy ).div( this._resolution ) ) ).max( 0 ).toConst();
|
|
551
|
+
|
|
552
|
+
if ( this.alphaSource === 'raylength' ) {
|
|
553
|
+
|
|
554
|
+
const sampleRl = neighbor.a.toVar();
|
|
555
|
+
If( sampleRl.greaterThan( ENV_RAY_LENGTH_THRESHOLD ), () => {
|
|
556
|
+
|
|
557
|
+
sampleRl.assign( 0.25 );
|
|
558
|
+
hasEnvRay.assign( true );
|
|
559
|
+
|
|
560
|
+
} );
|
|
561
|
+
const w = float( 1 ).div( sampleRl.add( 0.001 ) );
|
|
562
|
+
rlSum.addAssign( sampleRl.mul( w ) );
|
|
563
|
+
rlSumW.addAssign( w );
|
|
564
|
+
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
If( this.adaptiveTrust.greaterThan( 0 ), () => {
|
|
568
|
+
|
|
569
|
+
const nLuma = luminance( neighbor.rgb );
|
|
570
|
+
lumaCount.addAssign( 1 );
|
|
571
|
+
const delta = nLuma.sub( meanLuma ).toConst();
|
|
572
|
+
meanLuma.addAssign( delta.div( lumaCount ) );
|
|
573
|
+
m2Luma.addAssign( delta.mul( nLuma.sub( meanLuma ) ) );
|
|
574
|
+
|
|
575
|
+
} );
|
|
576
|
+
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
accumulate( 0, 0, centerSample );
|
|
580
|
+
accumulate( - 1, 0 );
|
|
581
|
+
accumulate( 1, 0 );
|
|
582
|
+
accumulate( 0, - 1 );
|
|
583
|
+
accumulate( 0, 1 );
|
|
584
|
+
|
|
585
|
+
const avgRayLength = this.alphaSource === 'raylength' ? rlSum.div( rlSumW ) : float( 1 );
|
|
586
|
+
const stddevLuma = sqrt( m2Luma.div( lumaCount.max( 1 ) ) );
|
|
587
|
+
|
|
588
|
+
// vec3( avgRayLength, meanLuma, stddevLuma )
|
|
589
|
+
return vec4( avgRayLength, meanLuma, stddevLuma, hasEnvRay.toFloat() );
|
|
590
|
+
|
|
591
|
+
} ).setLayout( {
|
|
592
|
+
name: 'getNeighborhoodStats',
|
|
593
|
+
type: 'vec4',
|
|
594
|
+
inputs: [
|
|
595
|
+
{ name: 'uvCoord', type: 'vec2' },
|
|
596
|
+
{ name: 'centerSample', type: 'vec4' }
|
|
597
|
+
]
|
|
598
|
+
} );
|
|
599
|
+
|
|
600
|
+
const denoiseFn = Fn( ( [ uvCoord ] ) => {
|
|
601
|
+
|
|
602
|
+
const result = property( 'vec4' );
|
|
603
|
+
|
|
604
|
+
const depth = sampleDepth( uvCoord ).toConst();
|
|
605
|
+
|
|
606
|
+
const runDenoise = () => {
|
|
607
|
+
|
|
608
|
+
const viewNormal = sampleNormal( uvCoord ).toConst();
|
|
609
|
+
const worldNormal = viewNormal.transformDirection( this._viewMatrix ).toConst();
|
|
610
|
+
const texel = sampleTexture( uvCoord ).max( 0 ).toConst();
|
|
611
|
+
|
|
612
|
+
const viewPosition = getViewPosition( uvCoord, depth, this._cameraProjectionMatrixInverse ).toConst();
|
|
613
|
+
const roughnessMetalness = sampleRoughnessMetalness( uvCoord ).toConst();
|
|
614
|
+
const roughness = roughnessMetalness.g;
|
|
615
|
+
const metalness = roughnessMetalness.r;
|
|
616
|
+
|
|
617
|
+
const noiseTexel = sampleAnalyticNoise( uvCoord, this._noiseIndex );
|
|
618
|
+
const rotationMatrix = noiseRotationMatrix( noiseTexel.r );
|
|
619
|
+
|
|
620
|
+
const frameNum = float( 1 ).div( texel.a );
|
|
621
|
+
const varianceFactor = getTemporalVarianceFactor( frameNum, this.strength.oneMinus() );
|
|
622
|
+
const aggressivity = varianceFactor.oneMinus();
|
|
623
|
+
|
|
624
|
+
const raw = sampleRaw( uvCoord ).toConst();
|
|
625
|
+
|
|
626
|
+
const viewZ = abs( viewPosition.z );
|
|
627
|
+
const rl = float( 1 ).toVar();
|
|
628
|
+
const nbhdMeanLuma = float( 0 ).toVar();
|
|
629
|
+
const nbhdStddevLuma = float( 0 ).toVar();
|
|
630
|
+
const hasEnvRay = bool( false ).toVar();
|
|
631
|
+
|
|
632
|
+
if ( this.alphaSource === 'raylength' ) {
|
|
633
|
+
|
|
634
|
+
const stats = getNeighborhoodStats( uvCoord, raw );
|
|
635
|
+
rl.assign( stats.x );
|
|
636
|
+
nbhdMeanLuma.assign( stats.y );
|
|
637
|
+
nbhdStddevLuma.assign( stats.z );
|
|
638
|
+
hasEnvRay.assign( stats.w.greaterThan( 0.5 ) );
|
|
639
|
+
|
|
640
|
+
} else {
|
|
641
|
+
|
|
642
|
+
If( this.adaptiveTrust.greaterThan( 0 ), () => {
|
|
643
|
+
|
|
644
|
+
const stats = getNeighborhoodStats( uvCoord, raw );
|
|
645
|
+
nbhdMeanLuma.assign( stats.y );
|
|
646
|
+
nbhdStddevLuma.assign( stats.z );
|
|
647
|
+
|
|
648
|
+
} );
|
|
649
|
+
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const tanHalfFovY = this.alphaSource === 'raylength' ? tan( this._fovY.mul( 0.5 ) ).toConst() : null;
|
|
653
|
+
const hitDistFactor = this.alphaSource === 'raylength'
|
|
654
|
+
? computeHitDistFactor( rl, viewZ, tanHalfFovY ).toConst()
|
|
655
|
+
: float( 1 );
|
|
656
|
+
|
|
657
|
+
const denoised = texel.rgb.toVar();
|
|
658
|
+
const totalWeight = float( 1 ).toVar();
|
|
659
|
+
const denoisedFrame = frameNum.toVar();
|
|
660
|
+
const totalFrameWeight = float( 1 ).toVar();
|
|
661
|
+
|
|
662
|
+
const denoisedRaw = raw.rgb.toVar();
|
|
663
|
+
const totalWeightRaw = float( 1 ).toVar();
|
|
664
|
+
|
|
665
|
+
If( raw.rgb.length().lessThan( 0.0001 ), () => {
|
|
666
|
+
|
|
667
|
+
denoisedRaw.assign( vec3( 0 ) );
|
|
668
|
+
totalWeightRaw.assign( 0 );
|
|
669
|
+
|
|
670
|
+
} );
|
|
671
|
+
|
|
672
|
+
const avgAo = this.alphaSource === 'ao' ? raw.a.toConst() : float( 1 );
|
|
673
|
+
const mappedAvgAo = this.alphaSource === 'ao' ? mapAo( avgAo ) : float( 0 );
|
|
674
|
+
|
|
675
|
+
const worldRadius = this.radius.mul( WORLD_RADIUS_SCALE ).toVar();
|
|
676
|
+
|
|
677
|
+
if ( this.mode === 'specular' ) {
|
|
678
|
+
|
|
679
|
+
worldRadius.mulAssign( rl.mul( viewPosition.z.abs() ) );
|
|
680
|
+
worldRadius.mulAssign( roughness.sqrt().max( 0.01 ) );
|
|
681
|
+
|
|
682
|
+
} else {
|
|
683
|
+
|
|
684
|
+
worldRadius.mulAssign( avgAo.pow( 2 ).mul( viewPosition.z.abs() ) );
|
|
685
|
+
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
worldRadius.mulAssign( mix( 1, AGGRESSIVITY_RADIUS_MIN, aggressivity ) );
|
|
689
|
+
|
|
690
|
+
const T = vec3( 0 ).toVar();
|
|
691
|
+
const B = vec3( 0 ).toVar();
|
|
692
|
+
|
|
693
|
+
if ( this.mode === 'specular' ) {
|
|
694
|
+
|
|
695
|
+
const V = normalize( viewPosition ).negate();
|
|
696
|
+
const D = getSpecularDominantDirection( viewNormal, V, roughness );
|
|
697
|
+
const R = reflect( D.negate(), viewNormal );
|
|
698
|
+
const Tv = normalize( cross( viewNormal, R ) );
|
|
699
|
+
const Bv = cross( R, Tv );
|
|
700
|
+
const viewAngle = abs( viewNormal.z ).acos().div( float( Math.PI * 0.5 ) ).clamp( 0, 1 );
|
|
701
|
+
const skewFactor = mix( 1.0, roughness, viewAngle );
|
|
702
|
+
T.assign( Tv.mul( skewFactor ) );
|
|
703
|
+
B.assign( Bv );
|
|
704
|
+
|
|
705
|
+
} else {
|
|
706
|
+
|
|
707
|
+
const up = vec3( 0, 0, 1 );
|
|
708
|
+
const Tv = cross( up, viewNormal ).normalize().toVar();
|
|
709
|
+
If( Tv.length().lessThan( EPSILON ), () => {
|
|
710
|
+
|
|
711
|
+
Tv.assign( cross( vec3( 0, 1, 0 ), viewNormal ).normalize() );
|
|
712
|
+
|
|
713
|
+
} );
|
|
714
|
+
T.assign( Tv );
|
|
715
|
+
B.assign( cross( viewNormal, Tv ).normalize() );
|
|
716
|
+
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
T.mulAssign( worldRadius );
|
|
720
|
+
B.mulAssign( worldRadius );
|
|
721
|
+
|
|
722
|
+
const centerDiffuse = sampleDiffuse( uvCoord ).toConst();
|
|
723
|
+
const radiusShrink = float( 1 ).toVar();
|
|
724
|
+
|
|
725
|
+
// Directional analog of radiusShrink: an accumulated tangent-space shift that skews
|
|
726
|
+
// subsequent taps toward directions that yielded high weight (related geometry).
|
|
727
|
+
const polarBias = vec2( 0 ).toVar();
|
|
728
|
+
|
|
729
|
+
const depthWeightScale = this.depthPhi.mul( 500 ).mul( viewNormal.z.abs() ).div( viewPosition.z.abs() );
|
|
730
|
+
|
|
731
|
+
// Lobe geometry depends only on per-pixel terms, so compute its falloff constant once here.
|
|
732
|
+
const lobeFalloff = lobeNormalFalloff( roughness, aggressivity, this.normalPhi.oneMinus() ).toConst();
|
|
733
|
+
|
|
734
|
+
Loop( { start: int( 0 ), end: int( KERNEL_SAMPLES ), type: 'int', condition: '<', name: 'i' }, ( { i } ) => {
|
|
735
|
+
|
|
736
|
+
const baseOffset = vogelDisk( float( i ), 1 ).toVar();
|
|
737
|
+
const sampleDir = baseOffset.normalize().toConst();
|
|
738
|
+
|
|
739
|
+
// Blend the tap direction toward the polar bias, then restore the Vogel radius and shrink.
|
|
740
|
+
const skewedDir = mix( sampleDir, polarBias.max( EPSILON ).normalize(), this.adapt.mul( aggressivity )
|
|
741
|
+
.mul( polarBias.dot( polarBias ).greaterThan( 0.001 ).select( 1, 0 ) ) );
|
|
742
|
+
const offset = rotationMatrix.mul( skewedDir.mul( baseOffset.length().mul( radiusShrink ) ) ).toVar();
|
|
743
|
+
|
|
744
|
+
// Exact per-sample view-space projection (both paths)
|
|
745
|
+
const sampleViewPos = viewPosition.add( B.mul( offset.x ).add( T.mul( offset.y ) ) );
|
|
746
|
+
const sampleUv = getScreenPosition( sampleViewPos, this._cameraProjectionMatrix ).toVar();
|
|
747
|
+
sampleUv.assign( sampleUv.abs().oneMinus().abs().oneMinus().clamp() );
|
|
748
|
+
|
|
749
|
+
const neighborColor = sampleTexture( sampleUv ).max( 0 ).toConst();
|
|
750
|
+
|
|
751
|
+
// When no raw texture is bound, sampleRaw falls back to the filtered texture at the same UV.
|
|
752
|
+
const rawNeighborColor = sampleRaw( sampleUv ).max( 0 ).toVar();
|
|
753
|
+
// if ( this.mode === 'diffuse' ) rawNeighborColor.rgb.assign( mix( neighborColor.rgb, rawNeighborColor.rgb, neighborColor.a ) );
|
|
754
|
+
|
|
755
|
+
const nDepth = sampleDepth( sampleUv );
|
|
756
|
+
const nViewPosition = getViewPosition( sampleUv, nDepth, this._cameraProjectionMatrixInverse ).toConst();
|
|
757
|
+
const nViewZ = abs( nViewPosition.z ).toConst();
|
|
758
|
+
|
|
759
|
+
const kernelDiff = float( 0 ).toVar();
|
|
760
|
+
|
|
761
|
+
// Luma edge stopping
|
|
762
|
+
kernelDiff.addAssign( luminance( rawNeighborColor.rgb ).sub( luminance( raw.rgb ) ).abs().mul( this.lumaPhi ).mul( 10 ) );
|
|
763
|
+
|
|
764
|
+
// Diffuse edge stopping (only relevant for specular mode)
|
|
765
|
+
if ( this.diffuseNode !== null ) {
|
|
766
|
+
|
|
767
|
+
kernelDiff.addAssign( ( diffuseColorDistance( centerDiffuse, sampleDiffuse( sampleUv ), float( 0 ) ).mul( this.diffusePhi ).mul( metalness ) ) );
|
|
768
|
+
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// AO edge stopping
|
|
772
|
+
if ( this.alphaSource === 'ao' ) {
|
|
773
|
+
|
|
774
|
+
const neighborMappedAo = mapAo( rawNeighborColor.a );
|
|
775
|
+
// We multiply here with aggressivity as well, since early application of aoW yields noise
|
|
776
|
+
const aoW = mappedAvgAo.div( mappedAvgAo.add( neighborMappedAo ).add( AO_EDGE_STOPPING_BIAS ) ).mul( this.alphaPhi ).mul( aggressivity );
|
|
777
|
+
|
|
778
|
+
kernelDiff.addAssign( ( aoW ) );
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
} else if ( this.alphaSource === 'raylength' ) {
|
|
782
|
+
|
|
783
|
+
// Ray length edge stopping
|
|
784
|
+
|
|
785
|
+
const neighborHitDistFactor = computeHitDistFactor( rawNeighborColor.a, nViewZ, tanHalfFovY );
|
|
786
|
+
const hdfDiff = hitDistFactor.sub( neighborHitDistFactor ).abs();
|
|
787
|
+
|
|
788
|
+
const rayLengthFactor = hdfDiff.mul( this.alphaPhi ).div( viewPosition.z.abs() );
|
|
789
|
+
|
|
790
|
+
// Env rays are harder to compare so we accept if this sample is an env ray and there is an env ray in the neighborhood
|
|
791
|
+
kernelDiff.addAssign( rawNeighborColor.a.greaterThan( ENV_RAY_LENGTH_THRESHOLD ).and( hasEnvRay ).select( 1, rayLengthFactor ) );
|
|
792
|
+
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// Roughness edge stopping
|
|
796
|
+
if ( this.mode === 'specular' ) kernelDiff.addAssign( ( abs( roughness.sub( sampleRoughnessMetalness( sampleUv ).g ) ).mul( this.roughnessPhi ) ) );
|
|
797
|
+
|
|
798
|
+
const nViewNormal = sampleNormal( sampleUv );
|
|
799
|
+
const nWorldNormal = nViewNormal.transformDirection( this._viewMatrix );
|
|
800
|
+
const distToPlane = planeDistance( viewPosition, nViewPosition, viewNormal );
|
|
801
|
+
|
|
802
|
+
// Geometric edge stopping (depth and normal)
|
|
803
|
+
const depthDiff = distToPlane.mul( depthWeightScale );
|
|
804
|
+
const normalW = lobeNormalWeight( worldNormal, nWorldNormal, lobeFalloff );
|
|
805
|
+
|
|
806
|
+
// Sum every negative-exponent edge-stopping term (kernel + depth/plane, plus the SSR hit-distance term)
|
|
807
|
+
const w = exp( kernelDiff.mul( aggressivity ).add( depthDiff ).negate() ).mul( normalW ).toVar();
|
|
808
|
+
|
|
809
|
+
// Feedback to shrink radius based on the weight
|
|
810
|
+
radiusShrink.assign( mix( radiusShrink, w, this.adapt ) );
|
|
811
|
+
|
|
812
|
+
// Polar feedback: skew subsequent taps toward high-weight directions (related geometry)
|
|
813
|
+
polarBias.assign( mix( polarBias, sampleDir.mul( w.sub( 0.5 ) ), 0.5 ) );
|
|
814
|
+
|
|
815
|
+
// to mitigate the effect of fireflies and high variance in recently disoccluded regions, we weigh by the inverse luminance for the first 5 frames
|
|
816
|
+
w.mulAssign( mix( float( 1 ).div( luminance( rawNeighborColor.rgb ).pow( 2 ).add( 0.01 ) ), 1, frameNum.div( 5 ).min( 1 ) ) );
|
|
817
|
+
|
|
818
|
+
denoisedRaw.addAssign( rawNeighborColor.rgb.mul( w ) );
|
|
819
|
+
totalWeightRaw.addAssign( w );
|
|
820
|
+
|
|
821
|
+
denoised.addAssign( neighborColor.rgb.mul( w ) );
|
|
822
|
+
totalWeight.addAssign( w );
|
|
823
|
+
|
|
824
|
+
// Denoising the alpha (accumulation speed), to get smoother disocclusion transitions
|
|
825
|
+
If( this.smoothDisocclusions, () => {
|
|
826
|
+
|
|
827
|
+
const neighborAWeight = neighborColor.a.greaterThan( texel.a ).select( w.mul( 0.33 ), 0 );
|
|
828
|
+
denoisedFrame.addAssign( float( 1 ).div( neighborColor.a ).mul( neighborAWeight ) );
|
|
829
|
+
totalFrameWeight.addAssign( neighborAWeight );
|
|
830
|
+
|
|
831
|
+
} );
|
|
832
|
+
|
|
833
|
+
} );
|
|
834
|
+
|
|
835
|
+
denoised.divAssign( totalWeight.max( EPSILON ) );
|
|
836
|
+
denoised.assign( denoised.max( EPSILON ) );
|
|
837
|
+
denoisedRaw.divAssign( totalWeightRaw.max( EPSILON ) );
|
|
838
|
+
|
|
839
|
+
if ( this.accumulate ) {
|
|
840
|
+
|
|
841
|
+
const computedFrame = denoisedFrame.div( totalFrameWeight.max( EPSILON ) );
|
|
842
|
+
const a = float( 1 ).div( computedFrame.max( EPSILON ) ).toConst();
|
|
843
|
+
|
|
844
|
+
if ( this.rawNode !== null ) {
|
|
845
|
+
|
|
846
|
+
const blended = karisTemporalBlend(
|
|
847
|
+
denoised,
|
|
848
|
+
denoisedRaw,
|
|
849
|
+
a,
|
|
850
|
+
this.flickerSuppression,
|
|
851
|
+
this.adaptiveTrust,
|
|
852
|
+
nbhdMeanLuma,
|
|
853
|
+
nbhdStddevLuma
|
|
854
|
+
);
|
|
855
|
+
|
|
856
|
+
result.assign( vec4( blended, a ) );
|
|
857
|
+
|
|
858
|
+
} else {
|
|
859
|
+
|
|
860
|
+
const finalDenoised = mix( denoised, denoisedRaw, a );
|
|
861
|
+
result.assign( vec4( finalDenoised, a ) );
|
|
862
|
+
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
} else {
|
|
866
|
+
|
|
867
|
+
result.assign( vec4( denoised, texel.a ) );
|
|
868
|
+
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
If( depth.greaterThanEqual( 1.0 ), () => {
|
|
874
|
+
|
|
875
|
+
Discard();
|
|
876
|
+
|
|
877
|
+
} ).Else( runDenoise );
|
|
878
|
+
|
|
879
|
+
return result;
|
|
880
|
+
|
|
881
|
+
} );
|
|
882
|
+
|
|
883
|
+
this._material.fragmentNode = denoiseFn( uv() ).context( builder.getSharedContext() );
|
|
884
|
+
this._material.needsUpdate = true;
|
|
885
|
+
|
|
886
|
+
return this._textureNode;
|
|
887
|
+
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
dispose() {
|
|
891
|
+
|
|
892
|
+
this._renderTarget.dispose();
|
|
893
|
+
this._material.dispose();
|
|
894
|
+
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
export default RecurrentDenoiseNode;
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* @tsl
|
|
903
|
+
* @param {Node} inputTexture - Temporally filtered input to denoise (e.g. TRAA output).
|
|
904
|
+
* @param {Camera} camera
|
|
905
|
+
* @param {RecurrentDenoiseNodeOptions} [options={}]
|
|
906
|
+
* @returns {RecurrentDenoiseNode}
|
|
907
|
+
*/
|
|
908
|
+
export const recurrentDenoise = ( inputTexture, camera, options = {} ) => nodeObject( new RecurrentDenoiseNode(
|
|
909
|
+
toTextureNode( inputTexture ),
|
|
910
|
+
camera,
|
|
911
|
+
options
|
|
912
|
+
) );
|