@plastic-software/three 0.183.3 → 0.184.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 +783 -290
- package/build/three.core.js +372 -110
- package/build/three.core.min.js +1 -1
- package/build/three.module.js +436 -184
- 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/PMREMGenerator.js +1 -1
- 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 +148 -49
- 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/batching_pars_vertex.glsl.js +20 -0
- package/src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl.js +9 -1
- 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 +5 -0
- package/src/renderers/webgl/WebGLPrograms.js +24 -3
- 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
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HalfFloatType, Vector2, RenderTarget, RendererUtils, QuadMesh, NodeMaterial, TempNode, NodeUpdateType, Matrix4, DepthTexture } from 'three/webgpu';
|
|
2
|
-
import { add, float, If, Fn, max, texture, uniform, uv, vec2, vec4, luminance, convertToTexture, passTexture, velocity, getViewPosition, viewZToPerspectiveDepth, struct, ivec2, mix } from 'three/tsl';
|
|
1
|
+
import { HalfFloatType, Vector2, RenderTarget, RendererUtils, QuadMesh, NodeMaterial, TempNode, NodeUpdateType, Matrix4, DepthTexture, FloatType } from 'three/webgpu';
|
|
2
|
+
import { add, float, If, Fn, max, texture, uniform, uv, vec2, vec4, luminance, convertToTexture, passTexture, velocity, getViewPosition, viewZToPerspectiveDepth, struct, ivec2, mix, logarithmicDepthToViewZ, viewZToOrthographicDepth } from 'three/tsl';
|
|
3
3
|
|
|
4
4
|
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
5
5
|
const _size = /*@__PURE__*/ new Vector2();
|
|
@@ -14,6 +14,8 @@ let _rendererState;
|
|
|
14
14
|
* - {@link https://alextardif.com/TAA.html}
|
|
15
15
|
* - {@link https://www.elopezr.com/temporal-aa-and-the-quest-for-the-holy-trail/}
|
|
16
16
|
*
|
|
17
|
+
* Note: MSAA must be disabled when TRAA is in use.
|
|
18
|
+
*
|
|
17
19
|
* @augments TempNode
|
|
18
20
|
* @three_import import { traa } from 'three/addons/tsl/display/TRAANode.js';
|
|
19
21
|
*/
|
|
@@ -235,11 +237,20 @@ class TRAANode extends TempNode {
|
|
|
235
237
|
|
|
236
238
|
/**
|
|
237
239
|
* Sync the post processing stack with the TRAA node.
|
|
240
|
+
*
|
|
238
241
|
* @private
|
|
239
242
|
* @type {boolean}
|
|
240
243
|
*/
|
|
241
244
|
this._needsPostProcessingSync = false;
|
|
242
245
|
|
|
246
|
+
/**
|
|
247
|
+
* The node used to render the scene's velocity.
|
|
248
|
+
*
|
|
249
|
+
* @private
|
|
250
|
+
* @type {?VelocityNode}
|
|
251
|
+
*/
|
|
252
|
+
this._velocityNode = null;
|
|
253
|
+
|
|
243
254
|
}
|
|
244
255
|
|
|
245
256
|
/**
|
|
@@ -282,7 +293,7 @@ class TRAANode extends TempNode {
|
|
|
282
293
|
this.camera.updateProjectionMatrix();
|
|
283
294
|
this._originalProjectionMatrix.copy( this.camera.projectionMatrix );
|
|
284
295
|
|
|
285
|
-
|
|
296
|
+
this._velocityNode.setProjectionMatrix( this._originalProjectionMatrix );
|
|
286
297
|
|
|
287
298
|
//
|
|
288
299
|
|
|
@@ -318,7 +329,7 @@ class TRAANode extends TempNode {
|
|
|
318
329
|
|
|
319
330
|
this.camera.clearViewOffset();
|
|
320
331
|
|
|
321
|
-
|
|
332
|
+
this._velocityNode.setProjectionMatrix( null );
|
|
322
333
|
|
|
323
334
|
// update jitter index
|
|
324
335
|
|
|
@@ -452,6 +463,30 @@ class TRAANode extends TempNode {
|
|
|
452
463
|
|
|
453
464
|
}
|
|
454
465
|
|
|
466
|
+
if ( builder.renderer.reversedDepthBuffer === true ) {
|
|
467
|
+
|
|
468
|
+
this._historyRenderTarget.depthTexture.type = FloatType;
|
|
469
|
+
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if ( builder.context.velocity !== undefined ) {
|
|
473
|
+
|
|
474
|
+
this._velocityNode = builder.context.velocity;
|
|
475
|
+
|
|
476
|
+
} else {
|
|
477
|
+
|
|
478
|
+
this._velocityNode = velocity;
|
|
479
|
+
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
const logarithmicToPerspectiveDepth = ( depth ) => {
|
|
483
|
+
|
|
484
|
+
const { x: near, y: far } = this._cameraNearFar;
|
|
485
|
+
const viewZ = logarithmicDepthToViewZ( depth, near, far );
|
|
486
|
+
return viewZToPerspectiveDepth( viewZ, near, far );
|
|
487
|
+
|
|
488
|
+
};
|
|
489
|
+
|
|
455
490
|
const currentDepthStruct = struct( {
|
|
456
491
|
|
|
457
492
|
closestDepth: 'float',
|
|
@@ -472,7 +507,10 @@ class TRAANode extends TempNode {
|
|
|
472
507
|
for ( let y = - 1; y <= 1; ++ y ) {
|
|
473
508
|
|
|
474
509
|
const neighbor = positionTexel.add( vec2( x, y ) ).toVar();
|
|
475
|
-
|
|
510
|
+
let depth = this.depthNode.load( neighbor ).r;
|
|
511
|
+
if ( builder.renderer.reversedDepthBuffer ) depth = depth.oneMinus();
|
|
512
|
+
if ( builder.renderer.logarithmicDepthBuffer ) depth = logarithmicToPerspectiveDepth( depth );
|
|
513
|
+
depth = depth.toVar();
|
|
476
514
|
|
|
477
515
|
If( depth.lessThan( closestDepth ), () => {
|
|
478
516
|
|
|
@@ -498,11 +536,14 @@ class TRAANode extends TempNode {
|
|
|
498
536
|
// Samples a previous depth and reproject it using the current camera matrices.
|
|
499
537
|
const samplePreviousDepth = ( uv ) => {
|
|
500
538
|
|
|
501
|
-
|
|
539
|
+
let depth = this._previousDepthNode.sample( uv ).r;
|
|
540
|
+
if ( builder.renderer.logarithmicDepthBuffer ) depth = logarithmicToPerspectiveDepth( depth );
|
|
502
541
|
const positionView = getViewPosition( uv, depth, this._previousCameraProjectionMatrixInverse );
|
|
503
542
|
const positionWorld = this._previousCameraWorldMatrix.mul( vec4( positionView, 1 ) ).xyz;
|
|
504
543
|
const viewZ = this._cameraWorldMatrixInverse.mul( vec4( positionWorld, 1 ) ).z;
|
|
505
|
-
return
|
|
544
|
+
return this.camera.isOrthographicCamera
|
|
545
|
+
? viewZToOrthographicDepth( viewZ, this._cameraNearFar.x, this._cameraNearFar.y )
|
|
546
|
+
: viewZToPerspectiveDepth( viewZ, this._cameraNearFar.x, this._cameraNearFar.y );
|
|
506
547
|
|
|
507
548
|
};
|
|
508
549
|
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { LightsNode, NodeUtils, warn } from 'three/webgpu';
|
|
2
|
+
import { nodeObject } from 'three/tsl';
|
|
3
|
+
|
|
4
|
+
import AmbientLightDataNode from './data/AmbientLightDataNode.js';
|
|
5
|
+
import DirectionalLightDataNode from './data/DirectionalLightDataNode.js';
|
|
6
|
+
import PointLightDataNode from './data/PointLightDataNode.js';
|
|
7
|
+
import SpotLightDataNode from './data/SpotLightDataNode.js';
|
|
8
|
+
import HemisphereLightDataNode from './data/HemisphereLightDataNode.js';
|
|
9
|
+
|
|
10
|
+
const _lightNodeRef = /*@__PURE__*/ new WeakMap();
|
|
11
|
+
const _hashData = [];
|
|
12
|
+
|
|
13
|
+
const _lightTypeToDataNode = {
|
|
14
|
+
AmbientLight: AmbientLightDataNode,
|
|
15
|
+
DirectionalLight: DirectionalLightDataNode,
|
|
16
|
+
PointLight: PointLightDataNode,
|
|
17
|
+
SpotLight: SpotLightDataNode,
|
|
18
|
+
HemisphereLight: HemisphereLightDataNode
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const _lightTypeToMaxProp = {
|
|
22
|
+
DirectionalLight: 'maxDirectionalLights',
|
|
23
|
+
PointLight: 'maxPointLights',
|
|
24
|
+
SpotLight: 'maxSpotLights',
|
|
25
|
+
HemisphereLight: 'maxHemisphereLights'
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const sortLights = ( lights ) => lights.sort( ( a, b ) => a.id - b.id );
|
|
29
|
+
|
|
30
|
+
const isSpecialSpotLight = ( light ) => {
|
|
31
|
+
|
|
32
|
+
return light.isSpotLight === true && ( light.map !== null || light.colorNode !== undefined );
|
|
33
|
+
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const canBatchLight = ( light ) => {
|
|
37
|
+
|
|
38
|
+
return light.isNode !== true &&
|
|
39
|
+
light.castShadow !== true &&
|
|
40
|
+
isSpecialSpotLight( light ) === false &&
|
|
41
|
+
_lightTypeToDataNode[ light.constructor.name ] !== undefined;
|
|
42
|
+
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const getOrCreateLightNode = ( light, nodeLibrary ) => {
|
|
46
|
+
|
|
47
|
+
const lightNodeClass = nodeLibrary.getLightNodeClass( light.constructor );
|
|
48
|
+
|
|
49
|
+
if ( lightNodeClass === null ) {
|
|
50
|
+
|
|
51
|
+
warn( `DynamicLightsNode: Light node not found for ${ light.constructor.name }.` );
|
|
52
|
+
return null;
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if ( _lightNodeRef.has( light ) === false ) {
|
|
57
|
+
|
|
58
|
+
_lightNodeRef.set( light, new lightNodeClass( light ) );
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return _lightNodeRef.get( light );
|
|
63
|
+
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A custom version of `LightsNode` that batches supported analytic lights into
|
|
68
|
+
* uniform arrays and loops.
|
|
69
|
+
*
|
|
70
|
+
* Unsupported lights, node lights, shadow-casting lights, and projected spot
|
|
71
|
+
* lights keep the default per-light path.
|
|
72
|
+
*
|
|
73
|
+
* @augments LightsNode
|
|
74
|
+
* @three_import import { DynamicLightsNode } from 'three/addons/tsl/lighting/DynamicLightsNode.js';
|
|
75
|
+
*/
|
|
76
|
+
class DynamicLightsNode extends LightsNode {
|
|
77
|
+
|
|
78
|
+
static get type() {
|
|
79
|
+
|
|
80
|
+
return 'DynamicLightsNode';
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Constructs a new dynamic lights node.
|
|
86
|
+
*
|
|
87
|
+
* @param {Object} [options={}] - Dynamic lighting configuration.
|
|
88
|
+
* @param {number} [options.maxDirectionalLights=8] - Maximum number of batched directional lights.
|
|
89
|
+
* @param {number} [options.maxPointLights=16] - Maximum number of batched point lights.
|
|
90
|
+
* @param {number} [options.maxSpotLights=16] - Maximum number of batched spot lights.
|
|
91
|
+
* @param {number} [options.maxHemisphereLights=4] - Maximum number of batched hemisphere lights.
|
|
92
|
+
*/
|
|
93
|
+
constructor( options = {} ) {
|
|
94
|
+
|
|
95
|
+
super();
|
|
96
|
+
|
|
97
|
+
this.maxDirectionalLights = options.maxDirectionalLights !== undefined ? options.maxDirectionalLights : 8;
|
|
98
|
+
this.maxPointLights = options.maxPointLights !== undefined ? options.maxPointLights : 16;
|
|
99
|
+
this.maxSpotLights = options.maxSpotLights !== undefined ? options.maxSpotLights : 16;
|
|
100
|
+
this.maxHemisphereLights = options.maxHemisphereLights !== undefined ? options.maxHemisphereLights : 4;
|
|
101
|
+
|
|
102
|
+
this._dataNodes = new Map();
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
customCacheKey() {
|
|
107
|
+
|
|
108
|
+
const typeSet = new Set();
|
|
109
|
+
|
|
110
|
+
for ( let i = 0; i < this._lights.length; i ++ ) {
|
|
111
|
+
|
|
112
|
+
const light = this._lights[ i ];
|
|
113
|
+
|
|
114
|
+
if ( canBatchLight( light ) ) {
|
|
115
|
+
|
|
116
|
+
typeSet.add( light.constructor.name );
|
|
117
|
+
|
|
118
|
+
} else {
|
|
119
|
+
|
|
120
|
+
_hashData.push( light.id );
|
|
121
|
+
_hashData.push( light.castShadow ? 1 : 0 );
|
|
122
|
+
|
|
123
|
+
if ( light.isSpotLight === true ) {
|
|
124
|
+
|
|
125
|
+
const hashMap = light.map !== null ? light.map.id : - 1;
|
|
126
|
+
const hashColorNode = light.colorNode ? light.colorNode.getCacheKey() : - 1;
|
|
127
|
+
|
|
128
|
+
_hashData.push( hashMap, hashColorNode );
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
for ( const typeName of this._dataNodes.keys() ) {
|
|
137
|
+
|
|
138
|
+
typeSet.add( typeName );
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
for ( const typeName of [ ...typeSet ].sort() ) {
|
|
143
|
+
|
|
144
|
+
_hashData.push( NodeUtils.hashString( typeName ) );
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const cacheKey = NodeUtils.hashArray( _hashData );
|
|
149
|
+
|
|
150
|
+
_hashData.length = 0;
|
|
151
|
+
|
|
152
|
+
return cacheKey;
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
setupLightsNode( builder ) {
|
|
157
|
+
|
|
158
|
+
const lightNodes = [];
|
|
159
|
+
const lightsByType = new Map();
|
|
160
|
+
const lights = sortLights( this._lights );
|
|
161
|
+
const nodeLibrary = builder.renderer.library;
|
|
162
|
+
|
|
163
|
+
for ( const light of lights ) {
|
|
164
|
+
|
|
165
|
+
if ( light.isNode === true ) {
|
|
166
|
+
|
|
167
|
+
lightNodes.push( nodeObject( light ) );
|
|
168
|
+
continue;
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if ( canBatchLight( light ) ) {
|
|
173
|
+
|
|
174
|
+
const typeName = light.constructor.name;
|
|
175
|
+
const typeLights = lightsByType.get( typeName );
|
|
176
|
+
|
|
177
|
+
if ( typeLights === undefined ) {
|
|
178
|
+
|
|
179
|
+
lightsByType.set( typeName, [ light ] );
|
|
180
|
+
|
|
181
|
+
} else {
|
|
182
|
+
|
|
183
|
+
typeLights.push( light );
|
|
184
|
+
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
continue;
|
|
188
|
+
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const lightNode = getOrCreateLightNode( light, nodeLibrary );
|
|
192
|
+
|
|
193
|
+
if ( lightNode !== null ) {
|
|
194
|
+
|
|
195
|
+
lightNodes.push( lightNode );
|
|
196
|
+
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
for ( const [ typeName, typeLights ] of lightsByType ) {
|
|
202
|
+
|
|
203
|
+
let dataNode = this._dataNodes.get( typeName );
|
|
204
|
+
|
|
205
|
+
if ( dataNode === undefined ) {
|
|
206
|
+
|
|
207
|
+
const DataNodeClass = _lightTypeToDataNode[ typeName ];
|
|
208
|
+
const maxProp = _lightTypeToMaxProp[ typeName ];
|
|
209
|
+
const maxCount = maxProp !== undefined ? this[ maxProp ] : undefined;
|
|
210
|
+
|
|
211
|
+
dataNode = maxCount !== undefined ? new DataNodeClass( maxCount ) : new DataNodeClass();
|
|
212
|
+
|
|
213
|
+
this._dataNodes.set( typeName, dataNode );
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
dataNode.setLights( typeLights );
|
|
218
|
+
lightNodes.push( dataNode );
|
|
219
|
+
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
for ( const [ typeName, dataNode ] of this._dataNodes ) {
|
|
223
|
+
|
|
224
|
+
if ( lightsByType.has( typeName ) === false ) {
|
|
225
|
+
|
|
226
|
+
dataNode.setLights( [] );
|
|
227
|
+
lightNodes.push( dataNode );
|
|
228
|
+
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
this._lightNodes = lightNodes;
|
|
234
|
+
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
setLights( lights ) {
|
|
238
|
+
|
|
239
|
+
super.setLights( lights );
|
|
240
|
+
|
|
241
|
+
if ( this._dataNodes.size > 0 ) {
|
|
242
|
+
|
|
243
|
+
this._updateDataNodeLights( lights );
|
|
244
|
+
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return this;
|
|
248
|
+
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
_updateDataNodeLights( lights ) {
|
|
252
|
+
|
|
253
|
+
const lightsByType = new Map();
|
|
254
|
+
|
|
255
|
+
for ( const light of lights ) {
|
|
256
|
+
|
|
257
|
+
if ( canBatchLight( light ) === false ) continue;
|
|
258
|
+
|
|
259
|
+
const typeName = light.constructor.name;
|
|
260
|
+
const typeLights = lightsByType.get( typeName );
|
|
261
|
+
|
|
262
|
+
if ( typeLights === undefined ) {
|
|
263
|
+
|
|
264
|
+
lightsByType.set( typeName, [ light ] );
|
|
265
|
+
|
|
266
|
+
} else {
|
|
267
|
+
|
|
268
|
+
typeLights.push( light );
|
|
269
|
+
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
for ( const [ typeName, dataNode ] of this._dataNodes ) {
|
|
275
|
+
|
|
276
|
+
dataNode.setLights( lightsByType.get( typeName ) || [] );
|
|
277
|
+
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
get hasLights() {
|
|
283
|
+
|
|
284
|
+
return super.hasLights || this._dataNodes.size > 0;
|
|
285
|
+
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export default DynamicLightsNode;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* TSL function that creates a dynamic lights node.
|
|
294
|
+
*
|
|
295
|
+
* @tsl
|
|
296
|
+
* @function
|
|
297
|
+
* @param {Object} [options={}] - Dynamic lighting configuration.
|
|
298
|
+
* @return {DynamicLightsNode} The created dynamic lights node.
|
|
299
|
+
*/
|
|
300
|
+
export const dynamicLights = ( options = {} ) => new DynamicLightsNode( options );
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Color, Node } from 'three/webgpu';
|
|
2
|
+
import { NodeUpdateType, renderGroup, uniform } from 'three/tsl';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Batched data node for ambient lights in dynamic lighting mode.
|
|
6
|
+
*
|
|
7
|
+
* @augments Node
|
|
8
|
+
*/
|
|
9
|
+
class AmbientLightDataNode extends Node {
|
|
10
|
+
|
|
11
|
+
static get type() {
|
|
12
|
+
|
|
13
|
+
return 'AmbientLightDataNode';
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
|
|
19
|
+
super();
|
|
20
|
+
|
|
21
|
+
this._color = new Color();
|
|
22
|
+
this._lights = [];
|
|
23
|
+
|
|
24
|
+
this.colorNode = uniform( this._color ).setGroup( renderGroup );
|
|
25
|
+
this.updateType = NodeUpdateType.RENDER;
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setLights( lights ) {
|
|
30
|
+
|
|
31
|
+
this._lights = lights;
|
|
32
|
+
|
|
33
|
+
return this;
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
update() {
|
|
38
|
+
|
|
39
|
+
this._color.setScalar( 0 );
|
|
40
|
+
|
|
41
|
+
for ( let i = 0; i < this._lights.length; i ++ ) {
|
|
42
|
+
|
|
43
|
+
const light = this._lights[ i ];
|
|
44
|
+
|
|
45
|
+
this._color.r += light.color.r * light.intensity;
|
|
46
|
+
this._color.g += light.color.g * light.intensity;
|
|
47
|
+
this._color.b += light.color.b * light.intensity;
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
setup( builder ) {
|
|
54
|
+
|
|
55
|
+
builder.context.irradiance.addAssign( this.colorNode );
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default AmbientLightDataNode;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Color, Node, Vector3 } from 'three/webgpu';
|
|
2
|
+
import { Loop, NodeUpdateType, renderGroup, uniform, uniformArray, vec3 } from 'three/tsl';
|
|
3
|
+
|
|
4
|
+
const _lightPosition = /*@__PURE__*/ new Vector3();
|
|
5
|
+
const _targetPosition = /*@__PURE__*/ new Vector3();
|
|
6
|
+
|
|
7
|
+
const warn = ( message ) => {
|
|
8
|
+
|
|
9
|
+
console.warn( `THREE.DirectionalLightDataNode: ${ message }` );
|
|
10
|
+
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Batched data node for directional lights in dynamic lighting mode.
|
|
15
|
+
*
|
|
16
|
+
* @augments Node
|
|
17
|
+
*/
|
|
18
|
+
class DirectionalLightDataNode extends Node {
|
|
19
|
+
|
|
20
|
+
static get type() {
|
|
21
|
+
|
|
22
|
+
return 'DirectionalLightDataNode';
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
constructor( maxCount = 8 ) {
|
|
27
|
+
|
|
28
|
+
super();
|
|
29
|
+
|
|
30
|
+
this.maxCount = maxCount;
|
|
31
|
+
this._lights = [];
|
|
32
|
+
this._colors = [];
|
|
33
|
+
this._directions = [];
|
|
34
|
+
|
|
35
|
+
for ( let i = 0; i < maxCount; i ++ ) {
|
|
36
|
+
|
|
37
|
+
this._colors.push( new Color() );
|
|
38
|
+
this._directions.push( new Vector3() );
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.colorsNode = uniformArray( this._colors, 'color' ).setGroup( renderGroup );
|
|
43
|
+
this.directionsNode = uniformArray( this._directions, 'vec3' ).setGroup( renderGroup );
|
|
44
|
+
this.countNode = uniform( 0, 'int' ).setGroup( renderGroup );
|
|
45
|
+
this.updateType = NodeUpdateType.RENDER;
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
setLights( lights ) {
|
|
50
|
+
|
|
51
|
+
if ( lights.length > this.maxCount ) {
|
|
52
|
+
|
|
53
|
+
warn( `${ lights.length } lights exceed the configured max of ${ this.maxCount }. Excess lights are ignored.` );
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this._lights = lights;
|
|
58
|
+
|
|
59
|
+
return this;
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
update( { camera } ) {
|
|
64
|
+
|
|
65
|
+
const count = Math.min( this._lights.length, this.maxCount );
|
|
66
|
+
|
|
67
|
+
this.countNode.value = count;
|
|
68
|
+
|
|
69
|
+
for ( let i = 0; i < count; i ++ ) {
|
|
70
|
+
|
|
71
|
+
const light = this._lights[ i ];
|
|
72
|
+
|
|
73
|
+
this._colors[ i ].copy( light.color ).multiplyScalar( light.intensity );
|
|
74
|
+
|
|
75
|
+
_lightPosition.setFromMatrixPosition( light.matrixWorld );
|
|
76
|
+
_targetPosition.setFromMatrixPosition( light.target.matrixWorld );
|
|
77
|
+
|
|
78
|
+
this._directions[ i ].subVectors( _lightPosition, _targetPosition ).transformDirection( camera.matrixWorldInverse );
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
setup( builder ) {
|
|
85
|
+
|
|
86
|
+
const { lightingModel, reflectedLight } = builder.context;
|
|
87
|
+
const dynDiffuse = vec3( 0 ).toVar( 'dynDirectionalDiffuse' );
|
|
88
|
+
const dynSpecular = vec3( 0 ).toVar( 'dynDirectionalSpecular' );
|
|
89
|
+
|
|
90
|
+
Loop( this.countNode, ( { i } ) => {
|
|
91
|
+
|
|
92
|
+
const lightColor = this.colorsNode.element( i ).toVar();
|
|
93
|
+
const lightDirection = this.directionsNode.element( i ).normalize().toVar();
|
|
94
|
+
|
|
95
|
+
lightingModel.direct( {
|
|
96
|
+
lightDirection,
|
|
97
|
+
lightColor,
|
|
98
|
+
lightNode: { light: {}, shadowNode: null },
|
|
99
|
+
reflectedLight: { directDiffuse: dynDiffuse, directSpecular: dynSpecular }
|
|
100
|
+
}, builder );
|
|
101
|
+
|
|
102
|
+
} );
|
|
103
|
+
|
|
104
|
+
reflectedLight.directDiffuse.addAssign( dynDiffuse );
|
|
105
|
+
reflectedLight.directSpecular.addAssign( dynSpecular );
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default DirectionalLightDataNode;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Color, Node, Vector3 } from 'three/webgpu';
|
|
2
|
+
import { Loop, NodeUpdateType, mix, normalWorld, renderGroup, uniform, uniformArray } from 'three/tsl';
|
|
3
|
+
|
|
4
|
+
const warn = ( message ) => {
|
|
5
|
+
|
|
6
|
+
console.warn( `THREE.HemisphereLightDataNode: ${ message }` );
|
|
7
|
+
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Batched data node for hemisphere lights in dynamic lighting mode.
|
|
12
|
+
*
|
|
13
|
+
* @augments Node
|
|
14
|
+
*/
|
|
15
|
+
class HemisphereLightDataNode extends Node {
|
|
16
|
+
|
|
17
|
+
static get type() {
|
|
18
|
+
|
|
19
|
+
return 'HemisphereLightDataNode';
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
constructor( maxCount = 4 ) {
|
|
24
|
+
|
|
25
|
+
super();
|
|
26
|
+
|
|
27
|
+
this.maxCount = maxCount;
|
|
28
|
+
this._lights = [];
|
|
29
|
+
this._skyColors = [];
|
|
30
|
+
this._groundColors = [];
|
|
31
|
+
this._directions = [];
|
|
32
|
+
|
|
33
|
+
for ( let i = 0; i < maxCount; i ++ ) {
|
|
34
|
+
|
|
35
|
+
this._skyColors.push( new Color() );
|
|
36
|
+
this._groundColors.push( new Color() );
|
|
37
|
+
this._directions.push( new Vector3() );
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.skyColorsNode = uniformArray( this._skyColors, 'color' ).setGroup( renderGroup );
|
|
42
|
+
this.groundColorsNode = uniformArray( this._groundColors, 'color' ).setGroup( renderGroup );
|
|
43
|
+
this.directionsNode = uniformArray( this._directions, 'vec3' ).setGroup( renderGroup );
|
|
44
|
+
this.countNode = uniform( 0, 'int' ).setGroup( renderGroup );
|
|
45
|
+
this.updateType = NodeUpdateType.RENDER;
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
setLights( lights ) {
|
|
50
|
+
|
|
51
|
+
if ( lights.length > this.maxCount ) {
|
|
52
|
+
|
|
53
|
+
warn( `${ lights.length } lights exceed the configured max of ${ this.maxCount }. Excess lights are ignored.` );
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this._lights = lights;
|
|
58
|
+
|
|
59
|
+
return this;
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
update() {
|
|
64
|
+
|
|
65
|
+
const count = Math.min( this._lights.length, this.maxCount );
|
|
66
|
+
|
|
67
|
+
this.countNode.value = count;
|
|
68
|
+
|
|
69
|
+
for ( let i = 0; i < count; i ++ ) {
|
|
70
|
+
|
|
71
|
+
const light = this._lights[ i ];
|
|
72
|
+
|
|
73
|
+
this._skyColors[ i ].copy( light.color ).multiplyScalar( light.intensity );
|
|
74
|
+
this._groundColors[ i ].copy( light.groundColor ).multiplyScalar( light.intensity );
|
|
75
|
+
this._directions[ i ].setFromMatrixPosition( light.matrixWorld ).normalize();
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
setup( builder ) {
|
|
82
|
+
|
|
83
|
+
Loop( this.countNode, ( { i } ) => {
|
|
84
|
+
|
|
85
|
+
const skyColor = this.skyColorsNode.element( i );
|
|
86
|
+
const groundColor = this.groundColorsNode.element( i );
|
|
87
|
+
const lightDirection = this.directionsNode.element( i );
|
|
88
|
+
const hemiDiffuseWeight = normalWorld.dot( lightDirection ).mul( 0.5 ).add( 0.5 );
|
|
89
|
+
const irradiance = mix( groundColor, skyColor, hemiDiffuseWeight );
|
|
90
|
+
|
|
91
|
+
builder.context.irradiance.addAssign( irradiance );
|
|
92
|
+
|
|
93
|
+
} );
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default HemisphereLightDataNode;
|