@gnsx/three 0.185.16 → 0.186.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 +10 -82600
- package/build/three.core.js +1309 -807
- package/build/three.module.js +439 -338
- package/build/three.tsl.js +74 -44
- package/build/three.webgpu.js +6036 -2184
- package/build/three.webgpu.nodes.js +6020 -2184
- package/examples/jsm/Addons.js +6 -6
- package/examples/jsm/controls/ArcballControls.js +1 -1
- package/examples/jsm/controls/FirstPersonControls.js +44 -20
- package/examples/jsm/controls/OrbitControls.js +9 -0
- package/examples/jsm/controls/TrackballControls.js +109 -4
- package/examples/jsm/csm/CSMShadowNode.js +13 -0
- package/examples/jsm/exporters/GLTFExporter.js +23 -7
- package/examples/jsm/exporters/USDZExporter.js +2 -2
- package/examples/jsm/generators/CityGenerator.js +377 -45
- package/examples/jsm/generators/ForestGenerator.js +12 -12
- package/examples/jsm/generators/TerrainGenerator.js +49 -37
- package/examples/jsm/generators/TreeGenerator.js +70 -76
- package/examples/jsm/generators/city/BenchGenerator.js +127 -0
- package/examples/jsm/generators/city/CarGenerator.js +479 -0
- package/examples/jsm/generators/city/CityGeneratorUtils.js +31 -0
- package/examples/jsm/generators/city/HydrantGenerator.js +106 -0
- package/examples/jsm/generators/city/InstancedMeshGenerator.js +86 -0
- package/examples/jsm/generators/city/PersonGenerator.js +447 -0
- package/examples/jsm/generators/city/SidewalkGenerator.js +33 -38
- package/examples/jsm/generators/city/SkyscraperGenerator.js +448 -48
- package/examples/jsm/generators/city/StreetTreeGenerator.js +231 -0
- package/examples/jsm/generators/city/StreetlightGenerator.js +100 -0
- package/examples/jsm/generators/city/TrafficlightGenerator.js +106 -0
- package/examples/jsm/generators/city/TrashcanGenerator.js +100 -0
- package/examples/jsm/geometries/BoxLineGeometry.js +1 -1
- package/examples/jsm/geometries/ParametricGeometry.js +1 -1
- package/examples/jsm/geometries/RoundedBoxGeometry.js +1 -1
- package/examples/jsm/gpgpu/CountingSort.js +271 -0
- package/examples/jsm/helpers/LightProbeGridHelper.js +60 -239
- package/examples/jsm/helpers/LightProbeGridHelperWebGL.js +221 -0
- package/examples/jsm/inspector/Extension.js +94 -0
- package/examples/jsm/inspector/Inspector.js +145 -41
- package/examples/jsm/inspector/RendererInspector.js +100 -52
- package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +2609 -0
- package/examples/jsm/inspector/extensions/color-grading/ColorWheel.js +352 -0
- package/examples/jsm/inspector/extensions/color-grading/CurveEditor.js +599 -0
- package/examples/jsm/inspector/extensions/color-grading/LUT3DStyle.js +1201 -0
- package/examples/jsm/inspector/extensions/color-grading/LUTMath.js +788 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/BrightnessModule.js +72 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ColorWheelModule.js +112 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ContrastModule.js +82 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/CurvesModule.js +109 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ExposureHueModule.js +110 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ExposureModule.js +73 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/HueModule.js +78 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/ImportedCubeModule.js +89 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/Module.js +285 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/OutputModule.js +101 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/RendererModule.js +225 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/SatVibranceModule.js +102 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/SaturationModule.js +76 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/VibranceModule.js +76 -0
- package/examples/jsm/inspector/extensions/color-grading/modules/WhiteBalanceModule.js +86 -0
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +26 -31
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -0
- package/examples/jsm/inspector/tabs/Memory.js +0 -2
- package/examples/jsm/inspector/tabs/Settings.js +4 -0
- package/examples/jsm/inspector/tabs/Timeline.js +223 -171
- package/examples/jsm/inspector/tabs/Viewer.js +515 -21
- package/examples/jsm/inspector/ui/List.js +15 -9
- package/examples/jsm/inspector/ui/Profiler.js +170 -14
- package/examples/jsm/inspector/ui/Style.js +269 -23
- package/examples/jsm/inspector/ui/Tab.js +2 -0
- package/examples/jsm/inspector/ui/Values.js +14 -2
- package/examples/jsm/interactive/HTMLMesh.js +19 -3
- package/examples/jsm/lighting/LightProbeGrid.js +484 -889
- package/examples/jsm/lighting/LightProbeGridUtils.js +107 -0
- package/examples/jsm/lighting/LightProbeGridWebGL.js +841 -0
- package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +194 -0
- package/examples/jsm/lighting/vxgi/VXGINode.js +660 -0
- package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +478 -0
- package/examples/jsm/lighting/vxgi/VXGIVolume.js +1430 -0
- package/examples/jsm/lights/SunLight.js +95 -0
- package/examples/jsm/lights/SunLightNode.js +56 -0
- package/examples/jsm/lights/SunLightShadow.js +319 -0
- package/examples/jsm/lights/SunShadowNode.js +312 -0
- package/examples/jsm/loaders/3DMLoader.js +150 -49
- package/examples/jsm/loaders/3MFLoader.js +202 -1
- package/examples/jsm/loaders/FBXLoader.js +81 -5
- package/examples/jsm/loaders/GLTFGaussianSplatLoaderExtension.js +330 -0
- package/examples/jsm/loaders/GLTFLoader.js +79 -14
- package/examples/jsm/loaders/GaussianSplatPLYLoader.js +386 -0
- package/examples/jsm/loaders/KSPLATLoader.js +463 -0
- package/examples/jsm/loaders/MaterialXLoader.js +111 -1010
- package/examples/jsm/loaders/PCDLoader.js +1 -1
- package/examples/jsm/loaders/SPLATLoader.js +139 -0
- package/examples/jsm/loaders/SPZLoader.js +561 -0
- package/examples/jsm/loaders/materialx/MaterialXArchive.js +108 -0
- package/examples/jsm/loaders/materialx/MaterialXDocument.js +878 -0
- package/examples/jsm/loaders/materialx/MaterialXHextile.js +183 -0
- package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +376 -0
- package/examples/jsm/loaders/materialx/MaterialXLog.js +75 -0
- package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +4 -0
- package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +1021 -0
- package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +661 -0
- package/examples/jsm/loaders/materialx/MaterialXUtils.js +57 -0
- package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +997 -0
- package/examples/jsm/loaders/materialx/parse/MaterialXParser.js +28 -0
- package/examples/jsm/loaders/usd/USDAParser.js +15 -2
- package/examples/jsm/loaders/usd/USDCParser.js +1 -4
- package/examples/jsm/loaders/usd/USDComposer.js +80 -42
- package/examples/jsm/materials/WoodNodeMaterial.js +6 -108
- package/examples/jsm/misc/RollerCoaster.js +2 -2
- package/examples/jsm/misc/SculptGL.LICENSE.txt +21 -0
- package/examples/jsm/misc/Sculptor.js +1679 -0
- package/examples/jsm/misc/SculptorMesh.js +1504 -0
- package/examples/jsm/misc/SculptorTools.js +1180 -0
- package/examples/jsm/misc/SculptorUtils.js +345 -0
- package/examples/jsm/misc/TubePainter.js +28 -16
- package/examples/jsm/misc/VolumeSlice.js +24 -24
- package/examples/jsm/modifiers/SimplifyModifier.js +63 -556
- package/examples/jsm/objects/GaussianSplat.js +1039 -0
- package/examples/jsm/objects/Sky.js +66 -45
- package/examples/jsm/objects/SkyMesh.js +70 -51
- package/examples/jsm/physics/JoltPhysics.js +1 -1
- package/examples/jsm/postprocessing/AfterimagePass.js +4 -2
- package/examples/jsm/postprocessing/BloomPass.js +2 -2
- package/examples/jsm/postprocessing/GTAOPass.js +1 -1
- package/examples/jsm/postprocessing/OutlinePass.js +5 -5
- package/examples/jsm/postprocessing/SAOPass.js +1 -1
- package/examples/jsm/postprocessing/SSAOPass.js +1 -1
- package/examples/jsm/postprocessing/SSRPass.js +4 -2
- package/examples/jsm/postprocessing/SavePass.js +1 -1
- package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
- package/examples/jsm/postprocessing/UnrealBloomPass.js +30 -13
- package/examples/jsm/renderers/CSS2DRenderer.js +29 -5
- package/examples/jsm/shaders/DepthLimitedBlurShader.js +4 -1
- package/examples/jsm/shaders/ExposureShader.js +1 -1
- package/examples/jsm/shaders/FilmShader.js +2 -1
- package/examples/jsm/transpiler/AST.js +21 -2
- package/examples/jsm/transpiler/GLSLDecoder.js +498 -8
- package/examples/jsm/transpiler/TSLEncoder.js +82 -10
- package/examples/jsm/transpiler/WGSLEncoder.js +33 -4
- package/examples/jsm/tsl/WebGLNodesHandler.js +29 -39
- package/examples/jsm/tsl/display/AfterImageNode.js +2 -0
- package/examples/jsm/tsl/display/AnaglyphPassNode.js +3 -2
- package/examples/jsm/tsl/display/BilateralBlurNode.js +5 -2
- package/examples/jsm/tsl/display/BloomNode.js +55 -30
- package/examples/jsm/tsl/display/DenoiseNode.js +21 -1
- package/examples/jsm/tsl/display/DepthOfFieldNode.js +24 -6
- package/examples/jsm/tsl/display/DotScreenNode.js +11 -11
- package/examples/jsm/tsl/display/FSR1Node.js +8 -4
- package/examples/jsm/tsl/display/GTAONode.js +199 -86
- package/examples/jsm/tsl/display/GaussianBlurNode.js +65 -52
- package/examples/jsm/tsl/display/GodraysNode.js +5 -2
- package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +2 -2
- package/examples/jsm/tsl/display/LensflareNode.js +5 -2
- package/examples/jsm/tsl/display/OITPassNode.js +352 -0
- package/examples/jsm/tsl/display/OutlineNode.js +2 -0
- package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +3 -2
- package/examples/jsm/tsl/display/RGBShiftNode.js +9 -9
- package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +7 -4
- package/examples/jsm/tsl/display/RetroPassNode.js +1 -1
- package/examples/jsm/tsl/display/SMAANode.js +22 -61
- package/examples/jsm/tsl/display/SSAAPassNode.js +2 -4
- package/examples/jsm/tsl/display/SSAONode.js +436 -0
- package/examples/jsm/tsl/display/SSGINode.js +5 -2
- package/examples/jsm/tsl/display/SSRNode.js +7 -2
- package/examples/jsm/tsl/display/SSSNode.js +5 -2
- package/examples/jsm/tsl/display/SharpenNode.js +5 -4
- package/examples/jsm/tsl/display/StereoCompositePassNode.js +1 -3
- package/examples/jsm/tsl/display/StereoPassNode.js +1 -3
- package/examples/jsm/tsl/display/TAAUNode.js +22 -125
- package/examples/jsm/tsl/display/TRAANode.js +16 -142
- package/examples/jsm/tsl/display/TemporalReprojectNode.js +21 -15
- package/examples/jsm/tsl/display/depthAwareBlur.js +63 -0
- package/examples/jsm/tsl/display/hashBlur.js +3 -2
- package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +38 -27
- package/examples/jsm/tsl/lighting/LightProbeGridNode.js +136 -0
- package/examples/jsm/tsl/math/voronoiNoise.js +112 -0
- package/examples/jsm/tsl/shadows/TileShadowNode.js +4 -6
- package/examples/jsm/tsl/utils/Raymarching.js +5 -5
- package/examples/jsm/tsl/utils/SoftParticles.js +60 -0
- package/examples/jsm/tsl/utils/TAAUtils.js +195 -0
- package/examples/jsm/utils/BufferGeometryUtils.js +14 -14
- package/examples/jsm/utils/GaussianSplatUtils.js +229 -0
- package/examples/jsm/utils/WebGLTextureUtils.js +1 -1
- package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
- package/examples/jsm/webxr/WebGLXRFallback.js +2 -16
- package/examples/jsm/webxr/XRControllerModelFactory.js +16 -4
- package/package.json +9 -16
- package/src/Three.Core.js +2 -1
- package/src/Three.TSL.js +73 -43
- package/src/Three.WebGPU.Nodes.js +1 -0
- package/src/Three.WebGPU.js +1 -0
- package/src/animation/AnimationClip.js +15 -2
- package/src/animation/AnimationObjectGroup.js +18 -6
- package/src/animation/AnimationUtils.js +26 -0
- package/src/animation/KeyframeTrack.js +37 -0
- package/src/constants.js +23 -1
- package/src/core/BufferAttribute.js +3 -2
- package/src/core/BufferGeometry.js +1 -1
- package/src/core/InterleavedBuffer.js +5 -1
- package/src/core/Object3D.js +40 -12
- package/src/core/Raycaster.js +4 -0
- package/src/core/RenderTarget.js +99 -9
- package/src/core/RenderTarget3D.js +12 -8
- package/src/extras/Controls.js +0 -8
- package/src/extras/PMREMGenerator.js +99 -205
- package/src/geometries/TorusGeometry.js +1 -1
- package/src/helpers/ArrowHelper.js +2 -0
- package/src/helpers/AxesHelper.js +2 -0
- package/src/helpers/Box3Helper.js +2 -0
- package/src/helpers/BoxHelper.js +2 -0
- package/src/helpers/CameraHelper.js +2 -0
- package/src/helpers/DirectionalLightHelper.js +2 -0
- package/src/helpers/GridHelper.js +2 -0
- package/src/helpers/HemisphereLightHelper.js +2 -0
- package/src/helpers/PlaneHelper.js +2 -0
- package/src/helpers/PointLightHelper.js +2 -0
- package/src/helpers/PolarGridHelper.js +2 -0
- package/src/helpers/SkeletonHelper.js +2 -0
- package/src/helpers/SpotLightHelper.js +2 -0
- package/src/lights/Light.js +0 -10
- package/src/lights/LightShadow.js +43 -12
- package/src/lights/SpotLightShadow.js +18 -0
- package/src/loaders/BufferGeometryLoader.js +5 -0
- package/src/loaders/ImageBitmapLoader.js +3 -1
- package/src/loaders/ObjectLoader.js +8 -5
- package/src/materials/Material.js +80 -57
- package/src/materials/MeshPhysicalMaterial.js +32 -0
- package/src/materials/nodes/Line2NodeMaterial.js +17 -8
- package/src/materials/nodes/MeshPhysicalNodeMaterial.js +42 -5
- package/src/materials/nodes/NodeMaterial.js +19 -13
- package/src/materials/nodes/PointsNodeMaterial.js +2 -1
- package/src/materials/nodes/manager/NodeMaterialObserver.js +282 -55
- package/src/math/Frustum.js +9 -0
- package/src/math/FrustumArray.js +1 -1
- package/src/math/MathUtils.js +5 -3
- package/src/math/Matrix4.js +2 -9
- package/src/math/Plane.js +30 -1
- package/src/math/Quaternion.js +0 -10
- package/src/math/Ray.js +95 -45
- package/src/math/Triangle.js +0 -2
- package/src/math/Vector3.js +2 -2
- package/src/math/Vector4.js +0 -4
- package/src/math/interpolants/BezierInterpolant.js +36 -23
- package/src/nodes/Nodes.js +2 -0
- package/src/nodes/TSL.js +11 -3
- package/src/nodes/accessors/Batch.js +85 -13
- package/src/nodes/accessors/BufferAttributeNode.js +1 -1
- package/src/nodes/accessors/BuiltinNode.js +1 -1
- package/src/nodes/accessors/Instance.js +19 -18
- package/src/nodes/accessors/MaterialNode.js +9 -0
- package/src/nodes/accessors/ModelNode.js +85 -9
- package/src/nodes/accessors/ReferenceBaseNode.js +1 -70
- package/src/nodes/accessors/ReferenceElementNode.js +72 -0
- package/src/nodes/accessors/ReferenceNode.js +1 -70
- package/src/nodes/accessors/Skinning.js +124 -12
- package/src/nodes/accessors/StorageTextureNode.js +7 -3
- package/src/nodes/accessors/Texture3DNode.js +1 -1
- package/src/nodes/accessors/TextureNode.js +51 -21
- package/src/nodes/accessors/TextureSizeNode.js +4 -2
- package/src/nodes/accessors/UniformArrayNode.js +30 -5
- package/src/nodes/code/CodeNode.js +1 -1
- package/src/nodes/code/FunctionNode.js +12 -2
- package/src/nodes/core/ArrayNode.js +2 -2
- package/src/nodes/core/ContextNode.js +57 -4
- package/src/nodes/core/IndexNode.js +69 -4
- package/src/nodes/core/InspectorNode.js +2 -2
- package/src/nodes/core/MRTNode.js +44 -2
- package/src/nodes/core/Node.js +6 -3
- package/src/nodes/core/NodeBuilder.js +65 -50
- package/src/nodes/core/NodeFrame.js +11 -3
- package/src/nodes/core/NodeUtils.js +88 -0
- package/src/nodes/core/PropertyNode.js +8 -0
- package/src/nodes/core/StackNode.js +0 -1
- package/src/nodes/core/StructNode.js +4 -3
- package/src/nodes/core/UniformGroupNode.js +3 -2
- package/src/nodes/core/UniformNode.js +26 -12
- package/src/nodes/core/VarNode.js +0 -1
- package/src/nodes/display/BumpMapNode.js +2 -2
- package/src/nodes/display/ColorAdjustment.js +1 -1
- package/src/nodes/display/PassNode.js +76 -15
- package/src/nodes/display/ScreenNode.js +22 -65
- package/src/nodes/fog/Fog.js +4 -4
- package/src/nodes/functions/BSDF/BRDF_GGX.js +6 -6
- package/src/nodes/functions/BSDF/BRDF_Sheen.js +1 -1
- package/src/nodes/functions/BSDF/DFGLUT.js +2 -1
- package/src/nodes/functions/BSDF/LTC.js +1 -1
- package/src/nodes/functions/PhongLightingModel.js +1 -1
- package/src/nodes/functions/PhysicalLightingModel.js +83 -25
- package/src/nodes/functions/ToonLightingModel.js +2 -2
- package/src/nodes/functions/material/getParallaxCorrectNormal.js +3 -3
- package/src/nodes/gpgpu/AtomicFunctionNode.js +64 -13
- package/src/nodes/gpgpu/BarrierNode.js +13 -4
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
- package/src/nodes/gpgpu/ComputeNode.js +20 -17
- package/src/nodes/gpgpu/SubgroupFunctionNode.js +165 -37
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +44 -6
- package/src/nodes/lighting/EnvironmentNode.js +40 -4
- package/src/nodes/lighting/LightsNode.js +20 -4
- package/src/nodes/lighting/ShadowBaseNode.js +158 -1
- package/src/nodes/lighting/ShadowFilterNode.js +2 -106
- package/src/nodes/lighting/ShadowNode.js +22 -91
- package/src/nodes/materialx/{lib/mx_hsv.js → MaterialXColor.js} +3 -6
- package/src/nodes/materialx/{lib/mx_transform_color.js → MaterialXColorTransform.js} +3 -6
- package/src/nodes/materialx/MaterialXCore.js +37 -0
- package/src/nodes/materialx/MaterialXNodes.js +64 -72
- package/src/nodes/materialx/{lib/mx_noise.js → MaterialXNoise.js} +426 -197
- package/src/nodes/math/BitcountNode.js +24 -4
- package/src/nodes/math/MathNode.js +4 -4
- package/src/nodes/math/MathUtils.js +15 -4
- package/src/nodes/math/OperatorNode.js +2 -2
- package/src/nodes/math/PackFloatNode.js +29 -1
- package/src/nodes/math/Packed4x8IntegerNode.js +433 -0
- package/src/nodes/math/UnpackFloatNode.js +30 -2
- package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
- package/src/nodes/pmrem/PMREMNode.js +1 -1
- package/src/nodes/pmrem/PMREMUtils.js +31 -74
- package/src/nodes/shapes/Shapes.js +1 -1
- package/src/nodes/tsl/TSLCore.js +1 -31
- package/src/nodes/utils/EventNode.js +75 -0
- package/src/nodes/utils/LoopNode.js +54 -13
- package/src/nodes/utils/PostProcessingUtils.js +23 -2
- package/src/nodes/utils/RTTNode.js +97 -32
- package/src/nodes/utils/ReflectorNode.js +8 -4
- package/src/nodes/utils/RotateNode.js +85 -8
- package/src/nodes/utils/SpriteUtils.js +58 -23
- package/src/objects/BatchedMesh.js +6 -0
- package/src/objects/InstancedMesh.js +1 -1
- package/src/objects/LOD.js +1 -1
- package/src/objects/Line.js +12 -0
- package/src/objects/Mesh.js +12 -0
- package/src/objects/Points.js +12 -0
- package/src/objects/Sprite.js +12 -0
- package/src/renderers/WebGLRenderer.js +93 -27
- package/src/renderers/common/Animation.js +12 -2
- package/src/renderers/common/Backend.js +38 -10
- package/src/renderers/common/BindGroup.js +0 -1
- package/src/renderers/common/Bindings.js +50 -4
- package/src/renderers/common/BundleGroup.js +4 -0
- package/src/renderers/common/ClippingContext.js +11 -1
- package/src/renderers/common/Color4.js +9 -0
- package/src/renderers/common/Constants.js +0 -5
- package/src/renderers/common/DirectRenderPipeline.js +233 -0
- package/src/renderers/common/Geometries.js +24 -3
- package/src/renderers/common/Info.js +3 -3
- package/src/renderers/common/InspectorBase.js +37 -8
- package/src/renderers/common/Lighting.js +11 -4
- package/src/renderers/common/Pipelines.js +6 -4
- package/src/renderers/common/QuadMesh.js +16 -2
- package/src/renderers/common/RenderContext.js +8 -0
- package/src/renderers/common/RenderList.js +53 -19
- package/src/renderers/common/RenderLists.js +58 -11
- package/src/renderers/common/RenderObject.js +14 -0
- package/src/renderers/common/RenderObjects.js +14 -9
- package/src/renderers/common/RenderPipeline.js +52 -44
- package/src/renderers/common/Renderer.js +226 -55
- package/src/renderers/common/Storage3DTexture.js +16 -0
- package/src/renderers/common/Textures.js +3 -3
- package/src/renderers/common/XRManager.js +79 -72
- package/src/renderers/common/extras/PMREMGenerator.js +76 -144
- package/src/renderers/common/nodes/NodeManager.js +144 -6
- package/src/renderers/common/nodes/NodeStorageBuffer.js +3 -1
- package/src/renderers/common/nodes/NodeUniformBuffer.js +3 -1
- package/src/renderers/shaders/DFGLUTData.js +2 -1
- package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +4 -2
- package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +48 -0
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +53 -4
- package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +20 -2
- package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +20 -0
- package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +61 -57
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +82 -0
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +9 -0
- package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +8 -1
- package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +15 -0
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
- package/src/renderers/shaders/ShaderLib.js +1 -0
- package/src/renderers/shaders/UniformsLib.js +16 -0
- package/src/renderers/webgl/WebGLAnimation.js +2 -2
- package/src/renderers/webgl/WebGLCapabilities.js +2 -2
- package/src/renderers/webgl/WebGLLights.js +74 -4
- package/src/renderers/webgl/WebGLMaterials.js +6 -0
- package/src/renderers/webgl/WebGLOutput.js +36 -24
- package/src/renderers/webgl/WebGLProgram.js +3 -0
- package/src/renderers/webgl/WebGLPrograms.js +8 -0
- package/src/renderers/webgl/WebGLRenderLists.js +6 -10
- package/src/renderers/webgl/WebGLShadowMap.js +47 -44
- package/src/renderers/webgl/WebGLTextures.js +7 -7
- package/src/renderers/webgl-fallback/WebGLBackend.js +153 -45
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +83 -29
- package/src/renderers/webgl-fallback/utils/WebGLState.js +163 -17
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +32 -5
- package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +11 -4
- package/src/renderers/webgpu/WebGPUBackend.js +513 -145
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +99 -20
- package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -1
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +3 -12
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +24 -14
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +80 -14
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -7
- package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +9 -3
- package/src/renderers/webgpu/utils/WebGPUUtils.js +16 -4
- package/src/renderers/webxr/WebXRManager.js +25 -2
- package/src/scenes/Scene.js +3 -3
- package/src/textures/CompressedArrayTexture.js +16 -0
- package/src/textures/Data3DTexture.js +16 -0
- package/src/textures/DataArrayTexture.js +16 -0
- package/src/textures/DepthTexture.js +3 -3
- package/src/textures/Texture.js +3 -3
- package/src/textures/{Source.js → TextureSource.js} +39 -8
- package/src/utils.js +6 -79
- package/build/three.core.min.js +0 -6
- package/build/three.module.min.js +0 -6
- package/build/three.tsl.min.js +0 -6
- package/build/three.webgpu.min.js +0 -6
- package/build/three.webgpu.nodes.min.js +0 -6
- package/examples/jsm/libs/ecsy.module.js +0 -1792
- package/examples/jsm/loaders/LottieLoader.js +0 -130
- package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +0 -52
|
@@ -0,0 +1,660 @@
|
|
|
1
|
+
import { RenderTarget, Vector2, Vector3, TempNode, QuadMesh, NodeMaterial, RendererUtils, HalfFloatType, RGBAFormat, RedFormat, UnsignedByteType } from '@gnsx/three/webgpu';
|
|
2
|
+
import { Fn, NodeUpdateType, uniform, reference, vec2, vec3, vec4, float, uint, uv, mix, passTexture, getViewPosition, getNormalFromDepth, logarithmicDepthToViewZ, viewZToPerspectiveDepth, screenCoordinate, interleavedGradientNoise, normalize, cross, abs, select, sqrt, fract, floor, cos, sin, exp2, pow, PI, Loop, If, Break, property, outputStruct, context } from '@gnsx/three/tsl';
|
|
3
|
+
|
|
4
|
+
import { VXGIVolume } from './VXGIVolume.js';
|
|
5
|
+
import { createConeTracer, intersectVolume, sampleDirectional } from './VXGIConeTracer.js';
|
|
6
|
+
|
|
7
|
+
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
8
|
+
const _size = /*@__PURE__*/ new Vector2();
|
|
9
|
+
|
|
10
|
+
const TEMPORAL_SHIFT = 5.588238;
|
|
11
|
+
const TEMPORAL_CYCLE = 64;
|
|
12
|
+
|
|
13
|
+
let _rendererState;
|
|
14
|
+
|
|
15
|
+
const _neutralContext = /*@__PURE__*/ context();
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Post processing node for voxel based global illumination. The scene is voxelized into a
|
|
19
|
+
* {@link VXGIVolume} and indirect diffuse light and ambient occlusion are gathered per
|
|
20
|
+
* pixel with approximate voxel cone tracing.
|
|
21
|
+
*
|
|
22
|
+
* The node is a middle path between SSGI and Light Probe Grids:
|
|
23
|
+
*
|
|
24
|
+
* - Compared to `SSGINode` it is free of screen-space artifacts and provides noticeably more
|
|
25
|
+
* consistent lighting, since off-screen surfaces and thin occluders contribute.
|
|
26
|
+
* However, it is less dynamic: objects should stay static, because geometry changes require
|
|
27
|
+
* a re-voxelization (`needsUpdate = true`) which is too expensive for per-frame animation.
|
|
28
|
+
* - Compared to `LightProbeGrid` it supports dynamic lighting without a new baking process and
|
|
29
|
+
* produces a better overall lighting quality with less light bleeding. However, it is more
|
|
30
|
+
* expensive and therefore less suitable for performance restricted use cases.
|
|
31
|
+
*
|
|
32
|
+
* The quality/performance of the effect mainly depend on the voxel resolution, the number of cones
|
|
33
|
+
* traced per pixel as well as the apeture of the cones.
|
|
34
|
+
*
|
|
35
|
+
* Lights and their shadow maps are picked up automatically. Only direct lights are injected.
|
|
36
|
+
*
|
|
37
|
+
* References:
|
|
38
|
+
* - {@link https://research.nvidia.com/publication/2011-09_interactive-indirect-illumination-using-voxel-cone-tracing}:
|
|
39
|
+
* Crassin et al., Interactive Indirect Illumination Using Voxel Cone Tracing, Pacific Graphics 2011.
|
|
40
|
+
*
|
|
41
|
+
* Note: This node can only be used with `WebGPURenderer` and a WebGPU backend.
|
|
42
|
+
*
|
|
43
|
+
* @augments TempNode
|
|
44
|
+
* @three_import import { vxgi } from 'three/addons/lighting/vxgi/VXGINode.js';
|
|
45
|
+
*/
|
|
46
|
+
class VXGINode extends TempNode {
|
|
47
|
+
|
|
48
|
+
static get type() {
|
|
49
|
+
|
|
50
|
+
return 'VXGINode';
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Constructs a new voxel GI node.
|
|
56
|
+
*
|
|
57
|
+
* @param {TextureNode} depthNode - A texture node that represents the scene's depth.
|
|
58
|
+
* @param {?TextureNode} normalNode - A texture node that represents the scene's view space normals.
|
|
59
|
+
* @param {Scene} scene - The scene to voxelize.
|
|
60
|
+
* @param {Camera} camera - The camera the scene is rendered with.
|
|
61
|
+
* @param {number} [resolution=128] - Number of voxels along the longest axis of the volume. Should not exceed `256`, higher values exceed the maximum storage buffer size of the voxelizer.
|
|
62
|
+
*/
|
|
63
|
+
constructor( depthNode, normalNode, scene, camera, resolution = 128 ) {
|
|
64
|
+
|
|
65
|
+
super( 'vec4' );
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A node that represents the scene's depth.
|
|
69
|
+
*
|
|
70
|
+
* @type {TextureNode}
|
|
71
|
+
*/
|
|
72
|
+
this.depthNode = depthNode;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A node that represents the scene's normals. If `null`, normals are reconstructed from depth.
|
|
76
|
+
*
|
|
77
|
+
* @type {?TextureNode}
|
|
78
|
+
*/
|
|
79
|
+
this.normalNode = normalNode;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The scene to voxelize.
|
|
83
|
+
*
|
|
84
|
+
* @type {Scene}
|
|
85
|
+
*/
|
|
86
|
+
this.scene = scene;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The camera the scene is rendered with.
|
|
90
|
+
*
|
|
91
|
+
* @type {Camera}
|
|
92
|
+
*/
|
|
93
|
+
this.camera = camera;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The voxel volume. Use it to configure bounds, layers and bounces.
|
|
97
|
+
*
|
|
98
|
+
* @type {VXGIVolume}
|
|
99
|
+
*/
|
|
100
|
+
this.volume = new VXGIVolume( resolution );
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
|
|
104
|
+
* its effect once per frame in `updateBefore()`.
|
|
105
|
+
*
|
|
106
|
+
* @type {string}
|
|
107
|
+
* @default 'frame'
|
|
108
|
+
*/
|
|
109
|
+
this.updateBeforeType = NodeUpdateType.FRAME;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Number of cones traced per pixel. Should be in the range `[2, 8]`.
|
|
113
|
+
*
|
|
114
|
+
* Mainly defines the quality and precision of the Voxel Cone Tracing. A value of
|
|
115
|
+
* `2` - `4` is the recommended setting. Use `2` for performance restricted use cases.
|
|
116
|
+
*
|
|
117
|
+
* @type {UniformNode<uint>}
|
|
118
|
+
* @default 3
|
|
119
|
+
*/
|
|
120
|
+
this.coneCount = uniform( 3, 'uint' );
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Aperture of the diffuse cones in degrees. Wider cones are faster (fewer steps) but leak
|
|
124
|
+
* and over-occlude more, narrow cones are more precise but noisier and take more steps.
|
|
125
|
+
* Choose it together with {@link VXGINode#coneCount}. Should be in the range `[10, 90]`.
|
|
126
|
+
*
|
|
127
|
+
* @type {UniformNode<float>}
|
|
128
|
+
* @default 40
|
|
129
|
+
*/
|
|
130
|
+
this.coneAngle = uniform( 40 );
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Intensity of the indirect diffuse irradiance.
|
|
134
|
+
*
|
|
135
|
+
* @type {UniformNode<float>}
|
|
136
|
+
* @default 1
|
|
137
|
+
*/
|
|
138
|
+
this.giIntensity = uniform( 1 );
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Power function applied to AO to make it appear darker/lighter.
|
|
142
|
+
*
|
|
143
|
+
* @type {UniformNode<float>}
|
|
144
|
+
* @default 1
|
|
145
|
+
*/
|
|
146
|
+
this.aoIntensity = uniform( 1 );
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The darkest value the ambient occlusion can reach. Lifts creases and contact regions out
|
|
150
|
+
* of pure black, which voxel-traced occlusion tends to overestimate at the resolution of
|
|
151
|
+
* a voxel. `0` keeps the full occlusion range.
|
|
152
|
+
*
|
|
153
|
+
* @type {UniformNode<float>}
|
|
154
|
+
* @default 0
|
|
155
|
+
*/
|
|
156
|
+
this.aoMinVisibility = uniform( 0 );
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Occlusion is weighted by `1 / ( 1 + distance / aoDistance )` for AO, so occluders at this
|
|
160
|
+
* world-space distance count half. `0` disables the falloff.
|
|
161
|
+
*
|
|
162
|
+
* @type {UniformNode<float>}
|
|
163
|
+
* @default 1
|
|
164
|
+
*/
|
|
165
|
+
this.aoDistance = uniform( 1 );
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Offset of the cone origins along the surface normal in voxels. The surface's own voxel
|
|
169
|
+
* can extend up to half a voxel above the surface and the trilinear footprint of a sample
|
|
170
|
+
* spans another half voxel, so 1.5 voxels avoid self-occlusion in every case.
|
|
171
|
+
*
|
|
172
|
+
* @type {UniformNode<float>}
|
|
173
|
+
* @default 1.5
|
|
174
|
+
*/
|
|
175
|
+
this.normalOffset = uniform( 1.5 );
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Debug visualization of the volume: `0` = off, `1` = radiance voxels, `2` = per-axis opacity voxels.
|
|
179
|
+
* The visualization replaces the GI output.
|
|
180
|
+
*
|
|
181
|
+
* @type {UniformNode<int>}
|
|
182
|
+
* @default 0
|
|
183
|
+
*/
|
|
184
|
+
this.debug = uniform( 0, 'int' );
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* The mip level shown by the debug visualization.
|
|
188
|
+
*
|
|
189
|
+
* @type {UniformNode<float>}
|
|
190
|
+
* @default 0
|
|
191
|
+
*/
|
|
192
|
+
this.debugLevel = uniform( 0 );
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Whether to use temporal filtering or not. Setting this property to `true` requires the
|
|
196
|
+
* usage of `TRAANode`. Cone directions are then rotated per frame to converge the noise.
|
|
197
|
+
*
|
|
198
|
+
* @type {boolean}
|
|
199
|
+
* @default true
|
|
200
|
+
*/
|
|
201
|
+
this.useTemporalFiltering = true;
|
|
202
|
+
|
|
203
|
+
// private uniforms
|
|
204
|
+
|
|
205
|
+
this._resolution = uniform( new Vector2() );
|
|
206
|
+
this._frame = uniform( 0 );
|
|
207
|
+
this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
|
|
208
|
+
this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
|
|
209
|
+
this._cameraWorldMatrix = uniform( camera.matrixWorld );
|
|
210
|
+
this._cameraPosition = uniform( new Vector3() ).onRenderUpdate( ( _, self ) => self.value.setFromMatrixPosition( camera.matrixWorld ) );
|
|
211
|
+
this._cameraNear = reference( 'near', 'float', camera );
|
|
212
|
+
this._cameraFar = reference( 'far', 'float', camera );
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* The render target the effect is rendered into. The first texture holds the AO,
|
|
216
|
+
* the second one the GI.
|
|
217
|
+
*
|
|
218
|
+
* @private
|
|
219
|
+
* @type {RenderTarget}
|
|
220
|
+
*/
|
|
221
|
+
this._renderTarget = new RenderTarget( 1, 1, { depthBuffer: false, count: 2 } );
|
|
222
|
+
|
|
223
|
+
const aoTexture = this._renderTarget.textures[ 0 ];
|
|
224
|
+
aoTexture.name = 'VXGI.AO';
|
|
225
|
+
aoTexture.type = UnsignedByteType;
|
|
226
|
+
aoTexture.format = RedFormat;
|
|
227
|
+
|
|
228
|
+
const giTexture = this._renderTarget.textures[ 1 ];
|
|
229
|
+
giTexture.name = 'VXGI.GI';
|
|
230
|
+
giTexture.type = HalfFloatType;
|
|
231
|
+
giTexture.format = RGBAFormat;
|
|
232
|
+
|
|
233
|
+
this._material = new NodeMaterial();
|
|
234
|
+
this._material.name = 'VXGI';
|
|
235
|
+
|
|
236
|
+
// the shared context of the last build and the directional setting the material was built with
|
|
237
|
+
|
|
238
|
+
this._sharedContext = null;
|
|
239
|
+
this._directional = null;
|
|
240
|
+
|
|
241
|
+
this._aoNode = passTexture( this, aoTexture );
|
|
242
|
+
this._giNode = passTexture( this, giTexture );
|
|
243
|
+
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Number of cached indirect bounces. See {@link VXGIVolume#bounces}.
|
|
248
|
+
*
|
|
249
|
+
* @type {number}
|
|
250
|
+
*/
|
|
251
|
+
get bounces() {
|
|
252
|
+
|
|
253
|
+
return this.volume.bounces;
|
|
254
|
+
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
set bounces( value ) {
|
|
258
|
+
|
|
259
|
+
this.volume.bounces = value;
|
|
260
|
+
this.volume.lightingNeedsUpdate = true;
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Whether the coarser radiance levels are filtered directionally to reduce light bleeding
|
|
266
|
+
* through thin walls and floors. Off by default since it costs memory and performance.
|
|
267
|
+
* See {@link VXGIVolume#directionalRadiance}.
|
|
268
|
+
*
|
|
269
|
+
* @type {boolean}
|
|
270
|
+
*/
|
|
271
|
+
get directionalRadiance() {
|
|
272
|
+
|
|
273
|
+
return this.volume.directionalRadiance;
|
|
274
|
+
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
set directionalRadiance( value ) {
|
|
278
|
+
|
|
279
|
+
this.volume.directionalRadiance = value;
|
|
280
|
+
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Set to `true` to re-voxelize the scene in the next frame.
|
|
285
|
+
*
|
|
286
|
+
* @type {boolean}
|
|
287
|
+
*/
|
|
288
|
+
get needsUpdate() {
|
|
289
|
+
|
|
290
|
+
return this.volume.needsUpdate;
|
|
291
|
+
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
set needsUpdate( value ) {
|
|
295
|
+
|
|
296
|
+
this.volume.needsUpdate = value;
|
|
297
|
+
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Set to `true` to re-inject lighting in the next frame.
|
|
302
|
+
*
|
|
303
|
+
* @type {boolean}
|
|
304
|
+
*/
|
|
305
|
+
get lightingNeedsUpdate() {
|
|
306
|
+
|
|
307
|
+
return this.volume.lightingNeedsUpdate;
|
|
308
|
+
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
set lightingNeedsUpdate( value ) {
|
|
312
|
+
|
|
313
|
+
this.volume.lightingNeedsUpdate = value;
|
|
314
|
+
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Returns the AO result of the effect as a texture node.
|
|
319
|
+
*
|
|
320
|
+
* @return {PassTextureNode} A texture node that represents the AO result of the effect.
|
|
321
|
+
*/
|
|
322
|
+
getAONode() {
|
|
323
|
+
|
|
324
|
+
return this._aoNode;
|
|
325
|
+
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Returns the GI result of the effect as a texture node. The texture holds the indirect
|
|
330
|
+
* diffuse irradiance, ready to be added to the lighting via `builtinGIContext()`.
|
|
331
|
+
*
|
|
332
|
+
* @return {PassTextureNode} A texture node that represents the GI result of the effect.
|
|
333
|
+
*/
|
|
334
|
+
getGINode() {
|
|
335
|
+
|
|
336
|
+
return this._giNode;
|
|
337
|
+
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Sets the size of the effect.
|
|
342
|
+
*
|
|
343
|
+
* @param {number} width - The width of the effect.
|
|
344
|
+
* @param {number} height - The height of the effect.
|
|
345
|
+
*/
|
|
346
|
+
setSize( width, height ) {
|
|
347
|
+
|
|
348
|
+
this._resolution.value.set( width, height );
|
|
349
|
+
this._renderTarget.setSize( width, height );
|
|
350
|
+
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* This method is used to render the effect once per frame.
|
|
355
|
+
*
|
|
356
|
+
* @param {NodeFrame} frame - The current node frame.
|
|
357
|
+
*/
|
|
358
|
+
updateBefore( frame ) {
|
|
359
|
+
|
|
360
|
+
const { renderer } = frame;
|
|
361
|
+
|
|
362
|
+
_rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
|
|
363
|
+
|
|
364
|
+
// this node is usually updated while a scene pass renders whose context injects the
|
|
365
|
+
// AO/GI of this node into the materials; the nested renders below must not inherit it
|
|
366
|
+
|
|
367
|
+
const currentContextNode = renderer.contextNode;
|
|
368
|
+
renderer.contextNode = _neutralContext;
|
|
369
|
+
|
|
370
|
+
//
|
|
371
|
+
|
|
372
|
+
const size = renderer.getDrawingBufferSize( _size );
|
|
373
|
+
this.setSize( size.width, size.height );
|
|
374
|
+
|
|
375
|
+
// voxelization and light injection
|
|
376
|
+
|
|
377
|
+
this.volume.update( renderer, this.scene );
|
|
378
|
+
|
|
379
|
+
// the sampling code depends on the volume's directional setting
|
|
380
|
+
|
|
381
|
+
if ( this._sharedContext !== null && this._directional !== this.volume.directionalRadiance ) {
|
|
382
|
+
|
|
383
|
+
this._setupMaterial( renderer );
|
|
384
|
+
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// update temporal uniforms
|
|
388
|
+
|
|
389
|
+
if ( this.useTemporalFiltering === true ) {
|
|
390
|
+
|
|
391
|
+
this._frame.value = frame.frameId % TEMPORAL_CYCLE;
|
|
392
|
+
|
|
393
|
+
} else {
|
|
394
|
+
|
|
395
|
+
this._frame.value = 0;
|
|
396
|
+
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
//
|
|
400
|
+
|
|
401
|
+
_quadMesh.material = this._material;
|
|
402
|
+
_quadMesh.name = 'VXGI';
|
|
403
|
+
|
|
404
|
+
// clear (white for the AO attachment)
|
|
405
|
+
|
|
406
|
+
renderer.setClearColor( 0xffffff, 1 );
|
|
407
|
+
|
|
408
|
+
renderer.setRenderTarget( this._renderTarget );
|
|
409
|
+
_quadMesh.render( renderer );
|
|
410
|
+
|
|
411
|
+
// restore
|
|
412
|
+
|
|
413
|
+
renderer.contextNode = currentContextNode;
|
|
414
|
+
|
|
415
|
+
RendererUtils.restoreRendererState( renderer, _rendererState );
|
|
416
|
+
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* This method is used to setup the effect's TSL code.
|
|
421
|
+
*
|
|
422
|
+
* @param {NodeBuilder} builder - The current node builder.
|
|
423
|
+
* @return {PassTextureNode}
|
|
424
|
+
*/
|
|
425
|
+
setup( builder ) {
|
|
426
|
+
|
|
427
|
+
this._sharedContext = builder.getSharedContext();
|
|
428
|
+
this._setupMaterial( builder.renderer );
|
|
429
|
+
|
|
430
|
+
return this._aoNode;
|
|
431
|
+
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Builds the TSL code of the effect into the internal pass material.
|
|
436
|
+
*
|
|
437
|
+
* @private
|
|
438
|
+
* @param {Renderer} renderer - The renderer.
|
|
439
|
+
*/
|
|
440
|
+
_setupMaterial( renderer ) {
|
|
441
|
+
|
|
442
|
+
const volume = this.volume;
|
|
443
|
+
const directional = this._directional = volume.directionalRadiance;
|
|
444
|
+
const uvNode = uv();
|
|
445
|
+
|
|
446
|
+
const sampleDepth = ( uv ) => {
|
|
447
|
+
|
|
448
|
+
const depth = this.depthNode.sample( uv ).r;
|
|
449
|
+
|
|
450
|
+
if ( renderer.logarithmicDepthBuffer === true ) {
|
|
451
|
+
|
|
452
|
+
const viewZ = logarithmicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
|
|
453
|
+
|
|
454
|
+
return viewZToPerspectiveDepth( viewZ, this._cameraNear, this._cameraFar );
|
|
455
|
+
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return depth;
|
|
459
|
+
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.sample( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this._cameraProjectionMatrixInverse );
|
|
463
|
+
|
|
464
|
+
const voxelSize = volume.voxelSizeNode;
|
|
465
|
+
const projectionMatrixInverse = this._cameraProjectionMatrixInverse;
|
|
466
|
+
|
|
467
|
+
const trace = createConeTracer( volume, {
|
|
468
|
+
radianceNode: volume.radianceNode,
|
|
469
|
+
directionalNode: directional === true ? volume.directionalNode : null
|
|
470
|
+
} );
|
|
471
|
+
|
|
472
|
+
const aoField = property( 'float' );
|
|
473
|
+
const giField = property( 'vec4' );
|
|
474
|
+
|
|
475
|
+
const outputNode = outputStruct( aoField, giField );
|
|
476
|
+
|
|
477
|
+
const gi = Fn( () => {
|
|
478
|
+
|
|
479
|
+
const depth = sampleDepth( uvNode ).toConst();
|
|
480
|
+
|
|
481
|
+
depth.greaterThanEqual( 1.0 ).discard();
|
|
482
|
+
|
|
483
|
+
const viewPosition = getViewPosition( uvNode, depth, projectionMatrixInverse ).toConst();
|
|
484
|
+
const worldPosition = this._cameraWorldMatrix.mul( vec4( viewPosition, 1 ) ).xyz.toConst();
|
|
485
|
+
const viewNormal = sampleNormal( uvNode ).toConst();
|
|
486
|
+
const worldNormal = normalize( this._cameraWorldMatrix.mul( vec4( viewNormal, 0 ) ).xyz ).toConst();
|
|
487
|
+
|
|
488
|
+
// interleaved gradient noise for both values: its spatial structure converges well under temporal filtering
|
|
489
|
+
|
|
490
|
+
const temporalShift = this._frame.mul( TEMPORAL_SHIFT ).toConst();
|
|
491
|
+
const rotationNoise = interleavedGradientNoise( screenCoordinate.add( temporalShift ) ).toConst();
|
|
492
|
+
const elevationNoise = interleavedGradientNoise( screenCoordinate.add( temporalShift ).add( vec2( 5.588238, 3.14159 ) ) ).toConst();
|
|
493
|
+
|
|
494
|
+
// tangent frame
|
|
495
|
+
|
|
496
|
+
const up = select( abs( worldNormal.y ).lessThan( 0.99 ), vec3( 0, 1, 0 ), vec3( 1, 0, 0 ) );
|
|
497
|
+
const tangent = normalize( cross( worldNormal, up ) ).toConst();
|
|
498
|
+
const bitangent = cross( worldNormal, tangent ).toConst();
|
|
499
|
+
|
|
500
|
+
const CONE_COUNT = this.coneCount.toConst();
|
|
501
|
+
const tanHalfAngle = this.coneAngle.mul( 0.5 ).radians().tan().toConst();
|
|
502
|
+
const traceDistance = volume.traceDistanceNode;
|
|
503
|
+
const aoDistance = this.aoDistance;
|
|
504
|
+
const originOffset = worldNormal.mul( voxelSize.mul( this.normalOffset ) ).toConst();
|
|
505
|
+
|
|
506
|
+
const color = vec3( 0 ).toVar();
|
|
507
|
+
const occlusion = float( 0 ).toVar();
|
|
508
|
+
|
|
509
|
+
Loop( { start: uint( 0 ), end: CONE_COUNT, type: 'uint', condition: '<', name: 'c' }, ( { c } ) => {
|
|
510
|
+
|
|
511
|
+
// stratified cosine-weighted directions
|
|
512
|
+
|
|
513
|
+
const u1 = float( c ).add( elevationNoise ).div( float( CONE_COUNT ) ).toConst();
|
|
514
|
+
const u2 = fract( float( c ).mul( 0.618034 ).add( rotationNoise ) ).toConst();
|
|
515
|
+
const sinTheta = sqrt( u1 ).toConst();
|
|
516
|
+
const cosTheta = sqrt( u1.oneMinus() ).toConst();
|
|
517
|
+
const phi = u2.mul( PI.mul( 2 ) ).toConst();
|
|
518
|
+
|
|
519
|
+
const direction = normalize( tangent.mul( cos( phi ).mul( sinTheta ) ).add( bitangent.mul( sin( phi ).mul( sinTheta ) ) ).add( worldNormal.mul( cosTheta ) ) ).toConst();
|
|
520
|
+
const origin = worldPosition.add( originOffset ).toConst();
|
|
521
|
+
|
|
522
|
+
const cone = trace( origin, direction, tanHalfAngle, traceDistance, aoDistance );
|
|
523
|
+
|
|
524
|
+
color.addAssign( cone.color );
|
|
525
|
+
occlusion.addAssign( cone.ao );
|
|
526
|
+
|
|
527
|
+
} );
|
|
528
|
+
|
|
529
|
+
// the mean radiance over the cosine-weighted hemisphere times PI is the irradiance
|
|
530
|
+
|
|
531
|
+
color.divAssign( float( CONE_COUNT ) );
|
|
532
|
+
color.mulAssign( this.giIntensity.mul( PI ) );
|
|
533
|
+
|
|
534
|
+
const ao = mix( this.aoMinVisibility, float( 1 ), pow( occlusion.div( float( CONE_COUNT ) ).oneMinus().clamp(), this.aoIntensity ) ).toVar();
|
|
535
|
+
|
|
536
|
+
// debug visualization: march the voxels from the camera
|
|
537
|
+
|
|
538
|
+
If( this.debug.greaterThan( 0 ), () => {
|
|
539
|
+
|
|
540
|
+
const cameraPosition = this._cameraPosition;
|
|
541
|
+
const direction = normalize( worldPosition.sub( cameraPosition ) ).toConst();
|
|
542
|
+
const surfaceDistance = worldPosition.sub( cameraPosition ).length().toConst();
|
|
543
|
+
const level = this.debugLevel.toConst();
|
|
544
|
+
const texel = voxelSize.mul( exp2( level ) ).toConst();
|
|
545
|
+
const levelSize = volume.volumeSizeNode.div( texel ).toConst();
|
|
546
|
+
const boundsMin = volume.boundsMinNode;
|
|
547
|
+
|
|
548
|
+
const { tEnter, tExit } = intersectVolume( volume, cameraPosition, direction );
|
|
549
|
+
const tMax = tExit.min( surfaceDistance ).toConst();
|
|
550
|
+
const t = tEnter.toVar();
|
|
551
|
+
|
|
552
|
+
color.assign( 0 );
|
|
553
|
+
ao.assign( 1 );
|
|
554
|
+
|
|
555
|
+
Loop( { start: 0, end: 512, type: 'int', condition: '<', name: 's' }, () => {
|
|
556
|
+
|
|
557
|
+
If( t.greaterThanEqual( tMax ), () => {
|
|
558
|
+
|
|
559
|
+
Break();
|
|
560
|
+
|
|
561
|
+
} );
|
|
562
|
+
|
|
563
|
+
const uvw = cameraPosition.add( direction.mul( t ) ).sub( boundsMin ).div( volume.volumeSizeNode );
|
|
564
|
+
const snapped = floor( uvw.mul( levelSize ) ).add( 0.5 ).div( levelSize ).toConst();
|
|
565
|
+
|
|
566
|
+
If( this.debug.equal( 1 ), () => {
|
|
567
|
+
|
|
568
|
+
let radiance;
|
|
569
|
+
|
|
570
|
+
if ( directional === false ) {
|
|
571
|
+
|
|
572
|
+
radiance = volume.radianceNode.sample( snapped ).level( level ).toConst();
|
|
573
|
+
|
|
574
|
+
} else {
|
|
575
|
+
|
|
576
|
+
radiance = vec4( 0 ).toVar();
|
|
577
|
+
|
|
578
|
+
If( level.lessThan( 1 ), () => {
|
|
579
|
+
|
|
580
|
+
radiance.assign( volume.radianceNode.sample( snapped ).level( float( 0 ) ) );
|
|
581
|
+
|
|
582
|
+
} ).Else( () => {
|
|
583
|
+
|
|
584
|
+
radiance.assign( sampleDirectional( volume, volume.directionalNode, snapped, level.sub( 1 ), direction ) );
|
|
585
|
+
|
|
586
|
+
} );
|
|
587
|
+
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
If( radiance.a.greaterThan( 0.01 ), () => {
|
|
591
|
+
|
|
592
|
+
color.assign( radiance.rgb.div( radiance.a ) );
|
|
593
|
+
Break();
|
|
594
|
+
|
|
595
|
+
} );
|
|
596
|
+
|
|
597
|
+
} ).Else( () => {
|
|
598
|
+
|
|
599
|
+
const opacity = volume.opacityNode.sample( snapped ).level( level ).toConst();
|
|
600
|
+
|
|
601
|
+
If( opacity.w.greaterThan( 0.01 ), () => {
|
|
602
|
+
|
|
603
|
+
color.assign( opacity.xyz );
|
|
604
|
+
Break();
|
|
605
|
+
|
|
606
|
+
} );
|
|
607
|
+
|
|
608
|
+
} );
|
|
609
|
+
|
|
610
|
+
t.addAssign( texel.mul( 0.25 ) );
|
|
611
|
+
|
|
612
|
+
} );
|
|
613
|
+
|
|
614
|
+
} );
|
|
615
|
+
|
|
616
|
+
aoField.assign( ao );
|
|
617
|
+
giField.assign( vec4( color, 1 ) );
|
|
618
|
+
|
|
619
|
+
return vec4( 0 );
|
|
620
|
+
|
|
621
|
+
} );
|
|
622
|
+
|
|
623
|
+
this._material.contextNode = context( this._sharedContext );
|
|
624
|
+
this._material.colorNode = gi();
|
|
625
|
+
this._material.outputNode = outputNode;
|
|
626
|
+
this._material.needsUpdate = true;
|
|
627
|
+
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Frees internal resources. This method should be called
|
|
632
|
+
* when the effect is no longer required.
|
|
633
|
+
*/
|
|
634
|
+
dispose() {
|
|
635
|
+
|
|
636
|
+
super.dispose();
|
|
637
|
+
|
|
638
|
+
this._renderTarget.dispose();
|
|
639
|
+
this._material.dispose();
|
|
640
|
+
this.volume.dispose();
|
|
641
|
+
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
export default VXGINode;
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* TSL function for creating a voxel GI effect.
|
|
650
|
+
*
|
|
651
|
+
* @tsl
|
|
652
|
+
* @function
|
|
653
|
+
* @param {TextureNode} depthNode - A texture node that represents the scene's depth.
|
|
654
|
+
* @param {?TextureNode} normalNode - A texture node that represents the scene's view space normals.
|
|
655
|
+
* @param {Scene} scene - The scene to voxelize.
|
|
656
|
+
* @param {Camera} camera - The camera the scene is rendered with.
|
|
657
|
+
* @param {number} [resolution=128] - Number of voxels along the longest axis of the volume. Should not exceed `256`, higher values exceed the maximum storage buffer size of the voxelizer.
|
|
658
|
+
* @returns {VXGINode}
|
|
659
|
+
*/
|
|
660
|
+
export const vxgi = ( depthNode, normalNode, scene, camera, resolution ) => new VXGINode( depthNode, normalNode, scene, camera, resolution );
|