super-three 0.157.0 → 0.158.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/README.md +6 -4
  2. package/build/three.cjs +1486 -842
  3. package/build/three.js +1486 -842
  4. package/build/three.min.js +1 -1
  5. package/build/three.module.js +1481 -843
  6. package/build/three.module.min.js +1 -1
  7. package/examples/jsm/Addons.js +290 -0
  8. package/examples/jsm/controls/FlyControls.js +26 -0
  9. package/examples/jsm/controls/OrbitControls.js +12 -1
  10. package/examples/jsm/controls/TransformControls.js +27 -11
  11. package/examples/jsm/csm/CSMShader.js +1 -1
  12. package/examples/jsm/exporters/GLTFExporter.js +72 -2
  13. package/examples/jsm/geometries/InstancedPointsGeometry.js +174 -0
  14. package/examples/jsm/geometries/SDFGeometryGenerator.js +144 -0
  15. package/examples/jsm/libs/lottie_canvas.module.js +6 -1
  16. package/examples/jsm/libs/opentype.module.js +13 -75
  17. package/examples/jsm/libs/surfaceNet.js +201 -0
  18. package/examples/jsm/loaders/GLTFLoader.js +12 -3
  19. package/examples/jsm/loaders/LUTImageLoader.js +162 -0
  20. package/examples/jsm/loaders/lwo/IFFParser.js +89 -93
  21. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
  22. package/examples/jsm/math/Capsule.js +0 -55
  23. package/examples/jsm/math/Octree.js +70 -3
  24. package/examples/jsm/modifiers/SimplifyModifier.js +103 -11
  25. package/examples/jsm/modifiers/TessellateModifier.js +3 -3
  26. package/examples/jsm/nodes/Nodes.js +6 -6
  27. package/examples/jsm/nodes/accessors/CubeTextureNode.js +3 -3
  28. package/examples/jsm/nodes/accessors/InstanceNode.js +3 -3
  29. package/examples/jsm/nodes/accessors/InstancedPointsMaterialNode.js +21 -0
  30. package/examples/jsm/nodes/accessors/MaterialNode.js +68 -31
  31. package/examples/jsm/nodes/accessors/ModelNode.js +1 -2
  32. package/examples/jsm/nodes/accessors/MorphNode.js +5 -5
  33. package/examples/jsm/nodes/accessors/NormalNode.js +1 -1
  34. package/examples/jsm/nodes/accessors/PositionNode.js +1 -1
  35. package/examples/jsm/nodes/accessors/SkinningNode.js +13 -3
  36. package/examples/jsm/nodes/accessors/TextureNode.js +3 -3
  37. package/examples/jsm/nodes/code/FunctionNode.js +1 -1
  38. package/examples/jsm/nodes/core/AssignNode.js +72 -0
  39. package/examples/jsm/nodes/core/LightingModel.js +3 -1
  40. package/examples/jsm/nodes/core/Node.js +7 -12
  41. package/examples/jsm/nodes/core/NodeBuilder.js +126 -16
  42. package/examples/jsm/nodes/core/NodeUtils.js +4 -2
  43. package/examples/jsm/nodes/core/OutputStructNode.js +1 -1
  44. package/examples/jsm/nodes/core/ParameterNode.js +33 -0
  45. package/examples/jsm/nodes/core/PropertyNode.js +4 -10
  46. package/examples/jsm/nodes/core/StackNode.js +7 -17
  47. package/examples/jsm/nodes/core/TempNode.js +1 -1
  48. package/examples/jsm/nodes/core/VarNode.js +6 -35
  49. package/examples/jsm/nodes/core/VaryingNode.js +2 -0
  50. package/examples/jsm/nodes/display/BumpMapNode.js +35 -13
  51. package/examples/jsm/nodes/display/NormalMapNode.js +3 -1
  52. package/examples/jsm/nodes/display/ViewportNode.js +14 -4
  53. package/examples/jsm/nodes/functions/BSDF/BRDF_Sheen.js +20 -6
  54. package/examples/jsm/nodes/functions/BSDF/DFGApprox.js +8 -7
  55. package/examples/jsm/nodes/functions/BSDF/D_GGX.js +8 -3
  56. package/examples/jsm/nodes/functions/BSDF/Schlick_to_F0.js +8 -0
  57. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +8 -0
  58. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +93 -43
  59. package/examples/jsm/nodes/gpgpu/ComputeNode.js +2 -2
  60. package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
  61. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +19 -5
  62. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +1 -1
  63. package/examples/jsm/nodes/lighting/EnvironmentNode.js +0 -6
  64. package/examples/jsm/nodes/lighting/LightingContextNode.js +21 -57
  65. package/examples/jsm/nodes/lighting/LightsNode.js +62 -4
  66. package/examples/jsm/nodes/lighting/PointLightNode.js +1 -1
  67. package/examples/jsm/nodes/lighting/SpotLightNode.js +1 -1
  68. package/examples/jsm/nodes/materials/InstancedPointsNodeMaterial.js +162 -0
  69. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +70 -71
  70. package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +5 -5
  71. package/examples/jsm/nodes/materials/Materials.js +1 -0
  72. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +2 -2
  73. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +3 -3
  74. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +47 -20
  75. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +6 -6
  76. package/examples/jsm/nodes/materials/NodeMaterial.js +17 -20
  77. package/examples/jsm/nodes/materialx/lib/mx_noise.js +5 -5
  78. package/examples/jsm/nodes/math/OperatorNode.js +5 -21
  79. package/examples/jsm/nodes/shadernode/ShaderNode.js +128 -9
  80. package/examples/jsm/nodes/utils/ArrayElementNode.js +2 -0
  81. package/examples/jsm/nodes/utils/DiscardNode.js +3 -2
  82. package/examples/jsm/nodes/utils/JoinNode.js +11 -1
  83. package/examples/jsm/nodes/utils/LoopNode.js +36 -24
  84. package/examples/jsm/nodes/utils/SplitNode.js +2 -0
  85. package/examples/jsm/objects/BatchedMesh.js +586 -0
  86. package/examples/jsm/objects/InstancedPoints.js +21 -0
  87. package/examples/jsm/objects/Lensflare.js +20 -0
  88. package/examples/jsm/objects/ReflectorForSSRPass.js +3 -0
  89. package/examples/jsm/objects/Refractor.js +3 -0
  90. package/examples/jsm/objects/Sky.js +5 -3
  91. package/examples/jsm/objects/Water.js +5 -2
  92. package/examples/jsm/objects/Water2.js +3 -0
  93. package/examples/jsm/physics/AmmoPhysics.js +21 -0
  94. package/examples/jsm/physics/RapierPhysics.js +21 -0
  95. package/examples/jsm/postprocessing/BokehPass.js +3 -2
  96. package/examples/jsm/postprocessing/LUTPass.js +2 -1
  97. package/examples/jsm/postprocessing/OutputPass.js +1 -0
  98. package/examples/jsm/postprocessing/Pass.js +14 -3
  99. package/examples/jsm/postprocessing/SAOPass.js +0 -1
  100. package/examples/jsm/postprocessing/SMAAPass.js +0 -2
  101. package/examples/jsm/postprocessing/TAARenderPass.js +1 -2
  102. package/examples/jsm/renderers/CSS3DRenderer.js +3 -9
  103. package/examples/jsm/renderers/SVGRenderer.js +9 -6
  104. package/examples/jsm/renderers/common/Bindings.js +1 -1
  105. package/examples/jsm/renderers/common/RenderObject.js +8 -1
  106. package/examples/jsm/renderers/common/RenderObjects.js +1 -1
  107. package/examples/jsm/renderers/common/Textures.js +4 -36
  108. package/examples/jsm/renderers/common/nodes/Nodes.js +53 -18
  109. package/examples/jsm/renderers/webgl/WebGLBackend.js +291 -50
  110. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +88 -12
  111. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +40 -5
  112. package/examples/jsm/renderers/webgl/utils/WebGLState.js +14 -2
  113. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +2 -0
  114. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +36 -4
  115. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +2 -0
  116. package/examples/jsm/shaders/AfterimageShader.js +2 -0
  117. package/examples/jsm/shaders/BasicShader.js +2 -0
  118. package/examples/jsm/shaders/BlendShader.js +2 -0
  119. package/examples/jsm/shaders/BokehShader.js +2 -0
  120. package/examples/jsm/shaders/BokehShader2.js +4 -0
  121. package/examples/jsm/shaders/BrightnessContrastShader.js +2 -0
  122. package/examples/jsm/shaders/ColorCorrectionShader.js +2 -0
  123. package/examples/jsm/shaders/DOFMipMapShader.js +2 -0
  124. package/examples/jsm/shaders/DepthLimitedBlurShader.js +5 -0
  125. package/examples/jsm/shaders/FXAAShader.js +2 -0
  126. package/examples/jsm/shaders/FilmShader.js +1 -1
  127. package/examples/jsm/shaders/FocusShader.js +2 -0
  128. package/examples/jsm/shaders/FreiChenShader.js +2 -0
  129. package/examples/jsm/shaders/GodRaysShader.js +8 -0
  130. package/examples/jsm/shaders/HalftoneShader.js +2 -0
  131. package/examples/jsm/shaders/HorizontalTiltShiftShader.js +2 -0
  132. package/examples/jsm/shaders/HueSaturationShader.js +2 -0
  133. package/examples/jsm/shaders/KaleidoShader.js +2 -0
  134. package/examples/jsm/shaders/LuminosityHighPassShader.js +2 -0
  135. package/examples/jsm/shaders/LuminosityShader.js +2 -0
  136. package/examples/jsm/shaders/MMDToonShader.js +2 -0
  137. package/examples/jsm/shaders/MirrorShader.js +2 -0
  138. package/examples/jsm/shaders/NormalMapShader.js +2 -0
  139. package/examples/jsm/shaders/OutputShader.js +4 -5
  140. package/examples/jsm/shaders/SAOShader.js +5 -0
  141. package/examples/jsm/shaders/SMAAShader.js +6 -0
  142. package/examples/jsm/shaders/SSAOShader.js +6 -0
  143. package/examples/jsm/shaders/SSRShader.js +6 -0
  144. package/examples/jsm/shaders/SobelOperatorShader.js +2 -0
  145. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +2 -0
  146. package/examples/jsm/shaders/TechnicolorShader.js +2 -0
  147. package/examples/jsm/shaders/TriangleBlurShader.js +2 -0
  148. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -0
  149. package/examples/jsm/shaders/VelocityShader.js +2 -0
  150. package/examples/jsm/shaders/VerticalTiltShiftShader.js +2 -0
  151. package/examples/jsm/shaders/WaterRefractionShader.js +2 -0
  152. package/examples/jsm/transpiler/AST.js +231 -0
  153. package/examples/jsm/transpiler/GLSLDecoder.js +899 -0
  154. package/examples/jsm/transpiler/ShaderToyDecoder.js +49 -0
  155. package/examples/jsm/transpiler/TSLEncoder.js +611 -0
  156. package/examples/jsm/transpiler/Transpiler.js +18 -0
  157. package/examples/jsm/webxr/VRButton.js +1 -1
  158. package/examples/jsm/webxr/XRButton.js +7 -5
  159. package/examples/jsm/webxr/XREstimatedLight.js +1 -1
  160. package/package.json +4 -1
  161. package/src/constants.js +7 -1
  162. package/src/extras/PMREMGenerator.js +7 -1
  163. package/src/loaders/MaterialLoader.js +10 -2
  164. package/src/materials/Material.js +27 -13
  165. package/src/math/Box3.js +35 -18
  166. package/src/math/Vector3.js +11 -12
  167. package/src/objects/SkinnedMesh.js +6 -7
  168. package/src/renderers/WebGLMultiviewRenderTarget.js +35 -0
  169. package/src/renderers/WebGLRenderer.js +199 -45
  170. package/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl.js +8 -0
  171. package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +3 -2
  172. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  173. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +8 -6
  174. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +2 -2
  175. package/src/renderers/webgl/WebGLBackground.js +1 -1
  176. package/src/renderers/webgl/WebGLMultiview.js +100 -0
  177. package/src/renderers/webgl/WebGLProgram.js +130 -50
  178. package/src/renderers/webgl/WebGLPrograms.js +8 -0
  179. package/src/renderers/webgl/WebGLState.js +25 -4
  180. package/src/renderers/webgl/WebGLTextures.js +197 -20
  181. package/src/renderers/webxr/WebXRManager.js +36 -12
  182. package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +0 -76
  183. package/examples/jsm/nodes/accessors/LineMaterialNode.js +0 -29
@@ -3,7 +3,7 @@
3
3
  * Copyright 2010-2023 Three.js Authors
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
- const REVISION = '157';
6
+ const REVISION = '158';
7
7
 
8
8
  const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
9
9
  const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
@@ -41,6 +41,10 @@ const OneMinusDstAlphaFactor = 207;
41
41
  const DstColorFactor = 208;
42
42
  const OneMinusDstColorFactor = 209;
43
43
  const SrcAlphaSaturateFactor = 210;
44
+ const ConstantColorFactor = 211;
45
+ const OneMinusConstantColorFactor = 212;
46
+ const ConstantAlphaFactor = 213;
47
+ const OneMinusConstantAlphaFactor = 214;
44
48
  const NeverDepth = 0;
45
49
  const AlwaysDepth = 1;
46
50
  const LessDepth = 2;
@@ -58,6 +62,8 @@ const ReinhardToneMapping = 2;
58
62
  const CineonToneMapping = 3;
59
63
  const ACESFilmicToneMapping = 4;
60
64
  const CustomToneMapping = 5;
65
+ const AttachedBindMode = 'attached';
66
+ const DetachedBindMode = 'detached';
61
67
 
62
68
  const UVMapping = 300;
63
69
  const CubeReflectionMapping = 301;
