copper3d 2.0.7 → 2.0.9

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.
@@ -5,7 +5,7 @@ import zlib from 'zlib';
5
5
  * Copyright 2010-2023 Three.js Authors
6
6
  * SPDX-License-Identifier: MIT
7
7
  */
8
- const REVISION$1 = '158';
8
+ const REVISION$1 = '161';
9
9
 
10
10
  const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
11
11
  const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
@@ -61,6 +61,7 @@ const ReinhardToneMapping = 2;
61
61
  const CineonToneMapping = 3;
62
62
  const ACESFilmicToneMapping = 4;
63
63
  const CustomToneMapping = 5;
64
+ const AgXToneMapping = 6;
64
65
  const AttachedBindMode = 'attached';
65
66
  const DetachedBindMode = 'detached';
66
67
 
@@ -1577,22 +1578,6 @@ const ColorManagement = {
1577
1578
 
1578
1579
  _workingColorSpace: LinearSRGBColorSpace,
1579
1580
 
1580
- get legacyMode() {
1581
-
1582
- console.warn( 'THREE.ColorManagement: .legacyMode=false renamed to .enabled=true in r150.' );
1583
-
1584
- return ! this.enabled;
1585
-
1586
- },
1587
-
1588
- set legacyMode( legacyMode ) {
1589
-
1590
- console.warn( 'THREE.ColorManagement: .legacyMode=false renamed to .enabled=true in r150.' );
1591
-
1592
- this.enabled = ! legacyMode;
1593
-
1594
- },
1595
-
1596
1581
  get workingColorSpace() {
1597
1582
 
1598
1583
  return this._workingColorSpace;
@@ -1805,6 +1790,7 @@ class Source {
1805
1790
  this.uuid = generateUUID();
1806
1791
 
1807
1792
  this.data = data;
1793
+ this.dataReady = true;
1808
1794
 
1809
1795
  this.version = 0;
1810
1796
 
@@ -3261,7 +3247,7 @@ class Quaternion {
3261
3247
 
3262
3248
  }
3263
3249
 
3264
- setFromEuler( euler, update ) {
3250
+ setFromEuler( euler, update = true ) {
3265
3251
 
3266
3252
  const x = euler._x, y = euler._y, z = euler._z, order = euler._order;
3267
3253
 
@@ -3329,7 +3315,7 @@ class Quaternion {
3329
3315
 
3330
3316
  }
3331
3317
 
3332
- if ( update !== false ) this._onChangeCallback();
3318
+ if ( update === true ) this._onChangeCallback();
3333
3319
 
3334
3320
  return this;
3335
3321
 
@@ -3624,8 +3610,7 @@ class Quaternion {
3624
3610
  this._y = s * y + t * this._y;
3625
3611
  this._z = s * z + t * this._z;
3626
3612
 
3627
- this.normalize();
3628
- this._onChangeCallback();
3613
+ this.normalize(); // normalize calls _onChangeCallback()
3629
3614
 
3630
3615
  return this;
3631
3616
 
@@ -3713,6 +3698,8 @@ class Quaternion {
3713
3698
  this._z = attribute.getZ( index );
3714
3699
  this._w = attribute.getW( index );
3715
3700
 
3701
+ this._onChangeCallback();
3702
+
3716
3703
  return this;
3717
3704
 
3718
3705
  }
@@ -4248,9 +4235,9 @@ class Vector3 {
4248
4235
 
4249
4236
  projectOnPlane( planeNormal ) {
4250
4237
 
4251
- _vector$b.copy( this ).projectOnVector( planeNormal );
4238
+ _vector$c.copy( this ).projectOnVector( planeNormal );
4252
4239
 
4253
- return this.sub( _vector$b );
4240
+ return this.sub( _vector$c );
4254
4241
 
4255
4242
  }
4256
4243
 
@@ -4259,7 +4246,7 @@ class Vector3 {
4259
4246
  // reflect incident vector off plane orthogonal to normal
4260
4247
  // normal is assumed to have unit length
4261
4248
 
4262
- return this.sub( _vector$b.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
4249
+ return this.sub( _vector$c.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
4263
4250
 
4264
4251
  }
4265
4252
 
@@ -4461,7 +4448,7 @@ class Vector3 {
4461
4448
 
4462
4449
  }
4463
4450
 
4464
- const _vector$b = /*@__PURE__*/ new Vector3();
4451
+ const _vector$c = /*@__PURE__*/ new Vector3();
4465
4452
  const _quaternion$4 = /*@__PURE__*/ new Quaternion();
4466
4453
 
4467
4454
  class Box3 {
@@ -4490,7 +4477,7 @@ class Box3 {
4490
4477
 
4491
4478
  for ( let i = 0, il = array.length; i < il; i += 3 ) {
4492
4479
 
4493
- this.expandByPoint( _vector$a.fromArray( array, i ) );
4480
+ this.expandByPoint( _vector$b.fromArray( array, i ) );
4494
4481
 
4495
4482
  }
4496
4483
 
@@ -4504,7 +4491,7 @@ class Box3 {
4504
4491
 
4505
4492
  for ( let i = 0, il = attribute.count; i < il; i ++ ) {
4506
4493
 
4507
- this.expandByPoint( _vector$a.fromBufferAttribute( attribute, i ) );
4494
+ this.expandByPoint( _vector$b.fromBufferAttribute( attribute, i ) );
4508
4495
 
4509
4496
  }
4510
4497
 
@@ -4528,7 +4515,7 @@ class Box3 {
4528
4515
 
4529
4516
  setFromCenterAndSize( center, size ) {
4530
4517
 
4531
- const halfSize = _vector$a.copy( size ).multiplyScalar( 0.5 );
4518
+ const halfSize = _vector$b.copy( size ).multiplyScalar( 0.5 );
4532
4519
 
4533
4520
  this.min.copy( center ).sub( halfSize );
4534
4521
  this.max.copy( center ).add( halfSize );
@@ -4638,16 +4625,16 @@ class Box3 {
4638
4625
 
4639
4626
  if ( object.isMesh === true ) {
4640
4627
 
4641
- object.getVertexPosition( i, _vector$a );
4628
+ object.getVertexPosition( i, _vector$b );
4642
4629
 
4643
4630
  } else {
4644
4631
 
4645
- _vector$a.fromBufferAttribute( positionAttribute, i );
4632
+ _vector$b.fromBufferAttribute( positionAttribute, i );
4646
4633
 
4647
4634
  }
4648
4635
 
4649
- _vector$a.applyMatrix4( object.matrixWorld );
4650
- this.expandByPoint( _vector$a );
4636
+ _vector$b.applyMatrix4( object.matrixWorld );
4637
+ this.expandByPoint( _vector$b );
4651
4638
 
4652
4639
  }
4653
4640
 
@@ -4663,7 +4650,7 @@ class Box3 {
4663
4650
 
4664
4651
  }
4665
4652
 
4666
- _box$3.copy( object.boundingBox );
4653
+ _box$4.copy( object.boundingBox );
4667
4654
 
4668
4655
 
4669
4656
  } else {
@@ -4676,13 +4663,13 @@ class Box3 {
4676
4663
 
4677
4664
  }
4678
4665
 
4679
- _box$3.copy( geometry.boundingBox );
4666
+ _box$4.copy( geometry.boundingBox );
4680
4667
 
4681
4668
  }
4682
4669
 
4683
- _box$3.applyMatrix4( object.matrixWorld );
4670
+ _box$4.applyMatrix4( object.matrixWorld );
4684
4671
 
4685
- this.union( _box$3 );
4672
+ this.union( _box$4 );
4686
4673
 
4687
4674
  }
4688
4675
 
@@ -4741,10 +4728,10 @@ class Box3 {
4741
4728
  intersectsSphere( sphere ) {
4742
4729
 
4743
4730
  // Find the point on the AABB closest to the sphere center.
4744
- this.clampPoint( sphere.center, _vector$a );
4731
+ this.clampPoint( sphere.center, _vector$b );
4745
4732
 
4746
4733
  // If that point is inside the sphere, the AABB and sphere intersect.
4747
- return _vector$a.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
4734
+ return _vector$b.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
4748
4735
 
4749
4736
  }
4750
4737
 
@@ -4856,7 +4843,7 @@ class Box3 {
4856
4843
 
4857
4844
  distanceToPoint( point ) {
4858
4845
 
4859
- return this.clampPoint( point, _vector$a ).distanceTo( point );
4846
+ return this.clampPoint( point, _vector$b ).distanceTo( point );
4860
4847
 
4861
4848
  }
4862
4849
 
@@ -4870,7 +4857,7 @@ class Box3 {
4870
4857
 
4871
4858
  this.getCenter( target.center );
4872
4859
 
4873
- target.radius = this.getSize( _vector$a ).length() * 0.5;
4860
+ target.radius = this.getSize( _vector$b ).length() * 0.5;
4874
4861
 
4875
4862
  }
4876
4863
 
@@ -4948,9 +4935,9 @@ const _points = [
4948
4935
  /*@__PURE__*/ new Vector3()
4949
4936
  ];
4950
4937
 
4951
- const _vector$a = /*@__PURE__*/ new Vector3();
4938
+ const _vector$b = /*@__PURE__*/ new Vector3();
4952
4939
 
4953
- const _box$3 = /*@__PURE__*/ new Box3();
4940
+ const _box$4 = /*@__PURE__*/ new Box3();
4954
4941
 
4955
4942
  // triangle centered vertices
4956
4943
 
@@ -4995,7 +4982,7 @@ function satForAxes( axes, v0, v1, v2, extents ) {
4995
4982
 
4996
4983
  }
4997
4984
 
4998
- const _box$2 = /*@__PURE__*/ new Box3();
4985
+ const _box$3 = /*@__PURE__*/ new Box3();
4999
4986
  const _v1$6 = /*@__PURE__*/ new Vector3();
5000
4987
  const _v2$3 = /*@__PURE__*/ new Vector3();
5001
4988
 
@@ -5003,6 +4990,8 @@ class Sphere {
5003
4990
 
5004
4991
  constructor( center = new Vector3(), radius = - 1 ) {
5005
4992
 
4993
+ this.isSphere = true;
4994
+
5006
4995
  this.center = center;
5007
4996
  this.radius = radius;
5008
4997
 
@@ -5027,7 +5016,7 @@ class Sphere {
5027
5016
 
5028
5017
  } else {
5029
5018
 
5030
- _box$2.setFromPoints( points ).getCenter( center );
5019
+ _box$3.setFromPoints( points ).getCenter( center );
5031
5020
 
5032
5021
  }
5033
5022
 
@@ -5234,7 +5223,7 @@ class Sphere {
5234
5223
 
5235
5224
  }
5236
5225
 
5237
- const _vector$9 = /*@__PURE__*/ new Vector3();
5226
+ const _vector$a = /*@__PURE__*/ new Vector3();
5238
5227
  const _segCenter = /*@__PURE__*/ new Vector3();
5239
5228
  const _segDir = /*@__PURE__*/ new Vector3();
5240
5229
  const _diff = /*@__PURE__*/ new Vector3();
@@ -5286,7 +5275,7 @@ class Ray {
5286
5275
 
5287
5276
  recast( t ) {
5288
5277
 
5289
- this.origin.copy( this.at( t, _vector$9 ) );
5278
+ this.origin.copy( this.at( t, _vector$a ) );
5290
5279
 
5291
5280
  return this;
5292
5281
 
@@ -5316,7 +5305,7 @@ class Ray {
5316
5305
 
5317
5306
  distanceSqToPoint( point ) {
5318
5307
 
5319
- const directionDistance = _vector$9.subVectors( point, this.origin ).dot( this.direction );
5308
+ const directionDistance = _vector$a.subVectors( point, this.origin ).dot( this.direction );
5320
5309
 
5321
5310
  // point behind the ray
5322
5311
 
@@ -5326,9 +5315,9 @@ class Ray {
5326
5315
 
5327
5316
  }
5328
5317
 
5329
- _vector$9.copy( this.origin ).addScaledVector( this.direction, directionDistance );
5318
+ _vector$a.copy( this.origin ).addScaledVector( this.direction, directionDistance );
5330
5319
 
5331
- return _vector$9.distanceToSquared( point );
5320
+ return _vector$a.distanceToSquared( point );
5332
5321
 
5333
5322
  }
5334
5323
 
@@ -5453,9 +5442,9 @@ class Ray {
5453
5442
 
5454
5443
  intersectSphere( sphere, target ) {
5455
5444
 
5456
- _vector$9.subVectors( sphere.center, this.origin );
5457
- const tca = _vector$9.dot( this.direction );
5458
- const d2 = _vector$9.dot( _vector$9 ) - tca * tca;
5445
+ _vector$a.subVectors( sphere.center, this.origin );
5446
+ const tca = _vector$a.dot( this.direction );
5447
+ const d2 = _vector$a.dot( _vector$a ) - tca * tca;
5459
5448
  const radius2 = sphere.radius * sphere.radius;
5460
5449
 
5461
5450
  if ( d2 > radius2 ) return null;
@@ -5622,7 +5611,7 @@ class Ray {
5622
5611
 
5623
5612
  intersectsBox( box ) {
5624
5613
 
5625
- return this.intersectBox( box, _vector$9 ) !== null;
5614
+ return this.intersectBox( box, _vector$a ) !== null;
5626
5615
 
5627
5616
  }
5628
5617
 
@@ -6635,7 +6624,7 @@ const _x = /*@__PURE__*/ new Vector3();
6635
6624
  const _y = /*@__PURE__*/ new Vector3();
6636
6625
  const _z = /*@__PURE__*/ new Vector3();
6637
6626
 
6638
- const _matrix = /*@__PURE__*/ new Matrix4();
6627
+ const _matrix$1 = /*@__PURE__*/ new Matrix4();
6639
6628
  const _quaternion$3 = /*@__PURE__*/ new Quaternion();
6640
6629
 
6641
6630
  class Euler {
@@ -6870,9 +6859,9 @@ class Euler {
6870
6859
 
6871
6860
  setFromQuaternion( q, order, update ) {
6872
6861
 
6873
- _matrix.makeRotationFromQuaternion( q );
6862
+ _matrix$1.makeRotationFromQuaternion( q );
6874
6863
 
6875
- return this.setFromRotationMatrix( _matrix, order, update );
6864
+ return this.setFromRotationMatrix( _matrix$1, order, update );
6876
6865
 
6877
6866
  }
6878
6867
 
@@ -7094,9 +7083,9 @@ class Object3D extends EventDispatcher {
7094
7083
  this.matrixWorld = new Matrix4();
7095
7084
 
7096
7085
  this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE;
7097
- this.matrixWorldNeedsUpdate = false;
7098
7086
 
7099
7087
  this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer
7088
+ this.matrixWorldNeedsUpdate = false;
7100
7089
 
7101
7090
  this.layers = new Layers();
7102
7091
  this.visible = true;
@@ -7113,6 +7102,10 @@ class Object3D extends EventDispatcher {
7113
7102
 
7114
7103
  }
7115
7104
 
7105
+ onBeforeShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {}
7106
+
7107
+ onAfterShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {}
7108
+
7116
7109
  onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {}
7117
7110
 
7118
7111
  onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {}
@@ -7453,21 +7446,15 @@ class Object3D extends EventDispatcher {
7453
7446
 
7454
7447
  }
7455
7448
 
7456
- getObjectsByProperty( name, value ) {
7457
-
7458
- let result = [];
7449
+ getObjectsByProperty( name, value, result = [] ) {
7459
7450
 
7460
7451
  if ( this[ name ] === value ) result.push( this );
7461
7452
 
7462
- for ( let i = 0, l = this.children.length; i < l; i ++ ) {
7463
-
7464
- const childResult = this.children[ i ].getObjectsByProperty( name, value );
7453
+ const children = this.children;
7465
7454
 
7466
- if ( childResult.length > 0 ) {
7455
+ for ( let i = 0, l = children.length; i < l; i ++ ) {
7467
7456
 
7468
- result = result.concat( childResult );
7469
-
7470
- }
7457
+ children[ i ].getObjectsByProperty( name, value, result );
7471
7458
 
7472
7459
  }
7473
7460
 
@@ -7715,6 +7702,56 @@ class Object3D extends EventDispatcher {
7715
7702
 
7716
7703
  }
7717
7704
 
7705
+ if ( this.isBatchedMesh ) {
7706
+
7707
+ object.type = 'BatchedMesh';
7708
+ object.perObjectFrustumCulled = this.perObjectFrustumCulled;
7709
+ object.sortObjects = this.sortObjects;
7710
+
7711
+ object.drawRanges = this._drawRanges;
7712
+ object.reservedRanges = this._reservedRanges;
7713
+
7714
+ object.visibility = this._visibility;
7715
+ object.active = this._active;
7716
+ object.bounds = this._bounds.map( bound => ( {
7717
+ boxInitialized: bound.boxInitialized,
7718
+ boxMin: bound.box.min.toArray(),
7719
+ boxMax: bound.box.max.toArray(),
7720
+
7721
+ sphereInitialized: bound.sphereInitialized,
7722
+ sphereRadius: bound.sphere.radius,
7723
+ sphereCenter: bound.sphere.center.toArray()
7724
+ } ) );
7725
+
7726
+ object.maxGeometryCount = this._maxGeometryCount;
7727
+ object.maxVertexCount = this._maxVertexCount;
7728
+ object.maxIndexCount = this._maxIndexCount;
7729
+
7730
+ object.geometryInitialized = this._geometryInitialized;
7731
+ object.geometryCount = this._geometryCount;
7732
+
7733
+ object.matricesTexture = this._matricesTexture.toJSON( meta );
7734
+
7735
+ if ( this.boundingSphere !== null ) {
7736
+
7737
+ object.boundingSphere = {
7738
+ center: object.boundingSphere.center.toArray(),
7739
+ radius: object.boundingSphere.radius
7740
+ };
7741
+
7742
+ }
7743
+
7744
+ if ( this.boundingBox !== null ) {
7745
+
7746
+ object.boundingBox = {
7747
+ min: object.boundingBox.min.toArray(),
7748
+ max: object.boundingBox.max.toArray()
7749
+ };
7750
+
7751
+ }
7752
+
7753
+ }
7754
+
7718
7755
  //
7719
7756
 
7720
7757
  function serialize( library, element ) {
@@ -7915,9 +7952,9 @@ class Object3D extends EventDispatcher {
7915
7952
  this.matrixWorld.copy( source.matrixWorld );
7916
7953
 
7917
7954
  this.matrixAutoUpdate = source.matrixAutoUpdate;
7918
- this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
7919
7955
 
7920
7956
  this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate;
7957
+ this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
7921
7958
 
7922
7959
  this.layers.mask = source.layers.mask;
7923
7960
  this.visible = source.visible;
@@ -7956,7 +7993,7 @@ Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true;
7956
7993
  const _v0$1 = /*@__PURE__*/ new Vector3();
7957
7994
  const _v1$3 = /*@__PURE__*/ new Vector3();
7958
7995
  const _v2$2 = /*@__PURE__*/ new Vector3();
7959
- const _v3$1 = /*@__PURE__*/ new Vector3();
7996
+ const _v3$2 = /*@__PURE__*/ new Vector3();
7960
7997
 
7961
7998
  const _vab = /*@__PURE__*/ new Vector3();
7962
7999
  const _vac = /*@__PURE__*/ new Vector3();
@@ -7965,8 +8002,6 @@ const _vap = /*@__PURE__*/ new Vector3();
7965
8002
  const _vbp = /*@__PURE__*/ new Vector3();
7966
8003
  const _vcp = /*@__PURE__*/ new Vector3();
7967
8004
 
7968
- let warnedGetUV = false;
7969
-
7970
8005
  class Triangle {
7971
8006
 
7972
8007
  constructor( a = new Vector3(), b = new Vector3(), c = new Vector3() ) {
@@ -8013,9 +8048,8 @@ class Triangle {
8013
8048
  // collinear or singular triangle
8014
8049
  if ( denom === 0 ) {
8015
8050
 
8016
- // arbitrary location outside of triangle?
8017
- // not sure if this is the best idea, maybe should be returning undefined
8018
- return target.set( - 2, - 1, - 1 );
8051
+ target.set( 0, 0, 0 );
8052
+ return null;
8019
8053
 
8020
8054
  }
8021
8055
 
@@ -8030,34 +8064,33 @@ class Triangle {
8030
8064
 
8031
8065
  static containsPoint( point, a, b, c ) {
8032
8066
 
8033
- this.getBarycoord( point, a, b, c, _v3$1 );
8034
-
8035
- return ( _v3$1.x >= 0 ) && ( _v3$1.y >= 0 ) && ( ( _v3$1.x + _v3$1.y ) <= 1 );
8036
-
8037
- }
8038
-
8039
- static getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) { // @deprecated, r151
8040
-
8041
- if ( warnedGetUV === false ) {
8067
+ // if the triangle is degenerate then we can't contain a point
8068
+ if ( this.getBarycoord( point, a, b, c, _v3$2 ) === null ) {
8042
8069
 
8043
- console.warn( 'THREE.Triangle.getUV() has been renamed to THREE.Triangle.getInterpolation().' );
8044
-
8045
- warnedGetUV = true;
8070
+ return false;
8046
8071
 
8047
8072
  }
8048
8073
 
8049
- return this.getInterpolation( point, p1, p2, p3, uv1, uv2, uv3, target );
8074
+ return ( _v3$2.x >= 0 ) && ( _v3$2.y >= 0 ) && ( ( _v3$2.x + _v3$2.y ) <= 1 );
8050
8075
 
8051
8076
  }
8052
8077
 
8053
8078
  static getInterpolation( point, p1, p2, p3, v1, v2, v3, target ) {
8054
8079
 
8055
- this.getBarycoord( point, p1, p2, p3, _v3$1 );
8080
+ if ( this.getBarycoord( point, p1, p2, p3, _v3$2 ) === null ) {
8081
+
8082
+ target.x = 0;
8083
+ target.y = 0;
8084
+ if ( 'z' in target ) target.z = 0;
8085
+ if ( 'w' in target ) target.w = 0;
8086
+ return null;
8087
+
8088
+ }
8056
8089
 
8057
8090
  target.setScalar( 0 );
8058
- target.addScaledVector( v1, _v3$1.x );
8059
- target.addScaledVector( v2, _v3$1.y );
8060
- target.addScaledVector( v3, _v3$1.z );
8091
+ target.addScaledVector( v1, _v3$2.x );
8092
+ target.addScaledVector( v2, _v3$2.y );
8093
+ target.addScaledVector( v3, _v3$2.z );
8061
8094
 
8062
8095
  return target;
8063
8096
 
@@ -8152,20 +8185,6 @@ class Triangle {
8152
8185
 
8153
8186
  }
8154
8187
 
8155
- getUV( point, uv1, uv2, uv3, target ) { // @deprecated, r151
8156
-
8157
- if ( warnedGetUV === false ) {
8158
-
8159
- console.warn( 'THREE.Triangle.getUV() has been renamed to THREE.Triangle.getInterpolation().' );
8160
-
8161
- warnedGetUV = true;
8162
-
8163
- }
8164
-
8165
- return Triangle.getInterpolation( point, this.a, this.b, this.c, uv1, uv2, uv3, target );
8166
-
8167
- }
8168
-
8169
8188
  getInterpolation( point, v1, v2, v3, target ) {
8170
8189
 
8171
8190
  return Triangle.getInterpolation( point, this.a, this.b, this.c, v1, v2, v3, target );
@@ -9658,7 +9677,7 @@ const DataUtils = {
9658
9677
  fromHalfFloat: fromHalfFloat,
9659
9678
  };
9660
9679
 
9661
- const _vector$8 = /*@__PURE__*/ new Vector3();
9680
+ const _vector$9 = /*@__PURE__*/ new Vector3();
9662
9681
  const _vector2$1 = /*@__PURE__*/ new Vector2();
9663
9682
 
9664
9683
  class BufferAttribute {
@@ -9681,7 +9700,8 @@ class BufferAttribute {
9681
9700
  this.normalized = normalized;
9682
9701
 
9683
9702
  this.usage = StaticDrawUsage;
9684
- this.updateRange = { offset: 0, count: - 1 };
9703
+ this._updateRange = { offset: 0, count: - 1 };
9704
+ this.updateRanges = [];
9685
9705
  this.gpuType = FloatType;
9686
9706
 
9687
9707
  this.version = 0;
@@ -9696,6 +9716,13 @@ class BufferAttribute {
9696
9716
 
9697
9717
  }
9698
9718
 
9719
+ get updateRange() {
9720
+
9721
+ warnOnce( 'THREE.BufferAttribute: updateRange() is deprecated and will be removed in r169. Use addUpdateRange() instead.' ); // @deprecated, r159
9722
+ return this._updateRange;
9723
+
9724
+ }
9725
+
9699
9726
  setUsage( value ) {
9700
9727
 
9701
9728
  this.usage = value;
@@ -9704,6 +9731,18 @@ class BufferAttribute {
9704
9731
 
9705
9732
  }
9706
9733
 
9734
+ addUpdateRange( start, count ) {
9735
+
9736
+ this.updateRanges.push( { start, count } );
9737
+
9738
+ }
9739
+
9740
+ clearUpdateRanges() {
9741
+
9742
+ this.updateRanges.length = 0;
9743
+
9744
+ }
9745
+
9707
9746
  copy( source ) {
9708
9747
 
9709
9748
  this.name = source.name;
@@ -9759,10 +9798,10 @@ class BufferAttribute {
9759
9798
 
9760
9799
  for ( let i = 0, l = this.count; i < l; i ++ ) {
9761
9800
 
9762
- _vector$8.fromBufferAttribute( this, i );
9763
- _vector$8.applyMatrix3( m );
9801
+ _vector$9.fromBufferAttribute( this, i );
9802
+ _vector$9.applyMatrix3( m );
9764
9803
 
9765
- this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z );
9804
+ this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );
9766
9805
 
9767
9806
  }
9768
9807
 
@@ -9776,11 +9815,11 @@ class BufferAttribute {
9776
9815
 
9777
9816
  for ( let i = 0, l = this.count; i < l; i ++ ) {
9778
9817
 
9779
- _vector$8.fromBufferAttribute( this, i );
9818
+ _vector$9.fromBufferAttribute( this, i );
9780
9819
 
9781
- _vector$8.applyMatrix4( m );
9820
+ _vector$9.applyMatrix4( m );
9782
9821
 
9783
- this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z );
9822
+ this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );
9784
9823
 
9785
9824
  }
9786
9825
 
@@ -9792,11 +9831,11 @@ class BufferAttribute {
9792
9831
 
9793
9832
  for ( let i = 0, l = this.count; i < l; i ++ ) {
9794
9833
 
9795
- _vector$8.fromBufferAttribute( this, i );
9834
+ _vector$9.fromBufferAttribute( this, i );
9796
9835
 
9797
- _vector$8.applyNormalMatrix( m );
9836
+ _vector$9.applyNormalMatrix( m );
9798
9837
 
9799
- this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z );
9838
+ this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );
9800
9839
 
9801
9840
  }
9802
9841
 
@@ -9808,11 +9847,11 @@ class BufferAttribute {
9808
9847
 
9809
9848
  for ( let i = 0, l = this.count; i < l; i ++ ) {
9810
9849
 
9811
- _vector$8.fromBufferAttribute( this, i );
9850
+ _vector$9.fromBufferAttribute( this, i );
9812
9851
 
9813
- _vector$8.transformDirection( m );
9852
+ _vector$9.transformDirection( m );
9814
9853
 
9815
- this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z );
9854
+ this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );
9816
9855
 
9817
9856
  }
9818
9857
 
@@ -10014,7 +10053,6 @@ class BufferAttribute {
10014
10053
 
10015
10054
  if ( this.name !== '' ) data.name = this.name;
10016
10055
  if ( this.usage !== StaticDrawUsage ) data.usage = this.usage;
10017
- if ( this.updateRange.offset !== 0 || this.updateRange.count !== - 1 ) data.updateRange = this.updateRange;
10018
10056
 
10019
10057
  return data;
10020
10058
 
@@ -10058,9 +10096,9 @@ let _id$2 = 0;
10058
10096
  const _m1 = /*@__PURE__*/ new Matrix4();
10059
10097
  const _obj = /*@__PURE__*/ new Object3D();
10060
10098
  const _offset = /*@__PURE__*/ new Vector3();
10061
- const _box$1 = /*@__PURE__*/ new Box3();
10099
+ const _box$2 = /*@__PURE__*/ new Box3();
10062
10100
  const _boxMorphTargets = /*@__PURE__*/ new Box3();
10063
- const _vector$7 = /*@__PURE__*/ new Vector3();
10101
+ const _vector$8 = /*@__PURE__*/ new Vector3();
10064
10102
 
10065
10103
  class BufferGeometry extends EventDispatcher {
10066
10104
 
@@ -10365,20 +10403,20 @@ class BufferGeometry extends EventDispatcher {
10365
10403
  for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
10366
10404
 
10367
10405
  const morphAttribute = morphAttributesPosition[ i ];
10368
- _box$1.setFromBufferAttribute( morphAttribute );
10406
+ _box$2.setFromBufferAttribute( morphAttribute );
10369
10407
 
10370
10408
  if ( this.morphTargetsRelative ) {
10371
10409
 
10372
- _vector$7.addVectors( this.boundingBox.min, _box$1.min );
10373
- this.boundingBox.expandByPoint( _vector$7 );
10410
+ _vector$8.addVectors( this.boundingBox.min, _box$2.min );
10411
+ this.boundingBox.expandByPoint( _vector$8 );
10374
10412
 
10375
- _vector$7.addVectors( this.boundingBox.max, _box$1.max );
10376
- this.boundingBox.expandByPoint( _vector$7 );
10413
+ _vector$8.addVectors( this.boundingBox.max, _box$2.max );
10414
+ this.boundingBox.expandByPoint( _vector$8 );
10377
10415
 
10378
10416
  } else {
10379
10417
 
10380
- this.boundingBox.expandByPoint( _box$1.min );
10381
- this.boundingBox.expandByPoint( _box$1.max );
10418
+ this.boundingBox.expandByPoint( _box$2.min );
10419
+ this.boundingBox.expandByPoint( _box$2.max );
10382
10420
 
10383
10421
  }
10384
10422
 
@@ -10427,7 +10465,7 @@ class BufferGeometry extends EventDispatcher {
10427
10465
 
10428
10466
  const center = this.boundingSphere.center;
10429
10467
 
10430
- _box$1.setFromBufferAttribute( position );
10468
+ _box$2.setFromBufferAttribute( position );
10431
10469
 
10432
10470
  // process morph attributes if present
10433
10471
 
@@ -10440,16 +10478,16 @@ class BufferGeometry extends EventDispatcher {
10440
10478
 
10441
10479
  if ( this.morphTargetsRelative ) {
10442
10480
 
10443
- _vector$7.addVectors( _box$1.min, _boxMorphTargets.min );
10444
- _box$1.expandByPoint( _vector$7 );
10481
+ _vector$8.addVectors( _box$2.min, _boxMorphTargets.min );
10482
+ _box$2.expandByPoint( _vector$8 );
10445
10483
 
10446
- _vector$7.addVectors( _box$1.max, _boxMorphTargets.max );
10447
- _box$1.expandByPoint( _vector$7 );
10484
+ _vector$8.addVectors( _box$2.max, _boxMorphTargets.max );
10485
+ _box$2.expandByPoint( _vector$8 );
10448
10486
 
10449
10487
  } else {
10450
10488
 
10451
- _box$1.expandByPoint( _boxMorphTargets.min );
10452
- _box$1.expandByPoint( _boxMorphTargets.max );
10489
+ _box$2.expandByPoint( _boxMorphTargets.min );
10490
+ _box$2.expandByPoint( _boxMorphTargets.max );
10453
10491
 
10454
10492
  }
10455
10493
 
@@ -10457,7 +10495,7 @@ class BufferGeometry extends EventDispatcher {
10457
10495
 
10458
10496
  }
10459
10497
 
10460
- _box$1.getCenter( center );
10498
+ _box$2.getCenter( center );
10461
10499
 
10462
10500
  // second, try to find a boundingSphere with a radius smaller than the
10463
10501
  // boundingSphere of the boundingBox: sqrt(3) smaller in the best case
@@ -10466,9 +10504,9 @@ class BufferGeometry extends EventDispatcher {
10466
10504
 
10467
10505
  for ( let i = 0, il = position.count; i < il; i ++ ) {
10468
10506
 
10469
- _vector$7.fromBufferAttribute( position, i );
10507
+ _vector$8.fromBufferAttribute( position, i );
10470
10508
 
10471
- maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$7 ) );
10509
+ maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) );
10472
10510
 
10473
10511
  }
10474
10512
 
@@ -10483,16 +10521,16 @@ class BufferGeometry extends EventDispatcher {
10483
10521
 
10484
10522
  for ( let j = 0, jl = morphAttribute.count; j < jl; j ++ ) {
10485
10523
 
10486
- _vector$7.fromBufferAttribute( morphAttribute, j );
10524
+ _vector$8.fromBufferAttribute( morphAttribute, j );
10487
10525
 
10488
10526
  if ( morphTargetsRelative ) {
10489
10527
 
10490
10528
  _offset.fromBufferAttribute( position, j );
10491
- _vector$7.add( _offset );
10529
+ _vector$8.add( _offset );
10492
10530
 
10493
10531
  }
10494
10532
 
10495
- maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$7 ) );
10533
+ maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) );
10496
10534
 
10497
10535
  }
10498
10536
 
@@ -10775,11 +10813,11 @@ class BufferGeometry extends EventDispatcher {
10775
10813
 
10776
10814
  for ( let i = 0, il = normals.count; i < il; i ++ ) {
10777
10815
 
10778
- _vector$7.fromBufferAttribute( normals, i );
10816
+ _vector$8.fromBufferAttribute( normals, i );
10779
10817
 
10780
- _vector$7.normalize();
10818
+ _vector$8.normalize();
10781
10819
 
10782
- normals.setXYZ( i, _vector$7.x, _vector$7.y, _vector$7.z );
10820
+ normals.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z );
10783
10821
 
10784
10822
  }
10785
10823
 
@@ -11121,7 +11159,7 @@ class BufferGeometry extends EventDispatcher {
11121
11159
 
11122
11160
  const _inverseMatrix$3 = /*@__PURE__*/ new Matrix4();
11123
11161
  const _ray$3 = /*@__PURE__*/ new Ray();
11124
- const _sphere$5 = /*@__PURE__*/ new Sphere();
11162
+ const _sphere$6 = /*@__PURE__*/ new Sphere();
11125
11163
  const _sphereHitAt = /*@__PURE__*/ new Vector3();
11126
11164
 
11127
11165
  const _vA$1 = /*@__PURE__*/ new Vector3();
@@ -11269,16 +11307,16 @@ class Mesh extends Object3D {
11269
11307
 
11270
11308
  if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
11271
11309
 
11272
- _sphere$5.copy( geometry.boundingSphere );
11273
- _sphere$5.applyMatrix4( matrixWorld );
11310
+ _sphere$6.copy( geometry.boundingSphere );
11311
+ _sphere$6.applyMatrix4( matrixWorld );
11274
11312
 
11275
11313
  // check distance from ray origin to bounding sphere
11276
11314
 
11277
11315
  _ray$3.copy( raycaster.ray ).recast( raycaster.near );
11278
11316
 
11279
- if ( _sphere$5.containsPoint( _ray$3.origin ) === false ) {
11317
+ if ( _sphere$6.containsPoint( _ray$3.origin ) === false ) {
11280
11318
 
11281
- if ( _ray$3.intersectSphere( _sphere$5, _sphereHitAt ) === null ) return;
11319
+ if ( _ray$3.intersectSphere( _sphere$6, _sphereHitAt ) === null ) return;
11282
11320
 
11283
11321
  if ( _ray$3.origin.distanceToSquared( _sphereHitAt ) > ( raycaster.far - raycaster.near ) ** 2 ) return;
11284
11322
 
@@ -11848,7 +11886,9 @@ class ShaderMaterial extends Material {
11848
11886
  derivatives: false, // set to use derivatives
11849
11887
  fragDepth: false, // set to use fragment depth values
11850
11888
  drawBuffers: false, // set to use draw buffers
11851
- shaderTextureLOD: false // set to use shader texture LOD
11889
+ shaderTextureLOD: false, // set to use shader texture LOD
11890
+ clipCullDistance: false, // set to use vertex shader clipping
11891
+ multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID
11852
11892
  };
11853
11893
 
11854
11894
  // When rendered geometry doesn't include these attributes but the material does,
@@ -12060,6 +12100,11 @@ class Camera extends Object3D {
12060
12100
 
12061
12101
  }
12062
12102
 
12103
+ const _v3$1 = /*@__PURE__*/ new Vector3();
12104
+ const _minTarget = /*@__PURE__*/ new Vector2();
12105
+ const _maxTarget = /*@__PURE__*/ new Vector2();
12106
+
12107
+
12063
12108
  class PerspectiveCamera extends Camera {
12064
12109
 
12065
12110
  constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) {
@@ -12158,6 +12203,34 @@ class PerspectiveCamera extends Camera {
12158
12203
 
12159
12204
  }
12160
12205
 
12206
+ /**
12207
+ * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction.
12208
+ * Sets minTarget and maxTarget to the coordinates of the lower-left and upper-right corners of the view rectangle.
12209
+ */
12210
+ getViewBounds( distance, minTarget, maxTarget ) {
12211
+
12212
+ _v3$1.set( - 1, - 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse );
12213
+
12214
+ minTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z );
12215
+
12216
+ _v3$1.set( 1, 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse );
12217
+
12218
+ maxTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z );
12219
+
12220
+ }
12221
+
12222
+ /**
12223
+ * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction.
12224
+ * Copies the result into the target Vector2, where x is width and y is height.
12225
+ */
12226
+ getViewSize( distance, target ) {
12227
+
12228
+ this.getViewBounds( distance, _minTarget, _maxTarget );
12229
+
12230
+ return target.subVectors( _maxTarget, _minTarget );
12231
+
12232
+ }
12233
+
12161
12234
  /**
12162
12235
  * Sets an offset in a larger frustum. This is useful for multi-window or
12163
12236
  * multi-monitor/multi-machine setups.
@@ -12831,8 +12904,8 @@ class Plane {
12831
12904
 
12832
12905
  }
12833
12906
 
12834
- const _sphere$4 = /*@__PURE__*/ new Sphere();
12835
- const _vector$6 = /*@__PURE__*/ new Vector3();
12907
+ const _sphere$5 = /*@__PURE__*/ new Sphere();
12908
+ const _vector$7 = /*@__PURE__*/ new Vector3();
12836
12909
 
12837
12910
  class Frustum {
12838
12911
 
@@ -12910,7 +12983,7 @@ class Frustum {
12910
12983
 
12911
12984
  if ( object.boundingSphere === null ) object.computeBoundingSphere();
12912
12985
 
12913
- _sphere$4.copy( object.boundingSphere ).applyMatrix4( object.matrixWorld );
12986
+ _sphere$5.copy( object.boundingSphere ).applyMatrix4( object.matrixWorld );
12914
12987
 
12915
12988
  } else {
12916
12989
 
@@ -12918,21 +12991,21 @@ class Frustum {
12918
12991
 
12919
12992
  if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
12920
12993
 
12921
- _sphere$4.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );
12994
+ _sphere$5.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );
12922
12995
 
12923
12996
  }
12924
12997
 
12925
- return this.intersectsSphere( _sphere$4 );
12998
+ return this.intersectsSphere( _sphere$5 );
12926
12999
 
12927
13000
  }
12928
13001
 
12929
13002
  intersectsSprite( sprite ) {
12930
13003
 
12931
- _sphere$4.center.set( 0, 0, 0 );
12932
- _sphere$4.radius = 0.7071067811865476;
12933
- _sphere$4.applyMatrix4( sprite.matrixWorld );
13004
+ _sphere$5.center.set( 0, 0, 0 );
13005
+ _sphere$5.radius = 0.7071067811865476;
13006
+ _sphere$5.applyMatrix4( sprite.matrixWorld );
12934
13007
 
12935
- return this.intersectsSphere( _sphere$4 );
13008
+ return this.intersectsSphere( _sphere$5 );
12936
13009
 
12937
13010
  }
12938
13011
 
@@ -12968,11 +13041,11 @@ class Frustum {
12968
13041
 
12969
13042
  // corner at max distance
12970
13043
 
12971
- _vector$6.x = plane.normal.x > 0 ? box.max.x : box.min.x;
12972
- _vector$6.y = plane.normal.y > 0 ? box.max.y : box.min.y;
12973
- _vector$6.z = plane.normal.z > 0 ? box.max.z : box.min.z;
13044
+ _vector$7.x = plane.normal.x > 0 ? box.max.x : box.min.x;
13045
+ _vector$7.y = plane.normal.y > 0 ? box.max.y : box.min.y;
13046
+ _vector$7.z = plane.normal.z > 0 ? box.max.z : box.min.z;
12974
13047
 
12975
- if ( plane.distanceToPoint( _vector$6 ) < 0 ) {
13048
+ if ( plane.distanceToPoint( _vector$7 ) < 0 ) {
12976
13049
 
12977
13050
  return false;
12978
13051
 
@@ -13072,6 +13145,7 @@ function WebGLAttributes( gl, capabilities ) {
13072
13145
 
13073
13146
  const array = attribute.array;
13074
13147
  const usage = attribute.usage;
13148
+ const size = array.byteLength;
13075
13149
 
13076
13150
  const buffer = gl.createBuffer();
13077
13151
 
@@ -13140,7 +13214,8 @@ function WebGLAttributes( gl, capabilities ) {
13140
13214
  buffer: buffer,
13141
13215
  type: type,
13142
13216
  bytesPerElement: array.BYTES_PER_ELEMENT,
13143
- version: attribute.version
13217
+ version: attribute.version,
13218
+ size: size
13144
13219
  };
13145
13220
 
13146
13221
  }
@@ -13148,17 +13223,43 @@ function WebGLAttributes( gl, capabilities ) {
13148
13223
  function updateBuffer( buffer, attribute, bufferType ) {
13149
13224
 
13150
13225
  const array = attribute.array;
13151
- const updateRange = attribute.updateRange;
13226
+ const updateRange = attribute._updateRange; // @deprecated, r159
13227
+ const updateRanges = attribute.updateRanges;
13152
13228
 
13153
13229
  gl.bindBuffer( bufferType, buffer );
13154
13230
 
13155
- if ( updateRange.count === - 1 ) {
13231
+ if ( updateRange.count === - 1 && updateRanges.length === 0 ) {
13156
13232
 
13157
13233
  // Not using update ranges
13158
-
13159
13234
  gl.bufferSubData( bufferType, 0, array );
13160
13235
 
13161
- } else {
13236
+ }
13237
+
13238
+ if ( updateRanges.length !== 0 ) {
13239
+
13240
+ for ( let i = 0, l = updateRanges.length; i < l; i ++ ) {
13241
+
13242
+ const range = updateRanges[ i ];
13243
+ if ( isWebGL2 ) {
13244
+
13245
+ gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT,
13246
+ array, range.start, range.count );
13247
+
13248
+ } else {
13249
+
13250
+ gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT,
13251
+ array.subarray( range.start, range.start + range.count ) );
13252
+
13253
+ }
13254
+
13255
+ }
13256
+
13257
+ attribute.clearUpdateRanges();
13258
+
13259
+ }
13260
+
13261
+ // @deprecated, r159
13262
+ if ( updateRange.count !== - 1 ) {
13162
13263
 
13163
13264
  if ( isWebGL2 ) {
13164
13265
 
@@ -13237,6 +13338,12 @@ function WebGLAttributes( gl, capabilities ) {
13237
13338
 
13238
13339
  } else if ( data.version < attribute.version ) {
13239
13340
 
13341
+ if ( data.size !== attribute.array.byteLength ) {
13342
+
13343
+ throw new Error( 'THREE.WebGLAttributes: The size of the buffer attribute\'s array buffer does not match the original size. Resizing buffer attributes is not supported.' );
13344
+
13345
+ }
13346
+
13240
13347
  updateBuffer( data.buffer, attribute, bufferType );
13241
13348
 
13242
13349
  data.version = attribute.version;
@@ -13357,7 +13464,7 @@ var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alp
13357
13464
 
13358
13465
  var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
13359
13466
 
13360
- var alphatest_fragment = "#ifdef USE_ALPHATEST\n\tif ( diffuseColor.a < alphaTest ) discard;\n#endif";
13467
+ var alphatest_fragment = "#ifdef USE_ALPHATEST\n\t#ifdef ALPHA_TO_COVERAGE\n\tdiffuseColor.a = smoothstep( alphaTest, alphaTest + fwidth( diffuseColor.a ), diffuseColor.a );\n\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\tif ( diffuseColor.a < alphaTest ) discard;\n\t#endif\n#endif";
13361
13468
 
13362
13469
  var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif";
13363
13470
 
@@ -13365,6 +13472,10 @@ var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D(
13365
13472
 
13366
13473
  var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
13367
13474
 
13475
+ var batching_pars_vertex = "#ifdef USE_BATCHING\n\tattribute float batchId;\n\tuniform highp sampler2D batchingTexture;\n\tmat4 getBatchingMatrix( const in float i ) {\n\t\tint size = textureSize( batchingTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif";
13476
+
13477
+ var batching_vertex = "#ifdef USE_BATCHING\n\tmat4 batchingMatrix = getBatchingMatrix( batchId );\n#endif";
13478
+
13368
13479
  var begin_vertex = "vec3 transformed = vec3( position );\n#ifdef USE_ALPHAHASH\n\tvPosition = vec3( position );\n#endif";
13369
13480
 
13370
13481
  var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif";
@@ -13375,7 +13486,7 @@ var iridescence_fragment = "#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 =
13375
13486
 
13376
13487
  var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vBumpMapUv );\n\t\tvec2 dSTdy = dFdy( vBumpMapUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vBumpMapUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n\t\tvec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) );\n\t\tvec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * faceDirection;\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif";
13377
13488
 
13378
- var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif";
13489
+ var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#ifdef ALPHA_TO_COVERAGE\n\t\tfloat distanceToPlane, distanceGradient;\n\t\tfloat clipOpacity = 1.0;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\tclipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\tif ( clipOpacity == 0.0 ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tfloat unionClipOpacity = 1.0;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\t\tunionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tclipOpacity *= 1.0 - unionClipOpacity;\n\t\t#endif\n\t\tdiffuseColor.a *= clipOpacity;\n\t\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tbool clipped = true;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tif ( clipped ) discard;\n\t\t#endif\n\t#endif\n#endif";
13379
13490
 
13380
13491
  var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif";
13381
13492
 
@@ -13393,9 +13504,9 @@ var color_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#el
13393
13504
 
13394
13505
  var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n\tvarying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat luminance( const in vec3 rgb ) {\n\tconst vec3 weights = vec3( 0.2126729, 0.7151522, 0.0721750 );\n\treturn dot( weights, rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated";
13395
13506
 
13396
- var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\thighp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_v0 0.339\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_v1 0.276\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_v4 0.046\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_v5 0.016\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_v6 0.0038\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif";
13507
+ var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\thighp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif";
13397
13508
 
13398
- var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif";
13509
+ var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n\tmat3 bm = mat3( batchingMatrix );\n\ttransformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n\ttransformedNormal = bm * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = bm * transformedTangent;\n\t#endif\n#endif\n#ifdef USE_INSTANCING\n\tmat3 im = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n\ttransformedNormal = im * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = im * transformedTangent;\n\t#endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\ttransformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif";
13399
13510
 
13400
13511
  var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";
13401
13512
 
@@ -13449,7 +13560,7 @@ var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor
13449
13560
 
13450
13561
  var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat 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\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.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\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong";
13451
13562
 
13452
- var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - 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\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tanisotropyV /= material.anisotropy;\n\tmaterial.anisotropy = saturate( material.anisotropy );\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x - tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x + tbn[ 0 ] * anisotropyV.y;\n#endif";
13563
+ var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - 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\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif";
13453
13564
 
13454
13565
  var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat anisotropy;\n\t\tfloat alphaT;\n\t\tvec3 anisotropyT;\n\t\tvec3 anisotropyB;\n\t#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\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n\tfloat 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\t\tfloat gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n\t\tfloat gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n\t\tfloat v = 0.5 / ( gv + gl );\n\t\treturn saturate(v);\n\t}\n\tfloat D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n\t\tfloat a2 = alphaT * alphaB;\n\t\thighp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n\t\thighp float v2 = dot( v, v );\n\t\tfloat w2 = a2 / v2;\n\t\treturn RECIPROCAL_PI * a2 * pow2 ( w2 );\n\t}\n#endif\n#ifdef USE_CLEARCOAT\n\tvec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n\t\tvec3 f0 = material.clearcoatF0;\n\t\tfloat f90 = material.clearcoatF90;\n\t\tfloat roughness = material.clearcoatRoughness;\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 f0 = material.specularColor;\n\tfloat f90 = material.specularF90;\n\tfloat roughness = material.roughness;\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t#ifdef USE_IRIDESCENCE\n\t\tF = mix( F, material.iridescenceFresnel, material.iridescence );\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat dotTL = dot( material.anisotropyT, lightDir );\n\t\tfloat dotTV = dot( material.anisotropyT, viewDir );\n\t\tfloat dotTH = dot( material.anisotropyT, halfDir );\n\t\tfloat dotBL = dot( material.anisotropyB, lightDir );\n\t\tfloat dotBV = dot( material.anisotropyB, viewDir );\n\t\tfloat dotBH = dot( material.anisotropyB, halfDir );\n\t\tfloat V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n\t\tfloat D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n\t#else\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t#endif\n\treturn F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn 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\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn 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\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn 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\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid 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\t\tvec3 normal = geometryNormal;\n\t\tvec3 viewDir = geometryViewDir;\n\t\tvec3 position = geometryPosition;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.roughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\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\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\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\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\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\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}";
13455
13566
 
@@ -13513,7 +13624,7 @@ var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normaliz
13513
13624
 
13514
13625
  var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif";
13515
13626
 
13516
- var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;";
13627
+ var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_BATCHING\n\tmvPosition = batchingMatrix * mvPosition;\n#endif\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;";
13517
13628
 
13518
13629
  var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif";
13519
13630
 
@@ -13533,7 +13644,7 @@ var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n
13533
13644
 
13534
13645
  var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif";
13535
13646
 
13536
- var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tuniform int boneTextureSize;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tfloat j = i * 4.0;\n\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\ty = dy * ( y + 0.5 );\n\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\treturn bone;\n\t}\n#endif";
13647
+ var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tint size = textureSize( boneTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif";
13537
13648
 
13538
13649
  var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif";
13539
13650
 
@@ -13545,7 +13656,7 @@ var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D spe
13545
13656
 
13546
13657
  var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif";
13547
13658
 
13548
- var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }";
13659
+ var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n\tvec3( 1.6605, - 0.1246, - 0.0182 ),\n\tvec3( - 0.5876, 1.1329, - 0.1006 ),\n\tvec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n\tvec3( 0.6274, 0.0691, 0.0164 ),\n\tvec3( 0.3293, 0.9195, 0.0880 ),\n\tvec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n\tvec3 x2 = x * x;\n\tvec3 x4 = x2 * x2;\n\treturn + 15.5 * x4 * x2\n\t\t- 40.14 * x4 * x\n\t\t+ 31.96 * x4\n\t\t- 6.868 * x2 * x\n\t\t+ 0.4298 * x2\n\t\t+ 0.1191 * x\n\t\t- 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n\tconst mat3 AgXInsetMatrix = mat3(\n\t\tvec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n\t\tvec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n\t\tvec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n\t);\n\tconst mat3 AgXOutsetMatrix = mat3(\n\t\tvec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n\t\tvec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n\t\tvec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n\t);\n\tconst float AgxMinEv = - 12.47393;\tconst float AgxMaxEv = 4.026069;\n\tcolor *= toneMappingExposure;\n\tcolor = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n\tcolor = AgXInsetMatrix * color;\n\tcolor = max( color, 1e-10 );\tcolor = log2( color );\n\tcolor = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n\tcolor = clamp( color, 0.0, 1.0 );\n\tcolor = agxDefaultContrastApprox( color );\n\tcolor = AgXOutsetMatrix * color;\n\tcolor = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n\tcolor = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n\tcolor = clamp( color, 0.0, 1.0 );\n\treturn color;\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }";
13549
13660
 
13550
13661
  var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmitted = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif";
13551
13662
 
@@ -13557,7 +13668,7 @@ var uv_pars_vertex = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvary
13557
13668
 
13558
13669
  var uv_vertex = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvUv = vec3( uv, 1 ).xy;\n#endif\n#ifdef USE_MAP\n\tvMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ALPHAMAP\n\tvAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_LIGHTMAP\n\tvLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_AOMAP\n\tvAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_BUMPMAP\n\tvBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_NORMALMAP\n\tvNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tvDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_METALNESSMAP\n\tvMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULARMAP\n\tvSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tvTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_THICKNESSMAP\n\tvThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;\n#endif";
13559
13670
 
13560
- var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif";
13671
+ var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_BATCHING\n\t\tworldPosition = batchingMatrix * worldPosition;\n\t#endif\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif";
13561
13672
 
13562
13673
  const vertex$h = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}";
13563
13674
 
@@ -13571,13 +13682,13 @@ const vertex$f = "varying vec3 vWorldDirection;\n#include <common>\nvoid main()
13571
13682
 
13572
13683
  const fragment$f = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}";
13573
13684
 
13574
- const vertex$e = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}";
13685
+ const vertex$e = "#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}";
13575
13686
 
13576
- const fragment$e = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\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 <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <logdepthbuf_fragment>\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}";
13687
+ const fragment$e = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\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 <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <clipping_planes_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <logdepthbuf_fragment>\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}";
13577
13688
 
13578
- const vertex$d = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}";
13689
+ const vertex$d = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}";
13579
13690
 
13580
- const fragment$d = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\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 <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}";
13691
+ const fragment$d = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\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 <clipping_planes_pars_fragment>\nvoid main () {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <clipping_planes_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}";
13581
13692
 
13582
13693
  const vertex$c = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}";
13583
13694
 
@@ -13585,47 +13696,47 @@ const fragment$c = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\
13585
13696
 
13586
13697
  const vertex$b = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <uv_pars_vertex>\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>\nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
13587
13698
 
13588
- const fragment$b = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
13699
+ const fragment$b = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
13589
13700
 
13590
- const vertex$a = "#include <common>\n#include <uv_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinbase_vertex>\n\t\t#include <skinnormal_vertex>\n\t\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}";
13701
+ const vertex$a = "#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinbase_vertex>\n\t\t#include <skinnormal_vertex>\n\t\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}";
13591
13702
 
13592
- const fragment$a = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\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 <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13703
+ const fragment$a = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\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 <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13593
13704
 
13594
- const vertex$9 = "#define LAMBERT\nvarying vec3 vViewPosition;\n#include <common>\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\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
13705
+ const vertex$9 = "#define LAMBERT\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\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
13595
13706
 
13596
- const fragment$9 = "#define LAMBERT\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\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 <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_lambert_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\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_lambert_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13707
+ const fragment$9 = "#define LAMBERT\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\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 <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_lambert_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\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_lambert_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13597
13708
 
13598
- const vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}";
13709
+ const vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}";
13599
13710
 
13600
- const fragment$8 = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\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 <fog_pars_fragment>\n#include <normal_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\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13711
+ const fragment$8 = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\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 <fog_pars_fragment>\n#include <normal_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\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13601
13712
 
13602
- const vertex$7 = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}";
13713
+ const vertex$7 = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}";
13603
13714
 
13604
- const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <normal_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\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}";
13715
+ const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <normal_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\tvec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity );\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), diffuseColor.a );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}";
13605
13716
 
13606
- const vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\n#include <common>\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\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
13717
+ 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\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
13607
13718
 
13608
- 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 <packing>\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 <envmap_common_pars_fragment>\n#include <envmap_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\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13719
+ 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 <packing>\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 <envmap_common_pars_fragment>\n#include <envmap_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\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13609
13720
 
13610
- const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include <common>\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\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}";
13721
+ const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying 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\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}";
13611
13722
 
13612
- const fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef USE_SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULAR_COLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\tuniform vec2 anisotropyVector;\n\t#ifdef USE_ANISOTROPYMAP\n\t\tuniform sampler2D anisotropyMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n#include <packing>\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\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include <transmission_fragment>\n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecularDirect + sheenSpecularIndirect;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n\t#endif\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13723
+ const fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef USE_SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULAR_COLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\tuniform vec2 anisotropyVector;\n\t#ifdef USE_ANISOTROPYMAP\n\t\tuniform sampler2D anisotropyMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n#include <packing>\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\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include <transmission_fragment>\n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecularDirect + sheenSpecularIndirect;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n\t#endif\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13613
13724
 
13614
- const vertex$4 = "#define TOON\nvarying vec3 vViewPosition;\n#include <common>\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\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
13725
+ 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\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
13615
13726
 
13616
- const fragment$4 = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\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\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13727
+ const fragment$4 = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\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\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
13617
13728
 
13618
13729
  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\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\nvoid main() {\n\t#ifdef USE_POINTS_UV\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\t#endif\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}";
13619
13730
 
13620
- const fragment$3 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
13731
+ const fragment$3 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
13621
13732
 
13622
- const vertex$2 = "#include <common>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
13733
+ const vertex$2 = "#include <common>\n#include <batching_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
13623
13734
 
13624
13735
  const fragment$2 = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <logdepthbuf_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\t#include <logdepthbuf_fragment>\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n}";
13625
13736
 
13626
13737
  const vertex$1 = "uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
13627
13738
 
13628
- const fragment$1 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\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 <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n}";
13739
+ const fragment$1 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\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 <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n}";
13629
13740
 
13630
13741
  const ShaderChunk = {
13631
13742
  alphahash_fragment: alphahash_fragment,
@@ -13636,6 +13747,8 @@ const ShaderChunk = {
13636
13747
  alphatest_pars_fragment: alphatest_pars_fragment,
13637
13748
  aomap_fragment: aomap_fragment,
13638
13749
  aomap_pars_fragment: aomap_pars_fragment,
13750
+ batching_pars_vertex: batching_pars_vertex,
13751
+ batching_vertex: batching_vertex,
13639
13752
  begin_vertex: begin_vertex,
13640
13753
  beginnormal_vertex: beginnormal_vertex,
13641
13754
  bsdfs: bsdfs,
@@ -15249,11 +15362,42 @@ function WebGLBufferRenderer( gl, extensions, info, capabilities ) {
15249
15362
 
15250
15363
  }
15251
15364
 
15365
+ function renderMultiDraw( starts, counts, drawCount ) {
15366
+
15367
+ if ( drawCount === 0 ) return;
15368
+
15369
+ const extension = extensions.get( 'WEBGL_multi_draw' );
15370
+ if ( extension === null ) {
15371
+
15372
+ for ( let i = 0; i < drawCount; i ++ ) {
15373
+
15374
+ this.render( starts[ i ], counts[ i ] );
15375
+
15376
+ }
15377
+
15378
+ } else {
15379
+
15380
+ extension.multiDrawArraysWEBGL( mode, starts, 0, counts, 0, drawCount );
15381
+
15382
+ let elementCount = 0;
15383
+ for ( let i = 0; i < drawCount; i ++ ) {
15384
+
15385
+ elementCount += counts[ i ];
15386
+
15387
+ }
15388
+
15389
+ info.update( elementCount, mode, 1 );
15390
+
15391
+ }
15392
+
15393
+ }
15394
+
15252
15395
  //
15253
15396
 
15254
15397
  this.setMode = setMode;
15255
15398
  this.render = render;
15256
15399
  this.renderInstances = renderInstances;
15400
+ this.renderMultiDraw = renderMultiDraw;
15257
15401
 
15258
15402
  }
15259
15403
 
@@ -15563,7 +15707,7 @@ function WebGLCubeMaps( renderer ) {
15563
15707
 
15564
15708
  function get( texture ) {
15565
15709
 
15566
- if ( texture && texture.isTexture && texture.isRenderTargetTexture === false ) {
15710
+ if ( texture && texture.isTexture ) {
15567
15711
 
15568
15712
  const mapping = texture.mapping;
15569
15713
 
@@ -15580,7 +15724,7 @@ function WebGLCubeMaps( renderer ) {
15580
15724
 
15581
15725
  if ( image && image.height > 0 ) {
15582
15726
 
15583
- const renderTarget = new WebGLCubeRenderTarget( image.height / 2 );
15727
+ const renderTarget = new WebGLCubeRenderTarget( image.height );
15584
15728
  renderTarget.fromEquirectangularTexture( renderer, texture );
15585
15729
  cubemaps.set( texture, renderTarget );
15586
15730
 
@@ -16831,6 +16975,7 @@ function WebGLExtensions( gl ) {
16831
16975
  if ( capabilities.isWebGL2 ) {
16832
16976
 
16833
16977
  getExtension( 'EXT_color_buffer_float' );
16978
+ getExtension( 'WEBGL_clip_cull_distance' );
16834
16979
 
16835
16980
  } else {
16836
16981
 
@@ -17135,12 +17280,43 @@ function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) {
17135
17280
 
17136
17281
  }
17137
17282
 
17283
+ function renderMultiDraw( starts, counts, drawCount ) {
17284
+
17285
+ if ( drawCount === 0 ) return;
17286
+
17287
+ const extension = extensions.get( 'WEBGL_multi_draw' );
17288
+ if ( extension === null ) {
17289
+
17290
+ for ( let i = 0; i < drawCount; i ++ ) {
17291
+
17292
+ this.render( starts[ i ] / bytesPerElement, counts[ i ] );
17293
+
17294
+ }
17295
+
17296
+ } else {
17297
+
17298
+ extension.multiDrawElementsWEBGL( mode, counts, 0, type, starts, 0, drawCount );
17299
+
17300
+ let elementCount = 0;
17301
+ for ( let i = 0; i < drawCount; i ++ ) {
17302
+
17303
+ elementCount += counts[ i ];
17304
+
17305
+ }
17306
+
17307
+ info.update( elementCount, mode, 1 );
17308
+
17309
+ }
17310
+
17311
+ }
17312
+
17138
17313
  //
17139
17314
 
17140
17315
  this.setMode = setMode;
17141
17316
  this.setIndex = setIndex;
17142
17317
  this.render = render;
17143
17318
  this.renderInstances = renderInstances;
17319
+ this.renderMultiDraw = renderMultiDraw;
17144
17320
 
17145
17321
  }
17146
17322
 
@@ -17596,6 +17772,60 @@ function WebGLObjects( gl, geometries, attributes, info ) {
17596
17772
 
17597
17773
  }
17598
17774
 
17775
+ class DepthTexture extends Texture {
17776
+
17777
+ constructor( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {
17778
+
17779
+ format = format !== undefined ? format : DepthFormat;
17780
+
17781
+ if ( format !== DepthFormat && format !== DepthStencilFormat ) {
17782
+
17783
+ throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );
17784
+
17785
+ }
17786
+
17787
+ if ( type === undefined && format === DepthFormat ) type = UnsignedIntType;
17788
+ if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;
17789
+
17790
+ super( null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
17791
+
17792
+ this.isDepthTexture = true;
17793
+
17794
+ this.image = { width: width, height: height };
17795
+
17796
+ this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
17797
+ this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
17798
+
17799
+ this.flipY = false;
17800
+ this.generateMipmaps = false;
17801
+
17802
+ this.compareFunction = null;
17803
+
17804
+ }
17805
+
17806
+
17807
+ copy( source ) {
17808
+
17809
+ super.copy( source );
17810
+
17811
+ this.compareFunction = source.compareFunction;
17812
+
17813
+ return this;
17814
+
17815
+ }
17816
+
17817
+ toJSON( meta ) {
17818
+
17819
+ const data = super.toJSON( meta );
17820
+
17821
+ if ( this.compareFunction !== null ) data.compareFunction = this.compareFunction;
17822
+
17823
+ return data;
17824
+
17825
+ }
17826
+
17827
+ }
17828
+
17599
17829
  /**
17600
17830
  * Uniforms of a program.
17601
17831
  * Those form a tree structure with a special top-level container for the root,
@@ -17641,6 +17871,10 @@ function WebGLObjects( gl, geometries, attributes, info ) {
17641
17871
 
17642
17872
 
17643
17873
  const emptyTexture = /*@__PURE__*/ new Texture();
17874
+
17875
+ const emptyShadowTexture = /*@__PURE__*/ new DepthTexture( 1, 1 );
17876
+ emptyShadowTexture.compareFunction = LessEqualCompare;
17877
+
17644
17878
  const emptyArrayTexture = /*@__PURE__*/ new DataArrayTexture();
17645
17879
  const empty3dTexture = /*@__PURE__*/ new Data3DTexture();
17646
17880
  const emptyCubeTexture = /*@__PURE__*/ new CubeTexture();
@@ -18157,7 +18391,9 @@ function setValueT1( gl, v, textures ) {
18157
18391
 
18158
18392
  }
18159
18393
 
18160
- textures.setTexture2D( v || emptyTexture, unit );
18394
+ const emptyTexture2D = ( this.type === gl.SAMPLER_2D_SHADOW ) ? emptyShadowTexture : emptyTexture;
18395
+
18396
+ textures.setTexture2D( v || emptyTexture2D, unit );
18161
18397
 
18162
18398
  }
18163
18399
 
@@ -18541,6 +18777,7 @@ class SingleUniform {
18541
18777
  this.id = id;
18542
18778
  this.addr = addr;
18543
18779
  this.cache = [];
18780
+ this.type = activeInfo.type;
18544
18781
  this.setValue = getSingularSetter( activeInfo.type );
18545
18782
 
18546
18783
  // this.path = activeInfo.name; // DEBUG
@@ -18556,6 +18793,7 @@ class PureArrayUniform {
18556
18793
  this.id = id;
18557
18794
  this.addr = addr;
18558
18795
  this.cache = [];
18796
+ this.type = activeInfo.type;
18559
18797
  this.size = activeInfo.size;
18560
18798
  this.setValue = getPureArraySetter( activeInfo.type );
18561
18799
 
@@ -18864,6 +19102,10 @@ function getToneMappingFunction( functionName, toneMapping ) {
18864
19102
  toneMappingName = 'ACESFilmic';
18865
19103
  break;
18866
19104
 
19105
+ case AgXToneMapping:
19106
+ toneMappingName = 'AgX';
19107
+ break;
19108
+
18867
19109
  case CustomToneMapping:
18868
19110
  toneMappingName = 'Custom';
18869
19111
  break;
@@ -18881,7 +19123,7 @@ function getToneMappingFunction( functionName, toneMapping ) {
18881
19123
  function generateExtensions( parameters ) {
18882
19124
 
18883
19125
  const chunks = [
18884
- ( parameters.extensionDerivatives || !! parameters.envMapCubeUVHeight || parameters.bumpMap || parameters.normalMapTangentSpace || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '',
19126
+ ( parameters.extensionDerivatives || !! parameters.envMapCubeUVHeight || parameters.bumpMap || parameters.normalMapTangentSpace || parameters.clearcoatNormalMap || parameters.flatShading || parameters.alphaToCoverage || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '',
18885
19127
  ( parameters.extensionFragDepth || parameters.logarithmicDepthBuffer ) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '',
18886
19128
  ( parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ) ? '#extension GL_EXT_draw_buffers : require' : '',
18887
19129
  ( parameters.extensionShaderTextureLOD || parameters.envMap || parameters.transmission ) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : ''
@@ -18891,6 +19133,17 @@ function generateExtensions( parameters ) {
18891
19133
 
18892
19134
  }
18893
19135
 
19136
+ function generateVertexExtensions( parameters ) {
19137
+
19138
+ const chunks = [
19139
+ parameters.extensionClipCullDistance ? '#extension GL_ANGLE_clip_cull_distance : require' : '',
19140
+ parameters.extensionMultiDraw ? '#extension GL_ANGLE_multi_draw : require' : '',
19141
+ ];
19142
+
19143
+ return chunks.filter( filterEmptyLine ).join( '\n' );
19144
+
19145
+ }
19146
+
18894
19147
  function generateDefines( defines ) {
18895
19148
 
18896
19149
  const chunks = [];
@@ -19043,7 +19296,30 @@ function loopReplacer( match, start, end, snippet ) {
19043
19296
 
19044
19297
  function generatePrecision( parameters ) {
19045
19298
 
19046
- let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;';
19299
+ let precisionstring = `precision ${parameters.precision} float;
19300
+ precision ${parameters.precision} int;
19301
+ precision ${parameters.precision} sampler2D;
19302
+ precision ${parameters.precision} samplerCube;
19303
+ `;
19304
+
19305
+ if ( parameters.isWebGL2 ) {
19306
+
19307
+ precisionstring += `precision ${parameters.precision} sampler3D;
19308
+ precision ${parameters.precision} sampler2DArray;
19309
+ precision ${parameters.precision} sampler2DShadow;
19310
+ precision ${parameters.precision} samplerCubeShadow;
19311
+ precision ${parameters.precision} sampler2DArrayShadow;
19312
+ precision ${parameters.precision} isampler2D;
19313
+ precision ${parameters.precision} isampler3D;
19314
+ precision ${parameters.precision} isamplerCube;
19315
+ precision ${parameters.precision} isampler2DArray;
19316
+ precision ${parameters.precision} usampler2D;
19317
+ precision ${parameters.precision} usampler3D;
19318
+ precision ${parameters.precision} usamplerCube;
19319
+ precision ${parameters.precision} usampler2DArray;
19320
+ `;
19321
+
19322
+ }
19047
19323
 
19048
19324
  if ( parameters.precision === 'highp' ) {
19049
19325
 
@@ -19195,6 +19471,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19195
19471
 
19196
19472
  const customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters );
19197
19473
 
19474
+ const customVertexExtensions = generateVertexExtensions( parameters );
19475
+
19198
19476
  const customDefines = generateDefines( defines );
19199
19477
 
19200
19478
  const program = gl.createProgram();
@@ -19247,6 +19525,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19247
19525
 
19248
19526
  customDefines,
19249
19527
 
19528
+ parameters.extensionClipCullDistance ? '#define USE_CLIP_DISTANCE' : '',
19529
+ parameters.batching ? '#define USE_BATCHING' : '',
19250
19530
  parameters.instancing ? '#define USE_INSTANCING' : '',
19251
19531
  parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '',
19252
19532
 
@@ -19468,6 +19748,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19468
19748
  parameters.useFog && parameters.fog ? '#define USE_FOG' : '',
19469
19749
  parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '',
19470
19750
 
19751
+ parameters.alphaToCoverage ? '#define ALPHA_TO_COVERAGE' : '',
19471
19752
  parameters.map ? '#define USE_MAP' : '',
19472
19753
  parameters.matcap ? '#define USE_MATCAP' : '',
19473
19754
  parameters.envMap ? '#define USE_ENVMAP' : '',
@@ -19586,6 +19867,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19586
19867
  versionString = '#version 300 es\n';
19587
19868
 
19588
19869
  prefixVertex = [
19870
+ customVertexExtensions,
19589
19871
  'precision mediump sampler2DArray;',
19590
19872
  '#define attribute in',
19591
19873
  '#define varying out',
@@ -19668,6 +19950,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19668
19950
  console.error(
19669
19951
  'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' +
19670
19952
  'VALIDATE_STATUS ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) + '\n\n' +
19953
+ 'Material Name: ' + self.name + '\n' +
19954
+ 'Material Type: ' + self.type + '\n\n' +
19671
19955
  'Program Info Log: ' + programLog + '\n' +
19672
19956
  vertexErrors + '\n' +
19673
19957
  fragmentErrors
@@ -19931,6 +20215,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
19931
20215
 
19932
20216
  const _programLayers = new Layers();
19933
20217
  const _customShaders = new WebGLShaderCache();
20218
+ const _activeChannels = new Set();
19934
20219
  const programs = [];
19935
20220
 
19936
20221
  const IS_WEBGL2 = capabilities.isWebGL2;
@@ -19959,6 +20244,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
19959
20244
 
19960
20245
  function getChannel( value ) {
19961
20246
 
20247
+ _activeChannels.add( value );
20248
+
19962
20249
  if ( value === 0 ) return 'uv';
19963
20250
 
19964
20251
  return `uv${ value }`;
@@ -20029,6 +20316,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20029
20316
  const currentRenderTarget = renderer.getRenderTarget();
20030
20317
 
20031
20318
  const IS_INSTANCEDMESH = object.isInstancedMesh === true;
20319
+ const IS_BATCHEDMESH = object.isBatchedMesh === true;
20032
20320
 
20033
20321
  const HAS_MAP = !! material.map;
20034
20322
  const HAS_MATCAP = !! material.matcap;
@@ -20078,10 +20366,6 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20078
20366
 
20079
20367
  const HAS_EXTENSIONS = !! material.extensions;
20080
20368
 
20081
- const HAS_ATTRIBUTE_UV1 = !! geometry.attributes.uv1;
20082
- const HAS_ATTRIBUTE_UV2 = !! geometry.attributes.uv2;
20083
- const HAS_ATTRIBUTE_UV3 = !! geometry.attributes.uv3;
20084
-
20085
20369
  let toneMapping = NoToneMapping;
20086
20370
 
20087
20371
  if ( material.toneMapped ) {
@@ -20114,11 +20398,13 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20114
20398
 
20115
20399
  precision: precision,
20116
20400
 
20401
+ batching: IS_BATCHEDMESH,
20117
20402
  instancing: IS_INSTANCEDMESH,
20118
20403
  instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null,
20119
20404
 
20120
20405
  supportsVertexTextures: SUPPORTS_VERTEX_TEXTURES,
20121
20406
  outputColorSpace: ( currentRenderTarget === null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace ),
20407
+ alphaToCoverage: !! material.alphaToCoverage,
20122
20408
 
20123
20409
  map: HAS_MAP,
20124
20410
  matcap: HAS_MATCAP,
@@ -20164,7 +20450,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20164
20450
 
20165
20451
  gradientMap: HAS_GRADIENTMAP,
20166
20452
 
20167
- opaque: material.transparent === false && material.blending === NormalBlending,
20453
+ opaque: material.transparent === false && material.blending === NormalBlending && material.alphaToCoverage === false,
20168
20454
 
20169
20455
  alphaMap: HAS_ALPHAMAP,
20170
20456
  alphaTest: HAS_ALPHATEST,
@@ -20211,15 +20497,12 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20211
20497
  vertexTangents: !! geometry.attributes.tangent && ( HAS_NORMALMAP || HAS_ANISOTROPY ),
20212
20498
  vertexColors: material.vertexColors,
20213
20499
  vertexAlphas: material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4,
20214
- vertexUv1s: HAS_ATTRIBUTE_UV1,
20215
- vertexUv2s: HAS_ATTRIBUTE_UV2,
20216
- vertexUv3s: HAS_ATTRIBUTE_UV3,
20217
20500
 
20218
20501
  pointsUvs: object.isPoints === true && !! geometry.attributes.uv && ( HAS_MAP || HAS_ALPHAMAP ),
20219
20502
 
20220
20503
  fog: !! fog,
20221
20504
  useFog: material.fog === true,
20222
- fogExp2: ( fog && fog.isFogExp2 ),
20505
+ fogExp2: ( !! fog && fog.isFogExp2 ),
20223
20506
 
20224
20507
  flatShading: material.flatShading === true,
20225
20508
 
@@ -20275,6 +20558,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20275
20558
  extensionFragDepth: HAS_EXTENSIONS && material.extensions.fragDepth === true,
20276
20559
  extensionDrawBuffers: HAS_EXTENSIONS && material.extensions.drawBuffers === true,
20277
20560
  extensionShaderTextureLOD: HAS_EXTENSIONS && material.extensions.shaderTextureLOD === true,
20561
+ extensionClipCullDistance: HAS_EXTENSIONS && material.extensions.clipCullDistance === true && extensions.has( 'WEBGL_clip_cull_distance' ),
20562
+ extensionMultiDraw: HAS_EXTENSIONS && material.extensions.multiDraw === true && extensions.has( 'WEBGL_multi_draw' ),
20278
20563
 
20279
20564
  rendererExtensionFragDepth: IS_WEBGL2 || extensions.has( 'EXT_frag_depth' ),
20280
20565
  rendererExtensionDrawBuffers: IS_WEBGL2 || extensions.has( 'WEBGL_draw_buffers' ),
@@ -20285,6 +20570,14 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20285
20570
 
20286
20571
  };
20287
20572
 
20573
+ // the usage of getChannel() determines the active texture channels for this shader
20574
+
20575
+ parameters.vertexUv1s = _activeChannels.has( 1 );
20576
+ parameters.vertexUv2s = _activeChannels.has( 2 );
20577
+ parameters.vertexUv3s = _activeChannels.has( 3 );
20578
+
20579
+ _activeChannels.clear();
20580
+
20288
20581
  return parameters;
20289
20582
 
20290
20583
  }
@@ -20424,6 +20717,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20424
20717
  _programLayers.enable( 17 );
20425
20718
  if ( parameters.alphaHash )
20426
20719
  _programLayers.enable( 18 );
20720
+ if ( parameters.batching )
20721
+ _programLayers.enable( 19 );
20427
20722
 
20428
20723
  array.push( _programLayers.mask );
20429
20724
  _programLayers.disableAll();
@@ -20468,6 +20763,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20468
20763
  _programLayers.enable( 18 );
20469
20764
  if ( parameters.decodeVideoTexture )
20470
20765
  _programLayers.enable( 19 );
20766
+ if ( parameters.alphaToCoverage )
20767
+ _programLayers.enable( 20 );
20471
20768
 
20472
20769
  array.push( _programLayers.mask );
20473
20770
 
@@ -21247,8 +21544,17 @@ function WebGLLights( extensions, capabilities ) {
21247
21544
 
21248
21545
  // WebGL 2
21249
21546
 
21250
- state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
21251
- state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
21547
+ if ( extensions.has( 'OES_texture_float_linear' ) === true ) {
21548
+
21549
+ state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
21550
+ state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
21551
+
21552
+ } else {
21553
+
21554
+ state.rectAreaLTC1 = UniformsLib.LTC_HALF_1;
21555
+ state.rectAreaLTC2 = UniformsLib.LTC_HALF_2;
21556
+
21557
+ }
21252
21558
 
21253
21559
  } else {
21254
21560
 
@@ -21885,6 +22191,7 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) {
21885
22191
 
21886
22192
  cachedMaterial = result.clone();
21887
22193
  materialsForVariant[ keyB ] = cachedMaterial;
22194
+ material.addEventListener( 'dispose', onMaterialDispose );
21888
22195
 
21889
22196
  }
21890
22197
 
@@ -21961,8 +22268,12 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) {
21961
22268
 
21962
22269
  const depthMaterial = getDepthMaterial( object, groupMaterial, light, type );
21963
22270
 
22271
+ object.onBeforeShadow( _renderer, object, camera, shadowCamera, geometry, depthMaterial, group );
22272
+
21964
22273
  _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
21965
22274
 
22275
+ object.onAfterShadow( _renderer, object, camera, shadowCamera, geometry, depthMaterial, group );
22276
+
21966
22277
  }
21967
22278
 
21968
22279
  }
@@ -21971,8 +22282,12 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) {
21971
22282
 
21972
22283
  const depthMaterial = getDepthMaterial( object, material, light, type );
21973
22284
 
22285
+ object.onBeforeShadow( _renderer, object, camera, shadowCamera, geometry, depthMaterial, null );
22286
+
21974
22287
  _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );
21975
22288
 
22289
+ object.onAfterShadow( _renderer, object, camera, shadowCamera, geometry, depthMaterial, null );
22290
+
21976
22291
  }
21977
22292
 
21978
22293
  }
@@ -21989,6 +22304,32 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) {
21989
22304
 
21990
22305
  }
21991
22306
 
22307
+ function onMaterialDispose( event ) {
22308
+
22309
+ const material = event.target;
22310
+
22311
+ material.removeEventListener( 'dispose', onMaterialDispose );
22312
+
22313
+ // make sure to remove the unique distance/depth materials used for shadow map rendering
22314
+
22315
+ for ( const id in _materialCache ) {
22316
+
22317
+ const cache = _materialCache[ id ];
22318
+
22319
+ const uuid = event.target.uuid;
22320
+
22321
+ if ( uuid in cache ) {
22322
+
22323
+ const shadowMaterial = cache[ uuid ];
22324
+ shadowMaterial.dispose();
22325
+ delete cache[ uuid ];
22326
+
22327
+ }
22328
+
22329
+ }
22330
+
22331
+ }
22332
+
21992
22333
  }
21993
22334
 
21994
22335
  function WebGLState( gl, extensions, capabilities ) {
@@ -23317,10 +23658,6 @@ function WebGLState( gl, extensions, capabilities ) {
23317
23658
  function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {
23318
23659
 
23319
23660
  const isWebGL2 = capabilities.isWebGL2;
23320
- const maxTextures = capabilities.maxTextures;
23321
- const maxCubemapSize = capabilities.maxCubemapSize;
23322
- const maxTextureSize = capabilities.maxTextureSize;
23323
- const maxSamples = capabilities.maxSamples;
23324
23661
  const multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null;
23325
23662
  const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent );
23326
23663
 
@@ -23739,9 +24076,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
23739
24076
 
23740
24077
  const textureUnit = textureUnits;
23741
24078
 
23742
- if ( textureUnit >= maxTextures ) {
24079
+ if ( textureUnit >= capabilities.maxTextures ) {
23743
24080
 
23744
- console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures );
24081
+ console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
23745
24082
 
23746
24083
  }
23747
24084
 
@@ -23881,6 +24218,14 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
23881
24218
 
23882
24219
  function setTextureParameters( textureType, texture, supportsMips ) {
23883
24220
 
24221
+ if ( texture.type === FloatType && extensions.has( 'OES_texture_float_linear' ) === false &&
24222
+ ( texture.magFilter === LinearFilter || texture.magFilter === LinearMipmapNearestFilter || texture.magFilter === NearestMipmapLinearFilter || texture.magFilter === LinearMipmapLinearFilter ||
24223
+ texture.minFilter === LinearFilter || texture.minFilter === LinearMipmapNearestFilter || texture.minFilter === NearestMipmapLinearFilter || texture.minFilter === LinearMipmapLinearFilter ) ) {
24224
+
24225
+ console.warn( 'THREE.WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device.' );
24226
+
24227
+ }
24228
+
23884
24229
  if ( supportsMips ) {
23885
24230
 
23886
24231
  _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[ texture.wrapS ] );
@@ -24058,7 +24403,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24058
24403
  _gl.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );
24059
24404
 
24060
24405
  const needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo$1( texture.image ) === false;
24061
- let image = resizeImage( texture.image, needsPowerOfTwo, false, maxTextureSize );
24406
+ let image = resizeImage( texture.image, needsPowerOfTwo, false, capabilities.maxTextureSize );
24062
24407
  image = verifyColorSpace( texture, image );
24063
24408
 
24064
24409
  const supportsMips = isPowerOfTwo$1( image ) || isWebGL2,
@@ -24072,8 +24417,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24072
24417
  let mipmap;
24073
24418
  const mipmaps = texture.mipmaps;
24074
24419
 
24075
- const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true );
24420
+ const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true && glInternalFormat !== RGB_ETC1_Format );
24076
24421
  const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true );
24422
+ const dataReady = source.dataReady;
24077
24423
  const levels = getMipLevels( texture, image, supportsMips );
24078
24424
 
24079
24425
  if ( texture.isDepthTexture ) {
@@ -24186,7 +24532,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24186
24532
 
24187
24533
  if ( useTexStorage ) {
24188
24534
 
24189
- state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );
24535
+ if ( dataReady ) {
24536
+
24537
+ state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );
24538
+
24539
+ }
24190
24540
 
24191
24541
  } else {
24192
24542
 
@@ -24208,7 +24558,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24208
24558
 
24209
24559
  }
24210
24560
 
24211
- state.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data );
24561
+ if ( dataReady ) {
24562
+
24563
+ state.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data );
24564
+
24565
+ }
24212
24566
 
24213
24567
  } else {
24214
24568
 
@@ -24238,7 +24592,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24238
24592
 
24239
24593
  if ( useTexStorage ) {
24240
24594
 
24241
- state.compressedTexSubImage3D( _gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data, 0, 0 );
24595
+ if ( dataReady ) {
24596
+
24597
+ state.compressedTexSubImage3D( _gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data, 0, 0 );
24598
+
24599
+ }
24242
24600
 
24243
24601
  } else {
24244
24602
 
@@ -24256,7 +24614,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24256
24614
 
24257
24615
  if ( useTexStorage ) {
24258
24616
 
24259
- state.texSubImage3D( _gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data );
24617
+ if ( dataReady ) {
24618
+
24619
+ state.texSubImage3D( _gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data );
24620
+
24621
+ }
24260
24622
 
24261
24623
  } else {
24262
24624
 
@@ -24286,7 +24648,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24286
24648
 
24287
24649
  if ( useTexStorage ) {
24288
24650
 
24289
- state.compressedTexSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data );
24651
+ if ( dataReady ) {
24652
+
24653
+ state.compressedTexSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data );
24654
+
24655
+ }
24290
24656
 
24291
24657
  } else {
24292
24658
 
@@ -24304,7 +24670,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24304
24670
 
24305
24671
  if ( useTexStorage ) {
24306
24672
 
24307
- state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );
24673
+ if ( dataReady ) {
24674
+
24675
+ state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );
24676
+
24677
+ }
24308
24678
 
24309
24679
  } else {
24310
24680
 
@@ -24328,7 +24698,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24328
24698
 
24329
24699
  }
24330
24700
 
24331
- state.texSubImage3D( _gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
24701
+ if ( dataReady ) {
24702
+
24703
+ state.texSubImage3D( _gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
24704
+
24705
+ }
24332
24706
 
24333
24707
  } else {
24334
24708
 
@@ -24346,7 +24720,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24346
24720
 
24347
24721
  }
24348
24722
 
24349
- state.texSubImage3D( _gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
24723
+ if ( dataReady ) {
24724
+
24725
+ state.texSubImage3D( _gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
24726
+
24727
+ }
24350
24728
 
24351
24729
  } else {
24352
24730
 
@@ -24401,7 +24779,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24401
24779
 
24402
24780
  if ( useTexStorage ) {
24403
24781
 
24404
- state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap );
24782
+ if ( dataReady ) {
24783
+
24784
+ state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap );
24785
+
24786
+ }
24405
24787
 
24406
24788
  } else {
24407
24789
 
@@ -24423,7 +24805,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24423
24805
 
24424
24806
  }
24425
24807
 
24426
- state.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image );
24808
+ if ( dataReady ) {
24809
+
24810
+ state.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image );
24811
+
24812
+ }
24427
24813
 
24428
24814
  } else {
24429
24815
 
@@ -24484,7 +24870,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24484
24870
 
24485
24871
  if ( ! isCompressed && ! isDataTexture ) {
24486
24872
 
24487
- cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, maxCubemapSize );
24873
+ cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, capabilities.maxCubemapSize );
24488
24874
 
24489
24875
  } else {
24490
24876
 
@@ -24504,6 +24890,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24504
24890
 
24505
24891
  const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true );
24506
24892
  const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true );
24893
+ const dataReady = source.dataReady;
24507
24894
  let levels = getMipLevels( texture, image, supportsMips );
24508
24895
 
24509
24896
  setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, supportsMips );
@@ -24532,7 +24919,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24532
24919
 
24533
24920
  if ( useTexStorage ) {
24534
24921
 
24535
- state.compressedTexSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data );
24922
+ if ( dataReady ) {
24923
+
24924
+ state.compressedTexSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data );
24925
+
24926
+ }
24536
24927
 
24537
24928
  } else {
24538
24929
 
@@ -24550,7 +24941,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24550
24941
 
24551
24942
  if ( useTexStorage ) {
24552
24943
 
24553
- state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );
24944
+ if ( dataReady ) {
24945
+
24946
+ state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );
24947
+
24948
+ }
24554
24949
 
24555
24950
  } else {
24556
24951
 
@@ -24586,7 +24981,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24586
24981
 
24587
24982
  if ( useTexStorage ) {
24588
24983
 
24589
- state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[ i ].width, cubeImage[ i ].height, glFormat, glType, cubeImage[ i ].data );
24984
+ if ( dataReady ) {
24985
+
24986
+ state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[ i ].width, cubeImage[ i ].height, glFormat, glType, cubeImage[ i ].data );
24987
+
24988
+ }
24590
24989
 
24591
24990
  } else {
24592
24991
 
@@ -24601,7 +25000,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24601
25000
 
24602
25001
  if ( useTexStorage ) {
24603
25002
 
24604
- state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data );
25003
+ if ( dataReady ) {
25004
+
25005
+ state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data );
25006
+
25007
+ }
24605
25008
 
24606
25009
  } else {
24607
25010
 
@@ -24615,7 +25018,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24615
25018
 
24616
25019
  if ( useTexStorage ) {
24617
25020
 
24618
- state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[ i ] );
25021
+ if ( dataReady ) {
25022
+
25023
+ state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[ i ] );
25024
+
25025
+ }
24619
25026
 
24620
25027
  } else {
24621
25028
 
@@ -24629,7 +25036,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24629
25036
 
24630
25037
  if ( useTexStorage ) {
24631
25038
 
24632
- state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[ i ] );
25039
+ if ( dataReady ) {
25040
+
25041
+ state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[ i ] );
25042
+
25043
+ }
24633
25044
 
24634
25045
  } else {
24635
25046
 
@@ -25315,7 +25726,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25315
25726
 
25316
25727
  function getRenderTargetSamples( renderTarget ) {
25317
25728
 
25318
- return Math.min( maxSamples, renderTarget.samples );
25729
+ return Math.min( capabilities.maxSamples, renderTarget.samples );
25319
25730
 
25320
25731
  }
25321
25732
 
@@ -26064,55 +26475,100 @@ class WebXRController {
26064
26475
 
26065
26476
  }
26066
26477
 
26067
- class DepthTexture extends Texture {
26478
+ const _occlusion_vertex = `
26479
+ void main() {
26068
26480
 
26069
- constructor( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {
26481
+ gl_Position = vec4( position, 1.0 );
26070
26482
 
26071
- format = format !== undefined ? format : DepthFormat;
26483
+ }`;
26072
26484
 
26073
- if ( format !== DepthFormat && format !== DepthStencilFormat ) {
26485
+ const _occlusion_fragment = `
26486
+ uniform sampler2DArray depthColor;
26487
+ uniform float depthWidth;
26488
+ uniform float depthHeight;
26074
26489
 
26075
- throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );
26490
+ void main() {
26076
26491
 
26077
- }
26492
+ vec2 coord = vec2( gl_FragCoord.x / depthWidth, gl_FragCoord.y / depthHeight );
26078
26493
 
26079
- if ( type === undefined && format === DepthFormat ) type = UnsignedIntType;
26080
- if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;
26494
+ if ( coord.x >= 1.0 ) {
26081
26495
 
26082
- super( null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
26496
+ gl_FragDepthEXT = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r;
26083
26497
 
26084
- this.isDepthTexture = true;
26498
+ } else {
26085
26499
 
26086
- this.image = { width: width, height: height };
26500
+ gl_FragDepthEXT = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r;
26087
26501
 
26088
- this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
26089
- this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
26502
+ }
26090
26503
 
26091
- this.flipY = false;
26092
- this.generateMipmaps = false;
26504
+ }`;
26093
26505
 
26094
- this.compareFunction = null;
26506
+ class WebXRDepthSensing {
26507
+
26508
+ constructor() {
26509
+
26510
+ this.texture = null;
26511
+ this.mesh = null;
26512
+
26513
+ this.depthNear = 0;
26514
+ this.depthFar = 0;
26095
26515
 
26096
26516
  }
26097
26517
 
26518
+ init( renderer, depthData, renderState ) {
26098
26519
 
26099
- copy( source ) {
26520
+ if ( this.texture === null ) {
26100
26521
 
26101
- super.copy( source );
26522
+ const texture = new Texture();
26102
26523
 
26103
- this.compareFunction = source.compareFunction;
26524
+ const texProps = renderer.properties.get( texture );
26525
+ texProps.__webglTexture = depthData.texture;
26104
26526
 
26105
- return this;
26527
+ if ( ( depthData.depthNear != renderState.depthNear ) || ( depthData.depthFar != renderState.depthFar ) ) {
26528
+
26529
+ this.depthNear = depthData.depthNear;
26530
+ this.depthFar = depthData.depthFar;
26531
+
26532
+ }
26533
+
26534
+ this.texture = texture;
26535
+
26536
+ }
26106
26537
 
26107
26538
  }
26108
26539
 
26109
- toJSON( meta ) {
26540
+ render( renderer, cameraXR ) {
26110
26541
 
26111
- const data = super.toJSON( meta );
26542
+ if ( this.texture !== null ) {
26112
26543
 
26113
- if ( this.compareFunction !== null ) data.compareFunction = this.compareFunction;
26544
+ if ( this.mesh === null ) {
26114
26545
 
26115
- return data;
26546
+ const viewport = cameraXR.cameras[ 0 ].viewport;
26547
+ const material = new ShaderMaterial( {
26548
+ extensions: { fragDepth: true },
26549
+ vertexShader: _occlusion_vertex,
26550
+ fragmentShader: _occlusion_fragment,
26551
+ uniforms: {
26552
+ depthColor: { value: this.texture },
26553
+ depthWidth: { value: viewport.z },
26554
+ depthHeight: { value: viewport.w }
26555
+ }
26556
+ } );
26557
+
26558
+ this.mesh = new Mesh( new PlaneGeometry( 20, 20 ), material );
26559
+
26560
+ }
26561
+
26562
+ renderer.render( this.mesh, cameraXR );
26563
+
26564
+ }
26565
+
26566
+ }
26567
+
26568
+ reset() {
26569
+
26570
+ this.texture = null;
26571
+ this.mesh = null;
26116
26572
 
26117
26573
  }
26118
26574
 
@@ -26141,13 +26597,19 @@ class WebXRManager extends EventDispatcher {
26141
26597
  let glProjLayer = null;
26142
26598
  let glBaseLayer = null;
26143
26599
  let xrFrame = null;
26600
+
26601
+ const depthSensing = new WebXRDepthSensing();
26144
26602
  const attributes = gl.getContextAttributes();
26603
+
26145
26604
  let initialRenderTarget = null;
26146
26605
  let newRenderTarget = null;
26147
26606
 
26148
26607
  const controllers = [];
26149
26608
  const controllerInputSources = [];
26150
26609
 
26610
+ const currentSize = new Vector2();
26611
+ let currentPixelRatio = null;
26612
+
26151
26613
  //
26152
26614
 
26153
26615
  const cameraL = new PerspectiveCamera();
@@ -26268,6 +26730,8 @@ class WebXRManager extends EventDispatcher {
26268
26730
  _currentDepthNear = null;
26269
26731
  _currentDepthFar = null;
26270
26732
 
26733
+ depthSensing.reset();
26734
+
26271
26735
  // restore framebuffer/rendering state
26272
26736
 
26273
26737
  renderer.setRenderTarget( initialRenderTarget );
@@ -26284,6 +26748,9 @@ class WebXRManager extends EventDispatcher {
26284
26748
 
26285
26749
  scope.isPresenting = false;
26286
26750
 
26751
+ renderer.setPixelRatio( currentPixelRatio );
26752
+ renderer.setSize( currentSize.width, currentSize.height, false );
26753
+
26287
26754
  scope.dispatchEvent( { type: 'sessionend' } );
26288
26755
 
26289
26756
  }
@@ -26371,6 +26838,9 @@ class WebXRManager extends EventDispatcher {
26371
26838
 
26372
26839
  }
26373
26840
 
26841
+ currentPixelRatio = renderer.getPixelRatio();
26842
+ renderer.getSize( currentSize );
26843
+
26374
26844
  if ( ( session.renderState.layers === undefined ) || ( renderer.capabilities.isWebGL2 === false ) ) {
26375
26845
 
26376
26846
  const layerInit = {
@@ -26385,6 +26855,9 @@ class WebXRManager extends EventDispatcher {
26385
26855
 
26386
26856
  session.updateRenderState( { baseLayer: glBaseLayer } );
26387
26857
 
26858
+ renderer.setPixelRatio( 1 );
26859
+ renderer.setSize( glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, false );
26860
+
26388
26861
  newRenderTarget = new WebGLRenderTarget(
26389
26862
  glBaseLayer.framebufferWidth,
26390
26863
  glBaseLayer.framebufferHeight,
@@ -26422,6 +26895,9 @@ class WebXRManager extends EventDispatcher {
26422
26895
 
26423
26896
  session.updateRenderState( { layers: [ glProjLayer ] } );
26424
26897
 
26898
+ renderer.setPixelRatio( 1 );
26899
+ renderer.setSize( glProjLayer.textureWidth, glProjLayer.textureHeight, false );
26900
+
26425
26901
  newRenderTarget = new WebGLRenderTarget(
26426
26902
  glProjLayer.textureWidth,
26427
26903
  glProjLayer.textureHeight,
@@ -26614,6 +27090,13 @@ class WebXRManager extends EventDispatcher {
26614
27090
 
26615
27091
  if ( session === null ) return;
26616
27092
 
27093
+ if ( depthSensing.texture !== null ) {
27094
+
27095
+ camera.near = depthSensing.depthNear;
27096
+ camera.far = depthSensing.depthFar;
27097
+
27098
+ }
27099
+
26617
27100
  cameraXR.near = cameraR.near = cameraL.near = camera.near;
26618
27101
  cameraXR.far = cameraR.far = cameraL.far = camera.far;
26619
27102
 
@@ -26629,6 +27112,15 @@ class WebXRManager extends EventDispatcher {
26629
27112
  _currentDepthNear = cameraXR.near;
26630
27113
  _currentDepthFar = cameraXR.far;
26631
27114
 
27115
+ cameraL.near = _currentDepthNear;
27116
+ cameraL.far = _currentDepthFar;
27117
+ cameraR.near = _currentDepthNear;
27118
+ cameraR.far = _currentDepthFar;
27119
+
27120
+ cameraL.updateProjectionMatrix();
27121
+ cameraR.updateProjectionMatrix();
27122
+ camera.updateProjectionMatrix();
27123
+
26632
27124
  }
26633
27125
 
26634
27126
  const parent = camera.parent;
@@ -26730,6 +27222,12 @@ class WebXRManager extends EventDispatcher {
26730
27222
 
26731
27223
  };
26732
27224
 
27225
+ this.hasDepthSensing = function () {
27226
+
27227
+ return depthSensing.texture !== null;
27228
+
27229
+ };
27230
+
26733
27231
  // Animation Loop
26734
27232
 
26735
27233
  let onAnimationFrameCallback = null;
@@ -26822,6 +27320,22 @@ class WebXRManager extends EventDispatcher {
26822
27320
 
26823
27321
  }
26824
27322
 
27323
+ //
27324
+
27325
+ const enabledFeatures = session.enabledFeatures;
27326
+
27327
+ if ( enabledFeatures && enabledFeatures.includes( 'depth-sensing' ) ) {
27328
+
27329
+ const depthData = glBinding.getDepthInformation( views[ 0 ] );
27330
+
27331
+ if ( depthData && depthData.isValid && depthData.texture ) {
27332
+
27333
+ depthSensing.init( renderer, depthData, session.renderState );
27334
+
27335
+ }
27336
+
27337
+ }
27338
+
26825
27339
  }
26826
27340
 
26827
27341
  //
@@ -26839,6 +27353,8 @@ class WebXRManager extends EventDispatcher {
26839
27353
 
26840
27354
  }
26841
27355
 
27356
+ depthSensing.render( renderer, cameraXR );
27357
+
26842
27358
  if ( onAnimationFrameCallback ) onAnimationFrameCallback( time, frame );
26843
27359
 
26844
27360
  if ( frame.detectedPlanes ) {
@@ -27528,57 +28044,62 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
27528
28044
 
27529
28045
  for ( let i = 0, il = uniforms.length; i < il; i ++ ) {
27530
28046
 
27531
- const uniform = uniforms[ i ];
28047
+ const uniformArray = Array.isArray( uniforms[ i ] ) ? uniforms[ i ] : [ uniforms[ i ] ];
27532
28048
 
27533
- // partly update the buffer if necessary
28049
+ for ( let j = 0, jl = uniformArray.length; j < jl; j ++ ) {
27534
28050
 
27535
- if ( hasUniformChanged( uniform, i, cache ) === true ) {
28051
+ const uniform = uniformArray[ j ];
27536
28052
 
27537
- const offset = uniform.__offset;
28053
+ if ( hasUniformChanged( uniform, i, j, cache ) === true ) {
27538
28054
 
27539
- const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
28055
+ const offset = uniform.__offset;
27540
28056
 
27541
- let arrayOffset = 0;
28057
+ const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
27542
28058
 
27543
- for ( let i = 0; i < values.length; i ++ ) {
28059
+ let arrayOffset = 0;
27544
28060
 
27545
- const value = values[ i ];
28061
+ for ( let k = 0; k < values.length; k ++ ) {
27546
28062
 
27547
- const info = getUniformSize( value );
28063
+ const value = values[ k ];
27548
28064
 
27549
- if ( typeof value === 'number' ) {
28065
+ const info = getUniformSize( value );
27550
28066
 
27551
- uniform.__data[ 0 ] = value;
27552
- gl.bufferSubData( gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data );
28067
+ // TODO add integer and struct support
28068
+ if ( typeof value === 'number' || typeof value === 'boolean' ) {
27553
28069
 
27554
- } else if ( value.isMatrix3 ) {
28070
+ uniform.__data[ 0 ] = value;
28071
+ gl.bufferSubData( gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data );
27555
28072
 
27556
- // manually converting 3x3 to 3x4
28073
+ } else if ( value.isMatrix3 ) {
27557
28074
 
27558
- uniform.__data[ 0 ] = value.elements[ 0 ];
27559
- uniform.__data[ 1 ] = value.elements[ 1 ];
27560
- uniform.__data[ 2 ] = value.elements[ 2 ];
27561
- uniform.__data[ 3 ] = value.elements[ 0 ];
27562
- uniform.__data[ 4 ] = value.elements[ 3 ];
27563
- uniform.__data[ 5 ] = value.elements[ 4 ];
27564
- uniform.__data[ 6 ] = value.elements[ 5 ];
27565
- uniform.__data[ 7 ] = value.elements[ 0 ];
27566
- uniform.__data[ 8 ] = value.elements[ 6 ];
27567
- uniform.__data[ 9 ] = value.elements[ 7 ];
27568
- uniform.__data[ 10 ] = value.elements[ 8 ];
27569
- uniform.__data[ 11 ] = value.elements[ 0 ];
28075
+ // manually converting 3x3 to 3x4
27570
28076
 
27571
- } else {
28077
+ uniform.__data[ 0 ] = value.elements[ 0 ];
28078
+ uniform.__data[ 1 ] = value.elements[ 1 ];
28079
+ uniform.__data[ 2 ] = value.elements[ 2 ];
28080
+ uniform.__data[ 3 ] = 0;
28081
+ uniform.__data[ 4 ] = value.elements[ 3 ];
28082
+ uniform.__data[ 5 ] = value.elements[ 4 ];
28083
+ uniform.__data[ 6 ] = value.elements[ 5 ];
28084
+ uniform.__data[ 7 ] = 0;
28085
+ uniform.__data[ 8 ] = value.elements[ 6 ];
28086
+ uniform.__data[ 9 ] = value.elements[ 7 ];
28087
+ uniform.__data[ 10 ] = value.elements[ 8 ];
28088
+ uniform.__data[ 11 ] = 0;
28089
+
28090
+ } else {
28091
+
28092
+ value.toArray( uniform.__data, arrayOffset );
27572
28093
 
27573
- value.toArray( uniform.__data, arrayOffset );
28094
+ arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT;
27574
28095
 
27575
- arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT;
28096
+ }
27576
28097
 
27577
28098
  }
27578
28099
 
27579
- }
28100
+ gl.bufferSubData( gl.UNIFORM_BUFFER, offset, uniform.__data );
27580
28101
 
27581
- gl.bufferSubData( gl.UNIFORM_BUFFER, offset, uniform.__data );
28102
+ }
27582
28103
 
27583
28104
  }
27584
28105
 
@@ -27588,31 +28109,22 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
27588
28109
 
27589
28110
  }
27590
28111
 
27591
- function hasUniformChanged( uniform, index, cache ) {
28112
+ function hasUniformChanged( uniform, index, indexArray, cache ) {
27592
28113
 
27593
28114
  const value = uniform.value;
28115
+ const indexString = index + '_' + indexArray;
27594
28116
 
27595
- if ( cache[ index ] === undefined ) {
28117
+ if ( cache[ indexString ] === undefined ) {
27596
28118
 
27597
28119
  // cache entry does not exist so far
27598
28120
 
27599
- if ( typeof value === 'number' ) {
28121
+ if ( typeof value === 'number' || typeof value === 'boolean' ) {
27600
28122
 
27601
- cache[ index ] = value;
28123
+ cache[ indexString ] = value;
27602
28124
 
27603
28125
  } else {
27604
28126
 
27605
- const values = Array.isArray( value ) ? value : [ value ];
27606
-
27607
- const tempValues = [];
27608
-
27609
- for ( let i = 0; i < values.length; i ++ ) {
27610
-
27611
- tempValues.push( values[ i ].clone() );
27612
-
27613
- }
27614
-
27615
- cache[ index ] = tempValues;
28127
+ cache[ indexString ] = value.clone();
27616
28128
 
27617
28129
  }
27618
28130
 
@@ -27620,32 +28132,25 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
27620
28132
 
27621
28133
  } else {
27622
28134
 
28135
+ const cachedObject = cache[ indexString ];
28136
+
27623
28137
  // compare current value with cached entry
27624
28138
 
27625
- if ( typeof value === 'number' ) {
28139
+ if ( typeof value === 'number' || typeof value === 'boolean' ) {
27626
28140
 
27627
- if ( cache[ index ] !== value ) {
28141
+ if ( cachedObject !== value ) {
27628
28142
 
27629
- cache[ index ] = value;
28143
+ cache[ indexString ] = value;
27630
28144
  return true;
27631
28145
 
27632
28146
  }
27633
28147
 
27634
28148
  } else {
27635
28149
 
27636
- const cachedObjects = Array.isArray( cache[ index ] ) ? cache[ index ] : [ cache[ index ] ];
27637
- const values = Array.isArray( value ) ? value : [ value ];
27638
-
27639
- for ( let i = 0; i < cachedObjects.length; i ++ ) {
28150
+ if ( cachedObject.equals( value ) === false ) {
27640
28151
 
27641
- const cachedObject = cachedObjects[ i ];
27642
-
27643
- if ( cachedObject.equals( values[ i ] ) === false ) {
27644
-
27645
- cachedObject.copy( values[ i ] );
27646
- return true;
27647
-
27648
- }
28152
+ cachedObject.copy( value );
28153
+ return true;
27649
28154
 
27650
28155
  }
27651
28156
 
@@ -27666,63 +28171,53 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
27666
28171
 
27667
28172
  let offset = 0; // global buffer offset in bytes
27668
28173
  const chunkSize = 16; // size of a chunk in bytes
27669
- let chunkOffset = 0; // offset within a single chunk in bytes
27670
28174
 
27671
28175
  for ( let i = 0, l = uniforms.length; i < l; i ++ ) {
27672
28176
 
27673
- const uniform = uniforms[ i ];
27674
-
27675
- const infos = {
27676
- boundary: 0, // bytes
27677
- storage: 0 // bytes
27678
- };
27679
-
27680
- const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
28177
+ const uniformArray = Array.isArray( uniforms[ i ] ) ? uniforms[ i ] : [ uniforms[ i ] ];
27681
28178
 
27682
- for ( let j = 0, jl = values.length; j < jl; j ++ ) {
28179
+ for ( let j = 0, jl = uniformArray.length; j < jl; j ++ ) {
27683
28180
 
27684
- const value = values[ j ];
28181
+ const uniform = uniformArray[ j ];
27685
28182
 
27686
- const info = getUniformSize( value );
28183
+ const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
27687
28184
 
27688
- infos.boundary += info.boundary;
27689
- infos.storage += info.storage;
28185
+ for ( let k = 0, kl = values.length; k < kl; k ++ ) {
27690
28186
 
27691
- }
28187
+ const value = values[ k ];
27692
28188
 
27693
- // the following two properties will be used for partial buffer updates
28189
+ const info = getUniformSize( value );
27694
28190
 
27695
- uniform.__data = new Float32Array( infos.storage / Float32Array.BYTES_PER_ELEMENT );
27696
- uniform.__offset = offset;
28191
+ // Calculate the chunk offset
28192
+ const chunkOffsetUniform = offset % chunkSize;
27697
28193
 
27698
- //
28194
+ // Check for chunk overflow
28195
+ if ( chunkOffsetUniform !== 0 && ( chunkSize - chunkOffsetUniform ) < info.boundary ) {
27699
28196
 
27700
- if ( i > 0 ) {
28197
+ // Add padding and adjust offset
28198
+ offset += ( chunkSize - chunkOffsetUniform );
27701
28199
 
27702
- chunkOffset = offset % chunkSize;
28200
+ }
27703
28201
 
27704
- const remainingSizeInChunk = chunkSize - chunkOffset;
28202
+ // the following two properties will be used for partial buffer updates
27705
28203
 
27706
- // check for chunk overflow
28204
+ uniform.__data = new Float32Array( info.storage / Float32Array.BYTES_PER_ELEMENT );
28205
+ uniform.__offset = offset;
27707
28206
 
27708
- if ( chunkOffset !== 0 && ( remainingSizeInChunk - infos.boundary ) < 0 ) {
27709
28207
 
27710
- // add padding and adjust offset
28208
+ // Update the global offset
28209
+ offset += info.storage;
27711
28210
 
27712
- offset += ( chunkSize - chunkOffset );
27713
- uniform.__offset = offset;
27714
28211
 
27715
28212
  }
27716
28213
 
27717
28214
  }
27718
28215
 
27719
- offset += infos.storage;
27720
-
27721
28216
  }
27722
28217
 
27723
28218
  // ensure correct final padding
27724
28219
 
27725
- chunkOffset = offset % chunkSize;
28220
+ const chunkOffset = offset % chunkSize;
27726
28221
 
27727
28222
  if ( chunkOffset > 0 ) offset += ( chunkSize - chunkOffset );
27728
28223
 
@@ -27744,9 +28239,9 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
27744
28239
 
27745
28240
  // determine sizes according to STD140
27746
28241
 
27747
- if ( typeof value === 'number' ) {
28242
+ if ( typeof value === 'number' || typeof value === 'boolean' ) {
27748
28243
 
27749
- // float/int
28244
+ // float/int/bool
27750
28245
 
27751
28246
  info.boundary = 4;
27752
28247
  info.storage = 4;
@@ -28674,7 +29169,11 @@ class WebGLRenderer {
28674
29169
 
28675
29170
  }
28676
29171
 
28677
- if ( object.isInstancedMesh ) {
29172
+ if ( object.isBatchedMesh ) {
29173
+
29174
+ renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );
29175
+
29176
+ } else if ( object.isInstancedMesh ) {
28678
29177
 
28679
29178
  renderer.renderInstances( drawStart, drawCount, object.count );
28680
29179
 
@@ -28983,7 +29482,11 @@ class WebGLRenderer {
28983
29482
 
28984
29483
  //
28985
29484
 
28986
- background.render( currentRenderList, scene );
29485
+ if ( xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false ) {
29486
+
29487
+ background.render( currentRenderList, scene );
29488
+
29489
+ }
28987
29490
 
28988
29491
  // render scene
28989
29492
 
@@ -29493,6 +29996,7 @@ class WebGLRenderer {
29493
29996
  const materialProperties = properties.get( material );
29494
29997
 
29495
29998
  materialProperties.outputColorSpace = parameters.outputColorSpace;
29999
+ materialProperties.batching = parameters.batching;
29496
30000
  materialProperties.instancing = parameters.instancing;
29497
30001
  materialProperties.instancingColor = parameters.instancingColor;
29498
30002
  materialProperties.skinning = parameters.skinning;
@@ -29573,6 +30077,14 @@ class WebGLRenderer {
29573
30077
 
29574
30078
  needsProgramChange = true;
29575
30079
 
30080
+ } else if ( object.isBatchedMesh && materialProperties.batching === false ) {
30081
+
30082
+ needsProgramChange = true;
30083
+
30084
+ } else if ( ! object.isBatchedMesh && materialProperties.batching === true ) {
30085
+
30086
+ needsProgramChange = true;
30087
+
29576
30088
  } else if ( object.isInstancedMesh && materialProperties.instancing === false ) {
29577
30089
 
29578
30090
  needsProgramChange = true;
@@ -29749,7 +30261,6 @@ class WebGLRenderer {
29749
30261
  if ( skeleton.boneTexture === null ) skeleton.computeBoneTexture();
29750
30262
 
29751
30263
  p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures );
29752
- p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
29753
30264
 
29754
30265
  } else {
29755
30266
 
@@ -29761,6 +30272,13 @@ class WebGLRenderer {
29761
30272
 
29762
30273
  }
29763
30274
 
30275
+ if ( object.isBatchedMesh ) {
30276
+
30277
+ p_uniforms.setOptional( _gl, object, 'batchingTexture' );
30278
+ p_uniforms.setValue( _gl, 'batchingTexture', object._matricesTexture, textures );
30279
+
30280
+ }
30281
+
29764
30282
  const morphAttributes = geometry.morphAttributes;
29765
30283
 
29766
30284
  if ( morphAttributes.position !== undefined || morphAttributes.normal !== undefined || ( morphAttributes.color !== undefined && capabilities.isWebGL2 === true ) ) {
@@ -30204,7 +30722,7 @@ class WebGLRenderer {
30204
30722
  textures.setTexture3D( dstTexture, 0 );
30205
30723
  glTarget = _gl.TEXTURE_3D;
30206
30724
 
30207
- } else if ( dstTexture.isDataArrayTexture ) {
30725
+ } else if ( dstTexture.isDataArrayTexture || dstTexture.isCompressedArrayTexture ) {
30208
30726
 
30209
30727
  textures.setTexture2DArray( dstTexture, 0 );
30210
30728
  glTarget = _gl.TEXTURE_2D_ARRAY;
@@ -30226,7 +30744,7 @@ class WebGLRenderer {
30226
30744
  const unpackSkipRows = _gl.getParameter( _gl.UNPACK_SKIP_ROWS );
30227
30745
  const unpackSkipImages = _gl.getParameter( _gl.UNPACK_SKIP_IMAGES );
30228
30746
 
30229
- const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ 0 ] : srcTexture.image;
30747
+ const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ level ] : srcTexture.image;
30230
30748
 
30231
30749
  _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
30232
30750
  _gl.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, image.height );
@@ -30331,20 +30849,6 @@ class WebGLRenderer {
30331
30849
 
30332
30850
  }
30333
30851
 
30334
- get physicallyCorrectLights() { // @deprecated, r150
30335
-
30336
- console.warn( 'THREE.WebGLRenderer: The property .physicallyCorrectLights has been removed. Set renderer.useLegacyLights instead.' );
30337
- return ! this.useLegacyLights;
30338
-
30339
- }
30340
-
30341
- set physicallyCorrectLights( value ) { // @deprecated, r150
30342
-
30343
- console.warn( 'THREE.WebGLRenderer: The property .physicallyCorrectLights has been removed. Set renderer.useLegacyLights instead.' );
30344
- this.useLegacyLights = ! value;
30345
-
30346
- }
30347
-
30348
30852
  get outputEncoding() { // @deprecated, r152
30349
30853
 
30350
30854
  console.warn( 'THREE.WebGLRenderer: Property .outputEncoding has been removed. Use .outputColorSpace instead.' );
@@ -30450,7 +30954,8 @@ class InterleavedBuffer {
30450
30954
  this.count = array !== undefined ? array.length / stride : 0;
30451
30955
 
30452
30956
  this.usage = StaticDrawUsage;
30453
- this.updateRange = { offset: 0, count: - 1 };
30957
+ this._updateRange = { offset: 0, count: - 1 };
30958
+ this.updateRanges = [];
30454
30959
 
30455
30960
  this.version = 0;
30456
30961
 
@@ -30466,6 +30971,13 @@ class InterleavedBuffer {
30466
30971
 
30467
30972
  }
30468
30973
 
30974
+ get updateRange() {
30975
+
30976
+ warnOnce( 'THREE.InterleavedBuffer: updateRange() is deprecated and will be removed in r169. Use addUpdateRange() instead.' ); // @deprecated, r159
30977
+ return this._updateRange;
30978
+
30979
+ }
30980
+
30469
30981
  setUsage( value ) {
30470
30982
 
30471
30983
  this.usage = value;
@@ -30474,6 +30986,18 @@ class InterleavedBuffer {
30474
30986
 
30475
30987
  }
30476
30988
 
30989
+ addUpdateRange( start, count ) {
30990
+
30991
+ this.updateRanges.push( { start, count } );
30992
+
30993
+ }
30994
+
30995
+ clearUpdateRanges() {
30996
+
30997
+ this.updateRanges.length = 0;
30998
+
30999
+ }
31000
+
30477
31001
  copy( source ) {
30478
31002
 
30479
31003
  this.array = new source.array.constructor( source.array );
@@ -30580,7 +31104,7 @@ class InterleavedBuffer {
30580
31104
 
30581
31105
  }
30582
31106
 
30583
- const _vector$5 = /*@__PURE__*/ new Vector3();
31107
+ const _vector$6 = /*@__PURE__*/ new Vector3();
30584
31108
 
30585
31109
  class InterleavedBufferAttribute {
30586
31110
 
@@ -30620,11 +31144,11 @@ class InterleavedBufferAttribute {
30620
31144
 
30621
31145
  for ( let i = 0, l = this.data.count; i < l; i ++ ) {
30622
31146
 
30623
- _vector$5.fromBufferAttribute( this, i );
31147
+ _vector$6.fromBufferAttribute( this, i );
30624
31148
 
30625
- _vector$5.applyMatrix4( m );
31149
+ _vector$6.applyMatrix4( m );
30626
31150
 
30627
- this.setXYZ( i, _vector$5.x, _vector$5.y, _vector$5.z );
31151
+ this.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z );
30628
31152
 
30629
31153
  }
30630
31154
 
@@ -30636,11 +31160,11 @@ class InterleavedBufferAttribute {
30636
31160
 
30637
31161
  for ( let i = 0, l = this.count; i < l; i ++ ) {
30638
31162
 
30639
- _vector$5.fromBufferAttribute( this, i );
31163
+ _vector$6.fromBufferAttribute( this, i );
30640
31164
 
30641
- _vector$5.applyNormalMatrix( m );
31165
+ _vector$6.applyNormalMatrix( m );
30642
31166
 
30643
- this.setXYZ( i, _vector$5.x, _vector$5.y, _vector$5.z );
31167
+ this.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z );
30644
31168
 
30645
31169
  }
30646
31170
 
@@ -30652,11 +31176,11 @@ class InterleavedBufferAttribute {
30652
31176
 
30653
31177
  for ( let i = 0, l = this.count; i < l; i ++ ) {
30654
31178
 
30655
- _vector$5.fromBufferAttribute( this, i );
31179
+ _vector$6.fromBufferAttribute( this, i );
30656
31180
 
30657
- _vector$5.transformDirection( m );
31181
+ _vector$6.transformDirection( m );
30658
31182
 
30659
- this.setXYZ( i, _vector$5.x, _vector$5.y, _vector$5.z );
31183
+ this.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z );
30660
31184
 
30661
31185
  }
30662
31186
 
@@ -30664,6 +31188,26 @@ class InterleavedBufferAttribute {
30664
31188
 
30665
31189
  }
30666
31190
 
31191
+ getComponent( index, component ) {
31192
+
31193
+ let value = this.array[ index * this.data.stride + this.offset + component ];
31194
+
31195
+ if ( this.normalized ) value = denormalize( value, this.array );
31196
+
31197
+ return value;
31198
+
31199
+ }
31200
+
31201
+ setComponent( index, component, value ) {
31202
+
31203
+ if ( this.normalized ) value = normalize( value, this.array );
31204
+
31205
+ this.data.array[ index * this.data.stride + this.offset + component ] = value;
31206
+
31207
+ return this;
31208
+
31209
+ }
31210
+
30667
31211
  setX( index, x ) {
30668
31212
 
30669
31213
  if ( this.normalized ) x = normalize( x, this.array );
@@ -31134,7 +31678,7 @@ const _vector3 = /*@__PURE__*/ new Vector3();
31134
31678
  const _matrix4 = /*@__PURE__*/ new Matrix4();
31135
31679
  const _vertex = /*@__PURE__*/ new Vector3();
31136
31680
 
31137
- const _sphere$3 = /*@__PURE__*/ new Sphere();
31681
+ const _sphere$4 = /*@__PURE__*/ new Sphere();
31138
31682
  const _inverseMatrix$2 = /*@__PURE__*/ new Matrix4();
31139
31683
  const _ray$2 = /*@__PURE__*/ new Ray();
31140
31684
 
@@ -31231,10 +31775,10 @@ class SkinnedMesh extends Mesh {
31231
31775
 
31232
31776
  if ( this.boundingSphere === null ) this.computeBoundingSphere();
31233
31777
 
31234
- _sphere$3.copy( this.boundingSphere );
31235
- _sphere$3.applyMatrix4( matrixWorld );
31778
+ _sphere$4.copy( this.boundingSphere );
31779
+ _sphere$4.applyMatrix4( matrixWorld );
31236
31780
 
31237
- if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return;
31781
+ if ( raycaster.ray.intersectsSphere( _sphere$4 ) === false ) return;
31238
31782
 
31239
31783
  // convert ray to local space of skinned mesh
31240
31784
 
@@ -31370,14 +31914,6 @@ class SkinnedMesh extends Mesh {
31370
31914
 
31371
31915
  }
31372
31916
 
31373
- boneTransform( index, vector ) { // @deprecated, r151
31374
-
31375
- console.warn( 'THREE.SkinnedMesh: .boneTransform() was renamed to .applyBoneTransform() in r151.' );
31376
- return this.applyBoneTransform( index, vector );
31377
-
31378
- }
31379
-
31380
-
31381
31917
  }
31382
31918
 
31383
31919
  class Bone extends Object3D {
@@ -31426,7 +31962,6 @@ class Skeleton {
31426
31962
  this.boneMatrices = null;
31427
31963
 
31428
31964
  this.boneTexture = null;
31429
- this.boneTextureSize = 0;
31430
31965
 
31431
31966
  this.init();
31432
31967
 
@@ -31574,7 +32109,7 @@ class Skeleton {
31574
32109
  // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
31575
32110
 
31576
32111
  let size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix
31577
- size = ceilPowerOfTwo( size );
32112
+ size = Math.ceil( size / 4 ) * 4;
31578
32113
  size = Math.max( size, 4 );
31579
32114
 
31580
32115
  const boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
@@ -31585,7 +32120,6 @@ class Skeleton {
31585
32120
 
31586
32121
  this.boneMatrices = boneMatrices;
31587
32122
  this.boneTexture = boneTexture;
31588
- this.boneTextureSize = size;
31589
32123
 
31590
32124
  return this;
31591
32125
 
@@ -31724,8 +32258,8 @@ const _instanceIntersects = [];
31724
32258
 
31725
32259
  const _box3 = /*@__PURE__*/ new Box3();
31726
32260
  const _identity = /*@__PURE__*/ new Matrix4();
31727
- const _mesh = /*@__PURE__*/ new Mesh();
31728
- const _sphere$2 = /*@__PURE__*/ new Sphere();
32261
+ const _mesh$1 = /*@__PURE__*/ new Mesh();
32262
+ const _sphere$3 = /*@__PURE__*/ new Sphere();
31729
32263
 
31730
32264
  class InstancedMesh extends Mesh {
31731
32265
 
@@ -31805,9 +32339,9 @@ class InstancedMesh extends Mesh {
31805
32339
 
31806
32340
  this.getMatrixAt( i, _instanceLocalMatrix );
31807
32341
 
31808
- _sphere$2.copy( geometry.boundingSphere ).applyMatrix4( _instanceLocalMatrix );
32342
+ _sphere$3.copy( geometry.boundingSphere ).applyMatrix4( _instanceLocalMatrix );
31809
32343
 
31810
- this.boundingSphere.union( _sphere$2 );
32344
+ this.boundingSphere.union( _sphere$3 );
31811
32345
 
31812
32346
  }
31813
32347
 
@@ -31847,19 +32381,19 @@ class InstancedMesh extends Mesh {
31847
32381
  const matrixWorld = this.matrixWorld;
31848
32382
  const raycastTimes = this.count;
31849
32383
 
31850
- _mesh.geometry = this.geometry;
31851
- _mesh.material = this.material;
32384
+ _mesh$1.geometry = this.geometry;
32385
+ _mesh$1.material = this.material;
31852
32386
 
31853
- if ( _mesh.material === undefined ) return;
32387
+ if ( _mesh$1.material === undefined ) return;
31854
32388
 
31855
32389
  // test with bounding sphere first
31856
32390
 
31857
32391
  if ( this.boundingSphere === null ) this.computeBoundingSphere();
31858
32392
 
31859
- _sphere$2.copy( this.boundingSphere );
31860
- _sphere$2.applyMatrix4( matrixWorld );
32393
+ _sphere$3.copy( this.boundingSphere );
32394
+ _sphere$3.applyMatrix4( matrixWorld );
31861
32395
 
31862
- if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) return;
32396
+ if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return;
31863
32397
 
31864
32398
  // now test each instance
31865
32399
 
@@ -31873,9 +32407,9 @@ class InstancedMesh extends Mesh {
31873
32407
 
31874
32408
  // the mesh represents this single instance
31875
32409
 
31876
- _mesh.matrixWorld = _instanceWorldMatrix;
32410
+ _mesh$1.matrixWorld = _instanceWorldMatrix;
31877
32411
 
31878
- _mesh.raycast( raycaster, _instanceIntersects );
32412
+ _mesh$1.raycast( raycaster, _instanceIntersects );
31879
32413
 
31880
32414
  // process the result of raycast
31881
32415
 
@@ -36113,6 +36647,25 @@ class ImageBitmapLoader extends Loader {
36113
36647
 
36114
36648
  scope.manager.itemStart( url );
36115
36649
 
36650
+ // If cached is a promise, wait for it to resolve
36651
+ if ( cached.then ) {
36652
+
36653
+ cached.then( imageBitmap => {
36654
+
36655
+ if ( onLoad ) onLoad( imageBitmap );
36656
+
36657
+ scope.manager.itemEnd( url );
36658
+
36659
+ } ).catch( e => {
36660
+
36661
+ if ( onError ) onError( e );
36662
+
36663
+ } );
36664
+ return;
36665
+
36666
+ }
36667
+
36668
+ // If cached is not a promise (i.e., it's already an imageBitmap)
36116
36669
  setTimeout( function () {
36117
36670
 
36118
36671
  if ( onLoad ) onLoad( cached );
@@ -36129,7 +36682,7 @@ class ImageBitmapLoader extends Loader {
36129
36682
  fetchOptions.credentials = ( this.crossOrigin === 'anonymous' ) ? 'same-origin' : 'include';
36130
36683
  fetchOptions.headers = this.requestHeader;
36131
36684
 
36132
- fetch( url, fetchOptions ).then( function ( res ) {
36685
+ const promise = fetch( url, fetchOptions ).then( function ( res ) {
36133
36686
 
36134
36687
  return res.blob();
36135
36688
 
@@ -36145,15 +36698,20 @@ class ImageBitmapLoader extends Loader {
36145
36698
 
36146
36699
  scope.manager.itemEnd( url );
36147
36700
 
36701
+ return imageBitmap;
36702
+
36148
36703
  } ).catch( function ( e ) {
36149
36704
 
36150
36705
  if ( onError ) onError( e );
36151
36706
 
36707
+ Cache.remove( url );
36708
+
36152
36709
  scope.manager.itemError( url );
36153
36710
  scope.manager.itemEnd( url );
36154
36711
 
36155
36712
  } );
36156
36713
 
36714
+ Cache.add( url, promise );
36157
36715
  scope.manager.itemStart( url );
36158
36716
 
36159
36717
  }
@@ -41421,12 +41979,6 @@ class NRRDLoader extends Loader {
41421
41979
 
41422
41980
  function scan( type, chunks ) {
41423
41981
 
41424
- if ( chunks === undefined || chunks === null ) {
41425
-
41426
- chunks = 1;
41427
-
41428
- }
41429
-
41430
41982
  let _chunkSize = 1;
41431
41983
  let _array_type = Uint8Array;
41432
41984
 
@@ -41483,13 +42035,6 @@ class NRRDLoader extends Loader {
41483
42035
 
41484
42036
  }
41485
42037
 
41486
- if ( chunks == 1 ) {
41487
-
41488
- // if only one chunk was requested, just return one value
41489
- return _bytes[ 0 ];
41490
-
41491
- }
41492
-
41493
42038
  // return the byte array
41494
42039
  return _bytes;
41495
42040
 
@@ -47098,9 +47643,14 @@ class OrbitControls extends EventDispatcher {
47098
47643
 
47099
47644
  } else if ( scope.object.isOrthographicCamera ) {
47100
47645
 
47101
- scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
47102
- scope.object.updateProjectionMatrix();
47103
- zoomChanged = true;
47646
+ zoomChanged = scale !== 1;
47647
+
47648
+ if ( zoomChanged ) {
47649
+
47650
+ scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
47651
+ scope.object.updateProjectionMatrix();
47652
+
47653
+ }
47104
47654
 
47105
47655
  }
47106
47656
 
@@ -47122,8 +47672,6 @@ class OrbitControls extends EventDispatcher {
47122
47672
  lastQuaternion.copy( scope.object.quaternion );
47123
47673
  lastTargetPosition.copy( scope.target );
47124
47674
 
47125
- zoomChanged = false;
47126
-
47127
47675
  return true;
47128
47676
 
47129
47677
  }
@@ -47204,6 +47752,8 @@ class OrbitControls extends EventDispatcher {
47204
47752
  const pointers = [];
47205
47753
  const pointerPositions = {};
47206
47754
 
47755
+ let controlActive = false;
47756
+
47207
47757
  function getAutoRotationAngle( deltaTime ) {
47208
47758
 
47209
47759
  if ( deltaTime !== null ) {
@@ -47218,9 +47768,10 @@ class OrbitControls extends EventDispatcher {
47218
47768
 
47219
47769
  }
47220
47770
 
47221
- function getZoomScale() {
47771
+ function getZoomScale( delta ) {
47222
47772
 
47223
- return Math.pow( 0.95, scope.zoomSpeed );
47773
+ const normalizedDelta = Math.abs( delta * 0.01 );
47774
+ return Math.pow( 0.95, scope.zoomSpeed * normalizedDelta );
47224
47775
 
47225
47776
  }
47226
47777
 
@@ -47347,7 +47898,7 @@ class OrbitControls extends EventDispatcher {
47347
47898
 
47348
47899
  }
47349
47900
 
47350
- function updateMouseParameters( event ) {
47901
+ function updateZoomParameters( x, y ) {
47351
47902
 
47352
47903
  if ( ! scope.zoomToCursor ) {
47353
47904
 
@@ -47358,13 +47909,13 @@ class OrbitControls extends EventDispatcher {
47358
47909
  performCursorZoom = true;
47359
47910
 
47360
47911
  const rect = scope.domElement.getBoundingClientRect();
47361
- const x = event.clientX - rect.left;
47362
- const y = event.clientY - rect.top;
47912
+ const dx = x - rect.left;
47913
+ const dy = y - rect.top;
47363
47914
  const w = rect.width;
47364
47915
  const h = rect.height;
47365
47916
 
47366
- mouse.x = ( x / w ) * 2 - 1;
47367
- mouse.y = - ( y / h ) * 2 + 1;
47917
+ mouse.x = ( dx / w ) * 2 - 1;
47918
+ mouse.y = - ( dy / h ) * 2 + 1;
47368
47919
 
47369
47920
  dollyDirection.set( mouse.x, mouse.y, 1 ).unproject( scope.object ).sub( scope.object.position ).normalize();
47370
47921
 
@@ -47388,7 +47939,7 @@ class OrbitControls extends EventDispatcher {
47388
47939
 
47389
47940
  function handleMouseDownDolly( event ) {
47390
47941
 
47391
- updateMouseParameters( event );
47942
+ updateZoomParameters( event.clientX, event.clientX );
47392
47943
  dollyStart.set( event.clientX, event.clientY );
47393
47944
 
47394
47945
  }
@@ -47425,11 +47976,11 @@ class OrbitControls extends EventDispatcher {
47425
47976
 
47426
47977
  if ( dollyDelta.y > 0 ) {
47427
47978
 
47428
- dollyOut( getZoomScale() );
47979
+ dollyOut( getZoomScale( dollyDelta.y ) );
47429
47980
 
47430
47981
  } else if ( dollyDelta.y < 0 ) {
47431
47982
 
47432
- dollyIn( getZoomScale() );
47983
+ dollyIn( getZoomScale( dollyDelta.y ) );
47433
47984
 
47434
47985
  }
47435
47986
 
@@ -47455,15 +48006,15 @@ class OrbitControls extends EventDispatcher {
47455
48006
 
47456
48007
  function handleMouseWheel( event ) {
47457
48008
 
47458
- updateMouseParameters( event );
48009
+ updateZoomParameters( event.clientX, event.clientY );
47459
48010
 
47460
48011
  if ( event.deltaY < 0 ) {
47461
48012
 
47462
- dollyIn( getZoomScale() );
48013
+ dollyIn( getZoomScale( event.deltaY ) );
47463
48014
 
47464
48015
  } else if ( event.deltaY > 0 ) {
47465
48016
 
47466
- dollyOut( getZoomScale() );
48017
+ dollyOut( getZoomScale( event.deltaY ) );
47467
48018
 
47468
48019
  }
47469
48020
 
@@ -47551,16 +48102,18 @@ class OrbitControls extends EventDispatcher {
47551
48102
 
47552
48103
  }
47553
48104
 
47554
- function handleTouchStartRotate() {
48105
+ function handleTouchStartRotate( event ) {
47555
48106
 
47556
48107
  if ( pointers.length === 1 ) {
47557
48108
 
47558
- rotateStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );
48109
+ rotateStart.set( event.pageX, event.pageY );
47559
48110
 
47560
48111
  } else {
47561
48112
 
47562
- const x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );
47563
- const y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );
48113
+ const position = getSecondPointerPosition( event );
48114
+
48115
+ const x = 0.5 * ( event.pageX + position.x );
48116
+ const y = 0.5 * ( event.pageY + position.y );
47564
48117
 
47565
48118
  rotateStart.set( x, y );
47566
48119
 
@@ -47568,16 +48121,18 @@ class OrbitControls extends EventDispatcher {
47568
48121
 
47569
48122
  }
47570
48123
 
47571
- function handleTouchStartPan() {
48124
+ function handleTouchStartPan( event ) {
47572
48125
 
47573
48126
  if ( pointers.length === 1 ) {
47574
48127
 
47575
- panStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );
48128
+ panStart.set( event.pageX, event.pageY );
47576
48129
 
47577
48130
  } else {
47578
48131
 
47579
- const x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );
47580
- const y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );
48132
+ const position = getSecondPointerPosition( event );
48133
+
48134
+ const x = 0.5 * ( event.pageX + position.x );
48135
+ const y = 0.5 * ( event.pageY + position.y );
47581
48136
 
47582
48137
  panStart.set( x, y );
47583
48138
 
@@ -47585,10 +48140,12 @@ class OrbitControls extends EventDispatcher {
47585
48140
 
47586
48141
  }
47587
48142
 
47588
- function handleTouchStartDolly() {
48143
+ function handleTouchStartDolly( event ) {
48144
+
48145
+ const position = getSecondPointerPosition( event );
47589
48146
 
47590
- const dx = pointers[ 0 ].pageX - pointers[ 1 ].pageX;
47591
- const dy = pointers[ 0 ].pageY - pointers[ 1 ].pageY;
48147
+ const dx = event.pageX - position.x;
48148
+ const dy = event.pageY - position.y;
47592
48149
 
47593
48150
  const distance = Math.sqrt( dx * dx + dy * dy );
47594
48151
 
@@ -47596,19 +48153,19 @@ class OrbitControls extends EventDispatcher {
47596
48153
 
47597
48154
  }
47598
48155
 
47599
- function handleTouchStartDollyPan() {
48156
+ function handleTouchStartDollyPan( event ) {
47600
48157
 
47601
- if ( scope.enableZoom ) handleTouchStartDolly();
48158
+ if ( scope.enableZoom ) handleTouchStartDolly( event );
47602
48159
 
47603
- if ( scope.enablePan ) handleTouchStartPan();
48160
+ if ( scope.enablePan ) handleTouchStartPan( event );
47604
48161
 
47605
48162
  }
47606
48163
 
47607
- function handleTouchStartDollyRotate() {
48164
+ function handleTouchStartDollyRotate( event ) {
47608
48165
 
47609
- if ( scope.enableZoom ) handleTouchStartDolly();
48166
+ if ( scope.enableZoom ) handleTouchStartDolly( event );
47610
48167
 
47611
- if ( scope.enableRotate ) handleTouchStartRotate();
48168
+ if ( scope.enableRotate ) handleTouchStartRotate( event );
47612
48169
 
47613
48170
  }
47614
48171
 
@@ -47683,6 +48240,11 @@ class OrbitControls extends EventDispatcher {
47683
48240
 
47684
48241
  dollyStart.copy( dollyEnd );
47685
48242
 
48243
+ const centerX = ( event.pageX + position.x ) * 0.5;
48244
+ const centerY = ( event.pageY + position.y ) * 0.5;
48245
+
48246
+ updateZoomParameters( centerX, centerY );
48247
+
47686
48248
  }
47687
48249
 
47688
48250
  function handleTouchMoveDollyPan( event ) {
@@ -47754,18 +48316,32 @@ class OrbitControls extends EventDispatcher {
47754
48316
 
47755
48317
  removePointer( event );
47756
48318
 
47757
- if ( pointers.length === 0 ) {
48319
+ switch ( pointers.length ) {
47758
48320
 
47759
- scope.domElement.releasePointerCapture( event.pointerId );
48321
+ case 0:
47760
48322
 
47761
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
47762
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
48323
+ scope.domElement.releasePointerCapture( event.pointerId );
47763
48324
 
47764
- }
48325
+ scope.domElement.removeEventListener( 'pointermove', onPointerMove );
48326
+ scope.domElement.removeEventListener( 'pointerup', onPointerUp );
47765
48327
 
47766
- scope.dispatchEvent( _endEvent$1 );
48328
+ scope.dispatchEvent( _endEvent$1 );
47767
48329
 
47768
- state = STATE.NONE;
48330
+ state = STATE.NONE;
48331
+
48332
+ break;
48333
+
48334
+ case 1:
48335
+
48336
+ const pointerId = pointers[ 0 ];
48337
+ const position = pointerPositions[ pointerId ];
48338
+
48339
+ // minimal placeholder event - allows state correction on pointer-up
48340
+ onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );
48341
+
48342
+ break;
48343
+
48344
+ }
47769
48345
 
47770
48346
  }
47771
48347
 
@@ -47906,12 +48482,76 @@ class OrbitControls extends EventDispatcher {
47906
48482
 
47907
48483
  scope.dispatchEvent( _startEvent$1 );
47908
48484
 
47909
- handleMouseWheel( event );
48485
+ handleMouseWheel( customWheelEvent( event ) );
47910
48486
 
47911
48487
  scope.dispatchEvent( _endEvent$1 );
47912
48488
 
47913
48489
  }
47914
48490
 
48491
+ function customWheelEvent( event ) {
48492
+
48493
+ const mode = event.deltaMode;
48494
+
48495
+ // minimal wheel event altered to meet delta-zoom demand
48496
+ const newEvent = {
48497
+ clientX: event.clientX,
48498
+ clientY: event.clientY,
48499
+ deltaY: event.deltaY,
48500
+ };
48501
+
48502
+ switch ( mode ) {
48503
+
48504
+ case 1: // LINE_MODE
48505
+ newEvent.deltaY *= 16;
48506
+ break;
48507
+
48508
+ case 2: // PAGE_MODE
48509
+ newEvent.deltaY *= 100;
48510
+ break;
48511
+
48512
+ }
48513
+
48514
+ // detect if event was triggered by pinching
48515
+ if ( event.ctrlKey && ! controlActive ) {
48516
+
48517
+ newEvent.deltaY *= 10;
48518
+
48519
+ }
48520
+
48521
+ return newEvent;
48522
+
48523
+ }
48524
+
48525
+ function interceptControlDown( event ) {
48526
+
48527
+ if ( event.key === 'Control' ) {
48528
+
48529
+ controlActive = true;
48530
+
48531
+
48532
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
48533
+
48534
+ document.addEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
48535
+
48536
+ }
48537
+
48538
+ }
48539
+
48540
+ function interceptControlUp( event ) {
48541
+
48542
+ if ( event.key === 'Control' ) {
48543
+
48544
+ controlActive = false;
48545
+
48546
+
48547
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
48548
+
48549
+ document.removeEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
48550
+
48551
+ }
48552
+
48553
+ }
48554
+
47915
48555
  function onKeyDown( event ) {
47916
48556
 
47917
48557
  if ( scope.enabled === false || scope.enablePan === false ) return;
@@ -47934,7 +48574,7 @@ class OrbitControls extends EventDispatcher {
47934
48574
 
47935
48575
  if ( scope.enableRotate === false ) return;
47936
48576
 
47937
- handleTouchStartRotate();
48577
+ handleTouchStartRotate( event );
47938
48578
 
47939
48579
  state = STATE.TOUCH_ROTATE;
47940
48580
 
@@ -47944,7 +48584,7 @@ class OrbitControls extends EventDispatcher {
47944
48584
 
47945
48585
  if ( scope.enablePan === false ) return;
47946
48586
 
47947
- handleTouchStartPan();
48587
+ handleTouchStartPan( event );
47948
48588
 
47949
48589
  state = STATE.TOUCH_PAN;
47950
48590
 
@@ -47966,7 +48606,7 @@ class OrbitControls extends EventDispatcher {
47966
48606
 
47967
48607
  if ( scope.enableZoom === false && scope.enablePan === false ) return;
47968
48608
 
47969
- handleTouchStartDollyPan();
48609
+ handleTouchStartDollyPan( event );
47970
48610
 
47971
48611
  state = STATE.TOUCH_DOLLY_PAN;
47972
48612
 
@@ -47976,7 +48616,7 @@ class OrbitControls extends EventDispatcher {
47976
48616
 
47977
48617
  if ( scope.enableZoom === false && scope.enableRotate === false ) return;
47978
48618
 
47979
- handleTouchStartDollyRotate();
48619
+ handleTouchStartDollyRotate( event );
47980
48620
 
47981
48621
  state = STATE.TOUCH_DOLLY_ROTATE;
47982
48622
 
@@ -48068,7 +48708,7 @@ class OrbitControls extends EventDispatcher {
48068
48708
 
48069
48709
  function addPointer( event ) {
48070
48710
 
48071
- pointers.push( event );
48711
+ pointers.push( event.pointerId );
48072
48712
 
48073
48713
  }
48074
48714
 
@@ -48078,7 +48718,7 @@ class OrbitControls extends EventDispatcher {
48078
48718
 
48079
48719
  for ( let i = 0; i < pointers.length; i ++ ) {
48080
48720
 
48081
- if ( pointers[ i ].pointerId == event.pointerId ) {
48721
+ if ( pointers[ i ] == event.pointerId ) {
48082
48722
 
48083
48723
  pointers.splice( i, 1 );
48084
48724
  return;
@@ -48106,9 +48746,9 @@ class OrbitControls extends EventDispatcher {
48106
48746
 
48107
48747
  function getSecondPointerPosition( event ) {
48108
48748
 
48109
- const pointer = ( event.pointerId === pointers[ 0 ].pointerId ) ? pointers[ 1 ] : pointers[ 0 ];
48749
+ const pointerId = ( event.pointerId === pointers[ 0 ] ) ? pointers[ 1 ] : pointers[ 0 ];
48110
48750
 
48111
- return pointerPositions[ pointer.pointerId ];
48751
+ return pointerPositions[ pointerId ];
48112
48752
 
48113
48753
  }
48114
48754
 
@@ -48120,6 +48760,10 @@ class OrbitControls extends EventDispatcher {
48120
48760
  scope.domElement.addEventListener( 'pointercancel', onPointerUp );
48121
48761
  scope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );
48122
48762
 
48763
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
48764
+
48765
+ document.addEventListener( 'keydown', interceptControlDown, { passive: true, capture: true } );
48766
+
48123
48767
  // force an update at start
48124
48768
 
48125
48769
  this.update();
@@ -49599,6 +50243,12 @@ class GLTFLoader extends Loader {
49599
50243
 
49600
50244
  } );
49601
50245
 
50246
+ this.register( function ( parser ) {
50247
+
50248
+ return new GLTFMaterialsBumpExtension( parser );
50249
+
50250
+ } );
50251
+
49602
50252
  this.register( function ( parser ) {
49603
50253
 
49604
50254
  return new GLTFLightsExtension( parser );
@@ -49631,7 +50281,13 @@ class GLTFLoader extends Loader {
49631
50281
 
49632
50282
  } else if ( this.path !== '' ) {
49633
50283
 
49634
- resourcePath = this.path;
50284
+ // If a base path is set, resources will be relative paths from that plus the relative path of the gltf file
50285
+ // Example path = 'https://my-cnd-server.com/', url = 'assets/models/model.gltf'
50286
+ // resourcePath = 'https://my-cnd-server.com/assets/models/'
50287
+ // referenced resource 'model.bin' will be loaded from 'https://my-cnd-server.com/assets/models/model.bin'
50288
+ // referenced resource '../textures/texture.png' will be loaded from 'https://my-cnd-server.com/assets/textures/texture.png'
50289
+ const relativeUrl = LoaderUtils.extractUrlBase( url );
50290
+ resourcePath = LoaderUtils.resolveURL( relativeUrl, this.path );
49635
50291
 
49636
50292
  } else {
49637
50293
 
@@ -49939,6 +50595,7 @@ const EXTENSIONS = {
49939
50595
  KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
49940
50596
  KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
49941
50597
  KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',
50598
+ EXT_MATERIALS_BUMP: 'EXT_materials_bump',
49942
50599
  EXT_TEXTURE_WEBP: 'EXT_texture_webp',
49943
50600
  EXT_TEXTURE_AVIF: 'EXT_texture_avif',
49944
50601
  EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
@@ -50649,6 +51306,61 @@ class GLTFMaterialsSpecularExtension {
50649
51306
 
50650
51307
  }
50651
51308
 
51309
+
51310
+ /**
51311
+ * Materials bump Extension
51312
+ *
51313
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump
51314
+ */
51315
+ class GLTFMaterialsBumpExtension {
51316
+
51317
+ constructor( parser ) {
51318
+
51319
+ this.parser = parser;
51320
+ this.name = EXTENSIONS.EXT_MATERIALS_BUMP;
51321
+
51322
+ }
51323
+
51324
+ getMaterialType( materialIndex ) {
51325
+
51326
+ const parser = this.parser;
51327
+ const materialDef = parser.json.materials[ materialIndex ];
51328
+
51329
+ if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
51330
+
51331
+ return MeshPhysicalMaterial;
51332
+
51333
+ }
51334
+
51335
+ extendMaterialParams( materialIndex, materialParams ) {
51336
+
51337
+ const parser = this.parser;
51338
+ const materialDef = parser.json.materials[ materialIndex ];
51339
+
51340
+ if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
51341
+
51342
+ return Promise.resolve();
51343
+
51344
+ }
51345
+
51346
+ const pending = [];
51347
+
51348
+ const extension = materialDef.extensions[ this.name ];
51349
+
51350
+ materialParams.bumpScale = extension.bumpFactor !== undefined ? extension.bumpFactor : 1.0;
51351
+
51352
+ if ( extension.bumpTexture !== undefined ) {
51353
+
51354
+ pending.push( parser.assignTexture( materialParams, 'bumpMap', extension.bumpTexture ) );
51355
+
51356
+ }
51357
+
51358
+ return Promise.all( pending );
51359
+
51360
+ }
51361
+
51362
+ }
51363
+
50652
51364
  /**
50653
51365
  * Materials anisotropy Extension
50654
51366
  *
@@ -51303,7 +52015,7 @@ class GLTFDracoMeshCompressionExtension {
51303
52015
 
51304
52016
  return parser.getDependency( 'bufferView', bufferViewIndex ).then( function ( bufferView ) {
51305
52017
 
51306
- return new Promise( function ( resolve ) {
52018
+ return new Promise( function ( resolve, reject ) {
51307
52019
 
51308
52020
  dracoLoader.decodeDracoFile( bufferView, function ( geometry ) {
51309
52021
 
@@ -51318,7 +52030,7 @@ class GLTFDracoMeshCompressionExtension {
51318
52030
 
51319
52031
  resolve( geometry );
51320
52032
 
51321
- }, threeAttributeMap, attributeTypeMap );
52033
+ }, threeAttributeMap, attributeTypeMap, LinearSRGBColorSpace, reject );
51322
52034
 
51323
52035
  } );
51324
52036
 
@@ -54209,17 +54921,32 @@ class KTX2Loader extends Loader {
54209
54921
 
54210
54922
  }
54211
54923
 
54924
+ async detectSupportAsync( renderer ) {
54925
+
54926
+ this.workerConfig = {
54927
+ astcSupported: await renderer.hasFeatureAsync( 'texture-compression-astc' ),
54928
+ etc1Supported: await renderer.hasFeatureAsync( 'texture-compression-etc1' ),
54929
+ etc2Supported: await renderer.hasFeatureAsync( 'texture-compression-etc2' ),
54930
+ dxtSupported: await renderer.hasFeatureAsync( 'texture-compression-bc' ),
54931
+ bptcSupported: await renderer.hasFeatureAsync( 'texture-compression-bptc' ),
54932
+ pvrtcSupported: await renderer.hasFeatureAsync( 'texture-compression-pvrtc' )
54933
+ };
54934
+
54935
+ return this;
54936
+
54937
+ }
54938
+
54212
54939
  detectSupport( renderer ) {
54213
54940
 
54214
54941
  if ( renderer.isWebGPURenderer === true ) {
54215
54942
 
54216
54943
  this.workerConfig = {
54217
54944
  astcSupported: renderer.hasFeature( 'texture-compression-astc' ),
54218
- etc1Supported: false,
54945
+ etc1Supported: renderer.hasFeature( 'texture-compression-etc1' ),
54219
54946
  etc2Supported: renderer.hasFeature( 'texture-compression-etc2' ),
54220
54947
  dxtSupported: renderer.hasFeature( 'texture-compression-bc' ),
54221
- bptcSupported: false,
54222
- pvrtcSupported: false
54948
+ bptcSupported: renderer.hasFeature( 'texture-compression-bptc' ),
54949
+ pvrtcSupported: renderer.hasFeature( 'texture-compression-pvrtc' )
54223
54950
  };
54224
54951
 
54225
54952
  } else {
@@ -54954,8 +55681,8 @@ async function createRawTexture( container ) {
54954
55681
  if ( UNCOMPRESSED_FORMATS.has( FORMAT_MAP[ vkFormat ] ) ) {
54955
55682
 
54956
55683
  texture = container.pixelDepth === 0
54957
- ? new DataTexture( mipmaps[ 0 ].data, container.pixelWidth, container.pixelHeight )
54958
- : new Data3DTexture( mipmaps[ 0 ].data, container.pixelWidth, container.pixelHeight, container.pixelDepth );
55684
+ ? new DataTexture( mipmaps[ 0 ].data, container.pixelWidth, container.pixelHeight )
55685
+ : new Data3DTexture( mipmaps[ 0 ].data, container.pixelWidth, container.pixelHeight, container.pixelDepth );
54959
55686
 
54960
55687
  } else {
54961
55688
 
@@ -55077,13 +55804,14 @@ class DRACOLoader extends Loader {
55077
55804
 
55078
55805
  }
55079
55806
 
55080
- parse( buffer, onLoad, onError ) {
55807
+
55808
+ parse( buffer, onLoad, onError = ()=>{} ) {
55081
55809
 
55082
55810
  this.decodeDracoFile( buffer, onLoad, null, null, SRGBColorSpace ).catch( onError );
55083
55811
 
55084
55812
  }
55085
55813
 
55086
- decodeDracoFile( buffer, callback, attributeIDs, attributeTypes, vertexColorSpace = LinearSRGBColorSpace ) {
55814
+ decodeDracoFile( buffer, callback, attributeIDs, attributeTypes, vertexColorSpace = LinearSRGBColorSpace, onError = () => {} ) {
55087
55815
 
55088
55816
  const taskConfig = {
55089
55817
  attributeIDs: attributeIDs || this.defaultAttributeIDs,
@@ -55092,7 +55820,7 @@ class DRACOLoader extends Loader {
55092
55820
  vertexColorSpace: vertexColorSpace,
55093
55821
  };
55094
55822
 
55095
- return this.decodeGeometry( buffer, taskConfig ).then( callback );
55823
+ return this.decodeGeometry( buffer, taskConfig ).then( callback ).catch( onError );
55096
55824
 
55097
55825
  }
55098
55826
 
@@ -69385,7 +70113,12 @@ class DragOperator {
69385
70113
  if (ev.key === "Shift") {
69386
70114
  this.removeDragMode();
69387
70115
  }
70116
+ });
70117
+ this.container.addEventListener("keyup", (ev) => {
69388
70118
  if (ev.key === 'Control' || ev.key === 'Meta') {
70119
+ /**
70120
+ * if ctrl pressed remove the drag mode
70121
+ */
69389
70122
  if (this.protectedData.Is_Ctrl_Pressed) {
69390
70123
  this.removeDragMode();
69391
70124
  }
@@ -69393,8 +70126,6 @@ class DragOperator {
69393
70126
  this.configDragMode();
69394
70127
  }
69395
70128
  }
69396
- });
69397
- this.container.addEventListener("keyup", (ev) => {
69398
70129
  if (ev.key === "Shift" && !this.gui_states.sphere) {
69399
70130
  if (this.protectedData.Is_Ctrl_Pressed) {
69400
70131
  return;
@@ -69868,6 +70599,7 @@ class DrawToolCore extends CommToolsData {
69868
70599
  this.initDrawToolCore();
69869
70600
  }
69870
70601
  initDrawToolCore() {
70602
+ let undoFlag = false;
69871
70603
  this.container.addEventListener("keydown", (ev) => {
69872
70604
  if (ev.key === "Shift" && !this.gui_states.sphere) {
69873
70605
  if (this.protectedData.Is_Ctrl_Pressed) {
@@ -69877,7 +70609,23 @@ class DrawToolCore extends CommToolsData {
69877
70609
  this.protectedData.Is_Shift_Pressed = true;
69878
70610
  this.nrrd_states.enableCursorChoose = false;
69879
70611
  }
70612
+ if (ev.key === "s") {
70613
+ this.protectedData.Is_Draw = false;
70614
+ this.nrrd_states.enableCursorChoose =
70615
+ !this.nrrd_states.enableCursorChoose;
70616
+ }
70617
+ if ((ev.ctrlKey || ev.metaKey) && ev.code === "KeyZ") {
70618
+ undoFlag = true;
70619
+ this.undoLastPainting();
70620
+ }
70621
+ });
70622
+ this.container.addEventListener("keyup", (ev) => {
69880
70623
  if (ev.key === 'Control' || ev.key === 'Meta') {
70624
+ if (undoFlag) {
70625
+ this.gui_states.readyToUpdate = true;
70626
+ undoFlag = false;
70627
+ return;
70628
+ }
69881
70629
  // Ctrl key pressed on either Windows or macOS
69882
70630
  this.protectedData.Is_Shift_Pressed = false;
69883
70631
  this.protectedData.Is_Ctrl_Pressed = !this.protectedData.Is_Ctrl_Pressed;
@@ -69886,15 +70634,9 @@ class DrawToolCore extends CommToolsData {
69886
70634
  }
69887
70635
  else {
69888
70636
  this.removeContrastDragMode();
70637
+ this.gui_states.readyToUpdate = true;
69889
70638
  }
69890
70639
  }
69891
- if (ev.key === "s") {
69892
- this.protectedData.Is_Draw = false;
69893
- this.nrrd_states.enableCursorChoose =
69894
- !this.nrrd_states.enableCursorChoose;
69895
- }
69896
- });
69897
- this.container.addEventListener("keyup", (ev) => {
69898
70640
  if (ev.key === "Shift") {
69899
70641
  this.protectedData.Is_Shift_Pressed = false;
69900
70642
  }
@@ -70283,11 +71025,6 @@ class DrawToolCore extends CommToolsData {
70283
71025
  this.redrawDisplayCanvas();
70284
71026
  }
70285
71027
  };
70286
- document.addEventListener("keydown", (e) => {
70287
- if ((e.ctrlKey || e.metaKey) && e.code === "KeyZ") {
70288
- this.undoLastPainting();
70289
- }
70290
- });
70291
71028
  }
70292
71029
  drawLinesOnLayer(ctx, x, y) {
70293
71030
  ctx.beginPath();
@@ -72171,7 +72908,7 @@ function evaluateElement(element, weights) {
72171
72908
  }
72172
72909
 
72173
72910
  // import * as kiwrious from "copper3d_plugin_heart_k";
72174
- const REVISION = "v2.0.7";
72175
- console.log("%cCopper3D Visualisation %cBeta:v2.0.7", "padding: 3px;color:white; background:#023047", "padding: 3px;color:white; background:#f50a25");
72911
+ const REVISION = "v2.0.9";
72912
+ console.log("%cCopper3D Visualisation %cBeta:v2.0.9", "padding: 3px;color:white; background:#023047", "padding: 3px;color:white; background:#f50a25");
72176
72913
 
72177
72914
  export { CameraViewPoint, Copper3dTrackballControls, MeshNodeTool, NrrdTools, REVISION, addBoxHelper, addLabelToScene, configKiwriousHeart, convert3DPostoScreenPos, convertScreenPosto3DPos, copperMScene, copperMSceneRenderer, copperRenderer, copperRendererOnDemond, copperScene, copperSceneOnDemond, createTexture2D_NRRD, fullScreenListenner, kiwrious, loading, removeGuiFolderChilden, setHDRFilePath, throttle };