super-three 0.157.0 → 0.158.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/README.md +6 -4
  2. package/build/three.cjs +1486 -842
  3. package/build/three.js +1486 -842
  4. package/build/three.min.js +1 -1
  5. package/build/three.module.js +1481 -843
  6. package/build/three.module.min.js +1 -1
  7. package/examples/jsm/Addons.js +290 -0
  8. package/examples/jsm/controls/FlyControls.js +26 -0
  9. package/examples/jsm/controls/OrbitControls.js +12 -1
  10. package/examples/jsm/controls/TransformControls.js +27 -11
  11. package/examples/jsm/csm/CSMShader.js +1 -1
  12. package/examples/jsm/exporters/GLTFExporter.js +72 -2
  13. package/examples/jsm/geometries/InstancedPointsGeometry.js +174 -0
  14. package/examples/jsm/geometries/SDFGeometryGenerator.js +144 -0
  15. package/examples/jsm/libs/lottie_canvas.module.js +6 -1
  16. package/examples/jsm/libs/opentype.module.js +13 -75
  17. package/examples/jsm/libs/surfaceNet.js +201 -0
  18. package/examples/jsm/loaders/GLTFLoader.js +12 -3
  19. package/examples/jsm/loaders/LUTImageLoader.js +162 -0
  20. package/examples/jsm/loaders/lwo/IFFParser.js +89 -93
  21. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
  22. package/examples/jsm/math/Capsule.js +0 -55
  23. package/examples/jsm/math/Octree.js +70 -3
  24. package/examples/jsm/modifiers/SimplifyModifier.js +103 -11
  25. package/examples/jsm/modifiers/TessellateModifier.js +3 -3
  26. package/examples/jsm/nodes/Nodes.js +6 -6
  27. package/examples/jsm/nodes/accessors/CubeTextureNode.js +3 -3
  28. package/examples/jsm/nodes/accessors/InstanceNode.js +3 -3
  29. package/examples/jsm/nodes/accessors/InstancedPointsMaterialNode.js +21 -0
  30. package/examples/jsm/nodes/accessors/MaterialNode.js +68 -31
  31. package/examples/jsm/nodes/accessors/ModelNode.js +1 -2
  32. package/examples/jsm/nodes/accessors/MorphNode.js +5 -5
  33. package/examples/jsm/nodes/accessors/NormalNode.js +1 -1
  34. package/examples/jsm/nodes/accessors/PositionNode.js +1 -1
  35. package/examples/jsm/nodes/accessors/SkinningNode.js +13 -3
  36. package/examples/jsm/nodes/accessors/TextureNode.js +3 -3
  37. package/examples/jsm/nodes/code/FunctionNode.js +1 -1
  38. package/examples/jsm/nodes/core/AssignNode.js +72 -0
  39. package/examples/jsm/nodes/core/LightingModel.js +3 -1
  40. package/examples/jsm/nodes/core/Node.js +7 -12
  41. package/examples/jsm/nodes/core/NodeBuilder.js +126 -16
  42. package/examples/jsm/nodes/core/NodeUtils.js +4 -2
  43. package/examples/jsm/nodes/core/OutputStructNode.js +1 -1
  44. package/examples/jsm/nodes/core/ParameterNode.js +33 -0
  45. package/examples/jsm/nodes/core/PropertyNode.js +4 -10
  46. package/examples/jsm/nodes/core/StackNode.js +7 -17
  47. package/examples/jsm/nodes/core/TempNode.js +1 -1
  48. package/examples/jsm/nodes/core/VarNode.js +6 -35
  49. package/examples/jsm/nodes/core/VaryingNode.js +2 -0
  50. package/examples/jsm/nodes/display/BumpMapNode.js +35 -13
  51. package/examples/jsm/nodes/display/NormalMapNode.js +3 -1
  52. package/examples/jsm/nodes/display/ViewportNode.js +14 -4
  53. package/examples/jsm/nodes/functions/BSDF/BRDF_Sheen.js +20 -6
  54. package/examples/jsm/nodes/functions/BSDF/DFGApprox.js +8 -7
  55. package/examples/jsm/nodes/functions/BSDF/D_GGX.js +8 -3
  56. package/examples/jsm/nodes/functions/BSDF/Schlick_to_F0.js +8 -0
  57. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +8 -0
  58. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +93 -43
  59. package/examples/jsm/nodes/gpgpu/ComputeNode.js +2 -2
  60. package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
  61. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +19 -5
  62. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +1 -1
  63. package/examples/jsm/nodes/lighting/EnvironmentNode.js +0 -6
  64. package/examples/jsm/nodes/lighting/LightingContextNode.js +21 -57
  65. package/examples/jsm/nodes/lighting/LightsNode.js +62 -4
  66. package/examples/jsm/nodes/lighting/PointLightNode.js +1 -1
  67. package/examples/jsm/nodes/lighting/SpotLightNode.js +1 -1
  68. package/examples/jsm/nodes/materials/InstancedPointsNodeMaterial.js +162 -0
  69. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +70 -71
  70. package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +5 -5
  71. package/examples/jsm/nodes/materials/Materials.js +1 -0
  72. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +2 -2
  73. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +3 -3
  74. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +47 -20
  75. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +6 -6
  76. package/examples/jsm/nodes/materials/NodeMaterial.js +17 -20
  77. package/examples/jsm/nodes/materialx/lib/mx_noise.js +5 -5
  78. package/examples/jsm/nodes/math/OperatorNode.js +5 -21
  79. package/examples/jsm/nodes/shadernode/ShaderNode.js +128 -9
  80. package/examples/jsm/nodes/utils/ArrayElementNode.js +2 -0
  81. package/examples/jsm/nodes/utils/DiscardNode.js +3 -2
  82. package/examples/jsm/nodes/utils/JoinNode.js +11 -1
  83. package/examples/jsm/nodes/utils/LoopNode.js +36 -24
  84. package/examples/jsm/nodes/utils/SplitNode.js +2 -0
  85. package/examples/jsm/objects/BatchedMesh.js +586 -0
  86. package/examples/jsm/objects/InstancedPoints.js +21 -0
  87. package/examples/jsm/objects/Lensflare.js +20 -0
  88. package/examples/jsm/objects/ReflectorForSSRPass.js +3 -0
  89. package/examples/jsm/objects/Refractor.js +3 -0
  90. package/examples/jsm/objects/Sky.js +5 -3
  91. package/examples/jsm/objects/Water.js +5 -2
  92. package/examples/jsm/objects/Water2.js +3 -0
  93. package/examples/jsm/physics/AmmoPhysics.js +21 -0
  94. package/examples/jsm/physics/RapierPhysics.js +21 -0
  95. package/examples/jsm/postprocessing/BokehPass.js +3 -2
  96. package/examples/jsm/postprocessing/LUTPass.js +2 -1
  97. package/examples/jsm/postprocessing/OutputPass.js +1 -0
  98. package/examples/jsm/postprocessing/Pass.js +14 -3
  99. package/examples/jsm/postprocessing/SAOPass.js +0 -1
  100. package/examples/jsm/postprocessing/SMAAPass.js +0 -2
  101. package/examples/jsm/postprocessing/TAARenderPass.js +1 -2
  102. package/examples/jsm/renderers/CSS3DRenderer.js +3 -9
  103. package/examples/jsm/renderers/SVGRenderer.js +9 -6
  104. package/examples/jsm/renderers/common/Bindings.js +1 -1
  105. package/examples/jsm/renderers/common/RenderObject.js +8 -1
  106. package/examples/jsm/renderers/common/RenderObjects.js +1 -1
  107. package/examples/jsm/renderers/common/Textures.js +4 -36
  108. package/examples/jsm/renderers/common/nodes/Nodes.js +53 -18
  109. package/examples/jsm/renderers/webgl/WebGLBackend.js +291 -50
  110. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +88 -12
  111. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +40 -5
  112. package/examples/jsm/renderers/webgl/utils/WebGLState.js +14 -2
  113. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +2 -0
  114. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +36 -4
  115. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +2 -0
  116. package/examples/jsm/shaders/AfterimageShader.js +2 -0
  117. package/examples/jsm/shaders/BasicShader.js +2 -0
  118. package/examples/jsm/shaders/BlendShader.js +2 -0
  119. package/examples/jsm/shaders/BokehShader.js +2 -0
  120. package/examples/jsm/shaders/BokehShader2.js +4 -0
  121. package/examples/jsm/shaders/BrightnessContrastShader.js +2 -0
  122. package/examples/jsm/shaders/ColorCorrectionShader.js +2 -0
  123. package/examples/jsm/shaders/DOFMipMapShader.js +2 -0
  124. package/examples/jsm/shaders/DepthLimitedBlurShader.js +5 -0
  125. package/examples/jsm/shaders/FXAAShader.js +2 -0
  126. package/examples/jsm/shaders/FilmShader.js +1 -1
  127. package/examples/jsm/shaders/FocusShader.js +2 -0
  128. package/examples/jsm/shaders/FreiChenShader.js +2 -0
  129. package/examples/jsm/shaders/GodRaysShader.js +8 -0
  130. package/examples/jsm/shaders/HalftoneShader.js +2 -0
  131. package/examples/jsm/shaders/HorizontalTiltShiftShader.js +2 -0
  132. package/examples/jsm/shaders/HueSaturationShader.js +2 -0
  133. package/examples/jsm/shaders/KaleidoShader.js +2 -0
  134. package/examples/jsm/shaders/LuminosityHighPassShader.js +2 -0
  135. package/examples/jsm/shaders/LuminosityShader.js +2 -0
  136. package/examples/jsm/shaders/MMDToonShader.js +2 -0
  137. package/examples/jsm/shaders/MirrorShader.js +2 -0
  138. package/examples/jsm/shaders/NormalMapShader.js +2 -0
  139. package/examples/jsm/shaders/OutputShader.js +4 -5
  140. package/examples/jsm/shaders/SAOShader.js +5 -0
  141. package/examples/jsm/shaders/SMAAShader.js +6 -0
  142. package/examples/jsm/shaders/SSAOShader.js +6 -0
  143. package/examples/jsm/shaders/SSRShader.js +6 -0
  144. package/examples/jsm/shaders/SobelOperatorShader.js +2 -0
  145. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +2 -0
  146. package/examples/jsm/shaders/TechnicolorShader.js +2 -0
  147. package/examples/jsm/shaders/TriangleBlurShader.js +2 -0
  148. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -0
  149. package/examples/jsm/shaders/VelocityShader.js +2 -0
  150. package/examples/jsm/shaders/VerticalTiltShiftShader.js +2 -0
  151. package/examples/jsm/shaders/WaterRefractionShader.js +2 -0
  152. package/examples/jsm/transpiler/AST.js +231 -0
  153. package/examples/jsm/transpiler/GLSLDecoder.js +899 -0
  154. package/examples/jsm/transpiler/ShaderToyDecoder.js +49 -0
  155. package/examples/jsm/transpiler/TSLEncoder.js +611 -0
  156. package/examples/jsm/transpiler/Transpiler.js +18 -0
  157. package/examples/jsm/webxr/VRButton.js +1 -1
  158. package/examples/jsm/webxr/XRButton.js +7 -5
  159. package/examples/jsm/webxr/XREstimatedLight.js +1 -1
  160. package/package.json +4 -1
  161. package/src/constants.js +7 -1
  162. package/src/extras/PMREMGenerator.js +7 -1
  163. package/src/loaders/MaterialLoader.js +10 -2
  164. package/src/materials/Material.js +27 -13
  165. package/src/math/Box3.js +35 -18
  166. package/src/math/Vector3.js +11 -12
  167. package/src/objects/SkinnedMesh.js +6 -7
  168. package/src/renderers/WebGLMultiviewRenderTarget.js +35 -0
  169. package/src/renderers/WebGLRenderer.js +199 -45
  170. package/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl.js +8 -0
  171. package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +3 -2
  172. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  173. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +8 -6
  174. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +2 -2
  175. package/src/renderers/webgl/WebGLBackground.js +1 -1
  176. package/src/renderers/webgl/WebGLMultiview.js +100 -0
  177. package/src/renderers/webgl/WebGLProgram.js +130 -50
  178. package/src/renderers/webgl/WebGLPrograms.js +8 -0
  179. package/src/renderers/webgl/WebGLState.js +25 -4
  180. package/src/renderers/webgl/WebGLTextures.js +197 -20
  181. package/src/renderers/webxr/WebXRManager.js +36 -12
  182. package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +0 -76
  183. package/examples/jsm/nodes/accessors/LineMaterialNode.js +0 -29
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 );
4803
4808
 
