@gnsx/three 0.185.15 → 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 +1303 -728
- 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/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,841 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Box3,
|
|
3
|
+
CubeCamera,
|
|
4
|
+
Data3DTexture,
|
|
5
|
+
FloatType,
|
|
6
|
+
HalfFloatType,
|
|
7
|
+
LinearFilter,
|
|
8
|
+
MathUtils,
|
|
9
|
+
Mesh,
|
|
10
|
+
NearestFilter,
|
|
11
|
+
Object3D,
|
|
12
|
+
OrthographicCamera,
|
|
13
|
+
PlaneGeometry,
|
|
14
|
+
RGBAFormat,
|
|
15
|
+
Scene,
|
|
16
|
+
ShaderMaterial,
|
|
17
|
+
Vector3,
|
|
18
|
+
WebGL3DRenderTarget,
|
|
19
|
+
WebGLCubeRenderTarget,
|
|
20
|
+
WebGLRenderTarget
|
|
21
|
+
} from '@gnsx/three';
|
|
22
|
+
|
|
23
|
+
import { replaceSunLights, restoreSunLights } from './LightProbeGridUtils.js';
|
|
24
|
+
|
|
25
|
+
// Shared fullscreen-quad scene / camera
|
|
26
|
+
let _scene = null;
|
|
27
|
+
let _camera = null;
|
|
28
|
+
let _mesh = null;
|
|
29
|
+
|
|
30
|
+
// SH projection material (depends on cubemapSize)
|
|
31
|
+
let _shMaterial = null;
|
|
32
|
+
let _lastCubemapSize = 0;
|
|
33
|
+
|
|
34
|
+
// Repack materials (one per output sub-volume / texture index)
|
|
35
|
+
let _repackMaterials = null;
|
|
36
|
+
|
|
37
|
+
// Cached bake resources
|
|
38
|
+
let _cubeRenderTarget = null;
|
|
39
|
+
let _cubeCamera = null;
|
|
40
|
+
let _cachedCubemapSize = 0;
|
|
41
|
+
let _cachedNear = 0;
|
|
42
|
+
let _cachedFar = 0;
|
|
43
|
+
|
|
44
|
+
// Cached batch render target
|
|
45
|
+
let _batchTarget = null;
|
|
46
|
+
let _batchTargetProbes = 0;
|
|
47
|
+
|
|
48
|
+
// Reusable temp objects
|
|
49
|
+
const _position = /*@__PURE__*/ new Vector3();
|
|
50
|
+
const _size = /*@__PURE__*/ new Vector3();
|
|
51
|
+
const _copyRegion = /*@__PURE__*/ new Box3();
|
|
52
|
+
|
|
53
|
+
// Direct-light captures use a black atlas without changing the light layout.
|
|
54
|
+
let _emptyAtlas = null;
|
|
55
|
+
|
|
56
|
+
// Number of padding texels added at each boundary of every sub-volume in the atlas.
|
|
57
|
+
const ATLAS_PADDING = 1;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A 3D grid of L2 Spherical Harmonic irradiance probes that provides
|
|
61
|
+
* position-dependent diffuse global illumination.
|
|
62
|
+
*
|
|
63
|
+
* Note that this class can only be used with {@link WebGLRenderer}.
|
|
64
|
+
* For {@link WebGPURenderer}, use {@link LightProbeGrid}.
|
|
65
|
+
*
|
|
66
|
+
* All seven packed SH sub-volumes are stored in a **single** RGBA
|
|
67
|
+
* `WebGL3DRenderTarget` using a texture-atlas layout along the Z axis.
|
|
68
|
+
* Each sub-volume occupies `( nz + 2 )` atlas slices: one padding slice at
|
|
69
|
+
* each end (a copy of the nearest edge data slice) to prevent color bleeding
|
|
70
|
+
* when the hardware trilinear filter reads across a sub-volume boundary.
|
|
71
|
+
*
|
|
72
|
+
* Atlas layout (nz = resolution.z, PADDING = 1):
|
|
73
|
+
* ```
|
|
74
|
+
* slice 0 : padding (copy of sub-volume 0, data slice 0)
|
|
75
|
+
* slices 1 … nz : sub-volume 0 data
|
|
76
|
+
* slice nz + 1 : padding (copy of sub-volume 0, data slice nz-1)
|
|
77
|
+
* slice nz + 2 : padding (copy of sub-volume 1, data slice 0)
|
|
78
|
+
* slices nz+3 … 2*nz+2 : sub-volume 1 data
|
|
79
|
+
* …
|
|
80
|
+
* ```
|
|
81
|
+
* Total atlas depth = `7 * ( nz + 2 )`.
|
|
82
|
+
*
|
|
83
|
+
* Baking is fully GPU-resident: cubemap rendering, SH projection, and
|
|
84
|
+
* texture packing all happen on the GPU with zero CPU readback.
|
|
85
|
+
*
|
|
86
|
+
* @three_import import { LightProbeGridWebGL } from 'three/addons/lighting/LightProbeGridWebGL.js';
|
|
87
|
+
*/
|
|
88
|
+
class LightProbeGridWebGL extends Object3D {
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Constructs a new irradiance probe grid.
|
|
92
|
+
*
|
|
93
|
+
* The volume is centered at the object's position.
|
|
94
|
+
*
|
|
95
|
+
* @param {number} [width=1] - Full width of the volume along X.
|
|
96
|
+
* @param {number} [height=1] - Full height of the volume along Y.
|
|
97
|
+
* @param {number} [depth=1] - Full depth of the volume along Z.
|
|
98
|
+
* @param {number} [widthProbes] - Number of probes along X. Defaults to `Math.max( 2, Math.round( width ) + 1 )`.
|
|
99
|
+
* @param {number} [heightProbes] - Number of probes along Y. Defaults to `Math.max( 2, Math.round( height ) + 1 )`.
|
|
100
|
+
* @param {number} [depthProbes] - Number of probes along Z. Defaults to `Math.max( 2, Math.round( depth ) + 1 )`.
|
|
101
|
+
*/
|
|
102
|
+
constructor( width = 1, height = 1, depth = 1, widthProbes, heightProbes, depthProbes ) {
|
|
103
|
+
|
|
104
|
+
super();
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* This flag can be used for type testing.
|
|
108
|
+
*
|
|
109
|
+
* @type {boolean}
|
|
110
|
+
* @readonly
|
|
111
|
+
* @default true
|
|
112
|
+
*/
|
|
113
|
+
this.isLightProbeGrid = true;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The full width of the volume along X.
|
|
117
|
+
*
|
|
118
|
+
* @type {number}
|
|
119
|
+
*/
|
|
120
|
+
this.width = width;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The full height of the volume along Y.
|
|
124
|
+
*
|
|
125
|
+
* @type {number}
|
|
126
|
+
*/
|
|
127
|
+
this.height = height;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The full depth of the volume along Z.
|
|
131
|
+
*
|
|
132
|
+
* @type {number}
|
|
133
|
+
*/
|
|
134
|
+
this.depth = depth;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The number of probes along each axis.
|
|
138
|
+
*
|
|
139
|
+
* @type {Vector3}
|
|
140
|
+
*/
|
|
141
|
+
this.resolution = new Vector3(
|
|
142
|
+
widthProbes !== undefined ? widthProbes : Math.max( 2, Math.round( width ) + 1 ),
|
|
143
|
+
heightProbes !== undefined ? heightProbes : Math.max( 2, Math.round( height ) + 1 ),
|
|
144
|
+
depthProbes !== undefined ? depthProbes : Math.max( 2, Math.round( depth ) + 1 )
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The world-space bounding box for the grid. Updated automatically
|
|
149
|
+
* by {@link LightProbeGridWebGL#bake}.
|
|
150
|
+
*
|
|
151
|
+
* @type {Box3}
|
|
152
|
+
*/
|
|
153
|
+
this.boundingBox = new Box3();
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The single RGBA atlas 3D texture storing all seven packed SH sub-volumes.
|
|
157
|
+
*
|
|
158
|
+
* @type {?Data3DTexture}
|
|
159
|
+
* @default null
|
|
160
|
+
*/
|
|
161
|
+
this.texture = null;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Internal render target for GPU-resident baking.
|
|
165
|
+
*
|
|
166
|
+
* @private
|
|
167
|
+
* @type {?WebGL3DRenderTarget}
|
|
168
|
+
* @default null
|
|
169
|
+
*/
|
|
170
|
+
this._renderTarget = null;
|
|
171
|
+
|
|
172
|
+
// Indirect captures read a snapshot while the live atlas is updated in place.
|
|
173
|
+
this._bounceTarget = null;
|
|
174
|
+
this._bouncePass = - 1;
|
|
175
|
+
|
|
176
|
+
this.updateBoundingBox();
|
|
177
|
+
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Returns the world-space position of the probe at grid indices (ix, iy, iz).
|
|
182
|
+
*
|
|
183
|
+
* @param {number} ix - X index.
|
|
184
|
+
* @param {number} iy - Y index.
|
|
185
|
+
* @param {number} iz - Z index.
|
|
186
|
+
* @param {Vector3} target - The target vector.
|
|
187
|
+
* @return {Vector3} The world-space position.
|
|
188
|
+
*/
|
|
189
|
+
getProbePosition( ix, iy, iz, target ) {
|
|
190
|
+
|
|
191
|
+
// WITH_GENESYS
|
|
192
|
+
const pos = _position;
|
|
193
|
+
this.getWorldPosition( pos );
|
|
194
|
+
// !WITH_GENESYS
|
|
195
|
+
// const pos = this.position;
|
|
196
|
+
const res = this.resolution;
|
|
197
|
+
const w = this.width, h = this.height, d = this.depth;
|
|
198
|
+
|
|
199
|
+
target.set(
|
|
200
|
+
res.x > 1 ? pos.x - w / 2 + ix * w / ( res.x - 1 ) : pos.x,
|
|
201
|
+
res.y > 1 ? pos.y - h / 2 + iy * h / ( res.y - 1 ) : pos.y,
|
|
202
|
+
res.z > 1 ? pos.z - d / 2 + iz * d / ( res.z - 1 ) : pos.z
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
return target;
|
|
206
|
+
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Updates the world-space bounding box from the current position and size.
|
|
211
|
+
*/
|
|
212
|
+
updateBoundingBox() {
|
|
213
|
+
|
|
214
|
+
// WITH_GENESYS
|
|
215
|
+
this.getWorldPosition( _position );
|
|
216
|
+
_size.set( this.width, this.height, this.depth );
|
|
217
|
+
this.boundingBox.setFromCenterAndSize( _position, _size );
|
|
218
|
+
// !WITH_GENESYS
|
|
219
|
+
/*
|
|
220
|
+
_size.set( this.width, this.height, this.depth );
|
|
221
|
+
this.boundingBox.setFromCenterAndSize( this.position, _size );
|
|
222
|
+
*/
|
|
223
|
+
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Bakes probes by rendering cubemaps at each probe position and
|
|
228
|
+
* projecting to L2 SH. Optionally iterates additional passes to capture
|
|
229
|
+
* indirect bounces: each extra pass samples the previous pass's data as
|
|
230
|
+
* indirect light, so a grid added to the scene before baking accumulates
|
|
231
|
+
* one bounce per extra pass.
|
|
232
|
+
*
|
|
233
|
+
* Use `start` and `count` to bake a range and publish its cells immediately.
|
|
234
|
+
* Indices advance along X, then Z, then Y, filling horizontal layers from bottom
|
|
235
|
+
* to top. For incremental indirect bounces, finish the whole grid for `pass: 0`,
|
|
236
|
+
* then repeat with `pass: 1`, etc. Start each pass at index 0 to snapshot the
|
|
237
|
+
* previous pass before updating its cells.
|
|
238
|
+
*
|
|
239
|
+
* Shadow-casting instances of `SunLight` are temporarily replaced with
|
|
240
|
+
* equivalent directional lights, since their view-fitted shadow cascades
|
|
241
|
+
* cannot be frozen across probe renders.
|
|
242
|
+
*
|
|
243
|
+
* @param {WebGLRenderer} renderer - The renderer.
|
|
244
|
+
* @param {Scene} scene - The scene to render.
|
|
245
|
+
* @param {Object} [options] - Bake options.
|
|
246
|
+
* @param {number} [options.cubemapSize=8] - Resolution of each cubemap face.
|
|
247
|
+
* @param {number} [options.near=0.1] - Near plane for the cube camera.
|
|
248
|
+
* @param {number} [options.far=100] - Far plane for the cube camera.
|
|
249
|
+
* @param {number} [options.bounces=0] - Additional bounce passes. Only available when baking the whole grid.
|
|
250
|
+
* @param {number} [options.start=0] - Index of the first probe to bake.
|
|
251
|
+
* @param {number} [options.count] - Number of probes to bake. Defaults to the remaining probes.
|
|
252
|
+
* @param {number} [options.pass=0] - Starting pass. Zero captures direct light; later passes sample the previous pass. Ranged calls require `bounces: 0`.
|
|
253
|
+
*/
|
|
254
|
+
bake( renderer, scene, options = {} ) {
|
|
255
|
+
|
|
256
|
+
const res = this.resolution;
|
|
257
|
+
const totalProbes = res.x * res.y * res.z;
|
|
258
|
+
const {
|
|
259
|
+
bounces = 0,
|
|
260
|
+
start = 0,
|
|
261
|
+
count = totalProbes - start,
|
|
262
|
+
pass: firstPass = 0
|
|
263
|
+
} = options;
|
|
264
|
+
const end = start + count;
|
|
265
|
+
|
|
266
|
+
if ( ! Number.isInteger( start ) || ! Number.isInteger( count ) || start < 0 || count < 0 || end > totalProbes ) {
|
|
267
|
+
|
|
268
|
+
throw new RangeError( 'THREE.LightProbeGridWebGL: Invalid probe range.' );
|
|
269
|
+
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if ( ! Number.isInteger( firstPass ) || firstPass < 0 || ! Number.isInteger( bounces ) || bounces < 0 ) {
|
|
273
|
+
|
|
274
|
+
throw new RangeError( 'THREE.LightProbeGridWebGL: Pass and bounce counts must be non-negative integers.' );
|
|
275
|
+
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if ( bounces > 0 && count !== totalProbes ) {
|
|
279
|
+
|
|
280
|
+
throw new RangeError( 'THREE.LightProbeGridWebGL: For ranged baking, use pass instead of bounces.' );
|
|
281
|
+
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if ( count === 0 ) return;
|
|
285
|
+
|
|
286
|
+
if ( firstPass > 0 && start > 0 && this._bouncePass !== firstPass ) {
|
|
287
|
+
|
|
288
|
+
throw new Error( 'THREE.LightProbeGridWebGL: Start each indirect pass at probe 0.' );
|
|
289
|
+
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
this._ensureTextures();
|
|
293
|
+
this.updateBoundingBox();
|
|
294
|
+
_ensureBakeResources( options );
|
|
295
|
+
_ensureBatchTarget( totalProbes );
|
|
296
|
+
_ensureRepackResources();
|
|
297
|
+
|
|
298
|
+
const currentRenderTarget = renderer.getRenderTarget();
|
|
299
|
+
const currentActiveCubeFace = renderer.getActiveCubeFace();
|
|
300
|
+
const currentActiveMipmapLevel = renderer.getActiveMipmapLevel();
|
|
301
|
+
const currentAutoClear = renderer.autoClear;
|
|
302
|
+
const currentXrEnabled = renderer.xr.enabled;
|
|
303
|
+
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
|
|
304
|
+
const currentMatrixWorldAutoUpdate = scene.matrixWorldAutoUpdate;
|
|
305
|
+
const currentVisible = this.visible;
|
|
306
|
+
const currentTexture = this.texture;
|
|
307
|
+
const renderTarget = this._renderTarget;
|
|
308
|
+
const currentViewport = renderTarget.viewport.clone();
|
|
309
|
+
let replacedSunLights = null;
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
|
|
313
|
+
this.visible = true;
|
|
314
|
+
|
|
315
|
+
// Scene is static during the bake: update once, disable auto-update.
|
|
316
|
+
|
|
317
|
+
if ( currentMatrixWorldAutoUpdate === true ) {
|
|
318
|
+
|
|
319
|
+
scene.updateMatrixWorld( true );
|
|
320
|
+
scene.matrixWorldAutoUpdate = false;
|
|
321
|
+
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
replacedSunLights = replaceSunLights( scene );
|
|
325
|
+
|
|
326
|
+
// Render shadow maps once, not once per cube face.
|
|
327
|
+
|
|
328
|
+
renderer.shadowMap.autoUpdate = false;
|
|
329
|
+
renderer.shadowMap.needsUpdate = true;
|
|
330
|
+
|
|
331
|
+
for ( let pass = firstPass; pass <= firstPass + bounces; pass ++ ) {
|
|
332
|
+
|
|
333
|
+
this._updateBakeTexture( renderer, pass, start );
|
|
334
|
+
this._captureProbes( renderer, scene, start, end );
|
|
335
|
+
this._repackProbes( renderer, start, end );
|
|
336
|
+
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
} finally {
|
|
340
|
+
|
|
341
|
+
renderTarget.viewport.copy( currentViewport );
|
|
342
|
+
renderer.setRenderTarget( currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel );
|
|
343
|
+
renderer.autoClear = currentAutoClear;
|
|
344
|
+
renderer.xr.enabled = currentXrEnabled;
|
|
345
|
+
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
|
|
346
|
+
|
|
347
|
+
if ( replacedSunLights !== null ) restoreSunLights( scene, replacedSunLights );
|
|
348
|
+
|
|
349
|
+
scene.matrixWorldAutoUpdate = currentMatrixWorldAutoUpdate;
|
|
350
|
+
this.visible = currentVisible;
|
|
351
|
+
this.texture = currentTexture;
|
|
352
|
+
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Selects the atlas to sample during capture, snapshotting each indirect pass
|
|
359
|
+
* before its first range overwrites the live atlas.
|
|
360
|
+
*
|
|
361
|
+
* @private
|
|
362
|
+
* @param {WebGLRenderer} renderer - The renderer.
|
|
363
|
+
* @param {number} pass - The bounce pass.
|
|
364
|
+
* @param {number} start - The first probe index.
|
|
365
|
+
*/
|
|
366
|
+
_updateBakeTexture( renderer, pass, start ) {
|
|
367
|
+
|
|
368
|
+
if ( pass === 0 ) {
|
|
369
|
+
|
|
370
|
+
this.texture = _emptyAtlas;
|
|
371
|
+
if ( start === 0 ) this._bouncePass = - 1;
|
|
372
|
+
return;
|
|
373
|
+
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if ( start === 0 ) {
|
|
377
|
+
|
|
378
|
+
const renderTarget = this._renderTarget;
|
|
379
|
+
|
|
380
|
+
if ( this._bounceTarget === null ) this._bounceTarget = renderTarget.clone();
|
|
381
|
+
|
|
382
|
+
renderer.initRenderTarget( renderTarget );
|
|
383
|
+
renderer.initRenderTarget( this._bounceTarget );
|
|
384
|
+
_copyRegion.min.set( 0, 0, 0 );
|
|
385
|
+
_copyRegion.max.set( renderTarget.width, renderTarget.height, renderTarget.depth );
|
|
386
|
+
renderer.copyTextureToTexture( renderTarget.texture, this._bounceTarget.texture, _copyRegion );
|
|
387
|
+
this._bouncePass = pass;
|
|
388
|
+
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
this.texture = this._bounceTarget.texture;
|
|
392
|
+
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Captures cubemaps and projects their SH coefficients into the batch target.
|
|
397
|
+
*
|
|
398
|
+
* @private
|
|
399
|
+
* @param {WebGLRenderer} renderer - The renderer.
|
|
400
|
+
* @param {Scene} scene - The scene to capture.
|
|
401
|
+
* @param {number} start - The first probe index.
|
|
402
|
+
* @param {number} end - The exclusive end probe index.
|
|
403
|
+
*/
|
|
404
|
+
_captureProbes( renderer, scene, start, end ) {
|
|
405
|
+
|
|
406
|
+
const { x: nx, y: ny, z: nz } = this.resolution;
|
|
407
|
+
const probesPerLayer = nx * nz;
|
|
408
|
+
|
|
409
|
+
_mesh.material = _shMaterial;
|
|
410
|
+
_shMaterial.uniforms.envMap.value = _cubeRenderTarget.texture;
|
|
411
|
+
|
|
412
|
+
for ( let probeIndex = start; probeIndex < end; probeIndex ++ ) {
|
|
413
|
+
|
|
414
|
+
const ix = probeIndex % nx;
|
|
415
|
+
const iy = Math.floor( probeIndex / probesPerLayer );
|
|
416
|
+
const iz = Math.floor( probeIndex / nx ) % nz;
|
|
417
|
+
|
|
418
|
+
this.getProbePosition( ix, iy, iz, _position );
|
|
419
|
+
_cubeCamera.position.copy( _position );
|
|
420
|
+
|
|
421
|
+
// The cube faces must be cleared per face.
|
|
422
|
+
renderer.autoClear = true;
|
|
423
|
+
_cubeCamera.update( renderer, scene );
|
|
424
|
+
|
|
425
|
+
// Keep batch rows in texture order (X, Y, Z).
|
|
426
|
+
const batchRow = ix + iy * nx + iz * nx * ny;
|
|
427
|
+
|
|
428
|
+
renderer.autoClear = false;
|
|
429
|
+
_batchTarget.viewport.set( 0, batchRow, 9, 1 );
|
|
430
|
+
renderer.setRenderTarget( _batchTarget );
|
|
431
|
+
renderer.render( _scene, _camera );
|
|
432
|
+
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Packs a probe range into the live atlas, including its boundary padding.
|
|
439
|
+
*
|
|
440
|
+
* @private
|
|
441
|
+
* @param {WebGLRenderer} renderer - The renderer.
|
|
442
|
+
* @param {number} start - The first probe index.
|
|
443
|
+
* @param {number} end - The exclusive end probe index.
|
|
444
|
+
*/
|
|
445
|
+
_repackProbes( renderer, start, end ) {
|
|
446
|
+
|
|
447
|
+
const { x: nx, y: ny, z: nz } = this.resolution;
|
|
448
|
+
const probesPerLayer = nx * nz;
|
|
449
|
+
const startY = Math.floor( start / probesPerLayer );
|
|
450
|
+
const endY = Math.floor( end / probesPerLayer );
|
|
451
|
+
const paddedSlices = nz + 2 * ATLAS_PADDING;
|
|
452
|
+
const renderTarget = this._renderTarget;
|
|
453
|
+
|
|
454
|
+
for ( const material of _repackMaterials ) {
|
|
455
|
+
|
|
456
|
+
material.uniforms.batchTexture.value = _batchTarget.texture;
|
|
457
|
+
material.uniforms.resolution.value.copy( this.resolution );
|
|
458
|
+
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Map the horizontal bake range to contiguous rows in each Z slice.
|
|
462
|
+
for ( let iz = 0; iz < nz; iz ++ ) {
|
|
463
|
+
|
|
464
|
+
const sliceStart = startY * nx + MathUtils.clamp( start % probesPerLayer - iz * nx, 0, nx );
|
|
465
|
+
const sliceEnd = endY * nx + MathUtils.clamp( end % probesPerLayer - iz * nx, 0, nx );
|
|
466
|
+
|
|
467
|
+
for ( let probeIndex = sliceStart; probeIndex < sliceEnd; ) {
|
|
468
|
+
|
|
469
|
+
const ix = probeIndex % nx;
|
|
470
|
+
const iy = Math.floor( probeIndex / nx );
|
|
471
|
+
|
|
472
|
+
// Coalesce complete rows within a slice into one rectangle.
|
|
473
|
+
const width = Math.min( nx - ix, sliceEnd - probeIndex );
|
|
474
|
+
let height = 1;
|
|
475
|
+
|
|
476
|
+
if ( width === nx ) {
|
|
477
|
+
|
|
478
|
+
height = Math.min( ny - iy, Math.floor( ( sliceEnd - probeIndex ) / nx ) );
|
|
479
|
+
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
renderTarget.viewport.set( ix, iy, width, height );
|
|
483
|
+
|
|
484
|
+
for ( let t = 0; t < 7; t ++ ) {
|
|
485
|
+
|
|
486
|
+
_mesh.material = _repackMaterials[ t ];
|
|
487
|
+
_mesh.material.uniforms.sliceZ.value = iz;
|
|
488
|
+
const base = t * paddedSlices;
|
|
489
|
+
|
|
490
|
+
renderer.setRenderTarget( renderTarget, base + ATLAS_PADDING + iz );
|
|
491
|
+
renderer.render( _scene, _camera );
|
|
492
|
+
|
|
493
|
+
if ( iz === 0 ) {
|
|
494
|
+
|
|
495
|
+
renderer.setRenderTarget( renderTarget, base );
|
|
496
|
+
renderer.render( _scene, _camera );
|
|
497
|
+
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if ( iz === nz - 1 ) {
|
|
501
|
+
|
|
502
|
+
renderer.setRenderTarget( renderTarget, base + ATLAS_PADDING + nz );
|
|
503
|
+
renderer.render( _scene, _camera );
|
|
504
|
+
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
probeIndex += width * height;
|
|
510
|
+
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Ensures the atlas 3D render target exists with the correct dimensions.
|
|
519
|
+
*
|
|
520
|
+
* @private
|
|
521
|
+
*/
|
|
522
|
+
_ensureTextures() {
|
|
523
|
+
|
|
524
|
+
if ( this._renderTarget !== null ) return;
|
|
525
|
+
|
|
526
|
+
const res = this.resolution;
|
|
527
|
+
const nx = res.x, ny = res.y, nz = res.z;
|
|
528
|
+
|
|
529
|
+
// Atlas depth: 7 sub-volumes, each with ATLAS_PADDING slices at both ends
|
|
530
|
+
const atlasDepth = 7 * ( nz + 2 * ATLAS_PADDING );
|
|
531
|
+
|
|
532
|
+
const rt = new WebGL3DRenderTarget( nx, ny, atlasDepth, {
|
|
533
|
+
format: RGBAFormat,
|
|
534
|
+
type: FloatType,
|
|
535
|
+
minFilter: LinearFilter,
|
|
536
|
+
magFilter: LinearFilter,
|
|
537
|
+
generateMipmaps: false,
|
|
538
|
+
depthBuffer: false
|
|
539
|
+
} );
|
|
540
|
+
|
|
541
|
+
this._renderTarget = rt;
|
|
542
|
+
this.texture = rt.texture;
|
|
543
|
+
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Frees GPU resources.
|
|
548
|
+
*/
|
|
549
|
+
dispose() {
|
|
550
|
+
|
|
551
|
+
if ( this._bounceTarget !== null ) {
|
|
552
|
+
|
|
553
|
+
this._bounceTarget.dispose();
|
|
554
|
+
this._bounceTarget = null;
|
|
555
|
+
this._bouncePass = - 1;
|
|
556
|
+
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if ( this._renderTarget !== null ) {
|
|
560
|
+
|
|
561
|
+
this._renderTarget.dispose();
|
|
562
|
+
this._renderTarget = null;
|
|
563
|
+
this.texture = null;
|
|
564
|
+
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Internal: Ensure the shared fullscreen-quad scene exists
|
|
572
|
+
function _ensureScene() {
|
|
573
|
+
|
|
574
|
+
if ( _scene === null ) {
|
|
575
|
+
|
|
576
|
+
_camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
|
577
|
+
_mesh = new Mesh( new PlaneGeometry( 2, 2 ) );
|
|
578
|
+
_scene = new Scene();
|
|
579
|
+
_scene.add( _mesh );
|
|
580
|
+
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Internal: Ensure GPU resources for SH projection are created
|
|
586
|
+
function _ensureGPUResources( cubemapSize ) {
|
|
587
|
+
|
|
588
|
+
_ensureScene();
|
|
589
|
+
|
|
590
|
+
// Recreate material when cubemap size changes
|
|
591
|
+
if ( cubemapSize !== _lastCubemapSize ) {
|
|
592
|
+
|
|
593
|
+
if ( _shMaterial !== null ) _shMaterial.dispose();
|
|
594
|
+
|
|
595
|
+
_shMaterial = new ShaderMaterial( {
|
|
596
|
+
precision: 'highp',
|
|
597
|
+
defines: {
|
|
598
|
+
CUBEMAP_SIZE: cubemapSize
|
|
599
|
+
},
|
|
600
|
+
uniforms: {
|
|
601
|
+
envMap: { value: null }
|
|
602
|
+
},
|
|
603
|
+
vertexShader: /* glsl */`
|
|
604
|
+
void main() {
|
|
605
|
+
gl_Position = vec4( position.xy, 0.0, 1.0 );
|
|
606
|
+
}
|
|
607
|
+
`,
|
|
608
|
+
fragmentShader: /* glsl */`
|
|
609
|
+
#include <common>
|
|
610
|
+
|
|
611
|
+
uniform samplerCube envMap;
|
|
612
|
+
|
|
613
|
+
void main() {
|
|
614
|
+
|
|
615
|
+
int coefIndex = int( gl_FragCoord.x );
|
|
616
|
+
|
|
617
|
+
vec3 accum0 = vec3( 0.0 );
|
|
618
|
+
vec3 accum1 = vec3( 0.0 );
|
|
619
|
+
vec3 accum2 = vec3( 0.0 );
|
|
620
|
+
vec3 accum3 = vec3( 0.0 );
|
|
621
|
+
vec3 accum4 = vec3( 0.0 );
|
|
622
|
+
vec3 accum5 = vec3( 0.0 );
|
|
623
|
+
vec3 accum6 = vec3( 0.0 );
|
|
624
|
+
vec3 accum7 = vec3( 0.0 );
|
|
625
|
+
vec3 accum8 = vec3( 0.0 );
|
|
626
|
+
float totalWeight = 0.0;
|
|
627
|
+
float pixelSize = 2.0 / float( CUBEMAP_SIZE );
|
|
628
|
+
|
|
629
|
+
for ( int face = 0; face < 6; face ++ ) {
|
|
630
|
+
|
|
631
|
+
for ( int iy = 0; iy < CUBEMAP_SIZE; iy ++ ) {
|
|
632
|
+
|
|
633
|
+
for ( int ix = 0; ix < CUBEMAP_SIZE; ix ++ ) {
|
|
634
|
+
|
|
635
|
+
// WebGL cubemaps have a left-handed orientation (flip = -1)
|
|
636
|
+
float col = ( float( ix ) + 0.5 ) * pixelSize - 1.0;
|
|
637
|
+
float row = 1.0 - ( float( iy ) + 0.5 ) * pixelSize;
|
|
638
|
+
|
|
639
|
+
vec3 coord;
|
|
640
|
+
|
|
641
|
+
if ( face == 0 ) coord = vec3( 1.0, row, -col );
|
|
642
|
+
else if ( face == 1 ) coord = vec3( -1.0, row, col );
|
|
643
|
+
else if ( face == 2 ) coord = vec3( col, 1.0, -row );
|
|
644
|
+
else if ( face == 3 ) coord = vec3( col, -1.0, row );
|
|
645
|
+
else if ( face == 4 ) coord = vec3( col, row, 1.0 );
|
|
646
|
+
else coord = vec3( -col, row, -1.0 );
|
|
647
|
+
|
|
648
|
+
float lengthSq = dot( coord, coord );
|
|
649
|
+
float weight = 4.0 / ( sqrt( lengthSq ) * lengthSq );
|
|
650
|
+
totalWeight += weight;
|
|
651
|
+
|
|
652
|
+
vec3 dir = normalize( coord );
|
|
653
|
+
vec3 cw = textureCube( envMap, coord ).rgb * weight;
|
|
654
|
+
|
|
655
|
+
// band 0
|
|
656
|
+
accum0 += cw * 0.282095;
|
|
657
|
+
|
|
658
|
+
// band 1
|
|
659
|
+
accum1 += cw * ( 0.488603 * dir.y );
|
|
660
|
+
accum2 += cw * ( 0.488603 * dir.z );
|
|
661
|
+
accum3 += cw * ( 0.488603 * dir.x );
|
|
662
|
+
|
|
663
|
+
// band 2
|
|
664
|
+
accum4 += cw * ( 1.092548 * ( dir.x * dir.y ) );
|
|
665
|
+
accum5 += cw * ( 1.092548 * ( dir.y * dir.z ) );
|
|
666
|
+
accum6 += cw * ( 0.315392 * ( 3.0 * dir.z * dir.z - 1.0 ) );
|
|
667
|
+
accum7 += cw * ( 1.092548 * ( dir.x * dir.z ) );
|
|
668
|
+
accum8 += cw * ( 0.546274 * ( dir.x * dir.x - dir.y * dir.y ) );
|
|
669
|
+
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
float norm = 4.0 * PI / totalWeight;
|
|
677
|
+
|
|
678
|
+
vec3 accum;
|
|
679
|
+
if ( coefIndex == 0 ) accum = accum0;
|
|
680
|
+
else if ( coefIndex == 1 ) accum = accum1;
|
|
681
|
+
else if ( coefIndex == 2 ) accum = accum2;
|
|
682
|
+
else if ( coefIndex == 3 ) accum = accum3;
|
|
683
|
+
else if ( coefIndex == 4 ) accum = accum4;
|
|
684
|
+
else if ( coefIndex == 5 ) accum = accum5;
|
|
685
|
+
else if ( coefIndex == 6 ) accum = accum6;
|
|
686
|
+
else if ( coefIndex == 7 ) accum = accum7;
|
|
687
|
+
else accum = accum8;
|
|
688
|
+
|
|
689
|
+
gl_FragColor = vec4( accum * norm, 1.0 );
|
|
690
|
+
|
|
691
|
+
}
|
|
692
|
+
`
|
|
693
|
+
} );
|
|
694
|
+
|
|
695
|
+
_lastCubemapSize = cubemapSize;
|
|
696
|
+
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Internal: Ensure GPU resources for repacking SH into the atlas 3D texture
|
|
702
|
+
function _ensureRepackResources() {
|
|
703
|
+
|
|
704
|
+
if ( _repackMaterials !== null ) return;
|
|
705
|
+
|
|
706
|
+
_ensureScene();
|
|
707
|
+
|
|
708
|
+
// Create 7 materials, one per output texture packing
|
|
709
|
+
// Texture 0: (c0.r, c0.g, c0.b, c1.r)
|
|
710
|
+
// Texture 1: (c1.g, c1.b, c2.r, c2.g)
|
|
711
|
+
// Texture 2: (c2.b, c3.r, c3.g, c3.b)
|
|
712
|
+
// Texture 3: (c4.r, c4.g, c4.b, c5.r)
|
|
713
|
+
// Texture 4: (c5.g, c5.b, c6.r, c6.g)
|
|
714
|
+
// Texture 5: (c6.b, c7.r, c7.g, c7.b)
|
|
715
|
+
// Texture 6: (c8.r, c8.g, c8.b, 0.0)
|
|
716
|
+
|
|
717
|
+
const repackVertexShader = /* glsl */`
|
|
718
|
+
void main() {
|
|
719
|
+
gl_Position = vec4( position.xy, 0.0, 1.0 );
|
|
720
|
+
}
|
|
721
|
+
`;
|
|
722
|
+
|
|
723
|
+
_repackMaterials = [];
|
|
724
|
+
|
|
725
|
+
for ( let t = 0; t < 7; t ++ ) {
|
|
726
|
+
|
|
727
|
+
_repackMaterials[ t ] = new ShaderMaterial( {
|
|
728
|
+
precision: 'highp',
|
|
729
|
+
defines: {
|
|
730
|
+
TEXTURE_INDEX: t
|
|
731
|
+
},
|
|
732
|
+
uniforms: {
|
|
733
|
+
batchTexture: { value: null },
|
|
734
|
+
resolution: { value: new Vector3() },
|
|
735
|
+
sliceZ: { value: 0 }
|
|
736
|
+
},
|
|
737
|
+
vertexShader: repackVertexShader,
|
|
738
|
+
fragmentShader: /* glsl */`
|
|
739
|
+
uniform sampler2D batchTexture;
|
|
740
|
+
uniform vec3 resolution;
|
|
741
|
+
uniform int sliceZ;
|
|
742
|
+
|
|
743
|
+
void main() {
|
|
744
|
+
|
|
745
|
+
int ix = int( gl_FragCoord.x );
|
|
746
|
+
int iy = int( gl_FragCoord.y );
|
|
747
|
+
int iz = sliceZ;
|
|
748
|
+
|
|
749
|
+
int probeIndex = ix + iy * int( resolution.x ) + iz * int( resolution.x ) * int( resolution.y );
|
|
750
|
+
|
|
751
|
+
// Read 9 SH coefficients from the batch texture row
|
|
752
|
+
vec4 c0 = texelFetch( batchTexture, ivec2( 0, probeIndex ), 0 );
|
|
753
|
+
vec4 c1 = texelFetch( batchTexture, ivec2( 1, probeIndex ), 0 );
|
|
754
|
+
vec4 c2 = texelFetch( batchTexture, ivec2( 2, probeIndex ), 0 );
|
|
755
|
+
vec4 c3 = texelFetch( batchTexture, ivec2( 3, probeIndex ), 0 );
|
|
756
|
+
vec4 c4 = texelFetch( batchTexture, ivec2( 4, probeIndex ), 0 );
|
|
757
|
+
vec4 c5 = texelFetch( batchTexture, ivec2( 5, probeIndex ), 0 );
|
|
758
|
+
vec4 c6 = texelFetch( batchTexture, ivec2( 6, probeIndex ), 0 );
|
|
759
|
+
vec4 c7 = texelFetch( batchTexture, ivec2( 7, probeIndex ), 0 );
|
|
760
|
+
vec4 c8 = texelFetch( batchTexture, ivec2( 8, probeIndex ), 0 );
|
|
761
|
+
|
|
762
|
+
// Pack into the output format for this texture index
|
|
763
|
+
#if TEXTURE_INDEX == 0
|
|
764
|
+
gl_FragColor = vec4( c0.rgb, c1.r );
|
|
765
|
+
#elif TEXTURE_INDEX == 1
|
|
766
|
+
gl_FragColor = vec4( c1.gb, c2.rg );
|
|
767
|
+
#elif TEXTURE_INDEX == 2
|
|
768
|
+
gl_FragColor = vec4( c2.b, c3.rgb );
|
|
769
|
+
#elif TEXTURE_INDEX == 3
|
|
770
|
+
gl_FragColor = vec4( c4.rgb, c5.r );
|
|
771
|
+
#elif TEXTURE_INDEX == 4
|
|
772
|
+
gl_FragColor = vec4( c5.gb, c6.rg );
|
|
773
|
+
#elif TEXTURE_INDEX == 5
|
|
774
|
+
gl_FragColor = vec4( c6.b, c7.rgb );
|
|
775
|
+
#else
|
|
776
|
+
gl_FragColor = vec4( c8.rgb, 0.0 );
|
|
777
|
+
#endif
|
|
778
|
+
|
|
779
|
+
}
|
|
780
|
+
`
|
|
781
|
+
} );
|
|
782
|
+
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// Internal: Ensure cube render target and camera exist with the right parameters
|
|
788
|
+
function _ensureBakeResources( options ) {
|
|
789
|
+
|
|
790
|
+
if ( _emptyAtlas === null ) {
|
|
791
|
+
|
|
792
|
+
_emptyAtlas = new Data3DTexture( new Uint16Array( 4 ), 1, 1, 1 );
|
|
793
|
+
_emptyAtlas.type = HalfFloatType;
|
|
794
|
+
_emptyAtlas.minFilter = LinearFilter;
|
|
795
|
+
_emptyAtlas.magFilter = LinearFilter;
|
|
796
|
+
_emptyAtlas.needsUpdate = true;
|
|
797
|
+
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
const {
|
|
801
|
+
cubemapSize = 8,
|
|
802
|
+
near = 0.1,
|
|
803
|
+
far = 100
|
|
804
|
+
} = options;
|
|
805
|
+
|
|
806
|
+
if ( _cubeRenderTarget === null || cubemapSize !== _cachedCubemapSize || near !== _cachedNear || far !== _cachedFar ) {
|
|
807
|
+
|
|
808
|
+
if ( _cubeRenderTarget !== null ) _cubeRenderTarget.dispose();
|
|
809
|
+
|
|
810
|
+
_cubeRenderTarget = new WebGLCubeRenderTarget( cubemapSize, { type: HalfFloatType } );
|
|
811
|
+
_cubeCamera = new CubeCamera( near, far, _cubeRenderTarget );
|
|
812
|
+
_cachedCubemapSize = cubemapSize;
|
|
813
|
+
_cachedNear = near;
|
|
814
|
+
_cachedFar = far;
|
|
815
|
+
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
_ensureGPUResources( cubemapSize );
|
|
819
|
+
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
function _ensureBatchTarget( totalProbes ) {
|
|
823
|
+
|
|
824
|
+
if ( _batchTarget === null || _batchTargetProbes !== totalProbes ) {
|
|
825
|
+
|
|
826
|
+
if ( _batchTarget !== null ) _batchTarget.dispose();
|
|
827
|
+
|
|
828
|
+
_batchTarget = new WebGLRenderTarget( 9, totalProbes, {
|
|
829
|
+
type: FloatType,
|
|
830
|
+
minFilter: NearestFilter,
|
|
831
|
+
magFilter: NearestFilter,
|
|
832
|
+
depthBuffer: false
|
|
833
|
+
} );
|
|
834
|
+
|
|
835
|
+
_batchTargetProbes = totalProbes;
|
|
836
|
+
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
export { LightProbeGridWebGL };
|