super-three 0.157.1 → 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 (178) hide show
  1. package/README.md +6 -4
  2. package/build/three.cjs +1013 -790
  3. package/build/three.js +1013 -790
  4. package/build/three.min.js +1 -1
  5. package/build/three.module.js +1008 -791
  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/WebGLRenderer.js +142 -25
  169. package/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl.js +8 -0
  170. package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +3 -2
  171. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  172. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +8 -6
  173. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +2 -2
  174. package/src/renderers/webgl/WebGLProgram.js +80 -50
  175. package/src/renderers/webgl/WebGLPrograms.js +3 -0
  176. package/src/renderers/webgl/WebGLState.js +25 -4
  177. package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +0 -76
  178. package/examples/jsm/nodes/accessors/LineMaterialNode.js +0 -29
package/build/three.cjs CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  'use strict';
7
7
 
8
- const REVISION = '157';
8
+ const REVISION = '158';
9
9
 
10
10
  const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
11
11
  const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
@@ -43,6 +43,10 @@ const OneMinusDstAlphaFactor = 207;
43
43
  const DstColorFactor = 208;
44
44
  const OneMinusDstColorFactor = 209;
45
45
  const SrcAlphaSaturateFactor = 210;
46
+ const ConstantColorFactor = 211;
47
+ const OneMinusConstantColorFactor = 212;
48
+ const ConstantAlphaFactor = 213;
49
+ const OneMinusConstantAlphaFactor = 214;
46
50
  const NeverDepth = 0;
47
51
  const AlwaysDepth = 1;
48
52
  const LessDepth = 2;
@@ -60,6 +64,8 @@ const ReinhardToneMapping = 2;
60
64
  const CineonToneMapping = 3;
61
65
  const ACESFilmicToneMapping = 4;
62
66
  const CustomToneMapping = 5;
67
+ const AttachedBindMode = 'attached';
68
+ const DetachedBindMode = 'detached';
63
69
 
64
70
  const UVMapping = 300;
65
71
  const CubeReflectionMapping = 301;