4804
- if ( geometry !== undefined ) {
4809
+ } else {
4810
+
4811
+ _vector$a.fromBufferAttribute( positionAttribute, i );
4812
+
4813
+ }
4805
4814
 
4806
- if ( precise && geometry.attributes !== undefined && geometry.attributes.position !== undefined ) {
4815
+ _vector$a.applyMatrix4( object.matrixWorld );
4816
+ this.expandByPoint( _vector$a );
4807
4817
 
4808
- const position = geometry.attributes.position;
4809
- for ( let i = 0, l = position.count; i < l; i ++ ) {
4818
+ }
4819
+
4820
+ } else {
4810
4821
 
4811
- _vector$a.fromBufferAttribute( position, i ).applyMatrix4( object.matrixWorld );
4812
- this.expandByPoint( _vector$a );
4822
+ if ( object.boundingBox !== undefined ) {
4823
+
4824
+ // object-level bounding box
4825
+
4826
+ if ( object.boundingBox === null ) {
4827
+
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 ) {
9175
+ setValues( values ) {
9205
9176
 
9206
- // color keywords
9207
- const hex = _colorKeywords[ style.toLowerCase() ];
9177
+ if ( values === undefined ) return;
9208
9178
 
9209
- if ( hex !== undefined ) {
9179
+ for ( const key in values ) {
9210
9180
 
9211
- // red
9212
- this.setHex( hex, colorSpace );
9181
+ const newValue = values[ key ];
9213
9182
 
9214
- } else {
9183
+ if ( newValue === undefined ) {
9215
9184
 
9216
- // unknown color
9217
- console.warn( 'THREE.Color: Unknown color ' + style );
9185
+ console.warn( `THREE.Material: parameter '${ key }' has value of undefined.` );
9186
+ continue;
9218
9187
 
9219
- }
9188
+ }
9220
9189
 
9221
- return this;
9190
+ const currentValue = this[ key ];
9222
9191
 
9223
- }
9192
+ if ( currentValue === undefined ) {
9224
9193
 
9225
- clone() {
9194
+ console.warn( `THREE.Material: '${ key }' is not a property of THREE.${ this.type }.` );
9195
+ continue;
9226
9196
 
9227
- return new this.constructor( this.r, this.g, this.b );
9197
+ }
9228
9198
 
9229
- }
9199
+ if ( currentValue && currentValue.isColor ) {
9230
9200
 
9231
- copy( color ) {
9201
+ currentValue.set( newValue );
9232
9202
 
9233
- this.r = color.r;
9234
- this.g = color.g;
9235
- this.b = color.b;
9203
+ } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
9236
9204
 
9237
- return this;
9205
+ currentValue.copy( newValue );
9238
9206
 
9239
- }
9207
+ } else {
9240
9208
 
9241
- copySRGBToLinear( color ) {
9209
+ this[ key ] = newValue;
9242
9210
 
9243
- this.r = SRGBToLinear( color.r );
9244
- this.g = SRGBToLinear( color.g );
9245
- this.b = SRGBToLinear( color.b );
9211
+ }
9246
9212
 
9247
- return this;
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
 
@@ -14749,7 +14784,7 @@ function WebGLBackground( renderer, cubemaps, cubeuvmaps, state, objects, alpha,
14749
14784
  if ( boxMesh === undefined ) {
14750
14785
 
14751
14786
  boxMesh = new Mesh(
14752
- new BoxGeometry( 1, 1, 1 ),
14787
+ new BoxGeometry( 10000, 10000, 10000 ),
14753
14788
  new ShaderMaterial( {
14754
14789
  name: 'BackgroundCubeMaterial',
14755
14790
  uniforms: cloneUniforms( ShaderLib.backgroundCube.uniforms ),
@@ -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 );
@@ -17845,6 +17886,103 @@ function WebGLMorphtargets( gl, capabilities, textures ) {
17845
17886
 
17846
17887
  }
17847
17888
 
17889
+ /**
17890
+ * @author fernandojsg / http://fernandojsg.com
17891
+ * @author Takahiro https://github.com/takahirox
17892
+ */
17893
+
17894
+ class WebGLMultiview {
17895
+
17896
+ constructor( renderer, extensions, gl ) {
17897
+
17898
+ this.renderer = renderer;
17899
+
17900
+ this.DEFAULT_NUMVIEWS = 2;
17901
+ this.maxNumViews = 0;
17902
+ this.gl = gl;
17903
+
17904
+ this.extensions = extensions;
17905
+
17906
+ this.available = this.extensions.has( 'OCULUS_multiview' );
17907
+
17908
+ if ( this.available ) {
17909
+
17910
+ const extension = this.extensions.get( 'OCULUS_multiview' );
17911
+
17912
+ this.maxNumViews = this.gl.getParameter( extension.MAX_VIEWS_OVR );
17913
+
17914
+ this.mat4 = [];
17915
+ this.mat3 = [];
17916
+ this.cameraArray = [];
17917
+
17918
+ for ( var i = 0; i < this.maxNumViews; i ++ ) {
17919
+
17920
+ this.mat4[ i ] = new Matrix4();
17921
+ this.mat3[ i ] = new Matrix3();
17922
+
17923
+ }
17924
+
17925
+ }
17926
+
17927
+ }
17928
+
17929
+ //
17930
+ getCameraArray( camera ) {
17931
+
17932
+ if ( camera.isArrayCamera ) return camera.cameras;
17933
+
17934
+ this.cameraArray[ 0 ] = camera;
17935
+
17936
+ return this.cameraArray;
17937
+
17938
+ }
17939
+
17940
+ updateCameraProjectionMatricesUniform( camera, uniforms ) {
17941
+
17942
+ var cameras = this.getCameraArray( camera );
17943
+
17944
+ for ( var i = 0; i < cameras.length; i ++ ) {
17945
+
17946
+ this.mat4[ i ].copy( cameras[ i ].projectionMatrix );
17947
+
17948
+ }
17949
+
17950
+ uniforms.setValue( this.gl, 'projectionMatrices', this.mat4 );
17951
+
17952
+ }
17953
+
17954
+ updateCameraViewMatricesUniform( camera, uniforms ) {
17955
+
17956
+ var cameras = this.getCameraArray( camera );
17957
+
17958
+ for ( var i = 0; i < cameras.length; i ++ ) {
17959
+
17960
+ this.mat4[ i ].copy( cameras[ i ].matrixWorldInverse );
17961
+
17962
+ }
17963
+
17964
+ uniforms.setValue( this.gl, 'viewMatrices', this.mat4 );
17965
+
17966
+ }
17967
+
17968
+ updateObjectMatricesUniforms( object, camera, uniforms ) {
17969
+
17970
+ var cameras = this.getCameraArray( camera );
17971
+
17972
+ for ( var i = 0; i < cameras.length; i ++ ) {
17973
+
17974
+ this.mat4[ i ].multiplyMatrices( cameras[ i ].matrixWorldInverse, object.matrixWorld );
17975
+ this.mat3[ i ].getNormalMatrix( this.mat4[ i ] );
17976
+
17977
+ }
17978
+
17979
+ uniforms.setValue( this.gl, 'modelViewMatrices', this.mat4 );
17980
+ uniforms.setValue( this.gl, 'normalMatrices', this.mat3 );
17981
+
17982
+ }
17983
+
17984
+ }
17985
+
17848
17986
  function WebGLObjects( gl, geometries, attributes, info ) {
17849
17987
 
17850
17988
  let updateMap = new WeakMap();
@@ -19087,6 +19225,9 @@ function WebGLShader( gl, type, string ) {
19087
19225
 
19088
19226
  }
19089
19227
 
19228
+ // From https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/
19229
+ const COMPLETION_STATUS_KHR = 0x91B1;
19230
+
19090
19231
  let programIdCount = 0;
19091
19232
 
19092
19233
  function handleSource( string, errorLine ) {
@@ -19538,6 +19679,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19538
19679
  let prefixVertex, prefixFragment;
19539
19680
  let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : '';
19540
19681
 
19682
+ const numMultiviewViews = parameters.numMultiviewViews;
19683
+
19541
19684
  if ( parameters.isRawShaderMaterial ) {
19542
19685
 
19543
19686
  prefixVertex = [
@@ -19929,6 +20072,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19929
20072
  ].join( '\n' ) + '\n' + prefixVertex;
19930
20073
 
19931
20074
  prefixFragment = [
20075
+ 'precision mediump sampler2DArray;',
19932
20076
  '#define varying in',
19933
20077
  ( parameters.glslVersion === GLSL3 ) ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;',
19934
20078
  ( parameters.glslVersion === GLSL3 ) ? '' : '#define gl_FragColor pc_fragColor',
@@ -19944,6 +20088,53 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19944
20088
  '#define textureCubeGradEXT textureGrad'
19945
20089
  ].join( '\n' ) + '\n' + prefixFragment;
19946
20090
 
20091
+ // Multiview
20092
+
20093
+ if ( numMultiviewViews > 0 ) {
20094
+
20095
+ // TODO: fix light transforms here?
20096
+
20097
+ prefixVertex = [
20098
+ '#extension GL_OVR_multiview : require',
20099
+ 'layout(num_views = ' + numMultiviewViews + ') in;',
20100
+ '#define VIEW_ID gl_ViewID_OVR'
20101
+ ].join( '\n' ) + '\n' + prefixVertex;
20102
+
20103
+ prefixVertex = prefixVertex.replace(
20104
+ [
20105
+ 'uniform mat4 modelViewMatrix;',
20106
+ 'uniform mat4 projectionMatrix;',
20107
+ 'uniform mat4 viewMatrix;',
20108
+ 'uniform mat3 normalMatrix;'
20109
+ ].join( '\n' ),
20110
+ [
20111
+ 'uniform mat4 modelViewMatrices[' + numMultiviewViews + '];',
20112
+ 'uniform mat4 projectionMatrices[' + numMultiviewViews + '];',
20113
+ 'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
20114
+ 'uniform mat3 normalMatrices[' + numMultiviewViews + '];',
20115
+
20116
+ '#define modelViewMatrix modelViewMatrices[VIEW_ID]',
20117
+ '#define projectionMatrix projectionMatrices[VIEW_ID]',
20118
+ '#define viewMatrix viewMatrices[VIEW_ID]',
20119
+ '#define normalMatrix normalMatrices[VIEW_ID]'
20120
+ ].join( '\n' )
20121
+ );
20122
+
20123
+ prefixFragment = [
20124
+ '#extension GL_OVR_multiview : require',
20125
+ '#define VIEW_ID gl_ViewID_OVR'
20126
+ ].join( '\n' ) + '\n' + prefixFragment;
20127
+
20128
+ prefixFragment = prefixFragment.replace(
20129
+ 'uniform mat4 viewMatrix;',
20130
+ [
20131
+ 'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
20132
+ '#define viewMatrix viewMatrices[VIEW_ID]'
20133
+ ].join( '\n' )
20134
+ );
20135
+
20136
+ }
20137
+
19947
20138
  }
19948
20139
 
19949
20140
  const vertexGlsl = versionString + prefixVertex + vertexShader;
@@ -19973,87 +20164,94 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19973
20164
 
19974
20165
  gl.linkProgram( program );
19975
20166
 
19976
- // check for link errors
19977
- if ( renderer.debug.checkShaderErrors ) {
20167
+ function onFirstUse( self ) {
19978
20168
 
19979
- const programLog = gl.getProgramInfoLog( program ).trim();
19980
- const vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
19981
- const fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
20169
+ // check for link errors
20170
+ if ( renderer.debug.checkShaderErrors ) {
19982
20171
 
19983
- let runnable = true;
19984
- let haveDiagnostics = true;
20172
+ const programLog = gl.getProgramInfoLog( program ).trim();
20173
+ const vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
20174
+ const fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
19985
20175
 
19986
- if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
20176
+ let runnable = true;
20177
+ let haveDiagnostics = true;
19987
20178
 
19988
- runnable = false;
20179
+ if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
19989
20180
 
19990
- if ( typeof renderer.debug.onShaderError === 'function' ) {
20181
+ runnable = false;
19991
20182
 
19992
- renderer.debug.onShaderError( gl, program, glVertexShader, glFragmentShader );
20183
+ if ( typeof renderer.debug.onShaderError === 'function' ) {
19993
20184
 
19994
- } else {
20185
+ renderer.debug.onShaderError( gl, program, glVertexShader, glFragmentShader );
19995
20186
 
19996
- // default error reporting
20187
+ } else {
19997
20188
 
19998
- const vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
19999
- const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
20189
+ // default error reporting
20000
20190
 
20001
- console.error(
20002
- 'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' +
20003
- 'VALIDATE_STATUS ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) + '\n\n' +
20004
- 'Program Info Log: ' + programLog + '\n' +
20005
- vertexErrors + '\n' +
20006
- fragmentErrors
20007
- );
20191
+ const vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
20192
+ const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
20008
20193
 
20009
- }
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
+ );
20010
20201
 
20011
- } else if ( programLog !== '' ) {
20202
+ }
20012
20203
 
20013
- console.warn( 'THREE.WebGLProgram: Program Info Log:', programLog );
20204
+ } else if ( programLog !== '' ) {
20014
20205
 
20015
- } else if ( vertexLog === '' || fragmentLog === '' ) {
20206
+ console.warn( 'THREE.WebGLProgram: Program Info Log:', programLog );
20016
20207
 
20017
- haveDiagnostics = false;
20208
+ } else if ( vertexLog === '' || fragmentLog === '' ) {
20018
20209
 
20019
- }
20210
+ haveDiagnostics = false;
20020
20211
 
20021
- if ( haveDiagnostics ) {
20212
+ }
20022
20213
 
20023
- this.diagnostics = {
20214
+ if ( haveDiagnostics ) {
20024
20215
 
20025
- runnable: runnable,
20216
+ self.diagnostics = {
20026
20217
 
20027
- programLog: programLog,
20218
+ runnable: runnable,
20028
20219
 
20029
- vertexShader: {
20220
+ programLog: programLog,
20030
20221
 
20031
- log: vertexLog,
20032
- prefix: prefixVertex
20222
+ vertexShader: {
20033
20223
 
20034
- },
20224
+ log: vertexLog,
20225
+ prefix: prefixVertex
20035
20226
 
20036
- fragmentShader: {
20227
+ },
20037
20228
 
20038
- log: fragmentLog,
20039
- prefix: prefixFragment
20229
+ fragmentShader: {
20040
20230
 
20041
- }
20231
+ log: fragmentLog,
20232
+ prefix: prefixFragment
20042
20233
 
20043
- };
20234
+ }
20235
+
20236
+ };
20237
+
20238
+ }
20044
20239
 
20045
20240
  }
20046
20241
 
20047
- }
20242
+ // Clean up
20243
+
20244
+ // Crashes in iOS9 and iOS10. #18402
20245
+ // gl.detachShader( program, glVertexShader );
20246
+ // gl.detachShader( program, glFragmentShader );
20048
20247
 
20049
- // Clean up
20248
+ gl.deleteShader( glVertexShader );
20249
+ gl.deleteShader( glFragmentShader );
20050
20250
 
20051
- // Crashes in iOS9 and iOS10. #18402
20052
- // gl.detachShader( program, glVertexShader );
20053
- // gl.detachShader( program, glFragmentShader );
20251
+ cachedUniforms = new WebGLUniforms( gl, program );
20252
+ cachedAttributes = fetchAttributeLocations( gl, program );
20054
20253
 
20055
- gl.deleteShader( glVertexShader );
20056
- gl.deleteShader( glFragmentShader );
20254
+ }
20057
20255
 
20058
20256
  // set up caching for uniform locations
20059
20257
 
@@ -20063,7 +20261,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20063
20261
 
20064
20262
  if ( cachedUniforms === undefined ) {
20065
20263
 
20066
- cachedUniforms = new WebGLUniforms( gl, program );
20264
+ // Populates cachedUniforms and cachedAttributes
20265
+ onFirstUse( this );
20067
20266
 
20068
20267
  }
20069
20268
 
@@ -20079,7 +20278,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20079
20278
 
20080
20279
  if ( cachedAttributes === undefined ) {
20081
20280
 
20082
- cachedAttributes = fetchAttributeLocations( gl, program );
20281
+ // Populates cachedAttributes and cachedUniforms
20282
+ onFirstUse( this );
20083
20283
 
20084
20284
  }
20085
20285
 
@@ -20087,6 +20287,23 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20087
20287
 
20088
20288
  };
20089
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
+
20090
20307
  // free resource
20091
20308
 
20092
20309
  this.destroy = function () {
@@ -20108,6 +20325,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20108
20325
  this.program = program;
20109
20326
  this.vertexShader = glVertexShader;
20110
20327
  this.fragmentShader = glFragmentShader;
20328
+ this.numMultiviewViews = numMultiviewViews;
20111
20329
 
20112
20330
  return this;
20113
20331
 
@@ -20337,6 +20555,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20337
20555
 
20338
20556
  const currentRenderTarget = renderer.getRenderTarget();
20339
20557
 
20558
+ const numMultiviewViews = currentRenderTarget && currentRenderTarget.isWebGLMultiviewRenderTarget ? currentRenderTarget.numViews : 0;
20559
+
20340
20560
  const IS_INSTANCEDMESH = object.isInstancedMesh === true;
20341
20561
 
20342
20562
  const HAS_MAP = !! material.map;
@@ -20427,6 +20647,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20427
20647
  instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null,
20428
20648
 
20429
20649
  supportsVertexTextures: SUPPORTS_VERTEX_TEXTURES,
20650
+ numMultiviewViews: numMultiviewViews,
20430
20651
  outputColorSpace: ( currentRenderTarget === null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace ),
20431
20652
 
20432
20653
  map: HAS_MAP,
@@ -20588,6 +20809,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20588
20809
  rendererExtensionFragDepth: IS_WEBGL2 || extensions.has( 'EXT_frag_depth' ),
20589
20810
  rendererExtensionDrawBuffers: IS_WEBGL2 || extensions.has( 'WEBGL_draw_buffers' ),
20590
20811
  rendererExtensionShaderTextureLod: IS_WEBGL2 || extensions.has( 'EXT_shader_texture_lod' ),
20812
+ rendererExtensionParallelShaderCompile: extensions.has( 'KHR_parallel_shader_compile' ),
20591
20813
 
20592
20814
  customProgramCacheKey: material.customProgramCacheKey()
20593
20815
 
@@ -20730,6 +20952,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20730
20952
  _programLayers.enable( 16 );
20731
20953
  if ( parameters.anisotropy )
20732
20954
  _programLayers.enable( 17 );
20955
+ if ( parameters.alphaHash )
20956
+ _programLayers.enable( 18 );
20733
20957
 
20734
20958
  array.push( _programLayers.mask );
20735
20959
  _programLayers.disableAll();
@@ -20774,6 +20998,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20774
20998
  _programLayers.enable( 18 );
20775
20999
  if ( parameters.decodeVideoTexture )
20776
21000
  _programLayers.enable( 19 );
21001
+ if ( parameters.numMultiviewViews )
21002
+ _programLayers.enable( 20 );
20777
21003
 
20778
21004
  array.push( _programLayers.mask );
20779
21005
 
@@ -22621,6 +22847,8 @@ function WebGLState( gl, extensions, capabilities ) {
22621
22847
  let currentBlendEquationAlpha = null;
22622
22848
  let currentBlendSrcAlpha = null;
22623
22849
  let currentBlendDstAlpha = null;
22850
+ let currentBlendColor = new Color( 0, 0, 0 );
22851
+ let currentBlendAlpha = 0;
22624
22852
  let currentPremultipledAlpha = false;
22625
22853
 
22626
22854
  let currentFlipSided = null;
@@ -22896,10 +23124,14 @@ function WebGLState( gl, extensions, capabilities ) {
22896
23124
  [ OneMinusSrcColorFactor ]: gl.ONE_MINUS_SRC_COLOR,
22897
23125
  [ OneMinusSrcAlphaFactor ]: gl.ONE_MINUS_SRC_ALPHA,
22898
23126
  [ OneMinusDstColorFactor ]: gl.ONE_MINUS_DST_COLOR,
22899
- [ 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
22900
23132
  };
22901
23133
 
22902
- function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
23134
+ function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, blendColor, blendAlpha, premultipliedAlpha ) {
22903
23135
 
22904
23136
  if ( blending === NoBlending ) {
22905
23137
 
@@ -22992,6 +23224,8 @@ function WebGLState( gl, extensions, capabilities ) {
22992
23224
  currentBlendDst = null;
22993
23225
  currentBlendSrcAlpha = null;
22994
23226
  currentBlendDstAlpha = null;
23227
+ currentBlendColor.set( 0, 0, 0 );
23228
+ currentBlendAlpha = 0;
22995
23229
 
22996
23230
  currentBlending = blending;
22997
23231
  currentPremultipledAlpha = premultipliedAlpha;
@@ -23028,6 +23262,15 @@ function WebGLState( gl, extensions, capabilities ) {
23028
23262
 
23029
23263
  }
23030
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
+
23031
23274
  currentBlending = blending;
23032
23275
  currentPremultipledAlpha = false;
23033
23276
 
@@ -23046,7 +23289,7 @@ function WebGLState( gl, extensions, capabilities ) {
23046
23289
 
23047
23290
  ( material.blending === NormalBlending && material.transparent === false )
23048
23291
  ? setBlending( NoBlending )
23049
- : 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 );
23050
23293
 
23051
23294
  depthBuffer.setFunc( material.depthFunc );
23052
23295
  depthBuffer.setTest( material.depthTest );
@@ -23470,6 +23713,7 @@ function WebGLState( gl, extensions, capabilities ) {
23470
23713
  gl.blendEquation( gl.FUNC_ADD );
23471
23714
  gl.blendFunc( gl.ONE, gl.ZERO );
23472
23715
  gl.blendFuncSeparate( gl.ONE, gl.ZERO, gl.ONE, gl.ZERO );
23716
+ gl.blendColor( 0, 0, 0, 0 );
23473
23717
 
23474
23718
  gl.colorMask( true, true, true, true );
23475
23719
  gl.clearColor( 0, 0, 0, 0 );
@@ -23527,6 +23771,8 @@ function WebGLState( gl, extensions, capabilities ) {
23527
23771
  currentBlendEquationAlpha = null;
23528
23772
  currentBlendSrcAlpha = null;
23529
23773
  currentBlendDstAlpha = null;
23774
+ currentBlendColor = new Color( 0, 0, 0 );
23775
+ currentBlendAlpha = 0;
23530
23776
  currentPremultipledAlpha = false;
23531
23777
 
23532
23778
  currentFlipSided = null;
@@ -23609,12 +23855,16 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
23609
23855
  const maxSamples = capabilities.maxSamples;
23610
23856
  const multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null;
23611
23857
  const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent );
23858
+ const multiviewExt = extensions.has( 'OCULUS_multiview' ) ? extensions.get( 'OCULUS_multiview' ) : null;
23612
23859
 
23613
23860
  const _videoTextures = new WeakMap();
23614
23861
  let _canvas;
23615
23862
 
23616
23863
  const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source
23617
23864
 
23865
+ let _deferredUploads = [];
23866
+ let _deferTextureUploads = false;
23867
+
23618
23868
  // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas,
23619
23869
  // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")!
23620
23870
  // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d).
@@ -24082,8 +24332,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24082
24332
 
24083
24333
  } else {
24084
24334
 
24085
- uploadTexture( textureProperties, texture, slot );
24086
- return;
24335
+ if ( uploadTexture( textureProperties, texture, slot ) ) {
24336
+
24337
+ return;
24338
+
24339
+ }
24087
24340
 
24088
24341
  }
24089
24342
 
@@ -24316,8 +24569,45 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24316
24569
 
24317
24570
  }
24318
24571
 
24572
+ function setDeferTextureUploads( deferFlag ) {
24573
+
24574
+ _deferTextureUploads = deferFlag;
24575
+
24576
+ }
24577
+
24578
+ function runDeferredUploads() {
24579
+
24580
+ const previousDeferSetting = _deferTextureUploads;
24581
+ _deferTextureUploads = false;
24582
+
24583
+ for ( const upload of _deferredUploads ) {
24584
+
24585
+ uploadTexture( upload.textureProperties, upload.texture, upload.slot );
24586
+ upload.texture.isPendingDeferredUpload = false;
24587
+
24588
+ }
24589
+
24590
+ _deferredUploads = [];
24591
+
24592
+ _deferTextureUploads = previousDeferSetting;
24593
+
24594
+ }
24595
+
24319
24596
  function uploadTexture( textureProperties, texture, slot ) {
24320
24597
 
24598
+ if ( _deferTextureUploads ) {
24599
+
24600
+ if ( ! texture.isPendingDeferredUpload ) {
24601
+
24602
+ texture.isPendingDeferredUpload = true;
24603
+ _deferredUploads.push( { textureProperties: textureProperties, texture: texture, slot: slot } );
24604
+
24605
+ }
24606
+
24607
+ return false;
24608
+
24609
+ }
24610
+
24321
24611
  let textureType = _gl.TEXTURE_2D;
24322
24612
 
24323
24613
  if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) textureType = _gl.TEXTURE_2D_ARRAY;
@@ -24734,6 +25024,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24734
25024
  }
24735
25025
 
24736
25026
  textureProperties.__version = texture.version;
25027
+ return true;
24737
25028
 
24738
25029
  }
24739
25030
 
@@ -24963,7 +25254,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24963
25254
  const width = Math.max( 1, renderTarget.width >> level );
24964
25255
  const height = Math.max( 1, renderTarget.height >> level );
24965
25256
 
24966
- if ( textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY ) {
25257
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25258
+
25259
+ state.texStorage3D( _gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.numViews );
25260
+
25261
+ } else if ( textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY ) {
24967
25262
 
24968
25263
  state.texImage3D( textureTarget, level, glInternalFormat, width, height, renderTarget.depth, 0, glFormat, glType, null );
24969
25264
 
@@ -24977,13 +25272,31 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24977
25272
 
24978
25273
  state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
24979
25274
 
24980
- if ( useMultisampledRTT( renderTarget ) ) {
25275
+ const multisampled = useMultisampledRTT( renderTarget );
25276
+
25277
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
24981
25278
 
24982
- multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) );
25279
+ if ( multisampled ) {
25280
+
25281
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ), 0, renderTarget.numViews );
25282
+
25283
+ } else {
25284
+
25285
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( texture ).__webglTexture, 0, 0, renderTarget.numViews );
25286
+
25287
+ }
24983
25288
 
24984
25289
  } else if ( textureTarget === _gl.TEXTURE_2D || ( textureTarget >= _gl.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= _gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ) ) { // see #24753
24985
25290
 
24986
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, level );
25291
+ if ( multisampled ) {
25292
+
25293
+ multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) );
25294
+
25295
+ } else {
25296
+
25297
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, level );
25298
+
25299
+ }
24987
25300
 
24988
25301
  }
24989
25302
 
@@ -24997,7 +25310,59 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24997
25310
 
24998
25311
  _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
24999
25312
 
25000
- if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
25313
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25314
+
25315
+ const useMultisample = useMultisampledRTT( renderTarget );
25316
+ const numViews = renderTarget.numViews;
25317
+
25318
+ const depthTexture = renderTarget.depthTexture;
25319
+ let glInternalFormat = _gl.DEPTH_COMPONENT24;
25320
+ let glDepthAttachment = _gl.DEPTH_ATTACHMENT;
25321
+
25322
+ if ( depthTexture && depthTexture.isDepthTexture ) {
25323
+
25324
+ if ( depthTexture.type === FloatType ) {
25325
+
25326
+ glInternalFormat = _gl.DEPTH_COMPONENT32F;
25327
+
25328
+ } else if ( depthTexture.type === UnsignedInt248Type ) {
25329
+
25330
+ glInternalFormat = _gl.DEPTH24_STENCIL8;
25331
+ glDepthAttachment = _gl.DEPTH_STENCIL_ATTACHMENT;
25332
+
25333
+ }
25334
+
25335
+ // we're defaulting to _gl.DEPTH_COMPONENT24 so don't assign here
25336
+ // or else DeepScan will complain
25337
+
25338
+ // else if ( depthTexture.type === UnsignedIntType ) {
25339
+
25340
+ // glInternalFormat = _gl.DEPTH_COMPONENT24;
25341
+
25342
+ // }
25343
+
25344
+ }
25345
+
25346
+ let depthStencilTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
25347
+ if ( depthStencilTexture === undefined ) {
25348
+
25349
+ depthStencilTexture = _gl.createTexture();
25350
+ _gl.bindTexture( _gl.TEXTURE_2D_ARRAY, depthStencilTexture );
25351
+ _gl.texStorage3D( _gl.TEXTURE_2D_ARRAY, 1, glInternalFormat, renderTarget.width, renderTarget.height, numViews );
25352
+
25353
+ }
25354
+
25355
+ if ( useMultisample ) {
25356
+
25357
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, glDepthAttachment, depthStencilTexture, 0, getRenderTargetSamples( renderTarget ), 0, numViews );
25358
+
25359
+ } else {
25360
+
25361
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, glDepthAttachment, depthStencilTexture, 0, 0, numViews );
25362
+
25363
+ }
25364
+
25365
+ } else if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
25001
25366
 
