@plastic-software/three 0.179.0 → 0.181.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/three.cjs +1108 -591
- package/build/three.core.js +616 -345
- package/build/three.core.min.js +1 -1
- package/build/three.module.js +488 -250
- package/build/three.module.min.js +1 -1
- package/build/three.tsl.js +37 -6
- package/build/three.tsl.min.js +1 -1
- package/build/three.webgpu.js +6576 -2152
- package/build/three.webgpu.min.js +1 -1
- package/build/three.webgpu.nodes.js +6575 -2151
- package/build/three.webgpu.nodes.min.js +1 -1
- package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
- package/examples/fonts/MPLUSRounded1c/OFL.txt +91 -0
- package/examples/jsm/Addons.js +1 -1
- package/examples/jsm/animation/CCDIKSolver.js +1 -1
- package/examples/jsm/controls/ArcballControls.js +8 -8
- package/examples/jsm/controls/DragControls.js +7 -57
- package/examples/jsm/controls/FirstPersonControls.js +3 -3
- package/examples/jsm/controls/FlyControls.js +1 -1
- package/examples/jsm/controls/OrbitControls.js +2 -2
- package/examples/jsm/controls/PointerLockControls.js +2 -10
- package/examples/jsm/controls/TrackballControls.js +1 -1
- package/examples/jsm/controls/TransformControls.js +1 -1
- package/examples/jsm/effects/AsciiEffect.js +8 -8
- package/examples/jsm/exporters/DRACOExporter.js +2 -2
- package/examples/jsm/exporters/EXRExporter.js +1 -1
- package/examples/jsm/exporters/GLTFExporter.js +33 -25
- package/examples/jsm/exporters/KTX2Exporter.js +4 -2
- package/examples/jsm/exporters/PLYExporter.js +1 -1
- package/examples/jsm/exporters/USDZExporter.js +9 -2
- package/examples/jsm/geometries/DecalGeometry.js +2 -2
- package/examples/jsm/geometries/ParametricGeometry.js +1 -1
- package/examples/jsm/geometries/TeapotGeometry.js +2 -2
- package/examples/jsm/geometries/TextGeometry.js +3 -2
- package/examples/jsm/gpgpu/BitonicSort.js +715 -0
- package/examples/jsm/helpers/ViewHelper.js +43 -5
- package/examples/jsm/inspector/Inspector.js +427 -0
- package/examples/jsm/inspector/RendererInspector.js +415 -0
- package/examples/jsm/inspector/tabs/Console.js +204 -0
- package/examples/jsm/inspector/tabs/Parameters.js +332 -0
- package/examples/jsm/inspector/tabs/Performance.js +268 -0
- package/examples/jsm/inspector/tabs/Viewer.js +166 -0
- package/examples/jsm/inspector/ui/Graph.js +95 -0
- package/examples/jsm/inspector/ui/Item.js +170 -0
- package/examples/jsm/inspector/ui/List.js +75 -0
- package/examples/jsm/inspector/ui/Profiler.js +170 -0
- package/examples/jsm/inspector/ui/Style.js +654 -0
- package/examples/jsm/inspector/ui/Tab.js +46 -0
- package/examples/jsm/inspector/ui/Values.js +423 -0
- package/examples/jsm/inspector/ui/utils.js +56 -0
- package/examples/jsm/interactive/HTMLMesh.js +6 -10
- package/examples/jsm/interactive/InteractiveGroup.js +1 -1
- package/examples/jsm/interactive/SelectionBox.js +30 -0
- package/examples/jsm/libs/ktx-parse.module.js +1 -1
- package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
- package/examples/jsm/lines/Line2.js +3 -3
- package/examples/jsm/lines/LineGeometry.js +1 -1
- package/examples/jsm/lines/LineSegments2.js +2 -2
- package/examples/jsm/lines/Wireframe.js +2 -2
- package/examples/jsm/lines/WireframeGeometry2.js +1 -1
- package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
- package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
- package/examples/jsm/loaders/3MFLoader.js +1 -1
- package/examples/jsm/loaders/ColladaLoader.js +3 -3
- package/examples/jsm/loaders/DDSLoader.js +1 -1
- package/examples/jsm/loaders/DRACOLoader.js +73 -22
- package/examples/jsm/loaders/EXRLoader.js +5 -5
- package/examples/jsm/loaders/FBXLoader.js +2 -2
- package/examples/jsm/loaders/FontLoader.js +23 -5
- package/examples/jsm/loaders/GLTFLoader.js +14 -8
- package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
- package/examples/jsm/loaders/HDRLoader.js +486 -0
- package/examples/jsm/loaders/KTX2Loader.js +136 -49
- package/examples/jsm/loaders/KTXLoader.js +2 -2
- package/examples/jsm/loaders/LDrawLoader.js +1 -1
- package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
- package/examples/jsm/loaders/LUTCubeLoader.js +1 -1
- package/examples/jsm/loaders/LWOLoader.js +2 -2
- package/examples/jsm/loaders/MaterialXLoader.js +22 -5
- package/examples/jsm/loaders/OBJLoader.js +1 -1
- package/examples/jsm/loaders/PDBLoader.js +1 -1
- package/examples/jsm/loaders/RGBELoader.js +7 -473
- package/examples/jsm/loaders/SVGLoader.js +2 -2
- package/examples/jsm/loaders/TTFLoader.js +4 -4
- package/examples/jsm/loaders/UltraHDRLoader.js +2 -2
- package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
- package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
- package/examples/jsm/math/ColorSpaces.js +19 -1
- package/examples/jsm/math/ConvexHull.js +3 -3
- package/examples/jsm/math/ImprovedNoise.js +1 -1
- package/examples/jsm/math/Lut.js +2 -2
- package/examples/jsm/math/SimplexNoise.js +1 -1
- package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
- package/examples/jsm/misc/ProgressiveLightMap.js +9 -3
- package/examples/jsm/misc/ProgressiveLightMapGPU.js +7 -1
- package/examples/jsm/misc/TubePainter.js +383 -40
- package/examples/jsm/misc/Volume.js +1 -1
- package/examples/jsm/modifiers/SimplifyModifier.js +1 -1
- package/examples/jsm/objects/ReflectorForSSRPass.js +1 -0
- package/examples/jsm/objects/Sky.js +1 -1
- package/examples/jsm/objects/SkyMesh.js +1 -1
- package/examples/jsm/objects/Water.js +3 -3
- package/examples/jsm/objects/WaterMesh.js +6 -6
- package/examples/jsm/postprocessing/GlitchPass.js +2 -2
- package/examples/jsm/postprocessing/OutlinePass.js +1 -1
- package/examples/jsm/postprocessing/SSRPass.js +37 -8
- package/examples/jsm/postprocessing/UnrealBloomPass.js +8 -6
- package/examples/jsm/renderers/CSS2DRenderer.js +16 -5
- package/examples/jsm/renderers/CSS3DRenderer.js +7 -6
- package/examples/jsm/renderers/SVGRenderer.js +1 -1
- package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +1 -1
- package/examples/jsm/shaders/AfterimageShader.js +1 -1
- package/examples/jsm/shaders/BleachBypassShader.js +1 -1
- package/examples/jsm/shaders/BokehShader.js +1 -1
- package/examples/jsm/shaders/BokehShader2.js +1 -1
- package/examples/jsm/shaders/DotScreenShader.js +1 -1
- package/examples/jsm/shaders/FocusShader.js +1 -1
- package/examples/jsm/shaders/GTAOShader.js +2 -2
- package/examples/jsm/shaders/GodRaysShader.js +1 -1
- package/examples/jsm/shaders/KaleidoShader.js +1 -1
- package/examples/jsm/shaders/PoissonDenoiseShader.js +2 -2
- package/examples/jsm/shaders/SSRShader.js +1 -1
- package/examples/jsm/shaders/SepiaShader.js +1 -1
- package/examples/jsm/shaders/SubsurfaceScatteringShader.js +1 -1
- package/examples/jsm/shaders/TriangleBlurShader.js +1 -1
- package/examples/jsm/shaders/UnpackDepthRGBAShader.js +1 -1
- package/examples/jsm/shaders/VignetteShader.js +1 -1
- package/examples/jsm/transpiler/GLSLDecoder.js +22 -19
- package/examples/jsm/transpiler/TSLEncoder.js +9 -10
- package/examples/jsm/transpiler/WGSLEncoder.js +24 -0
- package/examples/jsm/tsl/display/AfterImageNode.js +26 -24
- package/examples/jsm/tsl/display/AnamorphicNode.js +28 -4
- package/examples/jsm/tsl/display/BloomNode.js +7 -3
- package/examples/jsm/tsl/display/ChromaticAberrationNode.js +2 -1
- package/examples/jsm/tsl/display/DenoiseNode.js +2 -0
- package/examples/jsm/tsl/display/DepthOfFieldNode.js +446 -90
- package/examples/jsm/tsl/display/GTAONode.js +53 -5
- package/examples/jsm/tsl/display/GaussianBlurNode.js +49 -35
- package/examples/jsm/tsl/display/OutlineNode.js +13 -2
- package/examples/jsm/tsl/display/SSGINode.js +654 -0
- package/examples/jsm/tsl/display/SSRNode.js +182 -65
- package/examples/jsm/tsl/display/SSSNode.js +488 -0
- package/examples/jsm/tsl/display/TRAANode.js +124 -7
- package/examples/jsm/tsl/display/boxBlur.js +65 -0
- package/examples/jsm/tsl/display/hashBlur.js +16 -18
- package/examples/jsm/tsl/lighting/TiledLightsNode.js +21 -1
- package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
- package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
- package/examples/jsm/webxr/OculusHandModel.js +1 -1
- package/examples/jsm/webxr/XRControllerModelFactory.js +1 -1
- package/examples/jsm/webxr/XRHandModelFactory.js +2 -6
- package/package.json +5 -10
- package/src/Three.Core.js +4 -2
- package/src/Three.TSL.js +36 -5
- package/src/Three.WebGPU.Nodes.js +2 -0
- package/src/Three.WebGPU.js +2 -0
- package/src/animation/AnimationClip.js +20 -4
- package/src/animation/AnimationMixer.js +3 -3
- package/src/animation/AnimationObjectGroup.js +2 -1
- package/src/animation/KeyframeTrack.js +7 -6
- package/src/animation/PropertyBinding.js +12 -11
- package/src/audio/Audio.js +10 -9
- package/src/audio/PositionalAudio.js +1 -1
- package/src/cameras/OrthographicCamera.js +1 -1
- package/src/cameras/PerspectiveCamera.js +1 -1
- package/src/cameras/StereoCamera.js +2 -2
- package/src/constants.js +11 -3
- package/src/core/BufferGeometry.js +10 -10
- package/src/core/EventDispatcher.js +1 -1
- package/src/core/InterleavedBuffer.js +1 -1
- package/src/core/InterleavedBufferAttribute.js +3 -2
- package/src/core/Object3D.js +3 -2
- package/src/core/Raycaster.js +2 -1
- package/src/core/RenderTarget.js +10 -1
- package/src/extras/Controls.js +5 -4
- package/src/extras/DataUtils.js +2 -1
- package/src/extras/Earcut.js +6 -0
- package/src/extras/ImageUtils.js +2 -2
- package/src/extras/PMREMGenerator.js +268 -55
- package/src/extras/TextureUtils.js +2 -1
- package/src/extras/core/Curve.js +2 -1
- package/src/extras/core/Interpolations.js +7 -1
- package/src/extras/core/ShapePath.js +4 -4
- package/src/extras/lib/earcut.js +8 -8
- package/src/geometries/BoxGeometry.js +1 -0
- package/src/geometries/CapsuleGeometry.js +1 -0
- package/src/geometries/CircleGeometry.js +1 -0
- package/src/geometries/ConeGeometry.js +1 -0
- package/src/geometries/CylinderGeometry.js +1 -0
- package/src/geometries/DodecahedronGeometry.js +1 -0
- package/src/geometries/ExtrudeGeometry.js +8 -6
- package/src/geometries/IcosahedronGeometry.js +1 -0
- package/src/geometries/LatheGeometry.js +1 -0
- package/src/geometries/OctahedronGeometry.js +1 -0
- package/src/geometries/PlaneGeometry.js +1 -0
- package/src/geometries/RingGeometry.js +1 -0
- package/src/geometries/ShapeGeometry.js +1 -0
- package/src/geometries/SphereGeometry.js +1 -0
- package/src/geometries/TetrahedronGeometry.js +1 -0
- package/src/geometries/TorusGeometry.js +1 -0
- package/src/geometries/TorusKnotGeometry.js +1 -0
- package/src/geometries/TubeGeometry.js +1 -0
- package/src/helpers/CameraHelper.js +1 -1
- package/src/lights/webgpu/ProjectorLight.js +1 -1
- package/src/loaders/AnimationLoader.js +2 -1
- package/src/loaders/AudioLoader.js +2 -1
- package/src/loaders/BufferGeometryLoader.js +2 -2
- package/src/loaders/Cache.js +2 -2
- package/src/loaders/DataTextureLoader.js +1 -1
- package/src/loaders/FileLoader.js +3 -2
- package/src/loaders/ImageBitmapLoader.js +5 -4
- package/src/loaders/ImageLoader.js +1 -1
- package/src/loaders/Loader.js +3 -3
- package/src/loaders/LoadingManager.js +25 -3
- package/src/loaders/MaterialLoader.js +3 -2
- package/src/loaders/ObjectLoader.js +13 -13
- package/src/loaders/TextureLoader.js +1 -1
- package/src/loaders/nodes/NodeLoader.js +3 -2
- package/src/materials/Material.js +16 -3
- package/src/materials/MeshBasicMaterial.js +1 -0
- package/src/materials/MeshDepthMaterial.js +1 -0
- package/src/materials/MeshDistanceMaterial.js +1 -1
- package/src/materials/MeshLambertMaterial.js +2 -1
- package/src/materials/MeshMatcapMaterial.js +22 -0
- package/src/materials/MeshNormalMaterial.js +1 -0
- package/src/materials/MeshPhongMaterial.js +2 -1
- package/src/materials/MeshPhysicalMaterial.js +2 -1
- package/src/materials/MeshStandardMaterial.js +8 -7
- package/src/materials/MeshToonMaterial.js +1 -0
- package/src/materials/PointsMaterial.js +1 -1
- package/src/materials/ShaderMaterial.js +2 -2
- package/src/materials/nodes/Line2NodeMaterial.js +2 -2
- package/src/materials/nodes/MeshSSSNodeMaterial.js +1 -1
- package/src/materials/nodes/NodeMaterial.js +62 -22
- package/src/materials/nodes/PointsNodeMaterial.js +81 -28
- package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
- package/src/materials/nodes/manager/NodeMaterialObserver.js +3 -2
- package/src/math/Color.js +6 -5
- package/src/math/ColorManagement.js +9 -3
- package/src/math/Cylindrical.js +1 -1
- package/src/math/Euler.js +2 -1
- package/src/math/MathUtils.js +13 -11
- package/src/math/Matrix2.js +1 -1
- package/src/math/Matrix3.js +2 -2
- package/src/math/Matrix4.js +7 -7
- package/src/math/Plane.js +1 -1
- package/src/math/Quaternion.js +68 -66
- package/src/math/Spherical.js +1 -1
- package/src/nodes/Nodes.js +4 -1
- package/src/nodes/TSL.js +4 -1
- package/src/nodes/accessors/BufferNode.js +1 -1
- package/src/nodes/accessors/Camera.js +133 -7
- package/src/nodes/accessors/ClippingNode.js +6 -5
- package/src/nodes/accessors/CubeTextureNode.js +5 -4
- package/src/nodes/accessors/InstanceNode.js +25 -5
- package/src/nodes/accessors/Lights.js +10 -0
- package/src/nodes/accessors/Normal.js +5 -4
- package/src/nodes/accessors/Object3DNode.js +1 -1
- package/src/nodes/accessors/Position.js +18 -2
- package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
- package/src/nodes/accessors/ReferenceNode.js +3 -2
- package/src/nodes/accessors/SceneNode.js +2 -1
- package/src/nodes/accessors/StorageBufferNode.js +2 -1
- package/src/nodes/accessors/StorageTextureNode.js +22 -0
- package/src/nodes/accessors/Texture3DNode.js +14 -1
- package/src/nodes/accessors/TextureNode.js +130 -44
- package/src/nodes/code/FunctionCallNode.js +24 -4
- package/src/nodes/code/FunctionNode.js +23 -0
- package/src/nodes/core/ArrayNode.js +1 -0
- package/src/nodes/core/AssignNode.js +4 -3
- package/src/nodes/core/AttributeNode.js +2 -1
- package/src/nodes/core/ContextNode.js +29 -10
- package/src/nodes/core/IndexNode.js +2 -2
- package/src/nodes/core/InputNode.js +2 -1
- package/src/nodes/core/InspectorNode.js +128 -0
- package/src/nodes/core/{CacheNode.js → IsolateNode.js} +40 -7
- package/src/nodes/core/Node.js +152 -31
- package/src/nodes/core/NodeBuilder.js +183 -35
- package/src/nodes/core/NodeFrame.js +21 -21
- package/src/nodes/core/NodeFunction.js +2 -1
- package/src/nodes/core/NodeParser.js +2 -1
- package/src/nodes/core/NodeUniform.js +1 -1
- package/src/nodes/core/NodeUtils.js +17 -91
- package/src/nodes/core/ParameterNode.js +31 -0
- package/src/nodes/core/PropertyNode.js +7 -0
- package/src/nodes/core/StackNode.js +43 -16
- package/src/nodes/core/StructNode.js +5 -5
- package/src/nodes/core/StructTypeNode.js +1 -0
- package/src/nodes/core/SubBuildNode.js +2 -2
- package/src/nodes/core/UniformNode.js +18 -10
- package/src/nodes/core/VarNode.js +70 -33
- package/src/nodes/core/VaryingNode.js +3 -2
- package/src/nodes/display/BlendModes.js +5 -4
- package/src/nodes/display/BumpMapNode.js +1 -1
- package/src/nodes/display/ColorAdjustment.js +1 -1
- package/src/nodes/display/FrontFacingNode.js +4 -8
- package/src/nodes/display/NormalMapNode.js +2 -1
- package/src/nodes/display/PassNode.js +52 -11
- package/src/nodes/display/RenderOutputNode.js +28 -2
- package/src/nodes/display/ScreenNode.js +44 -14
- package/src/nodes/display/ToneMappingNode.js +31 -4
- package/src/nodes/display/ToonOutlinePassNode.js +8 -0
- package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
- package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
- package/src/nodes/display/ViewportTextureNode.js +42 -12
- package/src/nodes/fog/Fog.js +3 -2
- package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +52 -0
- package/src/nodes/functions/BSDF/DFGApprox.js +60 -19
- package/src/nodes/functions/BasicLightingModel.js +2 -1
- package/src/nodes/functions/PhysicalLightingModel.js +3 -2
- package/src/nodes/functions/VolumetricLightingModel.js +5 -5
- package/src/nodes/geometry/RangeNode.js +40 -4
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +2 -1
- package/src/nodes/gpgpu/ComputeNode.js +17 -5
- package/src/nodes/gpgpu/SubgroupFunctionNode.js +455 -0
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -1
- package/src/nodes/lighting/EnvironmentNode.js +6 -6
- package/src/nodes/lighting/LightsNode.js +3 -4
- package/src/nodes/lighting/PointShadowNode.js +6 -0
- package/src/nodes/lighting/ShadowFilterNode.js +2 -0
- package/src/nodes/lighting/ShadowNode.js +75 -8
- package/src/nodes/math/BitcastNode.js +156 -0
- package/src/nodes/math/ConditionalNode.js +24 -7
- package/src/nodes/math/MathNode.js +25 -19
- package/src/nodes/math/OperatorNode.js +7 -5
- package/src/nodes/pmrem/PMREMUtils.js +117 -2
- package/src/nodes/shapes/Shapes.js +1 -1
- package/src/nodes/tsl/TSLBase.js +5 -2
- package/src/nodes/tsl/TSLCore.js +460 -159
- package/src/nodes/utils/DebugNode.js +2 -1
- package/src/nodes/utils/EventNode.js +36 -0
- package/src/nodes/utils/FunctionOverloadingNode.js +37 -19
- package/src/nodes/utils/JoinNode.js +6 -3
- package/src/nodes/utils/LoopNode.js +20 -24
- package/src/nodes/utils/MemberNode.js +59 -7
- package/src/nodes/utils/PostProcessingUtils.js +28 -1
- package/src/nodes/utils/RTTNode.js +13 -3
- package/src/nodes/utils/ReflectorNode.js +58 -7
- package/src/nodes/utils/SampleNode.js +12 -2
- package/src/nodes/utils/SplitNode.js +11 -0
- package/src/nodes/utils/Timer.js +0 -47
- package/src/objects/BatchedMesh.js +2 -2
- package/src/objects/LOD.js +1 -1
- package/src/objects/Line.js +2 -1
- package/src/objects/LineSegments.js +2 -1
- package/src/objects/Skeleton.js +3 -2
- package/src/objects/SkinnedMesh.js +3 -1
- package/src/objects/Sprite.js +4 -3
- package/src/renderers/WebGLRenderer.js +48 -41
- package/src/renderers/common/Animation.js +13 -1
- package/src/renderers/common/Attributes.js +1 -1
- package/src/renderers/common/Backend.js +108 -27
- package/src/renderers/common/Background.js +2 -1
- package/src/renderers/common/Bindings.js +58 -2
- package/src/renderers/common/CanvasTarget.js +341 -0
- package/src/renderers/common/ChainMap.js +1 -1
- package/src/renderers/common/DataMap.js +1 -1
- package/src/renderers/common/Geometries.js +26 -0
- package/src/renderers/common/Info.js +4 -2
- package/src/renderers/common/InspectorBase.js +146 -0
- package/src/renderers/common/Pipelines.js +1 -1
- package/src/renderers/common/PostProcessing.js +6 -25
- package/src/renderers/common/QuadMesh.js +7 -1
- package/src/renderers/common/RenderContext.js +2 -2
- package/src/renderers/common/RenderList.js +7 -3
- package/src/renderers/common/RenderObject.js +16 -2
- package/src/renderers/common/RenderObjects.js +1 -1
- package/src/renderers/common/Renderer.js +473 -245
- package/src/renderers/common/RendererUtils.js +9 -0
- package/src/renderers/common/SampledTexture.js +9 -1
- package/src/renderers/common/Sampler.js +50 -12
- package/src/renderers/common/StorageTexture.js +9 -1
- package/src/renderers/common/Textures.js +121 -45
- package/src/renderers/common/TimestampQueryPool.js +65 -3
- package/src/renderers/common/UniformsGroup.js +2 -1
- package/src/renderers/common/XRManager.js +42 -22
- package/src/renderers/common/extras/PMREMGenerator.js +160 -65
- package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
- package/src/renderers/common/nodes/NodeLibrary.js +9 -7
- package/src/renderers/common/nodes/NodeSampler.js +13 -1
- package/src/renderers/common/nodes/Nodes.js +38 -16
- package/src/renderers/shaders/DFGLUTData.js +64 -0
- package/src/renderers/shaders/ShaderChunk/common.glsl.js +0 -12
- package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +52 -18
- package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +7 -15
- package/src/renderers/shaders/ShaderLib/depth.glsl.js +1 -1
- package/src/renderers/shaders/UniformsLib.js +1 -0
- package/src/renderers/shaders/UniformsUtils.js +25 -4
- package/src/renderers/webgl/WebGLCapabilities.js +2 -1
- package/src/renderers/webgl/WebGLExtensions.js +2 -25
- package/src/renderers/webgl/WebGLInfo.js +3 -1
- package/src/renderers/webgl/WebGLProgram.js +15 -14
- package/src/renderers/webgl/WebGLPrograms.js +2 -1
- package/src/renderers/webgl/WebGLShadowMap.js +3 -2
- package/src/renderers/webgl/WebGLState.js +15 -14
- package/src/renderers/webgl/WebGLTextures.js +19 -14
- package/src/renderers/webgl/WebGLUniformsGroups.js +5 -3
- package/src/renderers/webgl/WebGLUtils.js +3 -2
- package/src/renderers/webgl-fallback/WebGLBackend.js +199 -167
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +181 -25
- package/src/renderers/webgl-fallback/utils/WebGLConstants.js +2 -3
- package/src/renderers/webgl-fallback/utils/WebGLState.js +7 -6
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +169 -19
- package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +51 -22
- package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
- package/src/renderers/webgpu/WebGPUBackend.js +153 -123
- package/src/renderers/webgpu/WebGPURenderer.Nodes.js +2 -1
- package/src/renderers/webgpu/WebGPURenderer.js +3 -2
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +142 -50
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +2 -1
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +5 -3
- package/src/renderers/webgpu/utils/WebGPUConstants.js +7 -2
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +53 -34
- package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +6 -8
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +260 -99
- package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +32 -9
- package/src/renderers/webgpu/utils/WebGPUUtils.js +22 -2
- package/src/renderers/webxr/WebXRManager.js +42 -26
- package/src/textures/ExternalTexture.js +15 -4
- package/src/textures/Source.js +3 -2
- package/src/textures/Texture.js +3 -2
- package/src/textures/VideoTexture.js +2 -3
- package/src/utils.js +67 -3
- package/examples/jsm/loaders/RGBMLoader.js +0 -1148
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
import { RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, RendererUtils, MathUtils } from 'three/webgpu';
|
|
2
|
+
import { clamp, normalize, reference, nodeObject, Fn, NodeUpdateType, uniform, vec4, passTexture, uv, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getViewPosition, screenCoordinate, float, sub, fract, dot, vec2, rand, vec3, Loop, mul, PI, cos, sin, uint, cross, acos, sign, pow, luminance, If, max, abs, Break, sqrt, HALF_PI, div, ceil, shiftRight, convertToTexture, bool, getNormalFromDepth, interleavedGradientNoise } from 'three/tsl';
|
|
3
|
+
|
|
4
|
+
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
5
|
+
const _size = /*@__PURE__*/ new Vector2();
|
|
6
|
+
|
|
7
|
+
// From Activision GTAO paper: https://www.activision.com/cdn/research/s2016_pbs_activision_occlusion.pptx
|
|
8
|
+
const _temporalRotations = [ 60, 300, 180, 240, 120, 0 ];
|
|
9
|
+
const _spatialOffsets = [ 0, 0.5, 0.25, 0.75 ];
|
|
10
|
+
|
|
11
|
+
let _rendererState;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Post processing node for applying Screen Space Global Illumination (SSGI) to a scene.
|
|
15
|
+
*
|
|
16
|
+
* References:
|
|
17
|
+
* - {@link https://github.com/cdrinmatane/SSRT3}.
|
|
18
|
+
* - {@link https://cdrinmatane.github.io/posts/ssaovb-code/}.
|
|
19
|
+
* - {@link https://cdrinmatane.github.io/cgspotlight-slides/ssilvb_slides.pdf}.
|
|
20
|
+
*
|
|
21
|
+
* The quality and performance of the effect mainly depend on `sliceCount` and `stepCount`.
|
|
22
|
+
* The total number of samples taken per pixel is `sliceCount` * `stepCount` * `2`. Here are some
|
|
23
|
+
* recommended presets depending on whether temporal filtering is used or not.
|
|
24
|
+
*
|
|
25
|
+
* With temporal filtering (recommended):
|
|
26
|
+
*
|
|
27
|
+
* - Low: `sliceCount` of `1`, `stepCount` of `12`.
|
|
28
|
+
* - Medium: `sliceCount` of `2`, `stepCount` of `8`.
|
|
29
|
+
* - High: `sliceCount` of `3`, `stepCount` of `16`.
|
|
30
|
+
*
|
|
31
|
+
* Use for a higher slice count if you notice temporal instabilities like flickering. Reduce the sample
|
|
32
|
+
* count then to mitigate the performance lost.
|
|
33
|
+
*
|
|
34
|
+
* Without temporal filtering:
|
|
35
|
+
*
|
|
36
|
+
* - Low: `sliceCount` of `2`, `stepCount` of `6`.
|
|
37
|
+
* - Medium: `sliceCount` of `3`, `stepCount` of `8`.
|
|
38
|
+
* - High: `sliceCount` of `4`, `stepCount` of `12`.
|
|
39
|
+
*
|
|
40
|
+
* @augments TempNode
|
|
41
|
+
* @three_import import { ssgi } from 'three/addons/tsl/display/SSGINode.js';
|
|
42
|
+
*/
|
|
43
|
+
class SSGINode extends TempNode {
|
|
44
|
+
|
|
45
|
+
static get type() {
|
|
46
|
+
|
|
47
|
+
return 'SSGINode';
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Constructs a new SSGI node.
|
|
53
|
+
*
|
|
54
|
+
* @param {TextureNode} beautyNode - A texture node that represents the beauty or scene pass.
|
|
55
|
+
* @param {TextureNode} depthNode - A texture node that represents the scene's depth.
|
|
56
|
+
* @param {TextureNode} normalNode - A texture node that represents the scene's normals.
|
|
57
|
+
* @param {PerspectiveCamera} camera - The camera the scene is rendered with.
|
|
58
|
+
*/
|
|
59
|
+
constructor( beautyNode, depthNode, normalNode, camera ) {
|
|
60
|
+
|
|
61
|
+
super( 'vec4' );
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A texture node that represents the beauty or scene pass.
|
|
65
|
+
*
|
|
66
|
+
* @type {TextureNode}
|
|
67
|
+
*/
|
|
68
|
+
this.beautyNode = beautyNode;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A node that represents the scene's depth.
|
|
72
|
+
*
|
|
73
|
+
* @type {TextureNode}
|
|
74
|
+
*/
|
|
75
|
+
this.depthNode = depthNode;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A node that represents the scene's normals. If no normals are passed to the
|
|
79
|
+
* constructor (because MRT is not available), normals can be automatically
|
|
80
|
+
* reconstructed from depth values in the shader.
|
|
81
|
+
*
|
|
82
|
+
* @type {TextureNode}
|
|
83
|
+
*/
|
|
84
|
+
this.normalNode = normalNode;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
|
|
88
|
+
* its effect once per frame in `updateBefore()`.
|
|
89
|
+
*
|
|
90
|
+
* @type {string}
|
|
91
|
+
* @default 'frame'
|
|
92
|
+
*/
|
|
93
|
+
this.updateBeforeType = NodeUpdateType.FRAME;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Number of per-pixel hemisphere slices. This has a big performance cost and should be kept as low as possible.
|
|
97
|
+
* Should be in the range `[1, 4]`.
|
|
98
|
+
*
|
|
99
|
+
* @type {UniformNode<uint>}
|
|
100
|
+
* @default 1
|
|
101
|
+
*/
|
|
102
|
+
this.sliceCount = uniform( 1, 'uint' );
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Number of samples taken along one side of a given hemisphere slice. This has a big performance cost and should
|
|
106
|
+
* be kept as low as possible. Should be in the range `[1, 32]`.
|
|
107
|
+
*
|
|
108
|
+
* @type {UniformNode<uint>}
|
|
109
|
+
* @default 12
|
|
110
|
+
*/
|
|
111
|
+
this.stepCount = uniform( 12, 'uint' );
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Power function applied to AO to make it appear darker/lighter. Should be in the range `[0, 4]`.
|
|
115
|
+
*
|
|
116
|
+
* @type {UniformNode<float>}
|
|
117
|
+
* @default 1
|
|
118
|
+
*/
|
|
119
|
+
this.aoIntensity = uniform( 1, 'float' );
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Intensity of the indirect diffuse light. Should be in the range `[0, 100]`.
|
|
123
|
+
*
|
|
124
|
+
* @type {UniformNode<float>}
|
|
125
|
+
* @default 10
|
|
126
|
+
*/
|
|
127
|
+
this.giIntensity = uniform( 10, 'float' );
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Effective sampling radius in world space. AO and GI can only have influence within that radius.
|
|
131
|
+
* Should be in the range `[1, 25]`.
|
|
132
|
+
*
|
|
133
|
+
* @type {UniformNode<float>}
|
|
134
|
+
* @default 12
|
|
135
|
+
*/
|
|
136
|
+
this.radius = uniform( 12, 'float' );
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Makes the sample distance in screen space instead of world-space (helps having more detail up close).
|
|
140
|
+
*
|
|
141
|
+
* @type {UniformNode<bool>}
|
|
142
|
+
* @default false
|
|
143
|
+
*/
|
|
144
|
+
this.useScreenSpaceSampling = uniform( true, 'bool' );
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Controls samples distribution. It's an exponent applied at each step get increasing step size over the distance.
|
|
148
|
+
* Should be in the range `[1, 3]`.
|
|
149
|
+
*
|
|
150
|
+
* @type {UniformNode<float>}
|
|
151
|
+
* @default 2
|
|
152
|
+
*/
|
|
153
|
+
this.expFactor = uniform( 2, 'float' );
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Constant thickness value of objects on the screen in world units. Allows light to pass behind surfaces past that thickness value.
|
|
157
|
+
* Should be in the range `[0.01, 10]`.
|
|
158
|
+
*
|
|
159
|
+
* @type {UniformNode<float>}
|
|
160
|
+
* @default 1
|
|
161
|
+
*/
|
|
162
|
+
this.thickness = uniform( 1, 'float' );
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Whether to increase thickness linearly over distance or not (avoid losing detail over the distance).
|
|
166
|
+
*
|
|
167
|
+
* @type {UniformNode<bool>}
|
|
168
|
+
* @default false
|
|
169
|
+
*/
|
|
170
|
+
this.useLinearThickness = uniform( false, 'bool' );
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* How much light backface surfaces emit.
|
|
174
|
+
* Should be in the range `[0, 1]`.
|
|
175
|
+
*
|
|
176
|
+
* @type {UniformNode<float>}
|
|
177
|
+
* @default 0
|
|
178
|
+
*/
|
|
179
|
+
this.backfaceLighting = uniform( 0, 'float' );
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Whether to use temporal filtering or not. Setting this property to
|
|
183
|
+
* `true` requires the usage of `TRAANode`. This will help to reduce noise
|
|
184
|
+
* although it introduces typical TAA artifacts like ghosting and temporal
|
|
185
|
+
* instabilities.
|
|
186
|
+
*
|
|
187
|
+
* If setting this property to `false`, a manual denoise via `DenoiseNode`
|
|
188
|
+
* is required.
|
|
189
|
+
*
|
|
190
|
+
* @type {boolean}
|
|
191
|
+
* @default true
|
|
192
|
+
*/
|
|
193
|
+
this.useTemporalFiltering = true;
|
|
194
|
+
|
|
195
|
+
// private uniforms
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* The resolution of the effect.
|
|
199
|
+
*
|
|
200
|
+
* @type {UniformNode<vec2>}
|
|
201
|
+
*/
|
|
202
|
+
this._resolution = uniform( new Vector2() );
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Used to compute the effective step radius when viewSpaceSampling is `false`.
|
|
206
|
+
*
|
|
207
|
+
* @type {UniformNode<vec2>}
|
|
208
|
+
*/
|
|
209
|
+
this._halfProjScale = uniform( 1 );
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Temporal direction that influences the rotation angle for each slice.
|
|
213
|
+
*
|
|
214
|
+
* @type {UniformNode<float>}
|
|
215
|
+
*/
|
|
216
|
+
this._temporalDirection = uniform( 0 );
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Temporal offset added to the initial ray step.
|
|
220
|
+
*
|
|
221
|
+
* @type {UniformNode<float>}
|
|
222
|
+
*/
|
|
223
|
+
this._temporalOffset = uniform( 0 );
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Represents the projection matrix of the scene's camera.
|
|
227
|
+
*
|
|
228
|
+
* @private
|
|
229
|
+
* @type {UniformNode<mat4>}
|
|
230
|
+
*/
|
|
231
|
+
this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Represents the inverse projection matrix of the scene's camera.
|
|
235
|
+
*
|
|
236
|
+
* @private
|
|
237
|
+
* @type {UniformNode<mat4>}
|
|
238
|
+
*/
|
|
239
|
+
this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Represents the near value of the scene's camera.
|
|
243
|
+
*
|
|
244
|
+
* @private
|
|
245
|
+
* @type {ReferenceNode<float>}
|
|
246
|
+
*/
|
|
247
|
+
this._cameraNear = reference( 'near', 'float', camera );
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Represents the far value of the scene's camera.
|
|
251
|
+
*
|
|
252
|
+
* @private
|
|
253
|
+
* @type {ReferenceNode<float>}
|
|
254
|
+
*/
|
|
255
|
+
this._cameraFar = reference( 'far', 'float', camera );
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* A reference to the scene's camera.
|
|
259
|
+
*
|
|
260
|
+
* @private
|
|
261
|
+
* @type {PerspectiveCamera}
|
|
262
|
+
*/
|
|
263
|
+
this._camera = camera;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* The render target the GI is rendered into.
|
|
267
|
+
*
|
|
268
|
+
* @private
|
|
269
|
+
* @type {RenderTarget}
|
|
270
|
+
*/
|
|
271
|
+
this._ssgiRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false } );
|
|
272
|
+
this._ssgiRenderTarget.texture.name = 'SSGI';
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* The material that is used to render the effect.
|
|
276
|
+
*
|
|
277
|
+
* @private
|
|
278
|
+
* @type {NodeMaterial}
|
|
279
|
+
*/
|
|
280
|
+
this._material = new NodeMaterial();
|
|
281
|
+
this._material.name = 'SSGI';
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* The result of the effect is represented as a separate texture node.
|
|
285
|
+
*
|
|
286
|
+
* @private
|
|
287
|
+
* @type {PassTextureNode}
|
|
288
|
+
*/
|
|
289
|
+
this._textureNode = passTexture( this, this._ssgiRenderTarget.texture );
|
|
290
|
+
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Returns the result of the effect as a texture node.
|
|
295
|
+
*
|
|
296
|
+
* @return {PassTextureNode} A texture node that represents the result of the effect.
|
|
297
|
+
*/
|
|
298
|
+
getTextureNode() {
|
|
299
|
+
|
|
300
|
+
return this._textureNode;
|
|
301
|
+
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Sets the size of the effect.
|
|
306
|
+
*
|
|
307
|
+
* @param {number} width - The width of the effect.
|
|
308
|
+
* @param {number} height - The height of the effect.
|
|
309
|
+
*/
|
|
310
|
+
setSize( width, height ) {
|
|
311
|
+
|
|
312
|
+
this._resolution.value.set( width, height );
|
|
313
|
+
this._ssgiRenderTarget.setSize( width, height );
|
|
314
|
+
|
|
315
|
+
this._halfProjScale.value = height / ( Math.tan( this._camera.fov * MathUtils.DEG2RAD * 0.5 ) * 2 ) * 0.5;
|
|
316
|
+
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* This method is used to render the effect once per frame.
|
|
321
|
+
*
|
|
322
|
+
* @param {NodeFrame} frame - The current node frame.
|
|
323
|
+
*/
|
|
324
|
+
updateBefore( frame ) {
|
|
325
|
+
|
|
326
|
+
const { renderer } = frame;
|
|
327
|
+
|
|
328
|
+
_rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
|
|
329
|
+
|
|
330
|
+
//
|
|
331
|
+
|
|
332
|
+
const size = renderer.getDrawingBufferSize( _size );
|
|
333
|
+
this.setSize( size.width, size.height );
|
|
334
|
+
|
|
335
|
+
// update temporal uniforms
|
|
336
|
+
|
|
337
|
+
if ( this.useTemporalFiltering === true ) {
|
|
338
|
+
|
|
339
|
+
const frameId = frame.frameId;
|
|
340
|
+
|
|
341
|
+
this._temporalDirection.value = _temporalRotations[ frameId % 6 ] / 360;
|
|
342
|
+
this._temporalOffset.value = _spatialOffsets[ frameId % 4 ];
|
|
343
|
+
|
|
344
|
+
} else {
|
|
345
|
+
|
|
346
|
+
this._temporalDirection.value = 1;
|
|
347
|
+
this._temporalOffset.value = 1;
|
|
348
|
+
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
//
|
|
352
|
+
|
|
353
|
+
_quadMesh.material = this._material;
|
|
354
|
+
_quadMesh.name = 'SSGI';
|
|
355
|
+
|
|
356
|
+
// clear
|
|
357
|
+
|
|
358
|
+
renderer.setClearColor( 0x000000, 1 );
|
|
359
|
+
|
|
360
|
+
// gi
|
|
361
|
+
|
|
362
|
+
renderer.setRenderTarget( this._ssgiRenderTarget );
|
|
363
|
+
_quadMesh.render( renderer );
|
|
364
|
+
|
|
365
|
+
// restore
|
|
366
|
+
|
|
367
|
+
RendererUtils.restoreRendererState( renderer, _rendererState );
|
|
368
|
+
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* This method is used to setup the effect's TSL code.
|
|
373
|
+
*
|
|
374
|
+
* @param {NodeBuilder} builder - The current node builder.
|
|
375
|
+
* @return {PassTextureNode}
|
|
376
|
+
*/
|
|
377
|
+
setup( builder ) {
|
|
378
|
+
|
|
379
|
+
const uvNode = uv();
|
|
380
|
+
const MAX_RAY = uint( 32 );
|
|
381
|
+
const globalOccludedBitfield = uint( 0 );
|
|
382
|
+
|
|
383
|
+
const sampleDepth = ( uv ) => {
|
|
384
|
+
|
|
385
|
+
const depth = this.depthNode.sample( uv ).r;
|
|
386
|
+
|
|
387
|
+
if ( builder.renderer.logarithmicDepthBuffer === true ) {
|
|
388
|
+
|
|
389
|
+
const viewZ = logarithmicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
|
|
390
|
+
|
|
391
|
+
return viewZToPerspectiveDepth( viewZ, this._cameraNear, this._cameraFar );
|
|
392
|
+
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return depth;
|
|
396
|
+
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.sample( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this._cameraProjectionMatrixInverse );
|
|
400
|
+
const sampleBeauty = ( uv ) => this.beautyNode.sample( uv );
|
|
401
|
+
|
|
402
|
+
// From Activision GTAO paper: https://www.activision.com/cdn/research/s2016_pbs_activision_occlusion.pptx
|
|
403
|
+
|
|
404
|
+
const spatialOffsets = Fn( ( [ position ] ) => {
|
|
405
|
+
|
|
406
|
+
return float( 0.25 ).mul( sub( position.y, position.x ).bitAnd( 3 ) );
|
|
407
|
+
|
|
408
|
+
} ).setLayout( {
|
|
409
|
+
name: 'spatialOffsets',
|
|
410
|
+
type: 'float',
|
|
411
|
+
inputs: [
|
|
412
|
+
{ name: 'position', type: 'vec2' }
|
|
413
|
+
]
|
|
414
|
+
} );
|
|
415
|
+
|
|
416
|
+
const GTAOFastAcos = Fn( ( [ value ] ) => {
|
|
417
|
+
|
|
418
|
+
const outVal = abs( value ).mul( float( - 0.156583 ) ).add( HALF_PI );
|
|
419
|
+
outVal.mulAssign( sqrt( abs( value ).oneMinus() ) );
|
|
420
|
+
|
|
421
|
+
const x = value.x.greaterThanEqual( 0 ).select( outVal.x, PI.sub( outVal.x ) );
|
|
422
|
+
const y = value.y.greaterThanEqual( 0 ).select( outVal.y, PI.sub( outVal.y ) );
|
|
423
|
+
|
|
424
|
+
return vec2( x, y );
|
|
425
|
+
|
|
426
|
+
} ).setLayout( {
|
|
427
|
+
name: 'GTAOFastAcos',
|
|
428
|
+
type: 'vec2',
|
|
429
|
+
inputs: [
|
|
430
|
+
{ name: 'value', type: 'vec2' }
|
|
431
|
+
]
|
|
432
|
+
} );
|
|
433
|
+
|
|
434
|
+
const bitCount = Fn( ( [ value ] ) => {
|
|
435
|
+
|
|
436
|
+
const v = uint( value );
|
|
437
|
+
v.assign( v.sub( v.shiftRight( uint( 1 ) ).bitAnd( uint( 0x55555555 ) ) ) );
|
|
438
|
+
v.assign( v.bitAnd( uint( 0x33333333 ) ).add( v.shiftRight( uint( 2 ) ).bitAnd( uint( 0x33333333 ) ) ) );
|
|
439
|
+
|
|
440
|
+
return v.add( v.shiftRight( uint( 4 ) ) ).bitAnd( uint( 0xF0F0F0F ) ).mul( uint( 0x1010101 ) ).shiftRight( uint( 24 ) );
|
|
441
|
+
|
|
442
|
+
} ).setLayout( {
|
|
443
|
+
name: 'bitCount',
|
|
444
|
+
type: 'uint',
|
|
445
|
+
inputs: [
|
|
446
|
+
{ name: 'value', type: 'uint' }
|
|
447
|
+
]
|
|
448
|
+
} );
|
|
449
|
+
|
|
450
|
+
const horizonSampling = Fn( ( [ directionIsRight, RADIUS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ] ) => {
|
|
451
|
+
|
|
452
|
+
const STEP_COUNT = this.stepCount.toConst();
|
|
453
|
+
const EXP_FACTOR = this.expFactor.toConst();
|
|
454
|
+
const THICKNESS = this.thickness.toConst();
|
|
455
|
+
const BACKFACE_LIGHTING = this.backfaceLighting.toConst();
|
|
456
|
+
|
|
457
|
+
const stepRadius = float( 0 );
|
|
458
|
+
|
|
459
|
+
If( this.useScreenSpaceSampling.equal( true ), () => {
|
|
460
|
+
|
|
461
|
+
stepRadius.assign( RADIUS.mul( this._resolution.x.div( 2 ) ).div( float( 16 ) ) ); // SSRT3 has a bug where stepRadius is divided by STEP_COUNT twice; fix here
|
|
462
|
+
|
|
463
|
+
} ).Else( () => {
|
|
464
|
+
|
|
465
|
+
stepRadius.assign( max( RADIUS.mul( this._halfProjScale ).div( viewPosition.z.negate() ), float( STEP_COUNT ) ) ); // Port note: viewZ is negative so a negate is required
|
|
466
|
+
|
|
467
|
+
} );
|
|
468
|
+
|
|
469
|
+
stepRadius.divAssign( float( STEP_COUNT ).add( 1 ) );
|
|
470
|
+
const radiusVS = max( 1, float( STEP_COUNT.sub( 1 ) ) ).mul( stepRadius );
|
|
471
|
+
const uvDirection = directionIsRight.equal( true ).select( vec2( 1, - 1 ), vec2( - 1, 1 ) ); // Port note: Because of different uv conventions, uv-y has a different sign
|
|
472
|
+
const samplingDirection = directionIsRight.equal( true ).select( 1, - 1 );
|
|
473
|
+
|
|
474
|
+
const color = vec3( 0 );
|
|
475
|
+
|
|
476
|
+
const lastSampleViewPosition = vec3( viewPosition ).toVar();
|
|
477
|
+
|
|
478
|
+
Loop( { start: uint( 0 ), end: STEP_COUNT, type: 'uint', condition: '<' }, ( { i } ) => {
|
|
479
|
+
|
|
480
|
+
const offset = pow( abs( mul( stepRadius, float( i ).add( initialRayStep ) ).div( radiusVS ) ), EXP_FACTOR ).mul( radiusVS ).toConst();
|
|
481
|
+
const uvOffset = slideDirTexelSize.mul( max( offset, float( i ).add( 1 ) ) ).toConst();
|
|
482
|
+
const sampleUV = uvNode.add( uvOffset.mul( uvDirection ) ).toConst();
|
|
483
|
+
|
|
484
|
+
If( sampleUV.x.lessThanEqual( 0 ).or( sampleUV.y.lessThanEqual( 0 ) ).or( sampleUV.x.greaterThanEqual( 1 ) ).or( sampleUV.y.greaterThanEqual( 1 ) ), () => {
|
|
485
|
+
|
|
486
|
+
Break();
|
|
487
|
+
|
|
488
|
+
} );
|
|
489
|
+
|
|
490
|
+
const sampleViewPosition = getViewPosition( sampleUV, sampleDepth( sampleUV ), this._cameraProjectionMatrixInverse ).toConst();
|
|
491
|
+
const pixelToSample = sampleViewPosition.sub( viewPosition ).normalize().toConst();
|
|
492
|
+
const linearThicknessMultiplier = this.useLinearThickness.equal( true ).select( sampleViewPosition.z.negate().div( this._cameraFar ).clamp().mul( 100 ), float( 1 ) );
|
|
493
|
+
const pixelToSampleBackface = normalize( sampleViewPosition.sub( linearThicknessMultiplier.mul( viewDir ).mul( THICKNESS ) ).sub( viewPosition ) );
|
|
494
|
+
|
|
495
|
+
let frontBackHorizon = vec2( dot( pixelToSample, viewDir ), dot( pixelToSampleBackface, viewDir ) );
|
|
496
|
+
frontBackHorizon = GTAOFastAcos( clamp( frontBackHorizon, - 1, 1 ) );
|
|
497
|
+
frontBackHorizon = clamp( div( mul( samplingDirection, frontBackHorizon.negate() ).sub( n.sub( HALF_PI ) ), PI ) ); // Port note: subtract half pi instead of adding it
|
|
498
|
+
frontBackHorizon = directionIsRight.equal( true ).select( frontBackHorizon.yx, frontBackHorizon.xy ); // Front/Back get inverted depending on angle
|
|
499
|
+
|
|
500
|
+
// inline ComputeOccludedBitfield() for easier debugging
|
|
501
|
+
|
|
502
|
+
const minHorizon = frontBackHorizon.x.toConst();
|
|
503
|
+
const maxHorizon = frontBackHorizon.y.toConst();
|
|
504
|
+
|
|
505
|
+
const startHorizonInt = uint( frontBackHorizon.mul( float( MAX_RAY ) ) ).toConst();
|
|
506
|
+
const angleHorizonInt = uint( ceil( maxHorizon.sub( minHorizon ).mul( float( MAX_RAY ) ) ) ).toConst();
|
|
507
|
+
const angleHorizonBitfield = angleHorizonInt.greaterThan( uint( 0 ) ).select( uint( shiftRight( uint( 0xFFFFFFFF ), uint( 32 ).sub( MAX_RAY ).add( MAX_RAY.sub( angleHorizonInt ) ) ) ), uint( 0 ) ).toConst();
|
|
508
|
+
let currentOccludedBitfield = angleHorizonBitfield.shiftLeft( startHorizonInt );
|
|
509
|
+
currentOccludedBitfield = currentOccludedBitfield.bitAnd( globalOccludedBitfield.bitNot() );
|
|
510
|
+
|
|
511
|
+
globalOccludedBitfield.assign( globalOccludedBitfield.bitOr( currentOccludedBitfield ) );
|
|
512
|
+
const numOccludedZones = bitCount( currentOccludedBitfield );
|
|
513
|
+
|
|
514
|
+
//
|
|
515
|
+
|
|
516
|
+
If( numOccludedZones.greaterThan( 0 ), () => { // If a ray hit the sample, that sample is visible from shading point
|
|
517
|
+
|
|
518
|
+
const lightColor = sampleBeauty( sampleUV );
|
|
519
|
+
|
|
520
|
+
If( luminance( lightColor ).greaterThan( 0.001 ), () => { // Continue if there is light at that location (intensity > 0)
|
|
521
|
+
|
|
522
|
+
const lightDirectionVS = normalize( pixelToSample );
|
|
523
|
+
const normalDotLightDirection = clamp( dot( viewNormal, lightDirectionVS ) );
|
|
524
|
+
|
|
525
|
+
If( normalDotLightDirection.greaterThan( 0.001 ), () => { // Continue if light is facing surface normal
|
|
526
|
+
|
|
527
|
+
const lightNormalVS = sampleNormal( sampleUV );
|
|
528
|
+
|
|
529
|
+
// Intensity of outgoing light in the direction of the shading point
|
|
530
|
+
|
|
531
|
+
let lightNormalDotLightDirection = dot( lightNormalVS, lightDirectionVS.negate() );
|
|
532
|
+
|
|
533
|
+
const d = sign( lightNormalDotLightDirection ).lessThan( 0 ).select( abs( lightNormalDotLightDirection ).mul( BACKFACE_LIGHTING ), abs( lightNormalDotLightDirection ) );
|
|
534
|
+
lightNormalDotLightDirection = BACKFACE_LIGHTING.greaterThan( 0 ).and( dot( lightNormalVS, viewDir ).greaterThan( 0 ) ).select( d, clamp( lightNormalDotLightDirection ) );
|
|
535
|
+
|
|
536
|
+
color.rgb.addAssign( float( numOccludedZones ).div( float( MAX_RAY ) ).mul( lightColor ).mul( normalDotLightDirection ).mul( lightNormalDotLightDirection ) );
|
|
537
|
+
|
|
538
|
+
} );
|
|
539
|
+
|
|
540
|
+
} );
|
|
541
|
+
|
|
542
|
+
} );
|
|
543
|
+
|
|
544
|
+
lastSampleViewPosition.assign( sampleViewPosition );
|
|
545
|
+
|
|
546
|
+
} );
|
|
547
|
+
|
|
548
|
+
return vec3( color );
|
|
549
|
+
|
|
550
|
+
} );
|
|
551
|
+
|
|
552
|
+
const gi = Fn( () => {
|
|
553
|
+
|
|
554
|
+
const depth = sampleDepth( uvNode ).toVar();
|
|
555
|
+
|
|
556
|
+
depth.greaterThanEqual( 1.0 ).discard();
|
|
557
|
+
|
|
558
|
+
const viewPosition = getViewPosition( uvNode, depth, this._cameraProjectionMatrixInverse ).toVar();
|
|
559
|
+
const viewNormal = sampleNormal( uvNode ).toVar();
|
|
560
|
+
const viewDir = normalize( viewPosition.xyz.negate() ).toVar();
|
|
561
|
+
|
|
562
|
+
//
|
|
563
|
+
|
|
564
|
+
const noiseOffset = spatialOffsets( screenCoordinate );
|
|
565
|
+
const noiseDirection = interleavedGradientNoise( screenCoordinate );
|
|
566
|
+
const noiseJitterIdx = this._temporalDirection.mul( 0.02 ); // Port: Add noiseJitterIdx here for slightly better noise convergence with TRAA (see #31890 for more details)
|
|
567
|
+
const initialRayStep = fract( noiseOffset.add( this._temporalOffset ) ).add( rand( uvNode.add( noiseJitterIdx ).mul( 2 ).sub( 1 ) ) );
|
|
568
|
+
|
|
569
|
+
const ao = float( 0 );
|
|
570
|
+
const color = vec3( 0 );
|
|
571
|
+
|
|
572
|
+
const ROTATION_COUNT = this.sliceCount.toConst();
|
|
573
|
+
const AO_INTENSITY = this.aoIntensity.toConst();
|
|
574
|
+
const GI_INTENSITY = this.giIntensity.toConst();
|
|
575
|
+
const RADIUS = this.radius.toConst();
|
|
576
|
+
|
|
577
|
+
Loop( { start: uint( 0 ), end: ROTATION_COUNT, type: 'uint', condition: '<' }, ( { i } ) => {
|
|
578
|
+
|
|
579
|
+
const rotationAngle = mul( float( i ).add( noiseDirection ).add( this._temporalDirection ), PI.div( float( ROTATION_COUNT ) ) ).toConst();
|
|
580
|
+
const sliceDir = vec3( vec2( cos( rotationAngle ), sin( rotationAngle ) ), 0 ).toConst();
|
|
581
|
+
const slideDirTexelSize = sliceDir.xy.mul( float( 1 ).div( this._resolution ) ).toConst();
|
|
582
|
+
|
|
583
|
+
const planeNormal = normalize( cross( sliceDir, viewDir ) ).toConst();
|
|
584
|
+
const tangent = cross( viewDir, planeNormal ).toConst();
|
|
585
|
+
const projectedNormal = viewNormal.sub( planeNormal.mul( dot( viewNormal, planeNormal ) ) ).toConst();
|
|
586
|
+
const projectedNormalNormalized = normalize( projectedNormal ).toConst();
|
|
587
|
+
|
|
588
|
+
const cos_n = clamp( dot( projectedNormalNormalized, viewDir ), - 1, 1 ).toConst();
|
|
589
|
+
const n = sign( dot( projectedNormal, tangent ) ).negate().mul( acos( cos_n ) ).toConst();
|
|
590
|
+
|
|
591
|
+
globalOccludedBitfield.assign( 0 );
|
|
592
|
+
|
|
593
|
+
color.addAssign( horizonSampling( bool( true ), RADIUS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ) );
|
|
594
|
+
color.addAssign( horizonSampling( bool( false ), RADIUS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ) );
|
|
595
|
+
|
|
596
|
+
ao.addAssign( float( bitCount( globalOccludedBitfield ) ).div( float( MAX_RAY ) ) );
|
|
597
|
+
|
|
598
|
+
} );
|
|
599
|
+
|
|
600
|
+
ao.divAssign( float( ROTATION_COUNT ) );
|
|
601
|
+
ao.assign( pow( ao.clamp().oneMinus(), AO_INTENSITY ).clamp() );
|
|
602
|
+
|
|
603
|
+
color.divAssign( float( ROTATION_COUNT ) );
|
|
604
|
+
color.mulAssign( GI_INTENSITY );
|
|
605
|
+
|
|
606
|
+
// scale color based on luminance
|
|
607
|
+
|
|
608
|
+
const maxLuminance = float( 7 ).toConst(); // 7 represent a HDR luminance value
|
|
609
|
+
const currentLuminance = luminance( color );
|
|
610
|
+
|
|
611
|
+
const scale = currentLuminance.greaterThan( maxLuminance ).select( maxLuminance.div( currentLuminance ), float( 1 ) );
|
|
612
|
+
color.mulAssign( scale );
|
|
613
|
+
|
|
614
|
+
return vec4( color, ao );
|
|
615
|
+
|
|
616
|
+
} );
|
|
617
|
+
|
|
618
|
+
this._material.fragmentNode = gi().context( builder.getSharedContext() );
|
|
619
|
+
this._material.needsUpdate = true;
|
|
620
|
+
|
|
621
|
+
//
|
|
622
|
+
|
|
623
|
+
return this._textureNode;
|
|
624
|
+
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Frees internal resources. This method should be called
|
|
629
|
+
* when the effect is no longer required.
|
|
630
|
+
*/
|
|
631
|
+
dispose() {
|
|
632
|
+
|
|
633
|
+
this._ssgiRenderTarget.dispose();
|
|
634
|
+
|
|
635
|
+
this._material.dispose();
|
|
636
|
+
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
export default SSGINode;
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* TSL function for creating a SSGI effect.
|
|
645
|
+
*
|
|
646
|
+
* @tsl
|
|
647
|
+
* @function
|
|
648
|
+
* @param {TextureNode} beautyNode - The texture node that represents the input of the effect.
|
|
649
|
+
* @param {TextureNode} depthNode - A texture node that represents the scene's depth.
|
|
650
|
+
* @param {TextureNode} normalNode - A texture node that represents the scene's normals.
|
|
651
|
+
* @param {Camera} camera - The camera the scene is rendered with.
|
|
652
|
+
* @returns {SSGINode}
|
|
653
|
+
*/
|
|
654
|
+
export const ssgi = ( beautyNode, depthNode, normalNode, camera ) => nodeObject( new SSGINode( convertToTexture( beautyNode ), depthNode, normalNode, camera ) );
|