@@ -4152,21 +4158,20 @@ class Vector3 {
4152
4158
 
4153
4159
  applyQuaternion( q ) {
4154
4160
 
4155
- const x = this.x, y = this.y, z = this.z;
4156
- const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
4161
+ // quaternion q is assumed to have unit length
4157
4162
 
4158
- // calculate quat * vector
4159
-
4160
- const ix = qw * x + qy * z - qz * y;
4161
- const iy = qw * y + qz * x - qx * z;
4162
- const iz = qw * z + qx * y - qy * x;
4163
- const iw = - qx * x - qy * y - qz * z;
4163
+ const vx = this.x, vy = this.y, vz = this.z;
4164
+ const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
4164
4165
 
4165
- // calculate result * inverse quat
4166
+ // t = 2 * cross( q.xyz, v );
4167
+ const tx = 2 * ( qy * vz - qz * vy );
4168
+ const ty = 2 * ( qz * vx - qx * vz );
4169
+ const tz = 2 * ( qx * vy - qy * vx );
4166
4170
 
4167
- this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
4168
- this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
4169
- this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
4171
+ // v + q.w * t + cross( q.xyz, t );
4172
+ this.x = vx + qw * tx + qy * tz - qz * ty;
4173
+ this.y = vy + qw * ty + qz * tx - qx * tz;
4174
+ this.z = vz + qw * tz + qx * ty - qy * tx;
4170
4175
 
4171
4176
  return this;
4172
4177
 
@@ -4782,37 +4787,53 @@ class Box3 {
4782
4787
 
4783
4788
  object.updateWorldMatrix( false, false );
4784
4789
 
4785
- if ( object.boundingBox !== undefined ) {
4790
+ const geometry = object.geometry;
4786
4791
 
4787
- if ( object.boundingBox === null ) {
4792
+ if ( geometry !== undefined ) {
4788
4793
 
4789
- object.computeBoundingBox();
4794
+ const positionAttribute = geometry.getAttribute( 'position' );
4790
4795
 
4791
- }
4796
+ // precise AABB computation based on vertex data requires at least a position attribute.
4797
+ // instancing isn't supported so far and uses the normal (conservative) code path.
4792
4798
 
4793
- _box$3.copy( object.boundingBox );
4794
- _box$3.applyMatrix4( object.matrixWorld );
4799
+ if ( precise === true && positionAttribute !== undefined && object.isInstancedMesh !== true ) {
4795
4800
 
4796
- this.union( _box$3 );
4801
+ for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) {
4797
4802
 
4798
- } else {
4803
+ if ( object.isMesh === true ) {
4799
4804
 
4800
- const geometry = object.geometry;
4805
+ object.getVertexPosition( i, _vector$a );
4801
4806
 
4802
- if ( geometry !== undefined ) {
4807
+ } else {
4808
+
4809
+ _vector$a.fromBufferAttribute( positionAttribute, i );
4810
+
4811
+ }
4803
4812
 
4804
- if ( precise && geometry.attributes !== undefined && geometry.attributes.position !== undefined ) {
4813
+ _vector$a.applyMatrix4( object.matrixWorld );
4814
+ this.expandByPoint( _vector$a );
4805
4815
 
4806
- const position = geometry.attributes.position;
4807
- for ( let i = 0, l = position.count; i < l; i ++ ) {
4816
+ }
4817
+
4818
+ } else {
4808
4819
 
4809
- _vector$a.fromBufferAttribute( position, i ).applyMatrix4( object.matrixWorld );
4810
- this.expandByPoint( _vector$a );
4820
+ if ( object.boundingBox !== undefined ) {
4821
+
4822
+ // object-level bounding box
4823
+
4824
+ if ( object.boundingBox === null ) {
4825
+
4826
+ object.computeBoundingBox();
4811
4827
 
4812
4828
  }
4813
4829
 
4830
+ _box$3.copy( object.boundingBox );
4831
+
4832
+
4814
4833
  } else {
4815
4834
 
4835
+ // geometry-level bounding box
4836
+
4816
4837
  if ( geometry.boundingBox === null ) {
4817
4838
 
4818
4839
  geometry.computeBoundingBox();
@@ -4820,12 +4841,13 @@ class Box3 {
4820
4841
  }
4821
4842
 
4822
4843
  _box$3.copy( geometry.boundingBox );
4823
- _box$3.applyMatrix4( object.matrixWorld );
4824
-
4825
- this.union( _box$3 );
4826
4844
 
4827
4845
  }
4828
4846
 
4847
+ _box$3.applyMatrix4( object.matrixWorld );
4848
+
4849
+ this.union( _box$3 );
4850
+
4829
4851
  }
4830
4852
 
4831
4853
  }
@@ -8421,1127 +8443,1140 @@ class Triangle {
8421
8443
 
8422
8444
  }
8423
8445
 
8424
- let _materialId = 0;
8446
+ const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
8447
+ 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
8448
+ 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
8449
+ 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
8450
+ 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
8451
+ 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
8452
+ 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
8453
+ 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
8454
+ 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
8455
+ 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
8456
+ 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
8457
+ 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
8458
+ 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
8459
+ 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
8460
+ 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
8461
+ 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
8462
+ 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
8463
+ 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
8464
+ 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
8465
+ 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
8466
+ 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
8467
+ 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
8468
+ 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
8469
+ 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
8425
8470
 
8426
- class Material extends EventDispatcher {
8471
+ const _hslA = { h: 0, s: 0, l: 0 };
8472
+ const _hslB = { h: 0, s: 0, l: 0 };
8427
8473
 
8428
- constructor() {
8474
+ function hue2rgb( p, q, t ) {
8429
8475
 
8430
- super();
8476
+ if ( t < 0 ) t += 1;
8477
+ if ( t > 1 ) t -= 1;
8478
+ if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
8479
+ if ( t < 1 / 2 ) return q;
8480
+ if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
8481
+ return p;
8431
8482
 
8432
- this.isMaterial = true;
8483
+ }
8433
8484
 
8434
- Object.defineProperty( this, 'id', { value: _materialId ++ } );
8485
+ class Color {
8435
8486
 
8436
- this.uuid = generateUUID();
8487
+ constructor( r, g, b ) {
8437
8488
 
8438
- this.name = '';
8439
- this.type = 'Material';
8489
+ this.isColor = true;
8440
8490
 
8441
- this.blending = NormalBlending;
8442
- this.side = FrontSide;
8443
- this.vertexColors = false;
8491
+ this.r = 1;
8492
+ this.g = 1;
8493
+ this.b = 1;
8444
8494
 
8445
- this.opacity = 1;
8446
- this.transparent = false;
8447
- this.alphaHash = false;
8495
+ return this.set( r, g, b );
8448
8496
 
8449
- this.blendSrc = SrcAlphaFactor;
8450
- this.blendDst = OneMinusSrcAlphaFactor;
8451
- this.blendEquation = AddEquation;
8452
- this.blendSrcAlpha = null;
8453
- this.blendDstAlpha = null;
8454
- this.blendEquationAlpha = null;
8497
+ }
8455
8498
 
8456
- this.depthFunc = LessEqualDepth;
8457
- this.depthTest = true;
8458
- this.depthWrite = true;
8499
+ set( r, g, b ) {
8459
8500
 
8460
- this.stencilWriteMask = 0xff;
8461
- this.stencilFunc = AlwaysStencilFunc;
8462
- this.stencilRef = 0;
8463
- this.stencilFuncMask = 0xff;
8464
- this.stencilFail = KeepStencilOp;
8465
- this.stencilZFail = KeepStencilOp;
8466
- this.stencilZPass = KeepStencilOp;
8467
- this.stencilWrite = false;
8501
+ if ( g === undefined && b === undefined ) {
8468
8502
 
8469
- this.clippingPlanes = null;
8470
- this.clipIntersection = false;
8471
- this.clipShadows = false;
8503
+ // r is THREE.Color, hex or string
8472
8504
 
8473
- this.shadowSide = null;
8505
+ const value = r;
8474
8506
 
8475
- this.colorWrite = true;
8507
+ if ( value && value.isColor ) {
8476
8508
 
8477
- this.precision = null; // override the renderer's default precision for this material
8509
+ this.copy( value );
8478
8510
 
8479
- this.polygonOffset = false;
8480
- this.polygonOffsetFactor = 0;
8481
- this.polygonOffsetUnits = 0;
8511
+ } else if ( typeof value === 'number' ) {
8482
8512
 
8483
- this.dithering = false;
8513
+ this.setHex( value );
8484
8514
 
8485
- this.alphaToCoverage = false;
8486
- this.premultipliedAlpha = false;
8487
- this.forceSinglePass = false;
8515
+ } else if ( typeof value === 'string' ) {
8488
8516
 
8489
- this.visible = true;
8517
+ this.setStyle( value );
8490
8518
 
8491
- this.toneMapped = true;
8519
+ }
8492
8520
 
8493
- this.userData = {};
8521
+ } else {
8494
8522
 
8495
- this.version = 0;
8523
+ this.setRGB( r, g, b );
8496
8524
 
8497
- this._alphaTest = 0;
8525
+ }
8526
+
8527
+ return this;
8498
8528
 
8499
8529
  }
8500
8530
 
8501
- get alphaTest() {
8531
+ setScalar( scalar ) {
8502
8532
 
8503
- return this._alphaTest;
8533
+ this.r = scalar;
8534
+ this.g = scalar;
8535
+ this.b = scalar;
8536
+
8537
+ return this;
8504
8538
 
8505
8539
  }
8506
8540
 
8507
- set alphaTest( value ) {
8541
+ setHex( hex, colorSpace = SRGBColorSpace ) {
8508
8542
 
8509
- if ( this._alphaTest > 0 !== value > 0 ) {
8543
+ hex = Math.floor( hex );
8510
8544
 
8511
- this.version ++;
8545
+ this.r = ( hex >> 16 & 255 ) / 255;
8546
+ this.g = ( hex >> 8 & 255 ) / 255;
8547
+ this.b = ( hex & 255 ) / 255;
8512
8548
 
8513
- }
8549
+ ColorManagement.toWorkingColorSpace( this, colorSpace );
8514
8550
 
8515
- this._alphaTest = value;
8551
+ return this;
8516
8552
 
8517
8553
  }
8518
8554
 
8519
- onBuild( /* shaderobject, renderer */ ) {}
8520
-
8521
- onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {}
8555
+ setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) {
8522
8556
 
8523
- onBeforeCompile( /* shaderobject, renderer */ ) {}
8557
+ this.r = r;
8558
+ this.g = g;
8559
+ this.b = b;
8524
8560
 
8525
- customProgramCacheKey() {
8561
+ ColorManagement.toWorkingColorSpace( this, colorSpace );
8526
8562
 
8527
- return this.onBeforeCompile.toString();
8563
+ return this;
8528
8564
 
8529
8565
  }
8530
8566
 
8531
- setValues( values ) {
8532
-
8533
- if ( values === undefined ) return;
8567
+ setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) {
8534
8568
 
8535
- for ( const key in values ) {
8569
+ // h,s,l ranges are in 0.0 - 1.0
8570
+ h = euclideanModulo( h, 1 );
8571
+ s = clamp( s, 0, 1 );
8572
+ l = clamp( l, 0, 1 );
8536
8573
 
8537
- const newValue = values[ key ];
8574
+ if ( s === 0 ) {
8538
8575
 
8539
- if ( newValue === undefined ) {
8576
+ this.r = this.g = this.b = l;
8540
8577
 
8541
- console.warn( `THREE.Material: parameter '${ key }' has value of undefined.` );
8542
- continue;
8578
+ } else {
8543
8579
 
8544
- }
8580
+ const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
8581
+ const q = ( 2 * l ) - p;
8545
8582
 
8546
- const currentValue = this[ key ];
8583
+ this.r = hue2rgb( q, p, h + 1 / 3 );
8584
+ this.g = hue2rgb( q, p, h );
8585
+ this.b = hue2rgb( q, p, h - 1 / 3 );
8547
8586
 
8548
- if ( currentValue === undefined ) {
8587
+ }
8549
8588
 
8550
- console.warn( `THREE.Material: '${ key }' is not a property of THREE.${ this.type }.` );
8551
- continue;
8589
+ ColorManagement.toWorkingColorSpace( this, colorSpace );
8552
8590
 
8553
- }
8591
+ return this;
8554
8592
 
8555
- if ( currentValue && currentValue.isColor ) {
8593
+ }
8556
8594
 
8557
- currentValue.set( newValue );
8595
+ setStyle( style, colorSpace = SRGBColorSpace ) {
8558
8596
 
8559
- } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
8597
+ function handleAlpha( string ) {
8560
8598
 
8561
- currentValue.copy( newValue );
8599
+ if ( string === undefined ) return;
8562
8600
 
8563
- } else {
8601
+ if ( parseFloat( string ) < 1 ) {
8564
8602
 
8565
- this[ key ] = newValue;
8603
+ console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
8566
8604
 
8567
8605
  }
8568
8606
 
8569
8607
  }
8570
8608
 
8571
- }
8572
8609
 
8573
- toJSON( meta ) {
8610
+ let m;
8574
8611
 
8575
- const isRootObject = ( meta === undefined || typeof meta === 'string' );
8612
+ if ( m = /^(\w+)\(([^\)]*)\)/.exec( style ) ) {
8576
8613
 
8577
- if ( isRootObject ) {
8614
+ // rgb / hsl
8578
8615
 
8579
- meta = {
8580
- textures: {},
8581
- images: {}
8582
- };
8616
+ let color;
8617
+ const name = m[ 1 ];
8618
+ const components = m[ 2 ];
8583
8619
 
8584
- }
8620
+ switch ( name ) {
8585
8621
 
8586
- const data = {
8587
- metadata: {
8588
- version: 4.6,
8589
- type: 'Material',
8590
- generator: 'Material.toJSON'
8591
- }
8592
- };
8622
+ case 'rgb':
8623
+ case 'rgba':
8593
8624
 
8594
- // standard Material serialization
8595
- data.uuid = this.uuid;
8596
- data.type = this.type;
8625
+ if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
8597
8626
 
8598
- if ( this.name !== '' ) data.name = this.name;
8627
+ // rgb(255,0,0) rgba(255,0,0,0.5)
8599
8628
 
8600
- if ( this.color && this.color.isColor ) data.color = this.color.getHex();
8629
+ handleAlpha( color[ 4 ] );
8601
8630
 
8602
- if ( this.roughness !== undefined ) data.roughness = this.roughness;
8603
- if ( this.metalness !== undefined ) data.metalness = this.metalness;
8631
+ return this.setRGB(
8632
+ Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255,
8633
+ Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255,
8634
+ Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255,
8635
+ colorSpace
8636
+ );
8604
8637
 
8605
- if ( this.sheen !== undefined ) data.sheen = this.sheen;
8606
- if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex();
8607
- if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness;
8608
- if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
8609
- if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;
8638
+ }
8610
8639
 
8611
- if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
8612
- if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity;
8613
- if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex();
8614
- if ( this.shininess !== undefined ) data.shininess = this.shininess;
8615
- if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat;
8616
- if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness;
8640
+ if ( color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
8617
8641
 
8618
- if ( this.clearcoatMap && this.clearcoatMap.isTexture ) {
8642
+ // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
8619
8643
 
8620
- data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid;
8644
+ handleAlpha( color[ 4 ] );
8621
8645
 
8622
- }
8646
+ return this.setRGB(
8647
+ Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100,
8648
+ Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100,
8649
+ Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100,
8650
+ colorSpace
8651
+ );
8623
8652
 
8624
- if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) {
8653
+ }
8625
8654
 
8626
- data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid;
8655
+ break;
8627
8656
 
8628
- }
8657
+ case 'hsl':
8658
+ case 'hsla':
8629
8659
 
8630
- if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) {
8660
+ if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
8631
8661
 
8632
- data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid;
8633
- data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
8662
+ // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
8634
8663
 
8635
- }
8664
+ handleAlpha( color[ 4 ] );
8636
8665
 
8637
- if ( this.iridescence !== undefined ) data.iridescence = this.iridescence;
8638
- if ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR;
8639
- if ( this.iridescenceThicknessRange !== undefined ) data.iridescenceThicknessRange = this.iridescenceThicknessRange;
8666
+ return this.setHSL(
8667
+ parseFloat( color[ 1 ] ) / 360,
8668
+ parseFloat( color[ 2 ] ) / 100,
8669
+ parseFloat( color[ 3 ] ) / 100,
8670
+ colorSpace
8671
+ );
8640
8672
 
8641
- if ( this.iridescenceMap && this.iridescenceMap.isTexture ) {
8673
+ }
8642
8674
 
8643
- data.iridescenceMap = this.iridescenceMap.toJSON( meta ).uuid;
8675
+ break;
8644
8676
 
8645
- }
8677
+ default:
8646
8678
 
8647
- if ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) {
8679
+ console.warn( 'THREE.Color: Unknown color model ' + style );
8648
8680
 
8649
- data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid;
8681
+ }
8650
8682
 
8651
- }
8683
+ } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) {
8652
8684
 
8653
- if ( this.anisotropy !== undefined ) data.anisotropy = this.anisotropy;
8654
- if ( this.anisotropyRotation !== undefined ) data.anisotropyRotation = this.anisotropyRotation;
8685
+ // hex color
8655
8686
 
8656
- if ( this.anisotropyMap && this.anisotropyMap.isTexture ) {
8687
+ const hex = m[ 1 ];
8688
+ const size = hex.length;
8657
8689
 
8658
- data.anisotropyMap = this.anisotropyMap.toJSON( meta ).uuid;
8690
+ if ( size === 3 ) {
8659
8691
 
8660
- }
8692
+ // #ff0
8693
+ return this.setRGB(
8694
+ parseInt( hex.charAt( 0 ), 16 ) / 15,
8695
+ parseInt( hex.charAt( 1 ), 16 ) / 15,
8696
+ parseInt( hex.charAt( 2 ), 16 ) / 15,
8697
+ colorSpace
8698
+ );
8661
8699
 
8662
- if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
8663
- if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid;
8664
- if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
8700
+ } else if ( size === 6 ) {
8665
8701
 
8666
- if ( this.lightMap && this.lightMap.isTexture ) {
8702
+ // #ff0000
8703
+ return this.setHex( parseInt( hex, 16 ), colorSpace );
8667
8704
 
8668
- data.lightMap = this.lightMap.toJSON( meta ).uuid;
8669
- data.lightMapIntensity = this.lightMapIntensity;
8705
+ } else {
8670
8706
 
8671
- }
8707
+ console.warn( 'THREE.Color: Invalid hex color ' + style );
8672
8708
 
8673
- if ( this.aoMap && this.aoMap.isTexture ) {
8709
+ }
8674
8710
 
8675
- data.aoMap = this.aoMap.toJSON( meta ).uuid;
8676
- data.aoMapIntensity = this.aoMapIntensity;
8711
+ } else if ( style && style.length > 0 ) {
8712
+
8713
+ return this.setColorName( style, colorSpace );
8677
8714
 
8678
8715
  }
8679
8716
 
8680
- if ( this.bumpMap && this.bumpMap.isTexture ) {
8717
+ return this;
8681
8718
 
8682
- data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
8683
- data.bumpScale = this.bumpScale;
8719
+ }
8684
8720
 
8685
- }
8721
+ setColorName( style, colorSpace = SRGBColorSpace ) {
8686
8722
 
8687
- if ( this.normalMap && this.normalMap.isTexture ) {
8723
+ // color keywords
8724
+ const hex = _colorKeywords[ style.toLowerCase() ];
8688
8725
 
8689
- data.normalMap = this.normalMap.toJSON( meta ).uuid;
8690
- data.normalMapType = this.normalMapType;
8691
- data.normalScale = this.normalScale.toArray();
8726
+ if ( hex !== undefined ) {
8692
8727
 
8693
- }
8728
+ // red
8729
+ this.setHex( hex, colorSpace );
8694
8730
 
8695
- if ( this.displacementMap && this.displacementMap.isTexture ) {
8731
+ } else {
8696
8732
 
8697
- data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
8698
- data.displacementScale = this.displacementScale;
8699
- data.displacementBias = this.displacementBias;
8733
+ // unknown color
8734
+ console.warn( 'THREE.Color: Unknown color ' + style );
8700
8735
 
8701
8736
  }
8702
8737
 
8703
- if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
8704
- if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
8738
+ return this;
8705
8739
 
8706
- if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
8707
- if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
8708
- if ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid;
8709
- if ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid;
8740
+ }
8710
8741
 
8711
- if ( this.envMap && this.envMap.isTexture ) {
8742
+ clone() {
8712
8743
 
8713
- data.envMap = this.envMap.toJSON( meta ).uuid;
8744
+ return new this.constructor( this.r, this.g, this.b );
8714
8745
 
8715
- if ( this.combine !== undefined ) data.combine = this.combine;
8746
+ }
8716
8747
 
8717
- }
8748
+ copy( color ) {
8718
8749
 
8719
- if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity;
8720
- if ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity;
8721
- if ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio;
8750
+ this.r = color.r;
8751
+ this.g = color.g;
8752
+ this.b = color.b;
8722
8753
 
8723
- if ( this.gradientMap && this.gradientMap.isTexture ) {
8754
+ return this;
8724
8755
 
8725
- data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
8756
+ }
8726
8757
 
8727
- }
8758
+ copySRGBToLinear( color ) {
8728
8759
 
8729
- if ( this.transmission !== undefined ) data.transmission = this.transmission;
8730
- if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid;
8731
- if ( this.thickness !== undefined ) data.thickness = this.thickness;
8732
- if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid;
8733
- if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance;
8734
- if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex();
8760
+ this.r = SRGBToLinear( color.r );
8761
+ this.g = SRGBToLinear( color.g );
8762
+ this.b = SRGBToLinear( color.b );
8735
8763
 
8736
- if ( this.size !== undefined ) data.size = this.size;
8737
- if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide;
8738
- if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
8764
+ return this;
8739
8765
 
8740
- if ( this.blending !== NormalBlending ) data.blending = this.blending;
8741
- if ( this.side !== FrontSide ) data.side = this.side;
8742
- if ( this.vertexColors === true ) data.vertexColors = true;
8766
+ }
8743
8767
 
8744
- if ( this.opacity < 1 ) data.opacity = this.opacity;
8745
- if ( this.transparent === true ) data.transparent = true;
8768
+ copyLinearToSRGB( color ) {
8746
8769
 
8747
- data.depthFunc = this.depthFunc;
8748
- data.depthTest = this.depthTest;
8749
- data.depthWrite = this.depthWrite;
8750
- data.colorWrite = this.colorWrite;
8770
+ this.r = LinearToSRGB( color.r );
8771
+ this.g = LinearToSRGB( color.g );
8772
+ this.b = LinearToSRGB( color.b );
8751
8773
 
8752
- data.stencilWrite = this.stencilWrite;
8753
- data.stencilWriteMask = this.stencilWriteMask;
8754
- data.stencilFunc = this.stencilFunc;
8755
- data.stencilRef = this.stencilRef;
8756
- data.stencilFuncMask = this.stencilFuncMask;
8757
- data.stencilFail = this.stencilFail;
8758
- data.stencilZFail = this.stencilZFail;
8759
- data.stencilZPass = this.stencilZPass;
8774
+ return this;
8760
8775
 
8761
- // rotation (SpriteMaterial)
8762
- if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation;
8776
+ }
8763
8777
 
8764
- if ( this.polygonOffset === true ) data.polygonOffset = true;
8765
- if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor;
8766
- if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits;
8778
+ convertSRGBToLinear() {
8767
8779
 
8768
- if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth;
8769
- if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
8770
- if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
8771
- if ( this.scale !== undefined ) data.scale = this.scale;
8780
+ this.copySRGBToLinear( this );
8772
8781
 
8773
- if ( this.dithering === true ) data.dithering = true;
8782
+ return this;
8774
8783
 
8775
- if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
8776
- if ( this.alphaHash === true ) data.alphaHash = true;
8777
- if ( this.alphaToCoverage === true ) data.alphaToCoverage = true;
8778
- if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = true;
8779
- if ( this.forceSinglePass === true ) data.forceSinglePass = true;
8784
+ }
8780
8785
 
8781
- if ( this.wireframe === true ) data.wireframe = true;
8782
- if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
8783
- if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
8784
- if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
8786
+ convertLinearToSRGB() {
8785
8787
 
8786
- if ( this.flatShading === true ) data.flatShading = true;
8788
+ this.copyLinearToSRGB( this );
8787
8789
 
8788
- if ( this.visible === false ) data.visible = false;
8790
+ return this;
8789
8791
 
8790
- if ( this.toneMapped === false ) data.toneMapped = false;
8792
+ }
8791
8793
 
8792
- if ( this.fog === false ) data.fog = false;
8794
+ getHex( colorSpace = SRGBColorSpace ) {
8793
8795
 
8794
- if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData;
8796
+ ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
8795
8797
 
8796
- // TODO: Copied from Object3D.toJSON
8798
+ return Math.round( clamp( _color.r * 255, 0, 255 ) ) * 65536 + Math.round( clamp( _color.g * 255, 0, 255 ) ) * 256 + Math.round( clamp( _color.b * 255, 0, 255 ) );
8797
8799
 
8798
- function extractFromCache( cache ) {
8800
+ }
8799
8801
 
8800
- const values = [];
8802
+ getHexString( colorSpace = SRGBColorSpace ) {
8801
8803
 
8802
- for ( const key in cache ) {
8804
+ return ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( - 6 );
8803
8805
 
8804
- const data = cache[ key ];
8805
- delete data.metadata;
8806
- values.push( data );
8806
+ }
8807
8807
 
8808
- }
8808
+ getHSL( target, colorSpace = ColorManagement.workingColorSpace ) {
8809
8809
 
8810
- return values;
8810
+ // h,s,l ranges are in 0.0 - 1.0
8811
8811
 
8812
- }
8812
+ ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
8813
8813
 
8814
- if ( isRootObject ) {
8814
+ const r = _color.r, g = _color.g, b = _color.b;
8815
8815
 
8816
- const textures = extractFromCache( meta.textures );
8817
- const images = extractFromCache( meta.images );
8816
+ const max = Math.max( r, g, b );
8817
+ const min = Math.min( r, g, b );
8818
8818
 
8819
- if ( textures.length > 0 ) data.textures = textures;
8820
- if ( images.length > 0 ) data.images = images;
8819
+ let hue, saturation;
8820
+ const lightness = ( min + max ) / 2.0;
8821
8821
 
8822
- }
8822
+ if ( min === max ) {
8823
8823
 
8824
- return data;
8824
+ hue = 0;
8825
+ saturation = 0;
8825
8826
 
8826
- }
8827
+ } else {
8827
8828
 
8828
- clone() {
8829
+ const delta = max - min;
8829
8830
 
8830
- return new this.constructor().copy( this );
8831
+ saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
8831
8832
 
8832
- }
8833
+ switch ( max ) {
8833
8834
 
8834
- copy( source ) {
8835
+ case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
8836
+ case g: hue = ( b - r ) / delta + 2; break;
8837
+ case b: hue = ( r - g ) / delta + 4; break;
8835
8838
 
8836
- this.name = source.name;
8839
+ }
8837
8840
 
8838
- this.blending = source.blending;
8839
- this.side = source.side;
8840
- this.vertexColors = source.vertexColors;
8841
+ hue /= 6;
8841
8842
 
8842
- this.opacity = source.opacity;
8843
- this.transparent = source.transparent;
8843
+ }
8844
8844
 
8845
- this.blendSrc = source.blendSrc;
8846
- this.blendDst = source.blendDst;
8847
- this.blendEquation = source.blendEquation;
8848
- this.blendSrcAlpha = source.blendSrcAlpha;
8849
- this.blendDstAlpha = source.blendDstAlpha;
8850
- this.blendEquationAlpha = source.blendEquationAlpha;
8845
+ target.h = hue;
8846
+ target.s = saturation;
8847
+ target.l = lightness;
8851
8848
 
8852
- this.depthFunc = source.depthFunc;
8853
- this.depthTest = source.depthTest;
8854
- this.depthWrite = source.depthWrite;
8849
+ return target;
8855
8850
 
8856
- this.stencilWriteMask = source.stencilWriteMask;
8857
- this.stencilFunc = source.stencilFunc;
8858
- this.stencilRef = source.stencilRef;
8859
- this.stencilFuncMask = source.stencilFuncMask;
8860
- this.stencilFail = source.stencilFail;
8861
- this.stencilZFail = source.stencilZFail;
8862
- this.stencilZPass = source.stencilZPass;
8863
- this.stencilWrite = source.stencilWrite;
8851
+ }
8864
8852
 
8865
- const srcPlanes = source.clippingPlanes;
8866
- let dstPlanes = null;
8853
+ getRGB( target, colorSpace = ColorManagement.workingColorSpace ) {
8867
8854
 
8868
- if ( srcPlanes !== null ) {
8855
+ ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
8869
8856
 
8870
- const n = srcPlanes.length;
8871
- dstPlanes = new Array( n );
8857
+ target.r = _color.r;
8858
+ target.g = _color.g;
8859
+ target.b = _color.b;
8872
8860
 
8873
- for ( let i = 0; i !== n; ++ i ) {
8861
+ return target;
8874
8862
 
8875
- dstPlanes[ i ] = srcPlanes[ i ].clone();
8863
+ }
8876
8864
 
8877
- }
8865
+ getStyle( colorSpace = SRGBColorSpace ) {
8878
8866
 
8879
- }
8867
+ ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
8880
8868
 
8881
- this.clippingPlanes = dstPlanes;
8882
- this.clipIntersection = source.clipIntersection;
8883
- this.clipShadows = source.clipShadows;
8869
+ const r = _color.r, g = _color.g, b = _color.b;
8884
8870
 
8885
- this.shadowSide = source.shadowSide;
8871
+ if ( colorSpace !== SRGBColorSpace ) {
8886
8872
 
8887
- this.colorWrite = source.colorWrite;
8873
+ // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/).
8874
+ return `color(${ colorSpace } ${ r.toFixed( 3 ) } ${ g.toFixed( 3 ) } ${ b.toFixed( 3 ) })`;
8888
8875
 
8889
- this.precision = source.precision;
8876
+ }
8890
8877
 
8891
- this.polygonOffset = source.polygonOffset;
8892
- this.polygonOffsetFactor = source.polygonOffsetFactor;
8893
- this.polygonOffsetUnits = source.polygonOffsetUnits;
8878
+ return `rgb(${ Math.round( r * 255 ) },${ Math.round( g * 255 ) },${ Math.round( b * 255 ) })`;
8894
8879
 
8895
- this.dithering = source.dithering;
8880
+ }
8896
8881
 
8897
- this.alphaTest = source.alphaTest;
8898
- this.alphaHash = source.alphaHash;
8899
- this.alphaToCoverage = source.alphaToCoverage;
8900
- this.premultipliedAlpha = source.premultipliedAlpha;
8901
- this.forceSinglePass = source.forceSinglePass;
8882
+ offsetHSL( h, s, l ) {
8902
8883
 
8903
- this.visible = source.visible;
8884
+ this.getHSL( _hslA );
8904
8885
 
8905
- this.toneMapped = source.toneMapped;
8886
+ return this.setHSL( _hslA.h + h, _hslA.s + s, _hslA.l + l );
8906
8887
 
8907
- this.userData = JSON.parse( JSON.stringify( source.userData ) );
8888
+ }
8889
+
8890
+ add( color ) {
8891
+
8892
+ this.r += color.r;
8893
+ this.g += color.g;
8894
+ this.b += color.b;
8908
8895
 
8909
8896
  return this;
8910
8897
 
8911
8898
  }
8912
8899
 
8913
- dispose() {
8900
+ addColors( color1, color2 ) {
8914
8901
 
8915
- this.dispatchEvent( { type: 'dispose' } );
8902
+ this.r = color1.r + color2.r;
8903
+ this.g = color1.g + color2.g;
8904
+ this.b = color1.b + color2.b;
8905
+
8906
+ return this;
8916
8907
 
8917
8908
  }
8918
8909
 
8919
- set needsUpdate( value ) {
8910
+ addScalar( s ) {
8920
8911
 
8921
- if ( value === true ) this.version ++;
8912
+ this.r += s;
8913
+ this.g += s;
8914
+ this.b += s;
8915
+
8916
+ return this;
8922
8917
 
8923
8918
  }
8924
8919
 
8925
- }
8920
+ sub( color ) {
8926
8921
 
8927
- const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
8928
- 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
8929
- 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
8930
- 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
8931
- 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
8932
- 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
8933
- 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
8934
- 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
8935
- 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
8936
- 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
8937
- 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
8938
- 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
8939
- 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
8940
- 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
8941
- 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
8942
- 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
8943
- 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
8944
- 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
8945
- 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
8946
- 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
8947
- 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
8948
- 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
8949
- 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
8950
- 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
8922
+ this.r = Math.max( 0, this.r - color.r );
8923
+ this.g = Math.max( 0, this.g - color.g );
8924
+ this.b = Math.max( 0, this.b - color.b );
8951
8925
 
8952
- const _hslA = { h: 0, s: 0, l: 0 };
8953
- const _hslB = { h: 0, s: 0, l: 0 };
8926
+ return this;
8954
8927
 
8955
- function hue2rgb( p, q, t ) {
8928
+ }
8956
8929
 
8957
- if ( t < 0 ) t += 1;
8958
- if ( t > 1 ) t -= 1;
8959
- if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
8960
- if ( t < 1 / 2 ) return q;
8961
- if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
8962
- return p;
8930
+ multiply( color ) {
8963
8931
 
8964
- }
8932
+ this.r *= color.r;
8933
+ this.g *= color.g;
8934
+ this.b *= color.b;
8965
8935
 
8966
- class Color {
8936
+ return this;
8967
8937
 
8968
- constructor( r, g, b ) {
8938
+ }
8969
8939
 
8970
- this.isColor = true;
8940
+ multiplyScalar( s ) {
8971
8941
 
8972
- this.r = 1;
8973
- this.g = 1;
8974
- this.b = 1;
8942
+ this.r *= s;
8943
+ this.g *= s;
8944
+ this.b *= s;
8975
8945
 
8976
- return this.set( r, g, b );
8946
+ return this;
8977
8947
 
8978
8948
  }
8979
8949
 
8980
- set( r, g, b ) {
8981
-
8982
- if ( g === undefined && b === undefined ) {
8983
-
8984
- // r is THREE.Color, hex or string
8950
+ lerp( color, alpha ) {
8985
8951
 
8986
- const value = r;
8952
+ this.r += ( color.r - this.r ) * alpha;
8953
+ this.g += ( color.g - this.g ) * alpha;
8954
+ this.b += ( color.b - this.b ) * alpha;
8987
8955
 
8988
- if ( value && value.isColor ) {
8956
+ return this;
8989
8957
 
8990
- this.copy( value );
8958
+ }
8991
8959
 
8992
- } else if ( typeof value === 'number' ) {
8960
+ lerpColors( color1, color2, alpha ) {
8993
8961
 
8994
- this.setHex( value );
8962
+ this.r = color1.r + ( color2.r - color1.r ) * alpha;
8963
+ this.g = color1.g + ( color2.g - color1.g ) * alpha;
8964
+ this.b = color1.b + ( color2.b - color1.b ) * alpha;
8995
8965
 
8996
- } else if ( typeof value === 'string' ) {
8966
+ return this;
8997
8967
 
8998
- this.setStyle( value );
8968
+ }
8999
8969
 
9000
- }
8970
+ lerpHSL( color, alpha ) {
9001
8971
 
9002
- } else {
8972
+ this.getHSL( _hslA );
8973
+ color.getHSL( _hslB );
9003
8974
 
9004
- this.setRGB( r, g, b );
8975
+ const h = lerp( _hslA.h, _hslB.h, alpha );
8976
+ const s = lerp( _hslA.s, _hslB.s, alpha );
8977
+ const l = lerp( _hslA.l, _hslB.l, alpha );
9005
8978
 
9006
- }
8979
+ this.setHSL( h, s, l );
9007
8980
 
9008
8981
  return this;
9009
8982
 
9010
8983
  }
9011
8984
 
9012
- setScalar( scalar ) {
8985
+ setFromVector3( v ) {
9013
8986
 
9014
- this.r = scalar;
9015
- this.g = scalar;
9016
- this.b = scalar;
8987
+ this.r = v.x;
8988
+ this.g = v.y;
8989
+ this.b = v.z;
9017
8990
 
9018
8991
  return this;
9019
8992
 
9020
8993
  }
9021
8994
 
9022
- setHex( hex, colorSpace = SRGBColorSpace ) {
9023
-
9024
- hex = Math.floor( hex );
8995
+ applyMatrix3( m ) {
9025
8996
 
9026
- this.r = ( hex >> 16 & 255 ) / 255;
9027
- this.g = ( hex >> 8 & 255 ) / 255;
9028
- this.b = ( hex & 255 ) / 255;
8997
+ const r = this.r, g = this.g, b = this.b;
8998
+ const e = m.elements;
9029
8999
 
9030
- ColorManagement.toWorkingColorSpace( this, colorSpace );
9000
+ this.r = e[ 0 ] * r + e[ 3 ] * g + e[ 6 ] * b;
9001
+ this.g = e[ 1 ] * r + e[ 4 ] * g + e[ 7 ] * b;
9002
+ this.b = e[ 2 ] * r + e[ 5 ] * g + e[ 8 ] * b;
9031
9003
 
9032
9004
  return this;
9033
9005
 
9034
9006
  }
9035
9007
 
9036
- setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) {
9037
-
9038
- this.r = r;
9039
- this.g = g;
9040
- this.b = b;
9041
-
9042
- ColorManagement.toWorkingColorSpace( this, colorSpace );
9008
+ equals( c ) {
9043
9009
 
9044
- return this;
9010
+ return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
9045
9011
 
9046
9012
  }
9047
9013
 
9048
- setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) {
9014
+ fromArray( array, offset = 0 ) {
9049
9015
 
9050
- // h,s,l ranges are in 0.0 - 1.0
9051
- h = euclideanModulo( h, 1 );
9052
- s = clamp( s, 0, 1 );
9053
- l = clamp( l, 0, 1 );
9016
+ this.r = array[ offset ];
9017
+ this.g = array[ offset + 1 ];
9018
+ this.b = array[ offset + 2 ];
9054
9019
 
9055
- if ( s === 0 ) {
9020
+ return this;
9056
9021
 
9057
- this.r = this.g = this.b = l;
9022
+ }
9058
9023
 
9059
- } else {
9024
+ toArray( array = [], offset = 0 ) {
9060
9025
 
9061
- const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
9062
- const q = ( 2 * l ) - p;
9026
+ array[ offset ] = this.r;
9027
+ array[ offset + 1 ] = this.g;
9028
+ array[ offset + 2 ] = this.b;
9063
9029
 
9064
- this.r = hue2rgb( q, p, h + 1 / 3 );
9065
- this.g = hue2rgb( q, p, h );
9066
- this.b = hue2rgb( q, p, h - 1 / 3 );
9030
+ return array;
9067
9031
 
9068
- }
9032
+ }
9069
9033
 
9070
- ColorManagement.toWorkingColorSpace( this, colorSpace );
9034
+ fromBufferAttribute( attribute, index ) {
9035
+
9036
+ this.r = attribute.getX( index );
9037
+ this.g = attribute.getY( index );
9038
+ this.b = attribute.getZ( index );
9071
9039
 
9072
9040
  return this;
9073
9041
 
9074
9042
  }
9075
9043
 
9076
- setStyle( style, colorSpace = SRGBColorSpace ) {
9044
+ toJSON() {
9077
9045
 
9078
- function handleAlpha( string ) {
9046
+ return this.getHex();
9079
9047
 
9080
- if ( string === undefined ) return;
9048
+ }
9081
9049
 
9082
- if ( parseFloat( string ) < 1 ) {
9050
+ *[ Symbol.iterator ]() {
9083
9051
 
9084
- console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
9052
+ yield this.r;
9053
+ yield this.g;
9054
+ yield this.b;
9085
9055
 
9086
- }
9056
+ }
9087
9057
 
9088
- }
9058
+ }
9089
9059
 
9060
+ const _color = /*@__PURE__*/ new Color();
9090
9061
 
9091
- let m;
9062
+ Color.NAMES = _colorKeywords;
9092
9063
 
9093
- if ( m = /^(\w+)\(([^\)]*)\)/.exec( style ) ) {
9064
+ let _materialId = 0;
9094
9065
 
9095
- // rgb / hsl
9066
+ class Material extends EventDispatcher {
9096
9067
 
9097
- let color;
9098
- const name = m[ 1 ];
9099
- const components = m[ 2 ];
9068
+ constructor() {
9100
9069
 
9101
- switch ( name ) {
9070
+ super();
9102
9071
 
9103
- case 'rgb':
9104
- case 'rgba':
9072
+ this.isMaterial = true;
9105
9073
 
9106
- if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
9074
+ Object.defineProperty( this, 'id', { value: _materialId ++ } );
9107
9075
 
9108
- // rgb(255,0,0) rgba(255,0,0,0.5)
9076
+ this.uuid = generateUUID();
9109
9077
 
9110
- handleAlpha( color[ 4 ] );
9078
+ this.name = '';
9079
+ this.type = 'Material';
9111
9080
 
9112
- return this.setRGB(
9113
- Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255,
9114
- Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255,
9115
- Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255,
9116
- colorSpace
9117
- );
9081
+ this.blending = NormalBlending;
9082
+ this.side = FrontSide;
9083
+ this.vertexColors = false;
9118
9084
 
9119
- }
9085
+ this.opacity = 1;
9086
+ this.transparent = false;
9087
+ this.alphaHash = false;
9120
9088
 
9121
- if ( color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
9089
+ this.blendSrc = SrcAlphaFactor;
9090
+ this.blendDst = OneMinusSrcAlphaFactor;
9091
+ this.blendEquation = AddEquation;
9092
+ this.blendSrcAlpha = null;
9093
+ this.blendDstAlpha = null;
9094
+ this.blendEquationAlpha = null;
9095
+ this.blendColor = new Color( 0, 0, 0 );
9096
+ this.blendAlpha = 0;
9122
9097
 
9123
- // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
9098
+ this.depthFunc = LessEqualDepth;
9099
+ this.depthTest = true;
9100
+ this.depthWrite = true;
9124
9101
 
9125
- handleAlpha( color[ 4 ] );
9102
+ this.stencilWriteMask = 0xff;
9103
+ this.stencilFunc = AlwaysStencilFunc;
9104
+ this.stencilRef = 0;
9105
+ this.stencilFuncMask = 0xff;
9106
+ this.stencilFail = KeepStencilOp;
9107
+ this.stencilZFail = KeepStencilOp;
9108
+ this.stencilZPass = KeepStencilOp;
9109
+ this.stencilWrite = false;
9126
9110
 
9127
- return this.setRGB(
9128
- Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100,
9129
- Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100,
9130
- Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100,
9131
- colorSpace
9132
- );
9111
+ this.clippingPlanes = null;
9112
+ this.clipIntersection = false;
9113
+ this.clipShadows = false;
9133
9114
 
9134
- }
9115
+ this.shadowSide = null;
9135
9116
 
9136
- break;
9117
+ this.colorWrite = true;
9137
9118
 
9138
- case 'hsl':
9139
- case 'hsla':
9119
+ this.precision = null; // override the renderer's default precision for this material
9140
9120
 
9141
- if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
9121
+ this.polygonOffset = false;
9122
+ this.polygonOffsetFactor = 0;
9123
+ this.polygonOffsetUnits = 0;
9142
9124
 
9143
- // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
9125
+ this.dithering = false;
9144
9126
 
9145
- handleAlpha( color[ 4 ] );
9127
+ this.alphaToCoverage = false;
9128
+ this.premultipliedAlpha = false;
9129
+ this.forceSinglePass = false;
9146
9130
 
9147
- return this.setHSL(
9148
- parseFloat( color[ 1 ] ) / 360,
9149
- parseFloat( color[ 2 ] ) / 100,
9150
- parseFloat( color[ 3 ] ) / 100,
9151
- colorSpace
9152
- );
9131
+ this.visible = true;
9153
9132
 
9154
- }
9133
+ this.toneMapped = true;
9155
9134
 
9156
- break;
9135
+ this.userData = {};
9157
9136
 
9158
- default:
9137
+ this.version = 0;
9159
9138
 
9160
- console.warn( 'THREE.Color: Unknown color model ' + style );
9139
+ this._alphaTest = 0;
9161
9140
 
9162
- }
9141
+ }
9163
9142
 
9164
- } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) {
9143
+ get alphaTest() {
9165
9144
 
9166
- // hex color
9145
+ return this._alphaTest;
9167
9146
 
9168
- const hex = m[ 1 ];
9169
- const size = hex.length;
9147
+ }
9170
9148
 
9171
- if ( size === 3 ) {
9149
+ set alphaTest( value ) {
9172
9150
 
9173
- // #ff0
9174
- return this.setRGB(
9175
- parseInt( hex.charAt( 0 ), 16 ) / 15,
9176
- parseInt( hex.charAt( 1 ), 16 ) / 15,
9177
- parseInt( hex.charAt( 2 ), 16 ) / 15,
9178
- colorSpace
9179
- );
9151
+ if ( this._alphaTest > 0 !== value > 0 ) {
9180
9152
 
9181
- } else if ( size === 6 ) {
9153
+ this.version ++;
9182
9154
 
9183
- // #ff0000
9184
- return this.setHex( parseInt( hex, 16 ), colorSpace );
9155
+ }
9185
9156
 
9186
- } else {
9157
+ this._alphaTest = value;
9187
9158
 
9188
- console.warn( 'THREE.Color: Invalid hex color ' + style );
9159
+ }
9189
9160
 
9190
- }
9161
+ onBuild( /* shaderobject, renderer */ ) {}
9191
9162
 
9192
- } else if ( style && style.length > 0 ) {
9163
+ onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {}
9193
9164
 
9194
- return this.setColorName( style, colorSpace );
9165
+ onBeforeCompile( /* shaderobject, renderer */ ) {}
9195
9166
 
9196
- }
9167
+ customProgramCacheKey() {
9197
9168
 
9198
- return this;
9169
+ return this.onBeforeCompile.toString();
9199
9170
 
9200
9171
  }
9201
9172
 
9202
- setColorName( style, colorSpace = SRGBColorSpace ) {
9173
+ setValues( values ) {
9203
9174
 
9204
- // color keywords
9205
- const hex = _colorKeywords[ style.toLowerCase() ];
9175
+ if ( values === undefined ) return;
9206
9176
 
9207
- if ( hex !== undefined ) {
9177
+ for ( const key in values ) {
9208
9178
 
9209
- // red
9210
- this.setHex( hex, colorSpace );
9179
+ const newValue = values[ key ];
9211
9180
 
9212
- } else {
9181
+ if ( newValue === undefined ) {
9213
9182
 
9214
- // unknown color
9215
- console.warn( 'THREE.Color: Unknown color ' + style );
9183
+ console.warn( `THREE.Material: parameter '${ key }' has value of undefined.` );
9184
+ continue;
9216
9185
 
9217
- }
9186
+ }
9218
9187
 
9219
- return this;
9188
+ const currentValue = this[ key ];
9220
9189
 
9221
- }
9190
+ if ( currentValue === undefined ) {
9222
9191
 
9223
- clone() {
9192
+ console.warn( `THREE.Material: '${ key }' is not a property of THREE.${ this.type }.` );
9193
+ continue;
9224
9194
 
9225
- return new this.constructor( this.r, this.g, this.b );
9195
+ }
9226
9196
 
9227
- }
9197
+ if ( currentValue && currentValue.isColor ) {
9228
9198
 
9229
- copy( color ) {
9199
+ currentValue.set( newValue );
9230
9200
 
9231
- this.r = color.r;
9232
- this.g = color.g;
9233
- this.b = color.b;
9201
+ } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
9234
9202
 
9235
- return this;
9203
+ currentValue.copy( newValue );
9236
9204
 
9237
- }
9205
+ } else {
9238
9206
 
9239
- copySRGBToLinear( color ) {
9207
+ this[ key ] = newValue;
9240
9208
 
9241
- this.r = SRGBToLinear( color.r );
9242
- this.g = SRGBToLinear( color.g );
9243
- this.b = SRGBToLinear( color.b );
9209
+ }
9244
9210
 
9245
- return this;
9211
+ }
9246
9212
 
9247
9213
  }
9248
9214
 
9249
- copyLinearToSRGB( color ) {
9215
+ toJSON( meta ) {
9250
9216
 
9251
- this.r = LinearToSRGB( color.r );
9252
- this.g = LinearToSRGB( color.g );
9253
- this.b = LinearToSRGB( color.b );
9217
+ const isRootObject = ( meta === undefined || typeof meta === 'string' );
9254
9218
 
9255
- return this;
9219
+ if ( isRootObject ) {
9256
9220
 
9257
- }
9221
+ meta = {
9222
+ textures: {},
9223
+ images: {}
9224
+ };
9258
9225
 
9259
- convertSRGBToLinear() {
9226
+ }
9260
9227
 
9261
- this.copySRGBToLinear( this );
9228
+ const data = {
9229
+ metadata: {
9230
+ version: 4.6,
9231
+ type: 'Material',
9232
+ generator: 'Material.toJSON'
9233
+ }
9234
+ };
9262
9235
 
9263
- return this;
9236
+ // standard Material serialization
9237
+ data.uuid = this.uuid;
9238
+ data.type = this.type;
9264
9239
 
9265
- }
9240
+ if ( this.name !== '' ) data.name = this.name;
9266
9241
 
9267
- convertLinearToSRGB() {
9242
+ if ( this.color && this.color.isColor ) data.color = this.color.getHex();
9268
9243
 
9269
- this.copyLinearToSRGB( this );
9244
+ if ( this.roughness !== undefined ) data.roughness = this.roughness;
9245
+ if ( this.metalness !== undefined ) data.metalness = this.metalness;
9270
9246
 
9271
- return this;
9247
+ if ( this.sheen !== undefined ) data.sheen = this.sheen;
9248
+ if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex();
9249
+ if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness;
9250
+ if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
9251
+ if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;
9272
9252
 
9273
- }
9253
+ if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
9254
+ if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity;
9255
+ if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex();
9256
+ if ( this.shininess !== undefined ) data.shininess = this.shininess;
9257
+ if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat;
9258
+ if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness;
9274
9259
 
9275
- getHex( colorSpace = SRGBColorSpace ) {
9260
+ if ( this.clearcoatMap && this.clearcoatMap.isTexture ) {
9276
9261
 
9277
- ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
9262
+ data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid;
9278
9263
 
9279
- return Math.round( clamp( _color.r * 255, 0, 255 ) ) * 65536 + Math.round( clamp( _color.g * 255, 0, 255 ) ) * 256 + Math.round( clamp( _color.b * 255, 0, 255 ) );
9264
+ }
9280
9265
 
9281
- }
9266
+ if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) {
9282
9267
 
9283
- getHexString( colorSpace = SRGBColorSpace ) {
9268
+ data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid;
9284
9269
 
9285
- return ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( - 6 );
9270
+ }
9286
9271
 
9287
- }
9272
+ if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) {
9288
9273
 
9289
- getHSL( target, colorSpace = ColorManagement.workingColorSpace ) {
9274
+ data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid;
9275
+ data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
9290
9276
 
9291
- // h,s,l ranges are in 0.0 - 1.0
9277
+ }
9292
9278
 
9293
- ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
9279
+ if ( this.iridescence !== undefined ) data.iridescence = this.iridescence;
9280
+ if ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR;
9281
+ if ( this.iridescenceThicknessRange !== undefined ) data.iridescenceThicknessRange = this.iridescenceThicknessRange;
9294
9282
 
9295
- const r = _color.r, g = _color.g, b = _color.b;
9283
+ if ( this.iridescenceMap && this.iridescenceMap.isTexture ) {
9296
9284
 
9297
- const max = Math.max( r, g, b );
9298
- const min = Math.min( r, g, b );
9285
+ data.iridescenceMap = this.iridescenceMap.toJSON( meta ).uuid;
9299
9286
 
9300
- let hue, saturation;
9301
- const lightness = ( min + max ) / 2.0;
9287
+ }
9302
9288
 
9303
- if ( min === max ) {
9289
+ if ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) {
9304
9290
 
9305
- hue = 0;
9306
- saturation = 0;
9291
+ data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid;
9307
9292
 
9308
- } else {
9293
+ }
9309
9294
 
9310
- const delta = max - min;
9295
+ if ( this.anisotropy !== undefined ) data.anisotropy = this.anisotropy;
9296
+ if ( this.anisotropyRotation !== undefined ) data.anisotropyRotation = this.anisotropyRotation;
9311
9297
 
9312
- saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
9298
+ if ( this.anisotropyMap && this.anisotropyMap.isTexture ) {
9313
9299
 
9314
- switch ( max ) {
9300
+ data.anisotropyMap = this.anisotropyMap.toJSON( meta ).uuid;
9315
9301
 
9316
- case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
9317
- case g: hue = ( b - r ) / delta + 2; break;
9318
- case b: hue = ( r - g ) / delta + 4; break;
9302
+ }
9319
9303
 
9320
- }
9304
+ if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
9305
+ if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid;
9306
+ if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
9321
9307
 
9322
- hue /= 6;
9308
+ if ( this.lightMap && this.lightMap.isTexture ) {
9309
+
9310
+ data.lightMap = this.lightMap.toJSON( meta ).uuid;
9311
+ data.lightMapIntensity = this.lightMapIntensity;
9323
9312
 
9324
9313
  }
9325
9314
 
9326
- target.h = hue;
9327
- target.s = saturation;
9328
- target.l = lightness;
9315
+ if ( this.aoMap && this.aoMap.isTexture ) {
9329
9316
 
9330
- return target;
9317
+ data.aoMap = this.aoMap.toJSON( meta ).uuid;
9318
+ data.aoMapIntensity = this.aoMapIntensity;
9331
9319
 
9332
- }
9320
+ }
9333
9321
 
9334
- getRGB( target, colorSpace = ColorManagement.workingColorSpace ) {
9322
+ if ( this.bumpMap && this.bumpMap.isTexture ) {
9335
9323
 
9336
- ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
9324
+ data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
9325
+ data.bumpScale = this.bumpScale;
9337
9326
 
9338
- target.r = _color.r;
9339
- target.g = _color.g;
9340
- target.b = _color.b;
9327
+ }
9341
9328
 
9342
- return target;
9329
+ if ( this.normalMap && this.normalMap.isTexture ) {
9343
9330
 
9344
- }
9331
+ data.normalMap = this.normalMap.toJSON( meta ).uuid;
9332
+ data.normalMapType = this.normalMapType;
9333
+ data.normalScale = this.normalScale.toArray();
9345
9334
 
9346
- getStyle( colorSpace = SRGBColorSpace ) {
9335
+ }
9347
9336
 
9348
- ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
9337
+ if ( this.displacementMap && this.displacementMap.isTexture ) {
9349
9338
 
9350
- const r = _color.r, g = _color.g, b = _color.b;
9339
+ data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
9340
+ data.displacementScale = this.displacementScale;
9341
+ data.displacementBias = this.displacementBias;
9351
9342
 
9352
- if ( colorSpace !== SRGBColorSpace ) {
9343
+ }
9353
9344
 
9354
- // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/).
9355
- return `color(${ colorSpace } ${ r.toFixed( 3 ) } ${ g.toFixed( 3 ) } ${ b.toFixed( 3 ) })`;
9345
+ if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
9346
+ if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
9356
9347
 
9357
- }
9348
+ if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
9349
+ if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
9350
+ if ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid;
9351
+ if ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid;
9358
9352
 
9359
- return `rgb(${ Math.round( r * 255 ) },${ Math.round( g * 255 ) },${ Math.round( b * 255 ) })`;
9353
+ if ( this.envMap && this.envMap.isTexture ) {
9360
9354
 
9361
- }
9355
+ data.envMap = this.envMap.toJSON( meta ).uuid;
9362
9356
 
9363
- offsetHSL( h, s, l ) {
9357
+ if ( this.combine !== undefined ) data.combine = this.combine;
9364
9358
 
9365
- this.getHSL( _hslA );
9359
+ }
9366
9360
 
9367
- return this.setHSL( _hslA.h + h, _hslA.s + s, _hslA.l + l );
9361
+ if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity;
9362
+ if ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity;
9363
+ if ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio;
9368
9364
 
9369
- }
9365
+ if ( this.gradientMap && this.gradientMap.isTexture ) {
9370
9366
 
9371
- add( color ) {
9367
+ data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
9372
9368
 
9373
- this.r += color.r;
9374
- this.g += color.g;
9375
- this.b += color.b;
9369
+ }
9376
9370
 
9377
- return this;
9371
+ if ( this.transmission !== undefined ) data.transmission = this.transmission;
9372
+ if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid;
9373
+ if ( this.thickness !== undefined ) data.thickness = this.thickness;
9374
+ if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid;
9375
+ if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance;
9376
+ if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex();
9378
9377
 
9379
- }
9378
+ if ( this.size !== undefined ) data.size = this.size;
9379
+ if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide;
9380
+ if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
9380
9381
 
9381
- addColors( color1, color2 ) {
9382
+ if ( this.blending !== NormalBlending ) data.blending = this.blending;
9383
+ if ( this.side !== FrontSide ) data.side = this.side;
9384
+ if ( this.vertexColors === true ) data.vertexColors = true;
9382
9385
 
9383
- this.r = color1.r + color2.r;
9384
- this.g = color1.g + color2.g;
9385
- this.b = color1.b + color2.b;
9386
+ if ( this.opacity < 1 ) data.opacity = this.opacity;
9387
+ if ( this.transparent === true ) data.transparent = true;
9386
9388
 
9387
- return this;
9389
+ if ( this.blendSrc !== SrcAlphaFactor ) data.blendSrc = this.blendSrc;
9390
+ if ( this.blendDst !== OneMinusSrcAlphaFactor ) data.blendDst = this.blendDst;
9391
+ if ( this.blendEquation !== AddEquation ) data.blendEquation = this.blendEquation;
9392
+ if ( this.blendSrcAlpha !== null ) data.blendSrcAlpha = this.blendSrcAlpha;
9393
+ if ( this.blendDstAlpha !== null ) data.blendDstAlpha = this.blendDstAlpha;
9394
+ if ( this.blendEquationAlpha !== null ) data.blendEquationAlpha = this.blendEquationAlpha;
9395
+ if ( this.blendColor && this.blendColor.isColor ) data.blendColor = this.blendColor.getHex();
9396
+ if ( this.blendAlpha !== 0 ) data.blendAlpha = this.blendAlpha;
9397
+
9398
+ if ( this.depthFunc !== LessEqualDepth ) data.depthFunc = this.depthFunc;
9399
+ if ( this.depthTest === false ) data.depthTest = this.depthTest;
9400
+ if ( this.depthWrite === false ) data.depthWrite = this.depthWrite;
9401
+ if ( this.colorWrite === false ) data.colorWrite = this.colorWrite;
9402
+
9403
+ if ( this.stencilWriteMask !== 0xff ) data.stencilWriteMask = this.stencilWriteMask;
9404
+ if ( this.stencilFunc !== AlwaysStencilFunc ) data.stencilFunc = this.stencilFunc;
9405
+ if ( this.stencilRef !== 0 ) data.stencilRef = this.stencilRef;
9406
+ if ( this.stencilFuncMask !== 0xff ) data.stencilFuncMask = this.stencilFuncMask;
9407
+ if ( this.stencilFail !== KeepStencilOp ) data.stencilFail = this.stencilFail;
9408
+ if ( this.stencilZFail !== KeepStencilOp ) data.stencilZFail = this.stencilZFail;
9409
+ if ( this.stencilZPass !== KeepStencilOp ) data.stencilZPass = this.stencilZPass;
9410
+ if ( this.stencilWrite === true ) data.stencilWrite = this.stencilWrite;
9388
9411
 
9389
- }
9412
+ // rotation (SpriteMaterial)
9413
+ if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation;
9390
9414
 
9391
- addScalar( s ) {
9415
+ if ( this.polygonOffset === true ) data.polygonOffset = true;
9416
+ if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor;
9417
+ if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits;
9392
9418
 
9393
- this.r += s;
9394
- this.g += s;
9395
- this.b += s;
9419
+ if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth;
9420
+ if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
9421
+ if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
9422
+ if ( this.scale !== undefined ) data.scale = this.scale;
9396
9423
 
9397
- return this;
9424
+ if ( this.dithering === true ) data.dithering = true;
9398
9425
 
9399
- }
9426
+ if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
9427
+ if ( this.alphaHash === true ) data.alphaHash = true;
9428
+ if ( this.alphaToCoverage === true ) data.alphaToCoverage = true;
9429
+ if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = true;
9430
+ if ( this.forceSinglePass === true ) data.forceSinglePass = true;
9400
9431
 
9401
- sub( color ) {
9432
+ if ( this.wireframe === true ) data.wireframe = true;
9433
+ if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
9434
+ if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
9435
+ if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
9402
9436
 
9403
- this.r = Math.max( 0, this.r - color.r );
9404
- this.g = Math.max( 0, this.g - color.g );
9405
- this.b = Math.max( 0, this.b - color.b );
9437
+ if ( this.flatShading === true ) data.flatShading = true;
9406
9438
 
9407
- return this;
9439
+ if ( this.visible === false ) data.visible = false;
9408
9440
 
9409
- }
9441
+ if ( this.toneMapped === false ) data.toneMapped = false;
9410
9442
 
9411
- multiply( color ) {
9443
+ if ( this.fog === false ) data.fog = false;
9412
9444
 
9413
- this.r *= color.r;
9414
- this.g *= color.g;
9415
- this.b *= color.b;
9445
+ if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData;
9416
9446
 
9417
- return this;
9447
+ // TODO: Copied from Object3D.toJSON
9418
9448
 
9419
- }
9449
+ function extractFromCache( cache ) {
9420
9450
 
9421
- multiplyScalar( s ) {
9451
+ const values = [];
9422
9452
 
9423
- this.r *= s;
9424
- this.g *= s;
9425
- this.b *= s;
9453
+ for ( const key in cache ) {
9426
9454
 
9427
- return this;
9455
+ const data = cache[ key ];
9456
+ delete data.metadata;
9457
+ values.push( data );
9428
9458
 
9429
- }
9459
+ }
9430
9460
 
9431
- lerp( color, alpha ) {
9461
+ return values;
9432
9462
 
9433
- this.r += ( color.r - this.r ) * alpha;
9434
- this.g += ( color.g - this.g ) * alpha;
9435
- this.b += ( color.b - this.b ) * alpha;
9463
+ }
9436
9464
 
9437
- return this;
9465
+ if ( isRootObject ) {
9438
9466
 
9439
- }
9467
+ const textures = extractFromCache( meta.textures );
9468
+ const images = extractFromCache( meta.images );
9440
9469
 
9441
- lerpColors( color1, color2, alpha ) {
9470
+ if ( textures.length > 0 ) data.textures = textures;
9471
+ if ( images.length > 0 ) data.images = images;
9442
9472
 
9443
- this.r = color1.r + ( color2.r - color1.r ) * alpha;
9444
- this.g = color1.g + ( color2.g - color1.g ) * alpha;
9445
- this.b = color1.b + ( color2.b - color1.b ) * alpha;
9473
+ }
9446
9474
 
9447
- return this;
9475
+ return data;
9448
9476
 
9449
9477
  }
9450
9478
 
9451
- lerpHSL( color, alpha ) {
9452
-
9453
- this.getHSL( _hslA );
9454
- color.getHSL( _hslB );
9479
+ clone() {
9455
9480
 
9456
- const h = lerp( _hslA.h, _hslB.h, alpha );
9457
- const s = lerp( _hslA.s, _hslB.s, alpha );
9458
- const l = lerp( _hslA.l, _hslB.l, alpha );
9481
+ return new this.constructor().copy( this );
9459
9482
 
9460
- this.setHSL( h, s, l );
9483
+ }
9461
9484
 
9462
- return this;
9485
+ copy( source ) {
9463
9486
 
9464
- }
9487
+ this.name = source.name;
9465
9488
 
9466
- setFromVector3( v ) {
9489
+ this.blending = source.blending;
9490
+ this.side = source.side;
9491
+ this.vertexColors = source.vertexColors;
9467
9492
 
9468
- this.r = v.x;
9469
- this.g = v.y;
9470
- this.b = v.z;
9493
+ this.opacity = source.opacity;
9494
+ this.transparent = source.transparent;
9471
9495
 
9472
- return this;
9496
+ this.blendSrc = source.blendSrc;
9497
+ this.blendDst = source.blendDst;
9498
+ this.blendEquation = source.blendEquation;
9499
+ this.blendSrcAlpha = source.blendSrcAlpha;
9500
+ this.blendDstAlpha = source.blendDstAlpha;
9501
+ this.blendEquationAlpha = source.blendEquationAlpha;
9502
+ this.blendColor.copy( source.blendColor );
9503
+ this.blendAlpha = source.blendAlpha;
9473
9504
 
9474
- }
9505
+ this.depthFunc = source.depthFunc;
9506
+ this.depthTest = source.depthTest;
9507
+ this.depthWrite = source.depthWrite;
9475
9508
 
9476
- applyMatrix3( m ) {
9509
+ this.stencilWriteMask = source.stencilWriteMask;
9510
+ this.stencilFunc = source.stencilFunc;
9511
+ this.stencilRef = source.stencilRef;
9512
+ this.stencilFuncMask = source.stencilFuncMask;
9513
+ this.stencilFail = source.stencilFail;
9514
+ this.stencilZFail = source.stencilZFail;
9515
+ this.stencilZPass = source.stencilZPass;
9516
+ this.stencilWrite = source.stencilWrite;
9477
9517
 
9478
- const r = this.r, g = this.g, b = this.b;
9479
- const e = m.elements;
9518
+ const srcPlanes = source.clippingPlanes;
9519
+ let dstPlanes = null;
9480
9520
 
9481
- this.r = e[ 0 ] * r + e[ 3 ] * g + e[ 6 ] * b;
9482
- this.g = e[ 1 ] * r + e[ 4 ] * g + e[ 7 ] * b;
9483
- this.b = e[ 2 ] * r + e[ 5 ] * g + e[ 8 ] * b;
9521
+ if ( srcPlanes !== null ) {
9484
9522
 
9485
- return this;
9523
+ const n = srcPlanes.length;
9524
+ dstPlanes = new Array( n );
9486
9525
 
9487
- }
9526
+ for ( let i = 0; i !== n; ++ i ) {
9488
9527
 
9489
- equals( c ) {
9528
+ dstPlanes[ i ] = srcPlanes[ i ].clone();
9490
9529
 
9491
- return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
9530
+ }
9492
9531
 
9493
- }
9532
+ }
9494
9533
 
9495
- fromArray( array, offset = 0 ) {
9534
+ this.clippingPlanes = dstPlanes;
9535
+ this.clipIntersection = source.clipIntersection;
9536
+ this.clipShadows = source.clipShadows;
9496
9537
 
9497
- this.r = array[ offset ];
9498
- this.g = array[ offset + 1 ];
9499
- this.b = array[ offset + 2 ];
9538
+ this.shadowSide = source.shadowSide;
9500
9539
 
9501
- return this;
9540
+ this.colorWrite = source.colorWrite;
9502
9541
 
9503
- }
9542
+ this.precision = source.precision;
9504
9543
 
9505
- toArray( array = [], offset = 0 ) {
9544
+ this.polygonOffset = source.polygonOffset;
9545
+ this.polygonOffsetFactor = source.polygonOffsetFactor;
9546
+ this.polygonOffsetUnits = source.polygonOffsetUnits;
9506
9547
 
9507
- array[ offset ] = this.r;
9508
- array[ offset + 1 ] = this.g;
9509
- array[ offset + 2 ] = this.b;
9548
+ this.dithering = source.dithering;
9510
9549
 
9511
- return array;
9550
+ this.alphaTest = source.alphaTest;
9551
+ this.alphaHash = source.alphaHash;
9552
+ this.alphaToCoverage = source.alphaToCoverage;
9553
+ this.premultipliedAlpha = source.premultipliedAlpha;
9554
+ this.forceSinglePass = source.forceSinglePass;
9512
9555
 
9513
- }
9556
+ this.visible = source.visible;
9514
9557
 
9515
- fromBufferAttribute( attribute, index ) {
9558
+ this.toneMapped = source.toneMapped;
9516
9559
 
9517
- this.r = attribute.getX( index );
9518
- this.g = attribute.getY( index );
9519
- this.b = attribute.getZ( index );
9560
+ this.userData = JSON.parse( JSON.stringify( source.userData ) );
9520
9561
 
9521
9562
  return this;
9522
9563
 
9523
9564
  }
9524
9565
 
9525
- toJSON() {
9566
+ dispose() {
9526
9567
 
9527
- return this.getHex();
9568
+ this.dispatchEvent( { type: 'dispose' } );
9528
9569
 
9529
9570
  }
9530
9571
 
9531
- *[ Symbol.iterator ]() {
9572
+ set needsUpdate( value ) {
9532
9573
 
9533
- yield this.r;
9534
- yield this.g;
9535
- yield this.b;
9574
+ if ( value === true ) this.version ++;
9536
9575
 
9537
9576
  }
9538
9577
 
9539
9578
  }
9540
9579
 
9541
- const _color = /*@__PURE__*/ new Color();
9542
-
9543
- Color.NAMES = _colorKeywords;
9544
-
9545
9580
  class MeshBasicMaterial extends Material {
9546
9581
 
9547
9582
  constructor( parameters ) {
@@ -13704,7 +13739,7 @@ var alphatest_fragment = "#ifdef USE_ALPHATEST\n\tif ( diffuseColor.a < alphaTes
13704
13739
 
13705
13740
  var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif";
13706
13741
 
13707
- var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\t#endif\n#endif";
13742
+ var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_CLEARCOAT ) \n\t\tclearcoatSpecularIndirect *= ambientOcclusion;\n\t#endif\n\t#if defined( USE_SHEEN ) \n\t\tsheenSpecularIndirect *= ambientOcclusion;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\t#endif\n#endif";
13708
13743
 
13709
13744
  var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
13710
13745
 
@@ -13716,7 +13751,7 @@ var bsdfs = "float G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnP
13716
13751
 
13717
13752
  var iridescence_fragment = "#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660, 0.0556434,\n\t\t-1.5371385, 1.8760108, -0.2040259,\n\t\t-0.4985314, 0.0415560, 1.0572252\n\t);\n\tvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n\t\tvec3 sqrtF0 = sqrt( fresnel0 );\n\t\treturn ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n\t}\n\tvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n\t}\n\tfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n\t}\n\tvec3 evalSensitivity( float OPD, vec3 shift ) {\n\t\tfloat phase = 2.0 * PI * OPD * 1.0e-9;\n\t\tvec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n\t\tvec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n\t\tvec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n\t\tvec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );\n\t\txyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n\t\txyz /= 1.0685e-7;\n\t\tvec3 rgb = XYZ_TO_REC709 * xyz;\n\t\treturn rgb;\n\t}\n\tvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n\t\tvec3 I;\n\t\tfloat iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n\t\tfloat sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n\t\tfloat cosTheta2Sq = 1.0 - sinTheta2Sq;\n\t\tif ( cosTheta2Sq < 0.0 ) {\n\t\t\treturn vec3( 1.0 );\n\t\t}\n\t\tfloat cosTheta2 = sqrt( cosTheta2Sq );\n\t\tfloat R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n\t\tfloat R12 = F_Schlick( R0, 1.0, cosTheta1 );\n\t\tfloat T121 = 1.0 - R12;\n\t\tfloat phi12 = 0.0;\n\t\tif ( iridescenceIOR < outsideIOR ) phi12 = PI;\n\t\tfloat phi21 = PI - phi12;\n\t\tvec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) );\t\tvec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n\t\tvec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n\t\tvec3 phi23 = vec3( 0.0 );\n\t\tif ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;\n\t\tif ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;\n\t\tif ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;\n\t\tfloat OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n\t\tvec3 phi = vec3( phi21 ) + phi23;\n\t\tvec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n\t\tvec3 r123 = sqrt( R123 );\n\t\tvec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n\t\tvec3 C0 = R12 + Rs;\n\t\tI = C0;\n\t\tvec3 Cm = Rs - T121;\n\t\tfor ( int m = 1; m <= 2; ++ m ) {\n\t\t\tCm *= r123;\n\t\t\tvec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n\t\t\tI += Cm * Sm;\n\t\t}\n\t\treturn max( I, vec3( 0.0 ) );\n\t}\n#endif";
13718
13753
 
13719
- 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 = dFdx( surf_pos.xyz );\n\t\tvec3 vSigmaY = 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";
13754
+ 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";
13720
13755
 
13721
13756
  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";
13722
13757
 
@@ -13794,9 +13829,9 @@ var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhong
13794
13829
 
13795
13830
  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";
13796
13831
 
13797
- 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 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = 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\tclearcoatSpecular += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += 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\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += 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}";
13832
+ 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}";
13798
13833
 
13799
- var lights_fragment_begin = "\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal;\n#ifdef USE_CLEARCOAT\n\tgeometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if defined( USE_LIGHT_PROBES )\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
13834
+ var lights_fragment_begin = "\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n\tgeometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if defined( USE_LIGHT_PROBES )\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
13800
13835
 
13801
13836
  var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometryNormal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\t#ifdef USE_ANISOTROPY\n\t\tradiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n\t#else\n\t\tradiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif";
13802
13837
 
@@ -13952,7 +13987,7 @@ const fragment$6 = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;
13952
13987
 
13953
13988
  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}";
13954
13989
 
13955
- 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 + sheenSpecular;\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 ) + clearcoatSpecular * 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}";
13990
+ 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}";
13956
13991
 
13957
13992
  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}";
13958
13993
 
@@ -14747,7 +14782,7 @@ function WebGLBackground( renderer, cubemaps, cubeuvmaps, state, objects, alpha,
14747
14782
  if ( boxMesh === undefined ) {
14748
14783
 
14749
14784
  boxMesh = new Mesh(
14750
- new BoxGeometry( 1, 1, 1 ),
14785
+ new BoxGeometry( 10000, 10000, 10000 ),
14751
14786
  new ShaderMaterial( {
14752
14787
  name: 'BackgroundCubeMaterial',
14753
14788
  uniforms: cloneUniforms( ShaderLib.backgroundCube.uniforms ),
@@ -16127,6 +16162,8 @@ const MAX_SAMPLES = 20;
16127
16162
  const _flatCamera = /*@__PURE__*/ new OrthographicCamera();
16128
16163
  const _clearColor = /*@__PURE__*/ new Color();
16129
16164
  let _oldTarget = null;
16165
+ let _oldActiveCubeFace = 0;
16166
+ let _oldActiveMipmapLevel = 0;
16130
16167
 
16131
16168
  // Golden Ratio
16132
16169
  const PHI = ( 1 + Math.sqrt( 5 ) ) / 2;
@@ -16192,6 +16229,8 @@ class PMREMGenerator {
16192
16229
  fromScene( scene, sigma = 0, near = 0.1, far = 100 ) {
16193
16230
 
16194
16231
  _oldTarget = this._renderer.getRenderTarget();
16232
+ _oldActiveCubeFace = this._renderer.getActiveCubeFace();
16233
+ _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel();
16195
16234
 
16196
16235
  this._setSize( 256 );
16197
16236
 
@@ -16304,7 +16343,7 @@ class PMREMGenerator {
16304
16343
 
16305
16344
  _cleanup( outputTarget ) {
16306
16345
 
16307
- this._renderer.setRenderTarget( _oldTarget );
16346
+ this._renderer.setRenderTarget( _oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel );
16308
16347
  outputTarget.scissorTest = false;
16309
16348
  _setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height );
16310
16349
 
@@ -16323,6 +16362,8 @@ class PMREMGenerator {
16323
16362
  }
16324
16363
 
16325
16364
  _oldTarget = this._renderer.getRenderTarget();
16365
+ _oldActiveCubeFace = this._renderer.getActiveCubeFace();
16366
+ _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel();
16326
16367
 
16327
16368
  const cubeUVRenderTarget = renderTarget || this._allocateTargets();
16328
16369
  this._textureToCubeUV( texture, cubeUVRenderTarget );
@@ -17843,6 +17884,103 @@ function WebGLMorphtargets( gl, capabilities, textures ) {
17843
17884
 
17844
17885
  }
17845
17886
 
17887
+ /**
17888
+ * @author fernandojsg / http://fernandojsg.com
17889
+ * @author Takahiro https://github.com/takahirox
17890
+ */
17891
+
17892
+ class WebGLMultiview {
17893
+
17894
+ constructor( renderer, extensions, gl ) {
17895
+
17896
+ this.renderer = renderer;
17897
+
17898
+ this.DEFAULT_NUMVIEWS = 2;
17899
+ this.maxNumViews = 0;
17900
+ this.gl = gl;
17901
+
17902
+ this.extensions = extensions;
17903
+
17904
+ this.available = this.extensions.has( 'OCULUS_multiview' );
17905
+
17906
+ if ( this.available ) {
17907
+
17908
+ const extension = this.extensions.get( 'OCULUS_multiview' );
17909
+
17910
+ this.maxNumViews = this.gl.getParameter( extension.MAX_VIEWS_OVR );
17911
+
17912
+ this.mat4 = [];
17913
+ this.mat3 = [];
17914
+ this.cameraArray = [];
17915
+
17916
+ for ( var i = 0; i < this.maxNumViews; i ++ ) {
17917
+
17918
+ this.mat4[ i ] = new Matrix4();
17919
+ this.mat3[ i ] = new Matrix3();
17920
+
17921
+ }
17922
+
17923
+ }
17924
+
17925
+ }
17926
+
17927
+ //
17928
+ getCameraArray( camera ) {
17929
+
17930
+ if ( camera.isArrayCamera ) return camera.cameras;
17931
+
17932
+ this.cameraArray[ 0 ] = camera;
17933
+
17934
+ return this.cameraArray;
17935
+
17936
+ }
17937
+
17938
+ updateCameraProjectionMatricesUniform( camera, uniforms ) {
17939
+
17940
+ var cameras = this.getCameraArray( camera );
17941
+
17942
+ for ( var i = 0; i < cameras.length; i ++ ) {
17943
+
17944
+ this.mat4[ i ].copy( cameras[ i ].projectionMatrix );
17945
+
17946
+ }
17947
+
17948
+ uniforms.setValue( this.gl, 'projectionMatrices', this.mat4 );
17949
+
17950
+ }
17951
+
17952
+ updateCameraViewMatricesUniform( camera, uniforms ) {
17953
+
17954
+ var cameras = this.getCameraArray( camera );
17955
+
17956
+ for ( var i = 0; i < cameras.length; i ++ ) {
17957
+
17958
+ this.mat4[ i ].copy( cameras[ i ].matrixWorldInverse );
17959
+
17960
+ }
17961
+
17962
+ uniforms.setValue( this.gl, 'viewMatrices', this.mat4 );
17963
+
17964
+ }
17965
+
17966
+ updateObjectMatricesUniforms( object, camera, uniforms ) {
17967
+
17968
+ var cameras = this.getCameraArray( camera );
17969
+
17970
+ for ( var i = 0; i < cameras.length; i ++ ) {
17971
+
17972
+ this.mat4[ i ].multiplyMatrices( cameras[ i ].matrixWorldInverse, object.matrixWorld );
17973
+ this.mat3[ i ].getNormalMatrix( this.mat4[ i ] );
17974
+
17975
+ }
17976
+
17977
+ uniforms.setValue( this.gl, 'modelViewMatrices', this.mat4 );
17978
+ uniforms.setValue( this.gl, 'normalMatrices', this.mat3 );
17979
+
17980
+ }
17981
+
17982
+ }
17983
+
17846
17984
  function WebGLObjects( gl, geometries, attributes, info ) {
17847
17985
 
17848
17986
  let updateMap = new WeakMap();
@@ -19085,6 +19223,9 @@ function WebGLShader( gl, type, string ) {
19085
19223
 
19086
19224
  }
19087
19225
 
19226
+ // From https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/
19227
+ const COMPLETION_STATUS_KHR = 0x91B1;
19228
+
19088
19229
  let programIdCount = 0;
19089
19230
 
19090
19231
  function handleSource( string, errorLine ) {
@@ -19536,6 +19677,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19536
19677
  let prefixVertex, prefixFragment;
19537
19678
  let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : '';
19538
19679
 
19680
+ const numMultiviewViews = parameters.numMultiviewViews;
19681
+
19539
19682
  if ( parameters.isRawShaderMaterial ) {
19540
19683
 
19541
19684
  prefixVertex = [
@@ -19927,6 +20070,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19927
20070
  ].join( '\n' ) + '\n' + prefixVertex;
19928
20071
 
19929
20072
  prefixFragment = [
20073
+ 'precision mediump sampler2DArray;',
19930
20074
  '#define varying in',
19931
20075
  ( parameters.glslVersion === GLSL3 ) ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;',
19932
20076
  ( parameters.glslVersion === GLSL3 ) ? '' : '#define gl_FragColor pc_fragColor',
@@ -19942,6 +20086,53 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19942
20086
  '#define textureCubeGradEXT textureGrad'
19943
20087
  ].join( '\n' ) + '\n' + prefixFragment;
19944
20088
 
20089
+ // Multiview
20090
+
20091
+ if ( numMultiviewViews > 0 ) {
20092
+
20093
+ // TODO: fix light transforms here?
20094
+
20095
+ prefixVertex = [
20096
+ '#extension GL_OVR_multiview : require',
20097
+ 'layout(num_views = ' + numMultiviewViews + ') in;',
20098
+ '#define VIEW_ID gl_ViewID_OVR'
20099
+ ].join( '\n' ) + '\n' + prefixVertex;
20100
+
20101
+ prefixVertex = prefixVertex.replace(
20102
+ [
20103
+ 'uniform mat4 modelViewMatrix;',
20104
+ 'uniform mat4 projectionMatrix;',
20105
+ 'uniform mat4 viewMatrix;',
20106
+ 'uniform mat3 normalMatrix;'
20107
+ ].join( '\n' ),
20108
+ [
20109
+ 'uniform mat4 modelViewMatrices[' + numMultiviewViews + '];',
20110
+ 'uniform mat4 projectionMatrices[' + numMultiviewViews + '];',
20111
+ 'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
20112
+ 'uniform mat3 normalMatrices[' + numMultiviewViews + '];',
20113
+
20114
+ '#define modelViewMatrix modelViewMatrices[VIEW_ID]',
20115
+ '#define projectionMatrix projectionMatrices[VIEW_ID]',
20116
+ '#define viewMatrix viewMatrices[VIEW_ID]',
20117
+ '#define normalMatrix normalMatrices[VIEW_ID]'
20118
+ ].join( '\n' )
20119
+ );
20120
+
20121
+ prefixFragment = [
20122
+ '#extension GL_OVR_multiview : require',
20123
+ '#define VIEW_ID gl_ViewID_OVR'
20124
+ ].join( '\n' ) + '\n' + prefixFragment;
20125
+
20126
+ prefixFragment = prefixFragment.replace(
20127
+ 'uniform mat4 viewMatrix;',
20128
+ [
20129
+ 'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
20130
+ '#define viewMatrix viewMatrices[VIEW_ID]'
20131
+ ].join( '\n' )
20132
+ );
20133
+
20134
+ }
20135
+
19945
20136
  }
19946
20137
 
19947
20138
  const vertexGlsl = versionString + prefixVertex + vertexShader;
@@ -19971,87 +20162,94 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19971
20162
 
19972
20163
  gl.linkProgram( program );
19973
20164
 
19974
- // check for link errors
19975
- if ( renderer.debug.checkShaderErrors ) {
20165
+ function onFirstUse( self ) {
19976
20166
 
19977
- const programLog = gl.getProgramInfoLog( program ).trim();
19978
- const vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
19979
- const fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
20167
+ // check for link errors
20168
+ if ( renderer.debug.checkShaderErrors ) {
19980
20169
 
19981
- let runnable = true;
19982
- let haveDiagnostics = true;
20170
+ const programLog = gl.getProgramInfoLog( program ).trim();
20171
+ const vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
20172
+ const fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
19983
20173
 
19984
- if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
20174
+ let runnable = true;
20175
+ let haveDiagnostics = true;
19985
20176
 
19986
- runnable = false;
20177
+ if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
19987
20178
 
19988
- if ( typeof renderer.debug.onShaderError === 'function' ) {
20179
+ runnable = false;
19989
20180
 
19990
- renderer.debug.onShaderError( gl, program, glVertexShader, glFragmentShader );
20181
+ if ( typeof renderer.debug.onShaderError === 'function' ) {
19991
20182
 
19992
- } else {
20183
+ renderer.debug.onShaderError( gl, program, glVertexShader, glFragmentShader );
19993
20184
 
19994
- // default error reporting
20185
+ } else {
19995
20186
 
19996
- const vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
19997
- const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
20187
+ // default error reporting
19998
20188
 
19999
- console.error(
20000
- 'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' +
20001
- 'VALIDATE_STATUS ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) + '\n\n' +
20002
- 'Program Info Log: ' + programLog + '\n' +
20003
- vertexErrors + '\n' +
20004
- fragmentErrors
20005
- );
20189
+ const vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
20190
+ const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
20006
20191
 
20007
- }
20192
+ console.error(
20193
+ 'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' +
20194
+ 'VALIDATE_STATUS ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) + '\n\n' +
20195
+ 'Program Info Log: ' + programLog + '\n' +
20196
+ vertexErrors + '\n' +
20197
+ fragmentErrors
20198
+ );
20008
20199
 
20009
- } else if ( programLog !== '' ) {
20200
+ }
20010
20201
 
20011
- console.warn( 'THREE.WebGLProgram: Program Info Log:', programLog );
20202
+ } else if ( programLog !== '' ) {
20012
20203
 
20013
- } else if ( vertexLog === '' || fragmentLog === '' ) {
20204
+ console.warn( 'THREE.WebGLProgram: Program Info Log:', programLog );
20014
20205
 
20015
- haveDiagnostics = false;
20206
+ } else if ( vertexLog === '' || fragmentLog === '' ) {
20016
20207
 
20017
- }
20208
+ haveDiagnostics = false;
20018
20209
 
20019
- if ( haveDiagnostics ) {
20210
+ }
20020
20211
 
20021
- this.diagnostics = {
20212
+ if ( haveDiagnostics ) {
20022
20213
 
20023
- runnable: runnable,
20214
+ self.diagnostics = {
20024
20215
 
20025
- programLog: programLog,
20216
+ runnable: runnable,
20026
20217
 
20027
- vertexShader: {
20218
+ programLog: programLog,
20028
20219
 
20029
- log: vertexLog,
20030
- prefix: prefixVertex
20220
+ vertexShader: {
20031
20221
 
20032
- },
20222
+ log: vertexLog,
20223
+ prefix: prefixVertex
20033
20224
 
20034
- fragmentShader: {
20225
+ },
20035
20226
 
20036
- log: fragmentLog,
20037
- prefix: prefixFragment
20227
+ fragmentShader: {
20038
20228
 
20039
- }
20229
+ log: fragmentLog,
20230
+ prefix: prefixFragment
20040
20231
 
20041
- };
20232
+ }
20233
+
20234
+ };
20235
+
20236
+ }
20042
20237
 
20043
20238
  }
20044
20239
 
20045
- }
20240
+ // Clean up
20241
+
20242
+ // Crashes in iOS9 and iOS10. #18402
20243
+ // gl.detachShader( program, glVertexShader );
20244
+ // gl.detachShader( program, glFragmentShader );
20046
20245
 
20047
- // Clean up
20246
+ gl.deleteShader( glVertexShader );
20247
+ gl.deleteShader( glFragmentShader );
20048
20248
 
20049
- // Crashes in iOS9 and iOS10. #18402
20050
- // gl.detachShader( program, glVertexShader );
20051
- // gl.detachShader( program, glFragmentShader );
20249
+ cachedUniforms = new WebGLUniforms( gl, program );
20250
+ cachedAttributes = fetchAttributeLocations( gl, program );
20052
20251
 
20053
- gl.deleteShader( glVertexShader );
20054
- gl.deleteShader( glFragmentShader );
20252
+ }
20055
20253
 
20056
20254
  // set up caching for uniform locations
20057
20255
 
@@ -20061,7 +20259,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20061
20259
 
20062
20260
  if ( cachedUniforms === undefined ) {
20063
20261
 
20064
- cachedUniforms = new WebGLUniforms( gl, program );
20262
+ // Populates cachedUniforms and cachedAttributes
20263
+ onFirstUse( this );
20065
20264
 
20066
20265
  }
20067
20266
 
@@ -20077,7 +20276,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20077
20276
 
20078
20277
  if ( cachedAttributes === undefined ) {
20079
20278
 
20080
- cachedAttributes = fetchAttributeLocations( gl, program );
20279
+ // Populates cachedAttributes and cachedUniforms
20280
+ onFirstUse( this );
20081
20281
 
20082
20282
  }
20083
20283
 
@@ -20085,6 +20285,23 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20085
20285
 
20086
20286
  };
20087
20287
 
20288
+ // indicate when the program is ready to be used. if the KHR_parallel_shader_compile extension isn't supported,
20289
+ // flag the program as ready immediately. It may cause a stall when it's first used.
20290
+
20291
+ let programReady = ( parameters.rendererExtensionParallelShaderCompile === false );
20292
+
20293
+ this.isReady = function () {
20294
+
20295
+ if ( programReady === false ) {
20296
+
20297
+ programReady = gl.getProgramParameter( program, COMPLETION_STATUS_KHR );
20298
+
20299
+ }
20300
+
20301
+ return programReady;
20302
+
20303
+ };
20304
+
20088
20305
  // free resource
20089
20306
 
20090
20307
  this.destroy = function () {
@@ -20106,6 +20323,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20106
20323
  this.program = program;
20107
20324
  this.vertexShader = glVertexShader;
20108
20325
  this.fragmentShader = glFragmentShader;
20326
+ this.numMultiviewViews = numMultiviewViews;
20109
20327
 
20110
20328
  return this;
20111
20329
 
@@ -20335,6 +20553,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20335
20553
 
20336
20554
  const currentRenderTarget = renderer.getRenderTarget();
20337
20555
 
20556
+ const numMultiviewViews = currentRenderTarget && currentRenderTarget.isWebGLMultiviewRenderTarget ? currentRenderTarget.numViews : 0;
20557
+
20338
20558
  const IS_INSTANCEDMESH = object.isInstancedMesh === true;
20339
20559
 
20340
20560
  const HAS_MAP = !! material.map;
@@ -20425,6 +20645,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20425
20645
  instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null,
20426
20646
 
20427
20647
  supportsVertexTextures: SUPPORTS_VERTEX_TEXTURES,
20648
+ numMultiviewViews: numMultiviewViews,
20428
20649
  outputColorSpace: ( currentRenderTarget === null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace ),
20429
20650
 
20430
20651
  map: HAS_MAP,
@@ -20586,6 +20807,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20586
20807
  rendererExtensionFragDepth: IS_WEBGL2 || extensions.has( 'EXT_frag_depth' ),
20587
20808
  rendererExtensionDrawBuffers: IS_WEBGL2 || extensions.has( 'WEBGL_draw_buffers' ),
20588
20809
  rendererExtensionShaderTextureLod: IS_WEBGL2 || extensions.has( 'EXT_shader_texture_lod' ),
20810
+ rendererExtensionParallelShaderCompile: extensions.has( 'KHR_parallel_shader_compile' ),
20589
20811
 
20590
20812
  customProgramCacheKey: material.customProgramCacheKey()
20591
20813
 
@@ -20728,6 +20950,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20728
20950
  _programLayers.enable( 16 );
20729
20951
  if ( parameters.anisotropy )
20730
20952
  _programLayers.enable( 17 );
20953
+ if ( parameters.alphaHash )
20954
+ _programLayers.enable( 18 );
20731
20955
 
20732
20956
  array.push( _programLayers.mask );
20733
20957
  _programLayers.disableAll();
@@ -20772,6 +20996,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20772
20996
  _programLayers.enable( 18 );
20773
20997
  if ( parameters.decodeVideoTexture )
20774
20998
  _programLayers.enable( 19 );
20999
+ if ( parameters.numMultiviewViews )
21000
+ _programLayers.enable( 20 );
20775
21001
 
20776
21002
  array.push( _programLayers.mask );
20777
21003
 
@@ -22619,6 +22845,8 @@ function WebGLState( gl, extensions, capabilities ) {
22619
22845
  let currentBlendEquationAlpha = null;
22620
22846
  let currentBlendSrcAlpha = null;
22621
22847
  let currentBlendDstAlpha = null;
22848
+ let currentBlendColor = new Color( 0, 0, 0 );
22849
+ let currentBlendAlpha = 0;
22622
22850
  let currentPremultipledAlpha = false;
22623
22851
 
22624
22852
  let currentFlipSided = null;
@@ -22894,10 +23122,14 @@ function WebGLState( gl, extensions, capabilities ) {
22894
23122
  [ OneMinusSrcColorFactor ]: gl.ONE_MINUS_SRC_COLOR,
22895
23123
  [ OneMinusSrcAlphaFactor ]: gl.ONE_MINUS_SRC_ALPHA,
22896
23124
  [ OneMinusDstColorFactor ]: gl.ONE_MINUS_DST_COLOR,
22897
- [ OneMinusDstAlphaFactor ]: gl.ONE_MINUS_DST_ALPHA
23125
+ [ OneMinusDstAlphaFactor ]: gl.ONE_MINUS_DST_ALPHA,
23126
+ [ ConstantColorFactor ]: gl.CONSTANT_COLOR,
23127
+ [ OneMinusConstantColorFactor ]: gl.ONE_MINUS_CONSTANT_COLOR,
23128
+ [ ConstantAlphaFactor ]: gl.CONSTANT_ALPHA,
23129
+ [ OneMinusConstantAlphaFactor ]: gl.ONE_MINUS_CONSTANT_ALPHA
22898
23130
  };
22899
23131
 
22900
- function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
23132
+ function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, blendColor, blendAlpha, premultipliedAlpha ) {
22901
23133
 
22902
23134
  if ( blending === NoBlending ) {
22903
23135
 
@@ -22990,6 +23222,8 @@ function WebGLState( gl, extensions, capabilities ) {
22990
23222
  currentBlendDst = null;
22991
23223
  currentBlendSrcAlpha = null;
22992
23224
  currentBlendDstAlpha = null;
23225
+ currentBlendColor.set( 0, 0, 0 );
23226
+ currentBlendAlpha = 0;
22993
23227
 
22994
23228
  currentBlending = blending;
22995
23229
  currentPremultipledAlpha = premultipliedAlpha;
@@ -23026,6 +23260,15 @@ function WebGLState( gl, extensions, capabilities ) {
23026
23260
 
23027
23261
  }
23028
23262
 
23263
+ if ( blendColor.equals( currentBlendColor ) === false || blendAlpha !== currentBlendAlpha ) {
23264
+
23265
+ gl.blendColor( blendColor.r, blendColor.g, blendColor.b, blendAlpha );
23266
+
23267
+ currentBlendColor.copy( blendColor );
23268
+ currentBlendAlpha = blendAlpha;
23269
+
23270
+ }
23271
+
23029
23272
  currentBlending = blending;
23030
23273
  currentPremultipledAlpha = false;
23031
23274
 
@@ -23044,7 +23287,7 @@ function WebGLState( gl, extensions, capabilities ) {
23044
23287
 
23045
23288
  ( material.blending === NormalBlending && material.transparent === false )
23046
23289
  ? setBlending( NoBlending )
23047
- : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha );
23290
+ : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.blendColor, material.blendAlpha, material.premultipliedAlpha );
23048
23291
 
23049
23292
  depthBuffer.setFunc( material.depthFunc );
23050
23293
  depthBuffer.setTest( material.depthTest );
@@ -23468,6 +23711,7 @@ function WebGLState( gl, extensions, capabilities ) {
23468
23711
  gl.blendEquation( gl.FUNC_ADD );
23469
23712
  gl.blendFunc( gl.ONE, gl.ZERO );
23470
23713
  gl.blendFuncSeparate( gl.ONE, gl.ZERO, gl.ONE, gl.ZERO );
23714
+ gl.blendColor( 0, 0, 0, 0 );
23471
23715
 
23472
23716
  gl.colorMask( true, true, true, true );
23473
23717
  gl.clearColor( 0, 0, 0, 0 );
@@ -23525,6 +23769,8 @@ function WebGLState( gl, extensions, capabilities ) {
23525
23769
  currentBlendEquationAlpha = null;
23526
23770
  currentBlendSrcAlpha = null;
23527
23771
  currentBlendDstAlpha = null;
23772
+ currentBlendColor = new Color( 0, 0, 0 );
23773
+ currentBlendAlpha = 0;
23528
23774
  currentPremultipledAlpha = false;
23529
23775
 
23530
23776
  currentFlipSided = null;
@@ -23607,12 +23853,16 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
23607
23853
  const maxSamples = capabilities.maxSamples;
23608
23854
  const multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null;
23609
23855
  const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent );
23856
+ const multiviewExt = extensions.has( 'OCULUS_multiview' ) ? extensions.get( 'OCULUS_multiview' ) : null;
23610
23857
 
23611
23858
  const _videoTextures = new WeakMap();
23612
23859
  let _canvas;
23613
23860
 
23614
23861
  const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source
23615
23862
 
23863
+ let _deferredUploads = [];
23864
+ let _deferTextureUploads = false;
23865
+
23616
23866
  // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas,
23617
23867
  // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")!
23618
23868
  // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d).
@@ -24080,8 +24330,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24080
24330
 
24081
24331
  } else {
24082
24332
 
24083
- uploadTexture( textureProperties, texture, slot );
24084
- return;
24333
+ if ( uploadTexture( textureProperties, texture, slot ) ) {
24334
+
24335
+ return;
24336
+
24337
+ }
24085
24338
 
24086
24339
  }
24087
24340
 
@@ -24314,8 +24567,45 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24314
24567
 
24315
24568
  }
24316
24569
 
24570
+ function setDeferTextureUploads( deferFlag ) {
24571
+
24572
+ _deferTextureUploads = deferFlag;
24573
+
24574
+ }
24575
+
24576
+ function runDeferredUploads() {
24577
+
24578
+ const previousDeferSetting = _deferTextureUploads;
24579
+ _deferTextureUploads = false;
24580
+
24581
+ for ( const upload of _deferredUploads ) {
24582
+
24583
+ uploadTexture( upload.textureProperties, upload.texture, upload.slot );
24584
+ upload.texture.isPendingDeferredUpload = false;
24585
+
24586
+ }
24587
+
24588
+ _deferredUploads = [];
24589
+
24590
+ _deferTextureUploads = previousDeferSetting;
24591
+
24592
+ }
24593
+
24317
24594
  function uploadTexture( textureProperties, texture, slot ) {
24318
24595
 
24596
+ if ( _deferTextureUploads ) {
24597
+
24598
+ if ( ! texture.isPendingDeferredUpload ) {
24599
+
24600
+ texture.isPendingDeferredUpload = true;
24601
+ _deferredUploads.push( { textureProperties: textureProperties, texture: texture, slot: slot } );
24602
+
24603
+ }
24604
+
24605
+ return false;
24606
+
24607
+ }
24608
+
24319
24609
  let textureType = _gl.TEXTURE_2D;
24320
24610
 
24321
24611
  if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) textureType = _gl.TEXTURE_2D_ARRAY;
@@ -24732,6 +25022,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24732
25022
  }
24733
25023
 
24734
25024
  textureProperties.__version = texture.version;
25025
+ return true;
24735
25026
 
24736
25027
  }
24737
25028
 
@@ -24961,7 +25252,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24961
25252
  const width = Math.max( 1, renderTarget.width >> level );
24962
25253
  const height = Math.max( 1, renderTarget.height >> level );
24963
25254
 
24964
- if ( textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY ) {
25255
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25256
+
25257
+ state.texStorage3D( _gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.numViews );
25258
+
25259
+ } else if ( textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY ) {
24965
25260
 
24966
25261
  state.texImage3D( textureTarget, level, glInternalFormat, width, height, renderTarget.depth, 0, glFormat, glType, null );
24967
25262
 
@@ -24975,13 +25270,31 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24975
25270
 
24976
25271
  state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
24977
25272
 
24978
- if ( useMultisampledRTT( renderTarget ) ) {
25273
+ const multisampled = useMultisampledRTT( renderTarget );
25274
+
25275
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
24979
25276
 
24980
- multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) );
25277
+ if ( multisampled ) {
25278
+
25279
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ), 0, renderTarget.numViews );
25280
+
25281
+ } else {
25282
+
25283
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( texture ).__webglTexture, 0, 0, renderTarget.numViews );
25284
+
25285
+ }
24981
25286
 
24982
25287
  } else if ( textureTarget === _gl.TEXTURE_2D || ( textureTarget >= _gl.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= _gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ) ) { // see #24753
24983
25288
 
24984
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, level );
25289
+ if ( multisampled ) {
25290
+
25291
+ multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) );
25292
+
25293
+ } else {
25294
+
25295
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, level );
25296
+
25297
+ }
24985
25298
 
24986
25299
  }
24987
25300
 
@@ -24995,7 +25308,59 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24995
25308
 
24996
25309
  _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
24997
25310
 
24998
- if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
25311
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25312
+
25313
+ const useMultisample = useMultisampledRTT( renderTarget );
25314
+ const numViews = renderTarget.numViews;
25315
+
25316
+ const depthTexture = renderTarget.depthTexture;
25317
+ let glInternalFormat = _gl.DEPTH_COMPONENT24;
25318
+ let glDepthAttachment = _gl.DEPTH_ATTACHMENT;
25319
+
25320
+ if ( depthTexture && depthTexture.isDepthTexture ) {
25321
+
25322
+ if ( depthTexture.type === FloatType ) {
25323
+
25324
+ glInternalFormat = _gl.DEPTH_COMPONENT32F;
25325
+
25326
+ } else if ( depthTexture.type === UnsignedInt248Type ) {
25327
+
25328
+ glInternalFormat = _gl.DEPTH24_STENCIL8;
25329
+ glDepthAttachment = _gl.DEPTH_STENCIL_ATTACHMENT;
25330
+
25331
+ }
25332
+
25333
+ // we're defaulting to _gl.DEPTH_COMPONENT24 so don't assign here
25334
+ // or else DeepScan will complain
25335
+
25336
+ // else if ( depthTexture.type === UnsignedIntType ) {
25337
+
25338
+ // glInternalFormat = _gl.DEPTH_COMPONENT24;
25339
+
25340
+ // }
25341
+
25342
+ }
25343
+
25344
+ let depthStencilTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
25345
+ if ( depthStencilTexture === undefined ) {
25346
+
25347
+ depthStencilTexture = _gl.createTexture();
25348
+ _gl.bindTexture( _gl.TEXTURE_2D_ARRAY, depthStencilTexture );
25349
+ _gl.texStorage3D( _gl.TEXTURE_2D_ARRAY, 1, glInternalFormat, renderTarget.width, renderTarget.height, numViews );
25350
+
25351
+ }
25352
+
25353
+ if ( useMultisample ) {
25354
+
25355
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, glDepthAttachment, depthStencilTexture, 0, getRenderTargetSamples( renderTarget ), 0, numViews );
25356
+
25357
+ } else {
25358
+
25359
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, glDepthAttachment, depthStencilTexture, 0, 0, numViews );
25360
+
25361
+ }
25362
+
25363
+ } else if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
24999
25364
 
25000
25365
  let glInternalFormat = ( isWebGL2 === true ) ? _gl.DEPTH_COMPONENT24 : _gl.DEPTH_COMPONENT16;
25001
25366
 
@@ -25119,37 +25484,85 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25119
25484
  }
25120
25485
 
25121
25486
  setTexture2D( renderTarget.depthTexture, 0 );
25487
+ if ( renderTarget.depthTexture.image.depth != 1 ) {
25488
+
25489
+ setTexture2DArray( renderTarget.depthTexture, 0 );
25490
+
25491
+ } else {
25492
+
25493
+ setTexture2D( renderTarget.depthTexture, 0 );
25494
+
25495
+ }
25122
25496
 
25123
25497
  const webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
25124
25498
  const samples = getRenderTargetSamples( renderTarget );
25125
25499
 
25126
- if ( renderTarget.depthTexture.format === DepthFormat ) {
25500
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25127
25501
 
25128
- if ( useMultisampledRTT( renderTarget ) ) {
25502
+ const useMultisample = useMultisampledRTT( renderTarget );
25503
+ const numViews = renderTarget.numViews;
25129
25504
 
25130
- multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25505
+ if ( renderTarget.depthTexture.format === DepthFormat ) {
25131
25506
 
25132
- } else {
25507
+ if ( useMultisample ) {
25133
25508
 
25134
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25509
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, webglDepthTexture, 0, samples, 0, numViews );
25135
25510
 
25136
- }
25511
+ } else {
25512
+
25513
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, webglDepthTexture, 0, 0, numViews );
25514
+
25515
+ }
25137
25516
 
25138
- } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
25517
+ } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
25139
25518
 