25002
25367
  let glInternalFormat = ( isWebGL2 === true ) ? _gl.DEPTH_COMPONENT24 : _gl.DEPTH_COMPONENT16;
25003
25368
 
@@ -25121,37 +25486,85 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25121
25486
  }
25122
25487
 
25123
25488
  setTexture2D( renderTarget.depthTexture, 0 );
25489
+ if ( renderTarget.depthTexture.image.depth != 1 ) {
25490
+
25491
+ setTexture2DArray( renderTarget.depthTexture, 0 );
25492
+
25493
+ } else {
25494
+
25495
+ setTexture2D( renderTarget.depthTexture, 0 );
25496
+
25497
+ }
25124
25498
 
25125
25499
  const webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
25126
25500
  const samples = getRenderTargetSamples( renderTarget );
25127
25501
 
25128
- if ( renderTarget.depthTexture.format === DepthFormat ) {
25502
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25129
25503
 
25130
- if ( useMultisampledRTT( renderTarget ) ) {
25504
+ const useMultisample = useMultisampledRTT( renderTarget );
25505
+ const numViews = renderTarget.numViews;
25131
25506
 
25132
- multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25507
+ if ( renderTarget.depthTexture.format === DepthFormat ) {
25133
25508
 
25134
- } else {
25509
+ if ( useMultisample ) {
25135
25510
 
25136
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25511
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, webglDepthTexture, 0, samples, 0, numViews );
25137
25512
 
25138
- }
25513
+ } else {
25514
+
25515
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, webglDepthTexture, 0, 0, numViews );
25516
+
25517
+ }
25139
25518
 
