@splnlss/3d-story-viewer 0.7.0 → 0.8.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.
Files changed (36) hide show
  1. package/build/assets/viewer/{geojson.worker-QNi-d8kU.js → geojson.worker-D3uq_RbR.js} +1 -1
  2. package/build/assets/viewer/spark-a62bdfe36d20.wasm +0 -0
  3. package/build/assets/viewer/{spark-worker-5ec8a483b87c.js → spark-worker-c1a6c013b888.js} +194 -43
  4. package/build/computeElevation.cjs +1 -1
  5. package/build/computeElevation.js +2 -2
  6. package/build/index-D87IZDc6.cjs +1 -0
  7. package/build/{index-CsZhc21b.js → index-Hz3jbrou.js} +1302 -829
  8. package/build/main-Bdopx4KL.js +15819 -0
  9. package/build/main-CaYKxosA.cjs +1 -0
  10. package/build/spark.module-B1FWS-vq.js +18168 -0
  11. package/build/spark.module-BUdzSHba.cjs +1 -0
  12. package/build/types/src/viewer/ContentLayer/GaussianSplatLayer.d.ts +4 -6
  13. package/build/types/src/viewer/ContentLayer/MeshLayer.d.ts +1 -1
  14. package/build/types/src/viewer/ContentLayer/TilesLayer.d.ts +4 -2
  15. package/build/types/src/viewer/ContentLayer/gaussianSplatUtils.d.ts +2 -1
  16. package/build/types/src/viewer/ContentLayer/index.d.ts +5 -3
  17. package/build/types/src/viewer/EnvironmentControls.d.ts +18 -12
  18. package/build/types/src/viewer/GlobeControls.d.ts +9 -6
  19. package/build/types/src/viewer/GlobeManager.d.ts +2 -1
  20. package/build/types/src/viewer/Sky.d.ts +5 -2
  21. package/build/types/src/viewer/TransitionControls.d.ts +2 -1
  22. package/build/types/src/viewer/index.d.ts +48 -18
  23. package/build/types/src/viewer/loadSpark.d.ts +1 -0
  24. package/build/types/src/viewer/mods.d.ts +1 -0
  25. package/build/types/src/viewer/shaders/chunks.d.ts +1 -0
  26. package/build/types/src/viewer/surfacePicking.d.ts +31 -0
  27. package/build/types/src/viewer/utils.d.ts +6 -4
  28. package/build/types/src/workers/geojson.worker.d.ts +2 -2
  29. package/build/types/utils/elevation/gltf.d.ts +2 -1
  30. package/build/viewer.cjs +1 -1
  31. package/build/viewer.js +5 -28044
  32. package/package.json +18 -16
  33. package/build/assets/viewer/spark-8b93f8c03d97.wasm +0 -0
  34. package/build/assets/viewer/spark-old-worker-932b4a2c87ca.js +0 -8168
  35. package/build/assets/viewer/spark-worker-015de49d2d00.wasm +0 -0
  36. package/build/index-wUFLgXbb.cjs +0 -1
@@ -7,7 +7,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7
7
  * SPDX-License-Identifier: MIT
8
8
  */
9
9
  var _a, _b, _c;
10
- const REVISION = "185";
10
+ const REVISION = "186";
11
11
  const CullFaceNone = 0;
12
12
  const CullFaceBack = 1;
13
13
  const CullFaceFront = 2;
@@ -169,7 +169,6 @@ const NotEqualCompare = 517;
169
169
  const GreaterEqualCompare = 518;
170
170
  const AlwaysCompare = 519;
171
171
  const StaticDrawUsage = 35044;
172
- const DynamicDrawUsage = 35048;
173
172
  const GLSL3 = "300 es";
174
173
  const WebGLCoordinateSystem = 2e3;
175
174
  const WebGPUCoordinateSystem = 2001;
@@ -403,7 +402,7 @@ function radToDeg(radians) {
403
402
  return radians * RAD2DEG;
404
403
  }
405
404
  function isPowerOfTwo(value) {
406
- return (value & value - 1) === 0 && value !== 0;
405
+ return value > 0 && Number.isInteger(value) && 2 ** Math.round(Math.log2(value)) === value;
407
406
  }
408
407
  function ceilPowerOfTwo(value) {
409
408
  return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));