25140
- if ( useMultisampledRTT( renderTarget ) ) {
25519
+ if ( useMultisample ) {
25141
25520
 
25142
- multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25521
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, webglDepthTexture, 0, samples, 0, numViews );
25522
+
25523
+ } else {
25524
+
25525
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, webglDepthTexture, 0, 0, numViews );
25526
+
25527
+ }
25143
25528
 
25144
25529
  } else {
25145
25530
 
25146
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25531
+ throw new Error( 'Unknown depthTexture format' );
25147
25532
 
25148
25533
  }
25149
25534
 
25150
25535
  } else {
25151
25536
 
25152
- throw new Error( 'Unknown depthTexture format' );
25537
+ if ( renderTarget.depthTexture.format === DepthFormat ) {
25538
+
25539
+ if ( useMultisampledRTT( renderTarget ) ) {
25540
+
25541
+ multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25542
+
25543
+ } else {
25544
+
25545
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25546
+
25547
+ }
25548
+
25549
+ } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
25550
+
25551
+ if ( useMultisampledRTT( renderTarget ) ) {
25552
+
25553
+ multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25554
+
25555
+ } else {
25556
+
25557
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25558
+
25559
+ }
25560
+
25561
+ } else {
25562
+
25563
+ throw new Error( 'Unknown depthTexture format' );
25564
+
25565
+ }
25153
25566
 