25140
- } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
25519
+ } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
25141
25520
 
25142
- if ( useMultisampledRTT( renderTarget ) ) {
25521
+ if ( useMultisample ) {
25143
25522
 
25144
- multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25523
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, webglDepthTexture, 0, samples, 0, numViews );
25524
+
25525
+ } else {
25526
+
25527
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, webglDepthTexture, 0, 0, numViews );
25528
+
25529
+ }
25145
25530
 
25146
25531
  } else {
25147
25532
 
25148
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25533
+ throw new Error( 'Unknown depthTexture format' );
25149
25534
 
25150
25535
  }
25151
25536
 
25152
25537
  } else {
25153
25538
 
25154
- throw new Error( 'Unknown depthTexture format' );
25539
+ if ( renderTarget.depthTexture.format === DepthFormat ) {
25540
+
25541
+ if ( useMultisampledRTT( renderTarget ) ) {
25542
+
25543
+ multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25544
+
25545
+ } else {
25546
+
25547
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25548
+
25549
+ }
25550
+
25551
+ } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
25552
+
25553
+ if ( useMultisampledRTT( renderTarget ) ) {
25554
+
25555
+ multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25556
+
25557
+ } else {
25558
+
25559
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25560
+
25561
+ }
25562
+
25563
+ } else {
25564
+
25565
+ throw new Error( 'Unknown depthTexture format' );
25566
+
25567
+ }
25155
25568
 