@@ -454,6 +453,7 @@ function denormalize(value, array) {
454
453
  case Uint16Array:
455
454
  return value / 65535;
456
455
  case Uint8Array:
456
+ case Uint8ClampedArray:
457
457
  return value / 255;
458
458
  case Int32Array:
459
459
  return Math.max(value / 2147483647, -1);
@@ -474,6 +474,7 @@ function normalize(value, array) {
474
474
  case Uint16Array:
475
475
  return Math.round(value * 65535);
476
476
  case Uint8Array:
477
+ case Uint8ClampedArray:
477
478
  return Math.round(value * 255);
478
479
  case Int32Array:
479
480
  return Math.round(value * 2147483647);
@@ -2307,8 +2308,8 @@ let Vector3$1 = (_a = class {
2307
2308
  return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld);
2308
2309
  }
2309
2310
  /**
2310
- * Transforms the direction of this vector by a matrix (the upper left 3 x 3
2311
- * subset of the given 4x4 matrix and then normalizes the result.
2311
+ * Transforms this vector by the upper left 3x3 sub-matrix of the given 4x4 matrix,
2312
+ * and normalizes the result.
2312
2313
  *
2313
2314
  * @param {Matrix4} m - The matrix.
2314
2315
  * @return {Vector3} A reference to this vector.
@@ -3557,14 +3558,14 @@ class ImageUtils {
3557
3558
  }
3558
3559
  }
3559
3560
  let _sourceId = 0;
3560
- class Source {
3561
+ class TextureSource {
3561
3562
  /**
3562
- * Constructs a new video texture.
3563
+ * Constructs a new texture source.
3563
3564
  *
3564
3565
  * @param {any} [data=null] - The data definition of a texture.
3565
3566
  */
3566
3567
  constructor(data = null) {
3567
- this.isSource = true;
3568
+ this.isTextureSource = true;
3568
3569
  Object.defineProperty(this, "id", { value: _sourceId++ });
3569
3570
  this.uuid = generateUUID();
3570
3571
  this.data = data;
@@ -3681,7 +3682,7 @@ class Texture extends EventDispatcher {
3681
3682
  Object.defineProperty(this, "id", { value: _textureId++ });
3682
3683
  this.uuid = generateUUID();
3683
3684
  this.name = "";
3684
- this.source = new Source(image);
3685
+ this.source = new TextureSource(image);
3685
3686
  this.mipmaps = [];
3686
3687
  this.mapping = mapping;
3687
3688
  this.channel = 0;
@@ -4723,8 +4724,12 @@ class RenderTarget extends EventDispatcher {
4723
4724
  * @property {string} [colorSpace=NoColorSpace] - The texture's color space.
4724
4725
  * @property {boolean} [depthBuffer=true] - Whether to allocate a depth buffer or not.
4725
4726
  * @property {boolean} [stencilBuffer=false] - Whether to allocate a stencil buffer or not.
4726
- * @property {boolean} [resolveDepthBuffer=true] - Whether to resolve the depth buffer or not.
4727
- * @property {boolean} [resolveStencilBuffer=true] - Whether to resolve the stencil buffer or not.
4727
+ * @property {boolean} [resolveColorBuffer=true] - Whether to resolve the color buffer or not. Only relevant for multisampled render targets.
4728
+ * @property {boolean} [resolveDepthBuffer=true] - Whether to resolve the depth buffer or not. Only relevant for multisampled render targets.
4729
+ * @property {boolean} [resolveStencilBuffer=true] - Whether to resolve the stencil buffer or not. Only relevant for multisampled render targets.
4730
+ * @property {boolean} [storeMultisampledColorBuffer=true] - Whether to store the multisampled color buffer or not. Setting to `false` saves memory bandwidth when the multisampled data are not needed after a render pass.
4731
+ * @property {boolean} [storeMultisampledDepthBuffer=true] - Whether to store the multisampled depth buffer or not. Setting to `false` saves memory bandwidth when the multisampled data are not needed after a render pass.
4732
+ * @property {boolean} [storeMultisampledStencilBuffer=true] - Whether to store the multisampled stencil buffer or not. Setting to `false` saves memory bandwidth when the multisampled data are not needed after a render pass.
4728
4733
  * @property {?Texture} [depthTexture=null] - Reference to a depth texture.
4729
4734
  * @property {number} [samples=0] - The MSAA samples count.
4730
4735
  * @property {number} [count=1] - Defines the number of color attachments . Must be at least `1`.
@@ -4747,8 +4752,12 @@ class RenderTarget extends EventDispatcher {
4747
4752
  minFilter: LinearFilter,
4748
4753
  depthBuffer: true,
4749
4754
  stencilBuffer: false,
4755
+ resolveColorBuffer: true,
4750
4756
  resolveDepthBuffer: true,
4751
4757
  resolveStencilBuffer: true,
4758
+ storeMultisampledColorBuffer: true,
4759
+ storeMultisampledDepthBuffer: true,
4760
+ storeMultisampledStencilBuffer: true,
4752
4761
  depthTexture: null,
4753
4762
  samples: 0,
4754
4763
  count: 1,
@@ -4775,8 +4784,12 @@ class RenderTarget extends EventDispatcher {
4775
4784
  this._setTextureOptions(options);
4776
4785
  this.depthBuffer = options.depthBuffer;
4777
4786
  this.stencilBuffer = options.stencilBuffer;
4787
+ this.resolveColorBuffer = options.resolveColorBuffer;
4778
4788
  this.resolveDepthBuffer = options.resolveDepthBuffer;
4779
4789
  this.resolveStencilBuffer = options.resolveStencilBuffer;
4790
+ this.storeMultisampledColorBuffer = options.storeMultisampledColorBuffer;
4791
+ this.storeMultisampledDepthBuffer = options.storeMultisampledDepthBuffer;
4792
+ this.storeMultisampledStencilBuffer = options.storeMultisampledStencilBuffer;
4780
4793
  this._depthTexture = null;
4781
4794
  this.depthTexture = options.depthTexture;
4782
4795
  this.samples = options.samples;
@@ -4820,8 +4833,8 @@ class RenderTarget extends EventDispatcher {
4820
4833
  this.textures[0] = value;
4821
4834
  }
4822
4835
  set depthTexture(current) {
4823
- if (this._depthTexture !== null) this._depthTexture.renderTarget = null;
4824
- if (current !== null) current.renderTarget = this;
4836
+ if (this._depthTexture !== null && this._depthTexture.renderTarget === this) this._depthTexture.renderTarget = null;
4837
+ if (current !== null && current.renderTarget === null) current.renderTarget = this;
4825
4838
  this._depthTexture = current;
4826
4839
  }
4827
4840
  /**
@@ -4889,13 +4902,25 @@ class RenderTarget extends EventDispatcher {
4889
4902
  this.textures[i].isRenderTargetTexture = true;
4890
4903
  this.textures[i].renderTarget = this;
4891
4904
  const image = Object.assign({}, source.textures[i].image);
4892
- this.textures[i].source = new Source(image);
4905
+ this.textures[i].source = new TextureSource(image);
4893
4906
  }
4894
4907
  this.depthBuffer = source.depthBuffer;
4895
4908
  this.stencilBuffer = source.stencilBuffer;
4909
+ this.resolveColorBuffer = source.resolveColorBuffer;
4896
4910
  this.resolveDepthBuffer = source.resolveDepthBuffer;
4897
4911
  this.resolveStencilBuffer = source.resolveStencilBuffer;
4898
- if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone();
4912
+ this.storeMultisampledColorBuffer = source.storeMultisampledColorBuffer;
4913
+ this.storeMultisampledDepthBuffer = source.storeMultisampledDepthBuffer;
4914
+ this.storeMultisampledStencilBuffer = source.storeMultisampledStencilBuffer;
4915
+ if (source.depthTexture !== null) {
4916
+ if (source.depthTexture.renderTarget === source) {
4917
+ const depthTexture = source.depthTexture.clone();
4918
+ depthTexture.renderTarget = null;
4919
+ this.depthTexture = depthTexture;
4920
+ } else {
4921
+ this.depthTexture = source.depthTexture;
4922
+ }
4923
+ }
4899
4924
  this.samples = source.samples;
4900
4925
  this.multiview = source.multiview;
4901
4926
  this.useArrayDepthTexture = source.useArrayDepthTexture;
@@ -4945,6 +4970,17 @@ class DataArrayTexture extends Texture {
4945
4970
  this.unpackAlignment = 1;
4946
4971
  this.layerUpdates = /* @__PURE__ */ new Set();
4947
4972
  }
4973
+ /**
4974
+ * Copies the values of the given texture to this instance.
4975
+ *
4976
+ * @param {DataArrayTexture} source - The texture to copy.
4977
+ * @return {DataArrayTexture} A reference to this instance.
4978
+ */
4979
+ copy(source) {
4980
+ super.copy(source);
4981
+ this.wrapR = source.wrapR;
4982
+ return this;
4983
+ }
4948
4984
  /**
4949
4985
  * Describes that a specific layer of the texture needs to be updated.
4950
4986
  * Normally when {@link Texture#needsUpdate} is set to `true`, the
@@ -5002,6 +5038,17 @@ class Data3DTexture extends Texture {
5002
5038
  this.flipY = false;
5003
5039
  this.unpackAlignment = 1;
5004
5040
  }
5041
+ /**
5042
+ * Copies the values of the given texture to this instance.
5043
+ *
5044
+ * @param {Data3DTexture} source - The texture to copy.
5045
+ * @return {Data3DTexture} A reference to this instance.
5046
+ */
5047
+ copy(source) {
5048
+ super.copy(source);
5049
+ this.wrapR = source.wrapR;
5050
+ return this;
5051
+ }
5005
5052
  }
5006
5053
  const _Matrix4 = class _Matrix4 {
5007
5054
  /**
@@ -5195,7 +5242,7 @@ const _Matrix4 = class _Matrix4 {
5195
5242
  return this;
5196
5243
  }
5197
5244
  /**
5198
- * Extracts the basis of this matrix into the three axis vectors provided.
5245
+ * Extracts the basis vectors of this matrix into the three vectors provided.
5199
5246
  *
5200
5247
  * @param {Vector3} xAxis - The basis's x axis.
5201
5248
  * @param {Vector3} yAxis - The basis's y axis.
@@ -5506,8 +5553,6 @@ const _Matrix4 = class _Matrix4 {
5506
5553
  /**
5507
5554
  * Computes and returns the determinant of this matrix.
5508
5555
  *
5509
- * Based on the method outlined [here](http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.html).
5510
- *
5511
5556
  * @return {number} The determinant.
5512
5557
  */
5513
5558
  determinant() {
@@ -5623,7 +5668,7 @@ const _Matrix4 = class _Matrix4 {
5623
5668
  return this;
5624
5669
  }
5625
5670
  /**
5626
- * Multiplies the columns of this matrix by the given vector.
5671
+ * Scales each of the first three columns of this matrix by the corresponding component of the given vector.
5627
5672
  *
5628
5673
  * @param {Vector3} v - The scale vector.
5629
5674
  * @return {Matrix4} A reference to this matrix.
@@ -5798,9 +5843,6 @@ const _Matrix4 = class _Matrix4 {
5798
5843
  * Sets this matrix as a rotational transformation around the given axis by
5799
5844
  * the given angle.
5800
5845
  *
5801
- * This is a somewhat controversial but mathematically sound alternative to
5802
- * rotating via Quaternions. See the discussion [here](https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199).
5803
- *
5804
5846
  * @param {Vector3} axis - The normalized rotation axis.
5805
5847
  * @param {number} angle - The rotation in radians.
5806
5848
  * @return {Matrix4} A reference to this matrix.
@@ -7090,6 +7132,17 @@ class Object3D extends EventDispatcher {
7090
7132
  */
7091
7133
  raycast() {
7092
7134
  }
7135
+ /**
7136
+ * Abstract method to test whether this 3D object intersects the given frustum.
7137
+ * Renderable 3D objects such as {@link Mesh}, {@link Line} or {@link Points}
7138
+ * implement this method in order to use frustum culling.
7139
+ *
7140
+ * @abstract
7141
+ * @param {Frustum|FrustumArray} frustum - The frustum to test.
7142
+ * @return {boolean|undefined} Whether this 3D object intersects the given frustum or not.
7143
+ */
7144
+ intersectsFrustum() {
7145
+ }
7093
7146
  /**
7094
7147
  * Executes the callback on this 3D object and all descendants.
7095
7148
  *
@@ -7244,19 +7297,19 @@ class Object3D extends EventDispatcher {
7244
7297
  const object = {};
7245
7298
  object.uuid = this.uuid;
7246
7299
  object.type = this.type;
7247
- if (this.name !== "") object.name = this.name;
7248
- if (this.castShadow === true) object.castShadow = true;
7249
- if (this.receiveShadow === true) object.receiveShadow = true;
7250
- if (this.visible === false) object.visible = false;
7251
- if (this.frustumCulled === false) object.frustumCulled = false;
7252
- if (this.renderOrder !== 0) object.renderOrder = this.renderOrder;
7253
- if (this.static !== false) object.static = this.static;
7300
+ object.name = this.name;
7301
+ object.castShadow = this.castShadow;
7302
+ object.receiveShadow = this.receiveShadow;
7303
+ object.visible = this.visible;
7304
+ object.frustumCulled = this.frustumCulled;
7305
+ object.renderOrder = this.renderOrder;
7306
+ object.static = this.static;
7307
+ object.matrixAutoUpdate = this.matrixAutoUpdate;
7254
7308
  if (Object.keys(this.userData).length > 0) object.userData = this.userData;
7255
7309
  object.layers = this.layers.mask;
7256
7310
  object.matrix = this.matrix.toArray();
7257
7311
  object.up = this.up.toArray();
7258
7312
  if (this.pivot !== null) object.pivot = this.pivot.toArray();
7259
- if (this.matrixAutoUpdate === false) object.matrixAutoUpdate = false;
7260
7313
  if (this.morphTargetDictionary !== void 0) object.morphTargetDictionary = Object.assign({}, this.morphTargetDictionary);
7261
7314
  if (this.morphTargetInfluences !== void 0) object.morphTargetInfluences = this.morphTargetInfluences.slice();
7262
7315
  if (this.isInstancedMesh) {
@@ -7438,6 +7491,18 @@ class Object3D extends EventDispatcher {
7438
7491
  }
7439
7492
  return this;
7440
7493
  }
7494
+ /**
7495
+ * Frees the GPU-related resources allocated by this instance. Call this
7496
+ * method whenever this instance is no longer used in your app.
7497
+ *
7498
+ * Geometries, materials and textures are potentially shared with other
7499
+ * 3D objects and must be disposed of separately.
7500
+ *
7501
+ * @fires Object3D#dispose
7502
+ */
7503
+ dispose() {
7504
+ this.dispatchEvent({ type: "dispose" });
7505
+ }
7441
7506
  }
7442
7507
  Object3D.DEFAULT_UP = /* @__PURE__ */ new Vector3$1(0, 1, 0);
7443
7508
  Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true;
@@ -8490,10 +8555,10 @@ class Scene extends Object3D {
8490
8555
  toJSON(meta) {
8491
8556
  const data = super.toJSON(meta);
8492
8557
  if (this.fog !== null) data.object.fog = this.fog.toJSON();
8493
- if (this.backgroundBlurriness > 0) data.object.backgroundBlurriness = this.backgroundBlurriness;
8494
- if (this.backgroundIntensity !== 1) data.object.backgroundIntensity = this.backgroundIntensity;
8558
+ data.object.backgroundBlurriness = this.backgroundBlurriness;
8559
+ data.object.backgroundIntensity = this.backgroundIntensity;
8495
8560
  data.object.backgroundRotation = this.backgroundRotation.toArray();
8496
- if (this.environmentIntensity !== 1) data.object.environmentIntensity = this.environmentIntensity;
8561
+ data.object.environmentIntensity = this.environmentIntensity;
8497
8562
  data.object.environmentRotation = this.environmentRotation.toArray();
8498
8563
  return data;
8499
8564
  }
@@ -9934,8 +9999,9 @@ class BufferAttribute extends EventDispatcher {
9934
9999
  array: Array.from(this.array),
9935
10000
  normalized: this.normalized
9936
10001
  };
9937
- if (this.name !== "") data.name = this.name;
9938
- if (this.usage !== StaticDrawUsage) data.usage = this.usage;
10002
+ data.name = this.name;
10003
+ data.usage = this.usage;
10004
+ data.gpuType = this.gpuType;
9939
10005
  return data;
9940
10006
  }
9941
10007
  /**
@@ -10907,7 +10973,7 @@ class BufferGeometry extends EventDispatcher {
10907
10973
  };
10908
10974
  data.uuid = this.uuid;
10909
10975
  data.type = this.parameters !== void 0 && this._transformed === true ? "BufferGeometry" : this.type;
10910
- if (this.name !== "") data.name = this.name;
10976
+ data.name = this.name;
10911
10977
  if (Object.keys(this.userData).length > 0) data.userData = this.userData;
10912
10978
  if (this.parameters !== void 0 && this._transformed !== true) {
10913
10979
  const parameters = this.parameters;
@@ -11178,12 +11244,14 @@ class InterleavedBuffer {
11178
11244
  if (data.arrayBuffers[this.array.buffer._uuid] === void 0) {
11179
11245
  data.arrayBuffers[this.array.buffer._uuid] = Array.from(new Uint32Array(this.array.buffer));
11180
11246
  }
11181
- return {
11247
+ const json = {
11182
11248
  uuid: this.uuid,
11183
11249
  buffer: this.array.buffer._uuid,
11184
11250
  type: this.array.constructor.name,
11185
11251
  stride: this.stride
11186
11252
  };
11253
+ json.usage = this.usage;
11254
+ return json;
11187
11255
  }
11188
11256
  }
11189
11257
  const _vector$8 = /* @__PURE__ */ new Vector3$1();
@@ -11527,6 +11595,270 @@ class InterleavedBufferAttribute {
11527
11595
  }
11528
11596
  }
11529
11597
  }
11598
+ const _vector1 = /* @__PURE__ */ new Vector3$1();
11599
+ const _vector2 = /* @__PURE__ */ new Vector3$1();
11600
+ const _normalMatrix = /* @__PURE__ */ new Matrix3$1();
11601
+ class Plane {
11602
+ /**
11603
+ * Constructs a new plane.
11604
+ *
11605
+ * @param {Vector3} [normal=(1,0,0)] - A unit length vector defining the normal of the plane.
11606
+ * @param {number} [constant=0] - The signed distance from the origin to the plane.
11607
+ */
11608
+ constructor(normal = new Vector3$1(1, 0, 0), constant = 0) {
11609
+ this.isPlane = true;
11610
+ this.normal = normal;
11611
+ this.constant = constant;
11612
+ }
11613
+ /**
11614
+ * Sets the plane components by copying the given values.
11615
+ *
11616
+ * @param {Vector3} normal - The normal.
11617
+ * @param {number} constant - The constant.
11618
+ * @return {Plane} A reference to this plane.
11619
+ */
11620
+ set(normal, constant) {
11621
+ this.normal.copy(normal);
11622
+ this.constant = constant;
11623
+ return this;
11624
+ }
11625
+ /**
11626
+ * Sets the plane components by defining `x`, `y`, `z` as the
11627
+ * plane normal and `w` as the constant.
11628
+ *
11629
+ * @param {number} x - The value for the normal's x component.
11630
+ * @param {number} y - The value for the normal's y component.
11631
+ * @param {number} z - The value for the normal's z component.
11632
+ * @param {number} w - The constant value.
11633
+ * @return {Plane} A reference to this plane.
11634
+ */
11635
+ setComponents(x, y, z, w) {
11636
+ this.normal.set(x, y, z);
11637
+ this.constant = w;
11638
+ return this;
11639
+ }
11640
+ /**
11641
+ * Sets the plane from the given normal and coplanar point (that is a point
11642
+ * that lies onto the plane).
11643
+ *
11644
+ * @param {Vector3} normal - The normal.
11645
+ * @param {Vector3} point - A coplanar point.
11646
+ * @return {Plane} A reference to this plane.
11647
+ */
11648
+ setFromNormalAndCoplanarPoint(normal, point) {
11649
+ this.normal.copy(normal);
11650
+ this.constant = -point.dot(this.normal);
11651
+ return this;
11652
+ }
11653
+ /**
11654
+ * Sets the plane from three coplanar points. The winding order is
11655
+ * assumed to be counter-clockwise, and determines the direction of
11656
+ * the plane normal.
11657
+ *
11658
+ * @param {Vector3} a - The first coplanar point.
11659
+ * @param {Vector3} b - The second coplanar point.
11660
+ * @param {Vector3} c - The third coplanar point.
11661
+ * @return {Plane} A reference to this plane.
11662
+ */
11663
+ setFromCoplanarPoints(a, b, c) {
11664
+ const normal = _vector1.subVectors(c, b).cross(_vector2.subVectors(a, b)).normalize();
11665
+ this.setFromNormalAndCoplanarPoint(normal, a);
11666
+ return this;
11667
+ }
11668
+ /**
11669
+ * Copies the values of the given plane to this instance.
11670
+ *
11671
+ * @param {Plane} plane - The plane to copy.
11672
+ * @return {Plane} A reference to this plane.
11673
+ */
11674
+ copy(plane) {
11675
+ this.normal.copy(plane.normal);
11676
+ this.constant = plane.constant;
11677
+ return this;
11678
+ }
11679
+ /**
11680
+ * Normalizes the plane normal and adjusts the constant accordingly.
11681
+ *
11682
+ * @return {Plane} A reference to this plane.
11683
+ */
11684
+ normalize() {
11685
+ const inverseNormalLength = 1 / this.normal.length();
11686
+ this.normal.multiplyScalar(inverseNormalLength);
11687
+ this.constant *= inverseNormalLength;
11688
+ return this;
11689
+ }
11690
+ /**
11691
+ * Negates both the plane normal and the constant.
11692
+ *
11693
+ * @return {Plane} A reference to this plane.
11694
+ */
11695
+ negate() {
11696
+ this.constant *= -1;
11697
+ this.normal.negate();
11698
+ return this;
11699
+ }
11700
+ /**
11701
+ * Returns the signed distance from the given point to this plane.
11702
+ *
11703
+ * @param {Vector3} point - The point to compute the distance for.
11704
+ * @return {number} The signed distance.
11705
+ */
11706
+ distanceToPoint(point) {
11707
+ return this.normal.dot(point) + this.constant;
11708
+ }
11709
+ /**
11710
+ * Returns the signed distance from the given sphere to this plane.
11711
+ *
11712
+ * @param {Sphere} sphere - The sphere to compute the distance for.
11713
+ * @return {number} The signed distance.
11714
+ */
11715
+ distanceToSphere(sphere) {
11716
+ return this.distanceToPoint(sphere.center) - sphere.radius;
11717
+ }
11718
+ /**
11719
+ * Projects a the given point onto the plane.
11720
+ *
11721
+ * @param {Vector3} point - The point to project.
11722
+ * @param {Vector3} target - The target vector that is used to store the method's result.
11723
+ * @return {Vector3} The projected point on the plane.
11724
+ */
11725
+ projectPoint(point, target) {
11726
+ return target.copy(point).addScaledVector(this.normal, -this.distanceToPoint(point));
11727
+ }
11728
+ /**
11729
+ * Returns the intersection point of the passed line and the plane. Returns
11730
+ * `null` if the line does not intersect. Returns the line's starting point if
11731
+ * the line is coplanar with the plane.
11732
+ *
11733
+ * @param {Line3} line - The line to compute the intersection for.
11734
+ * @param {Vector3} target - The target vector that is used to store the method's result.
11735
+ * @param {boolean} [clampToLine=true] - Whether to clamp the intersection to the line segment.
11736
+ * @return {?Vector3} The intersection point. Returns `null` if no intersection is detected.
11737
+ */
11738
+ intersectLine(line, target, clampToLine = true) {
11739
+ const direction = line.delta(_vector1);
11740
+ const denominator = this.normal.dot(direction);
11741
+ if (denominator === 0) {
11742
+ if (this.distanceToPoint(line.start) === 0) {
11743
+ return target.copy(line.start);
11744
+ }
11745
+ return null;
11746
+ }
11747
+ const t = -(line.start.dot(this.normal) + this.constant) / denominator;
11748
+ if (clampToLine === true && (t < 0 || t > 1)) {
11749
+ return null;
11750
+ }
11751
+ return target.copy(line.start).addScaledVector(direction, t);
11752
+ }
11753
+ /**
11754
+ * Returns `true` if the given line segment intersects with (passes through) the plane.
11755
+ *
11756
+ * @param {Line3} line - The line to test.
11757
+ * @return {boolean} Whether the given line segment intersects with the plane or not.
11758
+ */
11759
+ intersectsLine(line) {
11760
+ const startSign = this.distanceToPoint(line.start);
11761
+ const endSign = this.distanceToPoint(line.end);
11762
+ return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0;
11763
+ }
11764
+ /**
11765
+ * Returns `true` if the given bounding box intersects with the plane.
11766
+ *
11767
+ * @param {Box3} box - The bounding box to test.
11768
+ * @return {boolean} Whether the given bounding box intersects with the plane or not.
11769
+ */
11770
+ intersectsBox(box) {
11771
+ return box.intersectsPlane(this);
11772
+ }
11773
+ /**
11774
+ * Returns `true` if the given bounding sphere intersects with the plane.
11775
+ *
11776
+ * @param {Sphere} sphere - The bounding sphere to test.
11777
+ * @return {boolean} Whether the given bounding sphere intersects with the plane or not.
11778
+ */
11779
+ intersectsSphere(sphere) {
11780
+ return sphere.intersectsPlane(this);
11781
+ }
11782
+ /**
11783
+ * Returns a coplanar vector to the plane, by calculating the
11784
+ * projection of the normal at the origin onto the plane.
11785
+ *
11786
+ * @param {Vector3} target - The target vector that is used to store the method's result.
11787
+ * @return {Vector3} The coplanar point.
11788
+ */
11789
+ coplanarPoint(target) {
11790
+ return target.copy(this.normal).multiplyScalar(-this.constant);
11791
+ }
11792
+ /**
11793
+ * Apply a 4x4 matrix to the plane. The matrix must be an affine, homogeneous transform.
11794
+ *
11795
+ * The optional normal matrix can be pre-computed like so:
11796
+ * ```js
11797
+ * const optionalNormalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
11798
+ * ```
11799
+ *
11800
+ * @param {Matrix4} matrix - The transformation matrix.
11801
+ * @param {Matrix4} [optionalNormalMatrix] - A pre-computed normal matrix.
11802
+ * @return {Plane} A reference to this plane.
11803
+ */
11804
+ applyMatrix4(matrix, optionalNormalMatrix) {
11805
+ const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix);
11806
+ const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix);
11807
+ const normal = this.normal.applyMatrix3(normalMatrix).normalize();
11808
+ this.constant = -referencePoint.dot(normal);
11809
+ return this;
11810
+ }
11811
+ /**
11812
+ * Translates the plane by the distance defined by the given offset vector.
11813
+ * Note that this only affects the plane constant and will not affect the normal vector.
11814
+ *
11815
+ * @param {Vector3} offset - The offset vector.
11816
+ * @return {Plane} A reference to this plane.
11817
+ */
11818
+ translate(offset) {
11819
+ this.constant -= offset.dot(this.normal);
11820
+ return this;
11821
+ }
11822
+ /**
11823
+ * Returns `true` if this plane is equal with the given one.
11824
+ *
11825
+ * @param {Plane} plane - The plane to test for equality.
11826
+ * @return {boolean} Whether this plane is equal with the given one.
11827
+ */
11828
+ equals(plane) {
11829
+ return plane.normal.equals(this.normal) && plane.constant === this.constant;
11830
+ }
11831
+ /**
11832
+ * Returns a new plane with copied values from this instance.
11833
+ *
11834
+ * @return {Plane} A clone of this instance.
11835
+ */
11836
+ clone() {
11837
+ return new this.constructor().copy(this);
11838
+ }
11839
+ /**
11840
+ * Returns a serialized structure of the plane.
11841
+ *
11842
+ * @return {Object} Serialized structure with fields representing the object state.
11843
+ */
11844
+ toJSON() {
11845
+ return {
11846
+ normal: this.normal.toArray(),
11847
+ constant: this.constant
11848
+ };
11849
+ }
11850
+ /**
11851
+ * Sets the plane properties from the given JSON.
11852
+ *
11853
+ * @param {Object} json - The serialized json to set the plane from.
11854
+ * @return {Plane} A reference to this plane.
11855
+ */
11856
+ fromJSON(json) {
11857
+ this.normal.fromArray(json.normal);
11858
+ this.constant = json.constant;
11859
+ return this;
11860
+ }
11861
+ }
11530
11862
  let _materialId = 0;
11531
11863
  class Material extends EventDispatcher {
11532
11864
  /**
@@ -11694,7 +12026,47 @@ class Material extends EventDispatcher {
11694
12026
  };
11695
12027
  data.uuid = this.uuid;
11696
12028
  data.type = this.type;
11697
- if (this.name !== "") data.name = this.name;
12029
+ data.blending = this.blending;
12030
+ data.side = this.side;
12031
+ data.shadowSide = this.shadowSide;
12032
+ data.vertexColors = this.vertexColors;
12033
+ data.opacity = this.opacity;
12034
+ data.transparent = this.transparent;
12035
+ data.blendSrc = this.blendSrc;
12036
+ data.blendDst = this.blendDst;
12037
+ data.blendEquation = this.blendEquation;
12038
+ data.blendSrcAlpha = this.blendSrcAlpha;
12039
+ data.blendDstAlpha = this.blendDstAlpha;
12040
+ data.blendEquationAlpha = this.blendEquationAlpha;
12041
+ data.blendColor = this.blendColor.getHex();
12042
+ data.blendAlpha = this.blendAlpha;
12043
+ data.depthFunc = this.depthFunc;
12044
+ data.depthTest = this.depthTest;
12045
+ data.depthWrite = this.depthWrite;
12046
+ data.colorWrite = this.colorWrite;
12047
+ data.clipIntersection = this.clipIntersection;
12048
+ data.clipShadows = this.clipShadows;
12049
+ data.stencilWriteMask = this.stencilWriteMask;
12050
+ data.stencilFunc = this.stencilFunc;
12051
+ data.stencilRef = this.stencilRef;
12052
+ data.stencilFuncMask = this.stencilFuncMask;
12053
+ data.stencilFail = this.stencilFail;
12054
+ data.stencilZFail = this.stencilZFail;
12055
+ data.stencilZPass = this.stencilZPass;
12056
+ data.stencilWrite = this.stencilWrite;
12057
+ data.polygonOffset = this.polygonOffset;
12058
+ data.polygonOffsetFactor = this.polygonOffsetFactor;
12059
+ data.polygonOffsetUnits = this.polygonOffsetUnits;
12060
+ data.dithering = this.dithering;
12061
+ data.alphaTest = this.alphaTest;
12062
+ data.alphaHash = this.alphaHash;
12063
+ data.alphaToCoverage = this.alphaToCoverage;
12064
+ data.premultipliedAlpha = this.premultipliedAlpha;
12065
+ data.forceSinglePass = this.forceSinglePass;
12066
+ data.allowOverride = this.allowOverride;
12067
+ data.visible = this.visible;
12068
+ data.toneMapped = this.toneMapped;
12069
+ data.name = this.name;
11698
12070
  if (this.color && this.color.isColor) data.color = this.color.getHex();
11699
12071
  if (this.roughness !== void 0) data.roughness = this.roughness;
11700
12072
  if (this.metalness !== void 0) data.metalness = this.metalness;
@@ -11702,7 +12074,7 @@ class Material extends EventDispatcher {
11702
12074
  if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex();
11703
12075
  if (this.sheenRoughness !== void 0) data.sheenRoughness = this.sheenRoughness;
11704
12076
  if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex();
11705
- if (this.emissiveIntensity !== void 0 && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity;
12077
+ if (this.emissiveIntensity !== void 0) data.emissiveIntensity = this.emissiveIntensity;
11706
12078
  if (this.specular && this.specular.isColor) data.specular = this.specular.getHex();
11707
12079
  if (this.specularIntensity !== void 0) data.specularIntensity = this.specularIntensity;
11708
12080
  if (this.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.getHex();
@@ -11726,6 +12098,7 @@ class Material extends EventDispatcher {
11726
12098
  data.sheenRoughnessMap = this.sheenRoughnessMap.toJSON(meta).uuid;
11727
12099
  }
11728
12100
  if (this.dispersion !== void 0) data.dispersion = this.dispersion;
12101
+ if (this.retroreflectivity !== void 0) data.retroreflectivity = this.retroreflectivity;
11729
12102
  if (this.iridescence !== void 0) data.iridescence = this.iridescence;
11730
12103
  if (this.iridescenceIOR !== void 0) data.iridescenceIOR = this.iridescenceIOR;
11731
12104
  if (this.iridescenceThicknessRange !== void 0) data.iridescenceThicknessRange = this.iridescenceThicknessRange;
@@ -11786,59 +12159,27 @@ class Material extends EventDispatcher {
11786
12159
  if (this.transmissionMap && this.transmissionMap.isTexture) data.transmissionMap = this.transmissionMap.toJSON(meta).uuid;
11787
12160
  if (this.thickness !== void 0) data.thickness = this.thickness;
11788
12161
  if (this.thicknessMap && this.thicknessMap.isTexture) data.thicknessMap = this.thicknessMap.toJSON(meta).uuid;
11789
- if (this.attenuationDistance !== void 0 && this.attenuationDistance !== Infinity) data.attenuationDistance = this.attenuationDistance;
12162
+ if (this.attenuationDistance !== void 0) data.attenuationDistance = this.attenuationDistance;
11790
12163
  if (this.attenuationColor !== void 0) data.attenuationColor = this.attenuationColor.getHex();
11791
12164
  if (this.size !== void 0) data.size = this.size;
11792
- if (this.shadowSide !== null) data.shadowSide = this.shadowSide;
11793
12165
  if (this.sizeAttenuation !== void 0) data.sizeAttenuation = this.sizeAttenuation;
11794
- if (this.blending !== NormalBlending) data.blending = this.blending;
11795
- if (this.side !== FrontSide) data.side = this.side;
11796
- if (this.vertexColors === true) data.vertexColors = true;
11797
- if (this.opacity < 1) data.opacity = this.opacity;
11798
- if (this.transparent === true) data.transparent = true;
11799
- if (this.blendSrc !== SrcAlphaFactor) data.blendSrc = this.blendSrc;
11800
- if (this.blendDst !== OneMinusSrcAlphaFactor) data.blendDst = this.blendDst;
11801
- if (this.blendEquation !== AddEquation) data.blendEquation = this.blendEquation;
11802
- if (this.blendSrcAlpha !== null) data.blendSrcAlpha = this.blendSrcAlpha;
11803
- if (this.blendDstAlpha !== null) data.blendDstAlpha = this.blendDstAlpha;
11804
- if (this.blendEquationAlpha !== null) data.blendEquationAlpha = this.blendEquationAlpha;
11805
- if (this.blendColor && this.blendColor.isColor) data.blendColor = this.blendColor.getHex();
11806
- if (this.blendAlpha !== 0) data.blendAlpha = this.blendAlpha;
11807
- if (this.depthFunc !== LessEqualDepth) data.depthFunc = this.depthFunc;
11808
- if (this.depthTest === false) data.depthTest = this.depthTest;
11809
- if (this.depthWrite === false) data.depthWrite = this.depthWrite;
11810
- if (this.colorWrite === false) data.colorWrite = this.colorWrite;
11811
- if (this.stencilWriteMask !== 255) data.stencilWriteMask = this.stencilWriteMask;
11812
- if (this.stencilFunc !== AlwaysStencilFunc) data.stencilFunc = this.stencilFunc;
11813
- if (this.stencilRef !== 0) data.stencilRef = this.stencilRef;
11814
- if (this.stencilFuncMask !== 255) data.stencilFuncMask = this.stencilFuncMask;
11815
- if (this.stencilFail !== KeepStencilOp) data.stencilFail = this.stencilFail;
11816
- if (this.stencilZFail !== KeepStencilOp) data.stencilZFail = this.stencilZFail;
11817
- if (this.stencilZPass !== KeepStencilOp) data.stencilZPass = this.stencilZPass;
11818
- if (this.stencilWrite === true) data.stencilWrite = this.stencilWrite;
11819
- if (this.rotation !== void 0 && this.rotation !== 0) data.rotation = this.rotation;
11820
- if (this.polygonOffset === true) data.polygonOffset = true;
11821
- if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor;
11822
- if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits;
11823
- if (this.linewidth !== void 0 && this.linewidth !== 1) data.linewidth = this.linewidth;
12166
+ if (Array.isArray(this.clippingPlanes) && this.clippingPlanes.length > 0) {
12167
+ data.clippingPlanes = this.clippingPlanes.map((plane) => plane.toJSON());
12168
+ }
12169
+ if (this.rotation !== void 0) data.rotation = this.rotation;
12170
+ if (this.depthPacking !== void 0) data.depthPacking = this.depthPacking;
12171
+ if (this.linewidth !== void 0) data.linewidth = this.linewidth;
12172
+ if (this.linecap !== void 0) data.linecap = this.linecap;
12173
+ if (this.linejoin !== void 0) data.linejoin = this.linejoin;
11824
12174
  if (this.dashSize !== void 0) data.dashSize = this.dashSize;
11825
12175
  if (this.gapSize !== void 0) data.gapSize = this.gapSize;
11826
12176
  if (this.scale !== void 0) data.scale = this.scale;
11827
- if (this.dithering === true) data.dithering = true;
11828
- if (this.alphaTest > 0) data.alphaTest = this.alphaTest;
11829
- if (this.alphaHash === true) data.alphaHash = true;
11830
- if (this.alphaToCoverage === true) data.alphaToCoverage = true;
11831
- if (this.premultipliedAlpha === true) data.premultipliedAlpha = true;
11832
- if (this.forceSinglePass === true) data.forceSinglePass = true;
11833
- if (this.allowOverride === false) data.allowOverride = false;
11834
- if (this.wireframe === true) data.wireframe = true;
11835
- if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth;
11836
- if (this.wireframeLinecap !== "round") data.wireframeLinecap = this.wireframeLinecap;
11837
- if (this.wireframeLinejoin !== "round") data.wireframeLinejoin = this.wireframeLinejoin;
11838
- if (this.flatShading === true) data.flatShading = true;
11839
- if (this.visible === false) data.visible = false;
11840
- if (this.toneMapped === false) data.toneMapped = false;
11841
- if (this.fog === false) data.fog = false;
12177
+ if (this.wireframe !== void 0) data.wireframe = this.wireframe;
12178
+ if (this.wireframeLinewidth !== void 0) data.wireframeLinewidth = this.wireframeLinewidth;
12179
+ if (this.wireframeLinecap !== void 0) data.wireframeLinecap = this.wireframeLinecap;
12180
+ if (this.wireframeLinejoin !== void 0) data.wireframeLinejoin = this.wireframeLinejoin;
12181
+ if (this.flatShading !== void 0) data.flatShading = this.flatShading;
12182
+ if (this.fog !== void 0) data.fog = this.fog;
11842
12183
  if (Object.keys(this.userData).length > 0) data.userData = this.userData;
11843
12184
  function extractFromCache(cache2) {
11844
12185
  const values = [];
@@ -11881,6 +12222,7 @@ class Material extends EventDispatcher {
11881
12222
  if (json.clearcoat !== void 0) this.clearcoat = json.clearcoat;
11882
12223
  if (json.clearcoatRoughness !== void 0) this.clearcoatRoughness = json.clearcoatRoughness;
11883
12224
  if (json.dispersion !== void 0) this.dispersion = json.dispersion;
12225
+ if (json.retroreflectivity !== void 0) this.retroreflectivity = json.retroreflectivity;
11884
12226
  if (json.iridescence !== void 0) this.iridescence = json.iridescence;
11885
12227
  if (json.iridescenceIOR !== void 0) this.iridescenceIOR = json.iridescenceIOR;
11886
12228
  if (json.iridescenceThicknessRange !== void 0) this.iridescenceThicknessRange = json.iridescenceThicknessRange;
@@ -11904,6 +12246,10 @@ class Material extends EventDispatcher {
11904
12246
  if (json.depthTest !== void 0) this.depthTest = json.depthTest;
11905
12247
  if (json.depthWrite !== void 0) this.depthWrite = json.depthWrite;
11906
12248
  if (json.colorWrite !== void 0) this.colorWrite = json.colorWrite;
12249
+ if (json.clippingPlanes !== void 0) this.clippingPlanes = json.clippingPlanes.map((plane) => new Plane().fromJSON(plane));
12250
+ if (json.clipIntersection !== void 0) this.clipIntersection = json.clipIntersection;
12251
+ if (json.clipShadows !== void 0) this.clipShadows = json.clipShadows;
12252
+ if (json.depthPacking !== void 0) this.depthPacking = json.depthPacking;
11907
12253
  if (json.blendSrc !== void 0) this.blendSrc = json.blendSrc;
11908
12254
  if (json.blendDst !== void 0) this.blendDst = json.blendDst;
11909
12255
  if (json.blendEquation !== void 0) this.blendEquation = json.blendEquation;
@@ -11926,6 +12272,8 @@ class Material extends EventDispatcher {
11926
12272
  if (json.wireframeLinejoin !== void 0) this.wireframeLinejoin = json.wireframeLinejoin;
11927
12273
  if (json.rotation !== void 0) this.rotation = json.rotation;
11928
12274
  if (json.linewidth !== void 0) this.linewidth = json.linewidth;
12275
+ if (json.linecap !== void 0) this.linecap = json.linecap;
12276
+ if (json.linejoin !== void 0) this.linejoin = json.linejoin;
11929
12277
  if (json.dashSize !== void 0) this.dashSize = json.dashSize;
11930
12278
  if (json.gapSize !== void 0) this.gapSize = json.gapSize;
11931
12279
  if (json.scale !== void 0) this.scale = json.scale;
@@ -12091,9 +12439,6 @@ const _vector$7 = /* @__PURE__ */ new Vector3$1();
12091
12439
  const _segCenter = /* @__PURE__ */ new Vector3$1();
12092
12440
  const _segDir = /* @__PURE__ */ new Vector3$1();
12093
12441
  const _diff = /* @__PURE__ */ new Vector3$1();
12094
- const _edge1 = /* @__PURE__ */ new Vector3$1();
12095
- const _edge2 = /* @__PURE__ */ new Vector3$1();
12096
- const _normal$1 = /* @__PURE__ */ new Vector3$1();
12097
12442
  class Ray {
12098
12443
  /**
12099
12444
  * Constructs a new ray.
@@ -12274,6 +12619,7 @@ class Ray {
12274
12619
  * @return {?Vector3} The intersection point.
12275
12620
  */
12276
12621
  intersectSphere(sphere, target) {
12622
+ if (sphere.radius < 0) return null;
12277
12623
  _vector$7.subVectors(sphere.center, this.origin);
12278
12624
  const tca = _vector$7.dot(this.direction);
12279
12625
  const d2 = _vector$7.dot(_vector$7) - tca * tca;
@@ -12409,37 +12755,108 @@ class Ray {
12409
12755
  * @return {?Vector3} The intersection point.
12410
12756
  */
12411
12757
  intersectTriangle(a, b, c, backfaceCulling, target) {
12412
- _edge1.subVectors(b, a);
12413
- _edge2.subVectors(c, a);
12414
- _normal$1.crossVectors(_edge1, _edge2);
12415
- let DdN = this.direction.dot(_normal$1);
12416
- let sign;
12417
- if (DdN > 0) {
12418
- if (backfaceCulling) return null;
12419
- sign = 1;
12420
- } else if (DdN < 0) {
12421
- sign = -1;
12422
- DdN = -DdN;
12758
+ const origin = this.origin;
12759
+ const direction = this.direction;
12760
+ const dx = direction.x;
12761
+ const dy = direction.y;
12762
+ const dz = direction.z;
12763
+ const aox = a.x - origin.x, aoy = a.y - origin.y, aoz = a.z - origin.z;
12764
+ const box = b.x - origin.x, boy = b.y - origin.y, boz = b.z - origin.z;
12765
+ const cox = c.x - origin.x, coy = c.y - origin.y, coz = c.z - origin.z;
12766
+ const adx = Math.abs(dx), ady = Math.abs(dy), adz = Math.abs(dz);
12767
+ let dkx, dky, dkz;
12768
+ let akx, aky, akz, bkx, bky, bkz, ckx, cky, ckz;
12769
+ if (adx >= ady && adx >= adz) {
12770
+ dkz = dx;
12771
+ akz = aox;
12772
+ bkz = box;
12773
+ ckz = cox;
12774
+ if (dx >= 0) {
12775
+ dkx = dy;
12776
+ dky = dz;
12777
+ akx = aoy;
12778
+ aky = aoz;
12779
+ bkx = boy;
12780
+ bky = boz;
12781
+ ckx = coy;
12782
+ cky = coz;
12783
+ } else {
12784
+ dkx = dz;
12785
+ dky = dy;
12786
+ akx = aoz;
12787
+ aky = aoy;
12788
+ bkx = boz;
12789
+ bky = boy;
12790
+ ckx = coz;
12791
+ cky = coy;
12792
+ }
12793
+ } else if (ady >= adz) {
12794
+ dkz = dy;
12795
+ akz = aoy;
12796
+ bkz = boy;
12797
+ ckz = coy;
12798
+ if (dy >= 0) {
12799
+ dkx = dz;
12800
+ dky = dx;
12801
+ akx = aoz;
12802
+ aky = aox;
12803
+ bkx = boz;
12804
+ bky = box;
12805
+ ckx = coz;
12806
+ cky = cox;
12807
+ } else {
12808
+ dkx = dx;
12809
+ dky = dz;
12810
+ akx = aox;
12811
+ aky = aoz;
12812
+ bkx = box;
12813
+ bky = boz;
12814
+ ckx = cox;
12815
+ cky = coz;
12816
+ }
12423
12817
  } else {
12424
- return null;
12425
- }
12426
- _diff.subVectors(this.origin, a);
12427
- const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2));
12428
- if (DdQxE2 < 0) {
12429
- return null;
12430
- }
12431
- const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff));
12432
- if (DdE1xQ < 0) {
12433
- return null;
12434
- }
12435
- if (DdQxE2 + DdE1xQ > DdN) {
12436
- return null;
12437
- }
12438
- const QdN = -sign * _diff.dot(_normal$1);
12439
- if (QdN < 0) {
12440
- return null;
12818
+ dkz = dz;
12819
+ akz = aoz;
12820
+ bkz = boz;
12821
+ ckz = coz;
12822
+ if (dz >= 0) {
12823
+ dkx = dx;
12824
+ dky = dy;
12825
+ akx = aox;
12826
+ aky = aoy;
12827
+ bkx = box;
12828
+ bky = boy;
12829
+ ckx = cox;
12830
+ cky = coy;
12831
+ } else {
12832
+ dkx = dy;
12833
+ dky = dx;
12834
+ akx = aoy;
12835
+ aky = aox;
12836
+ bkx = boy;
12837
+ bky = box;
12838
+ ckx = coy;
12839
+ cky = cox;
12840
+ }
12841
+ }
12842
+ if (dkz === 0) return null;
12843
+ const sx = dkx / dkz, sy = dky / dkz, sz = 1 / dkz;
12844
+ const ax = akx - sx * akz, ay = aky - sy * akz;
12845
+ const bx = bkx - sx * bkz, by = bky - sy * bkz;
12846
+ const cx = ckx - sx * ckz, cy = cky - sy * ckz;
12847
+ const u = cx * by - cy * bx;
12848
+ const v = ax * cy - ay * cx;
12849
+ const w = bx * ay - by * ax;
12850
+ if (backfaceCulling) {
12851
+ if (u < 0 || v < 0 || w < 0) return null;
12852
+ } else {
12853
+ if ((u < 0 || v < 0 || w < 0) && (u > 0 || v > 0 || w > 0)) return null;
12441
12854
  }
12442
- return this.at(QdN / DdN, target);
12855
+ const det = u + v + w;
12856
+ if (det === 0) return null;
12857
+ const tScaled = sz * (u * akz + v * bkz + w * ckz);
12858
+ if (det > 0 ? tScaled < 0 : tScaled > 0) return null;
12859
+ return this.at(tScaled / det, target);
12443
12860
  }
12444
12861
  /**
12445
12862
  * Transforms this ray with the given 4x4 transformation matrix.
@@ -12621,6 +13038,15 @@ class Mesh extends Object3D {
12621
13038
  }
12622
13039
  return target;
12623
13040
  }
13041
+ /**
13042
+ * Returns `true` if this mesh intersects the given frustum.
13043
+ *
13044
+ * @param {Frustum|FrustumArray} frustum - The frustum to test.
13045
+ * @return {boolean} Whether this mesh intersects the given frustum or not.
13046
+ */
13047
+ intersectsFrustum(frustum) {
13048
+ return frustum.intersectsObject(this);
13049
+ }
12624
13050
  /**
12625
13051
  * Computes intersection points between a casted ray and this line.
12626
13052
  *
@@ -13416,255 +13842,13 @@ class InstancedMesh extends Mesh {
13416
13842
  * method whenever this instance is no longer used in your app.
13417
13843
  */
13418
13844
  dispose() {
13419
- this.dispatchEvent({ type: "dispose" });
13845
+ super.dispose();
13420
13846
  if (this.morphTexture !== null) {
13421
13847
  this.morphTexture.dispose();
13422
13848
  this.morphTexture = null;
13423
13849
  }
13424
13850
  }
13425
13851
  }
13426
- const _vector1 = /* @__PURE__ */ new Vector3$1();
13427
- const _vector2 = /* @__PURE__ */ new Vector3$1();
13428
- const _normalMatrix = /* @__PURE__ */ new Matrix3$1();
13429
- class Plane {
13430
- /**
13431
- * Constructs a new plane.
13432
- *
13433
- * @param {Vector3} [normal=(1,0,0)] - A unit length vector defining the normal of the plane.
13434
- * @param {number} [constant=0] - The signed distance from the origin to the plane.
13435
- */
13436
- constructor(normal = new Vector3$1(1, 0, 0), constant = 0) {
13437
- this.isPlane = true;
13438
- this.normal = normal;
13439
- this.constant = constant;
13440
- }
13441
- /**
13442
- * Sets the plane components by copying the given values.
13443
- *
13444
- * @param {Vector3} normal - The normal.
13445
- * @param {number} constant - The constant.
13446
- * @return {Plane} A reference to this plane.
13447
- */
13448
- set(normal, constant) {
13449
- this.normal.copy(normal);
13450
- this.constant = constant;
13451
- return this;
13452
- }
13453
- /**
13454
- * Sets the plane components by defining `x`, `y`, `z` as the
13455
- * plane normal and `w` as the constant.
13456
- *
13457
- * @param {number} x - The value for the normal's x component.
13458
- * @param {number} y - The value for the normal's y component.
13459
- * @param {number} z - The value for the normal's z component.
13460
- * @param {number} w - The constant value.
13461
- * @return {Plane} A reference to this plane.
13462
- */
13463
- setComponents(x, y, z, w) {
13464
- this.normal.set(x, y, z);
13465
- this.constant = w;
13466
- return this;
13467
- }
13468
- /**
13469
- * Sets the plane from the given normal and coplanar point (that is a point
13470
- * that lies onto the plane).
13471
- *
13472
- * @param {Vector3} normal - The normal.
13473
- * @param {Vector3} point - A coplanar point.
13474
- * @return {Plane} A reference to this plane.
13475
- */
13476
- setFromNormalAndCoplanarPoint(normal, point) {
13477
- this.normal.copy(normal);
13478
- this.constant = -point.dot(this.normal);
13479
- return this;
13480
- }
13481
- /**
13482
- * Sets the plane from three coplanar points. The winding order is
13483
- * assumed to be counter-clockwise, and determines the direction of
13484
- * the plane normal.
13485
- *
13486
- * @param {Vector3} a - The first coplanar point.
13487
- * @param {Vector3} b - The second coplanar point.
13488
- * @param {Vector3} c - The third coplanar point.
13489
- * @return {Plane} A reference to this plane.
13490
- */
13491
- setFromCoplanarPoints(a, b, c) {
13492
- const normal = _vector1.subVectors(c, b).cross(_vector2.subVectors(a, b)).normalize();
13493
- this.setFromNormalAndCoplanarPoint(normal, a);
13494
- return this;
13495
- }
13496
- /**
13497
- * Copies the values of the given plane to this instance.
13498
- *
13499
- * @param {Plane} plane - The plane to copy.
13500
- * @return {Plane} A reference to this plane.
13501
- */
13502
- copy(plane) {
13503
- this.normal.copy(plane.normal);
13504
- this.constant = plane.constant;
13505
- return this;
13506
- }
13507
- /**
13508
- * Normalizes the plane normal and adjusts the constant accordingly.
13509
- *
13510
- * @return {Plane} A reference to this plane.
13511
- */
13512
- normalize() {
13513
- const inverseNormalLength = 1 / this.normal.length();
13514
- this.normal.multiplyScalar(inverseNormalLength);
13515
- this.constant *= inverseNormalLength;
13516
- return this;
13517
- }
13518
- /**
13519
- * Negates both the plane normal and the constant.
13520
- *
13521
- * @return {Plane} A reference to this plane.
13522
- */
13523
- negate() {
13524
- this.constant *= -1;
13525
- this.normal.negate();
13526
- return this;
13527
- }
13528
- /**
13529
- * Returns the signed distance from the given point to this plane.
13530
- *
13531
- * @param {Vector3} point - The point to compute the distance for.
13532
- * @return {number} The signed distance.
13533
- */
13534
- distanceToPoint(point) {
13535
- return this.normal.dot(point) + this.constant;
13536
- }
13537
- /**
13538
- * Returns the signed distance from the given sphere to this plane.
13539
- *
13540
- * @param {Sphere} sphere - The sphere to compute the distance for.
13541
- * @return {number} The signed distance.
13542
- */
13543
- distanceToSphere(sphere) {
13544
- return this.distanceToPoint(sphere.center) - sphere.radius;
13545
- }
13546
- /**
13547
- * Projects a the given point onto the plane.
13548
- *
13549
- * @param {Vector3} point - The point to project.
13550
- * @param {Vector3} target - The target vector that is used to store the method's result.
13551
- * @return {Vector3} The projected point on the plane.
13552
- */
13553
- projectPoint(point, target) {
13554
- return target.copy(point).addScaledVector(this.normal, -this.distanceToPoint(point));
13555
- }
13556
- /**
13557
- * Returns the intersection point of the passed line and the plane. Returns
13558
- * `null` if the line does not intersect. Returns the line's starting point if
13559
- * the line is coplanar with the plane.
13560
- *
13561
- * @param {Line3} line - The line to compute the intersection for.
13562
- * @param {Vector3} target - The target vector that is used to store the method's result.
13563
- * @param {boolean} [clampToLine=true] - Whether to clamp the intersection to the line segment.
13564
- * @return {?Vector3} The intersection point. Returns `null` if no intersection is detected.
13565
- */
13566
- intersectLine(line, target, clampToLine = true) {
13567
- const direction = line.delta(_vector1);
13568
- const denominator = this.normal.dot(direction);
13569
- if (denominator === 0) {
13570
- if (this.distanceToPoint(line.start) === 0) {
13571
- return target.copy(line.start);
13572
- }
13573
- return null;
13574
- }
13575
- const t = -(line.start.dot(this.normal) + this.constant) / denominator;
13576
- if (clampToLine === true && (t < 0 || t > 1)) {
13577
- return null;
13578
- }
13579
- return target.copy(line.start).addScaledVector(direction, t);
13580
- }
13581
- /**
13582
- * Returns `true` if the given line segment intersects with (passes through) the plane.
13583
- *
13584
- * @param {Line3} line - The line to test.
13585
- * @return {boolean} Whether the given line segment intersects with the plane or not.
13586
- */
13587
- intersectsLine(line) {
13588
- const startSign = this.distanceToPoint(line.start);
13589
- const endSign = this.distanceToPoint(line.end);
13590
- return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0;
13591
- }
13592
- /**
13593
- * Returns `true` if the given bounding box intersects with the plane.
13594
- *
13595
- * @param {Box3} box - The bounding box to test.
13596
- * @return {boolean} Whether the given bounding box intersects with the plane or not.
13597
- */
13598
- intersectsBox(box) {
13599
- return box.intersectsPlane(this);
13600
- }
13601
- /**
13602
- * Returns `true` if the given bounding sphere intersects with the plane.
13603
- *
13604
- * @param {Sphere} sphere - The bounding sphere to test.
13605
- * @return {boolean} Whether the given bounding sphere intersects with the plane or not.
13606
- */
13607
- intersectsSphere(sphere) {
13608
- return sphere.intersectsPlane(this);
13609
- }
13610
- /**
13611
- * Returns a coplanar vector to the plane, by calculating the
13612
- * projection of the normal at the origin onto the plane.
13613
- *
13614
- * @param {Vector3} target - The target vector that is used to store the method's result.
13615
- * @return {Vector3} The coplanar point.
13616
- */
13617
- coplanarPoint(target) {
13618
- return target.copy(this.normal).multiplyScalar(-this.constant);
13619
- }
13620
- /**
13621
- * Apply a 4x4 matrix to the plane. The matrix must be an affine, homogeneous transform.
13622
- *
13623
- * The optional normal matrix can be pre-computed like so:
13624
- * ```js
13625
- * const optionalNormalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
13626
- * ```
13627
- *
13628
- * @param {Matrix4} matrix - The transformation matrix.
13629
- * @param {Matrix4} [optionalNormalMatrix] - A pre-computed normal matrix.
13630
- * @return {Plane} A reference to this plane.
13631
- */
13632
- applyMatrix4(matrix, optionalNormalMatrix) {
13633
- const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix);
13634
- const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix);
13635
- const normal = this.normal.applyMatrix3(normalMatrix).normalize();
13636
- this.constant = -referencePoint.dot(normal);
13637
- return this;
13638
- }
13639
- /**
13640
- * Translates the plane by the distance defined by the given offset vector.
13641
- * Note that this only affects the plane constant and will not affect the normal vector.
13642
- *
13643
- * @param {Vector3} offset - The offset vector.
13644
- * @return {Plane} A reference to this plane.
13645
- */
13646
- translate(offset) {
13647
- this.constant -= offset.dot(this.normal);
13648
- return this;
13649
- }
13650
- /**
13651
- * Returns `true` if this plane is equal with the given one.
13652
- *
13653
- * @param {Plane} plane - The plane to test for equality.
13654
- * @return {boolean} Whether this plane is equal with the given one.
13655
- */
13656
- equals(plane) {
13657
- return plane.normal.equals(this.normal) && plane.constant === this.constant;
13658
- }
13659
- /**
13660
- * Returns a new plane with copied values from this instance.
13661
- *
13662
- * @return {Plane} A clone of this instance.
13663
- */
13664
- clone() {
13665
- return new this.constructor().copy(this);
13666
- }
13667
- }
13668
13852
  const _sphere$3 = /* @__PURE__ */ new Sphere();
