super-three 0.184.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/build/three.cjs +1260 -927
- package/build/three.core.js +1104 -829
- package/build/three.core.min.js +1 -1
- package/build/three.module.js +156 -98
- package/build/three.module.min.js +1 -1
- package/build/three.tsl.js +11 -4
- package/build/three.tsl.min.js +1 -1
- package/build/three.webgpu.js +7538 -3367
- package/build/three.webgpu.min.js +1 -1
- package/build/three.webgpu.nodes.js +7538 -3366
- package/build/three.webgpu.nodes.min.js +1 -1
- package/examples/jsm/Addons.js +3 -0
- package/examples/jsm/controls/ArcballControls.js +6 -2
- package/examples/jsm/controls/FirstPersonControls.js +79 -42
- package/examples/jsm/controls/TransformControls.js +68 -15
- package/examples/jsm/csm/CSMFrustum.js +31 -6
- package/examples/jsm/csm/CSMShadowNode.js +4 -1
- package/examples/jsm/effects/AsciiEffect.js +14 -1
- package/examples/jsm/exporters/DRACOExporter.js +27 -6
- package/examples/jsm/exporters/GLTFExporter.js +114 -12
- package/examples/jsm/exporters/PLYExporter.js +286 -73
- package/examples/jsm/exporters/USDZExporter.js +347 -112
- 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/LoftGeometry.js +355 -0
- package/examples/jsm/helpers/LightProbeGridHelper.js +1 -1
- package/examples/jsm/helpers/LightProbeHelper.js +5 -4
- package/examples/jsm/helpers/ViewHelper.js +16 -6
- package/examples/jsm/inspector/Inspector.js +53 -15
- package/examples/jsm/inspector/RendererInspector.js +152 -36
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +1 -1
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -1
- package/examples/jsm/inspector/tabs/Console.js +200 -18
- package/examples/jsm/inspector/tabs/Memory.js +8 -0
- package/examples/jsm/inspector/tabs/Parameters.js +64 -4
- package/examples/jsm/inspector/tabs/Performance.js +21 -6
- package/examples/jsm/inspector/tabs/Settings.js +51 -9
- package/examples/jsm/inspector/tabs/Timeline.js +178 -93
- package/examples/jsm/inspector/tabs/Viewer.js +628 -16
- 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 +1 -1
- package/examples/jsm/inspector/ui/Profiler.js +90 -45
- package/examples/jsm/inspector/ui/Style.js +1788 -1401
- package/examples/jsm/inspector/ui/Tab.js +5 -3
- package/examples/jsm/inspector/ui/Values.js +71 -6
- package/examples/jsm/inspector/ui/utils.js +130 -10
- 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_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/LightProbeGrid.js +106 -76
- package/examples/jsm/lines/LineMaterial.js +38 -15
- package/examples/jsm/lines/LineSegments2.js +8 -0
- package/examples/jsm/lines/webgpu/LineSegments2.js +8 -0
- package/examples/jsm/loaders/3DMLoader.js +1 -1
- package/examples/jsm/loaders/DRACOLoader.js +46 -13
- package/examples/jsm/loaders/EXRLoader.js +27 -55
- package/examples/jsm/loaders/HDRLoader.js +6 -28
- package/examples/jsm/loaders/KTX2Loader.js +31 -12
- package/examples/jsm/loaders/LDrawLoader.js +8 -8
- package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
- package/examples/jsm/loaders/LUTCubeLoader.js +2 -2
- package/examples/jsm/loaders/LWOLoader.js +4 -0
- package/examples/jsm/loaders/LottieLoader.js +1 -1
- package/examples/jsm/loaders/MaterialXLoader.js +31 -9
- package/examples/jsm/loaders/NRRDLoader.js +3 -3
- package/examples/jsm/loaders/PCDLoader.js +7 -7
- package/examples/jsm/loaders/PLYLoader.js +218 -55
- package/examples/jsm/loaders/SVGLoader.js +547 -495
- package/examples/jsm/loaders/TTFLoader.js +1 -1
- package/examples/jsm/loaders/USDLoader.js +33 -9
- package/examples/jsm/loaders/VRMLLoader.js +1 -1
- package/examples/jsm/loaders/usd/USDAParser.js +93 -20
- package/examples/jsm/loaders/usd/USDCParser.js +1 -1
- package/examples/jsm/loaders/usd/USDComposer.js +52 -19
- package/examples/jsm/misc/TileCreasedNormalsPlugin.js +270 -0
- package/examples/jsm/misc/Volume.js +2 -2
- package/examples/jsm/objects/GroundedSkybox.js +1 -1
- package/examples/jsm/objects/Reflector.js +2 -3
- package/examples/jsm/objects/Water2Mesh.js +1 -1
- package/examples/jsm/physics/AmmoPhysics.js +15 -8
- package/examples/jsm/physics/RapierPhysics.js +27 -2
- package/examples/jsm/shaders/VolumeShader.js +31 -44
- package/examples/jsm/transpiler/GLSLDecoder.js +6 -6
- package/examples/jsm/transpiler/Linker.js +1 -1
- package/examples/jsm/tsl/display/BloomNode.js +59 -19
- package/examples/jsm/tsl/display/DepthOfFieldNode.js +2 -2
- package/examples/jsm/tsl/display/FXAANode.js +11 -12
- package/examples/jsm/tsl/display/GTAONode.js +34 -13
- package/examples/jsm/tsl/display/GodraysNode.js +1 -1
- package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +560 -0
- package/examples/jsm/tsl/display/PixelationPassNode.js +2 -2
- package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +912 -0
- package/examples/jsm/tsl/display/SSAAPassNode.js +13 -25
- package/examples/jsm/tsl/display/SSGINode.js +89 -39
- package/examples/jsm/tsl/display/SSRNode.js +829 -132
- package/examples/jsm/tsl/display/SSSNode.js +2 -2
- package/examples/jsm/tsl/display/TemporalReprojectNode.js +1023 -0
- package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +622 -0
- package/examples/jsm/tsl/lighting/DynamicLightsNode.js +1 -1
- 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 +126 -59
- package/examples/jsm/utils/GeometryCompressionUtils.js +1 -1
- package/examples/jsm/utils/SceneOptimizer.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/package.json +7 -7
- package/src/Three.TSL.js +10 -3
- package/src/Three.WebGPU.js +4 -0
- package/src/animation/AnimationAction.js +15 -11
- package/src/animation/AnimationClip.js +0 -139
- package/src/animation/KeyframeTrack.js +2 -2
- package/src/animation/PropertyBinding.js +2 -2
- package/src/cameras/Camera.js +2 -2
- package/src/cameras/StereoCamera.js +5 -2
- package/src/constants.js +1 -1
- package/src/core/BufferGeometry.js +29 -7
- package/src/core/Object3D.js +17 -7
- package/src/core/Raycaster.js +1 -1
- package/src/core/RenderTarget.js +15 -2
- package/src/extras/PMREMGenerator.js +6 -4
- package/src/extras/TextureUtils.js +1 -1
- package/src/extras/core/ShapePath.js +149 -160
- package/src/geometries/SphereGeometry.js +8 -3
- package/src/helpers/DirectionalLightHelper.js +2 -0
- package/src/helpers/HemisphereLightHelper.js +2 -0
- package/src/helpers/PointLightHelper.js +2 -0
- package/src/helpers/SpotLightHelper.js +1 -1
- package/src/loaders/DataTextureLoader.js +69 -38
- package/src/loaders/LoadingManager.js +5 -0
- package/src/loaders/MaterialLoader.js +36 -266
- package/src/loaders/ObjectLoader.js +3 -1
- package/src/materials/LineBasicMaterial.js +4 -0
- package/src/materials/Material.js +196 -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 +40 -1
- package/src/materials/MeshMatcapMaterial.js +25 -1
- package/src/materials/MeshNormalMaterial.js +9 -1
- package/src/materials/MeshPhongMaterial.js +40 -1
- package/src/materials/MeshPhysicalMaterial.js +38 -0
- package/src/materials/MeshStandardMaterial.js +42 -1
- package/src/materials/MeshToonMaterial.js +34 -1
- package/src/materials/PointsMaterial.js +7 -0
- package/src/materials/ShaderMaterial.js +86 -0
- package/src/materials/SpriteMaterial.js +7 -0
- package/src/materials/nodes/Line2NodeMaterial.js +378 -322
- 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 +0 -30
- package/src/materials/nodes/MeshSSSNodeMaterial.js +0 -13
- package/src/materials/nodes/MeshStandardNodeMaterial.js +0 -11
- package/src/materials/nodes/NodeMaterial.js +115 -71
- package/src/materials/nodes/SpriteNodeMaterial.js +0 -10
- package/src/materials/nodes/manager/NodeMaterialObserver.js +49 -20
- package/src/math/Box3.js +5 -0
- package/src/math/FrustumArray.js +103 -133
- package/src/math/Interpolant.js +1 -1
- package/src/math/MathUtils.js +2 -2
- package/src/math/Matrix3.js +11 -0
- package/src/math/Matrix4.js +28 -3
- package/src/math/Vector2.js +2 -2
- package/src/math/Vector3.js +2 -2
- package/src/math/Vector4.js +2 -2
- package/src/math/interpolants/BezierInterpolant.js +4 -6
- package/src/nodes/Nodes.js +2 -5
- package/src/nodes/TSL.js +8 -6
- package/src/nodes/accessors/Arrays.js +4 -4
- package/src/nodes/accessors/Batch.js +108 -0
- package/src/nodes/accessors/Bitangent.js +2 -2
- package/src/nodes/accessors/BufferAttributeNode.js +13 -2
- package/src/nodes/accessors/Camera.js +7 -7
- package/src/nodes/accessors/ClippingNode.js +1 -1
- package/src/nodes/accessors/Instance.js +264 -0
- package/src/nodes/accessors/MaterialNode.js +18 -2
- package/src/nodes/accessors/MaterialProperties.js +4 -3
- package/src/nodes/accessors/{MorphNode.js → Morph.js} +99 -112
- package/src/nodes/accessors/Normal.js +13 -13
- package/src/nodes/accessors/Position.js +5 -1
- package/src/nodes/accessors/ReferenceNode.js +1 -0
- package/src/nodes/accessors/ReflectVector.js +3 -3
- package/src/nodes/accessors/SceneProperties.js +1 -1
- package/src/nodes/accessors/Skinning.js +263 -0
- package/src/nodes/accessors/StorageBufferNode.js +2 -2
- package/src/nodes/accessors/StorageTexture3DNode.js +100 -0
- package/src/nodes/accessors/StorageTextureNode.js +39 -7
- package/src/nodes/accessors/Tangent.js +4 -4
- package/src/nodes/accessors/TextureNode.js +60 -5
- package/src/nodes/code/FunctionNode.js +2 -16
- package/src/nodes/core/MRTNode.js +7 -2
- package/src/nodes/core/Node.js +39 -2
- package/src/nodes/core/NodeBuilder.js +201 -41
- package/src/nodes/core/NodeUtils.js +13 -13
- package/src/nodes/core/OutputStructNode.js +1 -1
- package/src/nodes/core/OverrideContextNode.js +153 -0
- package/src/nodes/core/PropertyNode.js +51 -5
- package/src/nodes/core/StackNode.js +56 -34
- package/src/nodes/core/StructNode.js +4 -6
- package/src/nodes/core/StructTypeNode.js +6 -6
- package/src/nodes/core/VarNode.js +8 -0
- package/src/nodes/core/VaryingNode.js +12 -2
- package/src/nodes/display/BlendModes.js +1 -41
- package/src/nodes/display/BumpMapNode.js +6 -1
- package/src/nodes/display/ColorAdjustment.js +10 -9
- package/src/nodes/display/FrontFacingNode.js +38 -9
- package/src/nodes/display/NormalMapNode.js +2 -2
- package/src/nodes/display/PassNode.js +35 -43
- package/src/nodes/display/PremultiplyAlphaFunctions.js +39 -0
- package/src/nodes/display/RenderOutputNode.js +12 -3
- package/src/nodes/functions/VolumetricLightingModel.js +40 -7
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +1 -1
- package/src/nodes/lighting/EnvironmentNode.js +2 -2
- package/src/nodes/lighting/IESSpotLightNode.js +40 -2
- package/src/nodes/lighting/LightingContextNode.js +10 -2
- package/src/nodes/lighting/LightsNode.js +90 -37
- package/src/nodes/lighting/PointShadowNode.js +6 -1
- package/src/nodes/lighting/ShadowFilterNode.js +21 -52
- package/src/nodes/lighting/ShadowNode.js +34 -14
- package/src/nodes/materialx/lib/mx_noise.js +2 -2
- package/src/nodes/math/ConditionalNode.js +3 -3
- package/src/nodes/math/MathNode.js +39 -11
- package/src/nodes/math/OperatorNode.js +23 -23
- package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
- package/src/nodes/pmrem/PMREMNode.js +33 -2
- package/src/nodes/tsl/TSLCore.js +63 -18
- package/src/nodes/utils/EquirectUV.js +30 -5
- package/src/nodes/utils/FunctionOverloadingNode.js +1 -1
- package/src/nodes/utils/Packing.js +35 -4
- package/src/nodes/utils/RTTNode.js +40 -24
- package/src/nodes/utils/ReflectorNode.js +1 -0
- package/src/nodes/utils/StorageArrayElementNode.js +1 -1
- package/src/objects/BatchedMesh.js +22 -14
- package/src/objects/InstancedMesh.js +0 -11
- package/src/objects/Skeleton.js +0 -9
- package/src/renderers/WebGLRenderer.js +19 -15
- package/src/renderers/common/Backend.js +49 -5
- package/src/renderers/common/Bindings.js +114 -45
- package/src/renderers/common/Buffer.js +9 -0
- package/src/renderers/common/ClippingContext.js +10 -2
- package/src/renderers/common/Info.js +63 -22
- package/src/renderers/common/Lighting.js +53 -5
- package/src/renderers/common/RenderList.js +41 -4
- package/src/renderers/common/RenderObject.js +73 -13
- package/src/renderers/common/Renderer.js +281 -108
- package/src/renderers/common/Sampler.js +16 -48
- package/src/renderers/common/Textures.js +32 -5
- package/src/renderers/common/TimestampQueryPool.js +1 -1
- package/src/renderers/common/UniformsGroup.js +31 -9
- package/src/renderers/common/XRManager.js +340 -22
- package/src/renderers/common/extras/PMREMGenerator.js +15 -38
- package/src/renderers/common/nodes/NodeBuilderState.js +9 -1
- package/src/renderers/common/nodes/NodeLibrary.js +4 -4
- package/src/renderers/common/nodes/NodeManager.js +63 -14
- package/src/renderers/common/nodes/NodeUniformBuffer.js +13 -0
- 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_fragment.glsl.js +1 -1
- 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/lights_fragment_begin.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk/normal_vertex.glsl.js +6 -0
- package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/distance.glsl.js +1 -1
- package/src/renderers/webgl/WebGLOutput.js +2 -1
- package/src/renderers/webgl/WebGLProgram.js +5 -4
- package/src/renderers/webgl/WebGLPrograms.js +12 -5
- package/src/renderers/webgl/WebGLRenderLists.js +9 -1
- package/src/renderers/webgl/WebGLShaderCache.js +5 -11
- package/src/renderers/webgl/WebGLTextures.js +20 -7
- package/src/renderers/webgl/WebGLUniformsGroups.js +66 -38
- package/src/renderers/webgl-fallback/WebGLBackend.js +84 -25
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +138 -8
- package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +1 -1
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -22
- package/src/renderers/webgl-fallback/utils/WebGLUtils.js +4 -2
- package/src/renderers/webgpu/WebGPUBackend.js +480 -169
- 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 +164 -7
- package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +1 -1
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +98 -38
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +72 -68
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +164 -69
- package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +158 -95
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +297 -141
- package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +33 -18
- package/src/renderers/webgpu/utils/WebGPUUtils.js +38 -3
- package/src/textures/DepthTexture.js +1 -1
- package/src/textures/ExternalTexture.js +0 -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/inspector/extensions/extensions.json +0 -6
- 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/tsl/display/AnamorphicNode.js +0 -293
- package/examples/jsm/tsl/lighting/TiledLightsNode.js +0 -442
- package/src/nodes/accessors/BatchNode.js +0 -163
- package/src/nodes/accessors/InstanceNode.js +0 -349
- package/src/nodes/accessors/InstancedMeshNode.js +0 -50
- package/src/nodes/accessors/SkinningNode.js +0 -328
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { mod, Fn, vec2, div, vec4, dot, floor, step, sub, min, max, mul, abs, vec3, inverseSqrt, add, float } from 'three/tsl';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Permutation polynomial for noise generation.
|
|
5
|
+
*
|
|
6
|
+
* @tsl
|
|
7
|
+
* @function
|
|
8
|
+
* @param {Node<vec4>} x - Input vector.
|
|
9
|
+
* @return {Node<vec4>} Permuted vector.
|
|
10
|
+
*/
|
|
11
|
+
export const permute = /*@__PURE__*/ Fn( ( [ x ] ) => {
|
|
12
|
+
|
|
13
|
+
return mod( x.mul( x ).mul( 34. ).add( x ), 289. );
|
|
14
|
+
|
|
15
|
+
}, { x: 'vec4', return: 'vec4' } );
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 3D Simplex noise implementation in TSL.
|
|
19
|
+
*
|
|
20
|
+
* @tsl
|
|
21
|
+
* @function
|
|
22
|
+
* @param {Node<vec3>} v - Input coordinate vector.
|
|
23
|
+
* @return {Node<float>} Simplex noise value.
|
|
24
|
+
*/
|
|
25
|
+
export const snoise = /*@__PURE__*/ Fn( ( [ v ] ) => {
|
|
26
|
+
|
|
27
|
+
const C = div( 1., vec2( 6, 3 ) );
|
|
28
|
+
const D = vec4( 0, .5, 1, 2 );
|
|
29
|
+
const i = floor( v.add( dot( v, C.yyy ) ) );
|
|
30
|
+
const x0 = v.sub( i ).add( dot( i, C.xxx ) );
|
|
31
|
+
const g = step( x0.yzx, x0.xyz );
|
|
32
|
+
const l = sub( 1., g );
|
|
33
|
+
const i1 = min( g.xyz, l.zxy );
|
|
34
|
+
const i2 = max( g.xyz, l.zxy );
|
|
35
|
+
const x1 = x0.sub( i1 ).add( C.x );
|
|
36
|
+
const x2 = x0.sub( i2 ).add( C.y );
|
|
37
|
+
const x3 = x0.sub( D.yyy );
|
|
38
|
+
i.assign( mod( i, 289. ) );
|
|
39
|
+
const p = permute( permute( permute( i.z.add( vec4( 0., i1.z, i2.z, 1. ) ) ).add( i.y ).add( vec4( 0., i1.y, i2.y, 1. ) ) ).add( i.x ).add( vec4( 0., i1.x, i2.x, 1. ) ) );
|
|
40
|
+
const ns = mul( .142857142857, D.wyz ).sub( D.xzx );
|
|
41
|
+
const j = p.sub( mul( 49., floor( p.mul( ns.z ).mul( ns.z ) ) ) );
|
|
42
|
+
const x_ = floor( j.mul( ns.z ) );
|
|
43
|
+
const x = x_.mul( ns.x ).add( ns.yyyy );
|
|
44
|
+
const y = floor( j.sub( mul( 7., x_ ) ) ).mul( ns.x ).add( ns.yyyy );
|
|
45
|
+
const h = sub( 1., abs( x ) ).sub( abs( y ) );
|
|
46
|
+
const b0 = vec4( x.xy, y.xy );
|
|
47
|
+
const b1 = vec4( x.zw, y.zw );
|
|
48
|
+
const sh = step( h, vec4( 0 ) ).negate();
|
|
49
|
+
const a0 = b0.xzyw.add( floor( b0 ).mul( 2. ).add( 1. ).xzyw.mul( sh.xxyy ) );
|
|
50
|
+
const a1 = b1.xzyw.add( floor( b1 ).mul( 2. ).add( 1. ).xzyw.mul( sh.zzww ) );
|
|
51
|
+
const p0 = vec3( a0.xy, h.x );
|
|
52
|
+
const p1 = vec3( a0.zw, h.y );
|
|
53
|
+
const p2 = vec3( a1.xy, h.z );
|
|
54
|
+
const p3 = vec3( a1.zw, h.w );
|
|
55
|
+
const norm = inverseSqrt( vec4( dot( p0, p0 ), dot( p1, p1 ), dot( p2, p2 ), dot( p3, p3 ) ) );
|
|
56
|
+
p0.mulAssign( norm.x );
|
|
57
|
+
p1.mulAssign( norm.y );
|
|
58
|
+
p2.mulAssign( norm.z );
|
|
59
|
+
p3.mulAssign( norm.w );
|
|
60
|
+
const m = max( sub( .6, vec4( dot( x0, x0 ), dot( x1, x1 ), dot( x2, x2 ), dot( x3, x3 ) ) ), 0. );
|
|
61
|
+
|
|
62
|
+
return add( .5, mul( 12., dot( m.mul( m ).mul( m ), vec4( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ), dot( p3, x3 ) ) ) ) );
|
|
63
|
+
|
|
64
|
+
}, { v: 'vec3', return: 'float' } );
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 3D Simplex noise vector. Returns a vec3 containing three independent noise samples.
|
|
68
|
+
*
|
|
69
|
+
* @tsl
|
|
70
|
+
* @function
|
|
71
|
+
* @param {Node<vec3>} x - Input coordinate vector.
|
|
72
|
+
* @return {Node<vec3>} Vector of three noise values.
|
|
73
|
+
*/
|
|
74
|
+
export const snoiseVec3 = /*@__PURE__*/ Fn( ( [ x ] ) => {
|
|
75
|
+
|
|
76
|
+
return vec3( snoise( vec3( x ).mul( 2. ).sub( 1. ) ), snoise( vec3( x.y.sub( 19.1 ), x.z.add( 33.4 ), x.x.add( 47.2 ) ) ).mul( 2. ).sub( 1. ), snoise( vec3( x.z.add( 74.2 ), x.x.sub( 124.5 ), x.y.add( 99.4 ) ).mul( 2. ).sub( 1. ) ) );
|
|
77
|
+
|
|
78
|
+
}, { x: 'vec3', return: 'vec3' } );
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 3D Curl noise in TSL. Generates a divergence-free vector field from simplex noise.
|
|
82
|
+
*
|
|
83
|
+
* @tsl
|
|
84
|
+
* @function
|
|
85
|
+
* @param {Node<vec3>} p - Input coordinate vector.
|
|
86
|
+
* @return {Node<vec3>} Curl noise vector.
|
|
87
|
+
*/
|
|
88
|
+
export const curlNoise = /*@__PURE__*/ Fn( ( [ p ] ) => {
|
|
89
|
+
|
|
90
|
+
const e = float( .1 );
|
|
91
|
+
const dx = vec3( e, 0.0, 0.0 );
|
|
92
|
+
const dy = vec3( 0.0, e, 0.0 );
|
|
93
|
+
const dz = vec3( 0.0, 0.0, e );
|
|
94
|
+
const p_x0 = snoiseVec3( p.sub( dx ) );
|
|
95
|
+
const p_x1 = snoiseVec3( p.add( dx ) );
|
|
96
|
+
const p_y0 = snoiseVec3( p.sub( dy ) );
|
|
97
|
+
const p_y1 = snoiseVec3( p.add( dy ) );
|
|
98
|
+
const p_z0 = snoiseVec3( p.sub( dz ) );
|
|
99
|
+
const p_z1 = snoiseVec3( p.add( dz ) );
|
|
100
|
+
const x = p_y1.z.sub( p_y0.z ).sub( p_z1.y ).add( p_z0.y );
|
|
101
|
+
const y = p_z1.x.sub( p_z0.x ).sub( p_x1.z ).add( p_x0.z );
|
|
102
|
+
const z = p_x1.y.sub( p_x0.y ).sub( p_y1.x ).add( p_y0.x );
|
|
103
|
+
const divisor = div( 1.0, mul( 2.0, e ) );
|
|
104
|
+
|
|
105
|
+
return vec3( x, y, z ).mul( divisor );
|
|
106
|
+
|
|
107
|
+
}, { p: 'vec3', return: 'vec3' } );
|
|
@@ -162,7 +162,7 @@ class TileShadowNode extends ShadowBaseNode {
|
|
|
162
162
|
const depthTexture = new DepthTexture( shadowWidth, shadowHeight, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, tileCount );
|
|
163
163
|
depthTexture.compareFunction = LessCompare;
|
|
164
164
|
depthTexture.name = 'ShadowDepthArrayTexture';
|
|
165
|
-
const shadowMap = builder.createRenderTarget( shadowWidth, shadowHeight, { format: RedFormat, depth: tileCount } );
|
|
165
|
+
const shadowMap = builder.createRenderTarget( shadowWidth, shadowHeight, { format: RedFormat, depth: tileCount, useArrayDepthTexture: true } );
|
|
166
166
|
shadowMap.depthTexture = depthTexture;
|
|
167
167
|
shadowMap.texture.name = 'ShadowTexture';
|
|
168
168
|
this.shadowMap = shadowMap;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Group, NodeMaterial, Mesh, PlaneGeometry, DoubleSide, CameraHelper } from 'three/webgpu';
|
|
2
|
-
import { Fn, vec4, vec3, texture, uv, positionLocal, vec2, float, screenSize } from 'three/tsl';
|
|
2
|
+
import { Fn, vec4, vec3, texture, uv, positionLocal, vec2, float, int, screenSize } from 'three/tsl';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Helper class to manage and display debug visuals for TileShadowNode.
|
|
@@ -18,7 +18,7 @@ class TileShadowNodeHelper extends Group {
|
|
|
18
18
|
|
|
19
19
|
if ( ! tileShadowNode ) {
|
|
20
20
|
|
|
21
|
-
throw new Error( 'TileShadowNode instance is required for TileShadowNodeHelper.' );
|
|
21
|
+
throw new Error( 'THREE.TileShadowNode instance is required for TileShadowNodeHelper.' );
|
|
22
22
|
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -109,7 +109,7 @@ class TileShadowNodeHelper extends Group {
|
|
|
109
109
|
|
|
110
110
|
const sampledDepth = texture( this.tileShadowNode.shadowMap.depthTexture )
|
|
111
111
|
.sample( uv().flipY() )
|
|
112
|
-
.depth(
|
|
112
|
+
.depth( int( i ) ) // Sample correct layer
|
|
113
113
|
.compare( 0.9 ); // Example comparison value
|
|
114
114
|
|
|
115
115
|
// Simple tint based on index for visual distinction
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Fn, If, vec3, float, min, cameraPosition, positionWorld } from 'three/tsl';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module GroundedSkybox
|
|
5
|
+
* @three_import import { getGroundProjectedNormal } from 'three/addons/tsl/utils/GroundedSkybox.js';
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Projects the world position onto a sphere whose bottom is clipped by a ground disk,
|
|
10
|
+
* then returns a vector usable for sampling an environment cube map.
|
|
11
|
+
*
|
|
12
|
+
* @tsl
|
|
13
|
+
* @function
|
|
14
|
+
* @param {Node<float>} radiusNode - The radius of the projection sphere. Must be large enough to ensure the scene's camera stays inside.
|
|
15
|
+
* @param {Node<float>} heightNode - The height is how far the camera that took the photo was above the ground. A larger value will magnify the downward part of the image.
|
|
16
|
+
* @return {Node<vec3>} A direction vector for sampling the environment cube map.
|
|
17
|
+
*/
|
|
18
|
+
export const getGroundProjectedNormal = Fn( ( [ radiusNode, heightNode ] ) => {
|
|
19
|
+
|
|
20
|
+
const p = positionWorld.sub( cameraPosition ).normalize().toConst();
|
|
21
|
+
const camPos = cameraPosition.toVar();
|
|
22
|
+
camPos.y.subAssign( heightNode );
|
|
23
|
+
|
|
24
|
+
// sphereIntersect( camPos, p, vec3( 0 ), radius )
|
|
25
|
+
const b = camPos.dot( p ).toConst();
|
|
26
|
+
const c = camPos.dot( camPos ).sub( radiusNode.mul( radiusNode ) ).toConst();
|
|
27
|
+
const h = b.mul( b ).sub( c ).toConst();
|
|
28
|
+
|
|
29
|
+
const intersection = h.greaterThanEqual( 0 ).select( h.sqrt().sub( b ), - 1 );
|
|
30
|
+
|
|
31
|
+
const projected = vec3( 0, 1, 0 ).toVar();
|
|
32
|
+
|
|
33
|
+
If( intersection.greaterThan( 0 ), () => {
|
|
34
|
+
|
|
35
|
+
// diskIntersectWithBackFaceCulling( camPos, p, diskCenter, n, radius )
|
|
36
|
+
const diskCenter = vec3( 0, heightNode.negate(), 0 ).toConst();
|
|
37
|
+
const n = vec3( 0, 1, 0 ).toConst();
|
|
38
|
+
const d = p.dot( n ).toConst();
|
|
39
|
+
|
|
40
|
+
const intersection2 = float( 1e6 ).toVar();
|
|
41
|
+
|
|
42
|
+
If( d.lessThanEqual( 0 ), () => {
|
|
43
|
+
|
|
44
|
+
const o = camPos.sub( diskCenter ).toConst();
|
|
45
|
+
const t = n.dot( o ).negate().div( d ).toConst();
|
|
46
|
+
const q = o.add( p.mul( t ) ).toConst();
|
|
47
|
+
|
|
48
|
+
If( q.dot( q ).lessThan( radiusNode.mul( radiusNode ) ), () => {
|
|
49
|
+
|
|
50
|
+
intersection2.assign( t );
|
|
51
|
+
|
|
52
|
+
} );
|
|
53
|
+
|
|
54
|
+
} );
|
|
55
|
+
|
|
56
|
+
projected.assign( camPos.add( p.mul( min( intersection, intersection2 ) ) ).div( radiusNode ) );
|
|
57
|
+
|
|
58
|
+
} );
|
|
59
|
+
|
|
60
|
+
return projected;
|
|
61
|
+
|
|
62
|
+
} );
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { float, Fn, fract, int, vec2, vec4 } from 'three/tsl';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns a TSL function that samples texture-free analytic R² noise.
|
|
5
|
+
* Index 0 uses continuous screen pixels; other indices tile-shift with an R²
|
|
6
|
+
* sequence into a 64×64 period. Values are four independent R² dimensions
|
|
7
|
+
* hashed from the sample coordinates.
|
|
8
|
+
*
|
|
9
|
+
* @param {UniformNode<Vector2>} resolution
|
|
10
|
+
* @param {number} [seed=0] - Added to the coordinate hash so each pass gets an independent R² phase.
|
|
11
|
+
*/
|
|
12
|
+
export function bindAnalyticNoise( resolution, seed = 0 ) {
|
|
13
|
+
|
|
14
|
+
const seedOffset = int( seed );
|
|
15
|
+
|
|
16
|
+
const r4 = ( coords ) => {
|
|
17
|
+
|
|
18
|
+
const P = 1.32471795724474602596;
|
|
19
|
+
|
|
20
|
+
const t = coords.x.mul( 1 / P ).add( coords.y.mul( 1 / P ** 2 ) ).add( float( seed ) );
|
|
21
|
+
|
|
22
|
+
return vec4(
|
|
23
|
+
fract( t.mul( P ).mul( 1 / P ) ),
|
|
24
|
+
fract( t.mul( P * 2 ).mul( 1 / P ** 2 ) ),
|
|
25
|
+
fract( t.mul( P * 3 ).mul( 0.4198754210 ) ), // this is not 1 / P ** 3, however this magic constant gives better noise
|
|
26
|
+
fract( t.mul( P * 4 ).mul( 1 / P ** 3 ) )
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return Fn( ( [ uvCoord, sampleIndex ] ) => {
|
|
32
|
+
|
|
33
|
+
const index = int( sampleIndex ).add( seedOffset );
|
|
34
|
+
const noise = vec4().toVar();
|
|
35
|
+
|
|
36
|
+
const tileSize = float( 32 );
|
|
37
|
+
|
|
38
|
+
const screenPixel = uvCoord.mul( resolution ).floor();
|
|
39
|
+
const offset = fract( vec2(
|
|
40
|
+
float( index ).mul( 0.7548776662 ),
|
|
41
|
+
float( index ).mul( 0.5698402910 )
|
|
42
|
+
) ).mul( tileSize ).floor();
|
|
43
|
+
const coords = screenPixel.add( offset ).mod( tileSize );
|
|
44
|
+
|
|
45
|
+
noise.assign( r4( coords ) );
|
|
46
|
+
|
|
47
|
+
return noise;
|
|
48
|
+
|
|
49
|
+
} );
|
|
50
|
+
|
|
51
|
+
}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { Fn, If, PI, clamp, cos, cross, dot, equirectUV, float, log, max, mix, normalize, pow, reflect, sin, sqrt, struct, vec3 } from 'three/tsl';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Specular / microfacet BRDF helpers: VNDF sampling, GTR distribution, Smith geometry,
|
|
5
|
+
* Fresnel, reflection importance sampling, parallax-corrected ray-length terms, and
|
|
6
|
+
* equirectangular environment sampling / MIS helpers.
|
|
7
|
+
* Pure TSL functions of their inputs (no scene/camera state).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Sentinel ray length the SSR pass writes for environment misses (no screen-space hit), set far above
|
|
12
|
+
* any real hit distance so a single magnitude test separates misses from hits and survives `.max( 0 )`.
|
|
13
|
+
*
|
|
14
|
+
* @type {number}
|
|
15
|
+
*/
|
|
16
|
+
export const ENV_RAY_LENGTH = 1e4;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Classification threshold for {@link ENV_RAY_LENGTH}: above this is an env miss, below a real hit.
|
|
20
|
+
* An order of magnitude under the sentinel, robust to fp16 storage and bilinear blending at borders.
|
|
21
|
+
*
|
|
22
|
+
* @type {number}
|
|
23
|
+
*/
|
|
24
|
+
export const ENV_RAY_LENGTH_THRESHOLD = 1e3;
|
|
25
|
+
|
|
26
|
+
// Bounded-VNDF sampler (Eto & Tokuyoshi 2023; spherical-cap form, Dupuy & Benyoub 2023)
|
|
27
|
+
const SampleGGXVNDF = Fn( ( [ V, ax, ay, r1, r2 ] ) => {
|
|
28
|
+
|
|
29
|
+
// Warp the view direction to the hemisphere ("standard") configuration.
|
|
30
|
+
const wiStd = normalize( vec3( ax.mul( V.x ), ay.mul( V.y ), V.z ) ).toVar();
|
|
31
|
+
|
|
32
|
+
// Isotropic bound on the spherical cap (Eto & Tokuyoshi eq. 5). alpha ∈ [0,1] here,
|
|
33
|
+
// so the sign term in `s` is always +1 and is dropped.
|
|
34
|
+
const a = ax.min( ay ).toVar();
|
|
35
|
+
const s = float( 1.0 ).add( V.xy.length() ).toVar();
|
|
36
|
+
const a2 = a.mul( a ).toVar();
|
|
37
|
+
const s2 = s.mul( s ).toVar();
|
|
38
|
+
const k = a2.oneMinus().mul( s2 ).div( s2.add( a2.mul( V.z ).mul( V.z ) ) ).toVar();
|
|
39
|
+
|
|
40
|
+
// Tighten the cap with the bound (upper hemisphere; N·V ≥ 0 in our usage).
|
|
41
|
+
const b = wiStd.z.mul( k ).toVar();
|
|
42
|
+
|
|
43
|
+
// Sample the (bounded) spherical cap.
|
|
44
|
+
const phi = float( 6.283185307179586 ).mul( r1 ).toVar(); // 2*pi
|
|
45
|
+
const z = r2.oneMinus().mul( float( 1.0 ).add( b ) ).sub( b ).toVar();
|
|
46
|
+
const sinTheta = sqrt( max( float( 0.0 ), float( 1.0 ).sub( z.mul( z ) ) ) ).toVar();
|
|
47
|
+
const c = vec3( sinTheta.mul( cos( phi ) ), sinTheta.mul( sin( phi ) ), z ).toVar();
|
|
48
|
+
|
|
49
|
+
// Microfacet normal in the standard config, then warp back to the ellipsoid (unstretch).
|
|
50
|
+
const wmStd = c.add( wiStd ).toVar();
|
|
51
|
+
const Ne = normalize( vec3(
|
|
52
|
+
ax.mul( wmStd.x ),
|
|
53
|
+
ay.mul( wmStd.y ),
|
|
54
|
+
max( float( 0.0 ), wmStd.z )
|
|
55
|
+
) ).toVar();
|
|
56
|
+
|
|
57
|
+
return Ne;
|
|
58
|
+
|
|
59
|
+
}, {
|
|
60
|
+
name: 'SampleGGXVNDF',
|
|
61
|
+
type: 'vec3',
|
|
62
|
+
inputs: [
|
|
63
|
+
{ name: 'V', type: 'vec3' },
|
|
64
|
+
{ name: 'ax', type: 'float' },
|
|
65
|
+
{ name: 'ay', type: 'float' },
|
|
66
|
+
{ name: 'r1', type: 'float' },
|
|
67
|
+
{ name: 'r2', type: 'float' },
|
|
68
|
+
]
|
|
69
|
+
} );
|
|
70
|
+
|
|
71
|
+
// Generalized Trowbridge-Reitz (GTR). For GGX set k=2.
|
|
72
|
+
// D_GTR(roughness, NoH, k) where roughness = α (not α²).
|
|
73
|
+
export const D_GTR = Fn( ( [ roughness, NoH, k ] ) => {
|
|
74
|
+
|
|
75
|
+
// see: Filament - Normal distribution function (specular D) - 4.4.1
|
|
76
|
+
const a2 = roughness.mul( roughness ).toVar(); // α²
|
|
77
|
+
const NoH2 = NoH.mul( NoH ).toVar();
|
|
78
|
+
const base = NoH2.mul( a2.sub( float( 1.0 ) ) ).add( float( 1.0 ) ).toVar();
|
|
79
|
+
// a² / (π * base^k)
|
|
80
|
+
return a2.div( PI.mul( pow( base, k ) ) ).toVar(); // float
|
|
81
|
+
|
|
82
|
+
} );
|
|
83
|
+
|
|
84
|
+
// Smith G1 (Heitz): expects alpha (not squared); it squares internally
|
|
85
|
+
export const SmithG = Fn( ( [ NDotX, alpha ] ) => {
|
|
86
|
+
|
|
87
|
+
// see: Filament - Geometric shadowing (specular G) - 4.4.2
|
|
88
|
+
|
|
89
|
+
const a2 = alpha.mul( alpha ).toVar(); // α²
|
|
90
|
+
const NDotX2 = NDotX.mul( NDotX ).toVar(); // (N·X)²
|
|
91
|
+
return float( 2.0 ).mul( NDotX ).div(
|
|
92
|
+
NDotX.add( sqrt(
|
|
93
|
+
a2.add( a2.oneMinus().mul( NDotX2 ) )
|
|
94
|
+
) )
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
} );
|
|
98
|
+
|
|
99
|
+
// Geometry term G = G1(N·L, α_G) * G1(N·V, α_G) (α_G is NOT squared here)
|
|
100
|
+
export const GeometryTerm = Fn( ( [ NoL, NoV, alphaG ] ) => {
|
|
101
|
+
|
|
102
|
+
const G1v = SmithG( NoV, alphaG ).toVar();
|
|
103
|
+
const G1l = SmithG( NoL, alphaG ).toVar();
|
|
104
|
+
return G1v.mul( G1l ).toVar();
|
|
105
|
+
|
|
106
|
+
} );
|
|
107
|
+
|
|
108
|
+
// Bounded VNDF direction PDF (reflection mapping), matching SampleGGXVNDF above.
|
|
109
|
+
// p(L) = D_GTR(roughness, NoH, 2) / ( 2 * (k * N·V + t) ) (Eto & Tokuyoshi eq. 8)
|
|
110
|
+
// with the isotropic cap bound k and t = ‖(α·V.xy, V.z)‖. Here 'roughness' is α, not α².
|
|
111
|
+
const GGXVNDFPdf = Fn( ( [ NoH, NoV, roughness ] ) => {
|
|
112
|
+
|
|
113
|
+
const D = D_GTR( roughness, NoH, float( 2.0 ) ).toVar();
|
|
114
|
+
const a2 = roughness.mul( roughness ).toVar();
|
|
115
|
+
const sinV2 = max( float( 0.0 ), float( 1.0 ).sub( NoV.mul( NoV ) ) ).toVar(); // ‖V.xy‖²
|
|
116
|
+
const s = float( 1.0 ).add( sqrt( sinV2 ) ).toVar();
|
|
117
|
+
const s2 = s.mul( s ).toVar();
|
|
118
|
+
const k = float( 1.0 ).sub( a2 ).mul( s2 ).div( s2.add( a2.mul( NoV ).mul( NoV ) ) ).toVar();
|
|
119
|
+
const t = sqrt( a2.mul( sinV2 ).add( NoV.mul( NoV ) ) ).toVar();
|
|
120
|
+
return D.div( max( float( 1e-6 ), float( 2.0 ).mul( k.mul( NoV ).add( t ) ) ) ).toVar();
|
|
121
|
+
|
|
122
|
+
} );
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Fresnel reflectance for the Schlick approximation.
|
|
126
|
+
*/
|
|
127
|
+
export const F_Schlick = Fn( ( [ f0, theta ] ) => {
|
|
128
|
+
|
|
129
|
+
const oneMinus = float( 1.0 ).sub( theta ).toVar();
|
|
130
|
+
const oneMinus2 = oneMinus.mul( oneMinus ).toVar();
|
|
131
|
+
const oneMinus5 = oneMinus2.mul( oneMinus2 ).mul( oneMinus ).toVar();
|
|
132
|
+
return f0.add( vec3( 1.0 ).sub( f0 ).mul( oneMinus5 ) ).toVar(); // vec3
|
|
133
|
+
|
|
134
|
+
} );
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Specular dominant factor for parallax-corrected ray length.
|
|
138
|
+
* From REBLUR: A Hierarchical Recurrent Denoiser (NRD).
|
|
139
|
+
*/
|
|
140
|
+
export const getSpecularDominantFactor = Fn( ( [ NoV, roughness ] ) => {
|
|
141
|
+
|
|
142
|
+
const a = float( 0.298475 ).mul(
|
|
143
|
+
log( float( 39.4115 ).sub( float( 39.0029 ).mul( roughness ) ) )
|
|
144
|
+
);
|
|
145
|
+
const f = float( 1.0 ).sub( NoV ).pow( 10.8649 )
|
|
146
|
+
.mul( float( 1.0 ).sub( a ) )
|
|
147
|
+
.add( a );
|
|
148
|
+
return clamp( f );
|
|
149
|
+
|
|
150
|
+
} ).setLayout( {
|
|
151
|
+
name: 'getSpecularDominantFactor',
|
|
152
|
+
type: 'float',
|
|
153
|
+
inputs: [
|
|
154
|
+
{ name: 'NoV', type: 'float' },
|
|
155
|
+
{ name: 'roughness', type: 'float' }
|
|
156
|
+
]
|
|
157
|
+
} );
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Everything a single GGX reflection sample produces. `reflectDir` and `sampleWeight`
|
|
161
|
+
* drive the SSR ray-march and compositing; `pdf`, `NdotV`, `alpha` and `f0` are the GGX
|
|
162
|
+
* terms the env-miss MIS fallback needs so the caller never re-derives microfacet math.
|
|
163
|
+
*/
|
|
164
|
+
const ggxReflectionStruct = struct( {
|
|
165
|
+
reflectDir: 'vec3', // view-space reflected ray direction
|
|
166
|
+
sampleWeight: 'vec3', // chromatic weight (incl. Fresnel tint) to multiply gathered radiance by
|
|
167
|
+
pdf: 'float', // VNDF direction pdf (for MIS against the env CDF)
|
|
168
|
+
NdotV: 'float',
|
|
169
|
+
alpha: 'float', // GGX alpha (roughness²), clamped
|
|
170
|
+
f0: 'vec3' // Fresnel reflectance at normal incidence
|
|
171
|
+
} );
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Importance-samples the GGX/VNDF specular lobe for one pixel and returns the reflected
|
|
175
|
+
* ray direction plus the Monte-Carlo weight to apply to the gathered radiance, along with
|
|
176
|
+
* the GGX terms the SSR env-miss MIS fallback needs.
|
|
177
|
+
*
|
|
178
|
+
* @param {Node<vec3>} N - View-space shading normal (normalized).
|
|
179
|
+
* @param {Node<vec3>} V - View-space surface→camera direction (normalized).
|
|
180
|
+
* @param {Node<float>} roughness - Perceptual roughness in `[0,1]`.
|
|
181
|
+
* @param {Node<float>} metalness - Metalness in `[0,1]`.
|
|
182
|
+
* @param {Node<vec3>} albedo - Surface base color; tints the metal Fresnel reflectance (`f0`).
|
|
183
|
+
* @param {Node<vec4>} Xi - Per-pixel random numbers; only `.xy` are used.
|
|
184
|
+
* @return {ggxReflectionStruct}
|
|
185
|
+
*/
|
|
186
|
+
export const ggxReflectionSample = Fn( ( [ N, V, roughness, metalness, albedo, Xi ] ) => {
|
|
187
|
+
|
|
188
|
+
// GGX alpha (use r^2, clamp to avoid degenerate)
|
|
189
|
+
const a = roughness.mul( roughness ).max( 0.001 ).toVar();
|
|
190
|
+
const ax = a.toVar();
|
|
191
|
+
const ay = a.toVar();
|
|
192
|
+
|
|
193
|
+
// TBN from view-space normal
|
|
194
|
+
const up = vec3( 0, 0, 1 );
|
|
195
|
+
let T = cross( up, N ).toVar();
|
|
196
|
+
T = T.normalize().toVar();
|
|
197
|
+
If( T.length().lessThan( 1e-3 ), () => {
|
|
198
|
+
|
|
199
|
+
T.assign( cross( vec3( 0, 1, 0 ), N ).normalize() );
|
|
200
|
+
|
|
201
|
+
} );
|
|
202
|
+
const B = cross( N, T ).normalize().toVar();
|
|
203
|
+
|
|
204
|
+
// transform V to LOCAL frame (N = +Z)
|
|
205
|
+
const Vlocal = vec3( dot( T, V ), dot( B, V ), dot( N, V ) ).toVar();
|
|
206
|
+
|
|
207
|
+
// VNDF sample **in local frame**
|
|
208
|
+
const Hlocal = SampleGGXVNDF( Vlocal, ax, ay, Xi.x, Xi.y ).toVar();
|
|
209
|
+
If( Hlocal.z.lessThan( 0 ), () => {
|
|
210
|
+
|
|
211
|
+
Hlocal.assign( Hlocal.negate() );
|
|
212
|
+
|
|
213
|
+
} );
|
|
214
|
+
|
|
215
|
+
// transform H back to VIEW space
|
|
216
|
+
const h = normalize( T.mul( Hlocal.x ).add( B.mul( Hlocal.y ) ).add( N.mul( Hlocal.z ) ) ).toVar();
|
|
217
|
+
|
|
218
|
+
// reflect with V (surface->camera) and H
|
|
219
|
+
const viewReflectDir = reflect( V.negate(), h ).normalize().toVar();
|
|
220
|
+
|
|
221
|
+
// BRDF/PDF evaluation for the sampled direction
|
|
222
|
+
// V: surface -> camera, L: reflected direction, N: normal, H: half-vector
|
|
223
|
+
const L = viewReflectDir.toVar();
|
|
224
|
+
const H = normalize( V.add( L ) ).toVar(); // ~h; recomputed for robustness
|
|
225
|
+
|
|
226
|
+
const NdotV = max( float( 0.0 ), dot( N, V ) ).toVar();
|
|
227
|
+
const NdotL = max( float( 0.0 ), dot( N, L ) ).toVar();
|
|
228
|
+
const NdotH = max( float( 0.0 ), dot( N, H ) ).toVar();
|
|
229
|
+
const VdotH = max( float( 0.0 ), dot( V, H ) ).toVar();
|
|
230
|
+
|
|
231
|
+
const f0 = mix( vec3( 0.04 ), albedo, metalness ).toVar();
|
|
232
|
+
// Chromatic Fresnel reflectance: for metals f0 = albedo, so the reflection is tinted and desaturates
|
|
233
|
+
// toward white at grazing angles. Kept as vec3 so colored metals reflect with the correct chroma.
|
|
234
|
+
const fresnelWeight = F_Schlick( f0, VdotH ).toVar(); // vec3
|
|
235
|
+
|
|
236
|
+
// Bounded-VNDF direction pdf — still needed for the env-miss MIS path.
|
|
237
|
+
const pdf = GGXVNDFPdf( NdotH, NdotV, ax ).toVar();
|
|
238
|
+
|
|
239
|
+
// Numerically stable importance weight: brdf·NdotL/pdf ≡ fresnel·G2·(k·NdotV + t)/(2·NdotV), which
|
|
240
|
+
// cancels the GGX D analytically. Evaluating D explicitly is catastrophic at low roughness
|
|
241
|
+
// (D → 3e5 at α = 0.001 wrecks f32 precision); the cancelled form stays stable down to a mirror.
|
|
242
|
+
// (k·NdotV + t) is the bounded-cap normalization; k shrinks the cap to drop below-horizon samples.
|
|
243
|
+
const a2 = ax.mul( ax ).toVar();
|
|
244
|
+
const sinV2 = NdotV.mul( NdotV ).oneMinus().max( 0.0 ).toVar(); // ‖V.xy‖²
|
|
245
|
+
const sB = float( 1.0 ).add( sqrt( sinV2 ) ).toVar();
|
|
246
|
+
const s2B = sB.mul( sB ).toVar();
|
|
247
|
+
const kB = a2.oneMinus().mul( s2B ).div( s2B.add( a2.mul( NdotV ).mul( NdotV ) ) ).toVar();
|
|
248
|
+
const tB = sqrt( a2.mul( sinV2 ).add( NdotV.mul( NdotV ) ) ).toVar();
|
|
249
|
+
const glossyWeight = fresnelWeight
|
|
250
|
+
.mul( GeometryTerm( NdotL, NdotV, ax ) )
|
|
251
|
+
.mul( kB.mul( NdotV ).add( tB ) )
|
|
252
|
+
.div( float( 2.0 ).mul( NdotV ).max( 1e-4 ) ).toVar();
|
|
253
|
+
|
|
254
|
+
return ggxReflectionStruct( viewReflectDir, glossyWeight, pdf, NdotV, ax, f0 );
|
|
255
|
+
|
|
256
|
+
} );
|
|
257
|
+
|
|
258
|
+
// Equirectangular environment sampling
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Equirectangular direction / UV / PDF helpers and MIS weighting shared by environment sampling code.
|
|
262
|
+
* Env-miss MIS integration lives in {@link ImportanceSampledEnvironment}.
|
|
263
|
+
*
|
|
264
|
+
* Equirectangular parameterization helpers used with CDF importance sampling are adapted from
|
|
265
|
+
* [three-gpu-pathtracer](https://github.com/gkjohnson/three-gpu-pathtracer).
|
|
266
|
+
*
|
|
267
|
+
* @see {@link https://github.com/gkjohnson/three-gpu-pathtracer}
|
|
268
|
+
*/
|
|
269
|
+
|
|
270
|
+
// uv -> direction (equirectangular)
|
|
271
|
+
export const equirectUvToDir = Fn( ( [ uvIn ] ) => {
|
|
272
|
+
|
|
273
|
+
const phi = uvIn.x.mul( Math.PI * 2 ).sub( Math.PI );
|
|
274
|
+
const lat = uvIn.y.sub( 0.5 ).mul( Math.PI );
|
|
275
|
+
const cosLat = cos( lat );
|
|
276
|
+
return normalize( vec3(
|
|
277
|
+
cosLat.mul( cos( phi ) ),
|
|
278
|
+
sin( lat ),
|
|
279
|
+
cosLat.mul( sin( phi ) )
|
|
280
|
+
) );
|
|
281
|
+
|
|
282
|
+
} ).setLayout( {
|
|
283
|
+
name: 'equirectUvToDir',
|
|
284
|
+
type: 'vec3',
|
|
285
|
+
inputs: [ { name: 'uv', type: 'vec2' } ]
|
|
286
|
+
} );
|
|
287
|
+
|
|
288
|
+
// Solid-angle PDF of a direction under equirectangular parameterization.
|
|
289
|
+
export const equirectDirPdf = Fn( ( [ direction ] ) => {
|
|
290
|
+
|
|
291
|
+
const uvDir = equirectUV( direction );
|
|
292
|
+
const sinTheta = sin( uvDir.y.mul( Math.PI ) );
|
|
293
|
+
return sinTheta.abs().lessThan( float( 1e-6 ) ).select(
|
|
294
|
+
float( 0 ),
|
|
295
|
+
float( 1 ).div( float( 2 * Math.PI * Math.PI ).mul( sinTheta ) )
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
} ).setLayout( {
|
|
299
|
+
name: 'equirectDirPdf',
|
|
300
|
+
type: 'float',
|
|
301
|
+
inputs: [ { name: 'direction', type: 'vec3' } ]
|
|
302
|
+
} );
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* MIS power heuristic with β = 2: `pdfA² / (pdfA² + pdfB²)`.
|
|
306
|
+
* Weights the contribution of the strategy that produced `pdfA` against the other strategy.
|
|
307
|
+
*
|
|
308
|
+
* @see Eric Veach, *Optimally Combining Sampling Techniques for Monte Carlo Rendering*
|
|
309
|
+
* @tsl
|
|
310
|
+
*/
|
|
311
|
+
export const misPowerHeuristic = Fn( ( [ pdfA, pdfB ] ) => {
|
|
312
|
+
|
|
313
|
+
const pdfASq = pdfA.mul( pdfA );
|
|
314
|
+
const pdfBSq = pdfB.mul( pdfB );
|
|
315
|
+
return pdfASq.div( pdfASq.add( pdfBSq ) );
|
|
316
|
+
|
|
317
|
+
} ).setLayout( {
|
|
318
|
+
name: 'misPowerHeuristic',
|
|
319
|
+
type: 'float',
|
|
320
|
+
inputs: [
|
|
321
|
+
{ name: 'pdfA', type: 'float' },
|
|
322
|
+
{ name: 'pdfB', type: 'float' }
|
|
323
|
+
]
|
|
324
|
+
} );
|
|
325
|
+
|