25156
25569
  }
25157
25570
 
@@ -25430,6 +25843,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25430
25843
 
25431
25844
  }
25432
25845
 
25846
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25847
+
25848
+ glTextureType = _gl.TEXTURE_2D_ARRAY;
25849
+
25850
+ }
25851
+
25433
25852
  state.bindTexture( glTextureType, textureProperties.__webglTexture );
25434
25853
  setTextureParameters( glTextureType, texture, supportsMips );
25435
25854
 
@@ -25459,9 +25878,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25459
25878
 
25460
25879
  // Setup depth and stencil buffers
25461
25880
 
25462
- if ( renderTarget.depthBuffer ) {
25881
+ if ( renderTarget.depthBuffer || renderTarget.isWebGLMultiviewRenderTarget === true ) {
25463
25882
 
25464
- setupDepthRenderbuffer( renderTarget );
25883
+ this.setupDepthRenderbuffer( renderTarget );
25465
25884
 
25466
25885
  }
25467
25886
 
@@ -25697,12 +26116,16 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25697
26116
  this.setTexture3D = setTexture3D;
25698
26117
  this.setTextureCube = setTextureCube;
25699
26118
  this.rebindTextures = rebindTextures;
26119
+ this.uploadTexture = uploadTexture;
25700
26120
  this.setupRenderTarget = setupRenderTarget;
25701
26121
  this.updateRenderTargetMipmap = updateRenderTargetMipmap;
25702
26122
  this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
26123
+ this.setupDepthTexture = setupDepthTexture;
25703
26124
  this.setupDepthRenderbuffer = setupDepthRenderbuffer;
25704
26125
  this.setupFrameBufferTexture = setupFrameBufferTexture;
25705
26126
  this.useMultisampledRTT = useMultisampledRTT;
26127
+ this.runDeferredUploads = runDeferredUploads;
26128
+ this.setDeferTextureUploads = setDeferTextureUploads;
25706
26129
 
25707
26130
  }