25154
25567
  }
25155
25568
 
@@ -25428,6 +25841,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25428
25841
 
25429
25842
  }
25430
25843
 
25844
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25845
+
25846
+ glTextureType = _gl.TEXTURE_2D_ARRAY;
25847
+
25848
+ }
25849
+
25431
25850
  state.bindTexture( glTextureType, textureProperties.__webglTexture );
25432
25851
  setTextureParameters( glTextureType, texture, supportsMips );
25433
25852
 
@@ -25457,9 +25876,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25457
25876
 
25458
25877
  // Setup depth and stencil buffers
25459
25878
 
25460
- if ( renderTarget.depthBuffer ) {
25879
+ if ( renderTarget.depthBuffer || renderTarget.isWebGLMultiviewRenderTarget === true ) {
25461
25880
 
25462
- setupDepthRenderbuffer( renderTarget );
25881
+ this.setupDepthRenderbuffer( renderTarget );
25463
25882
 
25464
25883
  }
25465
25884
 
@@ -25695,12 +26114,16 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25695
26114
  this.setTexture3D = setTexture3D;
25696
26115
  this.setTextureCube = setTextureCube;
25697
26116
  this.rebindTextures = rebindTextures;
26117
+ this.uploadTexture = uploadTexture;
25698
26118
  this.setupRenderTarget = setupRenderTarget;
25699
26119
  this.updateRenderTargetMipmap = updateRenderTargetMipmap;
25700
26120
  this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
26121
+ this.setupDepthTexture = setupDepthTexture;
25701
26122
  this.setupDepthRenderbuffer = setupDepthRenderbuffer;
25702
26123
  this.setupFrameBufferTexture = setupFrameBufferTexture;
25703
26124
  this.useMultisampledRTT = useMultisampledRTT;
26125
+ this.runDeferredUploads = runDeferredUploads;
26126
+ this.setDeferTextureUploads = setDeferTextureUploads;
25704
26127
 
25705
26128
  }
