@plastic-software/three 0.183.4 → 0.184.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/three.cjs +775 -287
- package/build/three.core.js +372 -110
- package/build/three.core.min.js +1 -1
- package/build/three.module.js +428 -181
- package/build/three.module.min.js +1 -1
- package/build/three.tsl.js +7 -1
- package/build/three.tsl.min.js +1 -1
- package/build/three.webgpu.js +2979 -1281
- package/build/three.webgpu.min.js +1 -1
- package/build/three.webgpu.nodes.js +2942 -1281
- package/build/three.webgpu.nodes.min.js +1 -1
- package/examples/jsm/Addons.js +11 -0
- package/examples/jsm/animation/CCDIKSolver.js +5 -1
- package/examples/jsm/controls/ArcballControls.js +4 -1
- package/examples/jsm/controls/DragControls.js +2 -2
- package/examples/jsm/controls/FirstPersonControls.js +58 -54
- package/examples/jsm/controls/FlyControls.js +4 -0
- package/examples/jsm/controls/OrbitControls.js +2 -2
- package/examples/jsm/controls/TrackballControls.js +2 -2
- package/examples/jsm/controls/TransformControls.js +34 -2
- package/examples/jsm/csm/CSMShadowNode.js +6 -2
- package/examples/jsm/exporters/GLTFExporter.js +21 -5
- package/examples/jsm/geometries/TextGeometry.js +18 -0
- package/examples/jsm/helpers/LightProbeGridHelper.js +221 -0
- package/examples/jsm/inspector/Extension.js +13 -0
- package/examples/jsm/inspector/Inspector.js +169 -114
- package/examples/jsm/inspector/RendererInspector.js +2 -2
- package/examples/jsm/inspector/extensions/extensions.json +6 -0
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +916 -0
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +281 -0
- package/examples/jsm/inspector/tabs/Memory.js +128 -0
- package/examples/jsm/inspector/tabs/Parameters.js +34 -2
- package/examples/jsm/inspector/tabs/Performance.js +2 -2
- package/examples/jsm/inspector/tabs/Settings.js +264 -0
- package/examples/jsm/inspector/tabs/Timeline.js +1611 -0
- package/examples/jsm/inspector/tabs/Viewer.js +105 -3
- package/examples/jsm/inspector/ui/Graph.js +2 -2
- package/examples/jsm/inspector/ui/List.js +1 -1
- package/examples/jsm/inspector/ui/Profiler.js +273 -176
- package/examples/jsm/inspector/ui/Style.js +64 -10
- package/examples/jsm/inspector/ui/Tab.js +39 -7
- package/examples/jsm/inspector/ui/Values.js +39 -2
- package/examples/jsm/inspector/ui/utils.js +13 -0
- package/examples/jsm/interaction/InteractionManager.js +226 -0
- package/examples/jsm/libs/meshopt_decoder.module.js +8 -8
- package/examples/jsm/lighting/DynamicLighting.js +82 -0
- package/examples/jsm/lighting/LightProbeGrid.js +651 -0
- package/examples/jsm/lines/LineMaterial.js +1 -1
- package/examples/jsm/loaders/EXRLoader.js +682 -43
- package/examples/jsm/loaders/FBXLoader.js +233 -33
- package/examples/jsm/loaders/GLTFLoader.js +24 -7
- package/examples/jsm/loaders/HDRLoader.js +1 -1
- package/examples/jsm/loaders/KTX2Loader.js +8 -2
- package/examples/jsm/loaders/LDrawLoader.js +39 -47
- package/examples/jsm/loaders/SVGLoader.js +1 -1
- package/examples/jsm/loaders/VTKLoader.js +5 -1
- package/examples/jsm/loaders/collada/ColladaComposer.js +101 -7
- package/examples/jsm/loaders/collada/ColladaParser.js +19 -4
- package/examples/jsm/loaders/usd/USDAParser.js +6 -0
- package/examples/jsm/loaders/usd/USDCParser.js +26 -0
- package/examples/jsm/loaders/usd/USDComposer.js +656 -103
- package/examples/jsm/misc/GPUComputationRenderer.js +2 -0
- package/examples/jsm/misc/RollerCoaster.js +42 -4
- package/examples/jsm/modifiers/TessellateModifier.js +1 -1
- package/examples/jsm/objects/Reflector.js +73 -25
- package/examples/jsm/objects/Sky.js +14 -2
- package/examples/jsm/objects/SkyMesh.js +23 -6
- package/examples/jsm/renderers/Projector.js +18 -38
- package/examples/jsm/renderers/SVGRenderer.js +6 -25
- package/examples/jsm/transpiler/GLSLDecoder.js +2 -2
- package/examples/jsm/tsl/WebGLNodesHandler.js +605 -0
- package/examples/jsm/tsl/display/AfterImageNode.js +10 -0
- package/examples/jsm/tsl/display/AnamorphicNode.js +11 -0
- package/examples/jsm/tsl/display/BilateralBlurNode.js +10 -0
- package/examples/jsm/tsl/display/ChromaticAberrationNode.js +3 -36
- package/examples/jsm/tsl/display/FSR1Node.js +477 -0
- package/examples/jsm/tsl/display/GTAONode.js +2 -1
- package/examples/jsm/tsl/display/GaussianBlurNode.js +10 -0
- package/examples/jsm/tsl/display/GodraysNode.js +2 -11
- package/examples/jsm/tsl/display/OutlineNode.js +66 -16
- package/examples/jsm/tsl/display/SSGINode.js +0 -4
- package/examples/jsm/tsl/display/SharpenNode.js +283 -0
- package/examples/jsm/tsl/display/TAAUNode.js +835 -0
- package/examples/jsm/tsl/display/TRAANode.js +48 -7
- package/examples/jsm/tsl/lighting/DynamicLightsNode.js +300 -0
- package/examples/jsm/tsl/lighting/data/AmbientLightDataNode.js +61 -0
- package/examples/jsm/tsl/lighting/data/DirectionalLightDataNode.js +111 -0
- package/examples/jsm/tsl/lighting/data/HemisphereLightDataNode.js +99 -0
- package/examples/jsm/tsl/lighting/data/PointLightDataNode.js +134 -0
- package/examples/jsm/tsl/lighting/data/SpotLightDataNode.js +161 -0
- package/examples/jsm/tsl/math/Bayer.js +13 -2
- package/examples/jsm/utils/BufferGeometryUtils.js +2 -3
- package/examples/jsm/utils/ColorUtils.js +76 -0
- package/examples/jsm/utils/SkeletonUtils.js +14 -8
- package/examples/jsm/webxr/XRHandMeshModel.js +36 -10
- package/examples/jsm/webxr/XRHandModelFactory.js +2 -1
- package/package.json +4 -4
- package/src/Three.Core.js +1 -0
- package/src/Three.TSL.js +6 -0
- package/src/Three.WebGPU.Nodes.js +3 -0
- package/src/Three.WebGPU.js +6 -0
- package/src/animation/AnimationAction.js +11 -1
- package/src/audio/AudioContext.js +2 -2
- package/src/constants.js +1 -1
- package/src/core/BufferAttribute.js +13 -1
- package/src/core/Clock.js +1 -1
- package/src/core/Object3D.js +1 -5
- package/src/core/RenderTarget.js +1 -0
- package/src/extras/curves/CatmullRomCurve3.js +3 -2
- package/src/loaders/AudioLoader.js +11 -1
- package/src/loaders/DataTextureLoader.js +6 -4
- package/src/loaders/FileLoader.js +1 -2
- package/src/loaders/ImageBitmapLoader.js +4 -6
- package/src/loaders/MaterialLoader.js +1 -1
- package/src/loaders/ObjectLoader.js +25 -4
- package/src/loaders/nodes/NodeObjectLoader.js +18 -0
- package/src/materials/MeshToonMaterial.js +1 -1
- package/src/materials/nodes/Line2NodeMaterial.js +27 -0
- package/src/materials/nodes/NodeMaterial.js +0 -27
- package/src/materials/nodes/manager/NodeMaterialObserver.js +188 -89
- package/src/math/Line3.js +3 -0
- package/src/math/Matrix2.js +13 -9
- package/src/math/Matrix3.js +13 -9
- package/src/math/Matrix4.js +13 -9
- package/src/math/Plane.js +4 -3
- package/src/math/Triangle.js +1 -1
- package/src/math/Vector2.js +11 -7
- package/src/math/Vector3.js +12 -8
- package/src/math/Vector4.js +13 -9
- package/src/nodes/Nodes.js +0 -1
- package/src/nodes/TSL.js +1 -1
- package/src/nodes/accessors/BufferAttributeNode.js +9 -3
- package/src/nodes/accessors/CubeTextureNode.js +7 -1
- package/src/nodes/accessors/MaterialProperties.js +2 -5
- package/src/nodes/accessors/Object3DNode.js +1 -1
- package/src/nodes/accessors/ReferenceBaseNode.js +2 -2
- package/src/nodes/accessors/ReferenceNode.js +4 -4
- package/src/nodes/accessors/SceneProperties.js +2 -8
- package/src/nodes/accessors/StorageBufferNode.js +10 -4
- package/src/nodes/accessors/StorageTextureNode.js +4 -9
- package/src/nodes/accessors/TextureNode.js +10 -2
- package/src/nodes/accessors/UniformArrayNode.js +2 -2
- package/src/nodes/code/FunctionCallNode.js +1 -1
- package/src/nodes/code/FunctionNode.js +1 -1
- package/src/nodes/core/ArrayNode.js +1 -1
- package/src/nodes/core/AssignNode.js +1 -1
- package/src/nodes/core/AttributeNode.js +1 -1
- package/src/nodes/core/BypassNode.js +1 -1
- package/src/nodes/core/ContextNode.js +1 -1
- package/src/nodes/core/IndexNode.js +2 -1
- package/src/nodes/core/InputNode.js +1 -1
- package/src/nodes/core/InspectorNode.js +1 -1
- package/src/nodes/core/IsolateNode.js +1 -1
- package/src/nodes/core/Node.js +83 -12
- package/src/nodes/core/NodeBuilder.js +117 -16
- package/src/nodes/core/NodeUtils.js +1 -1
- package/src/nodes/core/OutputStructNode.js +1 -1
- package/src/nodes/core/ParameterNode.js +1 -1
- package/src/nodes/core/StackNode.js +1 -1
- package/src/nodes/core/StructNode.js +1 -1
- package/src/nodes/core/StructTypeNode.js +1 -1
- package/src/nodes/core/SubBuildNode.js +1 -1
- package/src/nodes/core/UniformGroupNode.js +36 -6
- package/src/nodes/core/VarNode.js +1 -1
- package/src/nodes/core/VaryingNode.js +1 -1
- package/src/nodes/display/NormalMapNode.js +2 -2
- package/src/nodes/display/PassNode.js +27 -7
- package/src/nodes/display/RenderOutputNode.js +4 -4
- package/src/nodes/display/ScreenNode.js +1 -1
- package/src/nodes/display/ViewportDepthTextureNode.js +11 -15
- package/src/nodes/display/ViewportTextureNode.js +18 -7
- package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +2 -2
- package/src/nodes/geometry/RangeNode.js +1 -1
- package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
- package/src/nodes/gpgpu/BarrierNode.js +9 -0
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
- package/src/nodes/gpgpu/ComputeNode.js +69 -44
- package/src/nodes/gpgpu/SubgroupFunctionNode.js +1 -1
- package/src/nodes/lighting/LightsNode.js +6 -27
- package/src/nodes/lighting/ShadowNode.js +24 -2
- package/src/nodes/math/BitcastNode.js +1 -1
- package/src/nodes/math/ConditionalNode.js +1 -1
- package/src/nodes/math/MathNode.js +73 -1
- package/src/nodes/math/OperatorNode.js +1 -1
- package/src/nodes/math/PackFloatNode.js +1 -1
- package/src/nodes/math/UnpackFloatNode.js +1 -1
- package/src/nodes/tsl/TSLBase.js +1 -1
- package/src/nodes/tsl/TSLCore.js +21 -3
- package/src/nodes/utils/ArrayElementNode.js +1 -1
- package/src/nodes/utils/ConvertNode.js +1 -1
- package/src/nodes/utils/DebugNode.js +1 -1
- package/src/nodes/utils/EventNode.js +30 -0
- package/src/nodes/utils/FlipNode.js +1 -1
- package/src/nodes/utils/FunctionOverloadingNode.js +1 -1
- package/src/nodes/utils/JoinNode.js +1 -1
- package/src/nodes/utils/MemberNode.js +1 -1
- package/src/nodes/utils/Remap.js +48 -0
- package/src/nodes/utils/RotateNode.js +1 -1
- package/src/nodes/utils/SetNode.js +1 -1
- package/src/nodes/utils/SplitNode.js +1 -1
- package/src/objects/BatchedMesh.js +17 -2
- package/src/objects/InstancedMesh.js +19 -3
- package/src/objects/SkinnedMesh.js +26 -9
- package/src/renderers/WebGLRenderer.js +147 -48
- package/src/renderers/common/Animation.js +3 -3
- package/src/renderers/common/Attributes.js +15 -1
- package/src/renderers/common/Backend.js +0 -8
- package/src/renderers/common/Background.js +2 -2
- package/src/renderers/common/BindGroup.js +1 -8
- package/src/renderers/common/Bindings.js +2 -2
- package/src/renderers/common/ComputePipeline.js +1 -1
- package/src/renderers/common/CubeRenderTarget.js +1 -1
- package/src/renderers/common/Info.js +333 -4
- package/src/renderers/common/InspectorBase.js +6 -1
- package/src/renderers/common/Pipelines.js +36 -3
- package/src/renderers/common/ReadbackBuffer.js +78 -0
- package/src/renderers/common/RenderBundle.js +3 -1
- package/src/renderers/common/RenderBundles.js +5 -2
- package/src/renderers/common/RenderObject.js +2 -2
- package/src/renderers/common/RenderObjects.js +3 -3
- package/src/renderers/common/RenderPipeline.js +35 -6
- package/src/renderers/common/Renderer.js +232 -53
- package/src/renderers/common/Textures.js +72 -3
- package/src/renderers/common/UniformsGroup.js +1 -1
- package/src/renderers/common/XRManager.js +34 -27
- package/src/renderers/common/extras/PMREMGenerator.js +23 -15
- package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
- package/src/renderers/common/nodes/NodeManager.js +230 -99
- package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +0 -1
- package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lightprobes_pars_fragment.glsl.js +80 -0
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +8 -0
- package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +2 -0
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +1 -3
- package/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js +7 -0
- package/src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl.js +0 -1
- package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +12 -2
- package/src/renderers/shaders/ShaderChunk.js +2 -0
- package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +1 -2
- package/src/renderers/shaders/ShaderLib.js +0 -1
- package/src/renderers/shaders/UniformsLib.js +7 -2
- package/src/renderers/shaders/UniformsUtils.js +27 -5
- package/src/renderers/webgl/WebGLAnimation.js +2 -1
- package/src/renderers/webgl/WebGLBackground.js +13 -13
- package/src/renderers/webgl/WebGLBufferRenderer.js +0 -32
- package/src/renderers/webgl/WebGLCapabilities.js +6 -0
- package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +0 -32
- package/src/renderers/webgl/WebGLMaterials.js +12 -13
- package/src/renderers/webgl/WebGLOutput.js +4 -1
- package/src/renderers/webgl/WebGLProgram.js +4 -0
- package/src/renderers/webgl/WebGLPrograms.js +21 -4
- package/src/renderers/webgl/WebGLRenderStates.js +13 -2
- package/src/renderers/webgl/WebGLState.js +43 -0
- package/src/renderers/webgl/WebGLTextures.js +129 -26
- package/src/renderers/webgl/WebGLUniformsGroups.js +19 -0
- package/src/renderers/webgl-fallback/WebGLBackend.js +106 -65
- package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +0 -41
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +29 -51
- package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +53 -19
- package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +25 -0
- package/src/renderers/webgl-fallback/utils/WebGLState.js +42 -1
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +63 -50
- package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +1 -1
- package/src/renderers/webgpu/WebGPUBackend.js +160 -146
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +55 -33
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +103 -17
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +1 -1
- package/src/renderers/webgpu/utils/WebGPUCapabilities.js +48 -0
- package/src/renderers/webgpu/utils/WebGPUConstants.js +8 -0
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +91 -17
- package/src/renderers/webgpu/utils/WebGPUUtils.js +18 -2
- package/src/renderers/webxr/WebXRController.js +12 -0
- package/src/textures/HTMLTexture.js +74 -0
- package/src/textures/Source.js +1 -1
- package/src/textures/Texture.js +13 -2
- package/src/utils.js +23 -1
- package/src/nodes/utils/RemapNode.js +0 -125
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Box3,
|
|
3
|
+
CubeCamera,
|
|
4
|
+
FloatType,
|
|
5
|
+
HalfFloatType,
|
|
6
|
+
LinearFilter,
|
|
7
|
+
Mesh,
|
|
8
|
+
NearestFilter,
|
|
9
|
+
Object3D,
|
|
10
|
+
OrthographicCamera,
|
|
11
|
+
PlaneGeometry,
|
|
12
|
+
RGBAFormat,
|
|
13
|
+
Scene,
|
|
14
|
+
ShaderMaterial,
|
|
15
|
+
Vector3,
|
|
16
|
+
Vector4,
|
|
17
|
+
WebGL3DRenderTarget,
|
|
18
|
+
WebGLCubeRenderTarget,
|
|
19
|
+
WebGLRenderTarget
|
|
20
|
+
} from 'three';
|
|
21
|
+
|
|
22
|
+
// Shared fullscreen-quad scene / camera
|
|
23
|
+
let _scene = null;
|
|
24
|
+
let _camera = null;
|
|
25
|
+
let _mesh = null;
|
|
26
|
+
|
|
27
|
+
// SH projection material (depends on cubemapSize)
|
|
28
|
+
let _shMaterial = null;
|
|
29
|
+
let _lastCubemapSize = 0;
|
|
30
|
+
|
|
31
|
+
// Repack materials (one per output sub-volume / texture index)
|
|
32
|
+
let _repackMaterials = null;
|
|
33
|
+
|
|
34
|
+
// Cached bake resources
|
|
35
|
+
let _cubeRenderTarget = null;
|
|
36
|
+
let _cubeCamera = null;
|
|
37
|
+
let _cachedCubemapSize = 0;
|
|
38
|
+
let _cachedNear = 0;
|
|
39
|
+
let _cachedFar = 0;
|
|
40
|
+
|
|
41
|
+
// Cached batch render target
|
|
42
|
+
let _batchTarget = null;
|
|
43
|
+
let _batchTargetProbes = 0;
|
|
44
|
+
|
|
45
|
+
// Reusable temp objects
|
|
46
|
+
const _position = /*@__PURE__*/ new Vector3();
|
|
47
|
+
const _size = /*@__PURE__*/ new Vector3();
|
|
48
|
+
const _savedViewport = /*@__PURE__*/ new Vector4();
|
|
49
|
+
const _savedScissor = /*@__PURE__*/ new Vector4();
|
|
50
|
+
|
|
51
|
+
// Number of padding texels added at each boundary of every sub-volume in the atlas.
|
|
52
|
+
const ATLAS_PADDING = 1;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A 3D grid of L2 Spherical Harmonic irradiance probes that provides
|
|
56
|
+
* position-dependent diffuse global illumination.
|
|
57
|
+
*
|
|
58
|
+
* All seven packed SH sub-volumes are stored in a **single** RGBA
|
|
59
|
+
* `WebGL3DRenderTarget` using a texture-atlas layout along the Z axis.
|
|
60
|
+
* Each sub-volume occupies `( nz + 2 )` atlas slices: one padding slice at
|
|
61
|
+
* each end (a copy of the nearest edge data slice) to prevent color bleeding
|
|
62
|
+
* when the hardware trilinear filter reads across a sub-volume boundary.
|
|
63
|
+
*
|
|
64
|
+
* Atlas layout (nz = resolution.z, PADDING = 1):
|
|
65
|
+
* ```
|
|
66
|
+
* slice 0 : padding (copy of sub-volume 0, data slice 0)
|
|
67
|
+
* slices 1 … nz : sub-volume 0 data
|
|
68
|
+
* slice nz + 1 : padding (copy of sub-volume 0, data slice nz-1)
|
|
69
|
+
* slice nz + 2 : padding (copy of sub-volume 1, data slice 0)
|
|
70
|
+
* slices nz+3 … 2*nz+2 : sub-volume 1 data
|
|
71
|
+
* …
|
|
72
|
+
* ```
|
|
73
|
+
* Total atlas depth = `7 * ( nz + 2 )`.
|
|
74
|
+
*
|
|
75
|
+
* Baking is fully GPU-resident: cubemap rendering, SH projection, and
|
|
76
|
+
* texture packing all happen on the GPU with zero CPU readback.
|
|
77
|
+
*
|
|
78
|
+
* @three_import import { LightProbeGrid } from 'three/addons/lighting/LightProbeGrid.js';
|
|
79
|
+
*/
|
|
80
|
+
class LightProbeGrid extends Object3D {
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Constructs a new irradiance probe grid.
|
|
84
|
+
*
|
|
85
|
+
* The volume is centered at the object's position.
|
|
86
|
+
*
|
|
87
|
+
* @param {number} [width=1] - Full width of the volume along X.
|
|
88
|
+
* @param {number} [height=1] - Full height of the volume along Y.
|
|
89
|
+
* @param {number} [depth=1] - Full depth of the volume along Z.
|
|
90
|
+
* @param {number} [widthProbes] - Number of probes along X. Defaults to `Math.max( 2, Math.round( width ) + 1 )`.
|
|
91
|
+
* @param {number} [heightProbes] - Number of probes along Y. Defaults to `Math.max( 2, Math.round( height ) + 1 )`.
|
|
92
|
+
* @param {number} [depthProbes] - Number of probes along Z. Defaults to `Math.max( 2, Math.round( depth ) + 1 )`.
|
|
93
|
+
*/
|
|
94
|
+
constructor( width = 1, height = 1, depth = 1, widthProbes, heightProbes, depthProbes ) {
|
|
95
|
+
|
|
96
|
+
super();
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* This flag can be used for type testing.
|
|
100
|
+
*
|
|
101
|
+
* @type {boolean}
|
|
102
|
+
* @readonly
|
|
103
|
+
* @default true
|
|
104
|
+
*/
|
|
105
|
+
this.isLightProbeGrid = true;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The full width of the volume along X.
|
|
109
|
+
*
|
|
110
|
+
* @type {number}
|
|
111
|
+
*/
|
|
112
|
+
this.width = width;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* The full height of the volume along Y.
|
|
116
|
+
*
|
|
117
|
+
* @type {number}
|
|
118
|
+
*/
|
|
119
|
+
this.height = height;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* The full depth of the volume along Z.
|
|
123
|
+
*
|
|
124
|
+
* @type {number}
|
|
125
|
+
*/
|
|
126
|
+
this.depth = depth;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The number of probes along each axis.
|
|
130
|
+
*
|
|
131
|
+
* @type {Vector3}
|
|
132
|
+
*/
|
|
133
|
+
this.resolution = new Vector3(
|
|
134
|
+
widthProbes !== undefined ? widthProbes : Math.max( 2, Math.round( width ) + 1 ),
|
|
135
|
+
heightProbes !== undefined ? heightProbes : Math.max( 2, Math.round( height ) + 1 ),
|
|
136
|
+
depthProbes !== undefined ? depthProbes : Math.max( 2, Math.round( depth ) + 1 )
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The world-space bounding box for the grid. Updated automatically
|
|
141
|
+
* by {@link LightProbeGrid#bake}.
|
|
142
|
+
*
|
|
143
|
+
* @type {Box3}
|
|
144
|
+
*/
|
|
145
|
+
this.boundingBox = new Box3();
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The single RGBA atlas 3D texture storing all seven packed SH sub-volumes.
|
|
149
|
+
*
|
|
150
|
+
* @type {?Data3DTexture}
|
|
151
|
+
* @default null
|
|
152
|
+
*/
|
|
153
|
+
this.texture = null;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Internal render target for GPU-resident baking.
|
|
157
|
+
*
|
|
158
|
+
* @private
|
|
159
|
+
* @type {?WebGL3DRenderTarget}
|
|
160
|
+
* @default null
|
|
161
|
+
*/
|
|
162
|
+
this._renderTarget = null;
|
|
163
|
+
|
|
164
|
+
this.updateBoundingBox();
|
|
165
|
+
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Returns the world-space position of the probe at grid indices (ix, iy, iz).
|
|
170
|
+
*
|
|
171
|
+
* @param {number} ix - X index.
|
|
172
|
+
* @param {number} iy - Y index.
|
|
173
|
+
* @param {number} iz - Z index.
|
|
174
|
+
* @param {Vector3} target - The target vector.
|
|
175
|
+
* @return {Vector3} The world-space position.
|
|
176
|
+
*/
|
|
177
|
+
getProbePosition( ix, iy, iz, target ) {
|
|
178
|
+
|
|
179
|
+
const pos = this.position;
|
|
180
|
+
const res = this.resolution;
|
|
181
|
+
const w = this.width, h = this.height, d = this.depth;
|
|
182
|
+
|
|
183
|
+
target.set(
|
|
184
|
+
res.x > 1 ? pos.x - w / 2 + ix * w / ( res.x - 1 ) : pos.x,
|
|
185
|
+
res.y > 1 ? pos.y - h / 2 + iy * h / ( res.y - 1 ) : pos.y,
|
|
186
|
+
res.z > 1 ? pos.z - d / 2 + iz * d / ( res.z - 1 ) : pos.z
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
return target;
|
|
190
|
+
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Updates the world-space bounding box from the current position and size.
|
|
195
|
+
*/
|
|
196
|
+
updateBoundingBox() {
|
|
197
|
+
|
|
198
|
+
_size.set( this.width, this.height, this.depth );
|
|
199
|
+
this.boundingBox.setFromCenterAndSize( this.position, _size );
|
|
200
|
+
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Bakes all probes by rendering cubemaps at each probe position
|
|
205
|
+
* and projecting to L2 SH. Fully GPU-resident with zero CPU readback.
|
|
206
|
+
*
|
|
207
|
+
* @param {WebGLRenderer} renderer - The renderer.
|
|
208
|
+
* @param {Scene} scene - The scene to render.
|
|
209
|
+
* @param {Object} [options] - Bake options.
|
|
210
|
+
* @param {number} [options.cubemapSize=8] - Resolution of each cubemap face.
|
|
211
|
+
* @param {number} [options.near=0.1] - Near plane for the cube camera.
|
|
212
|
+
* @param {number} [options.far=100] - Far plane for the cube camera.
|
|
213
|
+
*/
|
|
214
|
+
bake( renderer, scene, options = {} ) {
|
|
215
|
+
|
|
216
|
+
const { cubeRenderTarget, cubeCamera } = _ensureBakeResources( options );
|
|
217
|
+
|
|
218
|
+
this._ensureTextures();
|
|
219
|
+
this.updateBoundingBox();
|
|
220
|
+
|
|
221
|
+
// Prevent feedback: temporarily hide the volume during baking
|
|
222
|
+
this.visible = false;
|
|
223
|
+
|
|
224
|
+
const res = this.resolution;
|
|
225
|
+
const totalProbes = res.x * res.y * res.z;
|
|
226
|
+
|
|
227
|
+
// Batch render target for SH coefficients: 9 pixels wide, one row per probe
|
|
228
|
+
const batchTarget = _ensureBatchTarget( totalProbes );
|
|
229
|
+
|
|
230
|
+
// Save renderer state
|
|
231
|
+
const savedRenderTarget = renderer.getRenderTarget();
|
|
232
|
+
renderer.getViewport( _savedViewport );
|
|
233
|
+
renderer.getScissor( _savedScissor );
|
|
234
|
+
const savedScissorTest = renderer.getScissorTest();
|
|
235
|
+
|
|
236
|
+
// Clear pooled batch target so skipped probes read as zero
|
|
237
|
+
batchTarget.scissorTest = false;
|
|
238
|
+
batchTarget.viewport.set( 0, 0, 9, totalProbes );
|
|
239
|
+
renderer.setRenderTarget( batchTarget );
|
|
240
|
+
renderer.clear();
|
|
241
|
+
|
|
242
|
+
// const t0 = performance.now();
|
|
243
|
+
|
|
244
|
+
// Phase 1: Render cubemaps and project to SH into batch target
|
|
245
|
+
// Note: set viewport/scissor on the render target directly to avoid pixel ratio scaling
|
|
246
|
+
batchTarget.scissorTest = true;
|
|
247
|
+
|
|
248
|
+
// Disable shadow map auto-update during bake — lights don't move between probes.
|
|
249
|
+
// Force one shadow update on the first render so maps are initialized.
|
|
250
|
+
const savedShadowAutoUpdate = renderer.shadowMap.autoUpdate;
|
|
251
|
+
renderer.shadowMap.autoUpdate = false;
|
|
252
|
+
renderer.shadowMap.needsUpdate = true;
|
|
253
|
+
|
|
254
|
+
for ( let iz = 0; iz < res.z; iz ++ ) {
|
|
255
|
+
|
|
256
|
+
for ( let iy = 0; iy < res.y; iy ++ ) {
|
|
257
|
+
|
|
258
|
+
for ( let ix = 0; ix < res.x; ix ++ ) {
|
|
259
|
+
|
|
260
|
+
const probeIndex = ix + iy * res.x + iz * res.x * res.y;
|
|
261
|
+
|
|
262
|
+
this.getProbePosition( ix, iy, iz, _position );
|
|
263
|
+
cubeCamera.position.copy( _position );
|
|
264
|
+
cubeCamera.update( renderer, scene );
|
|
265
|
+
|
|
266
|
+
// SH projection
|
|
267
|
+
_shMaterial.uniforms.envMap.value = cubeRenderTarget.texture;
|
|
268
|
+
_mesh.material = _shMaterial;
|
|
269
|
+
batchTarget.viewport.set( 0, probeIndex, 9, 1 );
|
|
270
|
+
batchTarget.scissor.set( 0, probeIndex, 9, 1 );
|
|
271
|
+
renderer.setRenderTarget( batchTarget );
|
|
272
|
+
renderer.render( _scene, _camera );
|
|
273
|
+
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
renderer.shadowMap.autoUpdate = savedShadowAutoUpdate;
|
|
281
|
+
|
|
282
|
+
// Phase 2: Repack SH data from batch target into the atlas 3D texture (GPU-to-GPU).
|
|
283
|
+
//
|
|
284
|
+
// For each of the 7 packed sub-volumes (texture index t) we write:
|
|
285
|
+
// - A leading padding slice (copy of data slice iz = 0)
|
|
286
|
+
// - All nz data slices (iz = 0 … nz-1)
|
|
287
|
+
// - A trailing padding slice (copy of data slice iz = nz-1)
|
|
288
|
+
//
|
|
289
|
+
// In the atlas the slices for sub-volume t occupy the range:
|
|
290
|
+
// [ t * paddedSlices, t * paddedSlices + paddedSlices - 1 ]
|
|
291
|
+
// where paddedSlices = nz + 2 * ATLAS_PADDING.
|
|
292
|
+
|
|
293
|
+
_ensureRepackResources();
|
|
294
|
+
|
|
295
|
+
const paddedSlices = res.z + 2 * ATLAS_PADDING;
|
|
296
|
+
const rt = this._renderTarget;
|
|
297
|
+
rt.scissorTest = false;
|
|
298
|
+
rt.viewport.set( 0, 0, res.x, res.y );
|
|
299
|
+
|
|
300
|
+
for ( let t = 0; t < 7; t ++ ) {
|
|
301
|
+
|
|
302
|
+
_repackMaterials[ t ].uniforms.batchTexture.value = batchTarget.texture;
|
|
303
|
+
_repackMaterials[ t ].uniforms.resolution.value.copy( res );
|
|
304
|
+
|
|
305
|
+
// Write data slices
|
|
306
|
+
for ( let iz = 0; iz < res.z; iz ++ ) {
|
|
307
|
+
|
|
308
|
+
_repackMaterials[ t ].uniforms.sliceZ.value = iz;
|
|
309
|
+
_mesh.material = _repackMaterials[ t ];
|
|
310
|
+
renderer.setRenderTarget( rt, t * paddedSlices + ATLAS_PADDING + iz );
|
|
311
|
+
renderer.render( _scene, _camera );
|
|
312
|
+
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Leading padding: copy of data slice iz = 0
|
|
316
|
+
_repackMaterials[ t ].uniforms.sliceZ.value = 0;
|
|
317
|
+
_mesh.material = _repackMaterials[ t ];
|
|
318
|
+
renderer.setRenderTarget( rt, t * paddedSlices );
|
|
319
|
+
renderer.render( _scene, _camera );
|
|
320
|
+
|
|
321
|
+
// Trailing padding: copy of data slice iz = nz - 1
|
|
322
|
+
_repackMaterials[ t ].uniforms.sliceZ.value = res.z - 1;
|
|
323
|
+
_mesh.material = _repackMaterials[ t ];
|
|
324
|
+
renderer.setRenderTarget( rt, t * paddedSlices + ATLAS_PADDING + res.z );
|
|
325
|
+
renderer.render( _scene, _camera );
|
|
326
|
+
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Restore renderer state
|
|
330
|
+
renderer.setRenderTarget( savedRenderTarget );
|
|
331
|
+
renderer.setViewport( _savedViewport );
|
|
332
|
+
renderer.setScissor( _savedScissor );
|
|
333
|
+
renderer.setScissorTest( savedScissorTest );
|
|
334
|
+
|
|
335
|
+
// console.log( `LightProbeGrid: bake complete ${ ( performance.now() - t0 ).toFixed( 1 ) }ms` );
|
|
336
|
+
|
|
337
|
+
this.visible = true;
|
|
338
|
+
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Ensures the atlas 3D render target exists with the correct dimensions.
|
|
343
|
+
*
|
|
344
|
+
* @private
|
|
345
|
+
*/
|
|
346
|
+
_ensureTextures() {
|
|
347
|
+
|
|
348
|
+
if ( this._renderTarget !== null ) return;
|
|
349
|
+
|
|
350
|
+
const res = this.resolution;
|
|
351
|
+
const nx = res.x, ny = res.y, nz = res.z;
|
|
352
|
+
|
|
353
|
+
// Atlas depth: 7 sub-volumes, each with ATLAS_PADDING slices at both ends
|
|
354
|
+
const atlasDepth = 7 * ( nz + 2 * ATLAS_PADDING );
|
|
355
|
+
|
|
356
|
+
const rt = new WebGL3DRenderTarget( nx, ny, atlasDepth, {
|
|
357
|
+
format: RGBAFormat,
|
|
358
|
+
type: FloatType,
|
|
359
|
+
minFilter: LinearFilter,
|
|
360
|
+
magFilter: LinearFilter,
|
|
361
|
+
generateMipmaps: false,
|
|
362
|
+
depthBuffer: false
|
|
363
|
+
} );
|
|
364
|
+
|
|
365
|
+
this._renderTarget = rt;
|
|
366
|
+
this.texture = rt.texture;
|
|
367
|
+
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Frees GPU resources.
|
|
372
|
+
*/
|
|
373
|
+
dispose() {
|
|
374
|
+
|
|
375
|
+
if ( this._renderTarget !== null ) {
|
|
376
|
+
|
|
377
|
+
this._renderTarget.dispose();
|
|
378
|
+
this._renderTarget = null;
|
|
379
|
+
this.texture = null;
|
|
380
|
+
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Internal: Ensure the shared fullscreen-quad scene exists
|
|
388
|
+
function _ensureScene() {
|
|
389
|
+
|
|
390
|
+
if ( _scene === null ) {
|
|
391
|
+
|
|
392
|
+
_camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
|
393
|
+
_mesh = new Mesh( new PlaneGeometry( 2, 2 ) );
|
|
394
|
+
_scene = new Scene();
|
|
395
|
+
_scene.add( _mesh );
|
|
396
|
+
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Internal: Ensure GPU resources for SH projection are created
|
|
402
|
+
function _ensureGPUResources( cubemapSize ) {
|
|
403
|
+
|
|
404
|
+
_ensureScene();
|
|
405
|
+
|
|
406
|
+
// Recreate material when cubemap size changes
|
|
407
|
+
if ( cubemapSize !== _lastCubemapSize ) {
|
|
408
|
+
|
|
409
|
+
if ( _shMaterial !== null ) _shMaterial.dispose();
|
|
410
|
+
|
|
411
|
+
_shMaterial = new ShaderMaterial( {
|
|
412
|
+
precision: 'highp',
|
|
413
|
+
defines: {
|
|
414
|
+
CUBEMAP_SIZE: cubemapSize
|
|
415
|
+
},
|
|
416
|
+
uniforms: {
|
|
417
|
+
envMap: { value: null }
|
|
418
|
+
},
|
|
419
|
+
vertexShader: /* glsl */`
|
|
420
|
+
void main() {
|
|
421
|
+
gl_Position = vec4( position.xy, 0.0, 1.0 );
|
|
422
|
+
}
|
|
423
|
+
`,
|
|
424
|
+
fragmentShader: /* glsl */`
|
|
425
|
+
#include <common>
|
|
426
|
+
|
|
427
|
+
uniform samplerCube envMap;
|
|
428
|
+
|
|
429
|
+
void main() {
|
|
430
|
+
|
|
431
|
+
int coefIndex = int( gl_FragCoord.x );
|
|
432
|
+
|
|
433
|
+
vec3 accum0 = vec3( 0.0 );
|
|
434
|
+
vec3 accum1 = vec3( 0.0 );
|
|
435
|
+
vec3 accum2 = vec3( 0.0 );
|
|
436
|
+
vec3 accum3 = vec3( 0.0 );
|
|
437
|
+
vec3 accum4 = vec3( 0.0 );
|
|
438
|
+
vec3 accum5 = vec3( 0.0 );
|
|
439
|
+
vec3 accum6 = vec3( 0.0 );
|
|
440
|
+
vec3 accum7 = vec3( 0.0 );
|
|
441
|
+
vec3 accum8 = vec3( 0.0 );
|
|
442
|
+
float totalWeight = 0.0;
|
|
443
|
+
float pixelSize = 2.0 / float( CUBEMAP_SIZE );
|
|
444
|
+
|
|
445
|
+
for ( int face = 0; face < 6; face ++ ) {
|
|
446
|
+
|
|
447
|
+
for ( int iy = 0; iy < CUBEMAP_SIZE; iy ++ ) {
|
|
448
|
+
|
|
449
|
+
for ( int ix = 0; ix < CUBEMAP_SIZE; ix ++ ) {
|
|
450
|
+
|
|
451
|
+
// WebGL cubemaps have a left-handed orientation (flip = -1)
|
|
452
|
+
float col = ( float( ix ) + 0.5 ) * pixelSize - 1.0;
|
|
453
|
+
float row = 1.0 - ( float( iy ) + 0.5 ) * pixelSize;
|
|
454
|
+
|
|
455
|
+
vec3 coord;
|
|
456
|
+
|
|
457
|
+
if ( face == 0 ) coord = vec3( 1.0, row, -col );
|
|
458
|
+
else if ( face == 1 ) coord = vec3( -1.0, row, col );
|
|
459
|
+
else if ( face == 2 ) coord = vec3( col, 1.0, -row );
|
|
460
|
+
else if ( face == 3 ) coord = vec3( col, -1.0, row );
|
|
461
|
+
else if ( face == 4 ) coord = vec3( col, row, 1.0 );
|
|
462
|
+
else coord = vec3( -col, row, -1.0 );
|
|
463
|
+
|
|
464
|
+
float lengthSq = dot( coord, coord );
|
|
465
|
+
float weight = 4.0 / ( sqrt( lengthSq ) * lengthSq );
|
|
466
|
+
totalWeight += weight;
|
|
467
|
+
|
|
468
|
+
vec3 dir = normalize( coord );
|
|
469
|
+
vec3 cw = textureCube( envMap, coord ).rgb * weight;
|
|
470
|
+
|
|
471
|
+
// band 0
|
|
472
|
+
accum0 += cw * 0.282095;
|
|
473
|
+
|
|
474
|
+
// band 1
|
|
475
|
+
accum1 += cw * ( 0.488603 * dir.y );
|
|
476
|
+
accum2 += cw * ( 0.488603 * dir.z );
|
|
477
|
+
accum3 += cw * ( 0.488603 * dir.x );
|
|
478
|
+
|
|
479
|
+
// band 2
|
|
480
|
+
accum4 += cw * ( 1.092548 * ( dir.x * dir.y ) );
|
|
481
|
+
accum5 += cw * ( 1.092548 * ( dir.y * dir.z ) );
|
|
482
|
+
accum6 += cw * ( 0.315392 * ( 3.0 * dir.z * dir.z - 1.0 ) );
|
|
483
|
+
accum7 += cw * ( 1.092548 * ( dir.x * dir.z ) );
|
|
484
|
+
accum8 += cw * ( 0.546274 * ( dir.x * dir.x - dir.y * dir.y ) );
|
|
485
|
+
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
float norm = 4.0 * PI / totalWeight;
|
|
493
|
+
|
|
494
|
+
vec3 accum;
|
|
495
|
+
if ( coefIndex == 0 ) accum = accum0;
|
|
496
|
+
else if ( coefIndex == 1 ) accum = accum1;
|
|
497
|
+
else if ( coefIndex == 2 ) accum = accum2;
|
|
498
|
+
else if ( coefIndex == 3 ) accum = accum3;
|
|
499
|
+
else if ( coefIndex == 4 ) accum = accum4;
|
|
500
|
+
else if ( coefIndex == 5 ) accum = accum5;
|
|
501
|
+
else if ( coefIndex == 6 ) accum = accum6;
|
|
502
|
+
else if ( coefIndex == 7 ) accum = accum7;
|
|
503
|
+
else accum = accum8;
|
|
504
|
+
|
|
505
|
+
gl_FragColor = vec4( accum * norm, 1.0 );
|
|
506
|
+
|
|
507
|
+
}
|
|
508
|
+
`
|
|
509
|
+
} );
|
|
510
|
+
|
|
511
|
+
_lastCubemapSize = cubemapSize;
|
|
512
|
+
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Internal: Ensure GPU resources for repacking SH into the atlas 3D texture
|
|
518
|
+
function _ensureRepackResources() {
|
|
519
|
+
|
|
520
|
+
if ( _repackMaterials !== null ) return;
|
|
521
|
+
|
|
522
|
+
_ensureScene();
|
|
523
|
+
|
|
524
|
+
// Create 7 materials, one per output texture packing
|
|
525
|
+
// Texture 0: (c0.r, c0.g, c0.b, c1.r)
|
|
526
|
+
// Texture 1: (c1.g, c1.b, c2.r, c2.g)
|
|
527
|
+
// Texture 2: (c2.b, c3.r, c3.g, c3.b)
|
|
528
|
+
// Texture 3: (c4.r, c4.g, c4.b, c5.r)
|
|
529
|
+
// Texture 4: (c5.g, c5.b, c6.r, c6.g)
|
|
530
|
+
// Texture 5: (c6.b, c7.r, c7.g, c7.b)
|
|
531
|
+
// Texture 6: (c8.r, c8.g, c8.b, 0.0)
|
|
532
|
+
|
|
533
|
+
const repackVertexShader = /* glsl */`
|
|
534
|
+
void main() {
|
|
535
|
+
gl_Position = vec4( position.xy, 0.0, 1.0 );
|
|
536
|
+
}
|
|
537
|
+
`;
|
|
538
|
+
|
|
539
|
+
_repackMaterials = [];
|
|
540
|
+
|
|
541
|
+
for ( let t = 0; t < 7; t ++ ) {
|
|
542
|
+
|
|
543
|
+
_repackMaterials[ t ] = new ShaderMaterial( {
|
|
544
|
+
precision: 'highp',
|
|
545
|
+
defines: {
|
|
546
|
+
TEXTURE_INDEX: t
|
|
547
|
+
},
|
|
548
|
+
uniforms: {
|
|
549
|
+
batchTexture: { value: null },
|
|
550
|
+
resolution: { value: new Vector3() },
|
|
551
|
+
sliceZ: { value: 0 }
|
|
552
|
+
},
|
|
553
|
+
vertexShader: repackVertexShader,
|
|
554
|
+
fragmentShader: /* glsl */`
|
|
555
|
+
uniform sampler2D batchTexture;
|
|
556
|
+
uniform vec3 resolution;
|
|
557
|
+
uniform int sliceZ;
|
|
558
|
+
|
|
559
|
+
void main() {
|
|
560
|
+
|
|
561
|
+
int ix = int( gl_FragCoord.x );
|
|
562
|
+
int iy = int( gl_FragCoord.y );
|
|
563
|
+
int iz = sliceZ;
|
|
564
|
+
|
|
565
|
+
int probeIndex = ix + iy * int( resolution.x ) + iz * int( resolution.x ) * int( resolution.y );
|
|
566
|
+
|
|
567
|
+
// Read 9 SH coefficients from the batch texture row
|
|
568
|
+
vec4 c0 = texelFetch( batchTexture, ivec2( 0, probeIndex ), 0 );
|
|
569
|
+
vec4 c1 = texelFetch( batchTexture, ivec2( 1, probeIndex ), 0 );
|
|
570
|
+
vec4 c2 = texelFetch( batchTexture, ivec2( 2, probeIndex ), 0 );
|
|
571
|
+
vec4 c3 = texelFetch( batchTexture, ivec2( 3, probeIndex ), 0 );
|
|
572
|
+
vec4 c4 = texelFetch( batchTexture, ivec2( 4, probeIndex ), 0 );
|
|
573
|
+
vec4 c5 = texelFetch( batchTexture, ivec2( 5, probeIndex ), 0 );
|
|
574
|
+
vec4 c6 = texelFetch( batchTexture, ivec2( 6, probeIndex ), 0 );
|
|
575
|
+
vec4 c7 = texelFetch( batchTexture, ivec2( 7, probeIndex ), 0 );
|
|
576
|
+
vec4 c8 = texelFetch( batchTexture, ivec2( 8, probeIndex ), 0 );
|
|
577
|
+
|
|
578
|
+
// Pack into the output format for this texture index
|
|
579
|
+
#if TEXTURE_INDEX == 0
|
|
580
|
+
gl_FragColor = vec4( c0.rgb, c1.r );
|
|
581
|
+
#elif TEXTURE_INDEX == 1
|
|
582
|
+
gl_FragColor = vec4( c1.gb, c2.rg );
|
|
583
|
+
#elif TEXTURE_INDEX == 2
|
|
584
|
+
gl_FragColor = vec4( c2.b, c3.rgb );
|
|
585
|
+
#elif TEXTURE_INDEX == 3
|
|
586
|
+
gl_FragColor = vec4( c4.rgb, c5.r );
|
|
587
|
+
#elif TEXTURE_INDEX == 4
|
|
588
|
+
gl_FragColor = vec4( c5.gb, c6.rg );
|
|
589
|
+
#elif TEXTURE_INDEX == 5
|
|
590
|
+
gl_FragColor = vec4( c6.b, c7.rgb );
|
|
591
|
+
#else
|
|
592
|
+
gl_FragColor = vec4( c8.rgb, 0.0 );
|
|
593
|
+
#endif
|
|
594
|
+
|
|
595
|
+
}
|
|
596
|
+
`
|
|
597
|
+
} );
|
|
598
|
+
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// Internal: Ensure cube render target and camera exist with the right parameters
|
|
604
|
+
function _ensureBakeResources( options ) {
|
|
605
|
+
|
|
606
|
+
const {
|
|
607
|
+
cubemapSize = 8,
|
|
608
|
+
near = 0.1,
|
|
609
|
+
far = 100
|
|
610
|
+
} = options;
|
|
611
|
+
|
|
612
|
+
if ( _cubeRenderTarget === null || cubemapSize !== _cachedCubemapSize || near !== _cachedNear || far !== _cachedFar ) {
|
|
613
|
+
|
|
614
|
+
if ( _cubeRenderTarget !== null ) _cubeRenderTarget.dispose();
|
|
615
|
+
|
|
616
|
+
_cubeRenderTarget = new WebGLCubeRenderTarget( cubemapSize, { type: HalfFloatType } );
|
|
617
|
+
_cubeCamera = new CubeCamera( near, far, _cubeRenderTarget );
|
|
618
|
+
_cachedCubemapSize = cubemapSize;
|
|
619
|
+
_cachedNear = near;
|
|
620
|
+
_cachedFar = far;
|
|
621
|
+
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
_ensureGPUResources( cubemapSize );
|
|
625
|
+
|
|
626
|
+
return { cubeRenderTarget: _cubeRenderTarget, cubeCamera: _cubeCamera };
|
|
627
|
+
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
function _ensureBatchTarget( totalProbes ) {
|
|
631
|
+
|
|
632
|
+
if ( _batchTarget === null || _batchTargetProbes !== totalProbes ) {
|
|
633
|
+
|
|
634
|
+
if ( _batchTarget !== null ) _batchTarget.dispose();
|
|
635
|
+
|
|
636
|
+
_batchTarget = new WebGLRenderTarget( 9, totalProbes, {
|
|
637
|
+
type: FloatType,
|
|
638
|
+
minFilter: NearestFilter,
|
|
639
|
+
magFilter: NearestFilter,
|
|
640
|
+
depthBuffer: false
|
|
641
|
+
} );
|
|
642
|
+
|
|
643
|
+
_batchTargetProbes = totalProbes;
|
|
644
|
+
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
return _batchTarget;
|
|
648
|
+
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
export { LightProbeGrid };
|
|
@@ -647,7 +647,7 @@ class LineMaterial extends ShaderMaterial {
|
|
|
647
647
|
|
|
648
648
|
/**
|
|
649
649
|
* The size of the viewport, in screen pixels. This must be kept updated to make
|
|
650
|
-
* screen-space rendering accurate.The `LineSegments2.onBeforeRender` callback
|
|
650
|
+
* screen-space rendering accurate. The `LineSegments2.onBeforeRender` callback
|
|
651
651
|
* performs the update for visible objects.
|
|
652
652
|
*
|
|
653
653
|
* @type {Vector2}
|