25708
26131
 
@@ -26559,6 +26982,39 @@ Object.assign( WebVRManager.prototype, {
26559
26982
  dispatchEvent: EventDispatcher.prototype.dispatchEvent
26560
26983
  } );
26561
26984
 
26985
+ /**
26986
+ * @author fernandojsg / http://fernandojsg.com
26987
+ * @author Takahiro https://github.com/takahirox
26988
+ */
26989
+
26990
+
26991
+ class WebGLMultiviewRenderTarget extends WebGLRenderTarget {
26992
+
26993
+ constructor( width, height, numViews, options = {} ) {
26994
+
26995
+ super( width, height, options );
26996
+
26997
+ this.depthBuffer = false;
26998
+ this.stencilBuffer = false;
26999
+
27000
+ this.numViews = numViews;
27001
+
27002
+ }
27003
+
27004
+ copy( source ) {
27005
+
27006
+ super.copy( source );
27007
+
27008
+ this.numViews = source.numViews;
27009
+
27010
+ return this;
27011
+
27012
+ }
27013
+
27014
+ }
27015
+
27016
+ WebGLMultiviewRenderTarget.prototype.isWebGLMultiviewRenderTarget = true;
27017
+
26562
27018
  const _moveEvent = { type: 'move' };
26563
27019
 