13669
13853
  const _defaultSpriteCenter = /* @__PURE__ */ new Vector2(0.5, 0.5);
13670
13854
  const _vector$6 = /* @__PURE__ */ new Vector3$1();
@@ -13785,6 +13969,10 @@ class Frustum {
13785
13969
  /**
13786
13970
  * Returns `true` if the given bounding sphere is intersecting this frustum.
13787
13971
  *
13972
+ * This is a fast, conservative test that favors performance over precision. It can
13973
+ * report false positives for spheres that lie outside the frustum but are not separated
13974
+ * by a single frustum plane. It never reports false negatives, so it is safe for culling.
13975
+ *
13788
13976
  * @param {Sphere} sphere - The bounding sphere to test.
13789
13977
  * @return {boolean} Whether the bounding sphere is intersecting this frustum or not.
13790
13978
  */
@@ -13803,6 +13991,11 @@ class Frustum {
13803
13991
  /**
13804
13992
  * Returns `true` if the given bounding box is intersecting this frustum.
13805
13993
  *
13994
+ * This is a fast, conservative test that favors performance over precision. It can
13995
+ * report false positives for large boxes that lie outside the frustum but are not
13996
+ * separated by a single frustum plane. It never reports false negatives, so it is
13997
+ * safe for culling.
13998
+ *
13806
13999
  * @param {Box3} box - The bounding box to test.
13807
14000
  * @return {boolean} Whether the bounding box is intersecting this frustum or not.
13808
14001
  */
@@ -13930,6 +14123,15 @@ class Line extends Object3D {
13930
14123
  }
13931
14124
  return this;
13932
14125
  }
14126
+ /**
14127
+ * Returns `true` if this line intersects the given frustum.
14128
+ *
14129
+ * @param {Frustum|FrustumArray} frustum - The frustum to test.
14130
+ * @return {boolean} Whether this line intersects the given frustum or not.
14131
+ */
14132
+ intersectsFrustum(frustum) {
14133
+ return frustum.intersectsObject(this);
14134
+ }
13933
14135
  /**
13934
14136
  * Computes intersection points between a casted ray and this line.
13935
14137
  *
@@ -14138,6 +14340,15 @@ class Points extends Object3D {
14138
14340
  this.geometry = source.geometry;
14139
14341
  return this;
14140
14342
  }
14343
+ /**
14344
+ * Returns `true` if this point cloud intersects the given frustum.
14345
+ *
14346
+ * @param {Frustum|FrustumArray} frustum - The frustum to test.
14347
+ * @return {boolean} Whether this point cloud intersects the given frustum or not.
14348
+ */
14349
+ intersectsFrustum(frustum) {
14350
+ return frustum.intersectsObject(this);
14351
+ }
14141
14352
  /**
14142
14353
  * Computes intersection points between a casted ray and this point cloud.
14143
14354
  *
@@ -14266,6 +14477,17 @@ class CompressedArrayTexture extends CompressedTexture {
14266
14477
  this.wrapR = ClampToEdgeWrapping;
14267
14478
  this.layerUpdates = /* @__PURE__ */ new Set();
14268
14479
  }