@@ -4154,21 +4160,20 @@ class Vector3 {
4154
4160
 
4155
4161
  applyQuaternion( q ) {
4156
4162
 
4157
- const x = this.x, y = this.y, z = this.z;
4158
- const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
4163
+ // quaternion q is assumed to have unit length
4159
4164
 
4160
- // calculate quat * vector
4161
-
4162
- const ix = qw * x + qy * z - qz * y;
4163
- const iy = qw * y + qz * x - qx * z;
4164
- const iz = qw * z + qx * y - qy * x;
4165
- const iw = - qx * x - qy * y - qz * z;
4165
+ const vx = this.x, vy = this.y, vz = this.z;
4166
+ const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
4166
4167
 
4167
- // calculate result * inverse quat
4168
+ // t = 2 * cross( q.xyz, v );
4169
+ const tx = 2 * ( qy * vz - qz * vy );
4170
+ const ty = 2 * ( qz * vx - qx * vz );
4171
+ const tz = 2 * ( qx * vy - qy * vx );
4168
4172
 
4169
- this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
4170
- this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
4171
- this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
4173
+ // v + q.w * t + cross( q.xyz, t );
4174
+ this.x = vx + qw * tx + qy * tz - qz * ty;
4175
+ this.y = vy + qw * ty + qz * tx - qx * tz;
4176
+ this.z = vz + qw * tz + qx * ty - qy * tx;
4172
4177
 
4173
4178
  return this;
4174
4179
 
@@ -4784,37 +4789,53 @@ class Box3 {
4784
4789
 
4785
4790
  object.updateWorldMatrix( false, false );
4786
4791
 
4787
- if ( object.boundingBox !== undefined ) {
4792
+ const geometry = object.geometry;
4788
4793
 
4789
- if ( object.boundingBox === null ) {
4794
+ if ( geometry !== undefined ) {
4790
4795
 
4791
- object.computeBoundingBox();
4796
+ const positionAttribute = geometry.getAttribute( 'position' );
4792
4797
 
4793
- }
4798
+ // precise AABB computation based on vertex data requires at least a position attribute.
4799
+ // instancing isn't supported so far and uses the normal (conservative) code path.
4794
4800
 
4795
- _box$3.copy( object.boundingBox );
4796
- _box$3.applyMatrix4( object.matrixWorld );
4801
+ if ( precise === true && positionAttribute !== undefined && object.isInstancedMesh !== true ) {
4797
4802
 
4798
- this.union( _box$3 );
4803
+ for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) {
4799
4804
 
4800
- } else {
4805
+ if ( object.isMesh === true ) {
4801
4806
 
4802
- const geometry = object.geometry;
4807
+ object.getVertexPosition( i, _vector$a );
4808
+
4809
+ } else {
4810
+
4811
+ _vector$a.fromBufferAttribute( positionAttribute, i );
4812
+
4813
+ }
4814
+
4815
+ _vector$a.applyMatrix4( object.matrixWorld );
4816
+ this.expandByPoint( _vector$a );
4817
+
4818
+ }
4819
+
4820
+ } else {
4803
4821
 
4804
- if ( geometry !== undefined ) {
4822
+ if ( object.boundingBox !== undefined ) {
4805
4823
 
4806
- if ( precise && geometry.attributes !== undefined && geometry.attributes.position !== undefined ) {
4824
+ // object-level bounding box
4807
4825
 
4808
- const position = geometry.attributes.position;
4809
- for ( let i = 0, l = position.count; i < l; i ++ ) {
4826
+ if ( object.boundingBox === null ) {
4810
4827
 
4811
- _vector$a.fromBufferAttribute( position, i ).applyMatrix4( object.matrixWorld );
4812
- this.expandByPoint( _vector$a );
4828
+ object.computeBoundingBox();
4813
4829
 
4814
4830
  }
4815
4831
 
4832
+ _box$3.copy( object.boundingBox );
4833
+
4834
+
4816
4835
  } else {
4817
4836
 
4837
+ // geometry-level bounding box
4838
+
4818
4839
  if ( geometry.boundingBox === null ) {
4819
4840
 
4820
4841
  geometry.computeBoundingBox();
@@ -4822,12 +4843,13 @@ class Box3 {
4822
4843
  }
4823
4844
 
4824
4845
  _box$3.copy( geometry.boundingBox );
4825
- _box$3.applyMatrix4( object.matrixWorld );
4826
-
4827
- this.union( _box$3 );
4828
4846
 
4829
4847
  }
4830
4848
 
4849
+ _box$3.applyMatrix4( object.matrixWorld );
4850
+
4851
+ this.union( _box$3 );
4852
+
4831
4853
  }
4832
4854
 
4833
4855
  }
@@ -8423,1127 +8445,1140 @@ class Triangle {
8423
8445
 
8424
8446
  }
8425
8447
 
8426
- let _materialId = 0;
8448
+ const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
8449
+ 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
8450
+ 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
8451
+ 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
8452
+ 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
8453
+ 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
8454
+ 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
8455
+ 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
8456
+ 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
8457
+ 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
8458
+ 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
8459
+ 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
8460
+ 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
8461
+ 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
8462
+ 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
8463
+ 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
8464
+ 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
8465
+ 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
8466
+ 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
8467
+ 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
8468
+ 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
8469
+ 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
8470
+ 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
8471
+ 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
8427
8472
 
8428
- class Material extends EventDispatcher {
8473
+ const _hslA = { h: 0, s: 0, l: 0 };
8474
+ const _hslB = { h: 0, s: 0, l: 0 };
8429
8475
 
8430
- constructor() {
8476
+ function hue2rgb( p, q, t ) {
8431
8477
 
8432
- super();
8478
+ if ( t < 0 ) t += 1;
8479
+ if ( t > 1 ) t -= 1;
8480
+ if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
8481
+ if ( t < 1 / 2 ) return q;
8482
+ if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
8483
+ return p;
8433
8484
 
8434
- this.isMaterial = true;
8485
+ }
8435
8486
 
8436
- Object.defineProperty( this, 'id', { value: _materialId ++ } );
8487
+ class Color {
8437
8488
 
8438
- this.uuid = generateUUID();
8489
+ constructor( r, g, b ) {
8439
8490
 
8440
- this.name = '';
8441
- this.type = 'Material';
8491
+ this.isColor = true;
8442
8492
 
8443
- this.blending = NormalBlending;
8444
- this.side = FrontSide;
8445
- this.vertexColors = false;
8493
+ this.r = 1;
8494
+ this.g = 1;
8495
+ this.b = 1;
8446
8496
 
8447
- this.opacity = 1;
8448
- this.transparent = false;
8449
- this.alphaHash = false;
8497
+ return this.set( r, g, b );
8450
8498
 
8451
- this.blendSrc = SrcAlphaFactor;
8452
- this.blendDst = OneMinusSrcAlphaFactor;
8453
- this.blendEquation = AddEquation;
8454
- this.blendSrcAlpha = null;
8455
- this.blendDstAlpha = null;
8456
- this.blendEquationAlpha = null;
8499
+ }
8457
8500
 
8458
- this.depthFunc = LessEqualDepth;
8459
- this.depthTest = true;
8460
- this.depthWrite = true;
8501
+ set( r, g, b ) {
8461
8502
 
8462
- this.stencilWriteMask = 0xff;
8463
- this.stencilFunc = AlwaysStencilFunc;
8464
- this.stencilRef = 0;
8465
- this.stencilFuncMask = 0xff;
8466
- this.stencilFail = KeepStencilOp;
8467
- this.stencilZFail = KeepStencilOp;
8468
- this.stencilZPass = KeepStencilOp;
8469
- this.stencilWrite = false;
8503
+ if ( g === undefined && b === undefined ) {
8470
8504
 
8471
- this.clippingPlanes = null;
8472
- this.clipIntersection = false;
8473
- this.clipShadows = false;
8505
+ // r is THREE.Color, hex or string
8474
8506
 
8475
- this.shadowSide = null;
8507
+ const value = r;
8476
8508
 
8477
- this.colorWrite = true;
8509
+ if ( value && value.isColor ) {
8478
8510
 
8479
- this.precision = null; // override the renderer's default precision for this material
8511
+ this.copy( value );
8480
8512
 
8481
- this.polygonOffset = false;
8482
- this.polygonOffsetFactor = 0;
8483
- this.polygonOffsetUnits = 0;
8513
+ } else if ( typeof value === 'number' ) {
8484
8514
 
8485
- this.dithering = false;
8515
+ this.setHex( value );
8486
8516
 
8487
- this.alphaToCoverage = false;
8488
- this.premultipliedAlpha = false;
8489
- this.forceSinglePass = false;
8517
+ } else if ( typeof value === 'string' ) {
8490
8518
 
8491
- this.visible = true;
8519
+ this.setStyle( value );
8492
8520
 
8493
- this.toneMapped = true;
8521
+ }
8494
8522
 
8495
- this.userData = {};
8523
+ } else {
8496
8524
 
8497
- this.version = 0;
8525
+ this.setRGB( r, g, b );
8498
8526
 
8499
- this._alphaTest = 0;
8527
+ }
8528
+
8529
+ return this;
8500
8530
 
8501
8531
  }
8502
8532
 
8503
- get alphaTest() {
8533
+ setScalar( scalar ) {
8504
8534
 
8505
- return this._alphaTest;
8535
+ this.r = scalar;
8536
+ this.g = scalar;
8537
+ this.b = scalar;
8538
+
8539
+ return this;
8506
8540
 
8507
8541
  }
8508
8542
 
8509
- set alphaTest( value ) {
8543
+ setHex( hex, colorSpace = SRGBColorSpace ) {
8510
8544
 
8511
- if ( this._alphaTest > 0 !== value > 0 ) {
8545
+ hex = Math.floor( hex );
8512
8546
 
8513
- this.version ++;
8547
+ this.r = ( hex >> 16 & 255 ) / 255;
8548
+ this.g = ( hex >> 8 & 255 ) / 255;
8549
+ this.b = ( hex & 255 ) / 255;
8514
8550
 
8515
- }
8551
+ ColorManagement.toWorkingColorSpace( this, colorSpace );
8516
8552
 
8517
- this._alphaTest = value;
8553
+ return this;
8518
8554
 
8519
8555
  }
8520
8556
 
8521
- onBuild( /* shaderobject, renderer */ ) {}
8522
-
8523
- onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {}
8557
+ setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) {
8524
8558
 
8525
- onBeforeCompile( /* shaderobject, renderer */ ) {}
8559
+ this.r = r;
8560
+ this.g = g;
8561
+ this.b = b;
8526
8562
 
8527
- customProgramCacheKey() {
8563
+ ColorManagement.toWorkingColorSpace( this, colorSpace );
8528
8564
 
8529
- return this.onBeforeCompile.toString();
8565
+ return this;
8530
8566
 
8531
8567
  }
8532
8568
 
8533
- setValues( values ) {
8534
-
8535
- if ( values === undefined ) return;
8569
+ setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) {
8536
8570
 
8537
- for ( const key in values ) {
8571
+ // h,s,l ranges are in 0.0 - 1.0
8572
+ h = euclideanModulo( h, 1 );
8573
+ s = clamp( s, 0, 1 );
8574
+ l = clamp( l, 0, 1 );
8538
8575
 
8539
- const newValue = values[ key ];
8576
+ if ( s === 0 ) {
8540
8577
 
8541
- if ( newValue === undefined ) {
8578
+ this.r = this.g = this.b = l;
8542
8579
 
8543
- console.warn( `THREE.Material: parameter '${ key }' has value of undefined.` );
8544
- continue;
8580
+ } else {
8545
8581
 
8546
- }
8582
+ const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
8583
+ const q = ( 2 * l ) - p;
8547
8584
 
8548
- const currentValue = this[ key ];
8585
+ this.r = hue2rgb( q, p, h + 1 / 3 );
8586
+ this.g = hue2rgb( q, p, h );
8587
+ this.b = hue2rgb( q, p, h - 1 / 3 );
8549
8588
 
8550
- if ( currentValue === undefined ) {
8589
+ }
8551
8590
 
8552
- console.warn( `THREE.Material: '${ key }' is not a property of THREE.${ this.type }.` );
8553
- continue;
8591
+ ColorManagement.toWorkingColorSpace( this, colorSpace );
8554
8592
 
8555
- }
8593
+ return this;
8556
8594
 
8557
- if ( currentValue && currentValue.isColor ) {
8595
+ }
8558
8596
 
8559
- currentValue.set( newValue );
8597
+ setStyle( style, colorSpace = SRGBColorSpace ) {
8560
8598
 
8561
- } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
8599
+ function handleAlpha( string ) {
8562
8600
 
8563
- currentValue.copy( newValue );
8601
+ if ( string === undefined ) return;
8564
8602
 
8565
- } else {
8603
+ if ( parseFloat( string ) < 1 ) {
8566
8604
 
8567
- this[ key ] = newValue;
8605
+ console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
8568
8606
 
8569
8607
  }
8570
8608
 
8571
8609
  }
8572
8610
 
8573
- }
8574
8611
 
8575
- toJSON( meta ) {
8612
+ let m;
8576
8613
 
8577
- const isRootObject = ( meta === undefined || typeof meta === 'string' );
8614
+ if ( m = /^(\w+)\(([^\)]*)\)/.exec( style ) ) {
8578
8615
 
8579
- if ( isRootObject ) {
8616
+ // rgb / hsl
8580
8617
 
8581
- meta = {
8582
- textures: {},
8583
- images: {}
8584
- };
8618
+ let color;
8619
+ const name = m[ 1 ];
8620
+ const components = m[ 2 ];
8585
8621
 
8586
- }
8622
+ switch ( name ) {
8587
8623
 
8588
- const data = {
8589
- metadata: {
8590
- version: 4.6,
8591
- type: 'Material',
8592
- generator: 'Material.toJSON'
8593
- }
8594
- };
8624
+ case 'rgb':
8625
+ case 'rgba':
8595
8626
 
8596
- // standard Material serialization
8597
- data.uuid = this.uuid;
8598
- data.type = this.type;
8627
+ if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
8599
8628
 
8600
- if ( this.name !== '' ) data.name = this.name;
8629
+ // rgb(255,0,0) rgba(255,0,0,0.5)
8601
8630
 
8602
- if ( this.color && this.color.isColor ) data.color = this.color.getHex();
8631
+ handleAlpha( color[ 4 ] );
8603
8632
 
8604
- if ( this.roughness !== undefined ) data.roughness = this.roughness;
8605
- if ( this.metalness !== undefined ) data.metalness = this.metalness;
8633
+ return this.setRGB(
8634
+ Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255,
8635
+ Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255,
8636
+ Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255,
8637
+ colorSpace
8638
+ );
8606
8639
 
8607
- if ( this.sheen !== undefined ) data.sheen = this.sheen;
8608
- if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex();
8609
- if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness;
8610
- if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
8611
- if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;
8640
+ }
8612
8641
 
8613
- if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
8614
- if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity;
8615
- if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex();
8616
- if ( this.shininess !== undefined ) data.shininess = this.shininess;
8617
- if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat;
8618
- if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness;
8642
+ if ( color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
8619
8643
 
8620
- if ( this.clearcoatMap && this.clearcoatMap.isTexture ) {
8644
+ // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
8621
8645
 
8622
- data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid;
8646
+ handleAlpha( color[ 4 ] );
8623
8647
 
8624
- }
8648
+ return this.setRGB(
8649
+ Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100,
8650
+ Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100,
8651
+ Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100,
8652
+ colorSpace
8653
+ );
8625
8654
 
8626
- if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) {
8655
+ }
8627
8656
 
8628
- data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid;
8657
+ break;
8629
8658
 
8630
- }
8659
+ case 'hsl':
8660
+ case 'hsla':
8631
8661
 
8632
- if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) {
8662
+ if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
8633
8663
 
8634
- data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid;
8635
- data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
8664
+ // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
8636
8665
 
8637
- }
8666
+ handleAlpha( color[ 4 ] );
8638
8667
 
8639
- if ( this.iridescence !== undefined ) data.iridescence = this.iridescence;
8640
- if ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR;
8641
- if ( this.iridescenceThicknessRange !== undefined ) data.iridescenceThicknessRange = this.iridescenceThicknessRange;
8668
+ return this.setHSL(
8669
+ parseFloat( color[ 1 ] ) / 360,
8670
+ parseFloat( color[ 2 ] ) / 100,
8671
+ parseFloat( color[ 3 ] ) / 100,
8672
+ colorSpace
8673
+ );
8642
8674
 
8643
- if ( this.iridescenceMap && this.iridescenceMap.isTexture ) {
8675
+ }
8644
8676
 
8645
- data.iridescenceMap = this.iridescenceMap.toJSON( meta ).uuid;
8677
+ break;
8646
8678
 
8647
- }
8679
+ default:
8648
8680
 
8649
- if ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) {
8681
+ console.warn( 'THREE.Color: Unknown color model ' + style );
8650
8682
 
8651
- data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid;
8683
+ }
8652
8684
 
8653
- }
8685
+ } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) {
8654
8686
 
8655
- if ( this.anisotropy !== undefined ) data.anisotropy = this.anisotropy;
8656
- if ( this.anisotropyRotation !== undefined ) data.anisotropyRotation = this.anisotropyRotation;
8687
+ // hex color
8657
8688
 
8658
- if ( this.anisotropyMap && this.anisotropyMap.isTexture ) {
8689
+ const hex = m[ 1 ];
8690
+ const size = hex.length;
8659
8691
 
8660
- data.anisotropyMap = this.anisotropyMap.toJSON( meta ).uuid;
8692
+ if ( size === 3 ) {
8661
8693
 
8662
- }
8694
+ // #ff0
8695
+ return this.setRGB(
8696
+ parseInt( hex.charAt( 0 ), 16 ) / 15,
8697
+ parseInt( hex.charAt( 1 ), 16 ) / 15,
8698
+ parseInt( hex.charAt( 2 ), 16 ) / 15,
8699
+ colorSpace
8700
+ );
8663
8701
 
8664
- if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
8665
- if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid;
8666
- if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
8702
+ } else if ( size === 6 ) {
8667
8703
 
8668
- if ( this.lightMap && this.lightMap.isTexture ) {
8704
+ // #ff0000
8705
+ return this.setHex( parseInt( hex, 16 ), colorSpace );
8669
8706
 
8670
- data.lightMap = this.lightMap.toJSON( meta ).uuid;
8671
- data.lightMapIntensity = this.lightMapIntensity;
8707
+ } else {
8672
8708
 
8673
- }
8709
+ console.warn( 'THREE.Color: Invalid hex color ' + style );
8674
8710
 
8675
- if ( this.aoMap && this.aoMap.isTexture ) {
8711
+ }
8676
8712
 
8677
- data.aoMap = this.aoMap.toJSON( meta ).uuid;
8678
- data.aoMapIntensity = this.aoMapIntensity;
8713
+ } else if ( style && style.length > 0 ) {
8714
+
8715
+ return this.setColorName( style, colorSpace );
8679
8716
 
8680
8717
  }
8681
8718
 
8682
- if ( this.bumpMap && this.bumpMap.isTexture ) {
8719
+ return this;
8683
8720
 
8684
- data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
8685
- data.bumpScale = this.bumpScale;
8721
+ }
8686
8722
 
8687
- }
8723
+ setColorName( style, colorSpace = SRGBColorSpace ) {
8688
8724
 
8689
- if ( this.normalMap && this.normalMap.isTexture ) {
8725
+ // color keywords
8726
+ const hex = _colorKeywords[ style.toLowerCase() ];
8690
8727
 
8691
- data.normalMap = this.normalMap.toJSON( meta ).uuid;
8692
- data.normalMapType = this.normalMapType;
8693
- data.normalScale = this.normalScale.toArray();
8728
+ if ( hex !== undefined ) {
8694
8729
 
8695
- }
8730
+ // red
8731
+ this.setHex( hex, colorSpace );
8696
8732
 
8697
- if ( this.displacementMap && this.displacementMap.isTexture ) {
8733
+ } else {
8698
8734
 
8699
- data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
8700
- data.displacementScale = this.displacementScale;
8701
- data.displacementBias = this.displacementBias;
8735
+ // unknown color
8736
+ console.warn( 'THREE.Color: Unknown color ' + style );
8702
8737
 
8703
8738
  }
8704
8739
 
8705
- if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
8706
- if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
8740
+ return this;
8707
8741
 
8708
- if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
8709
- if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
8710
- if ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid;
8711
- if ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid;
8742
+ }
8712
8743
 
8713
- if ( this.envMap && this.envMap.isTexture ) {
8744
+ clone() {
8714
8745
 
8715
- data.envMap = this.envMap.toJSON( meta ).uuid;
8746
+ return new this.constructor( this.r, this.g, this.b );
8716
8747
 
8717
- if ( this.combine !== undefined ) data.combine = this.combine;
8748
+ }
8718
8749
 
8719
- }
8750
+ copy( color ) {
8720
8751
 
8721
- if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity;
8722
- if ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity;
8723
- if ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio;
8752
+ this.r = color.r;
8753
+ this.g = color.g;
8754
+ this.b = color.b;
8724
8755
 
8725
- if ( this.gradientMap && this.gradientMap.isTexture ) {
8756
+ return this;
8726
8757
 
8727
- data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
8758
+ }
8728
8759
 
8729
- }
8760
+ copySRGBToLinear( color ) {
8730
8761
 
8731
- if ( this.transmission !== undefined ) data.transmission = this.transmission;
8732
- if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid;
8733
- if ( this.thickness !== undefined ) data.thickness = this.thickness;
8734
- if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid;
8735
- if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance;
8736
- if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex();
8762
+ this.r = SRGBToLinear( color.r );
8763
+ this.g = SRGBToLinear( color.g );
8764
+ this.b = SRGBToLinear( color.b );
8737
8765
 
8738
- if ( this.size !== undefined ) data.size = this.size;
8739
- if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide;
8740
- if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
8766
+ return this;
8741
8767
 
8742
- if ( this.blending !== NormalBlending ) data.blending = this.blending;
8743
- if ( this.side !== FrontSide ) data.side = this.side;
8744
- if ( this.vertexColors === true ) data.vertexColors = true;
8768
+ }
8745
8769
 
8746
- if ( this.opacity < 1 ) data.opacity = this.opacity;
8747
- if ( this.transparent === true ) data.transparent = true;
8770
+ copyLinearToSRGB( color ) {
8748
8771
 
8749
- data.depthFunc = this.depthFunc;
8750
- data.depthTest = this.depthTest;
8751
- data.depthWrite = this.depthWrite;
8752
- data.colorWrite = this.colorWrite;
8772
+ this.r = LinearToSRGB( color.r );
8773
+ this.g = LinearToSRGB( color.g );
8774
+ this.b = LinearToSRGB( color.b );
8753
8775
 
8754
- data.stencilWrite = this.stencilWrite;
8755
- data.stencilWriteMask = this.stencilWriteMask;
8756
- data.stencilFunc = this.stencilFunc;
8757
- data.stencilRef = this.stencilRef;
8758
- data.stencilFuncMask = this.stencilFuncMask;
8759
- data.stencilFail = this.stencilFail;
8760
- data.stencilZFail = this.stencilZFail;
8761
- data.stencilZPass = this.stencilZPass;
8776
+ return this;
8762
8777
 
8763
- // rotation (SpriteMaterial)
8764
- if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation;
8778
+ }
8765
8779
 
8766
- if ( this.polygonOffset === true ) data.polygonOffset = true;
8767
- if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor;
8768
- if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits;
8780
+ convertSRGBToLinear() {
8769
8781
 
8770
- if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth;
8771
- if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
8772
- if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
8773
- if ( this.scale !== undefined ) data.scale = this.scale;
8782
+ this.copySRGBToLinear( this );
8774
8783
 
8775
- if ( this.dithering === true ) data.dithering = true;
8784
+ return this;
8776
8785
 
8777
- if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
8778
- if ( this.alphaHash === true ) data.alphaHash = true;
8779
- if ( this.alphaToCoverage === true ) data.alphaToCoverage = true;
8780
- if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = true;
8781
- if ( this.forceSinglePass === true ) data.forceSinglePass = true;
8786
+ }
8782
8787
 
8783
- if ( this.wireframe === true ) data.wireframe = true;
8784
- if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
8785
- if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
8786
- if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
8788
+ convertLinearToSRGB() {
8787
8789
 
8788
- if ( this.flatShading === true ) data.flatShading = true;
8790
+ this.copyLinearToSRGB( this );
8789
8791
 
8790
- if ( this.visible === false ) data.visible = false;
8792
+ return this;
8791
8793
 
8792
- if ( this.toneMapped === false ) data.toneMapped = false;
8794
+ }
8793
8795
 
8794
- if ( this.fog === false ) data.fog = false;
8796
+ getHex( colorSpace = SRGBColorSpace ) {
8795
8797
 
8796
- if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData;
8798
+ ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
8797
8799
 
8798
- // TODO: Copied from Object3D.toJSON
8800
+ 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 ) );
8799
8801
 
8800
- function extractFromCache( cache ) {
8802
+ }
8801
8803
 
8802
- const values = [];
8804
+ getHexString( colorSpace = SRGBColorSpace ) {
8803
8805
 
8804
- for ( const key in cache ) {
8806
+ return ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( - 6 );
8805
8807
 
8806
- const data = cache[ key ];
8807
- delete data.metadata;
8808
- values.push( data );
8808
+ }
8809
8809
 
8810
- }
8810
+ getHSL( target, colorSpace = ColorManagement.workingColorSpace ) {
8811
8811
 
8812
- return values;
8812
+ // h,s,l ranges are in 0.0 - 1.0
8813
8813
 
8814
- }
8814
+ ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
8815
8815
 
8816
- if ( isRootObject ) {
8816
+ const r = _color.r, g = _color.g, b = _color.b;
8817
8817
 
8818
- const textures = extractFromCache( meta.textures );
8819
- const images = extractFromCache( meta.images );
8818
+ const max = Math.max( r, g, b );
8819
+ const min = Math.min( r, g, b );
8820
8820
 
8821
- if ( textures.length > 0 ) data.textures = textures;
8822
- if ( images.length > 0 ) data.images = images;
8821
+ let hue, saturation;
8822
+ const lightness = ( min + max ) / 2.0;
8823
8823
 
8824
- }
8824
+ if ( min === max ) {
8825
8825
 
8826
- return data;
8826
+ hue = 0;
8827
+ saturation = 0;
8827
8828
 
8828
- }
8829
+ } else {
8829
8830
 
8830
- clone() {
8831
+ const delta = max - min;
8831
8832
 
8832
- return new this.constructor().copy( this );
8833
+ saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
8833
8834
 
8834
- }
8835
+ switch ( max ) {
8835
8836
 
8836
- copy( source ) {
8837
+ case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
8838
+ case g: hue = ( b - r ) / delta + 2; break;
8839
+ case b: hue = ( r - g ) / delta + 4; break;
8837
8840
 
8838
- this.name = source.name;
8841
+ }
8839
8842
 
8840
- this.blending = source.blending;
8841
- this.side = source.side;
8842
- this.vertexColors = source.vertexColors;
8843
+ hue /= 6;
8843
8844
 
8844
- this.opacity = source.opacity;
8845
- this.transparent = source.transparent;
8845
+ }
8846
8846
 
8847
- this.blendSrc = source.blendSrc;
8848
- this.blendDst = source.blendDst;
8849
- this.blendEquation = source.blendEquation;
8850
- this.blendSrcAlpha = source.blendSrcAlpha;
8851
- this.blendDstAlpha = source.blendDstAlpha;
8852
- this.blendEquationAlpha = source.blendEquationAlpha;
8847
+ target.h = hue;
8848
+ target.s = saturation;
8849
+ target.l = lightness;
8853
8850
 
8854
- this.depthFunc = source.depthFunc;
8855
- this.depthTest = source.depthTest;
8856
- this.depthWrite = source.depthWrite;
8851
+ return target;
8857
8852
 
8858
- this.stencilWriteMask = source.stencilWriteMask;
8859
- this.stencilFunc = source.stencilFunc;
8860
- this.stencilRef = source.stencilRef;
8861
- this.stencilFuncMask = source.stencilFuncMask;
8862
- this.stencilFail = source.stencilFail;
8863
- this.stencilZFail = source.stencilZFail;
8864
- this.stencilZPass = source.stencilZPass;
8865
- this.stencilWrite = source.stencilWrite;
8853
+ }
8866
8854
 
8867
- const srcPlanes = source.clippingPlanes;
8868
- let dstPlanes = null;
8855
+ getRGB( target, colorSpace = ColorManagement.workingColorSpace ) {
8869
8856
 
8870
- if ( srcPlanes !== null ) {
8857
+ ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
8871
8858
 
8872
- const n = srcPlanes.length;
8873
- dstPlanes = new Array( n );
8859
+ target.r = _color.r;
8860
+ target.g = _color.g;
8861
+ target.b = _color.b;
8874
8862
 
8875
- for ( let i = 0; i !== n; ++ i ) {
8863
+ return target;
8876
8864
 
8877
- dstPlanes[ i ] = srcPlanes[ i ].clone();
8865
+ }
8878
8866
 
8879
- }
8867
+ getStyle( colorSpace = SRGBColorSpace ) {
8880
8868
 
8881
- }
8869
+ ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
8882
8870
 
8883
- this.clippingPlanes = dstPlanes;
8884
- this.clipIntersection = source.clipIntersection;
8885
- this.clipShadows = source.clipShadows;
8871
+ const r = _color.r, g = _color.g, b = _color.b;
8886
8872
 
8887
- this.shadowSide = source.shadowSide;
8873
+ if ( colorSpace !== SRGBColorSpace ) {
8888
8874
 
8889
- this.colorWrite = source.colorWrite;
8875
+ // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/).
8876
+ return `color(${ colorSpace } ${ r.toFixed( 3 ) } ${ g.toFixed( 3 ) } ${ b.toFixed( 3 ) })`;
8890
8877
 
8891
- this.precision = source.precision;
8878
+ }
8892
8879
 
8893
- this.polygonOffset = source.polygonOffset;
8894
- this.polygonOffsetFactor = source.polygonOffsetFactor;
8895
- this.polygonOffsetUnits = source.polygonOffsetUnits;
8880
+ return `rgb(${ Math.round( r * 255 ) },${ Math.round( g * 255 ) },${ Math.round( b * 255 ) })`;
8896
8881
 
8897
- this.dithering = source.dithering;
8882
+ }
8898
8883
 
8899
- this.alphaTest = source.alphaTest;
8900
- this.alphaHash = source.alphaHash;
8901
- this.alphaToCoverage = source.alphaToCoverage;
8902
- this.premultipliedAlpha = source.premultipliedAlpha;
8903
- this.forceSinglePass = source.forceSinglePass;
8884
+ offsetHSL( h, s, l ) {
8904
8885
 
8905
- this.visible = source.visible;
8886
+ this.getHSL( _hslA );
8906
8887
 
8907
- this.toneMapped = source.toneMapped;
8888
+ return this.setHSL( _hslA.h + h, _hslA.s + s, _hslA.l + l );
8908
8889
 
8909
- this.userData = JSON.parse( JSON.stringify( source.userData ) );
8890
+ }
8891
+
8892
+ add( color ) {
8893
+
8894
+ this.r += color.r;
8895
+ this.g += color.g;
8896
+ this.b += color.b;
8910
8897
 
8911
8898
  return this;
8912
8899
 
8913
8900
  }
8914
8901
 
8915
- dispose() {
8902
+ addColors( color1, color2 ) {
8916
8903
 
8917
- this.dispatchEvent( { type: 'dispose' } );
8904
+ this.r = color1.r + color2.r;
8905
+ this.g = color1.g + color2.g;
8906
+ this.b = color1.b + color2.b;
8907
+
8908
+ return this;
8918
8909
 
8919
8910
  }
8920
8911
 
8921
- set needsUpdate( value ) {
8912
+ addScalar( s ) {
8922
8913
 
8923
- if ( value === true ) this.version ++;
8914
+ this.r += s;
8915
+ this.g += s;
8916
+ this.b += s;
8917
+
8918
+ return this;
8924
8919
 
8925
8920
  }
8926
8921
 
8927
- }
8922
+ sub( color ) {
8928
8923
 
8929
- const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
8930
- 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
8931
- 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
8932
- 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
8933
- 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
8934
- 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
8935
- 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
8936
- 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
8937
- 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
8938
- 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
8939
- 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
8940
- 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
8941
- 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
8942
- 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
8943
- 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
8944
- 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
8945
- 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
8946
- 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
8947
- 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
8948
- 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
8949
- 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
8950
- 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
8951
- 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
8952
- 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
8924
+ this.r = Math.max( 0, this.r - color.r );
8925
+ this.g = Math.max( 0, this.g - color.g );
8926
+ this.b = Math.max( 0, this.b - color.b );
8953
8927
 
8954
- const _hslA = { h: 0, s: 0, l: 0 };
8955
- const _hslB = { h: 0, s: 0, l: 0 };
8928
+ return this;
8956
8929
 
8957
- function hue2rgb( p, q, t ) {
8930
+ }
8958
8931
 
8959
- if ( t < 0 ) t += 1;
8960
- if ( t > 1 ) t -= 1;
8961
- if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
8962
- if ( t < 1 / 2 ) return q;
8963
- if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
8964
- return p;
8932
+ multiply( color ) {
8965
8933
 
8966
- }
8934
+ this.r *= color.r;
8935
+ this.g *= color.g;
8936
+ this.b *= color.b;
8967
8937
 
8968
- class Color {
8938
+ return this;
8969
8939
 
8970
- constructor( r, g, b ) {
8940
+ }
8971
8941
 
8972
- this.isColor = true;
8942
+ multiplyScalar( s ) {
8973
8943
 
8974
- this.r = 1;
8975
- this.g = 1;
8976
- this.b = 1;
8944
+ this.r *= s;
8945
+ this.g *= s;
8946
+ this.b *= s;
8977
8947
 
8978
- return this.set( r, g, b );
8948
+ return this;
8979
8949
 
8980
8950
  }
8981
8951
 
8982
- set( r, g, b ) {
8983
-
8984
- if ( g === undefined && b === undefined ) {
8985
-
8986
- // r is THREE.Color, hex or string
8952
+ lerp( color, alpha ) {
8987
8953
 
8988
- const value = r;
8954
+ this.r += ( color.r - this.r ) * alpha;
8955
+ this.g += ( color.g - this.g ) * alpha;
8956
+ this.b += ( color.b - this.b ) * alpha;
8989
8957
 
8990
- if ( value && value.isColor ) {
8958
+ return this;
8991
8959
 
8992
- this.copy( value );
8960
+ }
8993
8961
 
8994
- } else if ( typeof value === 'number' ) {
8962
+ lerpColors( color1, color2, alpha ) {
8995
8963
 
8996
- this.setHex( value );
8964
+ this.r = color1.r + ( color2.r - color1.r ) * alpha;
8965
+ this.g = color1.g + ( color2.g - color1.g ) * alpha;
8966
+ this.b = color1.b + ( color2.b - color1.b ) * alpha;
8997
8967
 
8998
- } else if ( typeof value === 'string' ) {
8968
+ return this;
8999
8969
 
9000
- this.setStyle( value );
8970
+ }
9001
8971
 
9002
- }
8972
+ lerpHSL( color, alpha ) {
9003
8973
 
9004
- } else {
8974
+ this.getHSL( _hslA );
8975
+ color.getHSL( _hslB );
9005
8976
 
9006
- this.setRGB( r, g, b );
8977
+ const h = lerp( _hslA.h, _hslB.h, alpha );
8978
+ const s = lerp( _hslA.s, _hslB.s, alpha );
8979
+ const l = lerp( _hslA.l, _hslB.l, alpha );
9007
8980
 
9008
- }
8981
+ this.setHSL( h, s, l );
9009
8982
 
9010
8983
  return this;
9011
8984
 
9012
8985
  }
9013
8986
 
9014
- setScalar( scalar ) {
8987
+ setFromVector3( v ) {
9015
8988
 
9016
- this.r = scalar;
9017
- this.g = scalar;
9018
- this.b = scalar;
8989
+ this.r = v.x;
8990
+ this.g = v.y;
8991
+ this.b = v.z;
9019
8992
 
9020
8993
  return this;
9021
8994
 
9022
8995
  }
9023
8996
 
9024
- setHex( hex, colorSpace = SRGBColorSpace ) {
9025
-
9026
- hex = Math.floor( hex );
8997
+ applyMatrix3( m ) {
9027
8998
 
9028
- this.r = ( hex >> 16 & 255 ) / 255;
9029
- this.g = ( hex >> 8 & 255 ) / 255;
9030
- this.b = ( hex & 255 ) / 255;
8999
+ const r = this.r, g = this.g, b = this.b;
9000
+ const e = m.elements;
9031
9001
 
9032
- ColorManagement.toWorkingColorSpace( this, colorSpace );
9002
+ this.r = e[ 0 ] * r + e[ 3 ] * g + e[ 6 ] * b;
9003
+ this.g = e[ 1 ] * r + e[ 4 ] * g + e[ 7 ] * b;
9004
+ this.b = e[ 2 ] * r + e[ 5 ] * g + e[ 8 ] * b;
9033
9005
 
9034
9006
  return this;
9035
9007
 
9036
9008
  }
9037
9009
 
9038
- setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) {
9039
-
9040
- this.r = r;
9041
- this.g = g;
9042
- this.b = b;
9043
-
9044
- ColorManagement.toWorkingColorSpace( this, colorSpace );
9010
+ equals( c ) {
9045
9011
 
9046
- return this;
9012
+ return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
9047
9013
 
9048
9014
  }
9049
9015
 
9050
- setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) {
9016
+ fromArray( array, offset = 0 ) {
9051
9017
 
9052
- // h,s,l ranges are in 0.0 - 1.0
9053
- h = euclideanModulo( h, 1 );
9054
- s = clamp( s, 0, 1 );
9055
- l = clamp( l, 0, 1 );
9018
+ this.r = array[ offset ];
9019
+ this.g = array[ offset + 1 ];
9020
+ this.b = array[ offset + 2 ];
9056
9021
 
9057
- if ( s === 0 ) {
9022
+ return this;
9058
9023
 
9059
- this.r = this.g = this.b = l;
9024
+ }
9060
9025
 
9061
- } else {
9026
+ toArray( array = [], offset = 0 ) {
9062
9027
 
9063
- const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
9064
- const q = ( 2 * l ) - p;
9028
+ array[ offset ] = this.r;
9029
+ array[ offset + 1 ] = this.g;
9030
+ array[ offset + 2 ] = this.b;
9065
9031
 
9066
- this.r = hue2rgb( q, p, h + 1 / 3 );
9067
- this.g = hue2rgb( q, p, h );
9068
- this.b = hue2rgb( q, p, h - 1 / 3 );
9032
+ return array;
9069
9033
 
9070
- }
9034
+ }
9071
9035
 
9072
- ColorManagement.toWorkingColorSpace( this, colorSpace );
9036
+ fromBufferAttribute( attribute, index ) {
9037
+
9038
+ this.r = attribute.getX( index );
9039
+ this.g = attribute.getY( index );
9040
+ this.b = attribute.getZ( index );
9073
9041
 
9074
9042
  return this;
9075
9043
 
9076
9044
  }
9077
9045
 
9078
- setStyle( style, colorSpace = SRGBColorSpace ) {
9046
+ toJSON() {
9079
9047
 
9080
- function handleAlpha( string ) {
9048
+ return this.getHex();
9081
9049
 
9082
- if ( string === undefined ) return;
9050
+ }
9083
9051
 
9084
- if ( parseFloat( string ) < 1 ) {
9052
+ *[ Symbol.iterator ]() {
9085
9053
 
9086
- console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
9054
+ yield this.r;
9055
+ yield this.g;
9056
+ yield this.b;
9087
9057
 
9088
- }
9058
+ }
9089
9059
 
9090
- }
9060
+ }
9091
9061
 
9062
+ const _color = /*@__PURE__*/ new Color();
9092
9063
 
9093
- let m;
9064
+ Color.NAMES = _colorKeywords;
9094
9065
 
9095
- if ( m = /^(\w+)\(([^\)]*)\)/.exec( style ) ) {
9066
+ let _materialId = 0;
9096
9067
 
9097
- // rgb / hsl
9068
+ class Material extends EventDispatcher {
9098
9069
 
9099
- let color;
9100
- const name = m[ 1 ];
9101
- const components = m[ 2 ];
9070
+ constructor() {
9102
9071
 
9103
- switch ( name ) {
9072
+ super();
9104
9073
 
9105
- case 'rgb':
9106
- case 'rgba':
9074
+ this.isMaterial = true;
9107
9075
 
9108
- if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
9076
+ Object.defineProperty( this, 'id', { value: _materialId ++ } );
9109
9077
 
9110
- // rgb(255,0,0) rgba(255,0,0,0.5)
9078
+ this.uuid = generateUUID();
9111
9079
 
9112
- handleAlpha( color[ 4 ] );
9080
+ this.name = '';
9081
+ this.type = 'Material';
9113
9082
 
9114
- return this.setRGB(
9115
- Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255,
9116
- Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255,
9117
- Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255,
9118
- colorSpace
9119
- );
9083
+ this.blending = NormalBlending;
9084
+ this.side = FrontSide;
9085
+ this.vertexColors = false;
9120
9086
 
9121
- }
9087
+ this.opacity = 1;
9088
+ this.transparent = false;
9089
+ this.alphaHash = false;
9122
9090
 
9123
- if ( color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
9091
+ this.blendSrc = SrcAlphaFactor;
9092
+ this.blendDst = OneMinusSrcAlphaFactor;
9093
+ this.blendEquation = AddEquation;
9094
+ this.blendSrcAlpha = null;
9095
+ this.blendDstAlpha = null;
9096
+ this.blendEquationAlpha = null;
9097
+ this.blendColor = new Color( 0, 0, 0 );
9098
+ this.blendAlpha = 0;
9124
9099
 
9125
- // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
9100
+ this.depthFunc = LessEqualDepth;
9101
+ this.depthTest = true;
9102
+ this.depthWrite = true;
9126
9103
 
9127
- handleAlpha( color[ 4 ] );
9104
+ this.stencilWriteMask = 0xff;
9105
+ this.stencilFunc = AlwaysStencilFunc;
9106
+ this.stencilRef = 0;
9107
+ this.stencilFuncMask = 0xff;
9108
+ this.stencilFail = KeepStencilOp;
9109
+ this.stencilZFail = KeepStencilOp;
9110
+ this.stencilZPass = KeepStencilOp;
9111
+ this.stencilWrite = false;
9128
9112
 
9129
- return this.setRGB(
9130
- Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100,
9131
- Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100,
9132
- Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100,
9133
- colorSpace
9134
- );
9113
+ this.clippingPlanes = null;
9114
+ this.clipIntersection = false;
9115
+ this.clipShadows = false;
9135
9116
 
9136
- }
9117
+ this.shadowSide = null;
9137
9118
 
9138
- break;
9119
+ this.colorWrite = true;
9139
9120
 
9140
- case 'hsl':
9141
- case 'hsla':
9121
+ this.precision = null; // override the renderer's default precision for this material
9142
9122
 
9143
- if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
9123
+ this.polygonOffset = false;
9124
+ this.polygonOffsetFactor = 0;
9125
+ this.polygonOffsetUnits = 0;
9144
9126
 
9145
- // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
9127
+ this.dithering = false;
9146
9128
 
9147
- handleAlpha( color[ 4 ] );
9129
+ this.alphaToCoverage = false;
9130
+ this.premultipliedAlpha = false;
9131
+ this.forceSinglePass = false;
9148
9132
 
9149
- return this.setHSL(
9150
- parseFloat( color[ 1 ] ) / 360,
9151
- parseFloat( color[ 2 ] ) / 100,
9152
- parseFloat( color[ 3 ] ) / 100,
9153
- colorSpace
9154
- );
9133
+ this.visible = true;
9155
9134
 
9156
- }
9135
+ this.toneMapped = true;
9157
9136
 
9158
- break;
9137
+ this.userData = {};
9159
9138
 
9160
- default:
9139
+ this.version = 0;
9161
9140
 
9162
- console.warn( 'THREE.Color: Unknown color model ' + style );
9141
+ this._alphaTest = 0;
9163
9142
 
9164
- }
9143
+ }
9165
9144
 
9166
- } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) {
9145
+ get alphaTest() {
9167
9146
 
9168
- // hex color
9147
+ return this._alphaTest;
9169
9148
 
9170
- const hex = m[ 1 ];
9171
- const size = hex.length;
9149
+ }
9172
9150
 
9173
- if ( size === 3 ) {
9151
+ set alphaTest( value ) {
9174
9152
 
9175
- // #ff0
9176
- return this.setRGB(
9177
- parseInt( hex.charAt( 0 ), 16 ) / 15,
9178
- parseInt( hex.charAt( 1 ), 16 ) / 15,
9179
- parseInt( hex.charAt( 2 ), 16 ) / 15,
9180
- colorSpace
9181
- );
9153
+ if ( this._alphaTest > 0 !== value > 0 ) {
9182
9154
 
9183
- } else if ( size === 6 ) {
9155
+ this.version ++;
9184
9156
 
9185
- // #ff0000
9186
- return this.setHex( parseInt( hex, 16 ), colorSpace );
9157
+ }
9187
9158
 
9188
- } else {
9159
+ this._alphaTest = value;
9189
9160
 
9190
- console.warn( 'THREE.Color: Invalid hex color ' + style );
9161
+ }
9191
9162
 
9192
- }
9163
+ onBuild( /* shaderobject, renderer */ ) {}
9193
9164
 
9194
- } else if ( style && style.length > 0 ) {
9165
+ onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {}
9195
9166
 
9196
- return this.setColorName( style, colorSpace );
9167
+ onBeforeCompile( /* shaderobject, renderer */ ) {}
9197
9168
 
9198
- }
9169
+ customProgramCacheKey() {
9199
9170
 
9200
- return this;
9171
+ return this.onBeforeCompile.toString();
9201
9172
 
9202
9173
  }
9203
9174
 
9204
- setColorName( style, colorSpace = SRGBColorSpace ) {
9205
-
9206
- // color keywords
9207
- const hex = _colorKeywords[ style.toLowerCase() ];
9175
+ setValues( values ) {
9208
9176
 
9209
- if ( hex !== undefined ) {
9177
+ if ( values === undefined ) return;
9210
9178
 
9211
- // red
9212
- this.setHex( hex, colorSpace );
9179
+ for ( const key in values ) {
9213
9180
 
9214
- } else {
9181
+ const newValue = values[ key ];
9215
9182
 
9216
- // unknown color
9217
- console.warn( 'THREE.Color: Unknown color ' + style );
9183
+ if ( newValue === undefined ) {
9218
9184
 
9219
- }
9185
+ console.warn( `THREE.Material: parameter '${ key }' has value of undefined.` );
9186
+ continue;
9220
9187
 
9221
- return this;
9188
+ }
9222
9189
 
9223
- }
9190
+ const currentValue = this[ key ];
9224
9191
 
9225
- clone() {
9192
+ if ( currentValue === undefined ) {
9226
9193
 
9227
- return new this.constructor( this.r, this.g, this.b );
9194
+ console.warn( `THREE.Material: '${ key }' is not a property of THREE.${ this.type }.` );
9195
+ continue;
9228
9196
 
9229
- }
9197
+ }
9230
9198
 
9231
- copy( color ) {
9199
+ if ( currentValue && currentValue.isColor ) {
9232
9200
 
9233
- this.r = color.r;
9234
- this.g = color.g;
9235
- this.b = color.b;
9201
+ currentValue.set( newValue );
9236
9202
 
9237
- return this;
9203
+ } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
9238
9204
 
9239
- }
9205
+ currentValue.copy( newValue );
9240
9206
 
9241
- copySRGBToLinear( color ) {
9207
+ } else {
9242
9208
 
9243
- this.r = SRGBToLinear( color.r );
9244
- this.g = SRGBToLinear( color.g );
9245
- this.b = SRGBToLinear( color.b );
9209
+ this[ key ] = newValue;
9246
9210
 
9247
- return this;
9211
+ }
9212
+
9213
+ }
9248
9214
 
9249
9215
  }
9250
9216
 
9251
- copyLinearToSRGB( color ) {
9217
+ toJSON( meta ) {
9252
9218
 
9253
- this.r = LinearToSRGB( color.r );
9254
- this.g = LinearToSRGB( color.g );
9255
- this.b = LinearToSRGB( color.b );
9219
+ const isRootObject = ( meta === undefined || typeof meta === 'string' );
9256
9220
 
9257
- return this;
9221
+ if ( isRootObject ) {
9258
9222
 
9259
- }
9223
+ meta = {
9224
+ textures: {},
9225
+ images: {}
9226
+ };
9260
9227
 
9261
- convertSRGBToLinear() {
9228
+ }
9262
9229
 
9263
- this.copySRGBToLinear( this );
9230
+ const data = {
9231
+ metadata: {
9232
+ version: 4.6,
9233
+ type: 'Material',
9234
+ generator: 'Material.toJSON'
9235
+ }
9236
+ };
9264
9237
 
9265
- return this;
9238
+ // standard Material serialization
9239
+ data.uuid = this.uuid;
9240
+ data.type = this.type;
9266
9241
 
9267
- }
9242
+ if ( this.name !== '' ) data.name = this.name;
9268
9243
 
9269
- convertLinearToSRGB() {
9244
+ if ( this.color && this.color.isColor ) data.color = this.color.getHex();
9270
9245
 
9271
- this.copyLinearToSRGB( this );
9246
+ if ( this.roughness !== undefined ) data.roughness = this.roughness;
9247
+ if ( this.metalness !== undefined ) data.metalness = this.metalness;
9272
9248
 
9273
- return this;
9249
+ if ( this.sheen !== undefined ) data.sheen = this.sheen;
9250
+ if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex();
9251
+ if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness;
9252
+ if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
9253
+ if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;
9274
9254
 
9275
- }
9255
+ if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
9256
+ if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity;
9257
+ if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex();
9258
+ if ( this.shininess !== undefined ) data.shininess = this.shininess;
9259
+ if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat;
9260
+ if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness;
9276
9261
 
9277
- getHex( colorSpace = SRGBColorSpace ) {
9262
+ if ( this.clearcoatMap && this.clearcoatMap.isTexture ) {
9278
9263
 
9279
- ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
9264
+ data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid;
9280
9265
 
9281
- 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 ) );
9266
+ }
9282
9267
 
9283
- }
9268
+ if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) {
9284
9269
 
9285
- getHexString( colorSpace = SRGBColorSpace ) {
9270
+ data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid;
9286
9271
 
9287
- return ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( - 6 );
9272
+ }
9288
9273
 
9289
- }
9274
+ if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) {
9290
9275
 
9291
- getHSL( target, colorSpace = ColorManagement.workingColorSpace ) {
9276
+ data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid;
9277
+ data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
9292
9278
 
9293
- // h,s,l ranges are in 0.0 - 1.0
9279
+ }
9294
9280
 
9295
- ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
9281
+ if ( this.iridescence !== undefined ) data.iridescence = this.iridescence;
9282
+ if ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR;
9283
+ if ( this.iridescenceThicknessRange !== undefined ) data.iridescenceThicknessRange = this.iridescenceThicknessRange;
9296
9284
 
9297
- const r = _color.r, g = _color.g, b = _color.b;
9285
+ if ( this.iridescenceMap && this.iridescenceMap.isTexture ) {
9298
9286
 
9299
- const max = Math.max( r, g, b );
9300
- const min = Math.min( r, g, b );
9287
+ data.iridescenceMap = this.iridescenceMap.toJSON( meta ).uuid;
9301
9288
 
9302
- let hue, saturation;
9303
- const lightness = ( min + max ) / 2.0;
9289
+ }
9304
9290
 
9305
- if ( min === max ) {
9291
+ if ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) {
9306
9292
 
9307
- hue = 0;
9308
- saturation = 0;
9293
+ data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid;
9309
9294
 
9310
- } else {
9295
+ }
9311
9296
 
9312
- const delta = max - min;
9297
+ if ( this.anisotropy !== undefined ) data.anisotropy = this.anisotropy;
9298
+ if ( this.anisotropyRotation !== undefined ) data.anisotropyRotation = this.anisotropyRotation;
9313
9299
 
9314
- saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
9300
+ if ( this.anisotropyMap && this.anisotropyMap.isTexture ) {
9315
9301
 
9316
- switch ( max ) {
9302
+ data.anisotropyMap = this.anisotropyMap.toJSON( meta ).uuid;
9317
9303
 
9318
- case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
9319
- case g: hue = ( b - r ) / delta + 2; break;
9320
- case b: hue = ( r - g ) / delta + 4; break;
9304
+ }
9321
9305
 
9322
- }
9306
+ if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
9307
+ if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid;
9308
+ if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
9323
9309
 
9324
- hue /= 6;
9310
+ if ( this.lightMap && this.lightMap.isTexture ) {
9311
+
9312
+ data.lightMap = this.lightMap.toJSON( meta ).uuid;
9313
+ data.lightMapIntensity = this.lightMapIntensity;
9325
9314
 
9326
9315
  }
9327
9316
 
9328
- target.h = hue;
9329
- target.s = saturation;
9330
- target.l = lightness;
9317
+ if ( this.aoMap && this.aoMap.isTexture ) {
9331
9318
 
9332
- return target;
9319
+ data.aoMap = this.aoMap.toJSON( meta ).uuid;
9320
+ data.aoMapIntensity = this.aoMapIntensity;
9333
9321
 
9334
- }
9322
+ }
9335
9323
 
9336
- getRGB( target, colorSpace = ColorManagement.workingColorSpace ) {
9324
+ if ( this.bumpMap && this.bumpMap.isTexture ) {
9337
9325
 
9338
- ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
9326
+ data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
9327
+ data.bumpScale = this.bumpScale;
9339
9328
 
9340
- target.r = _color.r;
9341
- target.g = _color.g;
9342
- target.b = _color.b;
9329
+ }
9343
9330
 
9344
- return target;
9331
+ if ( this.normalMap && this.normalMap.isTexture ) {
9345
9332
 
9346
- }
9333
+ data.normalMap = this.normalMap.toJSON( meta ).uuid;
9334
+ data.normalMapType = this.normalMapType;
9335
+ data.normalScale = this.normalScale.toArray();
9347
9336
 
9348
- getStyle( colorSpace = SRGBColorSpace ) {
9337
+ }
9349
9338
 
9350
- ColorManagement.fromWorkingColorSpace( _color.copy( this ), colorSpace );
9339
+ if ( this.displacementMap && this.displacementMap.isTexture ) {
9351
9340
 
9352
- const r = _color.r, g = _color.g, b = _color.b;
9341
+ data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
9342
+ data.displacementScale = this.displacementScale;
9343
+ data.displacementBias = this.displacementBias;
9353
9344
 
9354
- if ( colorSpace !== SRGBColorSpace ) {
9345
+ }
9355
9346
 
9356
- // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/).
9357
- return `color(${ colorSpace } ${ r.toFixed( 3 ) } ${ g.toFixed( 3 ) } ${ b.toFixed( 3 ) })`;
9347
+ if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
9348
+ if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
9358
9349
 
9359
- }
9350
+ if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
9351
+ if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
9352
+ if ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid;
9353
+ if ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid;
9360
9354
 
9361
- return `rgb(${ Math.round( r * 255 ) },${ Math.round( g * 255 ) },${ Math.round( b * 255 ) })`;
9355
+ if ( this.envMap && this.envMap.isTexture ) {
9362
9356
 
9363
- }
9357
+ data.envMap = this.envMap.toJSON( meta ).uuid;
9364
9358
 
9365
- offsetHSL( h, s, l ) {
9359
+ if ( this.combine !== undefined ) data.combine = this.combine;
9366
9360
 
9367
- this.getHSL( _hslA );
9361
+ }
9368
9362
 
9369
- return this.setHSL( _hslA.h + h, _hslA.s + s, _hslA.l + l );
9363
+ if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity;
9364
+ if ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity;
9365
+ if ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio;
9370
9366
 
9371
- }
9367
+ if ( this.gradientMap && this.gradientMap.isTexture ) {
9372
9368
 
9373
- add( color ) {
9369
+ data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
9374
9370
 
9375
- this.r += color.r;
9376
- this.g += color.g;
9377
- this.b += color.b;
9371
+ }
9378
9372
 
9379
- return this;
9373
+ if ( this.transmission !== undefined ) data.transmission = this.transmission;
9374
+ if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid;
9375
+ if ( this.thickness !== undefined ) data.thickness = this.thickness;
9376
+ if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid;
9377
+ if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance;
9378
+ if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex();
9380
9379
 
9381
- }
9380
+ if ( this.size !== undefined ) data.size = this.size;
9381
+ if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide;
9382
+ if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
9382
9383
 
9383
- addColors( color1, color2 ) {
9384
+ if ( this.blending !== NormalBlending ) data.blending = this.blending;
9385
+ if ( this.side !== FrontSide ) data.side = this.side;
9386
+ if ( this.vertexColors === true ) data.vertexColors = true;
9384
9387
 
9385
- this.r = color1.r + color2.r;
9386
- this.g = color1.g + color2.g;
9387
- this.b = color1.b + color2.b;
9388
+ if ( this.opacity < 1 ) data.opacity = this.opacity;
9389
+ if ( this.transparent === true ) data.transparent = true;
9388
9390
 
9389
- return this;
9391
+ if ( this.blendSrc !== SrcAlphaFactor ) data.blendSrc = this.blendSrc;
9392
+ if ( this.blendDst !== OneMinusSrcAlphaFactor ) data.blendDst = this.blendDst;
9393
+ if ( this.blendEquation !== AddEquation ) data.blendEquation = this.blendEquation;
9394
+ if ( this.blendSrcAlpha !== null ) data.blendSrcAlpha = this.blendSrcAlpha;
9395
+ if ( this.blendDstAlpha !== null ) data.blendDstAlpha = this.blendDstAlpha;
9396
+ if ( this.blendEquationAlpha !== null ) data.blendEquationAlpha = this.blendEquationAlpha;
9397
+ if ( this.blendColor && this.blendColor.isColor ) data.blendColor = this.blendColor.getHex();
9398
+ if ( this.blendAlpha !== 0 ) data.blendAlpha = this.blendAlpha;
9399
+
9400
+ if ( this.depthFunc !== LessEqualDepth ) data.depthFunc = this.depthFunc;
9401
+ if ( this.depthTest === false ) data.depthTest = this.depthTest;
9402
+ if ( this.depthWrite === false ) data.depthWrite = this.depthWrite;
9403
+ if ( this.colorWrite === false ) data.colorWrite = this.colorWrite;
9404
+
9405
+ if ( this.stencilWriteMask !== 0xff ) data.stencilWriteMask = this.stencilWriteMask;
9406
+ if ( this.stencilFunc !== AlwaysStencilFunc ) data.stencilFunc = this.stencilFunc;
9407
+ if ( this.stencilRef !== 0 ) data.stencilRef = this.stencilRef;
9408
+ if ( this.stencilFuncMask !== 0xff ) data.stencilFuncMask = this.stencilFuncMask;
9409
+ if ( this.stencilFail !== KeepStencilOp ) data.stencilFail = this.stencilFail;
9410
+ if ( this.stencilZFail !== KeepStencilOp ) data.stencilZFail = this.stencilZFail;
9411
+ if ( this.stencilZPass !== KeepStencilOp ) data.stencilZPass = this.stencilZPass;
9412
+ if ( this.stencilWrite === true ) data.stencilWrite = this.stencilWrite;
9390
9413
 
9391
- }
9414
+ // rotation (SpriteMaterial)
9415
+ if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation;
9392
9416
 
9393
- addScalar( s ) {
9417
+ if ( this.polygonOffset === true ) data.polygonOffset = true;
9418
+ if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor;
9419
+ if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits;
9394
9420
 
9395
- this.r += s;
9396
- this.g += s;
9397
- this.b += s;
9421
+ if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth;
9422
+ if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
9423
+ if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
9424
+ if ( this.scale !== undefined ) data.scale = this.scale;
9398
9425
 
9399
- return this;
9426
+ if ( this.dithering === true ) data.dithering = true;
9400
9427
 
9401
- }
9428
+ if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
9429
+ if ( this.alphaHash === true ) data.alphaHash = true;
9430
+ if ( this.alphaToCoverage === true ) data.alphaToCoverage = true;
9431
+ if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = true;
9432
+ if ( this.forceSinglePass === true ) data.forceSinglePass = true;
9402
9433
 
9403
- sub( color ) {
9434
+ if ( this.wireframe === true ) data.wireframe = true;
9435
+ if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
9436
+ if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
9437
+ if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
9404
9438
 
9405
- this.r = Math.max( 0, this.r - color.r );
9406
- this.g = Math.max( 0, this.g - color.g );
9407
- this.b = Math.max( 0, this.b - color.b );
9439
+ if ( this.flatShading === true ) data.flatShading = true;
9408
9440
 
9409
- return this;
9441
+ if ( this.visible === false ) data.visible = false;
9410
9442
 
9411
- }
9443
+ if ( this.toneMapped === false ) data.toneMapped = false;
9412
9444
 
9413
- multiply( color ) {
9445
+ if ( this.fog === false ) data.fog = false;
9414
9446
 
9415
- this.r *= color.r;
9416
- this.g *= color.g;
9417
- this.b *= color.b;
9447
+ if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData;
9418
9448
 
9419
- return this;
9449
+ // TODO: Copied from Object3D.toJSON
9420
9450
 
9421
- }
9451
+ function extractFromCache( cache ) {
9422
9452
 
9423
- multiplyScalar( s ) {
9453
+ const values = [];
9424
9454
 
9425
- this.r *= s;
9426
- this.g *= s;
9427
- this.b *= s;
9455
+ for ( const key in cache ) {
9428
9456
 
9429
- return this;
9457
+ const data = cache[ key ];
9458
+ delete data.metadata;
9459
+ values.push( data );
9430
9460
 
9431
- }
9461
+ }
9432
9462
 
9433
- lerp( color, alpha ) {
9463
+ return values;
9434
9464
 
9435
- this.r += ( color.r - this.r ) * alpha;
9436
- this.g += ( color.g - this.g ) * alpha;
9437
- this.b += ( color.b - this.b ) * alpha;
9465
+ }
9438
9466
 
9439
- return this;
9467
+ if ( isRootObject ) {
9440
9468
 
9441
- }
9469
+ const textures = extractFromCache( meta.textures );
9470
+ const images = extractFromCache( meta.images );
9442
9471
 
9443
- lerpColors( color1, color2, alpha ) {
9472
+ if ( textures.length > 0 ) data.textures = textures;
9473
+ if ( images.length > 0 ) data.images = images;
9444
9474
 
9445
- this.r = color1.r + ( color2.r - color1.r ) * alpha;
9446
- this.g = color1.g + ( color2.g - color1.g ) * alpha;
9447
- this.b = color1.b + ( color2.b - color1.b ) * alpha;
9475
+ }
9448
9476
 
9449
- return this;
9477
+ return data;
9450
9478
 
9451
9479
  }
9452
9480
 
9453
- lerpHSL( color, alpha ) {
9454
-
9455
- this.getHSL( _hslA );
9456
- color.getHSL( _hslB );
9481
+ clone() {
9457
9482
 
9458
- const h = lerp( _hslA.h, _hslB.h, alpha );
9459
- const s = lerp( _hslA.s, _hslB.s, alpha );
9460
- const l = lerp( _hslA.l, _hslB.l, alpha );
9483
+ return new this.constructor().copy( this );
9461
9484
 
9462
- this.setHSL( h, s, l );
9485
+ }
9463
9486
 
9464
- return this;
9487
+ copy( source ) {
9465
9488
 
9466
- }
9489
+ this.name = source.name;
9467
9490
 
9468
- setFromVector3( v ) {
9491
+ this.blending = source.blending;
9492
+ this.side = source.side;
9493
+ this.vertexColors = source.vertexColors;
9469
9494
 
9470
- this.r = v.x;
9471
- this.g = v.y;
9472
- this.b = v.z;
9495
+ this.opacity = source.opacity;
9496
+ this.transparent = source.transparent;
9473
9497
 
9474
- return this;
9498
+ this.blendSrc = source.blendSrc;
9499
+ this.blendDst = source.blendDst;
9500
+ this.blendEquation = source.blendEquation;
9501
+ this.blendSrcAlpha = source.blendSrcAlpha;
9502
+ this.blendDstAlpha = source.blendDstAlpha;
9503
+ this.blendEquationAlpha = source.blendEquationAlpha;
9504
+ this.blendColor.copy( source.blendColor );
9505
+ this.blendAlpha = source.blendAlpha;
9475
9506
 
9476
- }
9507
+ this.depthFunc = source.depthFunc;
9508
+ this.depthTest = source.depthTest;
9509
+ this.depthWrite = source.depthWrite;
9477
9510
 
9478
- applyMatrix3( m ) {
9511
+ this.stencilWriteMask = source.stencilWriteMask;
9512
+ this.stencilFunc = source.stencilFunc;
9513
+ this.stencilRef = source.stencilRef;
9514
+ this.stencilFuncMask = source.stencilFuncMask;
9515
+ this.stencilFail = source.stencilFail;
9516
+ this.stencilZFail = source.stencilZFail;
9517
+ this.stencilZPass = source.stencilZPass;
9518
+ this.stencilWrite = source.stencilWrite;
9479
9519
 
9480
- const r = this.r, g = this.g, b = this.b;
9481
- const e = m.elements;
9520
+ const srcPlanes = source.clippingPlanes;
9521
+ let dstPlanes = null;
9482
9522
 
9483
- this.r = e[ 0 ] * r + e[ 3 ] * g + e[ 6 ] * b;
9484
- this.g = e[ 1 ] * r + e[ 4 ] * g + e[ 7 ] * b;
9485
- this.b = e[ 2 ] * r + e[ 5 ] * g + e[ 8 ] * b;
9523
+ if ( srcPlanes !== null ) {
9486
9524
 
9487
- return this;
9525
+ const n = srcPlanes.length;
9526
+ dstPlanes = new Array( n );
9488
9527
 
9489
- }
9528
+ for ( let i = 0; i !== n; ++ i ) {
9490
9529
 
9491
- equals( c ) {
9530
+ dstPlanes[ i ] = srcPlanes[ i ].clone();
9492
9531
 
9493
- return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
9532
+ }
9494
9533
 
9495
- }
9534
+ }
9496
9535
 
9497
- fromArray( array, offset = 0 ) {
9536
+ this.clippingPlanes = dstPlanes;
9537
+ this.clipIntersection = source.clipIntersection;
9538
+ this.clipShadows = source.clipShadows;
9498
9539
 
9499
- this.r = array[ offset ];
9500
- this.g = array[ offset + 1 ];
9501
- this.b = array[ offset + 2 ];
9540
+ this.shadowSide = source.shadowSide;
9502
9541
 
9503
- return this;
9542
+ this.colorWrite = source.colorWrite;
9504
9543
 
9505
- }
9544
+ this.precision = source.precision;
9506
9545
 
9507
- toArray( array = [], offset = 0 ) {
9546
+ this.polygonOffset = source.polygonOffset;
9547
+ this.polygonOffsetFactor = source.polygonOffsetFactor;
9548
+ this.polygonOffsetUnits = source.polygonOffsetUnits;
9508
9549
 
9509
- array[ offset ] = this.r;
9510
- array[ offset + 1 ] = this.g;
9511
- array[ offset + 2 ] = this.b;
9550
+ this.dithering = source.dithering;
9512
9551
 
9513
- return array;
9552
+ this.alphaTest = source.alphaTest;
9553
+ this.alphaHash = source.alphaHash;
9554
+ this.alphaToCoverage = source.alphaToCoverage;
9555
+ this.premultipliedAlpha = source.premultipliedAlpha;
9556
+ this.forceSinglePass = source.forceSinglePass;
9514
9557
 
9515
- }
9558
+ this.visible = source.visible;
9516
9559
 
9517
- fromBufferAttribute( attribute, index ) {
9560
+ this.toneMapped = source.toneMapped;
9518
9561
 
9519
- this.r = attribute.getX( index );
9520
- this.g = attribute.getY( index );
9521
- this.b = attribute.getZ( index );
9562
+ this.userData = JSON.parse( JSON.stringify( source.userData ) );
9522
9563
 
9523
9564
  return this;
9524
9565
 
9525
9566
  }
9526
9567
 
9527
- toJSON() {
9568
+ dispose() {
9528
9569
 
9529
- return this.getHex();
9570
+ this.dispatchEvent( { type: 'dispose' } );
9530
9571
 
9531
9572
  }
9532
9573
 
9533
- *[ Symbol.iterator ]() {
9574
+ set needsUpdate( value ) {
9534
9575
 
9535
- yield this.r;
9536
- yield this.g;
9537
- yield this.b;
9576
+ if ( value === true ) this.version ++;
9538
9577
 
9539
9578
  }
9540
9579
 
9541
9580
  }
9542
9581
 
9543
- const _color = /*@__PURE__*/ new Color();
9544
-
9545
- Color.NAMES = _colorKeywords;
9546
-
9547
9582
  class MeshBasicMaterial extends Material {
9548
9583
 
9549
9584
  constructor( parameters ) {
@@ -13706,7 +13741,7 @@ var alphatest_fragment = "#ifdef USE_ALPHATEST\n\tif ( diffuseColor.a < alphaTes
13706
13741
 
13707
13742
  var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif";
13708
13743
 
13709
- 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";
13744
+ 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";
13710
13745
 
13711
13746
  var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
13712
13747
 
@@ -13718,7 +13753,7 @@ var bsdfs = "float G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnP
13718
13753
 
13719
13754
  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";
13720
13755
 
13721
- 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";
13756
+ 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";
13722
13757
 
13723
13758
  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";
13724
13759
 
@@ -13796,9 +13831,9 @@ var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhong
13796
13831
 
13797
13832
  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";
13798
13833
 
13799
- 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}";
13834
+ 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}";
13800
13835
 
13801
- 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";
13836
+ 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";
13802
13837
 
13803
13838
  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";
13804
13839
 
@@ -13954,7 +13989,7 @@ const fragment$6 = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;
13954
13989
 
13955
13990
  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}";
13956
13991
 
13957
- 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}";
13992
+ 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}";
13958
13993
 
13959
13994
  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}";
13960
13995
 
@@ -16129,6 +16164,8 @@ const MAX_SAMPLES = 20;
16129
16164
  const _flatCamera = /*@__PURE__*/ new OrthographicCamera();
16130
16165
  const _clearColor = /*@__PURE__*/ new Color();
16131
16166
  let _oldTarget = null;
16167
+ let _oldActiveCubeFace = 0;
16168
+ let _oldActiveMipmapLevel = 0;
16132
16169
 
16133
16170
  // Golden Ratio
16134
16171
  const PHI = ( 1 + Math.sqrt( 5 ) ) / 2;
@@ -16194,6 +16231,8 @@ class PMREMGenerator {
16194
16231
  fromScene( scene, sigma = 0, near = 0.1, far = 100 ) {
16195
16232
 
16196
16233
  _oldTarget = this._renderer.getRenderTarget();
16234
+ _oldActiveCubeFace = this._renderer.getActiveCubeFace();
16235
+ _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel();
16197
16236
 
16198
16237
  this._setSize( 256 );
16199
16238
 
@@ -16306,7 +16345,7 @@ class PMREMGenerator {
16306
16345
 
16307
16346
  _cleanup( outputTarget ) {
16308
16347
 
16309
- this._renderer.setRenderTarget( _oldTarget );
16348
+ this._renderer.setRenderTarget( _oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel );
16310
16349
  outputTarget.scissorTest = false;
16311
16350
  _setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height );
16312
16351
 
@@ -16325,6 +16364,8 @@ class PMREMGenerator {
16325
16364
  }
16326
16365
 
16327
16366
  _oldTarget = this._renderer.getRenderTarget();
16367
+ _oldActiveCubeFace = this._renderer.getActiveCubeFace();
16368
+ _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel();
16328
16369
 
16329
16370
  const cubeUVRenderTarget = renderTarget || this._allocateTargets();
16330
16371
  this._textureToCubeUV( texture, cubeUVRenderTarget );
@@ -19184,6 +19225,9 @@ function WebGLShader( gl, type, string ) {
19184
19225
 
19185
19226
  }
19186
19227
 
19228
+ // From https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/
19229
+ const COMPLETION_STATUS_KHR = 0x91B1;
19230
+
19187
19231
  let programIdCount = 0;
19188
19232
 
19189
19233
  function handleSource( string, errorLine ) {
@@ -20028,6 +20072,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20028
20072
  ].join( '\n' ) + '\n' + prefixVertex;
20029
20073
 
20030
20074
  prefixFragment = [
20075
+ 'precision mediump sampler2DArray;',
20031
20076
  '#define varying in',
20032
20077
  ( parameters.glslVersion === GLSL3 ) ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;',
20033
20078
  ( parameters.glslVersion === GLSL3 ) ? '' : '#define gl_FragColor pc_fragColor',
@@ -20119,87 +20164,94 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20119
20164
 
20120
20165
  gl.linkProgram( program );
20121
20166
 
20122
- // check for link errors
20123
- if ( renderer.debug.checkShaderErrors ) {
20167
+ function onFirstUse( self ) {
20124
20168
 
20125
- const programLog = gl.getProgramInfoLog( program ).trim();
20126
- const vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
20127
- const fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
20169
+ // check for link errors
20170
+ if ( renderer.debug.checkShaderErrors ) {
20128
20171
 
20129
- let runnable = true;
20130
- let haveDiagnostics = true;
20172
+ const programLog = gl.getProgramInfoLog( program ).trim();
20173
+ const vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
20174
+ const fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
20131
20175
 
20132
- if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
20176
+ let runnable = true;
20177
+ let haveDiagnostics = true;
20133
20178
 
20134
- runnable = false;
20179
+ if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
20135
20180
 
20136
- if ( typeof renderer.debug.onShaderError === 'function' ) {
20181
+ runnable = false;
20137
20182
 
20138
- renderer.debug.onShaderError( gl, program, glVertexShader, glFragmentShader );
20183
+ if ( typeof renderer.debug.onShaderError === 'function' ) {
20139
20184
 
20140
- } else {
20185
+ renderer.debug.onShaderError( gl, program, glVertexShader, glFragmentShader );
20141
20186
 
20142
- // default error reporting
20187
+ } else {
20143
20188
 
20144
- const vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
20145
- const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
20189
+ // default error reporting
20146
20190
 
20147
- console.error(
20148
- 'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' +
20149
- 'VALIDATE_STATUS ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) + '\n\n' +
20150
- 'Program Info Log: ' + programLog + '\n' +
20151
- vertexErrors + '\n' +
20152
- fragmentErrors
20153
- );
20191
+ const vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
20192
+ const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
20154
20193
 
20155
- }
20194
+ console.error(
20195
+ 'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' +
20196
+ 'VALIDATE_STATUS ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) + '\n\n' +
20197
+ 'Program Info Log: ' + programLog + '\n' +
20198
+ vertexErrors + '\n' +
20199
+ fragmentErrors
20200
+ );
20201
+
20202
+ }
20156
20203
 
20157
- } else if ( programLog !== '' ) {
20204
+ } else if ( programLog !== '' ) {
20158
20205
 
20159
- console.warn( 'THREE.WebGLProgram: Program Info Log:', programLog );
20206
+ console.warn( 'THREE.WebGLProgram: Program Info Log:', programLog );
20160
20207
 
20161
- } else if ( vertexLog === '' || fragmentLog === '' ) {
20208
+ } else if ( vertexLog === '' || fragmentLog === '' ) {
20162
20209
 
20163
- haveDiagnostics = false;
20210
+ haveDiagnostics = false;
20164
20211
 
20165
- }
20212
+ }
20166
20213
 
20167
- if ( haveDiagnostics ) {
20214
+ if ( haveDiagnostics ) {
20168
20215
 
20169
- this.diagnostics = {
20216
+ self.diagnostics = {
20170
20217
 
20171
- runnable: runnable,
20218
+ runnable: runnable,
20172
20219
 
20173
- programLog: programLog,
20220
+ programLog: programLog,
20174
20221
 
20175
- vertexShader: {
20222
+ vertexShader: {
20176
20223
 
20177
- log: vertexLog,
20178
- prefix: prefixVertex
20224
+ log: vertexLog,
20225
+ prefix: prefixVertex
20179
20226
 
20180
- },
20227
+ },
20181
20228
 
20182
- fragmentShader: {
20229
+ fragmentShader: {
20183
20230
 
20184
- log: fragmentLog,
20185
- prefix: prefixFragment
20231
+ log: fragmentLog,
20232
+ prefix: prefixFragment
20186
20233
 
20187
- }
20234
+ }
20188
20235
 
20189
- };
20236
+ };
20237
+
20238
+ }
20190
20239
 
20191
20240
  }
20192
20241
 
20193
- }
20242
+ // Clean up
20243
+
20244
+ // Crashes in iOS9 and iOS10. #18402
20245
+ // gl.detachShader( program, glVertexShader );
20246
+ // gl.detachShader( program, glFragmentShader );
20194
20247
 
20195
- // Clean up
20248
+ gl.deleteShader( glVertexShader );
20249
+ gl.deleteShader( glFragmentShader );
20196
20250
 
20197
- // Crashes in iOS9 and iOS10. #18402
20198
- // gl.detachShader( program, glVertexShader );
20199
- // gl.detachShader( program, glFragmentShader );
20251
+ cachedUniforms = new WebGLUniforms( gl, program );
20252
+ cachedAttributes = fetchAttributeLocations( gl, program );
20200
20253
 
20201
- gl.deleteShader( glVertexShader );
20202
- gl.deleteShader( glFragmentShader );
20254
+ }
20203
20255
 
20204
20256
  // set up caching for uniform locations
20205
20257
 
@@ -20209,7 +20261,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20209
20261
 
20210
20262
  if ( cachedUniforms === undefined ) {
20211
20263
 
20212
- cachedUniforms = new WebGLUniforms( gl, program );
20264
+ // Populates cachedUniforms and cachedAttributes
20265
+ onFirstUse( this );
20213
20266
 
20214
20267
  }
20215
20268
 
@@ -20225,7 +20278,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20225
20278
 
20226
20279
  if ( cachedAttributes === undefined ) {
20227
20280
 
20228
- cachedAttributes = fetchAttributeLocations( gl, program );
20281
+ // Populates cachedAttributes and cachedUniforms
20282
+ onFirstUse( this );
20229
20283
 
20230
20284
  }
20231
20285
 
@@ -20233,6 +20287,23 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20233
20287
 
20234
20288
  };
20235
20289
 
20290
+ // indicate when the program is ready to be used. if the KHR_parallel_shader_compile extension isn't supported,
20291
+ // flag the program as ready immediately. It may cause a stall when it's first used.
20292
+
20293
+ let programReady = ( parameters.rendererExtensionParallelShaderCompile === false );
20294
+
20295
+ this.isReady = function () {
20296
+
20297
+ if ( programReady === false ) {
20298
+
20299
+ programReady = gl.getProgramParameter( program, COMPLETION_STATUS_KHR );
20300
+
20301
+ }
20302
+
20303
+ return programReady;
20304
+
20305
+ };
20306
+
20236
20307
  // free resource
20237
20308
 
20238
20309
  this.destroy = function () {
@@ -20738,6 +20809,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20738
20809
  rendererExtensionFragDepth: IS_WEBGL2 || extensions.has( 'EXT_frag_depth' ),
20739
20810
  rendererExtensionDrawBuffers: IS_WEBGL2 || extensions.has( 'WEBGL_draw_buffers' ),
20740
20811
  rendererExtensionShaderTextureLod: IS_WEBGL2 || extensions.has( 'EXT_shader_texture_lod' ),
20812
+ rendererExtensionParallelShaderCompile: extensions.has( 'KHR_parallel_shader_compile' ),
20741
20813
 
20742
20814
  customProgramCacheKey: material.customProgramCacheKey()
20743
20815
 
@@ -20880,6 +20952,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20880
20952
  _programLayers.enable( 16 );
20881
20953
  if ( parameters.anisotropy )
20882
20954
  _programLayers.enable( 17 );
20955
+ if ( parameters.alphaHash )
20956
+ _programLayers.enable( 18 );
20883
20957
 
20884
20958
  array.push( _programLayers.mask );
20885
20959
  _programLayers.disableAll();
@@ -22773,6 +22847,8 @@ function WebGLState( gl, extensions, capabilities ) {
22773
22847
  let currentBlendEquationAlpha = null;
22774
22848
  let currentBlendSrcAlpha = null;
22775
22849
  let currentBlendDstAlpha = null;
22850
+ let currentBlendColor = new Color( 0, 0, 0 );
22851
+ let currentBlendAlpha = 0;
22776
22852
  let currentPremultipledAlpha = false;
22777
22853
 
22778
22854
  let currentFlipSided = null;
@@ -23048,10 +23124,14 @@ function WebGLState( gl, extensions, capabilities ) {
23048
23124
  [ OneMinusSrcColorFactor ]: gl.ONE_MINUS_SRC_COLOR,
23049
23125
  [ OneMinusSrcAlphaFactor ]: gl.ONE_MINUS_SRC_ALPHA,
23050
23126
  [ OneMinusDstColorFactor ]: gl.ONE_MINUS_DST_COLOR,
23051
- [ OneMinusDstAlphaFactor ]: gl.ONE_MINUS_DST_ALPHA
23127
+ [ OneMinusDstAlphaFactor ]: gl.ONE_MINUS_DST_ALPHA,
23128
+ [ ConstantColorFactor ]: gl.CONSTANT_COLOR,
23129
+ [ OneMinusConstantColorFactor ]: gl.ONE_MINUS_CONSTANT_COLOR,
23130
+ [ ConstantAlphaFactor ]: gl.CONSTANT_ALPHA,
23131
+ [ OneMinusConstantAlphaFactor ]: gl.ONE_MINUS_CONSTANT_ALPHA
23052
23132
  };
23053
23133
 
23054
- function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
23134
+ function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, blendColor, blendAlpha, premultipliedAlpha ) {
23055
23135
 
23056
23136
  if ( blending === NoBlending ) {
23057
23137
 
@@ -23144,6 +23224,8 @@ function WebGLState( gl, extensions, capabilities ) {
23144
23224
  currentBlendDst = null;
23145
23225
  currentBlendSrcAlpha = null;
23146
23226
  currentBlendDstAlpha = null;
23227
+ currentBlendColor.set( 0, 0, 0 );
23228
+ currentBlendAlpha = 0;
23147
23229
 
23148
23230
  currentBlending = blending;
23149
23231
  currentPremultipledAlpha = premultipliedAlpha;
@@ -23180,6 +23262,15 @@ function WebGLState( gl, extensions, capabilities ) {
23180
23262
 
23181
23263
  }
23182
23264
 
23265
+ if ( blendColor.equals( currentBlendColor ) === false || blendAlpha !== currentBlendAlpha ) {
23266
+
23267
+ gl.blendColor( blendColor.r, blendColor.g, blendColor.b, blendAlpha );
23268
+
23269
+ currentBlendColor.copy( blendColor );
23270
+ currentBlendAlpha = blendAlpha;
23271
+
23272
+ }
23273
+
23183
23274
  currentBlending = blending;
23184
23275
  currentPremultipledAlpha = false;
23185
23276
 
@@ -23198,7 +23289,7 @@ function WebGLState( gl, extensions, capabilities ) {
23198
23289
 
23199
23290
  ( material.blending === NormalBlending && material.transparent === false )
23200
23291
  ? setBlending( NoBlending )
23201
- : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha );
23292
+ : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.blendColor, material.blendAlpha, material.premultipliedAlpha );
23202
23293
 
23203
23294
  depthBuffer.setFunc( material.depthFunc );
23204
23295
  depthBuffer.setTest( material.depthTest );
@@ -23622,6 +23713,7 @@ function WebGLState( gl, extensions, capabilities ) {
23622
23713
  gl.blendEquation( gl.FUNC_ADD );
23623
23714
  gl.blendFunc( gl.ONE, gl.ZERO );
23624
23715
  gl.blendFuncSeparate( gl.ONE, gl.ZERO, gl.ONE, gl.ZERO );
23716
+ gl.blendColor( 0, 0, 0, 0 );
23625
23717
 
23626
23718
  gl.colorMask( true, true, true, true );
23627
23719
  gl.clearColor( 0, 0, 0, 0 );
@@ -23679,6 +23771,8 @@ function WebGLState( gl, extensions, capabilities ) {
23679
23771
  currentBlendEquationAlpha = null;
23680
23772
  currentBlendSrcAlpha = null;
23681
23773
  currentBlendDstAlpha = null;
23774
+ currentBlendColor = new Color( 0, 0, 0 );
23775
+ currentBlendAlpha = 0;
23682
23776
  currentPremultipledAlpha = false;
23683
23777
 
23684
23778
  currentFlipSided = null;
@@ -29665,7 +29759,12 @@ class WebGLRenderer {
29665
29759
  }
29666
29760
 
29667
29761
  if ( depth ) bits |= _gl.DEPTH_BUFFER_BIT;
29668
- if ( stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
29762
+ if ( stencil ) {
29763
+
29764
+ bits |= _gl.STENCIL_BUFFER_BIT;
29765
+ this.state.buffers.stencil.setMask( 0xffffffff );
29766
+
29767
+ }
29669
29768
 
29670
29769
  _gl.clear( bits );
29671
29770
 
@@ -29948,36 +30047,40 @@ class WebGLRenderer {
29948
30047
 
29949
30048
  // Compile
29950
30049
 
29951
- this.compile = function ( scene, camera ) {
30050
+ function prepareMaterial( material, scene, object ) {
30051
+
30052
+ if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
29952
30053
 
29953
- function prepare( material, scene, object ) {
30054
+ material.side = BackSide;
30055
+ material.needsUpdate = true;
30056
+ getProgram( material, scene, object );
29954
30057
 
29955
- if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
30058
+ material.side = FrontSide;
30059
+ material.needsUpdate = true;
30060
+ getProgram( material, scene, object );
29956
30061
 
29957
- material.side = BackSide;
29958
- material.needsUpdate = true;
29959
- getProgram( material, scene, object );
30062
+ material.side = DoubleSide;
29960
30063
 
29961
- material.side = FrontSide;
29962
- material.needsUpdate = true;
29963
- getProgram( material, scene, object );
30064
+ } else {
29964
30065
 
29965
- material.side = DoubleSide;
30066
+ getProgram( material, scene, object );
29966
30067
 
29967
- } else {
30068
+ }
29968
30069
 
29969
- getProgram( material, scene, object );
30070
+ }
29970
30071
 
29971
- }
30072
+ this.compile = function ( scene, camera, targetScene = null ) {
29972
30073
 
29973
- }
30074
+ if ( targetScene === null ) targetScene = scene;
29974
30075
 
29975
- currentRenderState = renderStates.get( scene );
30076
+ currentRenderState = renderStates.get( targetScene );
29976
30077
  currentRenderState.init();
29977
30078
 
29978
30079
  renderStateStack.push( currentRenderState );
29979
30080
 
29980
- scene.traverseVisible( function ( object ) {
30081
+ // gather lights from both the target scene and the new object that will be added to the scene.
30082
+
30083
+ targetScene.traverseVisible( function ( object ) {
29981
30084
 
29982
30085
  if ( object.isLight && object.layers.test( camera.layers ) ) {
29983
30086
 
@@ -29993,8 +30096,32 @@ class WebGLRenderer {
29993
30096
 
29994
30097
  } );
29995
30098
 
30099
+ if ( scene !== targetScene ) {
30100
+
30101
+ scene.traverseVisible( function ( object ) {
30102
+
30103
+ if ( object.isLight && object.layers.test( camera.layers ) ) {
30104
+
30105
+ currentRenderState.pushLight( object );
30106
+
30107
+ if ( object.castShadow ) {
30108
+
30109
+ currentRenderState.pushShadow( object );
30110
+
30111
+ }
30112
+
30113
+ }
30114
+
30115
+ } );
30116
+
30117
+ }
30118
+
29996
30119
  currentRenderState.setupLights( _this._useLegacyLights );
29997
30120
 
30121
+ // Only initialize materials in the new scene, not the targetScene.
30122
+
30123
+ const materials = new Set();
30124
+
29998
30125
  scene.traverse( function ( object ) {
29999
30126
 
30000
30127
  const material = object.material;
@@ -30007,13 +30134,15 @@ class WebGLRenderer {
30007
30134
 
30008
30135
  const material2 = material[ i ];
30009
30136
 
30010
- prepare( material2, scene, object );
30137
+ prepareMaterial( material2, targetScene, object );
30138
+ materials.add( material2 );
30011
30139
 
30012
30140
  }
30013
30141
 
30014
30142
  } else {
30015
30143
 
30016
- prepare( material, scene, object );
30144
+ prepareMaterial( material, targetScene, object );
30145
+ materials.add( material );
30017
30146
 
30018
30147
  }
30019
30148
 
@@ -30024,6 +30153,70 @@ class WebGLRenderer {
30024
30153
  renderStateStack.pop();
30025
30154
  currentRenderState = null;
30026
30155
 
30156
+ return materials;
30157
+
30158
+ };
30159
+
30160
+ // compileAsync
30161
+
30162
+ this.compileAsync = function ( scene, camera, targetScene = null ) {
30163
+
30164
+ const materials = this.compile( scene, camera, targetScene );
30165
+
30166
+ // Wait for all the materials in the new object to indicate that they're
30167
+ // ready to be used before resolving the promise.
30168
+
30169
+ return new Promise( ( resolve ) => {
30170
+
30171
+ function checkMaterialsReady() {
30172
+
30173
+ materials.forEach( function ( material ) {
30174
+
30175
+ const materialProperties = properties.get( material );
30176
+ const program = materialProperties.currentProgram;
30177
+
30178
+ if ( program.isReady() ) {
30179
+
30180
+ // remove any programs that report they're ready to use from the list
30181
+ materials.delete( material );
30182
+
30183
+ }
30184
+
30185
+ } );
30186
+
30187
+ // once the list of compiling materials is empty, call the callback
30188
+
30189
+ if ( materials.size === 0 ) {
30190
+
30191
+ resolve( scene );
30192
+ return;
30193
+
30194
+ }
30195
+
30196
+ // if some materials are still not ready, wait a bit and check again
30197
+
30198
+ setTimeout( checkMaterialsReady, 10 );
30199
+
30200
+ }
30201
+
30202
+ if ( extensions.get( 'KHR_parallel_shader_compile' ) !== null ) {
30203
+
30204
+ // If we can check the compilation status of the materials without
30205
+ // blocking then do so right away.
30206
+
30207
+ checkMaterialsReady();
30208
+
30209
+ } else {
30210
+
30211
+ // Otherwise start by waiting a bit to give the materials we just
30212
+ // initialized a chance to finish.
30213
+
30214
+ setTimeout( checkMaterialsReady, 10 );
30215
+
30216
+ }
30217
+
30218
+ } );
30219
+
30027
30220
  };
30028
30221
 
30029
30222
  // Animation Loop
@@ -30377,6 +30570,14 @@ class WebGLRenderer {
30377
30570
 
30378
30571
  function renderTransmissionPass( opaqueObjects, transmissiveObjects, scene, camera ) {
30379
30572
 
30573
+ const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
30574
+
30575
+ if ( overrideMaterial !== null ) {
30576
+
30577
+ return;
30578
+
30579
+ }
30580
+
30380
30581
  const isWebGL2 = capabilities.isWebGL2;
30381
30582
 
30382
30583
  if ( _transmissionRenderTarget === null ) {
@@ -30636,16 +30837,26 @@ class WebGLRenderer {
30636
30837
 
30637
30838
  }
30638
30839
 
30639
- const progUniforms = program.getUniforms();
30640
- const uniformsList = WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
30641
-
30642
30840
  materialProperties.currentProgram = program;
30643
- materialProperties.uniformsList = uniformsList;
30841
+ materialProperties.uniformsList = null;
30644
30842
 
30645
30843
  return program;
30646
30844
 
30647
30845
  }
30648
30846
 
30847
+ function getUniformList( materialProperties ) {
30848
+
30849
+ if ( materialProperties.uniformsList === null ) {
30850
+
30851
+ const progUniforms = materialProperties.currentProgram.getUniforms();
30852
+ materialProperties.uniformsList = WebGLUniforms.seqWithValue( progUniforms.seq, materialProperties.uniforms );
30853
+
30854
+ }
30855
+
30856
+ return materialProperties.uniformsList;
30857
+
30858
+ }
30859
+
30649
30860
  function updateCommonMaterialProperties( material, parameters ) {
30650
30861
 
30651
30862
  const materialProperties = properties.get( material );
@@ -30989,13 +31200,13 @@ class WebGLRenderer {
30989
31200
 
30990
31201
  materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget );
30991
31202
 
30992
- WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
31203
+ WebGLUniforms.upload( _gl, getUniformList( materialProperties ), m_uniforms, textures );
30993
31204
 
30994
31205
  }
30995
31206
 
30996
31207
  if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {
30997
31208
 
30998
- WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
31209
+ WebGLUniforms.upload( _gl, getUniformList( materialProperties ), m_uniforms, textures );
30999
31210
  material.uniformsNeedUpdate = false;
31000
31211
 
31001
31212
  }
@@ -32629,7 +32840,7 @@ class SkinnedMesh extends Mesh {
32629
32840
 
32630
32841
  this.type = 'SkinnedMesh';
32631
32842
 
32632
- this.bindMode = 'attached';
32843
+ this.bindMode = AttachedBindMode;
32633
32844
  this.bindMatrix = new Matrix4();
32634
32845
  this.bindMatrixInverse = new Matrix4();
32635
32846
 
@@ -32654,8 +32865,7 @@ class SkinnedMesh extends Mesh {
32654
32865
 
32655
32866
  for ( let i = 0; i < positionAttribute.count; i ++ ) {
32656
32867
 
32657
- _vertex.fromBufferAttribute( positionAttribute, i );
32658
- this.applyBoneTransform( i, _vertex );
32868
+ this.getVertexPosition( i, _vertex );
32659
32869
  this.boundingBox.expandByPoint( _vertex );
32660
32870
 
32661
32871
  }
@@ -32678,8 +32888,7 @@ class SkinnedMesh extends Mesh {
32678
32888
 
32679
32889
  for ( let i = 0; i < positionAttribute.count; i ++ ) {
32680
32890
 
32681
- _vertex.fromBufferAttribute( positionAttribute, i );
32682
- this.applyBoneTransform( i, _vertex );
32891
+ this.getVertexPosition( i, _vertex );
32683
32892
  this.boundingSphere.expandByPoint( _vertex );
32684
32893
 
32685
32894
  }
@@ -32805,11 +33014,11 @@ class SkinnedMesh extends Mesh {
32805
33014
 
32806
33015
  super.updateMatrixWorld( force );
32807
33016
 
32808
- if ( this.bindMode === 'attached' ) {
33017
+ if ( this.bindMode === AttachedBindMode ) {
32809
33018
 
32810
33019
  this.bindMatrixInverse.copy( this.matrixWorld ).invert();
32811
33020
 
32812
- } else if ( this.bindMode === 'detached' ) {
33021
+ } else if ( this.bindMode === DetachedBindMode ) {
32813
33022
 
32814
33023
  this.bindMatrixInverse.copy( this.bindMatrix ).invert();
32815
33024
 
@@ -44708,11 +44917,18 @@ class MaterialLoader extends Loader {
44708
44917
  if ( json.transparent !== undefined ) material.transparent = json.transparent;
44709
44918
  if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
44710
44919
  if ( json.alphaHash !== undefined ) material.alphaHash = json.alphaHash;
44920
+ if ( json.depthFunc !== undefined ) material.depthFunc = json.depthFunc;
44711
44921
  if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
44712
44922
  if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
44713
44923
  if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
44714
-
44715
- if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite;
44924
+ if ( json.blendSrc !== undefined ) material.blendSrc = json.blendSrc;
44925
+ if ( json.blendDst !== undefined ) material.blendDst = json.blendDst;
44926
+ if ( json.blendEquation !== undefined ) material.blendEquation = json.blendEquation;
44927
+ if ( json.blendSrcAlpha !== undefined ) material.blendSrcAlpha = json.blendSrcAlpha;
44928
+ if ( json.blendDstAlpha !== undefined ) material.blendDstAlpha = json.blendDstAlpha;
44929
+ if ( json.blendEquationAlpha !== undefined ) material.blendEquationAlpha = json.blendEquationAlpha;
44930
+ if ( json.blendColor !== undefined && material.blendColor !== undefined ) material.blendColor.setHex( json.blendColor );
44931
+ if ( json.blendAlpha !== undefined ) material.blendAlpha = json.blendAlpha;
44716
44932
  if ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask;
44717
44933
  if ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc;
44718
44934
  if ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef;
@@ -44720,6 +44936,7 @@ class MaterialLoader extends Loader {
44720
44936
  if ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail;
44721
44937
  if ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail;
44722
44938
  if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass;
44939
+ if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite;
44723
44940
 
44724
44941
  if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
44725
44942
  if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
@@ -52558,6 +52775,7 @@ exports.AnimationUtils = AnimationUtils;
52558
52775
  exports.ArcCurve = ArcCurve;
52559
52776
  exports.ArrayCamera = ArrayCamera;
52560
52777
  exports.ArrowHelper = ArrowHelper;
52778
+ exports.AttachedBindMode = AttachedBindMode;
52561
52779
  exports.Audio = Audio;
52562
52780
  exports.AudioAnalyser = AudioAnalyser;
52563
52781
  exports.AudioContext = AudioContext;
@@ -52596,6 +52814,8 @@ exports.CompressedCubeTexture = CompressedCubeTexture;
52596
52814
  exports.CompressedTexture = CompressedTexture;
52597
52815
  exports.CompressedTextureLoader = CompressedTextureLoader;
52598
52816
  exports.ConeGeometry = ConeGeometry;
52817
+ exports.ConstantAlphaFactor = ConstantAlphaFactor;
52818
+ exports.ConstantColorFactor = ConstantColorFactor;
52599
52819
  exports.CubeCamera = CubeCamera;
52600
52820
  exports.CubeReflectionMapping = CubeReflectionMapping;
52601
52821
  exports.CubeRefractionMapping = CubeRefractionMapping;
@@ -52626,6 +52846,7 @@ exports.DefaultLoadingManager = DefaultLoadingManager;
52626
52846
  exports.DepthFormat = DepthFormat;
52627
52847
  exports.DepthStencilFormat = DepthStencilFormat;
52628
52848
  exports.DepthTexture = DepthTexture;
52849
+ exports.DetachedBindMode = DetachedBindMode;
52629
52850
  exports.DirectionalLight = DirectionalLight;
52630
52851
  exports.DirectionalLightHelper = DirectionalLightHelper;
52631
52852
  exports.DiscreteInterpolant = DiscreteInterpolant;
@@ -52777,6 +52998,8 @@ exports.ObjectLoader = ObjectLoader;
52777
52998
  exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap;
52778
52999
  exports.OctahedronGeometry = OctahedronGeometry;
52779
53000
  exports.OneFactor = OneFactor;
53001
+ exports.OneMinusConstantAlphaFactor = OneMinusConstantAlphaFactor;
53002
+ exports.OneMinusConstantColorFactor = OneMinusConstantColorFactor;
52780
53003
  exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;
52781
53004
  exports.OneMinusDstColorFactor = OneMinusDstColorFactor;
52782
53005
  exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;