26564
27020
  class WebXRController {
@@ -26953,7 +27409,7 @@ class DepthTexture extends Texture {
26953
27409
 
26954
27410
  class WebXRManager extends EventDispatcher {
26955
27411
 
26956
- constructor( renderer, gl ) {
27412
+ constructor( renderer, gl, extensions, useMultiview ) {
26957
27413
 
26958
27414
  super();
26959
27415
 
@@ -27009,6 +27465,7 @@ class WebXRManager extends EventDispatcher {
27009
27465
  this.enabled = false;
27010
27466
 
27011
27467
  this.isPresenting = false;
27468
+ this.isMultiview = false;
27012
27469
 
27013
27470
  this.getCameraPose = function ( ) {
27014
27471
 
@@ -27252,29 +27709,51 @@ class WebXRManager extends EventDispatcher {
27252
27709
 
27253
27710
  }
27254
27711
 
27712
+ scope.isMultiview = useMultiview && extensions.has( 'OCULUS_multiview' );
27713
+
27255
27714
  const projectionlayerInit = {
27256
27715
  colorFormat: gl.RGBA8,
27257
27716
  depthFormat: glDepthFormat,
27258
27717
  scaleFactor: framebufferScaleFactor
27259
27718
  };
27260
27719
 
27720
+ if ( scope.isMultiview ) {
27721
+
27722
+ projectionlayerInit.textureType = 'texture-array';
27723
+
27724
+ }
27725
+
27261
27726
  glBinding = new XRWebGLBinding( session, gl );
27262
27727
 
27263
27728
  glProjLayer = glBinding.createProjectionLayer( projectionlayerInit );
27264
27729
 
27265
27730
  session.updateRenderState( { layers: [ glProjLayer ] } );
27266
27731
 
27267
- newRenderTarget = new WebGLRenderTarget(
27268
- glProjLayer.textureWidth,
27269
- glProjLayer.textureHeight,
27270
- {
27271
- format: RGBAFormat,
27272
- type: UnsignedByteType,
27273
- depthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ),
27274
- stencilBuffer: attributes.stencil,
27275
- colorSpace: renderer.outputColorSpace,
27276
- samples: attributes.antialias ? 4 : 0
27277
- } );
27732
+ const renderTargetOptions = {
27733
+ format: RGBAFormat,
27734
+ type: UnsignedByteType,
27735
+ depthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ),
27736
+ stencilBuffer: attributes.stencil,
27737
+ colorSpace: renderer.outputColorSpace,
27738
+ samples: attributes.antialias ? 4 : 0
27739
+ };
27740
+
27741
+ if ( scope.isMultiview ) {
27742
+
27743
+ const extension = extensions.get( 'OCULUS_multiview' );
27744
+
27745
+ this.maxNumViews = gl.getParameter( extension.MAX_VIEWS_OVR );
27746
+
27747
+ newRenderTarget = new WebGLMultiviewRenderTarget( glProjLayer.textureWidth, glProjLayer.textureHeight, 2, renderTargetOptions );
27748
+
27749
+ } else {
27750
+
27751
+ newRenderTarget = new WebGLRenderTarget(
27752
+ glProjLayer.textureWidth,
27753
+ glProjLayer.textureHeight,
27754
+ renderTargetOptions );
27755
+
27756
+ }
27278
27757
 
27279
27758
  const renderTargetProperties = renderer.properties.get( newRenderTarget );
27280
27759
  renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues;
@@ -28726,6 +29205,7 @@ class WebGLRenderer {
28726
29205
  preserveDrawingBuffer = false,
28727
29206
  powerPreference = 'default',
28728
29207
  failIfMajorPerformanceCaveat = false,
29208
+ multiviewStereo = false,
28729
29209
  } = parameters;
28730
29210
 
28731
29211
  this.isWebGLRenderer = true;
@@ -28960,6 +29440,7 @@ class WebGLRenderer {
28960
29440
  let extensions, capabilities, state, info;
28961
29441
  let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects;
28962
29442
  let programCache, materials, renderLists, renderStates, clipping, shadowMap;
29443
+ let multiview;
28963
29444
 
28964
29445
  let background, morphtargets, bufferRenderer, indexedBufferRenderer;
28965
29446
 
@@ -28993,6 +29474,7 @@ class WebGLRenderer {
28993
29474
  renderLists = new WebGLRenderLists();
28994
29475
  renderStates = new WebGLRenderStates( extensions, capabilities );
28995
29476
  background = new WebGLBackground( _this, cubemaps, cubeuvmaps, state, objects, _alpha, premultipliedAlpha );
29477
+ multiview = new WebGLMultiview( _this, extensions, _gl );
28996
29478
  shadowMap = new WebGLShadowMap( _this, objects, capabilities );
28997
29479
  uniformsGroups = new WebGLUniformsGroups( _gl, info, capabilities, state );
28998
29480
 
@@ -29015,7 +29497,7 @@ class WebGLRenderer {
29015
29497
 
29016
29498
  // xr
29017
29499
 
29018
- const xr = ( typeof navigator !== 'undefined' && 'xr' in navigator ) ? new WebXRManager( _this, _gl ) : new WebVRManager( _this );
29500
+ const xr = ( typeof navigator !== 'undefined' && 'xr' in navigator ) ? new WebXRManager( _this, _gl, extensions, multiviewStereo ) : new WebVRManager( _this );
29019
29501
 
29020
29502
  this.xr = xr;
29021
29503
 
@@ -29277,7 +29759,12 @@ class WebGLRenderer {
29277
29759
  }
29278
29760
 
29279
29761
  if ( depth ) bits |= _gl.DEPTH_BUFFER_BIT;
29280
- 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
+ }
29281
29768
 
29282
29769
  _gl.clear( bits );
29283
29770
 
@@ -29560,36 +30047,40 @@ class WebGLRenderer {
29560
30047
 
29561
30048
  // Compile
29562
30049
 
29563
- this.compile = function ( scene, camera ) {
30050
+ function prepareMaterial( material, scene, object ) {
29564
30051
 
29565
- function prepare( material, scene, object ) {
30052
+ if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
29566
30053
 
29567
- if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
30054
+ material.side = BackSide;
30055
+ material.needsUpdate = true;
30056
+ getProgram( material, scene, object );
29568
30057
 
29569
- material.side = BackSide;
29570
- material.needsUpdate = true;
29571
- getProgram( material, scene, object );
30058
+ material.side = FrontSide;
30059
+ material.needsUpdate = true;
30060
+ getProgram( material, scene, object );
29572
30061
 
29573
- material.side = FrontSide;
29574
- material.needsUpdate = true;
29575
- getProgram( material, scene, object );
30062
+ material.side = DoubleSide;
30063
+
30064
+ } else {
29576
30065
 
29577
- material.side = DoubleSide;
30066
+ getProgram( material, scene, object );
29578
30067
 
29579
- } else {
30068
+ }
29580
30069
 
29581
- getProgram( material, scene, object );
30070
+ }
29582
30071
 
29583
- }
30072
+ this.compile = function ( scene, camera, targetScene = null ) {
29584
30073
 
29585
- }
30074
+ if ( targetScene === null ) targetScene = scene;
29586
30075
 
29587
- currentRenderState = renderStates.get( scene );
30076
+ currentRenderState = renderStates.get( targetScene );
29588
30077
  currentRenderState.init();
29589
30078
 
29590
30079
  renderStateStack.push( currentRenderState );
29591
30080
 
29592
- 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 ) {
29593
30084
 
29594
30085
  if ( object.isLight && object.layers.test( camera.layers ) ) {
29595
30086
 
@@ -29605,8 +30096,32 @@ class WebGLRenderer {
29605
30096
 
29606
30097
  } );
29607
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
+
29608
30119
  currentRenderState.setupLights( _this._useLegacyLights );
29609
30120
 
30121
+ // Only initialize materials in the new scene, not the targetScene.
30122
+
30123
+ const materials = new Set();
30124
+
29610
30125
  scene.traverse( function ( object ) {
29611
30126
 
29612
30127
  const material = object.material;
@@ -29619,13 +30134,15 @@ class WebGLRenderer {
29619
30134
 
29620
30135
  const material2 = material[ i ];
29621
30136
 
29622
- prepare( material2, scene, object );
30137
+ prepareMaterial( material2, targetScene, object );
30138
+ materials.add( material2 );
29623
30139
 
29624
30140
  }
29625
30141
 
29626
30142
  } else {
29627
30143
 
29628
- prepare( material, scene, object );
30144
+ prepareMaterial( material, targetScene, object );
30145
+ materials.add( material );
29629
30146
 
29630
30147
  }
29631
30148
 
@@ -29636,6 +30153,70 @@ class WebGLRenderer {
29636
30153
  renderStateStack.pop();
29637
30154
  currentRenderState = null;
29638
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
+
29639
30220
  };
29640
30221
 
29641
30222
  // Animation Loop
@@ -29762,13 +30343,23 @@ class WebGLRenderer {
29762
30343
 
29763
30344
  if ( camera.isArrayCamera ) {
29764
30345
 
29765
- const cameras = camera.cameras;
30346
+ if ( xr.enabled && xr.isMultiview ) {
30347
+
30348
+ textures.setDeferTextureUploads( true );
30349
+
30350
+ renderScene( currentRenderList, scene, camera, camera.cameras[ 0 ].viewport );
30351
+
30352
+ } else {
30353
+
30354
+ const cameras = camera.cameras;
29766
30355
 
29767
- for ( let i = 0, l = cameras.length; i < l; i ++ ) {
30356
+ for ( let i = 0, l = cameras.length; i < l; i ++ ) {
29768
30357
 
29769
- const camera2 = cameras[ i ];
30358
+ const camera2 = cameras[ i ];
29770
30359
 
29771
- renderScene( currentRenderList, scene, camera2, camera2.viewport );
30360
+ renderScene( currentRenderList, scene, camera2, camera2.viewport );
30361
+
30362
+ }
29772
30363
 
29773
30364
  }
29774
30365
 
@@ -29796,6 +30387,8 @@ class WebGLRenderer {
29796
30387
 
29797
30388
  if ( scene.isScene === true ) scene.onAfterRender( _this, scene, camera );
29798
30389
 
30390
+ textures.runDeferredUploads();
30391
+
29799
30392
  if ( xr.enabled && xr.submitFrame ) {
29800
30393
 
29801
30394
  xr.submitFrame();
@@ -29977,6 +30570,14 @@ class WebGLRenderer {
29977
30570
 
29978
30571
  function renderTransmissionPass( opaqueObjects, transmissiveObjects, scene, camera ) {
29979
30572
 
30573
+ const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
30574
+
30575
+ if ( overrideMaterial !== null ) {
30576
+
30577
+ return;
30578
+
30579
+ }
30580
+
29980
30581
  const isWebGL2 = capabilities.isWebGL2;
29981
30582
 
29982
30583
  if ( _transmissionRenderTarget === null ) {
@@ -30236,16 +30837,26 @@ class WebGLRenderer {
30236
30837
 
30237
30838
  }
30238
30839
 
30239
- const progUniforms = program.getUniforms();
30240
- const uniformsList = WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
30241
-
30242
30840
  materialProperties.currentProgram = program;
30243
- materialProperties.uniformsList = uniformsList;
30841
+ materialProperties.uniformsList = null;
30244
30842
 
30245
30843
  return program;
30246
30844
 
30247
30845
  }
30248
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
+
30249
30860
  function updateCommonMaterialProperties( material, parameters ) {
30250
30861
 
30251
30862
  const materialProperties = properties.get( material );
@@ -30263,6 +30874,7 @@ class WebGLRenderer {
30263
30874
  materialProperties.vertexAlphas = parameters.vertexAlphas;
30264
30875
  materialProperties.vertexTangents = parameters.vertexTangents;
30265
30876
  materialProperties.toneMapping = parameters.toneMapping;
30877
+ materialProperties.numMultiviewViews = parameters.numMultiviewViews;
30266
30878
 
30267
30879
  }
30268
30880
 
@@ -30294,6 +30906,8 @@ class WebGLRenderer {
30294
30906
 
30295
30907
  }
30296
30908
 
30909
+ const numMultiviewViews = _currentRenderTarget && _currentRenderTarget.isWebGLMultiviewRenderTarget ? _currentRenderTarget.numViews : 0;
30910
+
30297
30911
  const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
30298
30912
  const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;
30299
30913
 
@@ -30397,6 +31011,10 @@ class WebGLRenderer {
30397
31011
 
30398
31012
  needsProgramChange = true;
30399
31013
 
31014
+ } else if ( materialProperties.numMultiviewViews !== numMultiviewViews ) {
31015
+
31016
+ needsProgramChange = true;
31017
+
30400
31018
  }
30401
31019
 
30402
31020
  } else {
@@ -30443,8 +31061,17 @@ class WebGLRenderer {
30443
31061
 
30444
31062
  // common camera uniforms
30445
31063
 
30446
- p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
30447
- p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
31064
+ if ( program.numMultiviewViews > 0 ) {
31065
+
31066
+ multiview.updateCameraProjectionMatricesUniform( camera, p_uniforms );
31067
+ multiview.updateCameraViewMatricesUniform( camera, p_uniforms );
31068
+
31069
+ } else {
31070
+
31071
+ p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
31072
+ p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
31073
+
31074
+ }
30448
31075
 
30449
31076
  const uCamPos = p_uniforms.map.cameraPosition;
30450
31077
 
@@ -30573,13 +31200,13 @@ class WebGLRenderer {
30573
31200
 
30574
31201
  materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget );
30575
31202
 
30576
- WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
31203
+ WebGLUniforms.upload( _gl, getUniformList( materialProperties ), m_uniforms, textures );
30577
31204
 
30578
31205
  }
30579
31206
 
30580
31207
  if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {
30581
31208
 
30582
- WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
31209
+ WebGLUniforms.upload( _gl, getUniformList( materialProperties ), m_uniforms, textures );
30583
31210
  material.uniformsNeedUpdate = false;
30584
31211
 
30585
31212
  }
@@ -30592,8 +31219,17 @@ class WebGLRenderer {
30592
31219
 
30593
31220
  // common matrices
30594
31221
 
30595
- p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
30596
- p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
31222
+ if ( program.numMultiviewViews > 0 ) {
31223
+
31224
+ multiview.updateObjectMatricesUniforms( object, camera, p_uniforms );
31225
+
31226
+ } else {
31227
+
31228
+ p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
31229
+ p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
31230
+
31231
+ }
31232
+
30597
31233
  p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
30598
31234
 
30599
31235
  // UBOs
@@ -30703,20 +31339,16 @@ class WebGLRenderer {
30703
31339
  const renderTargetProperties = properties.get( renderTarget );
30704
31340
  renderTargetProperties.__hasExternalTextures = true;
30705
31341
 
30706
- if ( renderTargetProperties.__hasExternalTextures ) {
30707
-
30708
- renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;
30709
-
30710
- if ( ! renderTargetProperties.__autoAllocateDepthBuffer ) {
31342
+ renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;
30711
31343
 
30712
- // The multisample_render_to_texture extension doesn't work properly if there
30713
- // are midframe flushes and an external depth buffer. Disable use of the extension.
30714
- if ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) {
31344
+ if ( ! renderTargetProperties.__autoAllocateDepthBuffer && ! _currentRenderTarget.isWebGLMultiviewRenderTarget ) {
30715
31345
 
30716
- console.warn( 'THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided' );
30717
- renderTargetProperties.__useRenderToTexture = false;
31346
+ // The multisample_render_to_texture extension doesn't work properly if there
31347
+ // are midframe flushes and an external depth buffer. Disable use of the extension.
31348
+ if ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) {
30718
31349
 
30719
- }
31350
+ console.warn( 'THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided' );
31351
+ renderTargetProperties.__useRenderToTexture = false;
30720
31352
 
30721
31353
  }
30722
31354
 
@@ -32208,7 +32840,7 @@ class SkinnedMesh extends Mesh {
32208
32840
 
32209
32841
  this.type = 'SkinnedMesh';
32210
32842
 
32211
- this.bindMode = 'attached';
32843
+ this.bindMode = AttachedBindMode;
32212
32844
  this.bindMatrix = new Matrix4();
32213
32845
  this.bindMatrixInverse = new Matrix4();
32214
32846
 
@@ -32233,8 +32865,7 @@ class SkinnedMesh extends Mesh {
32233
32865
 
32234
32866
  for ( let i = 0; i < positionAttribute.count; i ++ ) {
32235
32867
 
32236
- _vertex.fromBufferAttribute( positionAttribute, i );
32237
- this.applyBoneTransform( i, _vertex );
32868
+ this.getVertexPosition( i, _vertex );
32238
32869
  this.boundingBox.expandByPoint( _vertex );
32239
32870
 
32240
32871
  }
@@ -32257,8 +32888,7 @@ class SkinnedMesh extends Mesh {
32257
32888
 
32258
32889
  for ( let i = 0; i < positionAttribute.count; i ++ ) {
32259
32890
 
32260
- _vertex.fromBufferAttribute( positionAttribute, i );
32261
- this.applyBoneTransform( i, _vertex );
32891
+ this.getVertexPosition( i, _vertex );
32262
32892
  this.boundingSphere.expandByPoint( _vertex );
32263
32893
 
32264
32894
  }
@@ -32384,11 +33014,11 @@ class SkinnedMesh extends Mesh {
32384
33014
 
32385
33015
  super.updateMatrixWorld( force );
32386
33016
 
32387
- if ( this.bindMode === 'attached' ) {
33017
+ if ( this.bindMode === AttachedBindMode ) {
32388
33018
 
32389
33019
  this.bindMatrixInverse.copy( this.matrixWorld ).invert();
32390
33020
 
32391
- } else if ( this.bindMode === 'detached' ) {
33021
+ } else if ( this.bindMode === DetachedBindMode ) {
32392
33022
 
32393
33023
  this.bindMatrixInverse.copy( this.bindMatrix ).invert();
32394
33024
 
@@ -44287,11 +44917,18 @@ class MaterialLoader extends Loader {
44287
44917
  if ( json.transparent !== undefined ) material.transparent = json.transparent;
44288
44918
  if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
44289
44919
  if ( json.alphaHash !== undefined ) material.alphaHash = json.alphaHash;
44920
+ if ( json.depthFunc !== undefined ) material.depthFunc = json.depthFunc;
44290
44921
  if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
44291
44922
  if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
44292
44923
  if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
44293
-
44294
- 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;
44295
44932
  if ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask;
44296
44933
  if ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc;
44297
44934
  if ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef;
@@ -44299,6 +44936,7 @@ class MaterialLoader extends Loader {
44299
44936
  if ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail;
44300
44937
  if ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail;
44301
44938
  if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass;
44939
+ if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite;
44302
44940
 
44303
44941
  if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
44304
44942
  if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
@@ -52137,6 +52775,7 @@ exports.AnimationUtils = AnimationUtils;
52137
52775
  exports.ArcCurve = ArcCurve;
52138
52776
  exports.ArrayCamera = ArrayCamera;
52139
52777
  exports.ArrowHelper = ArrowHelper;
52778
+ exports.AttachedBindMode = AttachedBindMode;
52140
52779
  exports.Audio = Audio;
52141
52780
  exports.AudioAnalyser = AudioAnalyser;
52142
52781
  exports.AudioContext = AudioContext;
@@ -52175,6 +52814,8 @@ exports.CompressedCubeTexture = CompressedCubeTexture;
52175
52814
  exports.CompressedTexture = CompressedTexture;
52176
52815
  exports.CompressedTextureLoader = CompressedTextureLoader;
52177
52816
  exports.ConeGeometry = ConeGeometry;
52817
+ exports.ConstantAlphaFactor = ConstantAlphaFactor;
52818
+ exports.ConstantColorFactor = ConstantColorFactor;
52178
52819
  exports.CubeCamera = CubeCamera;
52179
52820
  exports.CubeReflectionMapping = CubeReflectionMapping;
52180
52821
  exports.CubeRefractionMapping = CubeRefractionMapping;
@@ -52205,6 +52846,7 @@ exports.DefaultLoadingManager = DefaultLoadingManager;
52205
52846
  exports.DepthFormat = DepthFormat;
52206
52847
  exports.DepthStencilFormat = DepthStencilFormat;
52207
52848
  exports.DepthTexture = DepthTexture;
52849
+ exports.DetachedBindMode = DetachedBindMode;
52208
52850
  exports.DirectionalLight = DirectionalLight;
52209
52851
  exports.DirectionalLightHelper = DirectionalLightHelper;
52210
52852
  exports.DiscreteInterpolant = DiscreteInterpolant;
@@ -52356,6 +52998,8 @@ exports.ObjectLoader = ObjectLoader;
52356
52998
  exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap;
52357
52999
  exports.OctahedronGeometry = OctahedronGeometry;
52358
53000
  exports.OneFactor = OneFactor;
53001
+ exports.OneMinusConstantAlphaFactor = OneMinusConstantAlphaFactor;
53002
+ exports.OneMinusConstantColorFactor = OneMinusConstantColorFactor;
52359
53003
  exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;
52360
53004
  exports.OneMinusDstColorFactor = OneMinusDstColorFactor;
52361
53005
  exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;