25706
26129
 
@@ -26557,6 +26980,39 @@ Object.assign( WebVRManager.prototype, {
26557
26980
  dispatchEvent: EventDispatcher.prototype.dispatchEvent
26558
26981
  } );
26559
26982
 
26983
+ /**
26984
+ * @author fernandojsg / http://fernandojsg.com
26985
+ * @author Takahiro https://github.com/takahirox
26986
+ */
26987
+
26988
+
26989
+ class WebGLMultiviewRenderTarget extends WebGLRenderTarget {
26990
+
26991
+ constructor( width, height, numViews, options = {} ) {
26992
+
26993
+ super( width, height, options );
26994
+
26995
+ this.depthBuffer = false;
26996
+ this.stencilBuffer = false;
26997
+
26998
+ this.numViews = numViews;
26999
+
27000
+ }
27001
+
27002
+ copy( source ) {
27003
+
27004
+ super.copy( source );
27005
+
27006
+ this.numViews = source.numViews;
27007
+
27008
+ return this;
27009
+
27010
+ }
27011
+
27012
+ }
27013
+
27014
+ WebGLMultiviewRenderTarget.prototype.isWebGLMultiviewRenderTarget = true;
27015
+
26560
27016
  const _moveEvent = { type: 'move' };
26561
27017
 