14480
+ /**
14481
+ * Copies the values of the given texture to this instance.
14482
+ *
14483
+ * @param {CompressedArrayTexture} source - The texture to copy.
14484
+ * @return {CompressedArrayTexture} A reference to this instance.
14485
+ */
14486
+ copy(source) {
14487
+ super.copy(source);
14488
+ this.wrapR = source.wrapR;
14489
+ return this;
14490
+ }
14269
14491
  /**
14270
14492
  * Describes that a specific layer of the texture needs to be updated.
14271
14493
  * Normally when {@link Texture#needsUpdate} is set to `true`, the
@@ -14381,13 +14603,13 @@ class DepthTexture extends Texture {
14381
14603
  }
14382
14604
  copy(source) {
14383
14605
  super.copy(source);
14384
- this.source = new Source(Object.assign({}, source.image));
14606
+ this.source = new TextureSource(Object.assign({}, source.image));
14385
14607
  this.compareFunction = source.compareFunction;
14386
14608
  return this;
14387
14609
  }
14388
14610
  toJSON(meta) {
14389
14611
  const data = super.toJSON(meta);
14390
- if (this.compareFunction !== null) data.compareFunction = this.compareFunction;
14612
+ data.compareFunction = this.compareFunction;
14391
14613
  return data;
14392
14614
  }
14393
14615
  }
@@ -15011,6 +15233,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
15011
15233
  this._clearcoat = 0;
15012
15234
  this._dispersion = 0;
15013
15235
  this._iridescence = 0;
15236
+ this._retroreflectivity = 0;
15014
15237
  this._sheen = 0;
15015
15238
  this._transmission = 0;
15016
15239
  this.setValues(parameters);
@@ -15080,6 +15303,24 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
15080
15303
  }
15081
15304
  this._dispersion = value;
15082
15305
  }
15306
+ /**
15307
+ * The strength of retroreflection, from `0.0` to `1.0`. A value of `1.0`
15308
+ * evaluates the material's microfacet reflection with the view direction
15309
+ * reflected about the surface normal, redirecting the specular lobe back
15310
+ * toward the light source.
15311
+ *
15312
+ * @type {number}
15313
+ * @default 0
15314
+ */
15315
+ get retroreflectivity() {
15316
+ return this._retroreflectivity;
15317
+ }
15318
+ set retroreflectivity(value) {
15319
+ if (this._retroreflectivity > 0 !== value > 0) {
15320
+ this.version++;
15321
+ }
15322
+ this._retroreflectivity = value;
15323
+ }
15083
15324
  /**
15084
15325
  * The intensity of the sheen layer, from `0.0` to `1.0`.
15085
15326
  *
@@ -15138,6 +15379,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
15138
15379
  this.iridescenceIOR = source.iridescenceIOR;
15139
15380
  this.iridescenceThicknessRange = [...source.iridescenceThicknessRange];
15140
15381
  this.iridescenceThicknessMap = source.iridescenceThicknessMap;
15382
+ this.retroreflectivity = source.retroreflectivity;
15141
15383
  this.sheen = source.sheen;
15142
15384
  this.sheenColor.copy(source.sheenColor);
15143
15385
  this.sheenColorMap = source.sheenColorMap;
@@ -15231,6 +15473,9 @@ function convertArray(array, type) {
15231
15473
  }
15232
15474
  return Array.prototype.slice.call(array);
15233
15475
  }
15476
+ function hasTangents(settings) {
15477
+ return settings !== void 0 && settings.inTangents !== void 0 && settings.outTangents !== void 0;
15478
+ }
15234
15479
  function getKeyframeOrder(times) {
15235
15480
  function compareTime(i, j) {
15236
15481
  return times[i] - times[j];
@@ -15566,27 +15811,31 @@ class BezierInterpolant extends Interpolant {
15566
15811
  const inTangentOffset = i1 * tangentStride + i * 2;
15567
15812
  const c1x = inTangents[inTangentOffset];
15568
15813
  const c1y = inTangents[inTangentOffset + 1];
15569
- let s = (t - t0) / (t1 - t0);
15570
- let s2, s3, oneMinusS, oneMinusS2, oneMinusS3;
15571
- for (let iter = 0; iter < 8; iter++) {
15572
- s2 = s * s;
15573
- s3 = s2 * s;
15574
- oneMinusS = 1 - s;
15575
- oneMinusS2 = oneMinusS * oneMinusS;
15576
- oneMinusS3 = oneMinusS2 * oneMinusS;
15577
- const bx = oneMinusS3 * t0 + 3 * oneMinusS2 * s * c0x + 3 * oneMinusS * s2 * c1x + s3 * t1;
15578
- const error2 = bx - t;
15579
- if (Math.abs(error2) < 1e-10) break;
15580
- const dbx = 3 * oneMinusS2 * (c0x - t0) + 6 * oneMinusS * s * (c1x - c0x) + 3 * s2 * (t1 - c1x);
15581
- if (Math.abs(dbx) < 1e-10) break;
15582
- s = s - error2 / dbx;
15583
- s = Math.max(0, Math.min(1, s));
15584
- }
15585
- result[i] = oneMinusS3 * v0 + 3 * oneMinusS2 * s * c0y + 3 * oneMinusS * s2 * c1y + s3 * v1;
15814
+ const s = solveBezierParameter(t, t0, c0x, c1x, t1);
15815
+ result[i] = cubicBezier(s, v0, c0y, c1y, v1);
15586
15816
  }
15587
15817
  return result;
15588
15818
  }
15589
15819
  }
15820
+ function cubicBezier(s, p0, p1, p2, p3) {
15821
+ const k = 1 - s;
15822
+ return k * k * k * p0 + 3 * k * k * s * p1 + 3 * k * s * s * p2 + s * s * s * p3;
15823
+ }
15824
+ function cubicBezierSlope(s, p0, p1, p2, p3) {
15825
+ const k = 1 - s;
15826
+ return 3 * k * k * (p1 - p0) + 6 * k * s * (p2 - p1) + 3 * s * s * (p3 - p2);
15827
+ }
15828
+ function solveBezierParameter(x, x0, x1, x2, x3) {
15829
+ let s = (x - x0) / (x3 - x0);
15830
+ for (let i = 0; i < 8; i++) {
15831
+ const error2 = cubicBezier(s, x0, x1, x2, x3) - x;
15832
+ if (Math.abs(error2) < 1e-10) break;
15833
+ const slope = cubicBezierSlope(s, x0, x1, x2, x3);
15834
+ if (Math.abs(slope) < 1e-10) break;
15835
+ s = Math.max(0, Math.min(1, s - error2 / slope));
15836
+ }
15837
+ return s;
15838
+ }
15590
15839
  class KeyframeTrack {
15591
15840
  /**
15592
15841
  * Constructs a new keyframe track.
@@ -15626,6 +15875,12 @@ class KeyframeTrack {
15626
15875
  if (interpolation !== track.DefaultInterpolation) {
15627
15876
  json.interpolation = interpolation;
15628
15877
  }
15878
+ if (hasTangents(track.settings)) {
15879
+ json.settings = {
15880
+ inTangents: convertArray(track.settings.inTangents, Array),
15881
+ outTangents: convertArray(track.settings.outTangents, Array)
15882
+ };
15883
+ }
15629
15884
  }
15630
15885
  json.type = track.ValueTypeName;
15631
15886
  return json;
@@ -15769,6 +16024,10 @@ class KeyframeTrack {
15769
16024
  for (let i = 0, n = times.length; i !== n; ++i) {
15770
16025
  times[i] *= timeScale;
15771
16026
  }
16027
+ if (hasTangents(this.settings)) {
16028
+ scaleTangentTimes(this.settings.inTangents, timeScale);
16029
+ scaleTangentTimes(this.settings.outTangents, timeScale);
16030
+ }
15772
16031
  }
15773
16032
  return this;
15774
16033
  }
@@ -15915,9 +16174,20 @@ class KeyframeTrack {
15915
16174
  const TypedKeyframeTrack = this.constructor;
15916
16175
  const track = new TypedKeyframeTrack(this.name, times, values);
15917
16176
  track.createInterpolant = this.createInterpolant;
16177
+ if (hasTangents(this.settings)) {
16178
+ track.settings = {
16179
+ inTangents: this.settings.inTangents.slice(),
16180
+ outTangents: this.settings.outTangents.slice()
16181
+ };
16182
+ }
15918
16183
  return track;
15919
16184
  }
15920
16185
  }
16186
+ function scaleTangentTimes(tangents, timeScale) {
16187
+ for (let i = 0, n = tangents.length; i !== n; i += 2) {
16188
+ tangents[i] *= timeScale;
16189
+ }
16190
+ }
15921
16191
  KeyframeTrack.prototype.ValueTypeName = "";
15922
16192
  KeyframeTrack.prototype.TimeBufferType = Float32Array;
15923
16193
  KeyframeTrack.prototype.ValueBufferType = Float32Array;
@@ -16325,11 +16595,19 @@ function parseKeyframeTrack(json) {
16325
16595
  json.times = times;
16326
16596
  json.values = values;
16327
16597
  }
16598
+ let track;
16328
16599
  if (trackType.parse !== void 0) {
16329
- return trackType.parse(json);
16600
+ track = trackType.parse(json);
16330
16601
  } else {
16331
- return new trackType(json.name, json.times, json.values, json.interpolation);
16602
+ track = new trackType(json.name, json.times, json.values, json.interpolation);
16332
16603
  }
16604
+ if (hasTangents(json.settings)) {
16605
+ track.settings = {
16606
+ inTangents: convertArray(json.settings.inTangents, Float32Array),
16607
+ outTangents: convertArray(json.settings.outTangents, Float32Array)
16608
+ };
16609
+ }
16610
+ return track;
16333
16611
  }
16334
16612
  const Cache = {
16335
16613
  /**
@@ -17036,13 +17314,6 @@ class Light extends Object3D {
17036
17314
  this.color = new Color(color);
17037
17315
  this.intensity = intensity;
17038
17316
  }
17039
- /**
17040
- * Frees the GPU-related resources allocated by this instance. Call this
17041
- * method whenever this instance is no longer used in your app.
17042
- */
17043
- dispose() {
17044
- this.dispatchEvent({ type: "dispose" });
17045
- }
17046
17317
  copy(source, recursive) {
17047
17318
  super.copy(source, recursive);
17048
17319
  this.color.copy(source.color);
@@ -17096,6 +17367,15 @@ class LightShadow {
17096
17367
  getViewportCount() {
17097
17368
  return this._viewportCount;
17098
17369
  }
17370
+ /**
17371
+ * Used internally by the renderer to get the camera that renders the given viewport.
17372
+ *
17373
+ * @param {number} [viewportIndex=0] - The viewport index.
17374
+ * @return {Camera} The shadow camera.
17375
+ */
17376
+ getCamera() {
17377
+ return this.camera;
17378
+ }
17099
17379
  /**
17100
17380
  * Gets the shadow cameras frustum. Used internally by the renderer to cull objects.
17101
17381
  *
@@ -17111,24 +17391,40 @@ class LightShadow {
17111
17391
  */
17112
17392
  updateMatrices(light) {
17113
17393
  const shadowCamera = this.camera;
17114
- const shadowMatrix = this.matrix;
17115
17394
  _lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld);
17116
17395
  shadowCamera.position.copy(_lightPositionWorld$1);
17117
17396
  _lookTarget$1.setFromMatrixPosition(light.target.matrixWorld);
17118
17397
  shadowCamera.lookAt(_lookTarget$1);
17119
17398
  shadowCamera.updateMatrixWorld();
17399
+ this._updateMatrix(shadowCamera, this.matrix, this._frustum);
17400
+ }
17401
+ /**
17402
+ * Updates a shadow projection matrix and its corresponding frustum.
17403
+ *
17404
+ * @private
17405
+ * @param {Camera} shadowCamera - The shadow camera.
17406
+ * @param {Matrix4} shadowMatrix - The target shadow matrix.
17407
+ * @param {Frustum} frustum - The target frustum.
17408
+ * @param {Vector4} [viewport] - The viewport within the shadow atlas.
17409
+ */
17410
+ _updateMatrix(shadowCamera, shadowMatrix, frustum, viewport) {
17120
17411
  _projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse);
17121
- this._frustum.setFromProjectionMatrix(_projScreenMatrix$1, shadowCamera.coordinateSystem, shadowCamera.reversedDepth);
17412
+ frustum.setFromProjectionMatrix(_projScreenMatrix$1, shadowCamera.coordinateSystem, shadowCamera.reversedDepth);
17413
+ const frameExtents = this._frameExtents;
17414
+ const scaleX = viewport ? viewport.z / frameExtents.x : 1;
17415
+ const scaleY = viewport ? viewport.w / frameExtents.y : 1;
17416
+ const offsetX = viewport ? viewport.x / frameExtents.x : 0;
17417
+ const offsetY = viewport ? viewport.y / frameExtents.y : 0;
17122
17418
  if (shadowCamera.coordinateSystem === WebGPUCoordinateSystem || shadowCamera.reversedDepth) {
17123
17419
  shadowMatrix.set(
17124
- 0.5,
17420
+ 0.5 * scaleX,
17125
17421
  0,
17126
17422
  0,
17127
- 0.5,
17423
+ 0.5 * scaleX + offsetX,
17128
17424
  0,
17129
- 0.5,
17425
+ 0.5 * scaleY,
17130
17426
  0,
17131
- 0.5,
17427
+ 0.5 * scaleY + offsetY,
17132
17428
  0,
17133
17429
  0,
17134
17430
  1,
@@ -17141,14 +17437,14 @@ class LightShadow {
17141
17437
  );
17142
17438
  } else {
17143
17439
  shadowMatrix.set(
17144
- 0.5,
17440
+ 0.5 * scaleX,
17145
17441
  0,
17146
17442
  0,
17147
- 0.5,
17443
+ 0.5 * scaleX + offsetX,
17148
17444
  0,
17149
- 0.5,
17445
+ 0.5 * scaleY,
17150
17446
  0,
17151
- 0.5,
17447
+ 0.5 * scaleY + offsetY,
17152
17448
  0,
17153
17449
  0,
17154
17450
  0.5,
@@ -17225,11 +17521,12 @@ class LightShadow {
17225
17521
  */
17226
17522
  toJSON() {
17227
17523
  const object = {};
17228
- if (this.intensity !== 1) object.intensity = this.intensity;
17229
- if (this.bias !== 0) object.bias = this.bias;
17230
- if (this.normalBias !== 0) object.normalBias = this.normalBias;
17231
- if (this.radius !== 1) object.radius = this.radius;
17232
- if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray();
17524
+ object.intensity = this.intensity;
17525
+ object.bias = this.bias;
17526
+ object.normalBias = this.normalBias;
17527
+ object.radius = this.radius;
17528
+ object.blurSamples = this.blurSamples;
17529
+ object.mapSize = this.mapSize.toArray();
17233
17530
  object.camera = this.camera.toJSON(false).object;
17234
17531
  delete object.camera.matrix;
17235
17532
  return object;
@@ -17556,8 +17853,21 @@ class SpotLightShadow extends LightShadow {
17556
17853
  copy(source) {
17557
17854
  super.copy(source);
17558
17855
  this.focus = source.focus;
17856
+ this.aspect = source.aspect;
17559
17857
  return this;
17560
17858
  }
17859
+ /**
17860
+ * Serializes the light shadow into JSON.
17861
+ *
17862
+ * @return {Object} A JSON object representing the serialized light shadow.
17863
+ * @see {@link ObjectLoader#parse}
17864
+ */
17865
+ toJSON() {
17866
+ const object = super.toJSON();
17867
+ object.focus = this.focus;
17868
+ object.aspect = this.aspect;
17869
+ return object;
17870
+ }
17561
17871
  }
17562
17872
  class SpotLight extends Light {
17563
17873
  /**
@@ -17967,11 +18277,12 @@ class ImageBitmapLoader extends Loader {
17967
18277
  const promise = fetch(url, fetchOptions).then(function(res) {
17968
18278
  return res.blob();
17969
18279
  }).then(function(blob) {
17970
- return createImageBitmap(blob, Object.assign(scope.options, { colorSpaceConversion: "none" }));
18280
+ return createImageBitmap(blob, Object.assign({}, scope.options, { colorSpaceConversion: "none" }));
17971
18281
  }).then(function(imageBitmap) {
17972
18282
  Cache.add(`image-bitmap:${url}`, imageBitmap);
17973
18283
  if (onLoad) onLoad(imageBitmap);
17974
18284
  scope.manager.itemEnd(url);
18285
+ return imageBitmap;
17975
18286
  }).catch(function(e) {
17976
18287
  if (onError) onError(e);
17977
18288
  _errorMap.set(promise, e);
@@ -18135,6 +18446,120 @@ class ArrayCamera extends PerspectiveCamera {
18135
18446
  this.cameras = array;
18136
18447
  }
18137
18448
  }
18449
+ class Timer {
18450
+ /**
18451
+ * Constructs a new timer.
18452
+ */
18453
+ constructor() {
18454
+ this._previousTime = 0;
18455
+ this._currentTime = 0;
18456
+ this._startTime = performance.now();
18457
+ this._delta = 0;
18458
+ this._elapsed = 0;
18459
+ this._timescale = 1;
18460
+ this._document = null;
18461
+ this._pageVisibilityHandler = null;
18462
+ }
18463
+ /**
18464
+ * Connect the timer to the given document.Calling this method is not mandatory to
18465
+ * use the timer but enables the usage of the Page Visibility API to avoid large time
18466
+ * delta values.
18467
+ *
18468
+ * @param {Document} document - The document.
18469
+ */
18470
+ connect(document2) {
18471
+ this._document = document2;
18472
+ if (document2.hidden !== void 0) {
18473
+ this._pageVisibilityHandler = handleVisibilityChange.bind(this);
18474
+ document2.addEventListener("visibilitychange", this._pageVisibilityHandler, false);
18475
+ }
18476
+ }
18477
+ /**
18478
+ * Disconnects the timer from the DOM and also disables the usage of the Page Visibility API.
18479
+ */
18480
+ disconnect() {
18481
+ if (this._pageVisibilityHandler !== null) {
18482
+ this._document.removeEventListener("visibilitychange", this._pageVisibilityHandler);
18483
+ this._pageVisibilityHandler = null;
18484
+ }
18485
+ this._document = null;
18486
+ }
18487
+ /**
18488
+ * Returns the time delta in seconds.
18489
+ *
18490
+ * @return {number} The time delta in second.
18491
+ */
18492
+ getDelta() {
18493
+ return this._delta / 1e3;
18494
+ }
18495
+ /**
18496
+ * Returns the elapsed time in seconds.
18497
+ *
18498
+ * @return {number} The elapsed time in second.
18499
+ */
18500
+ getElapsed() {
18501
+ return this._elapsed / 1e3;
18502
+ }
18503
+ /**
18504
+ * Returns the timescale.
18505
+ *
18506
+ * @return {number} The timescale.
18507
+ */
18508
+ getTimescale() {
18509
+ return this._timescale;
18510
+ }
18511
+ /**
18512
+ * Sets the given timescale which scale the time delta computation
18513
+ * in `update()`.
18514
+ *
18515
+ * @param {number} timescale - The timescale to set.
18516
+ * @return {Timer} A reference to this timer.
18517
+ */
18518
+ setTimescale(timescale) {
18519
+ this._timescale = timescale;
18520
+ return this;
18521
+ }
18522
+ /**
18523
+ * Resets the time computation for the current simulation step.
18524
+ *
18525
+ * @return {Timer} A reference to this timer.
18526
+ */
18527
+ reset() {
18528
+ this._currentTime = performance.now() - this._startTime;
18529
+ return this;
18530
+ }
18531
+ /**
18532
+ * Can be used to free all internal resources. Usually called when
18533
+ * the timer instance isn't required anymore.
18534
+ */
18535
+ dispose() {
18536
+ this.disconnect();
18537
+ }
18538
+ /**
18539
+ * Updates the internal state of the timer. This method should be called
18540
+ * once per simulation step and before you perform queries against the timer
18541
+ * (e.g. via `getDelta()`).
18542
+ *
18543
+ * @param {number} timestamp - The current time in milliseconds. Can be obtained
18544
+ * from the `requestAnimationFrame` callback argument. If not provided, the current
18545
+ * time will be determined with `performance.now`.
18546
+ * @return {Timer} A reference to this timer.
18547
+ */
18548
+ update(timestamp) {
18549
+ if (this._pageVisibilityHandler !== null && this._document.hidden === true) {
18550
+ this._delta = 0;
18551
+ } else {
18552
+ this._previousTime = this._currentTime;
18553
+ this._currentTime = (timestamp !== void 0 ? timestamp : performance.now()) - this._startTime;
18554
+ this._delta = (this._currentTime - this._previousTime) * this._timescale;
18555
+ this._elapsed += this._delta;
18556
+ }
18557
+ return this;
18558
+ }
18559
+ }
18560
+ function handleVisibilityChange() {
18561
+ if (this._document.hidden === false) this.reset();
18562
+ }
18138
18563
  const _RESERVED_CHARS_RE = "\\[\\]\\.:\\/";
18139
18564
  const _reservedRe = new RegExp("[" + _RESERVED_CHARS_RE + "]", "g");
18140
18565
  const _wordChar = "[^" + _RESERVED_CHARS_RE + "]";
@@ -18654,6 +19079,10 @@ class Raycaster {
18654
19079
  * be detected. To raycast against both faces of an object, you'll want to set {@link Material#side}
18655
19080
  * to `THREE.DoubleSide`.
18656
19081
  *
19082
+ * Note that a ray hitting a triangle mesh exactly along an edge shared by two faces may be
19083
+ * reported by both faces, resulting in two coincident intersections (identical point and
19084
+ * distance) in the returned array.
19085
+ *
18657
19086
  * @param {Object3D} object - The 3D object to check for intersection with the ray.
18658
19087
  * @param {boolean} [recursive=true] - If set to `true`, it also checks all descendants.
18659
19088
  * Otherwise it only checks intersection with the object.
@@ -19398,8 +19827,8 @@ function WebGLAnimation() {
19398
19827
  let animationLoop = null;
19399
19828
  let requestId = null;
19400
19829
  function onAnimationFrame(time, frame) {
19401
- animationLoop(time, frame);
19402
19830
  requestId = context.requestAnimationFrame(onAnimationFrame);
19831
+ animationLoop(time, frame);
19403
19832
  }
19404
19833
  return {
19405
19834
  start: function() {
@@ -19590,16 +20019,16 @@ var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n uniform sampler2D grad
19590
20019
  var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n uniform sampler2D lightMap;\n uniform float lightMapIntensity;\n#endif";
19591
20020
  var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;";
19592
20021
  var lights_lambert_pars_fragment = "varying vec3 vViewPosition;\nstruct LambertMaterial {\n vec3 diffuseColor;\n float specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_Lambert\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Lambert";
19593
- var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n uniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n float x = normal.x, y = normal.y, z = normal.z;\n vec3 result = shCoefficients[ 0 ] * 0.886227;\n result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n return result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n vec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix );\n vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n return irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n vec3 irradiance = ambientLightColor;\n return irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n if ( cutoffDistance > 0.0 ) {\n distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n }\n return distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n return smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n struct DirectionalLight {\n vec3 direction;\n vec3 color;\n };\n uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n void getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n light.color = directionalLight.color;\n light.direction = directionalLight.direction;\n light.visible = true;\n }\n#endif\n#if NUM_POINT_LIGHTS > 0\n struct PointLight {\n vec3 position;\n vec3 color;\n float distance;\n float decay;\n };\n uniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n void getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = pointLight.position - geometryPosition;\n light.direction = normalize( lVector );\n float lightDistance = length( lVector );\n light.color = pointLight.color;\n light.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n }\n#endif\n#if NUM_SPOT_LIGHTS > 0\n struct SpotLight {\n vec3 position;\n vec3 direction;\n vec3 color;\n float distance;\n float decay;\n float coneCos;\n float penumbraCos;\n };\n uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n void getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = spotLight.position - geometryPosition;\n light.direction = normalize( lVector );\n float angleCos = dot( light.direction, spotLight.direction );\n float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n if ( spotAttenuation > 0.0 ) {\n float lightDistance = length( lVector );\n light.color = spotLight.color * spotAttenuation;\n light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n } else {\n light.color = vec3( 0.0 );\n light.visible = false;\n }\n }\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n struct RectAreaLight {\n vec3 color;\n vec3 position;\n vec3 halfWidth;\n vec3 halfHeight;\n };\n uniform sampler2D ltc_1; uniform sampler2D ltc_2;\n uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n struct HemisphereLight {\n vec3 direction;\n vec3 skyColor;\n vec3 groundColor;\n };\n uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n float dotNL = dot( normal, hemiLight.direction );\n float hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n return irradiance;\n }\n#endif\n#include <lightprobes_pars_fragment>";
19594
- var envmap_physical_pars_fragment = "#ifdef USE_ENVMAP\n vec3 getIBLIrradiance( const in vec3 normal ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n return PI * envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 reflectVec = reflect( - viewDir, normal );\n reflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) );\n reflectVec = transformDirectionByInverseViewMatrix( reflectVec, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n return envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n #ifdef USE_ANISOTROPY\n vec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 bentNormal = cross( bitangent, viewDir );\n bentNormal = normalize( cross( bentNormal, bitangent ) );\n bentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n return getIBLRadiance( viewDir, bentNormal, roughness );\n #else\n return vec3( 0.0 );\n #endif\n }\n #endif\n#endif";
20022
+ var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n uniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n float x = normal.x, y = normal.y, z = normal.z;\n vec3 result = shCoefficients[ 0 ] * 0.886227;\n result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n return result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n vec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix );\n vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n return irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n vec3 irradiance = ambientLightColor;\n return irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n if ( cutoffDistance > 0.0 ) {\n distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n }\n return distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n return smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_SUN_LIGHTS > 0\n struct SunLight {\n vec3 direction;\n vec3 color;\n };\n uniform SunLight sunLights[ NUM_SUN_LIGHTS ];\n void getSunLightInfo( const in SunLight sunLight, out IncidentLight light ) {\n light.color = sunLight.color;\n light.direction = sunLight.direction;\n light.visible = true;\n }\n#endif\n#if NUM_DIR_LIGHTS > 0\n struct DirectionalLight {\n vec3 direction;\n vec3 color;\n };\n uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n void getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n light.color = directionalLight.color;\n light.direction = directionalLight.direction;\n light.visible = true;\n }\n#endif\n#if NUM_POINT_LIGHTS > 0\n struct PointLight {\n vec3 position;\n vec3 color;\n float distance;\n float decay;\n };\n uniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n void getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = pointLight.position - geometryPosition;\n light.direction = normalize( lVector );\n float lightDistance = length( lVector );\n light.color = pointLight.color;\n light.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n }\n#endif\n#if NUM_SPOT_LIGHTS > 0\n struct SpotLight {\n vec3 position;\n vec3 direction;\n vec3 color;\n float distance;\n float decay;\n float coneCos;\n float penumbraCos;\n };\n uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n void getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = spotLight.position - geometryPosition;\n light.direction = normalize( lVector );\n float angleCos = dot( light.direction, spotLight.direction );\n float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n if ( spotAttenuation > 0.0 ) {\n float lightDistance = length( lVector );\n light.color = spotLight.color * spotAttenuation;\n light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n } else {\n light.color = vec3( 0.0 );\n light.visible = false;\n }\n }\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n struct RectAreaLight {\n vec3 color;\n vec3 position;\n vec3 halfWidth;\n vec3 halfHeight;\n };\n uniform sampler2D ltc_1; uniform sampler2D ltc_2;\n uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n struct HemisphereLight {\n vec3 direction;\n vec3 skyColor;\n vec3 groundColor;\n };\n uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n float dotNL = dot( normal, hemiLight.direction );\n float hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n return irradiance;\n }\n#endif\n#include <lightprobes_pars_fragment>";
20023
+ var envmap_physical_pars_fragment = "#ifdef USE_ENVMAP\n vec3 getIBLIrradiance( const in vec3 normal ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n return PI * envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 reflectVec = reflect( - viewDir, normal );\n reflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) );\n reflectVec = transformDirectionByInverseViewMatrix( reflectVec, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n return envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n #ifdef USE_RETROREFLECTION\n vec3 getIBLRetroRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 retroVec = normalize( mix( viewDir, normal, pow4( roughness ) ) );\n retroVec = transformDirectionByInverseViewMatrix( retroVec, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, envMapRotation * retroVec, roughness );\n return envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n #endif\n #ifdef USE_ANISOTROPY\n vec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 bentNormal = cross( bitangent, viewDir );\n bentNormal = normalize( cross( bentNormal, bitangent ) );\n bentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n return getIBLRadiance( viewDir, bentNormal, roughness );\n #else\n return vec3( 0.0 );\n #endif\n }\n #ifdef USE_RETROREFLECTION\n vec3 getIBLAnisotropyRetroRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 bentNormal = cross( bitangent, viewDir );\n bentNormal = normalize( cross( bentNormal, bitangent ) );\n bentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n return getIBLRetroRadiance( viewDir, bentNormal, roughness );\n #else\n return vec3( 0.0 );\n #endif\n }\n #endif\n #endif\n#endif";
19595
20024
  var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;";
19596
20025
  var lights_toon_pars_fragment = "varying vec3 vViewPosition;\nstruct ToonMaterial {\n vec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_Toon\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Toon";
19597
20026
  var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;";
19598
20027
  var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n vec3 diffuseColor;\n vec3 specularColor;\n float specularShininess;\n float specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_BlinnPhong\n#define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong";
19599
- var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.diffuseContribution = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.metalness = metalnessFactor;\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n material.ior = ior;\n #ifdef USE_SPECULAR\n float specularIntensityFactor = specularIntensity;\n vec3 specularColorFactor = specularColor;\n #ifdef USE_SPECULAR_COLORMAP\n specularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n #endif\n #ifdef USE_SPECULAR_INTENSITYMAP\n specularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n #endif\n material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n #else\n float specularIntensityFactor = 1.0;\n vec3 specularColorFactor = vec3( 1.0 );\n material.specularF90 = 1.0;\n #endif\n material.specularColor = min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor;\n material.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n#else\n material.specularColor = vec3( 0.04 );\n material.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n material.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n material.clearcoat = clearcoat;\n material.clearcoatRoughness = clearcoatRoughness;\n material.clearcoatF0 = vec3( 0.04 );\n material.clearcoatF90 = 1.0;\n #ifdef USE_CLEARCOATMAP\n material.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n #endif\n #ifdef USE_CLEARCOAT_ROUGHNESSMAP\n material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n #endif\n material.clearcoat = saturate( material.clearcoat ); material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n material.clearcoatRoughness += geometryRoughness;\n material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n material.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n material.iridescence = iridescence;\n material.iridescenceIOR = iridescenceIOR;\n #ifdef USE_IRIDESCENCEMAP\n material.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n #endif\n #ifdef USE_IRIDESCENCE_THICKNESSMAP\n material.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n #else\n material.iridescenceThickness = iridescenceThicknessMaximum;\n #endif\n#endif\n#ifdef USE_SHEEN\n material.sheenColor = sheenColor;\n #ifdef USE_SHEEN_COLORMAP\n material.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n #endif\n material.sheenRoughness = clamp( sheenRoughness, 0.0001, 1.0 );\n #ifdef USE_SHEEN_ROUGHNESSMAP\n material.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n #endif\n#endif\n#ifdef USE_ANISOTROPY\n #ifdef USE_ANISOTROPYMAP\n mat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n vec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n vec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n #else\n vec2 anisotropyV = anisotropyVector;\n #endif\n material.anisotropy = length( anisotropyV );\n if( material.anisotropy == 0.0 ) {\n anisotropyV = vec2( 1.0, 0.0 );\n } else {\n anisotropyV /= material.anisotropy;\n material.anisotropy = saturate( material.anisotropy );\n }\n material.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n material.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n material.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif";
19600
- var lights_physical_pars_fragment = "uniform sampler2D dfgLUT;\nstruct PhysicalMaterial {\n vec3 diffuseColor;\n vec3 diffuseContribution;\n vec3 specularColor;\n vec3 specularColorBlended;\n float roughness;\n float metalness;\n float specularF90;\n float dispersion;\n #ifdef USE_CLEARCOAT\n float clearcoat;\n float clearcoatRoughness;\n vec3 clearcoatF0;\n float clearcoatF90;\n #endif\n #ifdef USE_IRIDESCENCE\n float iridescence;\n float iridescenceIOR;\n float iridescenceThickness;\n vec3 iridescenceFresnel;\n vec3 iridescenceF0;\n vec3 iridescenceFresnelDielectric;\n vec3 iridescenceFresnelMetallic;\n #endif\n #ifdef USE_SHEEN\n vec3 sheenColor;\n float sheenRoughness;\n #endif\n #ifdef IOR\n float ior;\n #endif\n #ifdef USE_TRANSMISSION\n float transmission;\n float transmissionAlpha;\n float thickness;\n float attenuationDistance;\n vec3 attenuationColor;\n #endif\n #ifdef USE_ANISOTROPY\n float anisotropy;\n float alphaT;\n vec3 anisotropyT;\n vec3 anisotropyB;\n #endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n float a2 = pow2( alpha );\n float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n return 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n float a2 = pow2( alpha );\n float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n return RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n float V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n float gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n float gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n return 0.5 / max( gv + gl, EPSILON );\n }\n float D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n float a2 = alphaT * alphaB;\n highp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n highp float v2 = dot( v, v );\n float w2 = a2 / v2;\n return RECIPROCAL_PI * a2 * pow2 ( w2 );\n }\n#endif\n#ifdef USE_CLEARCOAT\n vec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n vec3 f0 = material.clearcoatF0;\n float f90 = material.clearcoatF90;\n float roughness = material.clearcoatRoughness;\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotVH = saturate( dot( viewDir, halfDir ) );\n vec3 F = F_Schlick( f0, f90, dotVH );\n float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n return F * ( V * D );\n }\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n vec3 f0 = material.specularColorBlended;\n float f90 = material.specularF90;\n float roughness = material.roughness;\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotVH = saturate( dot( viewDir, halfDir ) );\n vec3 F = F_Schlick( f0, f90, dotVH );\n #ifdef USE_IRIDESCENCE\n F = mix( F, material.iridescenceFresnel, material.iridescence );\n #endif\n #ifdef USE_ANISOTROPY\n float dotTL = dot( material.anisotropyT, lightDir );\n float dotTV = dot( material.anisotropyT, viewDir );\n float dotTH = dot( material.anisotropyT, halfDir );\n float dotBL = dot( material.anisotropyB, lightDir );\n float dotBV = dot( material.anisotropyB, viewDir );\n float dotBH = dot( material.anisotropyB, halfDir );\n float V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n float D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n #else\n float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n #endif\n return F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n const float LUT_SIZE = 64.0;\n const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n const float LUT_BIAS = 0.5 / LUT_SIZE;\n float dotNV = saturate( dot( N, V ) );\n vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n uv = uv * LUT_SCALE + LUT_BIAS;\n return uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n float l = length( f );\n return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n float x = dot( v1, v2 );\n float y = abs( x );\n float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n float b = 3.4175940 + ( 4.1616724 + y ) * y;\n float v = a / b;\n float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n return cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n vec3 lightNormal = cross( v1, v2 );\n if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n vec3 T1, T2;\n T1 = normalize( V - N * dot( V, N ) );\n T2 = - cross( N, T1 );\n mat3 mat = mInv * transpose( mat3( T1, T2, N ) );\n vec3 coords[ 4 ];\n coords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n coords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n coords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n coords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n coords[ 0 ] = normalize( coords[ 0 ] );\n coords[ 1 ] = normalize( coords[ 1 ] );\n coords[ 2 ] = normalize( coords[ 2 ] );\n coords[ 3 ] = normalize( coords[ 3 ] );\n vec3 vectorFormFactor = vec3( 0.0 );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n float result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n return vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n float alpha = pow2( roughness );\n float invAlpha = 1.0 / alpha;\n float cos2h = dotNH * dotNH;\n float sin2h = max( 1.0 - cos2h, 0.0078125 );\n return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float D = D_Charlie( sheenRoughness, dotNH );\n float V = V_Neubelt( dotNV, dotNL );\n return sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n float dotNV = saturate( dot( normal, viewDir ) );\n float r2 = roughness * roughness;\n float rInv = 1.0 / ( roughness + 0.1 );\n float a = -1.9362 + 1.0678 * roughness + 0.4573 * r2 - 0.8469 * rInv;\n float b = -0.6014 + 0.5538 * roughness - 0.4670 * r2 - 0.1255 * rInv;\n float DG = exp( a * dotNV + b );\n return saturate( DG );\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n float dotNV = saturate( dot( normal, viewDir ) );\n vec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\n return specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n float dotNV = saturate( dot( normal, viewDir ) );\n vec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\n #ifdef USE_IRIDESCENCE\n vec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n #else\n vec3 Fr = specularColor;\n #endif\n vec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n float Ess = fab.x + fab.y;\n float Ems = 1.0 - Ess;\n vec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n singleScatter += FssEss;\n multiScatter += Fms * Ems;\n}\nvec3 BRDF_GGX_Multiscatter( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n vec3 singleScatter = BRDF_GGX( lightDir, viewDir, normal, material );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n vec2 dfgV = texture2D( dfgLUT, vec2( material.roughness, dotNV ) ).rg;\n vec2 dfgL = texture2D( dfgLUT, vec2( material.roughness, dotNL ) ).rg;\n vec3 FssEss_V = material.specularColorBlended * dfgV.x + material.specularF90 * dfgV.y;\n vec3 FssEss_L = material.specularColorBlended * dfgL.x + material.specularF90 * dfgL.y;\n float Ess_V = dfgV.x + dfgV.y;\n float Ess_L = dfgL.x + dfgL.y;\n float Ems_V = 1.0 - Ess_V;\n float Ems_L = 1.0 - Ess_L;\n vec3 Favg = material.specularColorBlended + ( 1.0 - material.specularColorBlended ) * 0.047619;\n vec3 Fms = FssEss_V * FssEss_L * Favg / ( 1.0 - Ems_V * Ems_L * Favg + EPSILON );\n float compensationFactor = Ems_V * Ems_L;\n vec3 multiScatter = Fms * compensationFactor;\n return singleScatter + multiScatter;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 normal = geometryNormal;\n vec3 viewDir = geometryViewDir;\n vec3 position = geometryPosition;\n vec3 lightPos = rectAreaLight.position;\n vec3 halfWidth = rectAreaLight.halfWidth;\n vec3 halfHeight = rectAreaLight.halfHeight;\n vec3 lightColor = rectAreaLight.color;\n float roughness = material.roughness;\n vec3 rectCoords[ 4 ];\n rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; rectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n rectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n rectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n vec2 uv = LTC_Uv( normal, viewDir, roughness );\n vec4 t1 = texture2D( ltc_1, uv );\n vec4 t2 = texture2D( ltc_2, uv );\n mat3 mInv = mat3(\n vec3( t1.x, 0, t1.y ),\n vec3( 0, 1, 0 ),\n vec3( t1.z, 0, t1.w )\n );\n vec3 fresnel = ( material.specularColorBlended * t2.x + ( material.specularF90 - material.specularColorBlended ) * t2.y );\n reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n reflectedLight.directDiffuse += lightColor * material.diffuseContribution * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n #ifdef USE_CLEARCOAT\n vec3 Ncc = geometryClearcoatNormal;\n vec2 uvClearcoat = LTC_Uv( Ncc, viewDir, material.clearcoatRoughness );\n vec4 t1Clearcoat = texture2D( ltc_1, uvClearcoat );\n vec4 t2Clearcoat = texture2D( ltc_2, uvClearcoat );\n mat3 mInvClearcoat = mat3(\n vec3( t1Clearcoat.x, 0, t1Clearcoat.y ),\n vec3( 0, 1, 0 ),\n vec3( t1Clearcoat.z, 0, t1Clearcoat.w )\n );\n vec3 fresnelClearcoat = material.clearcoatF0 * t2Clearcoat.x + ( material.clearcoatF90 - material.clearcoatF0 ) * t2Clearcoat.y;\n clearcoatSpecularDirect += lightColor * fresnelClearcoat * LTC_Evaluate( Ncc, viewDir, position, mInvClearcoat, rectCoords );\n #endif\n }\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n #ifdef USE_CLEARCOAT\n float dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n vec3 ccIrradiance = dotNLcc * directLight.color;\n clearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n #endif\n #ifdef USE_SHEEN\n \n sheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n \n float sheenAlbedoV = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n float sheenAlbedoL = IBLSheenBRDF( geometryNormal, directLight.direction, material.sheenRoughness );\n \n float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * max( sheenAlbedoV, sheenAlbedoL );\n \n irradiance *= sheenEnergyComp;\n \n #endif\n reflectedLight.directSpecular += irradiance * BRDF_GGX_Multiscatter( directLight.direction, geometryViewDir, geometryNormal, material );\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseContribution );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 diffuse = irradiance * BRDF_Lambert( material.diffuseContribution );\n #ifdef USE_SHEEN\n float sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n diffuse *= sheenEnergyComp;\n #endif\n reflectedLight.indirectDiffuse += diffuse;\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n #ifdef USE_CLEARCOAT\n clearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n #endif\n #ifdef USE_SHEEN\n sheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness ) * RECIPROCAL_PI;\n #endif\n vec3 singleScatteringDielectric = vec3( 0.0 );\n vec3 multiScatteringDielectric = vec3( 0.0 );\n vec3 singleScatteringMetallic = vec3( 0.0 );\n vec3 multiScatteringMetallic = vec3( 0.0 );\n #ifdef USE_IRIDESCENCE\n computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnelDielectric, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.iridescence, material.iridescenceFresnelMetallic, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n #else\n computeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n computeMultiscattering( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n #endif\n vec3 singleScattering = mix( singleScatteringDielectric, singleScatteringMetallic, material.metalness );\n vec3 multiScattering = mix( multiScatteringDielectric, multiScatteringMetallic, material.metalness );\n vec3 totalScatteringDielectric = singleScatteringDielectric + multiScatteringDielectric;\n vec3 diffuse = material.diffuseContribution * ( 1.0 - totalScatteringDielectric );\n vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n vec3 indirectSpecular = radiance * singleScattering;\n indirectSpecular += multiScattering * cosineWeightedIrradiance;\n vec3 indirectDiffuse = diffuse * cosineWeightedIrradiance;\n #ifdef USE_SHEEN\n float sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n indirectSpecular *= sheenEnergyComp;\n indirectDiffuse *= sheenEnergyComp;\n #endif\n reflectedLight.indirectSpecular += indirectSpecular;\n reflectedLight.indirectDiffuse += indirectDiffuse;\n}\n#define RE_Direct RE_Direct_Physical\n#define RE_Direct_RectArea RE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular RE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}";
19601
- var lights_fragment_begin = "\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n geometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n float dotNVi = saturate( dot( normal, geometryViewDir ) );\n if ( material.iridescenceThickness == 0.0 ) {\n material.iridescence = 0.0;\n } else {\n material.iridescence = saturate( material.iridescence );\n }\n if ( material.iridescence > 0.0 ) {\n material.iridescenceFresnelDielectric = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n material.iridescenceFresnelMetallic = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.diffuseColor );\n material.iridescenceFresnel = mix( material.iridescenceFresnelDielectric, material.iridescenceFresnelMetallic, material.metalness );\n material.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n }\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n PointLight pointLight;\n #if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n PointLightShadow pointLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n pointLight = pointLights[ i ];\n getPointLightInfo( pointLight, geometryPosition, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS ) && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n pointLightShadow = pointLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n SpotLight spotLight;\n vec4 spotColor;\n vec3 spotLightCoord;\n bool inSpotLightMap;\n #if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n SpotLightShadow spotLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n spotLight = spotLights[ i ];\n getSpotLightInfo( spotLight, geometryPosition, directLight );\n #if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n #define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n #elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n #define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n #else\n #define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n #endif\n #if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n spotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n inSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n spotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n directLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n #endif\n #undef SPOT_LIGHT_MAP_INDEX\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n spotLightShadow = spotLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n DirectionalLight directionalLight;\n #if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n DirectionalLightShadow directionalLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n directionalLight = directionalLights[ i ];\n getDirectionalLightInfo( directionalLight, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n directionalLightShadow = directionalLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n RectAreaLight rectAreaLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n rectAreaLight = rectAreaLights[ i ];\n RE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n vec3 iblIrradiance = vec3( 0.0 );\n vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n #if defined( USE_LIGHT_PROBES )\n irradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n #endif\n #if ( NUM_HEMI_LIGHTS > 0 )\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n }\n #pragma unroll_loop_end\n #endif\n #ifdef USE_LIGHT_PROBES_GRID\n vec3 probeWorldPos = ( ( vec4( geometryPosition, 1.0 ) - viewMatrix[ 3 ] ) * viewMatrix ).xyz;\n vec3 probeWorldNormal = transformNormalByInverseViewMatrix( geometryNormal, viewMatrix );\n irradiance += getLightProbeGridIrradiance( probeWorldPos, probeWorldNormal );\n #endif\n#endif\n#if defined( RE_IndirectSpecular )\n vec3 radiance = vec3( 0.0 );\n vec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
19602
- var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n #ifdef USE_LIGHTMAP\n vec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n irradiance += lightMapIrradiance;\n #endif\n #if defined( USE_ENVMAP ) && defined( ENVMAP_TYPE_CUBE_UV )\n #if defined( STANDARD ) || defined( LAMBERT ) || defined( PHONG )\n iblIrradiance += getIBLIrradiance( geometryNormal );\n #endif\n #endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n #ifdef USE_ANISOTROPY\n radiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n #else\n radiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n #endif\n #ifdef USE_CLEARCOAT\n clearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n #endif\n#endif";
20028
+ var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.diffuseContribution = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.metalness = metalnessFactor;\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n material.ior = ior;\n #ifdef USE_SPECULAR\n float specularIntensityFactor = specularIntensity;\n vec3 specularColorFactor = specularColor;\n #ifdef USE_SPECULAR_COLORMAP\n specularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n #endif\n #ifdef USE_SPECULAR_INTENSITYMAP\n specularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n #endif\n material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n #else\n float specularIntensityFactor = 1.0;\n vec3 specularColorFactor = vec3( 1.0 );\n material.specularF90 = 1.0;\n #endif\n material.specularColor = min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor;\n material.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n#else\n material.specularColor = vec3( 0.04 );\n material.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n material.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n material.clearcoat = clearcoat;\n material.clearcoatRoughness = clearcoatRoughness;\n material.clearcoatF0 = vec3( 0.04 );\n material.clearcoatF90 = 1.0;\n #ifdef USE_CLEARCOATMAP\n material.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n #endif\n #ifdef USE_CLEARCOAT_ROUGHNESSMAP\n material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n #endif\n material.clearcoat = saturate( material.clearcoat ); material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n material.clearcoatRoughness += geometryRoughness;\n material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n material.dispersion = dispersion;\n#endif\n#ifdef USE_RETROREFLECTION\n material.retroreflectivity = retroreflectivity;\n#endif\n#ifdef USE_IRIDESCENCE\n material.iridescence = iridescence;\n material.iridescenceIOR = iridescenceIOR;\n #ifdef USE_IRIDESCENCEMAP\n material.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n #endif\n #ifdef USE_IRIDESCENCE_THICKNESSMAP\n material.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n #else\n material.iridescenceThickness = iridescenceThicknessMaximum;\n #endif\n#endif\n#ifdef USE_SHEEN\n material.sheenColor = sheenColor;\n #ifdef USE_SHEEN_COLORMAP\n material.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n #endif\n material.sheenRoughness = clamp( sheenRoughness, 0.0001, 1.0 );\n #ifdef USE_SHEEN_ROUGHNESSMAP\n material.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n #endif\n#endif\n#ifdef USE_ANISOTROPY\n #ifdef USE_ANISOTROPYMAP\n mat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n vec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n vec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n #else\n vec2 anisotropyV = anisotropyVector;\n #endif\n material.anisotropy = length( anisotropyV );\n if( material.anisotropy == 0.0 ) {\n anisotropyV = vec2( 1.0, 0.0 );\n } else {\n anisotropyV /= material.anisotropy;\n material.anisotropy = saturate( material.anisotropy );\n }\n material.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n material.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n material.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif";
20029
+ var lights_physical_pars_fragment = "uniform sampler2D dfgLUT;\nstruct PhysicalMaterial {\n vec3 diffuseColor;\n vec3 diffuseContribution;\n vec3 specularColor;\n vec3 specularColorBlended;\n float roughness;\n float metalness;\n float specularF90;\n float dispersion;\n vec2 dfg;\n vec3 multiScatteringCompensation;\n #ifdef USE_RETROREFLECTION\n float retroreflectivity;\n #endif\n #ifdef USE_CLEARCOAT\n float clearcoat;\n float clearcoatRoughness;\n vec3 clearcoatF0;\n float clearcoatF90;\n #endif\n #ifdef USE_IRIDESCENCE\n float iridescence;\n float iridescenceIOR;\n float iridescenceThickness;\n vec3 iridescenceFresnel;\n vec3 iridescenceF0Dielectric;\n vec3 iridescenceF0Metallic;\n #endif\n #ifdef USE_SHEEN\n vec3 sheenColor;\n float sheenRoughness;\n #endif\n #ifdef IOR\n float ior;\n #endif\n #ifdef USE_TRANSMISSION\n float transmission;\n float transmissionAlpha;\n float thickness;\n float attenuationDistance;\n vec3 attenuationColor;\n #endif\n #ifdef USE_ANISOTROPY\n float anisotropy;\n float alphaT;\n vec3 anisotropyT;\n vec3 anisotropyB;\n #endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n float a2 = pow2( alpha );\n float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n return 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n float a2 = pow2( alpha );\n float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n return RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n float V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n float gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n float gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n return 0.5 / max( gv + gl, EPSILON );\n }\n float D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n float a2 = alphaT * alphaB;\n highp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n highp float v2 = dot( v, v );\n float w2 = a2 / v2;\n return RECIPROCAL_PI * a2 * pow2 ( w2 );\n }\n#endif\n#ifdef USE_CLEARCOAT\n vec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n vec3 f0 = material.clearcoatF0;\n float f90 = material.clearcoatF90;\n float roughness = material.clearcoatRoughness;\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotVH = saturate( dot( viewDir, halfDir ) );\n vec3 F = F_Schlick( f0, f90, dotVH );\n float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n return F * ( V * D );\n }\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n vec3 f0 = material.specularColorBlended;\n float f90 = material.specularF90;\n float roughness = material.roughness;\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotVH = saturate( dot( viewDir, halfDir ) );\n vec3 F = F_Schlick( f0, f90, dotVH );\n #ifdef USE_IRIDESCENCE\n F = mix( F, material.iridescenceFresnel, material.iridescence );\n #endif\n #ifdef USE_ANISOTROPY\n float dotTL = dot( material.anisotropyT, lightDir );\n float dotTV = dot( material.anisotropyT, viewDir );\n float dotTH = dot( material.anisotropyT, halfDir );\n float dotBL = dot( material.anisotropyB, lightDir );\n float dotBV = dot( material.anisotropyB, viewDir );\n float dotBH = dot( material.anisotropyB, halfDir );\n float V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n float D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n #else\n float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n #endif\n return F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n const float LUT_SIZE = 64.0;\n const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n const float LUT_BIAS = 0.5 / LUT_SIZE;\n float dotNV = saturate( dot( N, V ) );\n vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n uv = uv * LUT_SCALE + LUT_BIAS;\n return uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n float l = length( f );\n return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n float x = dot( v1, v2 );\n float y = abs( x );\n float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n float b = 3.4175940 + ( 4.1616724 + y ) * y;\n float v = a / b;\n float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n return cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n vec3 lightNormal = cross( v1, v2 );\n if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n vec3 T1, T2;\n T1 = normalize( V - N * dot( V, N ) );\n T2 = - cross( N, T1 );\n mat3 mat = mInv * transpose( mat3( T1, T2, N ) );\n vec3 coords[ 4 ];\n coords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n coords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n coords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n coords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n coords[ 0 ] = normalize( coords[ 0 ] );\n coords[ 1 ] = normalize( coords[ 1 ] );\n coords[ 2 ] = normalize( coords[ 2 ] );\n coords[ 3 ] = normalize( coords[ 3 ] );\n vec3 vectorFormFactor = vec3( 0.0 );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n float result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n return vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n float alpha = pow2( roughness );\n float invAlpha = 1.0 / alpha;\n float cos2h = dotNH * dotNH;\n float sin2h = max( 1.0 - cos2h, 0.0078125 );\n return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float D = D_Charlie( sheenRoughness, dotNH );\n float V = V_Neubelt( dotNV, dotNL );\n return sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n float dotNV = saturate( dot( normal, viewDir ) );\n float r2 = roughness * roughness;\n float rInv = 1.0 / ( roughness + 0.1 );\n float a = -1.9362 + 1.0678 * roughness + 0.4573 * r2 - 0.8469 * rInv;\n float b = -0.6014 + 0.5538 * roughness - 0.4670 * r2 - 0.1255 * rInv;\n float DG = exp( a * dotNV + b );\n return saturate( DG );\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n float dotNV = saturate( dot( normal, viewDir ) );\n vec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\n return specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec2 fab, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec2 fab, const in vec3 specularColor, const in float specularF90, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n #ifdef USE_IRIDESCENCE\n vec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n #else\n vec3 Fr = specularColor;\n #endif\n vec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n float Ess = fab.x + fab.y;\n float Ems = 1.0 - Ess;\n vec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n singleScatter += FssEss;\n multiScatter += Fms * Ems;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 normal = geometryNormal;\n vec3 viewDir = geometryViewDir;\n vec3 position = geometryPosition;\n vec3 lightPos = rectAreaLight.position;\n vec3 halfWidth = rectAreaLight.halfWidth;\n vec3 halfHeight = rectAreaLight.halfHeight;\n vec3 lightColor = rectAreaLight.color;\n float roughness = material.roughness;\n vec3 rectCoords[ 4 ];\n rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; rectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n rectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n rectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n vec2 uv = LTC_Uv( normal, viewDir, roughness );\n vec4 t1 = texture2D( ltc_1, uv );\n vec4 t2 = texture2D( ltc_2, uv );\n mat3 mInv = mat3(\n vec3( t1.x, 0, t1.y ),\n vec3( 0, 1, 0 ),\n vec3( t1.z, 0, t1.w )\n );\n vec3 fresnel = ( material.specularColorBlended * t2.x + ( material.specularF90 - material.specularColorBlended ) * t2.y );\n reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n reflectedLight.directDiffuse += lightColor * material.diffuseContribution * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n #ifdef USE_CLEARCOAT\n vec3 Ncc = geometryClearcoatNormal;\n vec2 uvClearcoat = LTC_Uv( Ncc, viewDir, material.clearcoatRoughness );\n vec4 t1Clearcoat = texture2D( ltc_1, uvClearcoat );\n vec4 t2Clearcoat = texture2D( ltc_2, uvClearcoat );\n mat3 mInvClearcoat = mat3(\n vec3( t1Clearcoat.x, 0, t1Clearcoat.y ),\n vec3( 0, 1, 0 ),\n vec3( t1Clearcoat.z, 0, t1Clearcoat.w )\n );\n vec3 fresnelClearcoat = material.clearcoatF0 * t2Clearcoat.x + ( material.clearcoatF90 - material.clearcoatF0 ) * t2Clearcoat.y;\n clearcoatSpecularDirect += lightColor * fresnelClearcoat * LTC_Evaluate( Ncc, viewDir, position, mInvClearcoat, rectCoords );\n #endif\n }\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n #ifdef USE_CLEARCOAT\n float dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n vec3 ccIrradiance = dotNLcc * directLight.color;\n clearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n #endif\n #ifdef USE_SHEEN\n \n sheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n \n float sheenAlbedoV = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n float sheenAlbedoL = IBLSheenBRDF( geometryNormal, directLight.direction, material.sheenRoughness );\n \n float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * max( sheenAlbedoV, sheenAlbedoL );\n \n irradiance *= sheenEnergyComp;\n \n #endif\n vec3 specularBRDF = BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material );\n #ifdef USE_RETROREFLECTION\n vec3 retroViewDir = reflect( - geometryViewDir, geometryNormal );\n vec3 retroSpecularBRDF = BRDF_GGX( directLight.direction, retroViewDir, geometryNormal, material );\n specularBRDF = mix( specularBRDF, retroSpecularBRDF, saturate( material.retroreflectivity ) );\n #endif\n reflectedLight.directSpecular += irradiance * specularBRDF * material.multiScatteringCompensation;\n vec3 halfDir = normalize( directLight.direction + geometryViewDir );\n float dotVH = saturate( dot( geometryViewDir, halfDir ) );\n vec3 F = F_Schlick( material.specularColor, material.specularF90, dotVH );\n #ifdef USE_RETROREFLECTION\n vec3 retroHalfDir = normalize( directLight.direction + retroViewDir );\n float dotRetroVH = saturate( dot( retroViewDir, retroHalfDir ) );\n vec3 retroF = F_Schlick( material.specularColor, material.specularF90, dotRetroVH );\n F = mix( F, retroF, saturate( material.retroreflectivity ) );\n #endif\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseContribution ) * ( 1.0 - F );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 singleScattering = vec3( 0.0 );\n vec3 multiScattering = vec3( 0.0 );\n #ifdef USE_IRIDESCENCE\n computeMultiscatteringIridescence( material.dfg, material.specularColor, material.specularF90, material.iridescence, material.iridescenceF0Dielectric, singleScattering, multiScattering );\n #else\n computeMultiscattering( material.dfg, material.specularColor, material.specularF90, singleScattering, multiScattering );\n #endif\n vec3 diffuse = irradiance * BRDF_Lambert( material.diffuseContribution ) * ( 1.0 - singleScattering - multiScattering );\n #ifdef USE_SHEEN\n float sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n sheenSpecularIndirect += irradiance * material.sheenColor * sheenAlbedo * RECIPROCAL_PI;\n float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n diffuse *= sheenEnergyComp;\n #endif\n reflectedLight.indirectDiffuse += diffuse;\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n #ifdef USE_CLEARCOAT\n clearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n #endif\n #ifdef USE_SHEEN\n sheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness ) * RECIPROCAL_PI;\n #endif\n vec3 singleScatteringDielectric = vec3( 0.0 );\n vec3 multiScatteringDielectric = vec3( 0.0 );\n vec3 singleScatteringMetallic = vec3( 0.0 );\n vec3 multiScatteringMetallic = vec3( 0.0 );\n #ifdef USE_IRIDESCENCE\n computeMultiscatteringIridescence( material.dfg, material.specularColor, material.specularF90, material.iridescence, material.iridescenceF0Dielectric, singleScatteringDielectric, multiScatteringDielectric );\n computeMultiscatteringIridescence( material.dfg, material.diffuseColor, material.specularF90, material.iridescence, material.iridescenceF0Metallic, singleScatteringMetallic, multiScatteringMetallic );\n #else\n computeMultiscattering( material.dfg, material.specularColor, material.specularF90, singleScatteringDielectric, multiScatteringDielectric );\n computeMultiscattering( material.dfg, material.diffuseColor, material.specularF90, singleScatteringMetallic, multiScatteringMetallic );\n #endif\n vec3 singleScattering = mix( singleScatteringDielectric, singleScatteringMetallic, material.metalness );\n vec3 multiScattering = mix( multiScatteringDielectric, multiScatteringMetallic, material.metalness );\n vec3 totalScatteringDielectric = singleScatteringDielectric + multiScatteringDielectric;\n vec3 diffuse = material.diffuseContribution * ( 1.0 - totalScatteringDielectric );\n vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n vec3 indirectSpecular = radiance * singleScattering;\n indirectSpecular += multiScattering * cosineWeightedIrradiance;\n vec3 indirectDiffuse = diffuse * cosineWeightedIrradiance;\n #ifdef USE_SHEEN\n float sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n indirectSpecular *= sheenEnergyComp;\n indirectDiffuse *= sheenEnergyComp;\n #endif\n reflectedLight.indirectSpecular += indirectSpecular;\n reflectedLight.indirectDiffuse += indirectDiffuse;\n}\n#define RE_Direct RE_Direct_Physical\n#define RE_Direct_RectArea RE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular RE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}";
20030
+ var lights_fragment_begin = "\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n geometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n float dotNVi = saturate( dot( normal, geometryViewDir ) );\n if ( material.iridescenceThickness == 0.0 ) {\n material.iridescence = 0.0;\n } else {\n material.iridescence = saturate( material.iridescence );\n }\n if ( material.iridescence > 0.0 ) {\n vec3 iridescenceFresnelDielectric = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n vec3 iridescenceFresnelMetallic = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.diffuseColor );\n material.iridescenceFresnel = mix( iridescenceFresnelDielectric, iridescenceFresnelMetallic, material.metalness );\n material.iridescenceF0Dielectric = Schlick_to_F0( iridescenceFresnelDielectric, 1.0, dotNVi );\n material.iridescenceF0Metallic = Schlick_to_F0( iridescenceFresnelMetallic, 1.0, dotNVi );\n }\n#endif\n#ifdef STANDARD\n float dotNVms = saturate( dot( geometryNormal, geometryViewDir ) );\n material.dfg = texture2D( dfgLUT, vec2( material.roughness, dotNVms ) ).rg;\n #if ( NUM_SUN_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_SPOT_LIGHTS > 0 )\n float EssMs = material.dfg.x + material.dfg.y;\n material.multiScatteringCompensation = 1.0 + material.specularColorBlended * ( 1.0 / EssMs - 1.0 );\n #endif\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n PointLight pointLight;\n #if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n PointLightShadow pointLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n pointLight = pointLights[ i ];\n getPointLightInfo( pointLight, geometryPosition, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS ) && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n pointLightShadow = pointLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n SpotLight spotLight;\n vec4 spotColor;\n vec3 spotLightCoord;\n bool inSpotLightMap;\n #if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n SpotLightShadow spotLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n spotLight = spotLights[ i ];\n getSpotLightInfo( spotLight, geometryPosition, directLight );\n #if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n #define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n #elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n #define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n #else\n #define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n #endif\n #if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n spotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n inSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n spotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n directLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n #endif\n #undef SPOT_LIGHT_MAP_INDEX\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n spotLightShadow = spotLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_SUN_LIGHTS > 0 ) && defined( RE_Direct )\n SunLight sunLight;\n #if defined( USE_SHADOWMAP ) && NUM_SUN_LIGHT_SHADOWS > 0\n SunLightShadow sunLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SUN_LIGHTS; i ++ ) {\n sunLight = sunLights[ i ];\n getSunLightInfo( sunLight, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SUN_LIGHT_SHADOWS )\n sunLightShadow = sunLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getSunShadow( sunShadowMap[ i ], sunLightShadow, UNROLLED_LOOP_INDEX ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n DirectionalLight directionalLight;\n #if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n DirectionalLightShadow directionalLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n directionalLight = directionalLights[ i ];\n getDirectionalLightInfo( directionalLight, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n directionalLightShadow = directionalLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n RectAreaLight rectAreaLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n rectAreaLight = rectAreaLights[ i ];\n RE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n vec3 iblIrradiance = vec3( 0.0 );\n vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n #if defined( USE_LIGHT_PROBES )\n irradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n #endif\n #if ( NUM_HEMI_LIGHTS > 0 )\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n }\n #pragma unroll_loop_end\n #endif\n #ifdef USE_LIGHT_PROBES_GRID\n vec3 probeWorldPos = ( ( vec4( geometryPosition, 1.0 ) - viewMatrix[ 3 ] ) * viewMatrix ).xyz;\n vec3 probeWorldNormal = transformNormalByInverseViewMatrix( geometryNormal, viewMatrix );\n irradiance += getLightProbeGridIrradiance( probeWorldPos, probeWorldNormal );\n #endif\n#endif\n#if defined( RE_IndirectSpecular )\n vec3 radiance = vec3( 0.0 );\n vec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
20031
+ var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n #ifdef USE_LIGHTMAP\n vec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n irradiance += lightMapIrradiance;\n #endif\n #if defined( USE_ENVMAP ) && defined( ENVMAP_TYPE_CUBE_UV )\n #if defined( STANDARD ) || defined( LAMBERT ) || defined( PHONG )\n iblIrradiance += getIBLIrradiance( geometryNormal );\n #endif\n #endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n #ifdef USE_ANISOTROPY\n vec3 iblRadiance = getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n #else\n vec3 iblRadiance = getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n #endif\n #ifdef USE_RETROREFLECTION\n #ifdef USE_ANISOTROPY\n vec3 retroIBLRadiance = getIBLAnisotropyRetroRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n #else\n vec3 retroIBLRadiance = getIBLRetroRadiance( geometryViewDir, geometryNormal, material.roughness );\n #endif\n iblRadiance = mix( iblRadiance, retroIBLRadiance, saturate( material.retroreflectivity ) );\n #endif\n radiance += iblRadiance;\n #ifdef USE_CLEARCOAT\n clearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n #endif\n#endif";
19603
20032
  var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n #if defined( LAMBERT ) || defined( PHONG )\n irradiance += iblIrradiance;\n #endif\n RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif";
19604
20033
  var lightprobes_pars_fragment = "#ifdef USE_LIGHT_PROBES_GRID\nuniform highp sampler3D probesSH;\nuniform vec3 probesMin;\nuniform vec3 probesMax;\nuniform vec3 probesResolution;\nvec3 getLightProbeGridIrradiance( vec3 worldPos, vec3 worldNormal ) {\n vec3 res = probesResolution;\n vec3 gridRange = probesMax - probesMin;\n vec3 resMinusOne = res - 1.0;\n vec3 probeSpacing = gridRange / resMinusOne;\n vec3 samplePos = worldPos + worldNormal * probeSpacing * 0.5;\n vec3 uvw = clamp( ( samplePos - probesMin ) / gridRange, 0.0, 1.0 );\n uvw = uvw * resMinusOne / res + 0.5 / res;\n float nz = res.z;\n float paddedSlices = nz + 2.0;\n float atlasDepth = 7.0 * paddedSlices;\n float uvZBase = uvw.z * nz + 1.0;\n vec4 s0 = texture( probesSH, vec3( uvw.xy, ( uvZBase ) / atlasDepth ) );\n vec4 s1 = texture( probesSH, vec3( uvw.xy, ( uvZBase + paddedSlices ) / atlasDepth ) );\n vec4 s2 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 2.0 * paddedSlices ) / atlasDepth ) );\n vec4 s3 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 3.0 * paddedSlices ) / atlasDepth ) );\n vec4 s4 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 4.0 * paddedSlices ) / atlasDepth ) );\n vec4 s5 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 5.0 * paddedSlices ) / atlasDepth ) );\n vec4 s6 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 6.0 * paddedSlices ) / atlasDepth ) );\n vec3 c0 = s0.xyz;\n vec3 c1 = vec3( s0.w, s1.xy );\n vec3 c2 = vec3( s1.zw, s2.x );\n vec3 c3 = s2.yzw;\n vec3 c4 = s3.xyz;\n vec3 c5 = vec3( s3.w, s4.xy );\n vec3 c6 = vec3( s4.zw, s5.x );\n vec3 c7 = s5.yzw;\n vec3 c8 = s6.xyz;\n float x = worldNormal.x, y = worldNormal.y, z = worldNormal.z;\n vec3 result = c0 * 0.886227;\n result += c1 * 2.0 * 0.511664 * y;\n result += c2 * 2.0 * 0.511664 * z;\n result += c3 * 2.0 * 0.511664 * x;\n result += c4 * 2.0 * 0.429043 * x * y;\n result += c5 * 2.0 * 0.429043 * y * z;\n result += c6 * ( 0.743125 * z * z - 0.247708 );\n result += c7 * 2.0 * 0.429043 * x * z;\n result += c8 * 0.429043 * ( x * x - y * y );\n return max( result, vec3( 0.0 ) );\n}\n#endif";
19605
20034
  var logdepthbuf_fragment = "#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n gl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif";
@@ -19635,10 +20064,10 @@ var dithering_fragment = "#ifdef DITHERING\n gl_FragColor.rgb = dithering( gl_Fr
19635
20064
  var dithering_pars_fragment = "#ifdef DITHERING\n vec3 dithering( vec3 color ) {\n float grid_position = rand( gl_FragCoord.xy );\n vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n return color + dither_shift_RGB;\n }\n#endif";
19636
20065
  var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n vec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );\n roughnessFactor *= texelRoughness.g;\n#endif";
19637
20066
  var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n uniform sampler2D roughnessMap;\n#endif";
19638
- var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform sampler2DShadow directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n #else\n uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n struct DirectionalLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform sampler2DShadow spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n #else\n uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n struct SpotLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform samplerCubeShadow pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n #elif defined( SHADOWMAP_TYPE_BASIC )\n uniform samplerCube pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n struct PointLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n float shadowCameraNear;\n float shadowCameraFar;\n };\n uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n #if defined( SHADOWMAP_TYPE_PCF )\n float interleavedGradientNoise( vec2 position ) {\n return fract( 52.9829189 * fract( dot( position, vec2( 0.06711056, 0.00583715 ) ) ) );\n }\n vec2 vogelDiskSample( int sampleIndex, int samplesCount, float phi ) {\n const float goldenAngle = 2.399963229728653;\n float r = sqrt( ( float( sampleIndex ) + 0.5 ) / float( samplesCount ) );\n float theta = float( sampleIndex ) * goldenAngle + phi;\n return vec2( cos( theta ), sin( theta ) ) * r;\n }\n #endif\n #if defined( SHADOWMAP_TYPE_PCF )\n float getShadow( sampler2DShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n shadowCoord.z += shadowBias;\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n if ( frustumTest ) {\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n float radius = shadowRadius * texelSize.x;\n float phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n shadow = (\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 0, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 1, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 2, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 3, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 4, 5, phi ) * radius, shadowCoord.z ) )\n ) * 0.2;\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #elif defined( SHADOWMAP_TYPE_VSM )\n float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n shadowCoord.z -= shadowBias;\n #else\n shadowCoord.z += shadowBias;\n #endif\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n if ( frustumTest ) {\n vec2 distribution = texture2D( shadowMap, shadowCoord.xy ).rg;\n float mean = distribution.x;\n float variance = distribution.y * distribution.y;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n float hard_shadow = step( mean, shadowCoord.z );\n #else\n float hard_shadow = step( shadowCoord.z, mean );\n #endif\n \n if ( hard_shadow == 1.0 ) {\n shadow = 1.0;\n } else {\n variance = max( variance, 0.0000001 );\n float d = shadowCoord.z - mean;\n float p_max = variance / ( variance + d * d );\n p_max = clamp( ( p_max - 0.3 ) / 0.65, 0.0, 1.0 );\n shadow = max( hard_shadow, p_max );\n }\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #else\n float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n shadowCoord.z -= shadowBias;\n #else\n shadowCoord.z += shadowBias;\n #endif\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n if ( frustumTest ) {\n float depth = texture2D( shadowMap, shadowCoord.xy ).r;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n shadow = step( depth, shadowCoord.z );\n #else\n shadow = step( shadowCoord.z, depth );\n #endif\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n float getPointShadow( samplerCubeShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n float shadow = 1.0;\n vec3 lightToPosition = shadowCoord.xyz;\n vec3 bd3D = normalize( lightToPosition );\n vec3 absVec = abs( lightToPosition );\n float viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n if ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n #ifdef USE_REVERSED_DEPTH_BUFFER\n float dp = ( shadowCameraNear * ( shadowCameraFar - viewSpaceZ ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n dp -= shadowBias;\n #else\n float dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n dp += shadowBias;\n #endif\n float texelSize = shadowRadius / shadowMapSize.x;\n vec3 absDir = abs( bd3D );\n vec3 tangent = absDir.x > absDir.z ? vec3( 0.0, 1.0, 0.0 ) : vec3( 1.0, 0.0, 0.0 );\n tangent = normalize( cross( bd3D, tangent ) );\n vec3 bitangent = cross( bd3D, tangent );\n float phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n vec2 sample0 = vogelDiskSample( 0, 5, phi );\n vec2 sample1 = vogelDiskSample( 1, 5, phi );\n vec2 sample2 = vogelDiskSample( 2, 5, phi );\n vec2 sample3 = vogelDiskSample( 3, 5, phi );\n vec2 sample4 = vogelDiskSample( 4, 5, phi );\n shadow = (\n texture( shadowMap, vec4( bd3D + ( tangent * sample0.x + bitangent * sample0.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample1.x + bitangent * sample1.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample2.x + bitangent * sample2.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample3.x + bitangent * sample3.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample4.x + bitangent * sample4.y ) * texelSize, dp ) )\n ) * 0.2;\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #elif defined( SHADOWMAP_TYPE_BASIC )\n float getPointShadow( samplerCube shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n float shadow = 1.0;\n vec3 lightToPosition = shadowCoord.xyz;\n vec3 absVec = abs( lightToPosition );\n float viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n if ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n float dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n dp += shadowBias;\n vec3 bd3D = normalize( lightToPosition );\n float depth = textureCube( shadowMap, bd3D ).r;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n depth = 1.0 - depth;\n #endif\n shadow = step( dp, depth );\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #endif\n #endif\n#endif";
19639
- var shadowmap_pars_vertex = "#if NUM_SPOT_LIGHT_COORDS > 0\n uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0\n uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n struct DirectionalLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n struct SpotLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n struct PointLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n float shadowCameraNear;\n float shadowCameraFar;\n };\n uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n#endif";
19640
- var shadowmap_vertex = "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n #ifdef HAS_NORMAL\n vec3 shadowWorldNormal = transformNormalByInverseViewMatrix( transformedNormal, viewMatrix );\n #else\n vec3 shadowWorldNormal = vec3( 0.0 );\n #endif\n vec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n #if NUM_DIR_LIGHT_SHADOWS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n #endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n shadowWorldPosition = worldPosition;\n #if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n shadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n #endif\n vSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n#endif";
19641
- var shadowmask_pars_fragment = "float getShadowMask() {\n float shadow = 1.0;\n #ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0\n DirectionalLightShadow directionalLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n directionalLight = directionalLightShadows[ i ];\n shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n SpotLightShadow spotLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n spotLight = spotLightShadows[ i ];\n shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0 && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n PointLightShadow pointLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n pointLight = pointLightShadows[ i ];\n shadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #endif\n return shadow;\n}";
20067
+ var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#ifdef USE_SHADOWMAP\n #if NUM_SUN_LIGHT_SHADOWS > 0\n #define SUN_LIGHT_CASCADES 2\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform sampler2DShadow sunShadowMap[ NUM_SUN_LIGHT_SHADOWS ];\n #else\n uniform sampler2D sunShadowMap[ NUM_SUN_LIGHT_SHADOWS ];\n #endif\n uniform mat4 sunShadowMatrix[ NUM_SUN_LIGHT_SHADOWS * SUN_LIGHT_CASCADES ];\n uniform vec4 sunShadowCascade[ NUM_SUN_LIGHT_SHADOWS * SUN_LIGHT_CASCADES ];\n varying vec4 vSunShadowWorldPosition;\n varying vec3 vSunShadowWorldNormal;\n struct SunLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SunLightShadow sunLightShadows[ NUM_SUN_LIGHT_SHADOWS ];\n #endif\n #if NUM_DIR_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform sampler2DShadow directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n #else\n uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n struct DirectionalLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform sampler2DShadow spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n #else\n uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n struct SpotLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform samplerCubeShadow pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n #elif defined( SHADOWMAP_TYPE_BASIC )\n uniform samplerCube pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n struct PointLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n float shadowCameraNear;\n float shadowCameraFar;\n };\n uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n #if defined( SHADOWMAP_TYPE_PCF )\n float interleavedGradientNoise( vec2 position ) {\n return fract( 52.9829189 * fract( dot( position, vec2( 0.06711056, 0.00583715 ) ) ) );\n }\n vec2 vogelDiskSample( int sampleIndex, int samplesCount, float phi ) {\n const float goldenAngle = 2.399963229728653;\n float r = sqrt( ( float( sampleIndex ) + 0.5 ) / float( samplesCount ) );\n float theta = float( sampleIndex ) * goldenAngle + phi;\n return vec2( cos( theta ), sin( theta ) ) * r;\n }\n #endif\n #if defined( SHADOWMAP_TYPE_PCF )\n float getShadow( sampler2DShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n shadowCoord.z += shadowBias;\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n if ( frustumTest ) {\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n float radius = shadowRadius * texelSize.x;\n float phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n shadow = (\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 0, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 1, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 2, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 3, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 4, 5, phi ) * radius, shadowCoord.z ) )\n ) * 0.2;\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #elif defined( SHADOWMAP_TYPE_VSM )\n float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n shadowCoord.z -= shadowBias;\n #else\n shadowCoord.z += shadowBias;\n #endif\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n if ( frustumTest ) {\n vec2 distribution = texture2D( shadowMap, shadowCoord.xy ).rg;\n float mean = distribution.x;\n float variance = distribution.y * distribution.y;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n float hard_shadow = step( mean, shadowCoord.z );\n #else\n float hard_shadow = step( shadowCoord.z, mean );\n #endif\n \n if ( hard_shadow == 1.0 ) {\n shadow = 1.0;\n } else {\n variance = max( variance, 0.0000001 );\n float d = shadowCoord.z - mean;\n float p_max = variance / ( variance + d * d );\n p_max = clamp( ( p_max - 0.3 ) / 0.65, 0.0, 1.0 );\n shadow = max( hard_shadow, p_max );\n }\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #else\n float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n shadowCoord.z -= shadowBias;\n #else\n shadowCoord.z += shadowBias;\n #endif\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n if ( frustumTest ) {\n float depth = texture2D( shadowMap, shadowCoord.xy ).r;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n shadow = step( depth, shadowCoord.z );\n #else\n shadow = step( shadowCoord.z, depth );\n #endif\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #endif\n #if NUM_SUN_LIGHT_SHADOWS > 0\n float getSunShadow(\n #if defined( SHADOWMAP_TYPE_PCF )\n sampler2DShadow shadowMap,\n #else\n sampler2D shadowMap,\n #endif\n SunLightShadow sunLightShadow,\n int shadowIndex\n ) {\n vec4 shadowWorldPosition = vec4( vSunShadowWorldPosition.xyz + vSunShadowWorldNormal * sunLightShadow.shadowNormalBias, 1.0 );\n float viewDepth = vSunShadowWorldPosition.w;\n int cascadeOffset = shadowIndex * SUN_LIGHT_CASCADES;\n float shadow = 1.0;\n for ( int i = SUN_LIGHT_CASCADES - 1; i >= 0; i -- ) {\n vec4 cascade = sunShadowCascade[ cascadeOffset + i ];\n if ( viewDepth >= cascade.x && viewDepth < cascade.y ) {\n float cascadeShadow = getShadow(\n shadowMap,\n sunLightShadow.shadowMapSize,\n sunLightShadow.shadowIntensity,\n sunLightShadow.shadowBias,\n sunLightShadow.shadowRadius,\n sunShadowMatrix[ cascadeOffset + i ] * shadowWorldPosition\n );\n shadow = mix( cascadeShadow, shadow, smoothstep( cascade.z, cascade.y, viewDepth ) );\n }\n }\n return shadow;\n }\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n float getPointShadow( samplerCubeShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n float shadow = 1.0;\n vec3 lightToPosition = shadowCoord.xyz;\n vec3 bd3D = normalize( lightToPosition );\n vec3 absVec = abs( lightToPosition );\n float viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n if ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n #ifdef USE_REVERSED_DEPTH_BUFFER\n float dp = ( shadowCameraNear * ( shadowCameraFar - viewSpaceZ ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n dp -= shadowBias;\n #else\n float dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n dp += shadowBias;\n #endif\n float texelSize = shadowRadius / shadowMapSize.x;\n vec3 absDir = abs( bd3D );\n vec3 tangent = absDir.x > absDir.z ? vec3( 0.0, 1.0, 0.0 ) : vec3( 1.0, 0.0, 0.0 );\n tangent = normalize( cross( bd3D, tangent ) );\n vec3 bitangent = cross( bd3D, tangent );\n float phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n vec2 sample0 = vogelDiskSample( 0, 5, phi );\n vec2 sample1 = vogelDiskSample( 1, 5, phi );\n vec2 sample2 = vogelDiskSample( 2, 5, phi );\n vec2 sample3 = vogelDiskSample( 3, 5, phi );\n vec2 sample4 = vogelDiskSample( 4, 5, phi );\n shadow = (\n texture( shadowMap, vec4( bd3D + ( tangent * sample0.x + bitangent * sample0.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample1.x + bitangent * sample1.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample2.x + bitangent * sample2.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample3.x + bitangent * sample3.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample4.x + bitangent * sample4.y ) * texelSize, dp ) )\n ) * 0.2;\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #elif defined( SHADOWMAP_TYPE_BASIC )\n float getPointShadow( samplerCube shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n float shadow = 1.0;\n vec3 lightToPosition = shadowCoord.xyz;\n vec3 absVec = abs( lightToPosition );\n float viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n if ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n float dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n dp += shadowBias;\n vec3 bd3D = normalize( lightToPosition );\n float depth = textureCube( shadowMap, bd3D ).r;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n depth = 1.0 - depth;\n #endif\n shadow = step( dp, depth );\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #endif\n #endif\n#endif";
20068
+ var shadowmap_pars_vertex = "#if NUM_SPOT_LIGHT_COORDS > 0\n uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n #if NUM_SUN_LIGHT_SHADOWS > 0\n varying vec4 vSunShadowWorldPosition;\n varying vec3 vSunShadowWorldNormal;\n #endif\n #if NUM_DIR_LIGHT_SHADOWS > 0\n uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n struct DirectionalLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n struct SpotLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n struct PointLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n float shadowCameraNear;\n float shadowCameraFar;\n };\n uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n#endif";
20069
+ var shadowmap_vertex = "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SUN_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n #ifdef HAS_NORMAL\n vec3 shadowWorldNormal = transformNormalByInverseViewMatrix( transformedNormal, viewMatrix );\n #else\n vec3 shadowWorldNormal = vec3( 0.0 );\n #endif\n vec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n #if NUM_SUN_LIGHT_SHADOWS > 0\n vSunShadowWorldPosition = vec4( worldPosition.xyz, - mvPosition.z );\n vSunShadowWorldNormal = shadowWorldNormal;\n #endif\n #if NUM_DIR_LIGHT_SHADOWS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n #endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n shadowWorldPosition = worldPosition;\n #if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n shadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n #endif\n vSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n#endif";
20070
+ var shadowmask_pars_fragment = "float getShadowMask() {\n float shadow = 1.0;\n #ifdef USE_SHADOWMAP\n #if NUM_SUN_LIGHT_SHADOWS > 0\n SunLightShadow sunLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SUN_LIGHT_SHADOWS; i ++ ) {\n sunLight = sunLightShadows[ i ];\n shadow *= receiveShadow ? getSunShadow( sunShadowMap[ i ], sunLight, UNROLLED_LOOP_INDEX ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_DIR_LIGHT_SHADOWS > 0\n DirectionalLightShadow directionalLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n directionalLight = directionalLightShadows[ i ];\n shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n SpotLightShadow spotLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n spotLight = spotLightShadows[ i ];\n shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0 && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n PointLightShadow pointLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n pointLight = pointLightShadows[ i ];\n shadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #endif\n return shadow;\n}";
19642
20071
  var skinbase_vertex = "#ifdef USE_SKINNING\n mat4 boneMatX = getBoneMatrix( skinIndex.x );\n mat4 boneMatY = getBoneMatrix( skinIndex.y );\n mat4 boneMatZ = getBoneMatrix( skinIndex.z );\n mat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif";
19643
20072
  var skinning_pars_vertex = "#ifdef USE_SKINNING\n uniform mat4 bindMatrix;\n uniform mat4 bindMatrixInverse;\n uniform highp sampler2D boneTexture;\n mat4 getBoneMatrix( const in float i ) {\n int size = textureSize( boneTexture, 0 ).x;\n int j = int( i ) * 4;\n int x = j % size;\n int y = j / size;\n vec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n vec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n vec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n vec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n return mat4( v1, v2, v3, v4 );\n }\n#endif";
19644
20073
  var skinning_vertex = "#ifdef USE_SKINNING\n vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n vec4 skinned = vec4( 0.0 );\n skinned += boneMatX * skinVertex * skinWeight.x;\n skinned += boneMatY * skinVertex * skinWeight.y;\n skinned += boneMatZ * skinVertex * skinWeight.z;\n skinned += boneMatW * skinVertex * skinWeight.w;\n transformed = ( bindMatrixInverse * skinned ).xyz;\n#endif";
@@ -19678,7 +20107,7 @@ const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SH
19678
20107
  const vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphinstance_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}";
19679
20108
  const fragment$6 = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_phong_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n #include <envmap_fragment>\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}";
19680
20109
  const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n varying vec3 vWorldPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n#ifdef USE_TRANSMISSION\n vWorldPosition = worldPosition.xyz;\n#endif\n}";
19681
- const fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n #define IOR\n #define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n uniform float ior;\n#endif\n#ifdef USE_SPECULAR\n uniform float specularIntensity;\n uniform vec3 specularColor;\n #ifdef USE_SPECULAR_COLORMAP\n uniform sampler2D specularColorMap;\n #endif\n #ifdef USE_SPECULAR_INTENSITYMAP\n uniform sampler2D specularIntensityMap;\n #endif\n#endif\n#ifdef USE_CLEARCOAT\n uniform float clearcoat;\n uniform float clearcoatRoughness;\n#endif\n#ifdef USE_DISPERSION\n uniform float dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n uniform float iridescence;\n uniform float iridescenceIOR;\n uniform float iridescenceThicknessMinimum;\n uniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n uniform vec3 sheenColor;\n uniform float sheenRoughness;\n #ifdef USE_SHEEN_COLORMAP\n uniform sampler2D sheenColorMap;\n #endif\n #ifdef USE_SHEEN_ROUGHNESSMAP\n uniform sampler2D sheenRoughnessMap;\n #endif\n#endif\n#ifdef USE_ANISOTROPY\n uniform vec2 anisotropyVector;\n #ifdef USE_ANISOTROPYMAP\n uniform sampler2D anisotropyMap;\n #endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <iridescence_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <iridescence_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <roughnessmap_fragment>\n #include <metalnessmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <clearcoat_normal_fragment_begin>\n #include <clearcoat_normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_physical_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n vec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n #include <transmission_fragment>\n vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n #ifdef USE_SHEEN\n \n outgoingLight = outgoingLight + sheenSpecularDirect + sheenSpecularIndirect;\n \n #endif\n #ifdef USE_CLEARCOAT\n float dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n vec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n outgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n #endif\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}";
20110
+ const fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n #define IOR\n #define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n uniform float ior;\n#endif\n#ifdef USE_SPECULAR\n uniform float specularIntensity;\n uniform vec3 specularColor;\n #ifdef USE_SPECULAR_COLORMAP\n uniform sampler2D specularColorMap;\n #endif\n #ifdef USE_SPECULAR_INTENSITYMAP\n uniform sampler2D specularIntensityMap;\n #endif\n#endif\n#ifdef USE_CLEARCOAT\n uniform float clearcoat;\n uniform float clearcoatRoughness;\n#endif\n#ifdef USE_DISPERSION\n uniform float dispersion;\n#endif\n#ifdef USE_RETROREFLECTION\n uniform float retroreflectivity;\n#endif\n#ifdef USE_IRIDESCENCE\n uniform float iridescence;\n uniform float iridescenceIOR;\n uniform float iridescenceThicknessMinimum;\n uniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n uniform vec3 sheenColor;\n uniform float sheenRoughness;\n #ifdef USE_SHEEN_COLORMAP\n uniform sampler2D sheenColorMap;\n #endif\n #ifdef USE_SHEEN_ROUGHNESSMAP\n uniform sampler2D sheenRoughnessMap;\n #endif\n#endif\n#ifdef USE_ANISOTROPY\n uniform vec2 anisotropyVector;\n #ifdef USE_ANISOTROPYMAP\n uniform sampler2D anisotropyMap;\n #endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <iridescence_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <iridescence_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <roughnessmap_fragment>\n #include <metalnessmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <clearcoat_normal_fragment_begin>\n #include <clearcoat_normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_physical_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n vec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n #include <transmission_fragment>\n vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n #ifdef USE_SHEEN\n \n outgoingLight = outgoingLight + sheenSpecularDirect + sheenSpecularIndirect;\n \n #endif\n #ifdef USE_CLEARCOAT\n float dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n vec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n outgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n #endif\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}";
19682
20111
  const vertex$4 = "#define TOON\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}";
19683
20112
  const fragment$4 = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_toon_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}";
19684
20113
  const vertex$3 = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n#ifdef USE_POINTS_UV\n varying vec2 vUv;\n uniform mat3 uvTransform;\n#endif\nvoid main() {\n #ifdef USE_POINTS_UV\n vUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n #endif\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <project_vertex>\n gl_PointSize = size;\n #ifdef USE_SIZEATTENUATION\n bool isPerspective = isPerspectiveMatrix( projectionMatrix );\n if ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n #endif\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <worldpos_vertex>\n #include <fog_vertex>\n}";
@@ -19907,6 +20336,19 @@ const UniformsLib = {
19907
20336
  lights: {
19908
20337
  ambientLightColor: { value: [] },
19909
20338
  lightProbe: { value: [] },
20339
+ sunLights: { value: [], properties: {
20340
+ direction: {},
20341
+ color: {}
20342
+ } },
20343
+ sunLightShadows: { value: [], properties: {
20344
+ shadowIntensity: 1,
20345
+ shadowBias: {},
20346
+ shadowNormalBias: {},
20347
+ shadowRadius: {},
20348
+ shadowMapSize: {}
20349
+ } },
20350
+ sunShadowMatrix: { value: [] },
20351
+ sunShadowCascade: { value: [] },
19910
20352
  directionalLights: { value: [], properties: {
19911
20353
  direction: {},
19912
20354
  color: {}
@@ -20234,6 +20676,7 @@ ShaderLib.physical = {
20234
20676
  clearcoatRoughnessMap: { value: null },
20235
20677
  clearcoatRoughnessMapTransform: { value: /* @__PURE__ */ new Matrix3$1() },
20236
20678
  dispersion: { value: 0 },
20679
+ retroreflectivity: { value: 0 },
20237
20680
  iridescence: { value: 0 },
20238
20681
  iridescenceMap: { value: null },
20239
20682
  iridescenceMapTransform: { value: /* @__PURE__ */ new Matrix3$1() },
@@ -20852,8 +21295,7 @@ function WebGLCapabilities(gl, extensions, parameters, utils) {
20852
21295
  }
20853
21296
  function textureTypeReadable(textureType) {
20854
21297
  const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has("EXT_color_buffer_half_float") || extensions.has("EXT_color_buffer_float"));
20855
- if (textureType !== UnsignedByteType && utils.convert(textureType) !== gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513)
20856
- textureType !== FloatType && !halfFloatSupportedByExt) {
21298
+ if (textureType !== UnsignedByteType && textureType !== FloatType && !halfFloatSupportedByExt && utils.convert(textureType) !== gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE)) {
20857
21299
  return false;
20858
21300
  }
20859
21301
  return true;
@@ -20996,8 +21438,8 @@ function WebGLClipping(properties) {
20996
21438
  }
20997
21439
  }
20998
21440
  const LOD_MIN = 4;
20999
- const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582];
21000
- const MAX_SAMPLES = 20;
21441
+ const EXTRA_LODS = 6;
21442
+ const BLUR_SAMPLES = 20;
21001
21443
  const GGX_SAMPLES = 256;
21002
21444
  const _flatCamera = /* @__PURE__ */ new OrthographicCamera();
21003
21445
  const _clearColor = /* @__PURE__ */ new Color();
@@ -21006,6 +21448,7 @@ let _oldActiveCubeFace = 0;
21006
21448
  let _oldActiveMipmapLevel = 0;
21007
21449
  let _oldXrEnabled = false;
21008
21450
  const _origin = /* @__PURE__ */ new Vector3$1();
21451
+ const _direction = /* @__PURE__ */ new Vector3$1();
21009
21452
  class PMREMGenerator {
21010
21453
  /**
21011
21454
  * Constructs a new PMREM generator.
@@ -21018,7 +21461,6 @@ class PMREMGenerator {
21018
21461
  this._lodMax = 0;
21019
21462
  this._cubeSize = 0;
21020
21463
  this._sizeLods = [];
21021
- this._sigmas = [];
21022
21464
  this._lodMeshes = [];
21023
21465
  this._backgroundBox = null;
21024
21466
  this._cubemapMaterial = null;
@@ -21177,7 +21619,7 @@ class PMREMGenerator {
21177
21619
  }
21178
21620
  this._pingPongRenderTarget = _createRenderTarget(width, height, params);
21179
21621
  const { _lodMax } = this;
21180
- ({ lodMeshes: this._lodMeshes, sizeLods: this._sizeLods, sigmas: this._sigmas } = _createPlanes(_lodMax));
21622
+ ({ lodMeshes: this._lodMeshes, sizeLods: this._sizeLods } = _createPlanes(_lodMax));
21181
21623
  this._blurMaterial = _getBlurShader(_lodMax, width, height);
21182
21624
  this._ggxMaterial = _getGGXShader(_lodMax, width, height);
21183
21625
  }
@@ -21311,7 +21753,7 @@ class PMREMGenerator {
21311
21753
  const targetRoughness = lodOut / (this._lodMeshes.length - 1);
21312
21754
  const sourceRoughness = lodIn / (this._lodMeshes.length - 1);
21313
21755
  const incrementalRoughness = Math.sqrt(targetRoughness * targetRoughness - sourceRoughness * sourceRoughness);
21314
- const blurStrength = 0 + targetRoughness * 1.25;
21756
+ const blurStrength = targetRoughness * 1.25;
21315
21757
  const adjustedRoughness = incrementalRoughness * blurStrength;
21316
21758
  const { _lodMax } = this;
21317
21759
  const outputSize = this._sizeLods[lodOut];
@@ -21331,11 +21773,9 @@ class PMREMGenerator {
21331
21773
  renderer.render(ggxMesh, _flatCamera);
21332
21774
  }
21333
21775
  /**
21334
- * This is a two-pass Gaussian blur for a cubemap. Normally this is done
21335
- * vertically and horizontally, but this breaks down on a cube. Here we apply
21336
- * the blur latitudinally (around the poles), and then longitudinally (towards
21337
- * the poles) to approximate the orthogonally-separable blur. It is least
21338
- * accurate at the poles, but still does a decent job.
21776
+ * This is a two-pass Gaussian blur for a cubemap. Each pass importance-samples
21777
+ * the Gaussian along a spiral kernel (Golden Angle), which distributes samples
21778
+ * isotropically on the sphere (no pole artifacts).
21339
21779
  *
21340
21780
  * Used for initial scene blur in fromScene() method when sigma > 0.
21341
21781
  *
@@ -21344,75 +21784,24 @@ class PMREMGenerator {
21344
21784
  * @param {number} lodIn
21345
21785
  * @param {number} lodOut
21346
21786
  * @param {number} sigma
21347
- * @param {Vector3} [poleAxis]
21348
21787
  */
21349
- _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) {
21788
+ _blur(cubeUVRenderTarget, lodIn, lodOut, sigma) {
21350
21789
  const pingPongRenderTarget = this._pingPongRenderTarget;
21351
- this._halfBlur(
21352
- cubeUVRenderTarget,
21353
- pingPongRenderTarget,
21354
- lodIn,
21355
- lodOut,
21356
- sigma,
21357
- "latitudinal",
21358
- poleAxis
21359
- );
21360
- this._halfBlur(
21361
- pingPongRenderTarget,
21362
- cubeUVRenderTarget,
21363
- lodOut,
21364
- lodOut,
21365
- sigma,
21366
- "longitudinal",
21367
- poleAxis
21368
- );
21790
+ const blurSigma = Math.min(sigma, Math.PI) / Math.SQRT2;
21791
+ this._blurPass(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, blurSigma);
21792
+ this._blurPass(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, blurSigma);
21369
21793
  }
21370
- _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) {
21794
+ _blurPass(targetIn, targetOut, lodIn, lodOut, sigmaRadians) {
21371
21795
  const renderer = this._renderer;
21372
21796
  const blurMaterial = this._blurMaterial;
21373
- if (direction !== "latitudinal" && direction !== "longitudinal") {
21374
- error(
21375
- "blur direction must be either latitudinal or longitudinal!"
21376
- );
21377
- }
21378
- const STANDARD_DEVIATIONS = 3;
21379
21797
  const blurMesh = this._lodMeshes[lodOut];
21380
21798
  blurMesh.material = blurMaterial;
21381
21799
  const blurUniforms = blurMaterial.uniforms;
21382
- const pixels = this._sizeLods[lodIn] - 1;
21383
- const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1);
21384
- const sigmaPixels = sigmaRadians / radiansPerPixel;
21385
- const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES;
21386
- if (samples > MAX_SAMPLES) {
21387
- warn(`sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${samples} samples when the maximum is set to ${MAX_SAMPLES}`);
21388
- }
21389
- const weights = [];
21390
- let sum = 0;
21391
- for (let i = 0; i < MAX_SAMPLES; ++i) {
21392
- const x2 = i / sigmaPixels;
21393
- const weight = Math.exp(-x2 * x2 / 2);
21394
- weights.push(weight);
21395
- if (i === 0) {
21396
- sum += weight;
21397
- } else if (i < samples) {
21398
- sum += 2 * weight;
21399
- }
21400
- }
21401
- for (let i = 0; i < weights.length; i++) {
21402
- weights[i] = weights[i] / sum;
21403
- }
21404
21800
  blurUniforms["envMap"].value = targetIn.texture;
21405
- blurUniforms["samples"].value = samples;
21406
- blurUniforms["weights"].value = weights;
21407
- blurUniforms["latitudinal"].value = direction === "latitudinal";
21408
- if (poleAxis) {
21409
- blurUniforms["poleAxis"].value = poleAxis;
21410
- }
21411
- const { _lodMax } = this;
21412
- blurUniforms["dTheta"].value = radiansPerPixel;
21413
- blurUniforms["mipInt"].value = _lodMax - lodIn;
21801
+ blurUniforms["sigma"].value = sigmaRadians;
21802
+ blurUniforms["mipInt"].value = this._lodMax - lodIn;
21414
21803
  const outputSize = this._sizeLods[lodOut];
21415
- const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0);
21804
+ const x = 3 * outputSize * (lodOut > this._lodMax - LOD_MIN ? lodOut - this._lodMax + LOD_MIN : 0);
21416
21805
  const y = 4 * (this._cubeSize - outputSize);
21417
21806
  _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize);
21418
21807
  renderer.setRenderTarget(targetOut);
@@ -21421,20 +21810,12 @@ class PMREMGenerator {
21421
21810
  }
21422
21811
  function _createPlanes(lodMax) {
21423
21812
  const sizeLods = [];
21424
- const sigmas = [];
21425
21813
  const lodMeshes = [];
21426
21814
  let lod = lodMax;
21427
- const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length;
21815
+ const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LODS;
21428
21816
  for (let i = 0; i < totalLods; i++) {
21429
21817
  const sizeLod = Math.pow(2, lod);
21430
21818
  sizeLods.push(sizeLod);
21431
- let sigma = 1 / sizeLod;
21432
- if (i > lodMax - LOD_MIN) {
21433
- sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1];
21434
- } else if (i === 0) {
21435
- sigma = 0;
21436
- }
21437
- sigmas.push(sigma);
21438
21819
  const texelSize = 1 / (sizeLod - 2);
21439
21820
  const min = -texelSize;
21440
21821
  const max = 1 + texelSize;
@@ -21442,11 +21823,8 @@ function _createPlanes(lodMax) {
21442
21823
  const cubeFaces = 6;
21443
21824
  const vertices = 6;
21444
21825
  const positionSize = 3;
21445
- const uvSize = 2;
21446
- const faceIndexSize = 1;
21447
21826
  const position = new Float32Array(positionSize * vertices * cubeFaces);
21448
- const uv = new Float32Array(uvSize * vertices * cubeFaces);
21449
- const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces);
21827
+ const outputDirection = new Float32Array(positionSize * vertices * cubeFaces);
21450
21828
  for (let face = 0; face < cubeFaces; face++) {
21451
21829
  const x = face % 3 * 2 / 3 - 1;
21452
21830
  const y = face > 2 ? 0 : -1;
@@ -21471,20 +21849,34 @@ function _createPlanes(lodMax) {
21471
21849
  0
21472
21850
  ];
21473
21851
  position.set(coordinates, positionSize * vertices * face);
21474
- uv.set(uv1, uvSize * vertices * face);
21475
- const fill2 = [face, face, face, face, face, face];
21476
- faceIndex.set(fill2, faceIndexSize * vertices * face);
21852
+ for (let vertex2 = 0; vertex2 < vertices; vertex2++) {
21853
+ const u = uv1[vertex2 * 2] * 2 - 1;
21854
+ const v = uv1[vertex2 * 2 + 1] * 2 - 1;
21855
+ if (face === 0) {
21856
+ _direction.set(1, v, u);
21857
+ } else if (face === 1) {
21858
+ _direction.set(-u, 1, -v);
21859
+ } else if (face === 2) {
21860
+ _direction.set(-u, v, 1);
21861
+ } else if (face === 3) {
21862
+ _direction.set(-1, v, -u);
21863
+ } else if (face === 4) {
21864
+ _direction.set(-u, -1, v);
21865
+ } else {
21866
+ _direction.set(u, v, -1);
21867
+ }
21868
+ _direction.toArray(outputDirection, (face * vertices + vertex2) * positionSize);
21869
+ }
21477
21870
  }
21478
21871
  const planes = new BufferGeometry();
21479
21872
  planes.setAttribute("position", new BufferAttribute(position, positionSize));
21480
- planes.setAttribute("uv", new BufferAttribute(uv, uvSize));
21481
- planes.setAttribute("faceIndex", new BufferAttribute(faceIndex, faceIndexSize));
21873
+ planes.setAttribute("outputDirection", new BufferAttribute(outputDirection, positionSize));
21482
21874
  lodMeshes.push(new Mesh(planes, null));
21483
21875
  if (lod > LOD_MIN) {
21484
21876
  lod--;
21485
21877
  }
21486
21878
  }
21487
- return { lodMeshes, sizeLods, sigmas };
21879
+ return { lodMeshes, sizeLods };
21488
21880
  }
21489
21881
  function _createRenderTarget(width, height, params) {
21490
21882
  const cubeUVRenderTarget = new WebGLRenderTarget(width, height, params);
@@ -21627,87 +22019,81 @@ function _getGGXShader(lodMax, width, height) {
21627
22019
  return shaderMaterial;
21628
22020
  }
21629
22021
  function _getBlurShader(lodMax, width, height) {
21630
- const weights = new Float32Array(MAX_SAMPLES);
21631
- const poleAxis = new Vector3$1(0, 1, 0);
21632
22022
  const shaderMaterial = new ShaderMaterial({
21633
22023
  name: "SphericalGaussianBlur",
21634
22024
  defines: {
21635
- "n": MAX_SAMPLES,
22025
+ "SAMPLES": BLUR_SAMPLES,
21636
22026
  "CUBEUV_TEXEL_WIDTH": 1 / width,
21637
22027
  "CUBEUV_TEXEL_HEIGHT": 1 / height,
21638
22028
  "CUBEUV_MAX_MIP": `${lodMax}.0`
21639
22029
  },
21640
22030
  uniforms: {
21641
22031
  "envMap": { value: null },
21642
- "samples": { value: 1 },
21643
- "weights": { value: weights },
21644
- "latitudinal": { value: false },
21645
- "dTheta": { value: 0 },
21646
- "mipInt": { value: 0 },
21647
- "poleAxis": { value: poleAxis }
22032
+ "sigma": { value: 0 },
22033
+ "mipInt": { value: 0 }
21648
22034
  },
21649
22035
  vertexShader: _getCommonVertexShader(),
21650
22036
  fragmentShader: (
21651
22037
  /* glsl */
21652
22038
  `
21653
22039
 
21654
- precision mediump float;
21655
- precision mediump int;
22040
+ precision highp float;
22041
+ precision highp int;
21656
22042
 
21657
22043
  varying vec3 vOutputDirection;
21658
22044
 
21659
22045
  uniform sampler2D envMap;
21660
- uniform int samples;
21661
- uniform float weights[ n ];
21662
- uniform bool latitudinal;
21663
- uniform float dTheta;
22046
+ uniform float sigma;
21664
22047
  uniform float mipInt;
21665
- uniform vec3 poleAxis;
21666
22048
 
21667
22049
  #define ENVMAP_TYPE_CUBE_UV
21668
22050
  #include <cube_uv_reflection_fragment>
21669
22051
 
21670
- vec3 getSample( float theta, vec3 axis ) {
21671
-
21672
- float cosTheta = cos( theta );
21673
- // Rodrigues' axis-angle rotation
21674
- vec3 sampleDirection = vOutputDirection * cosTheta
21675
- + cross( axis, vOutputDirection ) * sin( theta )
21676
- + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );
21677
-
21678
- return bilinearCubeUV( envMap, sampleDirection, mipInt );
21679
-
21680
- }
22052
+ #define PI 3.14159265359
22053
+ #define GOLDEN_ANGLE 2.39996322973
21681
22054
 
21682
22055
  void main() {
21683
22056
 
21684
- vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );
22057
+ if ( sigma == 0.0 ) {
21685
22058
 
21686
- if ( all( equal( axis, vec3( 0.0 ) ) ) ) {
21687
-
21688
- axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );
22059
+ gl_FragColor = vec4( bilinearCubeUV( envMap, vOutputDirection, mipInt ), 1.0 );
22060
+ return;
21689
22061
 
21690
22062
  }
21691
22063
 
21692
- axis = normalize( axis );
22064
+ vec3 outputDirection = normalize( vOutputDirection );
21693
22065
 
21694
- gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
21695
- gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );
22066
+ vec3 up = abs( outputDirection.z ) < 0.999 ? vec3( 0.0, 0.0, 1.0 ) : vec3( 1.0, 0.0, 0.0 );
22067
+ vec3 tangent = normalize( cross( up, outputDirection ) );
22068
+ vec3 bitangent = cross( outputDirection, tangent );
21696
22069
 
21697
- for ( int i = 1; i < n; i++ ) {
22070
+ // Truncate the kernel at three standard deviations or at the antipode.
22071
+ float thetaMax = min( 3.0 * sigma, PI );
22072
+ float truncation = 1.0 - exp( - 0.5 * thetaMax * thetaMax / ( sigma * sigma ) );
21698
22073
 
21699
- if ( i >= samples ) {
22074
+ vec3 accumColor = vec3( 0.0 );
22075
+ float accumWeight = 0.0;
21700
22076
 
21701
- break;
22077
+ for ( int i = 0; i < SAMPLES; i ++ ) {
21702
22078
 
21703
- }
22079
+ // Stratified inverse-CDF sampling of the Gaussian, placed on a golden-angle spiral.
22080
+ float stratum = ( float( i ) + 0.5 ) / float( SAMPLES );
22081
+ float theta = sigma * sqrt( - 2.0 * log( 1.0 - stratum * truncation ) );
22082
+ float phi = float( i ) * GOLDEN_ANGLE;
21704
22083
 
21705
- float theta = dTheta * float( i );
21706
- gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );
21707
- gl_FragColor.rgb += weights[ i ] * getSample( theta, axis );
22084
+ vec3 offset = cos( phi ) * tangent + sin( phi ) * bitangent;
22085
+ vec3 sampleDirection = cos( theta ) * outputDirection + sin( theta ) * offset;
22086
+
22087
+ // Correct the planar sample density to solid angle.
22088
+ float weight = sin( theta ) / theta;
22089
+
22090
+ accumColor += weight * bilinearCubeUV( envMap, sampleDirection, mipInt );
22091
+ accumWeight += weight;
21708
22092
 
21709
22093
  }
21710
22094
 
22095
+ gl_FragColor = vec4( accumColor / accumWeight, 1.0 );
22096
+
21711
22097
  }
21712
22098
  `
21713
22099
  ),
@@ -21793,53 +22179,13 @@ function _getCommonVertexShader() {
21793
22179
  precision mediump float;
21794
22180
  precision mediump int;
21795
22181
 
21796
- attribute float faceIndex;
22182
+ attribute vec3 outputDirection;
21797
22183
 
21798
22184
  varying vec3 vOutputDirection;
21799
22185
 
21800
- // RH coordinate system; PMREM face-indexing convention
21801
- vec3 getDirection( vec2 uv, float face ) {
21802
-
21803
- uv = 2.0 * uv - 1.0;
21804
-
21805
- vec3 direction = vec3( uv, 1.0 );
21806
-
21807
- if ( face == 0.0 ) {
21808
-
21809
- direction = direction.zyx; // ( 1, v, u ) pos x
21810
-
21811
- } else if ( face == 1.0 ) {
21812
-
21813
- direction = direction.xzy;
21814
- direction.xz *= -1.0; // ( -u, 1, -v ) pos y
21815
-
21816
- } else if ( face == 2.0 ) {
21817
-
21818
- direction.x *= -1.0; // ( -u, v, 1 ) pos z
21819
-
21820
- } else if ( face == 3.0 ) {
21821
-
21822
- direction = direction.zyx;
21823
- direction.xz *= -1.0; // ( -1, v, -u ) neg x
21824
-
21825
- } else if ( face == 4.0 ) {
21826
-
21827
- direction = direction.xzy;
21828
- direction.xy *= -1.0; // ( -u, -1, v ) neg y
21829
-
21830
- } else if ( face == 5.0 ) {
21831
-
21832
- direction.z *= -1.0; // ( u, v, -1 ) neg z
21833
-
21834
- }
21835
-
21836
- return direction;
21837
-
21838
- }
21839
-
21840
22186
  void main() {
21841
22187
 
21842
- vOutputDirection = getDirection( uv, faceIndex );
22188
+ vOutputDirection = outputDirection;
21843
22189
  gl_Position = vec4( position, 1.0 );
21844
22190
 
21845
22191
  }
@@ -22430,18 +22776,18 @@ const toneMappingMap = {
22430
22776
  [CustomToneMapping]: "CUSTOM_TONE_MAPPING"
22431
22777
  };
22432
22778
  function WebGLOutput(type, width, height, antialias, depth, stencil) {
22433
- const targetA = new WebGLRenderTarget(width, height, {
22779
+ const targetScene = new WebGLRenderTarget(width, height, {
22434
22780
  type,
22435
22781
  depthBuffer: depth,
22436
22782
  stencilBuffer: stencil,
22437
22783
  samples: antialias ? 4 : 0,
22438
- depthTexture: depth ? new DepthTexture(width, height) : void 0
22439
- });
22440
- const targetB = new WebGLRenderTarget(width, height, {
22441
- type: HalfFloatType,
22442
- depthBuffer: false,
22443
- stencilBuffer: false
22784
+ storeMultisampledDepthBuffer: false,
22785
+ storeMultisampledStencilBuffer: false,
22786
+ resolveDepthBuffer: false,
22787
+ resolveStencilBuffer: false
22444
22788
  });
22789
+ let targetA = null;
22790
+ let targetB = null;
22445
22791
  const geometry = new BufferGeometry();
22446
22792
  geometry.setAttribute("position", new Float32BufferAttribute([-1, 3, 0, -1, -1, 0, 3, -1, 0], 3));
22447
22793
  geometry.setAttribute("uv", new Float32BufferAttribute([0, 2, 0, 0, 2, 0], 2));
@@ -22516,8 +22862,9 @@ function WebGLOutput(type, width, height, antialias, depth, stencil) {
22516
22862
  let _effects = [];
22517
22863
  let _hasRenderPass = false;
22518
22864
  this.setSize = function(width2, height2) {
22519
- targetA.setSize(width2, height2);
22520
- targetB.setSize(width2, height2);
22865
+ targetScene.setSize(width2, height2);
22866
+ if (targetA !== null) targetA.setSize(width2, height2);
22867
+ if (targetB !== null) targetB.setSize(width2, height2);
22521
22868
  for (let i = 0; i < _effects.length; i++) {
22522
22869
  const effect = _effects[i];
22523
22870
  if (effect.setSize) effect.setSize(width2, height2);
@@ -22526,8 +22873,12 @@ function WebGLOutput(type, width, height, antialias, depth, stencil) {
22526
22873
  this.setEffects = function(effects) {
22527
22874
  _effects = effects;
22528
22875
  _hasRenderPass = _effects.length > 0 && _effects[0].isRenderPass === true;
22529
- const width2 = targetA.width;
22530
- const height2 = targetA.height;
22876
+ const width2 = targetScene.width;
22877
+ const height2 = targetScene.height;
22878
+ if (_effects.length > 0 && targetA === null) {
22879
+ targetA = new WebGLRenderTarget(width2, height2, { type: HalfFloatType, depthBuffer: false, stencilBuffer: false });
22880
+ targetB = new WebGLRenderTarget(width2, height2, { type: HalfFloatType, depthBuffer: false, stencilBuffer: false });
22881
+ }
22531
22882
  for (let i = 0; i < _effects.length; i++) {
22532
22883
  const effect = _effects[i];
22533
22884
  if (effect.setSize) effect.setSize(width2, height2);
@@ -22540,12 +22891,12 @@ function WebGLOutput(type, width, height, antialias, depth, stencil) {
22540
22891
  if (renderTarget !== null) {
22541
22892
  const width2 = renderTarget.width;
22542
22893
  const height2 = renderTarget.height;
22543
- if (targetA.width !== width2 || targetA.height !== height2) {
22894
+ if (targetScene.width !== width2 || targetScene.height !== height2) {
22544
22895
  this.setSize(width2, height2);
22545
22896
  }
22546
22897
  }
22547
22898
  if (_hasRenderPass === false) {
22548
- renderer.setRenderTarget(targetA);
22899
+ renderer.setRenderTarget(targetScene);
22549
22900
  }
22550
22901
  _savedToneMapping = renderer.toneMapping;
22551
22902
  renderer.toneMapping = NoToneMapping;
@@ -22557,16 +22908,15 @@ function WebGLOutput(type, width, height, antialias, depth, stencil) {
22557
22908
  this.end = function(renderer, deltaTime) {
22558
22909
  renderer.toneMapping = _savedToneMapping;
22559
22910
  _isCompositing = true;
22560
- let readBuffer = targetA;
22561
- let writeBuffer = targetB;
22911
+ let readBuffer = targetScene;
22912
+ let writeBuffer = targetA;
22562
22913
  for (let i = 0; i < _effects.length; i++) {
22563
22914
  const effect = _effects[i];
22564
22915
  if (effect.enabled === false) continue;
22565
22916
  effect.render(renderer, writeBuffer, readBuffer, deltaTime);
22566
22917
  if (effect.needsSwap !== false) {
22567
- const temp = readBuffer;
22568
22918
  readBuffer = writeBuffer;
22569
- writeBuffer = temp;
22919
+ writeBuffer = writeBuffer === targetA ? targetB : targetA;
22570
22920
  }
22571
22921
  }
22572
22922
  if (_outputColorSpace !== renderer.outputColorSpace || _outputToneMapping !== renderer.toneMapping) {
@@ -22588,9 +22938,9 @@ function WebGLOutput(type, width, height, antialias, depth, stencil) {
22588
22938
  return _isCompositing;
22589
22939
  };
22590
22940
  this.dispose = function() {
22591
- if (targetA.depthTexture) targetA.depthTexture.dispose();
22592
- targetA.dispose();
22593
- targetB.dispose();
22941
+ targetScene.dispose();
22942
+ if (targetA !== null) targetA.dispose();
22943
+ if (targetB !== null) targetB.dispose();
22594
22944
  geometry.dispose();
22595
22945
  material.dispose();
22596
22946
  };
@@ -23396,7 +23746,7 @@ function filterEmptyLine(string) {
23396
23746
  }
23397
23747
  function replaceLightNums(string, parameters) {
23398
23748
  const numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps;
23399
- return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g, parameters.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g, numSpotLightCoords).replace(/NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g, parameters.numPointLights).replace(/NUM_HEMI_LIGHTS/g, parameters.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g, parameters.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows);
23749
+ return string.replace(/NUM_SUN_LIGHTS/g, parameters.numSunLights).replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g, parameters.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g, numSpotLightCoords).replace(/NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g, parameters.numPointLights).replace(/NUM_HEMI_LIGHTS/g, parameters.numHemiLights).replace(/NUM_SUN_LIGHT_SHADOWS/g, parameters.numSunLightShadows).replace(/NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g, parameters.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows);
23400
23750
  }
23401
23751
  function replaceClippingPlaneNums(string, parameters) {
23402
23752
  return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection);
@@ -23696,6 +24046,7 @@ function WebGLProgram(renderer, cacheKey, parameters, bindingStates) {
23696
24046
  parameters.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "",
23697
24047
  parameters.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "",
23698
24048
  parameters.dispersion ? "#define USE_DISPERSION" : "",
24049
+ parameters.retroreflection ? "#define USE_RETROREFLECTION" : "",
23699
24050
  parameters.iridescence ? "#define USE_IRIDESCENCE" : "",
23700
24051
  parameters.iridescenceMap ? "#define USE_IRIDESCENCEMAP" : "",
23701
24052
  parameters.iridescenceThicknessMap ? "#define USE_IRIDESCENCE_THICKNESSMAP" : "",
@@ -24025,6 +24376,7 @@ function WebGLPrograms(renderer, environments, extensions, capabilities, binding
24025
24376
  const HAS_ANISOTROPY = material.anisotropy > 0;
24026
24377
  const HAS_CLEARCOAT = material.clearcoat > 0;
24027
24378
  const HAS_DISPERSION = material.dispersion > 0;
24379
+ const HAS_RETROREFLECTION = material.retroreflectivity > 0;
24028
24380
  const HAS_IRIDESCENCE = material.iridescence > 0;
24029
24381
  const HAS_SHEEN = material.sheen > 0;
24030
24382
  const HAS_TRANSMISSION = material.transmission > 0;
@@ -24094,6 +24446,7 @@ function WebGLPrograms(renderer, environments, extensions, capabilities, binding
24094
24446
  clearcoatNormalMap: HAS_CLEARCOAT_NORMALMAP,
24095
24447
  clearcoatRoughnessMap: HAS_CLEARCOAT_ROUGHNESSMAP,
24096
24448
  dispersion: HAS_DISPERSION,
24449
+ retroreflection: HAS_RETROREFLECTION,
24097
24450
  iridescence: HAS_IRIDESCENCE,
24098
24451
  iridescenceMap: HAS_IRIDESCENCEMAP,
24099
24452
  iridescenceThicknessMap: HAS_IRIDESCENCE_THICKNESSMAP,
@@ -24156,12 +24509,14 @@ function WebGLPrograms(renderer, environments, extensions, capabilities, binding
24156
24509
  morphColors: geometry.morphAttributes.color !== void 0,
24157
24510
  morphTargetsCount,
24158
24511
  morphTextureStride,
24512
+ numSunLights: lights.sun.length,
24159
24513
  numDirLights: lights.directional.length,
24160
24514
  numPointLights: lights.point.length,
24161
24515
  numSpotLights: lights.spot.length,
24162
24516
  numSpotLightMaps: lights.spotLightMap.length,
24163
24517
  numRectAreaLights: lights.rectArea.length,
24164
24518
  numHemiLights: lights.hemi.length,
24519
+ numSunLightShadows: lights.sunShadowMap.length,
24165
24520
  numDirLightShadows: lights.directionalShadowMap.length,
24166
24521
  numPointLightShadows: lights.pointShadowMap.length,
24167
24522
  numSpotLightShadows: lights.spotShadowMap.length,
@@ -24248,12 +24603,14 @@ function WebGLPrograms(renderer, environments, extensions, capabilities, binding
24248
24603
  array.push(parameters.sizeAttenuation);
24249
24604
  array.push(parameters.morphTargetsCount);
24250
24605
  array.push(parameters.morphAttributeCount);
24606
+ array.push(parameters.numSunLights);
24251
24607
  array.push(parameters.numDirLights);
24252
24608
  array.push(parameters.numPointLights);
24253
24609
  array.push(parameters.numSpotLights);
24254
24610
  array.push(parameters.numSpotLightMaps);
24255
24611
  array.push(parameters.numHemiLights);
24256
24612
  array.push(parameters.numRectAreaLights);
24613
+ array.push(parameters.numSunLightShadows);
24257
24614
  array.push(parameters.numDirLightShadows);
24258
24615
  array.push(parameters.numPointLightShadows);
24259
24616
  array.push(parameters.numSpotLightShadows);
@@ -24307,6 +24664,8 @@ function WebGLPrograms(renderer, environments, extensions, capabilities, binding
24307
24664
  _programLayers.enable(18);
24308
24665
  if (parameters.dispersion)
24309
24666
  _programLayers.enable(19);
24667
+ if (parameters.retroreflection)
24668
+ _programLayers.enable(24);
24310
24669
  if (parameters.batchingColor)
24311
24670
  _programLayers.enable(20);
24312
24671
  if (parameters.gradientMap)
@@ -24519,7 +24878,8 @@ function WebGLRenderList() {
24519
24878
  renderItemsIndex++;
24520
24879
  return renderItem;
24521
24880
  }
24522
- function push(object, geometry, material, groupOrder, z, group) {
24881
+ function push(object, geometry, material, groupOrder, z, group, camera) {
24882
+ if (camera.reversedDepth === true) z = -z;
24523
24883
  const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group);
24524
24884
  if (material.transmission > 0) {
24525
24885
  transmissive.push(renderItem);
@@ -24539,15 +24899,10 @@ function WebGLRenderList() {
24539
24899
  opaque.unshift(renderItem);
24540
24900
  }
24541
24901
  }
24542
- function sort(customOpaqueSort, customTransparentSort, reversedDepth) {
24902
+ function sort(customOpaqueSort, customTransparentSort) {
24543
24903
  if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable);
24544
24904
  if (transmissive.length > 1) transmissive.sort(customTransparentSort || reversePainterSortStable);
24545
24905
  if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable);
24546
- if (reversedDepth) {
24547
- opaque.reverse();
24548
- transmissive.reverse();
24549
- transparent.reverse();
24550
- }
24551
24906
  }
24552
24907
  function finish() {
24553
24908
  for (let i = renderItemsIndex, il = renderItems.length; i < il; i++) {
@@ -24606,6 +24961,7 @@ function UniformsCache() {
24606
24961
  }
24607
24962
  let uniforms;
24608
24963
  switch (light.type) {
24964
+ case "SunLight":
24609
24965
  case "DirectionalLight":
24610
24966
  uniforms = {
24611
24967
  direction: new Vector3$1(),
@@ -24661,6 +25017,7 @@ function ShadowUniformsCache() {
24661
25017
  }
24662
25018
  let uniforms;
24663
25019
  switch (light.type) {
25020
+ case "SunLight":
24664
25021
  case "DirectionalLight":
24665
25022
  uniforms = {
24666
25023
  shadowIntensity: 1,
@@ -24706,11 +25063,13 @@ function WebGLLights(extensions) {
24706
25063
  const state = {
24707
25064
  version: 0,
24708
25065
  hash: {
25066
+ sunLength: -1,
24709
25067
  directionalLength: -1,
24710
25068
  pointLength: -1,
24711
25069
  spotLength: -1,
24712
25070
  rectAreaLength: -1,
24713
25071
  hemiLength: -1,
25072
+ numSunShadows: -1,
24714
25073
  numDirectionalShadows: -1,
24715
25074
  numPointShadows: -1,
24716
25075
  numSpotShadows: -1,
@@ -24719,6 +25078,11 @@ function WebGLLights(extensions) {
24719
25078
  },
24720
25079
  ambient: [0, 0, 0],
24721
25080
  probe: [],
25081
+ sun: [],
25082
+ sunShadow: [],
25083
+ sunShadowMap: [],
25084
+ sunShadowMatrix: [],
25085
+ sunShadowCascade: [],
24722
25086
  directional: [],
24723
25087
  directionalShadow: [],
24724
25088
  directionalShadowMap: [],
@@ -24746,6 +25110,9 @@ function WebGLLights(extensions) {
24746
25110
  function setup(lights) {
24747
25111
  let r = 0, g = 0, b = 0;
24748
25112
  for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0);
25113
+ let sunLength = 0;
25114
+ let numSunShadows = 0;
25115
+ let numSunShadowCascades = 0;
24749
25116
  let directionalLength = 0;
24750
25117
  let pointLength = 0;
24751
25118
  let spotLength = 0;
@@ -24780,6 +25147,29 @@ function WebGLLights(extensions) {
24780
25147
  state.probe[j].addScaledVector(light.sh.coefficients[j], intensity);
24781
25148
  }
24782
25149
  numLightProbes++;
25150
+ } else if (light.isSunLight) {
25151
+ const uniforms = cache2.get(light);
25152
+ uniforms.color.copy(light.color).multiplyScalar(light.intensity);
25153
+ if (light.castShadow) {
25154
+ const shadow = light.shadow;
25155
+ const shadowUniforms = shadowCache.get(light);
25156
+ shadowUniforms.shadowIntensity = shadow.intensity;
25157
+ shadowUniforms.shadowBias = shadow.bias;
25158
+ shadowUniforms.shadowNormalBias = shadow.normalBias;
25159
+ shadowUniforms.shadowRadius = shadow.radius;
25160
+ shadowUniforms.shadowMapSize.copy(shadow.mapSize).multiply(shadow.getFrameExtents());
25161
+ state.sunShadow[numSunShadows] = shadowUniforms;
25162
+ state.sunShadowMap[numSunShadows] = shadowMap;
25163
+ const cascadeCount = shadow.getViewportCount();
25164
+ for (let j = 0; j < cascadeCount; j++) {
25165
+ state.sunShadowMatrix[numSunShadowCascades + j] = shadow.getMatrix(j);
25166
+ state.sunShadowCascade[numSunShadowCascades + j] = shadow._cascadeData[j];
25167
+ }
25168
+ numSunShadowCascades += cascadeCount;
25169
+ numSunShadows++;
25170
+ }
25171
+ state.sun[sunLength] = uniforms;
25172
+ sunLength++;
24783
25173
  } else if (light.isDirectionalLight) {
24784
25174
  const uniforms = cache2.get(light);
24785
25175
  uniforms.color.copy(light.color).multiplyScalar(light.intensity);
@@ -24877,29 +25267,36 @@ function WebGLLights(extensions) {
24877
25267
  state.ambient[1] = g;
24878
25268
  state.ambient[2] = b;
24879
25269
  const hash = state.hash;
24880
- if (hash.directionalLength !== directionalLength || hash.pointLength !== pointLength || hash.spotLength !== spotLength || hash.rectAreaLength !== rectAreaLength || hash.hemiLength !== hemiLength || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || hash.numSpotShadows !== numSpotShadows || hash.numSpotMaps !== numSpotMaps || hash.numLightProbes !== numLightProbes) {
25270
+ if (hash.sunLength !== sunLength || hash.directionalLength !== directionalLength || hash.pointLength !== pointLength || hash.spotLength !== spotLength || hash.rectAreaLength !== rectAreaLength || hash.hemiLength !== hemiLength || hash.numSunShadows !== numSunShadows || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || hash.numSpotShadows !== numSpotShadows || hash.numSpotMaps !== numSpotMaps || hash.numLightProbes !== numLightProbes) {
25271
+ state.sun.length = sunLength;
24881
25272
  state.directional.length = directionalLength;
24882
25273
  state.spot.length = spotLength;
24883
25274
  state.rectArea.length = rectAreaLength;
24884
25275
  state.point.length = pointLength;
24885
25276
  state.hemi.length = hemiLength;
25277
+ state.sunShadow.length = numSunShadows;
25278
+ state.sunShadowMap.length = numSunShadows;
25279
+ state.sunShadowMatrix.length = numSunShadowCascades;
25280
+ state.sunShadowCascade.length = numSunShadowCascades;
24886
25281
  state.directionalShadow.length = numDirectionalShadows;
24887
25282
  state.directionalShadowMap.length = numDirectionalShadows;
25283
+ state.directionalShadowMatrix.length = numDirectionalShadows;
24888
25284
  state.pointShadow.length = numPointShadows;
24889
25285
  state.pointShadowMap.length = numPointShadows;
25286
+ state.pointShadowMatrix.length = numPointShadows;
24890
25287
  state.spotShadow.length = numSpotShadows;
24891
25288
  state.spotShadowMap.length = numSpotShadows;
24892
- state.directionalShadowMatrix.length = numDirectionalShadows;
24893
- state.pointShadowMatrix.length = numPointShadows;
24894
25289
  state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps;
24895
25290
  state.spotLightMap.length = numSpotMaps;
24896
25291
  state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps;
24897
25292
  state.numLightProbes = numLightProbes;
25293
+ hash.sunLength = sunLength;
24898
25294
  hash.directionalLength = directionalLength;
24899
25295
  hash.pointLength = pointLength;
24900
25296
  hash.spotLength = spotLength;
24901
25297
  hash.rectAreaLength = rectAreaLength;
24902
25298
  hash.hemiLength = hemiLength;
25299
+ hash.numSunShadows = numSunShadows;
24903
25300
  hash.numDirectionalShadows = numDirectionalShadows;
24904
25301
  hash.numPointShadows = numPointShadows;
24905
25302
  hash.numSpotShadows = numSpotShadows;
@@ -24909,6 +25306,7 @@ function WebGLLights(extensions) {
24909
25306
  }
24910
25307
  }
24911
25308
  function setupView(lights, camera) {
25309
+ let sunLength = 0;
24912
25310
  let directionalLength = 0;
24913
25311
  let pointLength = 0;
24914
25312
  let spotLength = 0;
@@ -24917,7 +25315,12 @@ function WebGLLights(extensions) {
24917
25315
  const viewMatrix = camera.matrixWorldInverse;
24918
25316
  for (let i = 0, l = lights.length; i < l; i++) {
24919
25317
  const light = lights[i];
24920
- if (light.isDirectionalLight) {
25318
+ if (light.isSunLight) {
25319
+ const uniforms = state.sun[sunLength];
25320
+ uniforms.direction.setFromMatrixPosition(light.matrixWorld);
25321
+ uniforms.direction.transformDirection(viewMatrix);
25322
+ sunLength++;
25323
+ } else if (light.isDirectionalLight) {
24921
25324
  const uniforms = state.directional[directionalLength];
24922
25325
  uniforms.direction.setFromMatrixPosition(light.matrixWorld);
24923
25326
  vector3.setFromMatrixPosition(light.target.matrixWorld);
@@ -25095,7 +25498,7 @@ function WebGLShadowMap(renderer, objects, capabilities) {
25095
25498
  if (scope.autoUpdate === false && scope.needsUpdate === false) return;
25096
25499
  if (lights.length === 0) return;
25097
25500
  if (this.type === PCFSoftShadowMap) {
25098
- warn("WebGLShadowMap: PCFSoftShadowMap has been deprecated. Using PCFShadowMap instead.");
25501
+ warn("WebGLShadowMap: PCFSoftShadowMap has been removed. Using PCFShadowMap instead.");
25099
25502
  this.type = PCFShadowMap;
25100
25503
  }
25101
25504
  const currentRenderTarget = renderer.getRenderTarget();
@@ -25197,25 +25600,13 @@ function WebGLShadowMap(renderer, objects, capabilities) {
25197
25600
  }
25198
25601
  shadow.camera.updateProjectionMatrix();
25199
25602
  }
25200
- const faceCount = shadow.map.isWebGLCubeRenderTarget ? 6 : 1;
25603
+ if (shadow.map.isWebGLCubeRenderTarget !== true && (shadow.map.width !== _shadowMapSize.x || shadow.map.height !== _shadowMapSize.y)) {
25604
+ shadow.map.setSize(_shadowMapSize.x, _shadowMapSize.y);
25605
+ }
25606
+ const faceCount = shadow.map.isWebGLCubeRenderTarget ? 6 : shadow.getViewportCount();
25607
+ if (light.isPointLight !== true) shadow.updateMatrices(light, camera);
25201
25608
  for (let face = 0; face < faceCount; face++) {
25202
- if (shadow.map.isWebGLCubeRenderTarget) {
25203
- renderer.setRenderTarget(shadow.map, face);
25204
- renderer.clear();
25205
- } else {
25206
- if (face === 0) {
25207
- renderer.setRenderTarget(shadow.map);
25208
- renderer.clear();
25209
- }
25210
- const viewport = shadow.getViewport(face);
25211
- _viewport.set(
25212
- _viewportSize.x * viewport.x,
25213
- _viewportSize.y * viewport.y,
25214
- _viewportSize.x * viewport.z,
25215
- _viewportSize.y * viewport.w
25216
- );
25217
- _state.viewport(_viewport);
25218
- }
25609
+ const shadowCamera = shadow.getCamera(face);
25219
25610
  if (light.isPointLight) {
25220
25611
  const camera2 = shadow.camera;
25221
25612
  const shadowMatrix = shadow.matrix;
@@ -25234,11 +25625,26 @@ function WebGLShadowMap(renderer, objects, capabilities) {
25234
25625
  shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z);
25235
25626
  _projScreenMatrix.multiplyMatrices(camera2.projectionMatrix, camera2.matrixWorldInverse);
25236
25627
  shadow._frustum.setFromProjectionMatrix(_projScreenMatrix, camera2.coordinateSystem, camera2.reversedDepth);
25628
+ }
25629
+ if (shadow.map.isWebGLCubeRenderTarget) {
25630
+ renderer.setRenderTarget(shadow.map, face);
25631
+ renderer.clear();
25237
25632
  } else {
25238
- shadow.updateMatrices(light);
25633
+ if (face === 0) {
25634
+ renderer.setRenderTarget(shadow.map);
25635
+ renderer.clear();
25636
+ }
25637
+ const viewport = shadow.getViewport(face);
25638
+ _viewport.set(
25639
+ _viewportSize.x * viewport.x,
25640
+ _viewportSize.y * viewport.y,
25641
+ _viewportSize.x * viewport.z,
25642
+ _viewportSize.y * viewport.w
25643
+ );
25644
+ _state.viewport(_viewport);
25239
25645
  }
25240
- _frustum = shadow.getFrustum();
25241
- renderObject(scene, camera, shadow.camera, light, this.type);
25646
+ _frustum = shadow.getFrustum(face);
25647
+ renderObject(scene, camera, shadowCamera, light, this.type);
25242
25648
  }
25243
25649
  if (shadow.isPointLightShadow !== true && this.type === VSMShadowMap) {
25244
25650
  VSMPass(shadow, camera);
@@ -25262,15 +25668,17 @@ function WebGLShadowMap(renderer, objects, capabilities) {
25262
25668
  format: RGFormat,
25263
25669
  type: HalfFloatType
25264
25670
  });
25671
+ } else if (shadow.mapPass.width !== shadow.map.width || shadow.mapPass.height !== shadow.map.height) {
25672
+ shadow.mapPass.setSize(shadow.map.width, shadow.map.height);
25265
25673
  }
25266
25674
  shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.depthTexture;
25267
- shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;
25675
+ shadowMaterialVertical.uniforms.resolution.value.set(shadow.map.width, shadow.map.height);
25268
25676
  shadowMaterialVertical.uniforms.radius.value = shadow.radius;
25269
25677
  renderer.setRenderTarget(shadow.mapPass);
25270
25678
  renderer.clear();
25271
25679
  renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null);
25272
25680
  shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture;
25273
- shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize;
25681
+ shadowMaterialHorizontal.uniforms.resolution.value.set(shadow.map.width, shadow.map.height);
25274
25682
  shadowMaterialHorizontal.uniforms.radius.value = shadow.radius;
25275
25683
  renderer.setRenderTarget(shadow.map);
25276
25684
  renderer.clear();
@@ -25327,7 +25735,7 @@ function WebGLShadowMap(renderer, objects, capabilities) {
25327
25735
  if (object.visible === false) return;
25328
25736
  const visible = object.layers.test(camera.layers);
25329
25737
  if (visible && (object.isMesh || object.isLine || object.isPoints)) {
25330
- if ((object.castShadow || object.receiveShadow && type === VSMShadowMap) && (!object.frustumCulled || _frustum.intersectsObject(object))) {
25738
+ if ((object.castShadow || object.receiveShadow && type === VSMShadowMap) && (!object.frustumCulled || object.intersectsFrustum(_frustum))) {
25331
25739
  object.modelViewMatrix.multiplyMatrices(shadowCamera.matrixWorldInverse, object.matrixWorld);
25332
25740
  const geometry = objects.update(object);
25333
25741
  const material = object.material;
@@ -26416,7 +26824,7 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils,
26416
26824
  function allocateTextureUnit() {
26417
26825
  const textureUnit = textureUnits;
26418
26826
  if (textureUnit >= capabilities.maxTextures) {
26419
- warn("WebGLTextures: Trying to use " + textureUnit + " texture units while this GPU supports only " + capabilities.maxTextures);
26827
+ warn("WebGLTextures: Trying to use " + (textureUnit + 1) + " texture units while this GPU supports only " + capabilities.maxTextures);
26420
26828
  }
26421
26829
  textureUnits += 1;
26422
26830
  return textureUnit;
@@ -26706,7 +27114,6 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils,
26706
27114
  );
26707
27115
  state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, layerIndex, mipmap.width, mipmap.height, 1, glFormat, layerData);
26708
27116
  }
26709
- texture.clearLayerUpdates();
26710
27117
  } else {
26711
27118
  state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data);
26712
27119
  }
@@ -26727,6 +27134,7 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils,
26727
27134
  }
26728
27135
  }
26729
27136
  }
27137
+ if (texture.layerUpdates.size > 0) texture.clearLayerUpdates();
26730
27138
  } else {
26731
27139
  if (useTexStorage && allocateMemory) {
26732
27140
  state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
@@ -27363,7 +27771,7 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils,
27363
27771
  invalidationArrayRead.length = 0;
27364
27772
  invalidationArrayDraw.length = 0;
27365
27773
  invalidationArrayRead.push(_gl.COLOR_ATTACHMENT0 + i);
27366
- if (renderTarget.depthBuffer && renderTarget.resolveDepthBuffer === false) {
27774
+ if (renderTarget.depthBuffer && renderTarget.storeMultisampledDepthBuffer === false) {
27367
27775
  invalidationArrayRead.push(depthStyle);
27368
27776
  invalidationArrayDraw.push(depthStyle);
27369
27777
  _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, invalidationArrayDraw);
@@ -27384,7 +27792,7 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils,
27384
27792
  }
27385
27793
  state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
27386
27794
  } else {
27387
- if (renderTarget.depthBuffer && renderTarget.resolveDepthBuffer === false && supportsInvalidateFramebuffer) {
27795
+ if (renderTarget.depthBuffer && renderTarget.storeMultisampledDepthBuffer === false && supportsInvalidateFramebuffer) {
27388
27796
  const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT;
27389
27797
  _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]);
27390
27798
  }
@@ -27696,6 +28104,7 @@ class WebXRManager extends EventDispatcher {
27696
28104
  const controllerInputSources = [];
27697
28105
  const currentSize = new Vector2();
27698
28106
  let currentPixelRatio = null;
28107
+ let currentCameraSettings = null;
27699
28108
  const cameraL = new PerspectiveCamera();
27700
28109
  cameraL.viewport = new Vector4();
27701
28110
  const cameraR = new PerspectiveCamera();
@@ -27773,6 +28182,13 @@ class WebXRManager extends EventDispatcher {
27773
28182
  scope.isPresenting = false;
27774
28183
  renderer.setPixelRatio(currentPixelRatio);
27775
28184
  renderer.setSize(currentSize.width, currentSize.height, false);
28185
+ if (currentCameraSettings !== null) {
28186
+ const camera = currentCameraSettings.camera;
28187
+ camera.fov = currentCameraSettings.fov;
28188
+ camera.zoom = currentCameraSettings.zoom;
28189
+ camera.updateProjectionMatrix();
28190
+ currentCameraSettings = null;
28191
+ }
27776
28192
  scope.dispatchEvent({ type: "sessionend" });
27777
28193
  }
27778
28194
  this.setFramebufferScaleFactor = function(value) {
@@ -27847,7 +28263,9 @@ class WebXRManager extends EventDispatcher {
27847
28263
  colorSpace: renderer.outputColorSpace,
27848
28264
  stencilBuffer: attributes.stencil,
27849
28265
  resolveDepthBuffer: glBaseLayer.ignoreDepthValues === false,
27850
- resolveStencilBuffer: glBaseLayer.ignoreDepthValues === false
28266
+ resolveStencilBuffer: glBaseLayer.ignoreDepthValues === false,
28267
+ storeMultisampledDepthBuffer: glBaseLayer.ignoreDepthValues === false,
28268
+ storeMultisampledStencilBuffer: glBaseLayer.ignoreDepthValues === false
27851
28269
  }
27852
28270
  );
27853
28271
  } else {
@@ -27880,7 +28298,9 @@ class WebXRManager extends EventDispatcher {
27880
28298
  colorSpace: renderer.outputColorSpace,
27881
28299
  samples: attributes.antialias ? 4 : 0,
27882
28300
  resolveDepthBuffer: glProjLayer.ignoreDepthValues === false,
27883
- resolveStencilBuffer: glProjLayer.ignoreDepthValues === false
28301
+ resolveStencilBuffer: glProjLayer.ignoreDepthValues === false,
28302
+ storeMultisampledDepthBuffer: glProjLayer.ignoreDepthValues === false,
28303
+ storeMultisampledStencilBuffer: glProjLayer.ignoreDepthValues === false
27884
28304
  }
27885
28305
  );
27886
28306
  }
@@ -28011,6 +28431,9 @@ class WebXRManager extends EventDispatcher {
28011
28431
  } else {
28012
28432
  cameraXR.projectionMatrix.copy(cameraL.projectionMatrix);
28013
28433
  }
28434
+ if (currentCameraSettings === null && camera.isPerspectiveCamera) {
28435
+ currentCameraSettings = { camera, fov: camera.fov, zoom: camera.zoom };
28436
+ }
28014
28437
  updateUserCamera(camera, cameraXR, parent);
28015
28438
  };
28016
28439
  function updateUserCamera(camera, cameraXR2, parent) {
@@ -28408,6 +28831,9 @@ function WebGLMaterials(renderer, properties) {
28408
28831
  if (material.dispersion > 0) {
28409
28832
  uniforms.dispersion.value = material.dispersion;
28410
28833
  }
28834
+ if (material.retroreflectivity > 0) {
28835
+ uniforms.retroreflectivity.value = material.retroreflectivity;
28836
+ }
28411
28837
  if (material.iridescence > 0) {
28412
28838
  uniforms.iridescence.value = material.iridescence;
28413
28839
  uniforms.iridescenceIOR.value = material.iridescenceIOR;
@@ -29285,6 +29711,14 @@ class WebGLRenderer {
29285
29711
  * @type {boolean}
29286
29712
  */
29287
29713
  checkShaderErrors: true,
29714
+ /**
29715
+ * Diagnostics configuration for the shader generation. Only relevant for TSL.
29716
+ * @type {Object}
29717
+ * @property {boolean} keywords - Whether declaration names that collide with reserved keywords of the shading language should be renamed or not.
29718
+ */
29719
+ diagnostics: {
29720
+ keywords: false
29721
+ },
29288
29722
  /**
29289
29723
  * Callback for custom error reporting.
29290
29724
  * @type {?Function}
@@ -29341,6 +29775,11 @@ class WebGLRenderer {
29341
29775
  function getContext(contextName, contextAttributes) {
29342
29776
  return canvas.getContext(contextName, contextAttributes);
29343
29777
  }
29778
+ let extensions, capabilities, state, info;
29779
+ let properties, textures, environments, attributes, geometries, objects;
29780
+ let programCache, materials, renderLists, renderStates, clipping, shadowMap;
29781
+ let background, morphtargets, bufferRenderer, indexedBufferRenderer;
29782
+ let utils, bindingStates, uniformsGroups;
29344
29783
  try {
29345
29784
  const contextAttributes = {
29346
29785
  alpha: true,
@@ -29367,15 +29806,14 @@ class WebGLRenderer {
29367
29806
  }
29368
29807
  }
29369
29808
  }
29809
+ initGLContext();
29370
29810
  } catch (e) {
29811
+ canvas.removeEventListener("webglcontextlost", onContextLost, false);
29812
+ canvas.removeEventListener("webglcontextrestored", onContextRestore, false);
29813
+ canvas.removeEventListener("webglcontextcreationerror", onContextCreationError, false);
29371
29814
  error("WebGLRenderer: " + e.message);
29372
29815
  throw e;
29373
29816
  }
29374
- let extensions, capabilities, state, info;
29375
- let properties, textures, environments, attributes, geometries, objects;
29376
- let programCache, materials, renderLists, renderStates, clipping, shadowMap;
29377
- let background, morphtargets, bufferRenderer, indexedBufferRenderer;
29378
- let utils, bindingStates, uniformsGroups;
29379
29817
  function initGLContext() {
29380
29818
  extensions = new WebGLExtensions(_gl);
29381
29819
  extensions.init();
@@ -29416,7 +29854,6 @@ class WebGLRenderer {
29416
29854
  _this.state = state;
29417
29855
  _this.info = info;
29418
29856
  }
29419
- initGLContext();
29420
29857
  if (_outputBufferType !== UnsignedByteType) {
29421
29858
  output = new WebGLOutput(_outputBufferType, canvas.width, canvas.height, antialias, depth, stencil);
29422
29859
  }
@@ -29743,7 +30180,9 @@ class WebGLRenderer {
29743
30180
  renderer.render(drawStart, drawCount);
29744
30181
  }
29745
30182
  };
29746
- function prepareMaterial(material, scene, object) {
30183
+ function prepareMaterial(material, scene, camera, object) {
30184
+ if (_nodesHandler !== null && material.isNodeMaterial) _nodesHandler.setObject(object, material);
30185
+ if (_clippingEnabled === true) clipping.setState(material, camera, false);
29747
30186
  if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) {
29748
30187
  material.side = BackSide;
29749
30188
  material.needsUpdate = true;
@@ -29758,6 +30197,7 @@ class WebGLRenderer {
29758
30197
  }
29759
30198
  this.compile = function(scene, camera, targetScene = null) {
29760
30199
  if (targetScene === null) targetScene = scene;
30200
+ if (_nodesHandler !== null) _nodesHandler.renderStart(scene, camera, targetScene);
29761
30201
  currentRenderState = renderStates.get(targetScene);
29762
30202
  currentRenderState.init(camera);
29763
30203
  renderStateStack.push(currentRenderState);
@@ -29780,6 +30220,11 @@ class WebGLRenderer {
29780
30220
  });
29781
30221
  }
29782
30222
  currentRenderState.setupLights();
30223
+ if (_nodesHandler !== null) _nodesHandler.updateLights(currentRenderState.state.lightsArray);
30224
+ _localClippingEnabled = this.localClippingEnabled;
30225
+ _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled);
30226
+ if (_clippingEnabled === true) clipping.setGlobalState(this.clippingPlanes, camera);
30227
+ if (_nodesHandler !== null) shadowMap.render(currentRenderState.state.shadowsArray, targetScene, camera);
29783
30228
  const materials2 = /* @__PURE__ */ new Set();
29784
30229
  scene.traverse(function(object) {
29785
30230
  if (!(object.isMesh || object.isPoints || object.isLine || object.isSprite)) {
@@ -29790,16 +30235,17 @@ class WebGLRenderer {
29790
30235
  if (Array.isArray(material)) {
29791
30236
  for (let i = 0; i < material.length; i++) {
29792
30237
  const material2 = material[i];
29793
- prepareMaterial(material2, targetScene, object);
30238
+ prepareMaterial(material2, targetScene, camera, object);
29794
30239
  materials2.add(material2);
29795
30240
  }
29796
30241
  } else {
29797
- prepareMaterial(material, targetScene, object);
30242
+ prepareMaterial(material, targetScene, camera, object);
29798
30243
  materials2.add(material);
29799
30244
  }
29800
30245
  }
29801
30246
  });
29802
30247
  currentRenderState = renderStateStack.pop();
30248
+ if (_nodesHandler !== null) _nodesHandler.renderEnd();
29803
30249
  return materials2;
29804
30250
  };
29805
30251
  this.compileAsync = function(scene, camera, targetScene = null) {
@@ -29809,7 +30255,7 @@ class WebGLRenderer {
29809
30255
  materials2.forEach(function(material) {
29810
30256
  const materialProperties = properties.get(material);
29811
30257
  const program = materialProperties.currentProgram;
29812
- if (program.isReady()) {
30258
+ if (program === void 0 || program.isReady()) {
29813
30259
  materials2.delete(material);
29814
30260
  }
29815
30261
  });
@@ -29883,8 +30329,9 @@ class WebGLRenderer {
29883
30329
  }
29884
30330
  projectObject(scene, camera, 0, _this.sortObjects);
29885
30331
  currentRenderList.finish();
30332
+ if (_nodesHandler !== null) _nodesHandler.updateLights(currentRenderState.state.lightsArray);
29886
30333
  if (_this.sortObjects === true) {
29887
- currentRenderList.sort(_opaqueSort, _transparentSort, camera.reversedDepth);
30334
+ currentRenderList.sort(_opaqueSort, _transparentSort);
29888
30335
  }
29889
30336
  _renderBackground = xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false;
29890
30337
  if (_renderBackground) {
@@ -29965,18 +30412,18 @@ class WebGLRenderer {
29965
30412
  currentRenderState.pushShadow(object);
29966
30413
  }
29967
30414
  } else if (object.isSprite) {
29968
- if (!object.frustumCulled || _frustum.intersectsSprite(object)) {
30415
+ if (!object.frustumCulled || object.intersectsFrustum(_frustum)) {
29969
30416
  if (sortObjects) {
29970
30417
  _vector42.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix2);
29971
30418
  }
29972
30419
  const geometry = objects.update(object);
29973
30420
  const material = object.material;
29974
30421
  if (material.visible) {
29975
- currentRenderList.push(object, geometry, material, groupOrder, _vector42.z, null);
30422
+ currentRenderList.push(object, geometry, material, groupOrder, _vector42.z, null, camera);
29976
30423
  }
29977
30424
  }
29978
30425
  } else if (object.isMesh || object.isLine || object.isPoints) {
29979
- if (!object.frustumCulled || _frustum.intersectsObject(object)) {
30426
+ if (!object.frustumCulled || object.intersectsFrustum(_frustum)) {
29980
30427
  const geometry = objects.update(object);
29981
30428
  const material = object.material;
29982
30429
  if (sortObjects) {
@@ -29995,11 +30442,11 @@ class WebGLRenderer {
29995
30442
  const group = groups[i];
29996
30443
  const groupMaterial = material[group.materialIndex];
29997
30444
  if (groupMaterial && groupMaterial.visible) {
29998
- currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector42.z, group);
30445
+ currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector42.z, group, camera);
29999
30446
  }
30000
30447
  }
30001
30448
  } else if (material.visible) {
30002
- currentRenderList.push(object, geometry, material, groupOrder, _vector42.z, null);
30449
+ currentRenderList.push(object, geometry, material, groupOrder, _vector42.z, null, camera);
30003
30450
  }
30004
30451
  }
30005
30452
  }
@@ -30038,6 +30485,8 @@ class WebGLRenderer {
30038
30485
  stencilBuffer: stencil,
30039
30486
  resolveDepthBuffer: false,
30040
30487
  resolveStencilBuffer: false,
30488
+ storeMultisampledDepthBuffer: false,
30489
+ storeMultisampledStencilBuffer: false,
30041
30490
  colorSpace: ColorManagement.workingColorSpace
30042
30491
  });
30043
30492
  }
@@ -30102,6 +30551,7 @@ class WebGLRenderer {
30102
30551
  }
30103
30552
  }
30104
30553
  function renderObject(object, scene, camera, geometry, material, group) {
30554
+ if (_nodesHandler !== null && material.isNodeMaterial) _nodesHandler.setObject(object, material);
30105
30555
  object.onBeforeRender(_this, scene, camera, geometry, material, group);
30106
30556
  object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld);
30107
30557
  object.normalMatrix.getNormalMatrix(object.modelViewMatrix);
@@ -30164,6 +30614,8 @@ class WebGLRenderer {
30164
30614
  if (materialProperties.needsLights) {
30165
30615
  uniforms.ambientLightColor.value = lights.state.ambient;
30166
30616
  uniforms.lightProbe.value = lights.state.probe;
30617
+ uniforms.sunLights.value = lights.state.sun;
30618
+ uniforms.sunLightShadows.value = lights.state.sunShadow;
30167
30619
  uniforms.directionalLights.value = lights.state.directional;
30168
30620
  uniforms.directionalLightShadows.value = lights.state.directionalShadow;
30169
30621
  uniforms.spotLights.value = lights.state.spot;
@@ -30174,6 +30626,8 @@ class WebGLRenderer {
30174
30626
  uniforms.pointLights.value = lights.state.point;
30175
30627
  uniforms.pointLightShadows.value = lights.state.pointShadow;
30176
30628
  uniforms.hemisphereLights.value = lights.state.hemi;
30629
+ uniforms.sunShadowMatrix.value = lights.state.sunShadowMatrix;
30630
+ uniforms.sunShadowCascade.value = lights.state.sunShadowCascade;
30177
30631
  uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix;
30178
30632
  uniforms.spotLightMatrix.value = lights.state.spotLightMatrix;
30179
30633
  uniforms.spotLightMap.value = lights.state.spotLightMap;
@@ -30261,9 +30715,9 @@ class WebGLRenderer {
30261
30715
  needsProgramChange = true;
30262
30716
  } else if (!object.isBatchedMesh && materialProperties.batching === true) {
30263
30717
  needsProgramChange = true;
30264
- } else if (object.isBatchedMesh && materialProperties.batchingColor === true && object.colorTexture === null) {
30718
+ } else if (object.isBatchedMesh && materialProperties.batchingColor === true && object._colorsTexture === null) {
30265
30719
  needsProgramChange = true;
30266
- } else if (object.isBatchedMesh && materialProperties.batchingColor === false && object.colorTexture !== null) {
30720
+ } else if (object.isBatchedMesh && materialProperties.batchingColor === false && object._colorsTexture !== null) {
30267
30721
  needsProgramChange = true;
30268
30722
  } else if (object.isInstancedMesh && materialProperties.instancing === false) {
30269
30723
  needsProgramChange = true;
@@ -30364,6 +30818,9 @@ class WebGLRenderer {
30364
30818
  }
30365
30819
  }
30366
30820
  if (materialProperties.needsLights) {
30821
+ if (lights.state.sunShadowMap.length > 0) {
30822
+ p_uniforms.setValue(_gl, "sunShadowMap", lights.state.sunShadowMap, textures);
30823
+ }
30367
30824
  if (lights.state.directionalShadowMap.length > 0) {
30368
30825
  p_uniforms.setValue(_gl, "directionalShadowMap", lights.state.directionalShadowMap, textures);
30369
30826
  }
@@ -30448,6 +30905,8 @@ class WebGLRenderer {
30448
30905
  function markUniformsLightsNeedsUpdate(uniforms, value) {
30449
30906
  uniforms.ambientLightColor.needsUpdate = value;
30450
30907
  uniforms.lightProbe.needsUpdate = value;
30908
+ uniforms.sunLights.needsUpdate = value;
30909
+ uniforms.sunLightShadows.needsUpdate = value;
30451
30910
  uniforms.directionalLights.needsUpdate = value;
30452
30911
  uniforms.directionalLightShadows.needsUpdate = value;
30453
30912
  uniforms.pointLights.needsUpdate = value;
@@ -30570,6 +31029,16 @@ class WebGLRenderer {
30570
31029
  }
30571
31030
  _currentMaterialId = -1;
30572
31031
  };
31032
+ function getReadableState(texture) {
31033
+ const textureProperties = properties.get(texture);
31034
+ if (textureProperties.__readFormat !== texture.format || textureProperties.__readType !== texture.type) {
31035
+ textureProperties.__readFormat = texture.format;
31036
+ textureProperties.__readType = texture.type;
31037
+ textureProperties.__formatReadable = capabilities.textureFormatReadable(texture.format);
31038
+ textureProperties.__typeReadable = capabilities.textureTypeReadable(texture.type);
31039
+ }
31040
+ return textureProperties;
31041
+ }
30573
31042
  this.readRenderTargetPixels = function(renderTarget, x, y, width, height, buffer, activeCubeFaceIndex, textureIndex = 0) {
30574
31043
  if (!(renderTarget && renderTarget.isWebGLRenderTarget)) {
30575
31044
  error("WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");
@@ -30586,11 +31055,12 @@ class WebGLRenderer {
30586
31055
  const textureFormat = texture.format;
30587
31056
  const textureType = texture.type;
30588
31057
  if (renderTarget.textures.length > 1) _gl.readBuffer(_gl.COLOR_ATTACHMENT0 + textureIndex);
30589
- if (!capabilities.textureFormatReadable(textureFormat)) {
31058
+ const readableState = getReadableState(texture);
31059
+ if (readableState.__formatReadable === false) {
30590
31060
  error("WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.");
30591
31061
  return;
30592
31062
  }
30593
- if (!capabilities.textureTypeReadable(textureType)) {
31063
+ if (readableState.__typeReadable === false) {
30594
31064
  error("WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.");
30595
31065
  return;
30596
31066
  }
@@ -30618,16 +31088,18 @@ class WebGLRenderer {
30618
31088
  const textureFormat = texture.format;
30619
31089
  const textureType = texture.type;
30620
31090
  if (renderTarget.textures.length > 1) _gl.readBuffer(_gl.COLOR_ATTACHMENT0 + textureIndex);
30621
- if (!capabilities.textureFormatReadable(textureFormat)) {
31091
+ const readableState = getReadableState(texture);
31092
+ if (readableState.__formatReadable === false) {
30622
31093
  throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.");
30623
31094
  }
30624
- if (!capabilities.textureTypeReadable(textureType)) {
31095
+ if (readableState.__typeReadable === false) {
30625
31096
  throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.");
30626
31097
  }
30627
31098
  const glBuffer = _gl.createBuffer();
30628
31099
  _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, glBuffer);
30629
31100
  _gl.bufferData(_gl.PIXEL_PACK_BUFFER, buffer.byteLength, _gl.STREAM_READ);
30630
31101
  _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), 0);
31102
+ _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, null);
30631
31103
  const currFramebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null;
30632
31104
  state.bindFramebuffer(_gl.FRAMEBUFFER, currFramebuffer);
30633
31105
  const sync = _gl.fenceSync(_gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
@@ -30635,6 +31107,7 @@ class WebGLRenderer {
30635
31107
  await probeAsync(_gl, sync, 4);
30636
31108
  _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, glBuffer);
30637
31109
  _gl.getBufferSubData(_gl.PIXEL_PACK_BUFFER, 0, buffer);
31110
+ _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, null);
30638
31111
  _gl.deleteBuffer(glBuffer);
30639
31112
  _gl.deleteSync(sync);
30640
31113
  return buffer;
@@ -38781,168 +39254,168 @@ async function computeElevation(lon, lat, options) {
38781
39254
  }
38782
39255
  }
38783
39256
  export {
38784
- Raycaster as $,
38785
- Camera as A,
39257
+ Line as $,
39258
+ MirroredRepeatWrapping as A,
38786
39259
  BufferGeometry as B,
38787
- Color as C,
38788
- DataArrayTexture as D,
38789
- PMREMGenerator as E,
38790
- Float32BufferAttribute as F,
38791
- GLSL3 as G,
38792
- MeshStandardMaterial as H,
38793
- InstancedBufferGeometry as I,
38794
- REVISION as J,
38795
- Matrix2 as K,
39260
+ Clock as C,
39261
+ DirectionalLight as D,
39262
+ EventDispatcher as E,
39263
+ FileLoader as F,
39264
+ ClampToEdgeWrapping as G,
39265
+ PointsMaterial as H,
39266
+ InstancedMesh as I,
39267
+ Material as J,
39268
+ LineBasicMaterial as K,
38796
39269
  Loader as L,
38797
39270
  Matrix4 as M,
38798
- NearestFilter as N,
39271
+ NearestMipmapLinearFilter as N,
38799
39272
  Object3D as O,
38800
- PerspectiveCamera as P,
39273
+ PlaneGeometry as P,
38801
39274
  Quaternion as Q,
38802
- RGBAIntegerFormat as R,
39275
+ Ray as R,
38803
39276
  ShaderChunk as S,
38804
- Texture as T,
38805
- UnsignedIntType as U,
39277
+ TrianglesDrawMode as T,
39278
+ MeshStandardMaterial as U,
38806
39279
  Vector3$1 as V,
38807
- WebGLArrayRenderTarget as W,
38808
- PlaneGeometry as X,
38809
- Ray as Y,
38810
- EventDispatcher as Z,
38811
- Plane as _,
39280
+ DoubleSide as W,
39281
+ MeshBasicMaterial as X,
39282
+ PropertyBinding as Y,
39283
+ SkinnedMesh as Z,
39284
+ LineSegments as _,
38812
39285
  Vector2 as a,
38813
- Source as a$,
38814
- MathUtils as a0,
38815
- Sphere as a1,
38816
- Euler as a2,
38817
- Spherical as a3,
38818
- Group as a4,
38819
- LoaderUtils as a5,
38820
- InterleavedBuffer as a6,
38821
- ColorManagement as a7,
38822
- InterleavedBufferAttribute as a8,
38823
- TrianglesDrawMode as a9,
38824
- Skeleton as aA,
38825
- AnimationClip as aB,
38826
- Bone as aC,
38827
- InterpolateDiscrete as aD,
38828
- InterpolateLinear as aE,
38829
- VectorKeyframeTrack as aF,
38830
- NumberKeyframeTrack as aG,
38831
- QuaternionKeyframeTrack as aH,
38832
- FrontSide as aI,
38833
- Interpolant as aJ,
38834
- LoadingManager as aK,
38835
- Frustum as aL,
38836
- DefaultLoadingManager as aM,
38837
- TextureUtils as aN,
38838
- RGFormat as aO,
38839
- Triangle as aP,
38840
- CanvasTexture as aQ,
38841
- WebGLRenderer as aR,
38842
- OneFactor as aS,
38843
- ZeroFactor as aT,
38844
- CustomBlending as aU,
38845
- Box2 as aV,
38846
- DataTextureLoader as aW,
38847
- HalfFloatType as aX,
38848
- FloatType as aY,
38849
- DataUtils as aZ,
38850
- CompressedTexture as a_,
38851
- TriangleFanDrawMode as aa,
38852
- TriangleStripDrawMode as ab,
38853
- MeshPhysicalMaterial as ac,
38854
- SpotLight as ad,
38855
- PointLight as ae,
38856
- DirectionalLight as af,
38857
- InstancedMesh as ag,
38858
- TextureLoader as ah,
38859
- ImageBitmapLoader as ai,
38860
- LinearMipmapLinearFilter as aj,
38861
- NearestMipmapLinearFilter as ak,
38862
- LinearMipmapNearestFilter as al,
38863
- NearestMipmapNearestFilter as am,
38864
- RepeatWrapping as an,
38865
- MirroredRepeatWrapping as ao,
38866
- ClampToEdgeWrapping as ap,
38867
- PointsMaterial as aq,
38868
- Material as ar,
38869
- LineBasicMaterial as as,
38870
- MeshBasicMaterial as at,
38871
- PropertyBinding as au,
38872
- SkinnedMesh as av,
38873
- LineSegments as aw,
38874
- Line as ax,
38875
- LineLoop as ay,
38876
- Points as az,
39286
+ SIGNED_RED_GREEN_RGTC2_Format as a$,
39287
+ LineLoop as a0,
39288
+ Points as a1,
39289
+ Group as a2,
39290
+ PerspectiveCamera as a3,
39291
+ OrthographicCamera as a4,
39292
+ Skeleton as a5,
39293
+ AnimationClip as a6,
39294
+ Bone as a7,
39295
+ InterpolateDiscrete as a8,
39296
+ InterpolateLinear as a9,
39297
+ OneFactor as aA,
39298
+ ZeroFactor as aB,
39299
+ CustomBlending as aC,
39300
+ Box2 as aD,
39301
+ Matrix2 as aE,
39302
+ Vector4 as aF,
39303
+ DataTextureLoader as aG,
39304
+ HalfFloatType as aH,
39305
+ FloatType as aI,
39306
+ DataUtils as aJ,
39307
+ REVISION as aK,
39308
+ CompressedTexture as aL,
39309
+ TextureSource as aM,
39310
+ NoColorSpace as aN,
39311
+ RGBAFormat as aO,
39312
+ ImageUtils as aP,
39313
+ Scene as aQ,
39314
+ ecefToGeodeticPosition as aR,
39315
+ getEnuBasis as aS,
39316
+ BackSide as aT,
39317
+ BoxGeometry as aU,
39318
+ CompressedCubeTexture as aV,
39319
+ CompressedArrayTexture as aW,
39320
+ RGBA_PVRTC_2BPPV1_Format as aX,
39321
+ RGBA_PVRTC_4BPPV1_Format as aY,
39322
+ RGBA_BPTC_Format as aZ,
39323
+ RED_GREEN_RGTC2_Format as a_,
39324
+ InterleavedBufferAttribute as aa,
39325
+ Texture as ab,
39326
+ VectorKeyframeTrack as ac,
39327
+ NumberKeyframeTrack as ad,
39328
+ QuaternionKeyframeTrack as ae,
39329
+ ColorManagement as af,
39330
+ FrontSide as ag,
39331
+ Interpolant as ah,
39332
+ Box3 as ai,
39333
+ Sphere as aj,
39334
+ Euler as ak,
39335
+ Spherical as al,
39336
+ LoadingManager as am,
39337
+ Frustum as an,
39338
+ DefaultLoadingManager as ao,
39339
+ Matrix3$1 as ap,
39340
+ TextureUtils as aq,
39341
+ Float32BufferAttribute as ar,
39342
+ RGFormat as as,
39343
+ UnsignedByteType as at,
39344
+ DataTexture as au,
39345
+ LinearMipMapLinearFilter as av,
39346
+ Triangle as aw,
39347
+ CanvasTexture as ax,
39348
+ WebGLRenderer as ay,
39349
+ WebGLRenderTarget as az,
38877
39350
  Mesh as b,
38878
- NoColorSpace as b0,
38879
- ImageUtils as b1,
38880
- Scene as b2,
38881
- ecefToGeodeticPosition as b3,
38882
- getEnuBasis as b4,
38883
- BackSide as b5,
38884
- BoxGeometry as b6,
38885
- CompressedCubeTexture as b7,
38886
- CompressedArrayTexture as b8,
38887
- RGBA_PVRTC_2BPPV1_Format as b9,
38888
- geodeticOffsetToEcefDelta as bA,
38889
- validateGeodeticPosition as bB,
38890
- validateTuple as bC,
38891
- validateScale as bD,
38892
- geodeticToEcefPosition as bE,
38893
- AgXToneMapping as bF,
38894
- EquirectangularReflectionMapping as bG,
38895
- validateRotation as bH,
38896
- requireFiniteNumber as bI,
38897
- computeElevation as bJ,
38898
- RGBA_PVRTC_4BPPV1_Format as ba,
38899
- RGBA_BPTC_Format as bb,
38900
- RED_GREEN_RGTC2_Format as bc,
38901
- SIGNED_RED_GREEN_RGTC2_Format as bd,
38902
- RED_RGTC1_Format as be,
38903
- SIGNED_RED_RGTC1_Format as bf,
38904
- RGBA_S3TC_DXT5_Format as bg,
38905
- RGB_S3TC_DXT1_Format as bh,
38906
- RGBA_S3TC_DXT1_Format as bi,
38907
- RGBA_ASTC_6x6_Format as bj,
38908
- RGBA_ASTC_4x4_Format as bk,
38909
- SIGNED_RG11_EAC_Format as bl,
38910
- RG11_EAC_Format as bm,
38911
- SIGNED_R11_EAC_Format as bn,
38912
- R11_EAC_Format as bo,
38913
- RGB_ETC2_Format as bp,
38914
- RGBA_ETC2_EAC_Format as bq,
38915
- RGBFormat as br,
38916
- RedFormat as bs,
38917
- UnsignedInt101111Type as bt,
38918
- UnsignedInt5999Type as bu,
38919
- UnsignedShortType as bv,
38920
- RGB_PVRTC_4BPPV1_Format as bw,
38921
- RGB_ETC1_Format as bx,
38922
- RGB_BPTC_UNSIGNED_Format as by,
38923
- normalizeLayerOffset as bz,
38924
- OrthographicCamera as c,
38925
- RawShaderMaterial as d,
38926
- DataTexture as e,
38927
- RGIntegerFormat as f,
38928
- ShaderMaterial as g,
38929
- Data3DTexture as h,
38930
- Vector4 as i,
38931
- Box3 as j,
38932
- Matrix3$1 as k,
38933
- BufferAttribute as l,
38934
- InstancedBufferAttribute as m,
38935
- DynamicDrawUsage as n,
38936
- FileLoader as o,
38937
- DoubleSide as p,
38938
- Clock as q,
38939
- WebGLRenderTarget as r,
38940
- SRGBColorSpace as s,
38941
- UnsignedByteType as t,
38942
- RGBAFormat as u,
38943
- WebGLCubeRenderTarget as v,
38944
- LinearSRGBColorSpace as w,
39351
+ RED_RGTC1_Format as b0,
39352
+ SIGNED_RED_RGTC1_Format as b1,
39353
+ RGBA_S3TC_DXT5_Format as b2,
39354
+ RGB_S3TC_DXT1_Format as b3,
39355
+ RGBA_S3TC_DXT1_Format as b4,
39356
+ RGBA_ASTC_6x6_Format as b5,
39357
+ RGBA_ASTC_4x4_Format as b6,
39358
+ SIGNED_RG11_EAC_Format as b7,
39359
+ RG11_EAC_Format as b8,
39360
+ SIGNED_R11_EAC_Format as b9,
39361
+ RGBAIntegerFormat as bA,
39362
+ WebGLArrayRenderTarget as bB,
39363
+ GLSL3 as bC,
39364
+ Timer as bD,
39365
+ WebGLCubeRenderTarget as bE,
39366
+ CubeCamera as bF,
39367
+ Camera as bG,
39368
+ PMREMGenerator as bH,
39369
+ InstancedBufferGeometry as bI,
39370
+ RawShaderMaterial as bJ,
39371
+ R11_EAC_Format as ba,
39372
+ RGB_ETC2_Format as bb,
39373
+ RGBA_ETC2_EAC_Format as bc,
39374
+ RGBFormat as bd,
39375
+ RedFormat as be,
39376
+ UnsignedInt101111Type as bf,
39377
+ UnsignedInt5999Type as bg,
39378
+ UnsignedShortType as bh,
39379
+ Data3DTexture as bi,
39380
+ RGB_PVRTC_4BPPV1_Format as bj,
39381
+ RGB_ETC1_Format as bk,
39382
+ RGB_BPTC_UNSIGNED_Format as bl,
39383
+ normalizeLayerOffset as bm,
39384
+ geodeticOffsetToEcefDelta as bn,
39385
+ validateGeodeticPosition as bo,
39386
+ validateTuple as bp,
39387
+ validateScale as bq,
39388
+ geodeticToEcefPosition as br,
39389
+ AgXToneMapping as bs,
39390
+ EquirectangularReflectionMapping as bt,
39391
+ validateRotation as bu,
39392
+ requireFiniteNumber as bv,
39393
+ computeElevation as bw,
39394
+ DataArrayTexture as bx,
39395
+ RGIntegerFormat as by,
39396
+ UnsignedIntType as bz,
39397
+ ShaderMaterial as c,
39398
+ Plane as d,
39399
+ Raycaster as e,
39400
+ MathUtils as f,
39401
+ TriangleFanDrawMode as g,
39402
+ TriangleStripDrawMode as h,
39403
+ LoaderUtils as i,
39404
+ MeshPhysicalMaterial as j,
39405
+ Color as k,
39406
+ LinearSRGBColorSpace as l,
39407
+ SRGBColorSpace as m,
39408
+ SpotLight as n,
39409
+ PointLight as o,
39410
+ InstancedBufferAttribute as p,
39411
+ TextureLoader as q,
39412
+ ImageBitmapLoader as r,
39413
+ BufferAttribute as s,
39414
+ InterleavedBuffer as t,
39415
+ LinearMipmapLinearFilter as u,
39416
+ LinearMipmapNearestFilter as v,
39417
+ NearestMipmapNearestFilter as w,
38945
39418
  LinearFilter as x,
38946
- LinearMipMapLinearFilter as y,
38947
- CubeCamera as z
39419
+ NearestFilter as y,
39420
+ RepeatWrapping as z
38948
39421
  };