26562
27018
  class WebXRController {
@@ -26951,7 +27407,7 @@ class DepthTexture extends Texture {
26951
27407
 
26952
27408
  class WebXRManager extends EventDispatcher {
26953
27409
 
26954
- constructor( renderer, gl ) {
27410
+ constructor( renderer, gl, extensions, useMultiview ) {
26955
27411
 
26956
27412
  super();
26957
27413
 
@@ -27007,6 +27463,7 @@ class WebXRManager extends EventDispatcher {
27007
27463
  this.enabled = false;
27008
27464
 
27009
27465
  this.isPresenting = false;
27466
+ this.isMultiview = false;
27010
27467
 
27011
27468
  this.getCameraPose = function ( ) {
27012
27469
 
@@ -27250,29 +27707,51 @@ class WebXRManager extends EventDispatcher {
27250
27707
 
27251
27708
  }
27252
27709
 
27710
+ scope.isMultiview = useMultiview && extensions.has( 'OCULUS_multiview' );
27711
+
27253
27712
  const projectionlayerInit = {
27254
27713
  colorFormat: gl.RGBA8,
27255
27714
  depthFormat: glDepthFormat,
27256
27715
  scaleFactor: framebufferScaleFactor
27257
27716
  };
27258
27717
 
27718
+ if ( scope.isMultiview ) {
27719
+
27720
+ projectionlayerInit.textureType = 'texture-array';
27721
+
27722
+ }
27723
+
27259
27724
  glBinding = new XRWebGLBinding( session, gl );
27260
27725
 
27261
27726
  glProjLayer = glBinding.createProjectionLayer( projectionlayerInit );
27262
27727
 
27263
27728
  session.updateRenderState( { layers: [ glProjLayer ] } );
27264
27729
 
27265
- newRenderTarget = new WebGLRenderTarget(
27266
- glProjLayer.textureWidth,
27267
- glProjLayer.textureHeight,
27268
- {
27269
- format: RGBAFormat,
27270
- type: UnsignedByteType,
27271
- depthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ),
27272
- stencilBuffer: attributes.stencil,
27273
- colorSpace: renderer.outputColorSpace,
27274
- samples: attributes.antialias ? 4 : 0
27275
- } );
27730
+ const renderTargetOptions = {
27731
+ format: RGBAFormat,
27732
+ type: UnsignedByteType,
27733
+ depthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ),
27734
+ stencilBuffer: attributes.stencil,
27735
+ colorSpace: renderer.outputColorSpace,
27736
+ samples: attributes.antialias ? 4 : 0
27737
+ };
27738
+
27739
+ if ( scope.isMultiview ) {
27740
+
27741
+ const extension = extensions.get( 'OCULUS_multiview' );
27742
+
27743
+ this.maxNumViews = gl.getParameter( extension.MAX_VIEWS_OVR );
27744
+
27745
+ newRenderTarget = new WebGLMultiviewRenderTarget( glProjLayer.textureWidth, glProjLayer.textureHeight, 2, renderTargetOptions );
27746
+
27747
+ } else {
27748
+
27749
+ newRenderTarget = new WebGLRenderTarget(
27750
+ glProjLayer.textureWidth,
27751
+ glProjLayer.textureHeight,
27752
+ renderTargetOptions );
27753
+
27754
+ }
27276
27755
 
27277
27756
  const renderTargetProperties = renderer.properties.get( newRenderTarget );
27278
27757
  renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues;
@@ -28724,6 +29203,7 @@ class WebGLRenderer {
28724
29203
  preserveDrawingBuffer = false,
28725
29204
  powerPreference = 'default',
28726
29205
  failIfMajorPerformanceCaveat = false,
29206
+ multiviewStereo = false,
28727
29207
  } = parameters;
28728
29208
 
28729
29209
  this.isWebGLRenderer = true;
@@ -28958,6 +29438,7 @@ class WebGLRenderer {
28958
29438
  let extensions, capabilities, state, info;
28959
29439
  let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects;
28960
29440
  let programCache, materials, renderLists, renderStates, clipping, shadowMap;
29441
+ let multiview;
28961
29442
 
28962
29443
  let background, morphtargets, bufferRenderer, indexedBufferRenderer;
28963
29444
 
@@ -28991,6 +29472,7 @@ class WebGLRenderer {
28991
29472
  renderLists = new WebGLRenderLists();
28992
29473
  renderStates = new WebGLRenderStates( extensions, capabilities );
28993
29474
  background = new WebGLBackground( _this, cubemaps, cubeuvmaps, state, objects, _alpha, premultipliedAlpha );
29475
+ multiview = new WebGLMultiview( _this, extensions, _gl );
28994
29476
  shadowMap = new WebGLShadowMap( _this, objects, capabilities );
28995
29477
  uniformsGroups = new WebGLUniformsGroups( _gl, info, capabilities, state );
28996
29478
 
@@ -29013,7 +29495,7 @@ class WebGLRenderer {
29013
29495
 
29014
29496
  // xr
29015
29497
 
29016
- const xr = ( typeof navigator !== 'undefined' && 'xr' in navigator ) ? new WebXRManager( _this, _gl ) : new WebVRManager( _this );
29498
+ const xr = ( typeof navigator !== 'undefined' && 'xr' in navigator ) ? new WebXRManager( _this, _gl, extensions, multiviewStereo ) : new WebVRManager( _this );
29017
29499
 
29018
29500
  this.xr = xr;
29019
29501
 
@@ -29275,7 +29757,12 @@ class WebGLRenderer {
29275
29757
  }
29276
29758
 
29277
29759
  if ( depth ) bits |= _gl.DEPTH_BUFFER_BIT;
29278
- if ( stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
29760
+ if ( stencil ) {
29761
+
29762
+ bits |= _gl.STENCIL_BUFFER_BIT;
29763
+ this.state.buffers.stencil.setMask( 0xffffffff );
29764
+
29765
+ }
29279
29766
 
29280
29767
  _gl.clear( bits );
29281
29768
 
@@ -29558,36 +30045,40 @@ class WebGLRenderer {
29558
30045
 
29559
30046
  // Compile
29560
30047
 
29561
- this.compile = function ( scene, camera ) {
30048
+ function prepareMaterial( material, scene, object ) {
29562
30049
 
29563
- function prepare( material, scene, object ) {
30050
+ if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
29564
30051
 
29565
- if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
30052
+ material.side = BackSide;
30053
+ material.needsUpdate = true;
30054
+ getProgram( material, scene, object );
29566
30055
 
29567
- material.side = BackSide;
29568
- material.needsUpdate = true;
29569
- getProgram( material, scene, object );
30056
+ material.side = FrontSide;
30057
+ material.needsUpdate = true;
30058
+ getProgram( material, scene, object );
29570
30059
 
29571
- material.side = FrontSide;
29572
- material.needsUpdate = true;
29573
- getProgram( material, scene, object );
30060
+ material.side = DoubleSide;
30061
+
30062
+ } else {
29574
30063
 
29575
- material.side = DoubleSide;
30064
+ getProgram( material, scene, object );
29576
30065
 
29577
- } else {
30066
+ }
29578
30067
 
29579
- getProgram( material, scene, object );
30068
+ }
29580
30069
 
29581
- }
30070
+ this.compile = function ( scene, camera, targetScene = null ) {
29582
30071
 
29583
- }
30072
+ if ( targetScene === null ) targetScene = scene;
29584
30073
 
29585
- currentRenderState = renderStates.get( scene );
30074
+ currentRenderState = renderStates.get( targetScene );
29586
30075
  currentRenderState.init();
29587
30076
 
29588
30077
  renderStateStack.push( currentRenderState );
29589
30078
 
29590
- scene.traverseVisible( function ( object ) {
30079
+ // gather lights from both the target scene and the new object that will be added to the scene.
30080
+
30081
+ targetScene.traverseVisible( function ( object ) {
29591
30082
 
29592
30083
  if ( object.isLight && object.layers.test( camera.layers ) ) {
29593
30084
 
@@ -29603,8 +30094,32 @@ class WebGLRenderer {
29603
30094
 
29604
30095
  } );
29605
30096
 
30097
+ if ( scene !== targetScene ) {
30098
+
30099
+ scene.traverseVisible( function ( object ) {
30100
+
30101
+ if ( object.isLight && object.layers.test( camera.layers ) ) {
30102
+
30103
+ currentRenderState.pushLight( object );
30104
+
30105
+ if ( object.castShadow ) {
30106
+
30107
+ currentRenderState.pushShadow( object );
30108
+
30109
+ }
30110
+
30111
+ }
30112
+
30113
+ } );
30114
+
30115
+ }
30116
+
29606
30117
  currentRenderState.setupLights( _this._useLegacyLights );
29607
30118
 
30119
+ // Only initialize materials in the new scene, not the targetScene.
30120
+
30121
+ const materials = new Set();
30122
+
29608
30123
  scene.traverse( function ( object ) {
29609
30124
 
29610
30125
  const material = object.material;
@@ -29617,13 +30132,15 @@ class WebGLRenderer {
29617
30132
 
29618
30133
  const material2 = material[ i ];
29619
30134
 
29620
- prepare( material2, scene, object );
30135
+ prepareMaterial( material2, targetScene, object );
30136
+ materials.add( material2 );
29621
30137
 
29622
30138
  }
29623
30139
 
29624
30140
  } else {
29625
30141
 
29626
- prepare( material, scene, object );
30142
+ prepareMaterial( material, targetScene, object );
30143
+ materials.add( material );
29627
30144
 
29628
30145
  }
29629
30146
 
@@ -29634,6 +30151,70 @@ class WebGLRenderer {
29634
30151
  renderStateStack.pop();
29635
30152
  currentRenderState = null;
29636
30153
 
30154
+ return materials;
30155
+
30156
+ };
30157
+
30158
+ // compileAsync
30159
+
30160
+ this.compileAsync = function ( scene, camera, targetScene = null ) {
30161
+
30162
+ const materials = this.compile( scene, camera, targetScene );
30163
+
30164
+ // Wait for all the materials in the new object to indicate that they're
30165
+ // ready to be used before resolving the promise.
30166
+
30167
+ return new Promise( ( resolve ) => {
30168
+
30169
+ function checkMaterialsReady() {
30170
+
30171
+ materials.forEach( function ( material ) {
30172
+
30173
+ const materialProperties = properties.get( material );
30174
+ const program = materialProperties.currentProgram;
30175
+
30176
+ if ( program.isReady() ) {
30177
+
30178
+ // remove any programs that report they're ready to use from the list
30179
+ materials.delete( material );
30180
+
30181
+ }
30182
+
30183
+ } );
30184
+
30185
+ // once the list of compiling materials is empty, call the callback
30186
+
30187
+ if ( materials.size === 0 ) {
30188
+
30189
+ resolve( scene );
30190
+ return;
30191
+
30192
+ }
30193
+
30194
+ // if some materials are still not ready, wait a bit and check again
30195
+
30196
+ setTimeout( checkMaterialsReady, 10 );
30197
+
30198
+ }
30199
+
30200
+ if ( extensions.get( 'KHR_parallel_shader_compile' ) !== null ) {
30201
+
30202
+ // If we can check the compilation status of the materials without
30203
+ // blocking then do so right away.
30204
+
30205
+ checkMaterialsReady();
30206
+
30207
+ } else {
30208
+
30209
+ // Otherwise start by waiting a bit to give the materials we just
30210
+ // initialized a chance to finish.
30211
+
30212
+ setTimeout( checkMaterialsReady, 10 );
30213
+
30214
+ }
30215
+
30216
+ } );
30217
+
29637
30218
  };
29638
30219
 
29639
30220
  // Animation Loop
@@ -29760,13 +30341,23 @@ class WebGLRenderer {
29760
30341
 
29761
30342
  if ( camera.isArrayCamera ) {
29762
30343
 
29763
- const cameras = camera.cameras;
30344
+ if ( xr.enabled && xr.isMultiview ) {
30345
+
30346
+ textures.setDeferTextureUploads( true );
30347
+
30348
+ renderScene( currentRenderList, scene, camera, camera.cameras[ 0 ].viewport );
30349
+
30350
+ } else {
30351
+
30352
+ const cameras = camera.cameras;
29764
30353
 
29765
- for ( let i = 0, l = cameras.length; i < l; i ++ ) {
30354
+ for ( let i = 0, l = cameras.length; i < l; i ++ ) {
29766
30355
 
29767
- const camera2 = cameras[ i ];
30356
+ const camera2 = cameras[ i ];
29768
30357
 
29769
- renderScene( currentRenderList, scene, camera2, camera2.viewport );
30358
+ renderScene( currentRenderList, scene, camera2, camera2.viewport );
30359
+
30360
+ }
29770
30361
 
29771
30362
  }
29772
30363
 
@@ -29794,6 +30385,8 @@ class WebGLRenderer {
29794
30385
 
29795
30386
  if ( scene.isScene === true ) scene.onAfterRender( _this, scene, camera );
29796
30387
 
30388
+ textures.runDeferredUploads();
30389
+
29797
30390
  if ( xr.enabled && xr.submitFrame ) {
29798
30391
 
29799
30392
  xr.submitFrame();
@@ -29975,6 +30568,14 @@ class WebGLRenderer {
29975
30568
 
29976
30569
  function renderTransmissionPass( opaqueObjects, transmissiveObjects, scene, camera ) {
29977
30570
 
30571
+ const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
30572
+
30573
+ if ( overrideMaterial !== null ) {
30574
+
30575
+ return;
30576
+
30577
+ }
30578
+
29978
30579
  const isWebGL2 = capabilities.isWebGL2;
29979
30580
 
29980
30581
  if ( _transmissionRenderTarget === null ) {
@@ -30234,16 +30835,26 @@ class WebGLRenderer {
30234
30835
 
30235
30836
  }
30236
30837
 
30237
- const progUniforms = program.getUniforms();
30238
- const uniformsList = WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
30239
-
30240
30838
  materialProperties.currentProgram = program;
30241
- materialProperties.uniformsList = uniformsList;
30839
+ materialProperties.uniformsList = null;
30242
30840
 
30243
30841
  return program;
30244
30842
 
30245
30843
  }
30246
30844
 
30845
+ function getUniformList( materialProperties ) {
30846
+
30847
+ if ( materialProperties.uniformsList === null ) {
30848
+
30849
+ const progUniforms = materialProperties.currentProgram.getUniforms();
30850
+ materialProperties.uniformsList = WebGLUniforms.seqWithValue( progUniforms.seq, materialProperties.uniforms );
30851
+
30852
+ }
30853
+
30854
+ return materialProperties.uniformsList;
30855
+
30856
+ }
30857
+
30247
30858
  function updateCommonMaterialProperties( material, parameters ) {
30248
30859
 
30249
30860
  const materialProperties = properties.get( material );
@@ -30261,6 +30872,7 @@ class WebGLRenderer {
30261
30872
  materialProperties.vertexAlphas = parameters.vertexAlphas;
30262
30873
  materialProperties.vertexTangents = parameters.vertexTangents;
30263
30874
  materialProperties.toneMapping = parameters.toneMapping;
30875
+ materialProperties.numMultiviewViews = parameters.numMultiviewViews;
30264
30876
 
30265
30877
  }
30266
30878
 
@@ -30292,6 +30904,8 @@ class WebGLRenderer {
30292
30904
 
30293
30905
  }
30294
30906
 
30907
+ const numMultiviewViews = _currentRenderTarget && _currentRenderTarget.isWebGLMultiviewRenderTarget ? _currentRenderTarget.numViews : 0;
30908
+
30295
30909
  const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
30296
30910
  const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;
30297
30911
 
@@ -30395,6 +31009,10 @@ class WebGLRenderer {
30395
31009
 
30396
31010
  needsProgramChange = true;
30397
31011
 
31012
+ } else if ( materialProperties.numMultiviewViews !== numMultiviewViews ) {
31013
+
31014
+ needsProgramChange = true;
31015
+
30398
31016
  }
30399
31017
 
30400
31018
  } else {
@@ -30441,8 +31059,17 @@ class WebGLRenderer {
30441
31059
 
30442
31060
  // common camera uniforms
30443
31061
 
30444
- p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
30445
- p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
31062
+ if ( program.numMultiviewViews > 0 ) {
31063
+
31064
+ multiview.updateCameraProjectionMatricesUniform( camera, p_uniforms );
31065
+ multiview.updateCameraViewMatricesUniform( camera, p_uniforms );
31066
+
31067
+ } else {
31068
+
31069
+ p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
31070
+ p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
31071
+
31072
+ }
30446
31073
 
30447
31074
  const uCamPos = p_uniforms.map.cameraPosition;
30448
31075
 
@@ -30571,13 +31198,13 @@ class WebGLRenderer {
30571
31198
 
30572
31199
  materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget );
30573
31200
 
30574
- WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
31201
+ WebGLUniforms.upload( _gl, getUniformList( materialProperties ), m_uniforms, textures );
30575
31202
 
30576
31203
  }
30577
31204
 
30578
31205
  if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {
30579
31206
 
30580
- WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
31207
+ WebGLUniforms.upload( _gl, getUniformList( materialProperties ), m_uniforms, textures );
30581
31208
  material.uniformsNeedUpdate = false;
30582
31209
 
30583
31210
  }
@@ -30590,8 +31217,17 @@ class WebGLRenderer {
30590
31217
 
30591
31218
  // common matrices
30592
31219
 
30593
- p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
30594
- p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
31220
+ if ( program.numMultiviewViews > 0 ) {
31221
+
31222
+ multiview.updateObjectMatricesUniforms( object, camera, p_uniforms );
31223
+
31224
+ } else {
31225
+
31226
+ p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
31227
+ p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
31228
+
31229
+ }
31230
+
30595
31231
  p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
30596
31232
 
30597
31233
  // UBOs
@@ -30701,20 +31337,16 @@ class WebGLRenderer {
30701
31337
  const renderTargetProperties = properties.get( renderTarget );
30702
31338
  renderTargetProperties.__hasExternalTextures = true;
30703
31339
 
30704
- if ( renderTargetProperties.__hasExternalTextures ) {
30705
-
30706
- renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;
30707
-
30708
- if ( ! renderTargetProperties.__autoAllocateDepthBuffer ) {
31340
+ renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;
30709
31341
 
30710
- // The multisample_render_to_texture extension doesn't work properly if there
30711
- // are midframe flushes and an external depth buffer. Disable use of the extension.
30712
- if ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) {
31342
+ if ( ! renderTargetProperties.__autoAllocateDepthBuffer && ! _currentRenderTarget.isWebGLMultiviewRenderTarget ) {
30713
31343
 
30714
- console.warn( 'THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided' );
30715
- renderTargetProperties.__useRenderToTexture = false;
31344
+ // The multisample_render_to_texture extension doesn't work properly if there
31345
+ // are midframe flushes and an external depth buffer. Disable use of the extension.
31346
+ if ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) {
30716
31347
 
30717
- }
31348
+ console.warn( 'THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided' );
31349
+ renderTargetProperties.__useRenderToTexture = false;
30718
31350
 
30719
31351
  }
30720
31352
 
@@ -32206,7 +32838,7 @@ class SkinnedMesh extends Mesh {
32206
32838
 
32207
32839
  this.type = 'SkinnedMesh';
32208
32840
 
32209
- this.bindMode = 'attached';
32841
+ this.bindMode = AttachedBindMode;
32210
32842
  this.bindMatrix = new Matrix4();
32211
32843
  this.bindMatrixInverse = new Matrix4();
32212
32844
 
@@ -32231,8 +32863,7 @@ class SkinnedMesh extends Mesh {
32231
32863
 
32232
32864
  for ( let i = 0; i < positionAttribute.count; i ++ ) {
32233
32865
 
32234
- _vertex.fromBufferAttribute( positionAttribute, i );
32235
- this.applyBoneTransform( i, _vertex );
32866
+ this.getVertexPosition( i, _vertex );
32236
32867
  this.boundingBox.expandByPoint( _vertex );
32237
32868
 
32238
32869
  }
@@ -32255,8 +32886,7 @@ class SkinnedMesh extends Mesh {
32255
32886
 
32256
32887
  for ( let i = 0; i < positionAttribute.count; i ++ ) {
32257
32888
 
32258
- _vertex.fromBufferAttribute( positionAttribute, i );
32259
- this.applyBoneTransform( i, _vertex );
32889
+ this.getVertexPosition( i, _vertex );
32260
32890
  this.boundingSphere.expandByPoint( _vertex );
32261
32891
 
32262
32892
  }
@@ -32382,11 +33012,11 @@ class SkinnedMesh extends Mesh {
32382
33012
 
32383
33013
  super.updateMatrixWorld( force );
32384
33014
 
32385
- if ( this.bindMode === 'attached' ) {
33015
+ if ( this.bindMode === AttachedBindMode ) {
32386
33016
 
32387
33017
  this.bindMatrixInverse.copy( this.matrixWorld ).invert();
32388
33018
 
32389
- } else if ( this.bindMode === 'detached' ) {
33019
+ } else if ( this.bindMode === DetachedBindMode ) {
32390
33020
 
32391
33021
  this.bindMatrixInverse.copy( this.bindMatrix ).invert();
32392
33022
 
@@ -44285,11 +44915,18 @@ class MaterialLoader extends Loader {
44285
44915
  if ( json.transparent !== undefined ) material.transparent = json.transparent;
44286
44916
  if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
44287
44917
  if ( json.alphaHash !== undefined ) material.alphaHash = json.alphaHash;
44918
+ if ( json.depthFunc !== undefined ) material.depthFunc = json.depthFunc;
44288
44919
  if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
44289
44920
  if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
44290
44921
  if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
44291
-
44292
- if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite;
44922
+ if ( json.blendSrc !== undefined ) material.blendSrc = json.blendSrc;
44923
+ if ( json.blendDst !== undefined ) material.blendDst = json.blendDst;
44924
+ if ( json.blendEquation !== undefined ) material.blendEquation = json.blendEquation;
44925
+ if ( json.blendSrcAlpha !== undefined ) material.blendSrcAlpha = json.blendSrcAlpha;
44926
+ if ( json.blendDstAlpha !== undefined ) material.blendDstAlpha = json.blendDstAlpha;
44927
+ if ( json.blendEquationAlpha !== undefined ) material.blendEquationAlpha = json.blendEquationAlpha;
44928
+ if ( json.blendColor !== undefined && material.blendColor !== undefined ) material.blendColor.setHex( json.blendColor );
44929
+ if ( json.blendAlpha !== undefined ) material.blendAlpha = json.blendAlpha;
44293
44930
  if ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask;
44294
44931
  if ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc;
44295
44932
  if ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef;
@@ -44297,6 +44934,7 @@ class MaterialLoader extends Loader {
44297
44934
  if ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail;
44298
44935
  if ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail;
44299
44936
  if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass;
44937
+ if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite;
44300
44938
 
44301
44939
  if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
44302
44940
  if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
@@ -52116,4 +52754,4 @@ if ( typeof window !== 'undefined' ) {
52116
52754
 
52117
52755
  }
52118
52756
 
52119
- export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AnimationAction, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BackSide, BasicDepthPacking, BasicShadowMap, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasTexture, CapsuleGeometry, CatmullRomCurve3, CineonToneMapping, CircleGeometry, ClampToEdgeWrapping, Clock, Color, ColorKeyframeTrack, ColorManagement, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CompressedTextureLoader, ConeGeometry, CubeCamera, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CustomToneMapping, CylinderGeometry, Cylindrical, Data3DTexture, DataArrayTexture, DataTexture, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DisplayP3ColorSpace, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeGeometry, FileLoader, Float16BufferAttribute, Float32BufferAttribute, Float64BufferAttribute, FloatType, Fog, FogExp2, FramebufferTexture, FrontSide, Frustum, GLBufferAttribute, GLSL1, GLSL3, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, KeepStencilOp, KeyframeTrack, LOD, LatheGeometry, Layers, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LineSegments, LinearDisplayP3ColorSpace, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, MathUtils, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronGeometry, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, P3Primaries, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, Path, PerspectiveCamera, Plane, PlaneGeometry, PlaneHelper, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, Rec709Primaries, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RenderTarget, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingGeometry, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SRGBColorSpace, SRGBTransfer, Scene, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, Source, Sphere, SphereGeometry, Spherical, SphericalHarmonics3, SplineCurve, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronGeometry, Texture, TextureLoader, TorusGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry, TwoPassDoubleSide, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, VideoTexture, WebGL1Renderer, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLCoordinateSystem, WebGLCubeRenderTarget, WebGLMultipleRenderTargets, WebGLRenderTarget, WebGLRenderer, WebGLUtils, WebGPUCoordinateSystem, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, _SRGBAFormat, createCanvasElement, sRGBEncoding };
52757
+ export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AnimationAction, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, AttachedBindMode, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BackSide, BasicDepthPacking, BasicShadowMap, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasTexture, CapsuleGeometry, CatmullRomCurve3, CineonToneMapping, CircleGeometry, ClampToEdgeWrapping, Clock, Color, ColorKeyframeTrack, ColorManagement, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CompressedTextureLoader, ConeGeometry, ConstantAlphaFactor, ConstantColorFactor, CubeCamera, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CustomToneMapping, CylinderGeometry, Cylindrical, Data3DTexture, DataArrayTexture, DataTexture, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DetachedBindMode, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DisplayP3ColorSpace, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeGeometry, FileLoader, Float16BufferAttribute, Float32BufferAttribute, Float64BufferAttribute, FloatType, Fog, FogExp2, FramebufferTexture, FrontSide, Frustum, GLBufferAttribute, GLSL1, GLSL3, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, KeepStencilOp, KeyframeTrack, LOD, LatheGeometry, Layers, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LineSegments, LinearDisplayP3ColorSpace, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, MathUtils, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronGeometry, OneFactor, OneMinusConstantAlphaFactor, OneMinusConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, P3Primaries, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, Path, PerspectiveCamera, Plane, PlaneGeometry, PlaneHelper, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, Rec709Primaries, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RenderTarget, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingGeometry, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SRGBColorSpace, SRGBTransfer, Scene, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, Source, Sphere, SphereGeometry, Spherical, SphericalHarmonics3, SplineCurve, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronGeometry, Texture, TextureLoader, TorusGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry, TwoPassDoubleSide, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, VideoTexture, WebGL1Renderer, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLCoordinateSystem, WebGLCubeRenderTarget, WebGLMultipleRenderTargets, WebGLRenderTarget, WebGLRenderer, WebGLUtils, WebGPUCoordinateSystem, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, _SRGBAFormat, createCanvasElement, sRGBEncoding };