@gnsx/three 0.184.19 → 0.185.2

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 (367) hide show
  1. package/build/three.cjs +1667 -1189
  2. package/build/three.core.js +1289 -871
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +157 -97
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +11 -4
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +7542 -3371
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +7542 -3370
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +3 -0
  13. package/examples/jsm/controls/ArcballControls.js +6 -2
  14. package/examples/jsm/controls/FirstPersonControls.js +79 -42
  15. package/examples/jsm/controls/TransformControls.js +68 -15
  16. package/examples/jsm/csm/CSMFrustum.js +31 -6
  17. package/examples/jsm/csm/CSMShadowNode.js +4 -1
  18. package/examples/jsm/effects/AsciiEffect.js +14 -1
  19. package/examples/jsm/exporters/DRACOExporter.js +27 -6
  20. package/examples/jsm/exporters/GLTFExporter.js +114 -12
  21. package/examples/jsm/exporters/PLYExporter.js +286 -73
  22. package/examples/jsm/exporters/USDZExporter.js +347 -112
  23. package/examples/jsm/generators/CityGenerator.js +346 -0
  24. package/examples/jsm/generators/ForestGenerator.js +347 -0
  25. package/examples/jsm/generators/TerrainGenerator.js +504 -0
  26. package/examples/jsm/generators/TreeGenerator.js +377 -0
  27. package/examples/jsm/generators/city/SidewalkGenerator.js +253 -0
  28. package/examples/jsm/generators/city/SkyscraperGenerator.js +1357 -0
  29. package/examples/jsm/geometries/LoftGeometry.js +355 -0
  30. package/examples/jsm/helpers/LightProbeGridHelper.js +1 -1
  31. package/examples/jsm/helpers/LightProbeHelper.js +5 -4
  32. package/examples/jsm/helpers/ViewHelper.js +16 -6
  33. package/examples/jsm/inspector/Inspector.js +57 -64
  34. package/examples/jsm/inspector/RendererInspector.js +152 -36
  35. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +1 -1
  36. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -1
  37. package/examples/jsm/inspector/tabs/Console.js +200 -18
  38. package/examples/jsm/inspector/tabs/Memory.js +8 -0
  39. package/examples/jsm/inspector/tabs/Parameters.js +64 -4
  40. package/examples/jsm/inspector/tabs/Performance.js +21 -6
  41. package/examples/jsm/inspector/tabs/Settings.js +51 -9
  42. package/examples/jsm/inspector/tabs/Timeline.js +178 -93
  43. package/examples/jsm/inspector/tabs/Viewer.js +628 -16
  44. package/examples/jsm/inspector/ui/Graph.js +162 -25
  45. package/examples/jsm/inspector/ui/Item.js +92 -13
  46. package/examples/jsm/inspector/ui/List.js +1 -1
  47. package/examples/jsm/inspector/ui/Profiler.js +90 -45
  48. package/examples/jsm/inspector/ui/Style.js +1788 -1401
  49. package/examples/jsm/inspector/ui/Tab.js +5 -3
  50. package/examples/jsm/inspector/ui/Values.js +71 -6
  51. package/examples/jsm/inspector/ui/utils.js +130 -10
  52. package/examples/jsm/libs/basis/README.md +0 -1
  53. package/examples/jsm/libs/demuxer_mp4.js +3 -3
  54. package/examples/jsm/libs/draco/README.md +0 -1
  55. package/examples/jsm/libs/meshopt_clusterizer.module.js +421 -0
  56. package/examples/jsm/libs/meshopt_simplifier.module.js +627 -0
  57. package/examples/jsm/libs/mikktspace.module.js +34 -9
  58. package/examples/jsm/lighting/ClusteredLighting.js +55 -0
  59. package/examples/jsm/lighting/LightProbeGrid.js +124 -91
  60. package/examples/jsm/lines/LineMaterial.js +38 -15
  61. package/examples/jsm/lines/LineSegments2.js +8 -0
  62. package/examples/jsm/lines/webgpu/LineSegments2.js +8 -0
  63. package/examples/jsm/loaders/3DMLoader.js +1 -1
  64. package/examples/jsm/loaders/DRACOLoader.js +46 -13
  65. package/examples/jsm/loaders/EXRLoader.js +27 -55
  66. package/examples/jsm/loaders/HDRLoader.js +6 -28
  67. package/examples/jsm/loaders/KTX2Loader.js +31 -12
  68. package/examples/jsm/loaders/LDrawLoader.js +8 -8
  69. package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
  70. package/examples/jsm/loaders/LUTCubeLoader.js +2 -2
  71. package/examples/jsm/loaders/LWOLoader.js +4 -0
  72. package/examples/jsm/loaders/LottieLoader.js +1 -1
  73. package/examples/jsm/loaders/MaterialXLoader.js +31 -9
  74. package/examples/jsm/loaders/NRRDLoader.js +3 -3
  75. package/examples/jsm/loaders/PCDLoader.js +7 -7
  76. package/examples/jsm/loaders/PLYLoader.js +218 -55
  77. package/examples/jsm/loaders/SVGLoader.js +547 -495
  78. package/examples/jsm/loaders/TTFLoader.js +1 -1
  79. package/examples/jsm/loaders/USDLoader.js +33 -9
  80. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  81. package/examples/jsm/loaders/usd/USDAParser.js +93 -20
  82. package/examples/jsm/loaders/usd/USDCParser.js +1 -1
  83. package/examples/jsm/loaders/usd/USDComposer.js +52 -19
  84. package/examples/jsm/misc/TileCreasedNormalsPlugin.js +270 -0
  85. package/examples/jsm/misc/Volume.js +2 -2
  86. package/examples/jsm/objects/GroundedSkybox.js +1 -1
  87. package/examples/jsm/objects/Reflector.js +2 -3
  88. package/examples/jsm/objects/Water2Mesh.js +1 -1
  89. package/examples/jsm/physics/AmmoPhysics.js +15 -8
  90. package/examples/jsm/physics/RapierPhysics.js +27 -2
  91. package/examples/jsm/shaders/VolumeShader.js +31 -44
  92. package/examples/jsm/transpiler/GLSLDecoder.js +6 -6
  93. package/examples/jsm/transpiler/Linker.js +1 -1
  94. package/examples/jsm/tsl/display/BloomNode.js +59 -19
  95. package/examples/jsm/tsl/display/DepthOfFieldNode.js +2 -2
  96. package/examples/jsm/tsl/display/FXAANode.js +11 -12
  97. package/examples/jsm/tsl/display/GTAONode.js +34 -13
  98. package/examples/jsm/tsl/display/GodraysNode.js +1 -1
  99. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +560 -0
  100. package/examples/jsm/tsl/display/PixelationPassNode.js +2 -2
  101. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +912 -0
  102. package/examples/jsm/tsl/display/SSAAPassNode.js +13 -25
  103. package/examples/jsm/tsl/display/SSGINode.js +89 -39
  104. package/examples/jsm/tsl/display/SSRNode.js +829 -132
  105. package/examples/jsm/tsl/display/SSSNode.js +2 -2
  106. package/examples/jsm/tsl/display/TemporalReprojectNode.js +1023 -0
  107. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +622 -0
  108. package/examples/jsm/tsl/lighting/DynamicLightsNode.js +1 -1
  109. package/examples/jsm/tsl/math/curlNoise.js +107 -0
  110. package/examples/jsm/tsl/shadows/TileShadowNode.js +1 -1
  111. package/examples/jsm/tsl/shadows/TileShadowNodeHelper.js +3 -3
  112. package/examples/jsm/tsl/utils/GroundedSkybox.js +62 -0
  113. package/examples/jsm/tsl/utils/RNoise.js +51 -0
  114. package/examples/jsm/tsl/utils/SpecularHelpers.js +325 -0
  115. package/examples/jsm/utils/BufferGeometryUtils.js +126 -59
  116. package/examples/jsm/utils/GeometryCompressionUtils.js +1 -1
  117. package/examples/jsm/utils/SceneOptimizer.js +1 -1
  118. package/examples/jsm/webxr/ARButton.js +1 -1
  119. package/examples/jsm/webxr/WebGLXRFallback.js +89 -0
  120. package/examples/jsm/webxr/XRControllerModelFactory.js +2 -2
  121. package/package.json +7 -7
  122. package/src/Three.TSL.js +10 -3
  123. package/src/Three.WebGPU.js +4 -0
  124. package/src/animation/AnimationAction.js +15 -11
  125. package/src/animation/AnimationClip.js +0 -139
  126. package/src/animation/KeyframeTrack.js +2 -2
  127. package/src/animation/PropertyBinding.js +2 -2
  128. package/src/cameras/Camera.js +2 -2
  129. package/src/cameras/StereoCamera.js +5 -2
  130. package/src/constants.js +1 -1
  131. package/src/core/BufferGeometry.js +29 -7
  132. package/src/core/Object3D.js +17 -7
  133. package/src/core/Raycaster.js +1 -1
  134. package/src/core/RenderTarget.js +15 -2
  135. package/src/extras/PMREMGenerator.js +6 -4
  136. package/src/extras/TextureUtils.js +1 -1
  137. package/src/extras/core/ShapePath.js +149 -160
  138. package/src/geometries/SphereGeometry.js +8 -3
  139. package/src/helpers/DirectionalLightHelper.js +2 -0
  140. package/src/helpers/HemisphereLightHelper.js +2 -0
  141. package/src/helpers/PointLightHelper.js +2 -0
  142. package/src/helpers/SpotLightHelper.js +1 -1
  143. package/src/loaders/DataTextureLoader.js +69 -38
  144. package/src/loaders/LoadingManager.js +5 -0
  145. package/src/loaders/MaterialLoader.js +36 -266
  146. package/src/loaders/ObjectLoader.js +3 -1
  147. package/src/materials/LineBasicMaterial.js +4 -0
  148. package/src/materials/Material.js +196 -1
  149. package/src/materials/MeshBasicMaterial.js +24 -0
  150. package/src/materials/MeshDepthMaterial.js +10 -0
  151. package/src/materials/MeshDistanceMaterial.js +10 -0
  152. package/src/materials/MeshLambertMaterial.js +40 -1
  153. package/src/materials/MeshMatcapMaterial.js +25 -1
  154. package/src/materials/MeshNormalMaterial.js +9 -1
  155. package/src/materials/MeshPhongMaterial.js +40 -1
  156. package/src/materials/MeshPhysicalMaterial.js +38 -0
  157. package/src/materials/MeshStandardMaterial.js +42 -1
  158. package/src/materials/MeshToonMaterial.js +34 -1
  159. package/src/materials/PointsMaterial.js +7 -0
  160. package/src/materials/ShaderMaterial.js +86 -0
  161. package/src/materials/SpriteMaterial.js +7 -0
  162. package/src/materials/nodes/Line2NodeMaterial.js +378 -322
  163. package/src/materials/nodes/MeshBasicNodeMaterial.js +2 -2
  164. package/src/materials/nodes/MeshNormalNodeMaterial.js +2 -2
  165. package/src/materials/nodes/MeshPhongNodeMaterial.js +0 -9
  166. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +0 -30
  167. package/src/materials/nodes/MeshSSSNodeMaterial.js +0 -13
  168. package/src/materials/nodes/MeshStandardNodeMaterial.js +0 -11
  169. package/src/materials/nodes/NodeMaterial.js +115 -74
  170. package/src/materials/nodes/SpriteNodeMaterial.js +0 -10
  171. package/src/materials/nodes/manager/NodeMaterialObserver.js +49 -20
  172. package/src/math/Box3.js +5 -0
  173. package/src/math/FrustumArray.js +103 -133
  174. package/src/math/Interpolant.js +1 -1
  175. package/src/math/MathUtils.js +2 -2
  176. package/src/math/Matrix3.js +11 -0
  177. package/src/math/Matrix4.js +28 -3
  178. package/src/math/Vector2.js +2 -2
  179. package/src/math/Vector3.js +2 -2
  180. package/src/math/Vector4.js +2 -2
  181. package/src/math/interpolants/BezierInterpolant.js +4 -6
  182. package/src/nodes/Nodes.js +2 -5
  183. package/src/nodes/TSL.js +8 -6
  184. package/src/nodes/accessors/Arrays.js +4 -4
  185. package/src/nodes/accessors/Batch.js +108 -0
  186. package/src/nodes/accessors/Bitangent.js +2 -2
  187. package/src/nodes/accessors/BufferAttributeNode.js +13 -2
  188. package/src/nodes/accessors/Camera.js +7 -7
  189. package/src/nodes/accessors/ClippingNode.js +1 -1
  190. package/src/nodes/accessors/Instance.js +264 -0
  191. package/src/nodes/accessors/MaterialNode.js +18 -2
  192. package/src/nodes/accessors/MaterialProperties.js +4 -3
  193. package/src/nodes/accessors/{MorphNode.js → Morph.js} +99 -112
  194. package/src/nodes/accessors/Normal.js +13 -13
  195. package/src/nodes/accessors/Position.js +5 -1
  196. package/src/nodes/accessors/ReferenceNode.js +1 -0
  197. package/src/nodes/accessors/ReflectVector.js +3 -3
  198. package/src/nodes/accessors/SceneProperties.js +1 -1
  199. package/src/nodes/accessors/Skinning.js +263 -0
  200. package/src/nodes/accessors/StorageBufferNode.js +2 -2
  201. package/src/nodes/accessors/StorageTexture3DNode.js +100 -0
  202. package/src/nodes/accessors/StorageTextureNode.js +39 -7
  203. package/src/nodes/accessors/Tangent.js +4 -4
  204. package/src/nodes/accessors/TextureNode.js +60 -5
  205. package/src/nodes/code/FunctionNode.js +2 -16
  206. package/src/nodes/core/MRTNode.js +7 -2
  207. package/src/nodes/core/Node.js +39 -2
  208. package/src/nodes/core/NodeBuilder.js +201 -41
  209. package/src/nodes/core/NodeUtils.js +13 -13
  210. package/src/nodes/core/OutputStructNode.js +1 -1
  211. package/src/nodes/core/OverrideContextNode.js +153 -0
  212. package/src/nodes/core/PropertyNode.js +51 -5
  213. package/src/nodes/core/StackNode.js +56 -34
  214. package/src/nodes/core/StructNode.js +4 -6
  215. package/src/nodes/core/StructTypeNode.js +6 -6
  216. package/src/nodes/core/VarNode.js +8 -0
  217. package/src/nodes/core/VaryingNode.js +12 -2
  218. package/src/nodes/display/BlendModes.js +1 -41
  219. package/src/nodes/display/BumpMapNode.js +6 -1
  220. package/src/nodes/display/ColorAdjustment.js +10 -9
  221. package/src/nodes/display/FrontFacingNode.js +38 -9
  222. package/src/nodes/display/NormalMapNode.js +2 -2
  223. package/src/nodes/display/PassNode.js +35 -43
  224. package/src/nodes/display/PremultiplyAlphaFunctions.js +39 -0
  225. package/src/nodes/display/RenderOutputNode.js +12 -3
  226. package/src/nodes/functions/VolumetricLightingModel.js +40 -7
  227. package/src/nodes/gpgpu/WorkgroupInfoNode.js +1 -1
  228. package/src/nodes/lighting/EnvironmentNode.js +2 -2
  229. package/src/nodes/lighting/IESSpotLightNode.js +40 -2
  230. package/src/nodes/lighting/LightingContextNode.js +10 -2
  231. package/src/nodes/lighting/LightsNode.js +92 -37
  232. package/src/nodes/lighting/PointShadowNode.js +7 -1
  233. package/src/nodes/lighting/ShadowFilterNode.js +21 -52
  234. package/src/nodes/lighting/ShadowNode.js +34 -14
  235. package/src/nodes/materialx/lib/mx_noise.js +2 -2
  236. package/src/nodes/math/ConditionalNode.js +3 -3
  237. package/src/nodes/math/MathNode.js +39 -11
  238. package/src/nodes/math/OperatorNode.js +23 -23
  239. package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
  240. package/src/nodes/pmrem/PMREMNode.js +33 -2
  241. package/src/nodes/tsl/TSLCore.js +63 -18
  242. package/src/nodes/utils/EquirectUV.js +30 -5
  243. package/src/nodes/utils/FunctionOverloadingNode.js +1 -1
  244. package/src/nodes/utils/Packing.js +35 -4
  245. package/src/nodes/utils/RTTNode.js +40 -24
  246. package/src/nodes/utils/ReflectorNode.js +1 -0
  247. package/src/nodes/utils/StorageArrayElementNode.js +1 -1
  248. package/src/objects/BatchedMesh.js +22 -14
  249. package/src/objects/InstancedMesh.js +0 -11
  250. package/src/objects/Skeleton.js +0 -9
  251. package/src/profiler/ProfilerService.js +185 -42
  252. package/src/renderers/WebGLRenderer.js +21 -15
  253. package/src/renderers/common/Backend.js +49 -5
  254. package/src/renderers/common/Bindings.js +114 -45
  255. package/src/renderers/common/Buffer.js +9 -0
  256. package/src/renderers/common/ClippingContext.js +10 -2
  257. package/src/renderers/common/Info.js +63 -22
  258. package/src/renderers/common/Lighting.js +53 -5
  259. package/src/renderers/common/RenderList.js +42 -4
  260. package/src/renderers/common/RenderObject.js +73 -13
  261. package/src/renderers/common/Renderer.js +282 -109
  262. package/src/renderers/common/Sampler.js +16 -48
  263. package/src/renderers/common/Textures.js +32 -5
  264. package/src/renderers/common/TimestampQueryPool.js +1 -1
  265. package/src/renderers/common/UniformsGroup.js +31 -9
  266. package/src/renderers/common/XRManager.js +340 -22
  267. package/src/renderers/common/extras/PMREMGenerator.js +15 -38
  268. package/src/renderers/common/nodes/NodeBuilderState.js +9 -1
  269. package/src/renderers/common/nodes/NodeLibrary.js +4 -4
  270. package/src/renderers/common/nodes/NodeManager.js +63 -14
  271. package/src/renderers/common/nodes/NodeUniformBuffer.js +13 -0
  272. package/src/renderers/shaders/ShaderChunk/common.glsl.js +13 -4
  273. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +0 -6
  274. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  275. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +2 -2
  276. package/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js +1 -1
  277. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  278. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +1 -1
  279. package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +2 -2
  280. package/src/renderers/shaders/ShaderChunk/normal_vertex.glsl.js +6 -0
  281. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +1 -1
  282. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  283. package/src/renderers/shaders/ShaderLib/distance.glsl.js +1 -1
  284. package/src/renderers/webgl/WebGLOutput.js +2 -1
  285. package/src/renderers/webgl/WebGLProgram.js +5 -4
  286. package/src/renderers/webgl/WebGLPrograms.js +11 -4
  287. package/src/renderers/webgl/WebGLRenderLists.js +9 -1
  288. package/src/renderers/webgl/WebGLShaderCache.js +5 -11
  289. package/src/renderers/webgl/WebGLTextures.js +20 -7
  290. package/src/renderers/webgl/WebGLUniformsGroups.js +66 -38
  291. package/src/renderers/webgl-fallback/WebGLBackend.js +84 -25
  292. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +138 -8
  293. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +1 -1
  294. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -22
  295. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +4 -2
  296. package/src/renderers/webgpu/WebGPUBackend.js +480 -169
  297. package/src/renderers/webgpu/descriptors/GPUBindGroupDescriptor.js +48 -0
  298. package/src/renderers/webgpu/descriptors/GPUBufferDescriptor.js +57 -0
  299. package/src/renderers/webgpu/descriptors/GPUCommandEncoderDescriptor.js +30 -0
  300. package/src/renderers/webgpu/descriptors/GPUComputePassDescriptor.js +38 -0
  301. package/src/renderers/webgpu/descriptors/GPUComputePipelineDescriptor.js +48 -0
  302. package/src/renderers/webgpu/descriptors/GPUCopyExternalImageDestInfo.js +47 -0
  303. package/src/renderers/webgpu/descriptors/GPUCopyExternalImageSourceInfo.js +50 -0
  304. package/src/renderers/webgpu/descriptors/GPUExtent3D.js +51 -0
  305. package/src/renderers/webgpu/descriptors/GPUPipelineLayoutDescriptor.js +39 -0
  306. package/src/renderers/webgpu/descriptors/GPUQuerySetDescriptor.js +47 -0
  307. package/src/renderers/webgpu/descriptors/GPURenderBundleEncoderDescriptor.js +74 -0
  308. package/src/renderers/webgpu/descriptors/GPURenderPassColorAttachment.js +72 -0
  309. package/src/renderers/webgpu/descriptors/GPURenderPassDepthStencilAttachment.js +99 -0
  310. package/src/renderers/webgpu/descriptors/GPURenderPassDescriptor.js +72 -0
  311. package/src/renderers/webgpu/descriptors/GPURenderPassTimestampWrites.js +49 -0
  312. package/src/renderers/webgpu/descriptors/GPURenderPipelineDescriptor.js +130 -0
  313. package/src/renderers/webgpu/descriptors/GPUSamplerDescriptor.js +119 -0
  314. package/src/renderers/webgpu/descriptors/GPUShaderModuleDescriptor.js +46 -0
  315. package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferInfo.js +57 -0
  316. package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferLayout.js +48 -0
  317. package/src/renderers/webgpu/descriptors/GPUTexelCopyTextureInfo.js +61 -0
  318. package/src/renderers/webgpu/descriptors/GPUTextureDescriptor.js +99 -0
  319. package/src/renderers/webgpu/descriptors/GPUTextureViewDescriptor.js +108 -0
  320. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +0 -1
  321. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +164 -7
  322. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +1 -1
  323. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +98 -38
  324. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +72 -68
  325. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +164 -69
  326. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +158 -95
  327. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +297 -141
  328. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +33 -18
  329. package/src/renderers/webgpu/utils/WebGPUUtils.js +38 -3
  330. package/src/textures/DepthTexture.js +1 -1
  331. package/src/textures/ExternalTexture.js +0 -3
  332. package/examples/fonts/LICENSE +0 -13
  333. package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
  334. package/examples/fonts/MPLUSRounded1c/OFL.txt +0 -91
  335. package/examples/fonts/README.md +0 -11
  336. package/examples/fonts/droid/NOTICE +0 -190
  337. package/examples/fonts/droid/README.txt +0 -18
  338. package/examples/fonts/droid/droid_sans_bold.typeface.json +0 -1
  339. package/examples/fonts/droid/droid_sans_mono_regular.typeface.json +0 -1
  340. package/examples/fonts/droid/droid_sans_regular.typeface.json +0 -1
  341. package/examples/fonts/droid/droid_serif_bold.typeface.json +0 -1
  342. package/examples/fonts/droid/droid_serif_regular.typeface.json +0 -1
  343. package/examples/fonts/gentilis_bold.typeface.json +0 -1
  344. package/examples/fonts/gentilis_regular.typeface.json +0 -1
  345. package/examples/fonts/helvetiker_bold.typeface.json +0 -1
  346. package/examples/fonts/helvetiker_regular.typeface.json +0 -1
  347. package/examples/fonts/optimer_bold.typeface.json +0 -1
  348. package/examples/fonts/optimer_regular.typeface.json +0 -1
  349. package/examples/fonts/ttf/README.md +0 -9
  350. package/examples/fonts/ttf/kenpixel.ttf +0 -0
  351. package/examples/jsm/inspector/extensions/extensions.json +0 -6
  352. package/examples/jsm/libs/ammo.wasm.js +0 -822
  353. package/examples/jsm/libs/ammo.wasm.wasm +0 -0
  354. package/examples/jsm/libs/draco/draco_encoder.js +0 -33
  355. package/examples/jsm/libs/draco/gltf/draco_encoder.js +0 -33
  356. package/examples/jsm/libs/lottie_canvas.module.js +0 -14849
  357. package/examples/jsm/libs/opentype.module.js +0 -14506
  358. package/examples/jsm/libs/rhino3dm/rhino3dm.js +0 -21
  359. package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +0 -16
  360. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  361. package/examples/jsm/lighting/TiledLighting.js +0 -42
  362. package/examples/jsm/tsl/display/AnamorphicNode.js +0 -293
  363. package/examples/jsm/tsl/lighting/TiledLightsNode.js +0 -442
  364. package/src/nodes/accessors/BatchNode.js +0 -163
  365. package/src/nodes/accessors/InstanceNode.js +0 -349
  366. package/src/nodes/accessors/InstancedMeshNode.js +0 -50
  367. package/src/nodes/accessors/SkinningNode.js +0 -328
package/build/three.cjs CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  'use strict';
7
7
 
8
- const REVISION = '184';
8
+ const REVISION = '185';
9
9
 
10
10
  /**
11
11
  * Represents mouse buttons and interaction types in context of controls.
@@ -2677,7 +2677,7 @@ function denormalize( value, array ) {
2677
2677
 
2678
2678
  default:
2679
2679
 
2680
- throw new Error( 'Invalid component type.' );
2680
+ throw new Error( 'THREE.MathUtils: Invalid component type.' );
2681
2681
 
2682
2682
  }
2683
2683
 
@@ -2724,7 +2724,7 @@ function normalize( value, array ) {
2724
2724
 
2725
2725
  default:
2726
2726
 
2727
- throw new Error( 'Invalid component type.' );
2727
+ throw new Error( 'THREE.MathUtils: Invalid component type.' );
2728
2728
 
2729
2729
  }
2730
2730
 
@@ -3150,7 +3150,7 @@ class Vector2 {
3150
3150
 
3151
3151
  case 0: this.x = value; break;
3152
3152
  case 1: this.y = value; break;
3153
- default: throw new Error( 'index is out of range: ' + index );
3153
+ default: throw new Error( 'THREE.Vector2: index is out of range: ' + index );
3154
3154
 
3155
3155
  }
3156
3156
 
@@ -3170,7 +3170,7 @@ class Vector2 {
3170
3170
 
3171
3171
  case 0: return this.x;
3172
3172
  case 1: return this.y;
3173
- default: throw new Error( 'index is out of range: ' + index );
3173
+ default: throw new Error( 'THREE.Vector2: index is out of range: ' + index );
3174
3174
 
3175
3175
  }
3176
3176
 
@@ -4925,7 +4925,7 @@ class Vector3 {
4925
4925
  case 0: this.x = value; break;
4926
4926
  case 1: this.y = value; break;
4927
4927
  case 2: this.z = value; break;
4928
- default: throw new Error( 'index is out of range: ' + index );
4928
+ default: throw new Error( 'THREE.Vector3: index is out of range: ' + index );
4929
4929
 
4930
4930
  }
4931
4931
 
@@ -4946,7 +4946,7 @@ class Vector3 {
4946
4946
  case 0: return this.x;
4947
4947
  case 1: return this.y;
4948
4948
  case 2: return this.z;
4949
- default: throw new Error( 'index is out of range: ' + index );
4949
+ default: throw new Error( 'THREE.Vector3: index is out of range: ' + index );
4950
4950
 
4951
4951
  }
4952
4952
 
@@ -6429,12 +6429,15 @@ class Matrix3 {
6429
6429
  /**
6430
6430
  * Scales this matrix with the given scalar values.
6431
6431
  *
6432
+ * @deprecated
6432
6433
  * @param {number} sx - The amount to scale in the X axis.
6433
6434
  * @param {number} sy - The amount to scale in the Y axis.
6434
6435
  * @return {Matrix3} A reference to this matrix.
6435
6436
  */
6436
6437
  scale( sx, sy ) {
6437
6438
 
6439
+ warnOnce( 'Matrix3: .scale() is deprecated. Use .makeScale() instead.' ); // @deprecated r185
6440
+
6438
6441
  this.premultiply( _m3.makeScale( sx, sy ) );
6439
6442
 
6440
6443
  return this;
@@ -6444,11 +6447,14 @@ class Matrix3 {
6444
6447
  /**
6445
6448
  * Rotates this matrix by the given angle.
6446
6449
  *
6450
+ * @deprecated
6447
6451
  * @param {number} theta - The rotation in radians.
6448
6452
  * @return {Matrix3} A reference to this matrix.
6449
6453
  */
6450
6454
  rotate( theta ) {
6451
6455
 
6456
+ warnOnce( 'Matrix3: .rotate() is deprecated. Use .makeRotation() instead.' ); // @deprecated r185
6457
+
6452
6458
  this.premultiply( _m3.makeRotation( - theta ) );
6453
6459
 
6454
6460
  return this;
@@ -6458,12 +6464,15 @@ class Matrix3 {
6458
6464
  /**
6459
6465
  * Translates this matrix by the given scalar values.
6460
6466
  *
6467
+ * @deprecated
6461
6468
  * @param {number} tx - The amount to translate in the X axis.
6462
6469
  * @param {number} ty - The amount to translate in the Y axis.
6463
6470
  * @return {Matrix3} A reference to this matrix.
6464
6471
  */
6465
6472
  translate( tx, ty ) {
6466
6473
 
6474
+ warnOnce( 'Matrix3: .translate() is deprecated. Use .makeTranslation() instead.' ); // @deprecated r185
6475
+
6467
6476
  this.premultiply( _m3.makeTranslation( tx, ty ) );
6468
6477
 
6469
6478
  return this;
@@ -8220,7 +8229,7 @@ class Vector4 {
8220
8229
  case 1: this.y = value; break;
8221
8230
  case 2: this.z = value; break;
8222
8231
  case 3: this.w = value; break;
8223
- default: throw new Error( 'index is out of range: ' + index );
8232
+ default: throw new Error( 'THREE.Vector4: index is out of range: ' + index );
8224
8233
 
8225
8234
  }
8226
8235
 
@@ -8243,7 +8252,7 @@ class Vector4 {
8243
8252
  case 1: return this.y;
8244
8253
  case 2: return this.z;
8245
8254
  case 3: return this.w;
8246
- default: throw new Error( 'index is out of range: ' + index );
8255
+ default: throw new Error( 'THREE.Vector4: index is out of range: ' + index );
8247
8256
 
8248
8257
  }
8249
8258
 
@@ -9094,7 +9103,8 @@ class RenderTarget extends EventDispatcher {
9094
9103
  * @property {number} [samples=0] - The MSAA samples count.
9095
9104
  * @property {number} [count=1] - Defines the number of color attachments . Must be at least `1`.
9096
9105
  * @property {number} [depth=1] - The texture depth.
9097
- * @property {boolean} [multiview=false] - Whether this target is used for multiview rendering.
9106
+ * @property {boolean} [multiview=false] - Whether this target is used for multiview rendering (WebGL OVR_multiview2 extension).
9107
+ * @property {boolean} [useArrayDepthTexture=false] - Whether to create the depth texture as an array texture for per-layer depth testing. This is separate from multiview so layered render targets can use array depth without the multiview extension.
9098
9108
  */
9099
9109
 
9100
9110
  /**
@@ -9120,7 +9130,8 @@ class RenderTarget extends EventDispatcher {
9120
9130
  samples: 0,
9121
9131
  count: 1,
9122
9132
  depth: 1,
9123
- multiview: false
9133
+ multiview: false,
9134
+ useArrayDepthTexture: false
9124
9135
  }, options );
9125
9136
 
9126
9137
  /**
@@ -9257,6 +9268,16 @@ class RenderTarget extends EventDispatcher {
9257
9268
  */
9258
9269
  this.multiview = options.multiview;
9259
9270
 
9271
+ /**
9272
+ * Whether to create the depth texture as an array texture for per-layer depth testing.
9273
+ * This is separate from multiview so layered render targets can use array depth without
9274
+ * the multiview extension.
9275
+ *
9276
+ * @type {boolean}
9277
+ * @default false
9278
+ */
9279
+ this.useArrayDepthTexture = options.useArrayDepthTexture;
9280
+
9260
9281
  }
9261
9282
 
9262
9283
  _setTextureOptions( options = {} ) {
@@ -9428,6 +9449,7 @@ class RenderTarget extends EventDispatcher {
9428
9449
 
9429
9450
  this.samples = source.samples;
9430
9451
  this.multiview = source.multiview;
9452
+ this.useArrayDepthTexture = source.useArrayDepthTexture;
9431
9453
 
9432
9454
  return this;
9433
9455
 
@@ -10041,7 +10063,7 @@ class Matrix4 {
10041
10063
  */
10042
10064
  extractBasis( xAxis, yAxis, zAxis ) {
10043
10065
 
10044
- if ( this.determinant() === 0 ) {
10066
+ if ( this.determinantAffine() === 0 ) {
10045
10067
 
10046
10068
  xAxis.set( 1, 0, 0 );
10047
10069
  yAxis.set( 0, 1, 0 );
@@ -10091,7 +10113,7 @@ class Matrix4 {
10091
10113
  */
10092
10114
  extractRotation( m ) {
10093
10115
 
10094
- if ( m.determinant() === 0 ) {
10116
+ if ( m.determinantAffine() === 0 ) {
10095
10117
 
10096
10118
  return this.identity();
10097
10119
 
@@ -10452,6 +10474,31 @@ class Matrix4 {
10452
10474
 
10453
10475
  }
10454
10476
 
10477
+ /**
10478
+ * Computes and returns the determinant of the 4x4 matrix, but assumes the
10479
+ * matrix is affine, saving some computations.
10480
+ *
10481
+ * For affine matrices (like an object's world matrix), this value equals the
10482
+ * full 4x4 {@link Matrix4#determinant} but is cheaper to compute.
10483
+ *
10484
+ * Assumes the bottom row is [0, 0, 0, 1].
10485
+ *
10486
+ * @return {number} The determinant of the matrix.
10487
+ */
10488
+ determinantAffine() {
10489
+
10490
+ const te = this.elements;
10491
+
10492
+ const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ];
10493
+ const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ];
10494
+ const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ];
10495
+
10496
+ return n11 * ( n22 * n33 - n23 * n32 ) -
10497
+ n12 * ( n21 * n33 - n23 * n31 ) +
10498
+ n13 * ( n21 * n32 - n22 * n31 );
10499
+
10500
+ }
10501
+
10455
10502
  /**
10456
10503
  * Transposes this matrix in place.
10457
10504
  *
@@ -10861,7 +10908,7 @@ class Matrix4 {
10861
10908
  position.y = te[ 13 ];
10862
10909
  position.z = te[ 14 ];
10863
10910
 
10864
- const det = this.determinant();
10911
+ const det = this.determinantAffine();
10865
10912
 
10866
10913
  if ( det === 0 ) {
10867
10914
 
@@ -12887,8 +12934,10 @@ class Object3D extends EventDispatcher {
12887
12934
  *
12888
12935
  * @param {boolean} [updateParents=false] Whether ancestor nodes should be updated or not.
12889
12936
  * @param {boolean} [updateChildren=false] Whether descendant nodes should be updated or not.
12937
+ * @param {boolean} [force=false] - When set to `true`, a recomputation of world matrices is forced even
12938
+ * when {@link Object3D#matrixWorldNeedsUpdate} is `false`.
12890
12939
  */
12891
- updateWorldMatrix( updateParents, updateChildren ) {
12940
+ updateWorldMatrix( updateParents, updateChildren, force = false ) {
12892
12941
 
12893
12942
  const parent = this.parent;
12894
12943
 
@@ -12900,18 +12949,26 @@ class Object3D extends EventDispatcher {
12900
12949
 
12901
12950
  if ( this.matrixAutoUpdate ) this.updateMatrix();
12902
12951
 
12903
- if ( this.matrixWorldAutoUpdate === true ) {
12952
+ if ( this.matrixWorldNeedsUpdate || force ) {
12904
12953
 
12905
- if ( this.parent === null ) {
12954
+ if ( this.matrixWorldAutoUpdate === true ) {
12906
12955
 
12907
- this.matrixWorld.copy( this.matrix );
12956
+ if ( this.parent === null ) {
12908
12957
 
12909
- } else {
12958
+ this.matrixWorld.copy( this.matrix );
12910
12959
 
12911
- this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
12960
+ } else {
12961
+
12962
+ this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
12963
+
12964
+ }
12912
12965
 
12913
12966
  }
12914
12967
 
12968
+ this.matrixWorldNeedsUpdate = false;
12969
+
12970
+ force = true;
12971
+
12915
12972
  }
12916
12973
 
12917
12974
  // make sure descendants are updated
@@ -12924,7 +12981,7 @@ class Object3D extends EventDispatcher {
12924
12981
 
12925
12982
  const child = children[ i ];
12926
12983
 
12927
- child.updateWorldMatrix( false, true );
12984
+ child.updateWorldMatrix( false, true, force );
12928
12985
 
12929
12986
  }
12930
12987
 
@@ -15799,6 +15856,11 @@ class Box3 {
15799
15856
  * (including its children), accounting for the object's, and children's,
15800
15857
  * world transforms. The function may result in a larger box than strictly necessary.
15801
15858
  *
15859
+ * Note: To compute the correct bounding box, make sure the given 3D object
15860
+ * has an up-to-date world matrix that reflects the current transformation of its
15861
+ * ancestor nodes. Call `object.updateWorldMatrix( true, false )` beforehand if
15862
+ * you're unsure.
15863
+ *
15802
15864
  * @param {Object3D} object - The 3D object to compute the bounding box for.
15803
15865
  * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest
15804
15866
  * world-axis-aligned bounding box at the expense of more computation.
@@ -18304,6 +18366,19 @@ class BufferGeometry extends EventDispatcher {
18304
18366
  */
18305
18367
  this.userData = {};
18306
18368
 
18369
+ /**
18370
+ * `true` when the geometry has been transformed since construction
18371
+ * (e.g. via {@link BufferGeometry#applyMatrix4}). Only relevant for
18372
+ * geometry generators (subclasses that populate `parameters`): when set,
18373
+ * {@link BufferGeometry#toJSON} omits `parameters` since they no longer
18374
+ * describe the geometry.
18375
+ *
18376
+ * @private
18377
+ * @type {boolean}
18378
+ * @default false
18379
+ */
18380
+ this._transformed = false;
18381
+
18307
18382
  }
18308
18383
 
18309
18384
  /**
@@ -18515,6 +18590,8 @@ class BufferGeometry extends EventDispatcher {
18515
18590
 
18516
18591
  }
18517
18592
 
18593
+ this._transformed = true;
18594
+
18518
18595
  return this;
18519
18596
 
18520
18597
  }
@@ -18950,13 +19027,14 @@ class BufferGeometry extends EventDispatcher {
18950
19027
  const normalAttribute = attributes.normal;
18951
19028
  const uvAttribute = attributes.uv;
18952
19029
 
18953
- if ( this.hasAttribute( 'tangent' ) === false ) {
19030
+ let tangentAttribute = this.getAttribute( 'tangent' );
18954
19031
 
18955
- this.setAttribute( 'tangent', new BufferAttribute( new Float32Array( 4 * positionAttribute.count ), 4 ) );
19032
+ if ( tangentAttribute === undefined || tangentAttribute.count !== positionAttribute.count ) {
18956
19033
 
18957
- }
19034
+ tangentAttribute = new BufferAttribute( new Float32Array( 4 * positionAttribute.count ), 4 );
19035
+ this.setAttribute( 'tangent', tangentAttribute );
18958
19036
 
18959
- const tangentAttribute = this.getAttribute( 'tangent' );
19037
+ }
18960
19038
 
18961
19039
  const tan1 = [], tan2 = [];
18962
19040
 
@@ -19085,6 +19163,8 @@ class BufferGeometry extends EventDispatcher {
19085
19163
 
19086
19164
  }
19087
19165
 
19166
+ this._transformed = true;
19167
+
19088
19168
  }
19089
19169
 
19090
19170
  /**
@@ -19102,7 +19182,7 @@ class BufferGeometry extends EventDispatcher {
19102
19182
 
19103
19183
  let normalAttribute = this.getAttribute( 'normal' );
19104
19184
 
19105
- if ( normalAttribute === undefined ) {
19185
+ if ( normalAttribute === undefined || normalAttribute.count !== positionAttribute.count ) {
19106
19186
 
19107
19187
  normalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 );
19108
19188
  this.setAttribute( 'normal', normalAttribute );
@@ -19331,11 +19411,11 @@ class BufferGeometry extends EventDispatcher {
19331
19411
  // standard BufferGeometry serialization
19332
19412
 
19333
19413
  data.uuid = this.uuid;
19334
- data.type = this.type;
19414
+ data.type = ( this.parameters !== undefined && this._transformed === true ) ? 'BufferGeometry' : this.type;
19335
19415
  if ( this.name !== '' ) data.name = this.name;
19336
19416
  if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData;
19337
19417
 
19338
- if ( this.parameters !== undefined ) {
19418
+ if ( this.parameters !== undefined && this._transformed !== true ) {
19339
19419
 
19340
19420
  const parameters = this.parameters;
19341
19421
 
@@ -19546,6 +19626,10 @@ class BufferGeometry extends EventDispatcher {
19546
19626
 
19547
19627
  this.userData = source.userData;
19548
19628
 
19629
+ // transformed flag
19630
+
19631
+ this._transformed = source._transformed;
19632
+
19549
19633
  return this;
19550
19634
 
19551
19635
  }
@@ -20969,7 +21053,11 @@ class Material extends EventDispatcher {
20969
21053
 
20970
21054
  currentValue.set( newValue );
20971
21055
 
20972
- } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
21056
+ } else if (
21057
+ ( ( currentValue && currentValue.isVector2 ) && ( newValue && newValue.isVector2 ) ) ||
21058
+ ( ( currentValue && currentValue.isEuler ) && ( newValue && newValue.isEuler ) ) ||
21059
+ ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) )
21060
+ ) {
20973
21061
 
20974
21062
  currentValue.copy( newValue );
20975
21063
 
@@ -21270,6 +21358,196 @@ class Material extends EventDispatcher {
21270
21358
 
21271
21359
  }
21272
21360
 
21361
+ /**
21362
+ * Deserializes the material from the given JSON.
21363
+ *
21364
+ * @param {Object} json - The JSON holding the serialized material.
21365
+ * @param {Object<string,Texture>} textures - A dictionary holding textures referenced by the material.
21366
+ * @return {Material} A reference to this material.
21367
+ */
21368
+ fromJSON( json, textures ) {
21369
+
21370
+ if ( json.uuid !== undefined ) this.uuid = json.uuid;
21371
+ if ( json.name !== undefined ) this.name = json.name;
21372
+ if ( json.color !== undefined && this.color !== undefined ) this.color.setHex( json.color );
21373
+ if ( json.roughness !== undefined ) this.roughness = json.roughness;
21374
+ if ( json.metalness !== undefined ) this.metalness = json.metalness;
21375
+ if ( json.sheen !== undefined ) this.sheen = json.sheen;
21376
+ if ( json.sheenColor !== undefined ) this.sheenColor = new Color().setHex( json.sheenColor );
21377
+ if ( json.sheenRoughness !== undefined ) this.sheenRoughness = json.sheenRoughness;
21378
+ if ( json.emissive !== undefined && this.emissive !== undefined ) this.emissive.setHex( json.emissive );
21379
+ if ( json.specular !== undefined && this.specular !== undefined ) this.specular.setHex( json.specular );
21380
+ if ( json.specularIntensity !== undefined ) this.specularIntensity = json.specularIntensity;
21381
+ if ( json.specularColor !== undefined && this.specularColor !== undefined ) this.specularColor.setHex( json.specularColor );
21382
+ if ( json.shininess !== undefined ) this.shininess = json.shininess;
21383
+ if ( json.clearcoat !== undefined ) this.clearcoat = json.clearcoat;
21384
+ if ( json.clearcoatRoughness !== undefined ) this.clearcoatRoughness = json.clearcoatRoughness;
21385
+ if ( json.dispersion !== undefined ) this.dispersion = json.dispersion;
21386
+ if ( json.iridescence !== undefined ) this.iridescence = json.iridescence;
21387
+ if ( json.iridescenceIOR !== undefined ) this.iridescenceIOR = json.iridescenceIOR;
21388
+ if ( json.iridescenceThicknessRange !== undefined ) this.iridescenceThicknessRange = json.iridescenceThicknessRange;
21389
+ if ( json.transmission !== undefined ) this.transmission = json.transmission;
21390
+ if ( json.thickness !== undefined ) this.thickness = json.thickness;
21391
+ if ( json.attenuationDistance !== undefined ) this.attenuationDistance = json.attenuationDistance;
21392
+ if ( json.attenuationColor !== undefined && this.attenuationColor !== undefined ) this.attenuationColor.setHex( json.attenuationColor );
21393
+ if ( json.anisotropy !== undefined ) this.anisotropy = json.anisotropy;
21394
+ if ( json.anisotropyRotation !== undefined ) this.anisotropyRotation = json.anisotropyRotation;
21395
+ if ( json.fog !== undefined ) this.fog = json.fog;
21396
+ if ( json.flatShading !== undefined ) this.flatShading = json.flatShading;
21397
+ if ( json.blending !== undefined ) this.blending = json.blending;
21398
+ if ( json.combine !== undefined ) this.combine = json.combine;
21399
+ if ( json.side !== undefined ) this.side = json.side;
21400
+ if ( json.shadowSide !== undefined ) this.shadowSide = json.shadowSide;
21401
+ if ( json.opacity !== undefined ) this.opacity = json.opacity;
21402
+ if ( json.transparent !== undefined ) this.transparent = json.transparent;
21403
+ if ( json.alphaTest !== undefined ) this.alphaTest = json.alphaTest;
21404
+ if ( json.alphaHash !== undefined ) this.alphaHash = json.alphaHash;
21405
+ if ( json.depthFunc !== undefined ) this.depthFunc = json.depthFunc;
21406
+ if ( json.depthTest !== undefined ) this.depthTest = json.depthTest;
21407
+ if ( json.depthWrite !== undefined ) this.depthWrite = json.depthWrite;
21408
+ if ( json.colorWrite !== undefined ) this.colorWrite = json.colorWrite;
21409
+ if ( json.blendSrc !== undefined ) this.blendSrc = json.blendSrc;
21410
+ if ( json.blendDst !== undefined ) this.blendDst = json.blendDst;
21411
+ if ( json.blendEquation !== undefined ) this.blendEquation = json.blendEquation;
21412
+ if ( json.blendSrcAlpha !== undefined ) this.blendSrcAlpha = json.blendSrcAlpha;
21413
+ if ( json.blendDstAlpha !== undefined ) this.blendDstAlpha = json.blendDstAlpha;
21414
+ if ( json.blendEquationAlpha !== undefined ) this.blendEquationAlpha = json.blendEquationAlpha;
21415
+ if ( json.blendColor !== undefined && this.blendColor !== undefined ) this.blendColor.setHex( json.blendColor );
21416
+ if ( json.blendAlpha !== undefined ) this.blendAlpha = json.blendAlpha;
21417
+ if ( json.stencilWriteMask !== undefined ) this.stencilWriteMask = json.stencilWriteMask;
21418
+ if ( json.stencilFunc !== undefined ) this.stencilFunc = json.stencilFunc;
21419
+ if ( json.stencilRef !== undefined ) this.stencilRef = json.stencilRef;
21420
+ if ( json.stencilFuncMask !== undefined ) this.stencilFuncMask = json.stencilFuncMask;
21421
+ if ( json.stencilFail !== undefined ) this.stencilFail = json.stencilFail;
21422
+ if ( json.stencilZFail !== undefined ) this.stencilZFail = json.stencilZFail;
21423
+ if ( json.stencilZPass !== undefined ) this.stencilZPass = json.stencilZPass;
21424
+ if ( json.stencilWrite !== undefined ) this.stencilWrite = json.stencilWrite;
21425
+
21426
+ if ( json.wireframe !== undefined ) this.wireframe = json.wireframe;
21427
+ if ( json.wireframeLinewidth !== undefined ) this.wireframeLinewidth = json.wireframeLinewidth;
21428
+ if ( json.wireframeLinecap !== undefined ) this.wireframeLinecap = json.wireframeLinecap;
21429
+ if ( json.wireframeLinejoin !== undefined ) this.wireframeLinejoin = json.wireframeLinejoin;
21430
+
21431
+ if ( json.rotation !== undefined ) this.rotation = json.rotation;
21432
+
21433
+ if ( json.linewidth !== undefined ) this.linewidth = json.linewidth;
21434
+ if ( json.dashSize !== undefined ) this.dashSize = json.dashSize;
21435
+ if ( json.gapSize !== undefined ) this.gapSize = json.gapSize;
21436
+ if ( json.scale !== undefined ) this.scale = json.scale;
21437
+
21438
+ if ( json.polygonOffset !== undefined ) this.polygonOffset = json.polygonOffset;
21439
+ if ( json.polygonOffsetFactor !== undefined ) this.polygonOffsetFactor = json.polygonOffsetFactor;
21440
+ if ( json.polygonOffsetUnits !== undefined ) this.polygonOffsetUnits = json.polygonOffsetUnits;
21441
+
21442
+ if ( json.dithering !== undefined ) this.dithering = json.dithering;
21443
+
21444
+ if ( json.alphaToCoverage !== undefined ) this.alphaToCoverage = json.alphaToCoverage;
21445
+ if ( json.premultipliedAlpha !== undefined ) this.premultipliedAlpha = json.premultipliedAlpha;
21446
+ if ( json.forceSinglePass !== undefined ) this.forceSinglePass = json.forceSinglePass;
21447
+ if ( json.allowOverride !== undefined ) this.allowOverride = json.allowOverride;
21448
+
21449
+ if ( json.visible !== undefined ) this.visible = json.visible;
21450
+
21451
+ if ( json.toneMapped !== undefined ) this.toneMapped = json.toneMapped;
21452
+
21453
+ if ( json.userData !== undefined ) this.userData = json.userData;
21454
+
21455
+ if ( json.vertexColors !== undefined ) {
21456
+
21457
+ if ( typeof json.vertexColors === 'number' ) {
21458
+
21459
+ this.vertexColors = json.vertexColors > 0;
21460
+
21461
+ } else {
21462
+
21463
+ this.vertexColors = json.vertexColors;
21464
+
21465
+ }
21466
+
21467
+ }
21468
+
21469
+ // for PointsMaterial
21470
+
21471
+ if ( json.size !== undefined ) this.size = json.size;
21472
+ if ( json.sizeAttenuation !== undefined ) this.sizeAttenuation = json.sizeAttenuation;
21473
+
21474
+ // maps
21475
+
21476
+ if ( json.map !== undefined ) this.map = textures[ json.map ] || null;
21477
+ if ( json.matcap !== undefined ) this.matcap = textures[ json.matcap ] || null;
21478
+
21479
+ if ( json.alphaMap !== undefined ) this.alphaMap = textures[ json.alphaMap ] || null;
21480
+
21481
+ if ( json.bumpMap !== undefined ) this.bumpMap = textures[ json.bumpMap ] || null;
21482
+ if ( json.bumpScale !== undefined ) this.bumpScale = json.bumpScale;
21483
+
21484
+ if ( json.normalMap !== undefined ) this.normalMap = textures[ json.normalMap ] || null;
21485
+ if ( json.normalMapType !== undefined ) this.normalMapType = json.normalMapType;
21486
+ if ( json.normalScale !== undefined ) {
21487
+
21488
+ let normalScale = json.normalScale;
21489
+
21490
+ if ( Array.isArray( normalScale ) === false ) {
21491
+
21492
+ // Blender exporter used to export a scalar. See #7459
21493
+
21494
+ normalScale = [ normalScale, normalScale ];
21495
+
21496
+ }
21497
+
21498
+ this.normalScale = new Vector2().fromArray( normalScale );
21499
+
21500
+ }
21501
+
21502
+ if ( json.displacementMap !== undefined ) this.displacementMap = textures[ json.displacementMap ] || null;
21503
+ if ( json.displacementScale !== undefined ) this.displacementScale = json.displacementScale;
21504
+ if ( json.displacementBias !== undefined ) this.displacementBias = json.displacementBias;
21505
+
21506
+ if ( json.roughnessMap !== undefined ) this.roughnessMap = textures[ json.roughnessMap ] || null;
21507
+ if ( json.metalnessMap !== undefined ) this.metalnessMap = textures[ json.metalnessMap ] || null;
21508
+
21509
+ if ( json.emissiveMap !== undefined ) this.emissiveMap = textures[ json.emissiveMap ] || null;
21510
+ if ( json.emissiveIntensity !== undefined ) this.emissiveIntensity = json.emissiveIntensity;
21511
+
21512
+ if ( json.specularMap !== undefined ) this.specularMap = textures[ json.specularMap ] || null;
21513
+ if ( json.specularIntensityMap !== undefined ) this.specularIntensityMap = textures[ json.specularIntensityMap ] || null;
21514
+ if ( json.specularColorMap !== undefined ) this.specularColorMap = textures[ json.specularColorMap ] || null;
21515
+
21516
+ if ( json.envMap !== undefined ) this.envMap = textures[ json.envMap ] || null;
21517
+ if ( json.envMapRotation !== undefined ) this.envMapRotation.fromArray( json.envMapRotation );
21518
+ if ( json.envMapIntensity !== undefined ) this.envMapIntensity = json.envMapIntensity;
21519
+
21520
+ if ( json.reflectivity !== undefined ) this.reflectivity = json.reflectivity;
21521
+ if ( json.refractionRatio !== undefined ) this.refractionRatio = json.refractionRatio;
21522
+
21523
+ if ( json.lightMap !== undefined ) this.lightMap = textures[ json.lightMap ] || null;
21524
+ if ( json.lightMapIntensity !== undefined ) this.lightMapIntensity = json.lightMapIntensity;
21525
+
21526
+ if ( json.aoMap !== undefined ) this.aoMap = textures[ json.aoMap ] || null;
21527
+ if ( json.aoMapIntensity !== undefined ) this.aoMapIntensity = json.aoMapIntensity;
21528
+
21529
+ if ( json.gradientMap !== undefined ) this.gradientMap = textures[ json.gradientMap ] || null;
21530
+
21531
+ if ( json.clearcoatMap !== undefined ) this.clearcoatMap = textures[ json.clearcoatMap ] || null;
21532
+ if ( json.clearcoatRoughnessMap !== undefined ) this.clearcoatRoughnessMap = textures[ json.clearcoatRoughnessMap ] || null;
21533
+ if ( json.clearcoatNormalMap !== undefined ) this.clearcoatNormalMap = textures[ json.clearcoatNormalMap ] || null;
21534
+ if ( json.clearcoatNormalScale !== undefined ) this.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale );
21535
+
21536
+ if ( json.iridescenceMap !== undefined ) this.iridescenceMap = textures[ json.iridescenceMap ] || null;
21537
+ if ( json.iridescenceThicknessMap !== undefined ) this.iridescenceThicknessMap = textures[ json.iridescenceThicknessMap ] || null;
21538
+
21539
+ if ( json.transmissionMap !== undefined ) this.transmissionMap = textures[ json.transmissionMap ] || null;
21540
+ if ( json.thicknessMap !== undefined ) this.thicknessMap = textures[ json.thicknessMap ] || null;
21541
+
21542
+ if ( json.anisotropyMap !== undefined ) this.anisotropyMap = textures[ json.anisotropyMap ] || null;
21543
+
21544
+ if ( json.sheenColorMap !== undefined ) this.sheenColorMap = textures[ json.sheenColorMap ] || null;
21545
+ if ( json.sheenRoughnessMap !== undefined ) this.sheenRoughnessMap = textures[ json.sheenRoughnessMap ] || null;
21546
+
21547
+ return this;
21548
+
21549
+ }
21550
+
21273
21551
  /**
21274
21552
  * Returns a new material with copied values from this instance.
21275
21553
  *
@@ -21456,6 +21734,10 @@ class SpriteMaterial extends Material {
21456
21734
  * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map
21457
21735
  * color is modulated by the diffuse `color`.
21458
21736
  *
21737
+ * `map` represents color data, and the texture must be assigned a
21738
+ * {@link Texture#colorSpace}. Most `map` textures set
21739
+ * `texture.colorSpace = SRGBColorSpace`.
21740
+ *
21459
21741
  * @type {?Texture}
21460
21742
  * @default null
21461
21743
  */
@@ -21471,6 +21753,9 @@ class SpriteMaterial extends Material {
21471
21753
  * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
21472
21754
  * luminance/alpha textures will also still work as expected.
21473
21755
  *
21756
+ * `alphaMap` represents non-color data. Any texture assigned must have
21757
+ * `texture.colorSpace = NoColorSpace` (default).
21758
+ *
21474
21759
  * @type {?Texture}
21475
21760
  * @default null
21476
21761
  */
@@ -22791,6 +23076,10 @@ class MeshBasicMaterial extends Material {
22791
23076
  * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map
22792
23077
  * color is modulated by the diffuse `color`.
22793
23078
  *
23079
+ * `map` represents color data, and the texture must be assigned a
23080
+ * {@link Texture#colorSpace}. Most `map` textures set
23081
+ * `texture.colorSpace = SRGBColorSpace`.
23082
+ *
22794
23083
  * @type {?Texture}
22795
23084
  * @default null
22796
23085
  */
@@ -22799,6 +23088,11 @@ class MeshBasicMaterial extends Material {
22799
23088
  /**
22800
23089
  * The light map. Requires a second set of UVs.
22801
23090
  *
23091
+ * `lightMap` represents pre-baked illuminance data, and the texture must be assigned
23092
+ * a {@link Texture#colorSpace}. Most `lightMap` textures set
23093
+ * `texture.colorSpace = LinearSRGBColorSpace` and use float-type formats
23094
+ * such as `.exr` or `.hdr`.
23095
+ *
22802
23096
  * @type {?Texture}
22803
23097
  * @default null
22804
23098
  */
@@ -22816,6 +23110,9 @@ class MeshBasicMaterial extends Material {
22816
23110
  * The red channel of this texture is used as the ambient occlusion map.
22817
23111
  * Requires a second set of UVs.
22818
23112
  *
23113
+ * `aoMap` represents non-color data. Any texture assigned must have
23114
+ * `texture.colorSpace = NoColorSpace` (default).
23115
+ *
22819
23116
  * @type {?Texture}
22820
23117
  * @default null
22821
23118
  */
@@ -22834,6 +23131,10 @@ class MeshBasicMaterial extends Material {
22834
23131
  /**
22835
23132
  * Specular map used by the material.
22836
23133
  *
23134
+ * `specularMap` represents color data, and the texture must be assigned a
23135
+ * {@link Texture#colorSpace}. Most `specularMap` textures set
23136
+ * `texture.colorSpace = SRGBColorSpace`.
23137
+ *
22837
23138
  * @type {?Texture}
22838
23139
  * @default null
22839
23140
  */
@@ -22849,6 +23150,9 @@ class MeshBasicMaterial extends Material {
22849
23150
  * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
22850
23151
  * luminance/alpha textures will also still work as expected.
22851
23152
  *
23153
+ * `alphaMap` represents non-color data. Any texture assigned must have
23154
+ * `texture.colorSpace = NoColorSpace` (default).
23155
+ *
22852
23156
  * @type {?Texture}
22853
23157
  * @default null
22854
23158
  */
@@ -22857,6 +23161,11 @@ class MeshBasicMaterial extends Material {
22857
23161
  /**
22858
23162
  * The environment map.
22859
23163
  *
23164
+ * `envMap` represents luminance data, and the texture must be assigned
23165
+ * a {@link Texture#colorSpace}. Most `envMap` textures set
23166
+ * `texture.colorSpace = LinearSRGBColorSpace` and use float-type formats
23167
+ * such as `.exr` or `.hdr`.
23168
+ *
22860
23169
  * @type {?Texture}
22861
23170
  * @default null
22862
23171
  */
@@ -24014,15 +24323,6 @@ class Skeleton {
24014
24323
  */
24015
24324
  this.boneMatrices = null;
24016
24325
 
24017
- /**
24018
- * An array buffer holding the bone data of the previous frame.
24019
- * Required for computing velocity. Maintained in {@link SkinningNode}.
24020
- *
24021
- * @type {?Float32Array}
24022
- * @default null
24023
- */
24024
- this.previousBoneMatrices = null;
24025
-
24026
24326
  /**
24027
24327
  * A texture holding the bone data for use
24028
24328
  * in the vertex shader.
@@ -24448,15 +24748,6 @@ class InstancedMesh extends Mesh {
24448
24748
  */
24449
24749
  this.instanceMatrix = new InstancedBufferAttribute( new Float32Array( count * 16 ), 16 );
24450
24750
 
24451
- /**
24452
- * Represents the local transformation of all instances of the previous frame.
24453
- * Required for computing velocity. Maintained in {@link InstanceNode}.
24454
- *
24455
- * @type {?InstancedBufferAttribute}
24456
- * @default null
24457
- */
24458
- this.previousInstanceMatrix = null;
24459
-
24460
24751
  /**
24461
24752
  * Represents the color of all instances. You have to set its
24462
24753
  * {@link BufferAttribute#needsUpdate} flag to true if you modify instanced data
@@ -24586,8 +24877,6 @@ class InstancedMesh extends Mesh {
24586
24877
 
24587
24878
  this.instanceMatrix.copy( source.instanceMatrix );
24588
24879
 
24589
- if ( source.previousInstanceMatrix !== null ) this.previousInstanceMatrix = source.previousInstanceMatrix.clone();
24590
-
24591
24880
  if ( source.morphTexture !== null ) this.morphTexture = source.morphTexture.clone();
24592
24881
  if ( source.instanceColor !== null ) this.instanceColor = source.instanceColor.clone();
24593
24882
 
@@ -25453,7 +25742,6 @@ class Frustum {
25453
25742
  }
25454
25743
 
25455
25744
  const _projScreenMatrix$2 = /*@__PURE__*/ new Matrix4();
25456
- const _frustum$1 = /*@__PURE__*/ new Frustum();
25457
25745
 
25458
25746
  /**
25459
25747
  * FrustumArray is used to determine if an object is visible in at least one camera
@@ -25475,220 +25763,191 @@ class FrustumArray {
25475
25763
  */
25476
25764
  this.coordinateSystem = WebGLCoordinateSystem;
25477
25765
 
25766
+ /**
25767
+ * A pool of frustum instances. It may hold more entries than are
25768
+ * currently in use; surplus instances are kept for reuse to avoid
25769
+ * reallocating when array cameras of different lengths are rendered.
25770
+ *
25771
+ * @private
25772
+ * @type {Array<Frustum>}
25773
+ */
25774
+ this._frustums = [];
25775
+
25776
+ /**
25777
+ * The number of frustums in {@link FrustumArray#_frustums} that are currently
25778
+ * in use.
25779
+ *
25780
+ * @private
25781
+ * @type {number}
25782
+ * @default 0
25783
+ */
25784
+ this._count = 0;
25785
+
25478
25786
  }
25479
25787
 
25480
25788
  /**
25481
- * Returns `true` if the 3D object's bounding sphere is intersecting any frustum
25482
- * from the camera array.
25789
+ * Computes and caches a frustum for each camera of the given array camera.
25483
25790
  *
25484
- * @param {Object3D} object - The 3D object to test.
25485
- * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
25486
- * @return {boolean} Whether the 3D object is visible in any camera.
25791
+ * @param {ArrayCamera} cameraArray - The array camera whose sub-cameras define the frustums.
25792
+ * @return {FrustumArray} A reference to this frustum array.
25487
25793
  */
25488
- intersectsObject( object, cameraArray ) {
25794
+ setFromArrayCamera( cameraArray ) {
25489
25795
 
25490
- if ( ! cameraArray.isArrayCamera || cameraArray.cameras.length === 0 ) {
25796
+ const cameras = cameraArray.cameras;
25797
+ const frustums = this._frustums;
25491
25798
 
25492
- return false;
25799
+ for ( let i = 0; i < cameras.length; i ++ ) {
25493
25800
 
25494
- }
25495
-
25496
- for ( let i = 0; i < cameraArray.cameras.length; i ++ ) {
25801
+ const camera = cameras[ i ];
25497
25802
 
25498
- const camera = cameraArray.cameras[ i ];
25803
+ _projScreenMatrix$2.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
25499
25804
 
25500
- _projScreenMatrix$2.multiplyMatrices(
25501
- camera.projectionMatrix,
25502
- camera.matrixWorldInverse
25503
- );
25805
+ if ( frustums[ i ] === undefined ) frustums[ i ] = new Frustum();
25504
25806
 
25505
- _frustum$1.setFromProjectionMatrix(
25506
- _projScreenMatrix$2,
25507
- camera.coordinateSystem,
25508
- camera.reversedDepth
25509
- );
25510
-
25511
- if ( _frustum$1.intersectsObject( object ) ) {
25512
-
25513
- return true; // Object is visible in at least one camera
25514
-
25515
- }
25807
+ frustums[ i ].setFromProjectionMatrix( _projScreenMatrix$2, camera.coordinateSystem, camera.reversedDepth );
25516
25808
 
25517
25809
  }
25518
25810
 
25519
- return false; // Not visible in any camera
25811
+ this._count = cameras.length;
25812
+
25813
+ return this;
25520
25814
 
25521
25815
  }
25522
25816
 
25523
25817
  /**
25524
- * Returns `true` if the given sprite is intersecting any frustum
25525
- * from the camera array.
25818
+ * Returns `true` if the 3D object's bounding sphere is intersecting any cached frustum.
25526
25819
  *
25527
- * @param {Sprite} sprite - The sprite to test.
25528
- * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
25529
- * @return {boolean} Whether the sprite is visible in any camera.
25820
+ * {@link FrustumArray#setFromArrayCamera} must be called once per render before this method.
25821
+ *
25822
+ * @param {Object3D} object - The 3D object to test.
25823
+ * @return {boolean} Whether the 3D object is visible in any camera.
25530
25824
  */
25531
- intersectsSprite( sprite, cameraArray ) {
25825
+ intersectsObject( object ) {
25532
25826
 
25533
- if ( ! cameraArray || ! cameraArray.cameras || cameraArray.cameras.length === 0 ) {
25827
+ const frustums = this._frustums;
25534
25828
 
25535
- return false;
25829
+ for ( let i = 0; i < this._count; i ++ ) {
25536
25830
 
25537
- }
25831
+ if ( frustums[ i ].intersectsObject( object ) ) return true;
25538
25832
 
25539
- for ( let i = 0; i < cameraArray.cameras.length; i ++ ) {
25833
+ }
25540
25834
 
25541
- const camera = cameraArray.cameras[ i ];
25835
+ return false;
25542
25836
 
25543
- _projScreenMatrix$2.multiplyMatrices(
25544
- camera.projectionMatrix,
25545
- camera.matrixWorldInverse
25546
- );
25837
+ }
25547
25838
 
25548
- _frustum$1.setFromProjectionMatrix(
25549
- _projScreenMatrix$2,
25550
- camera.coordinateSystem,
25551
- camera.reversedDepth
25552
- );
25839
+ /**
25840
+ * Returns `true` if the given sprite is intersecting any cached frustum.
25841
+ *
25842
+ * {@link FrustumArray#setFromArrayCamera} must be called once per render before this method.
25843
+ *
25844
+ * @param {Sprite} sprite - The sprite to test.
25845
+ * @return {boolean} Whether the sprite is visible in any camera.
25846
+ */
25847
+ intersectsSprite( sprite ) {
25553
25848
 
25554
- if ( _frustum$1.intersectsSprite( sprite ) ) {
25849
+ const frustums = this._frustums;
25555
25850
 
25556
- return true; // Sprite is visible in at least one camera
25851
+ for ( let i = 0; i < this._count; i ++ ) {
25557
25852
 
25558
- }
25853
+ if ( frustums[ i ].intersectsSprite( sprite ) ) return true;
25559
25854
 
25560
25855
  }
25561
25856
 
25562
- return false; // Not visible in any camera
25857
+ return false;
25563
25858
 
25564
25859
  }
25565
25860
 
25566
25861
  /**
25567
- * Returns `true` if the given bounding sphere is intersecting any frustum
25568
- * from the camera array.
25862
+ * Returns `true` if the given bounding sphere is intersecting any cached frustum.
25863
+ *
25864
+ * {@link FrustumArray#setFromArrayCamera} must be called once per render before this method.
25569
25865
  *
25570
25866
  * @param {Sphere} sphere - The bounding sphere to test.
25571
- * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
25572
25867
  * @return {boolean} Whether the sphere is visible in any camera.
25573
25868
  */
25574
- intersectsSphere( sphere, cameraArray ) {
25575
-
25576
- if ( ! cameraArray || ! cameraArray.cameras || cameraArray.cameras.length === 0 ) {
25577
-
25578
- return false;
25579
-
25580
- }
25581
-
25582
- for ( let i = 0; i < cameraArray.cameras.length; i ++ ) {
25583
-
25584
- const camera = cameraArray.cameras[ i ];
25585
-
25586
- _projScreenMatrix$2.multiplyMatrices(
25587
- camera.projectionMatrix,
25588
- camera.matrixWorldInverse
25589
- );
25590
-
25591
- _frustum$1.setFromProjectionMatrix(
25592
- _projScreenMatrix$2,
25593
- camera.coordinateSystem,
25594
- camera.reversedDepth
25595
- );
25869
+ intersectsSphere( sphere ) {
25596
25870
 
25597
- if ( _frustum$1.intersectsSphere( sphere ) ) {
25871
+ const frustums = this._frustums;
25598
25872
 
25599
- return true; // Sphere is visible in at least one camera
25873
+ for ( let i = 0; i < this._count; i ++ ) {
25600
25874
 
25601
- }
25875
+ if ( frustums[ i ].intersectsSphere( sphere ) ) return true;
25602
25876
 
25603
25877
  }
25604
25878
 
25605
- return false; // Not visible in any camera
25879
+ return false;
25606
25880
 
25607
25881
  }
25608
25882
 
25609
25883
  /**
25610
- * Returns `true` if the given bounding box is intersecting any frustum
25611
- * from the camera array.
25884
+ * Returns `true` if the given bounding box is intersecting any cached frustum.
25885
+ *
25886
+ * {@link FrustumArray#setFromArrayCamera} must be called once per render before this method.
25612
25887
  *
25613
25888
  * @param {Box3} box - The bounding box to test.
25614
- * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
25615
25889
  * @return {boolean} Whether the box is visible in any camera.
25616
25890
  */
25617
- intersectsBox( box, cameraArray ) {
25618
-
25619
- if ( ! cameraArray || ! cameraArray.cameras || cameraArray.cameras.length === 0 ) {
25620
-
25621
- return false;
25622
-
25623
- }
25624
-
25625
- for ( let i = 0; i < cameraArray.cameras.length; i ++ ) {
25626
-
25627
- const camera = cameraArray.cameras[ i ];
25628
-
25629
- _projScreenMatrix$2.multiplyMatrices(
25630
- camera.projectionMatrix,
25631
- camera.matrixWorldInverse
25632
- );
25633
-
25634
- _frustum$1.setFromProjectionMatrix(
25635
- _projScreenMatrix$2,
25636
- camera.coordinateSystem,
25637
- camera.reversedDepth
25638
- );
25891
+ intersectsBox( box ) {
25639
25892
 
25640
- if ( _frustum$1.intersectsBox( box ) ) {
25893
+ const frustums = this._frustums;
25641
25894
 
25642
- return true; // Box is visible in at least one camera
25895
+ for ( let i = 0; i < this._count; i ++ ) {
25643
25896
 
25644
- }
25897
+ if ( frustums[ i ].intersectsBox( box ) ) return true;
25645
25898
 
25646
25899
  }
25647
25900
 
25648
- return false; // Not visible in any camera
25901
+ return false;
25649
25902
 
25650
25903
  }
25651
25904
 
25652
25905
  /**
25653
- * Returns `true` if the given point lies within any frustum
25654
- * from the camera array.
25906
+ * Returns `true` if the given point lies within any cached frustum.
25907
+ *
25908
+ * {@link FrustumArray#setFromArrayCamera} must be called once per render before this method.
25655
25909
  *
25656
25910
  * @param {Vector3} point - The point to test.
25657
- * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
25658
25911
  * @return {boolean} Whether the point is visible in any camera.
25659
25912
  */
25660
- containsPoint( point, cameraArray ) {
25913
+ containsPoint( point ) {
25661
25914
 
25662
- if ( ! cameraArray || ! cameraArray.cameras || cameraArray.cameras.length === 0 ) {
25915
+ const frustums = this._frustums;
25663
25916
 
25664
- return false;
25917
+ for ( let i = 0; i < this._count; i ++ ) {
25918
+
25919
+ if ( frustums[ i ].containsPoint( point ) ) return true;
25665
25920
 
25666
25921
  }
25667
25922
 
25668
- for ( let i = 0; i < cameraArray.cameras.length; i ++ ) {
25923
+ return false;
25924
+
25925
+ }
25669
25926
 
25670
- const camera = cameraArray.cameras[ i ];
25927
+ /**
25928
+ * Copies the values of the given frustum array to this instance.
25929
+ *
25930
+ * @param {FrustumArray} frustumArray - The frustum array to copy.
25931
+ * @return {FrustumArray} A reference to this frustum array.
25932
+ */
25933
+ copy( source ) {
25671
25934
 
25672
- _projScreenMatrix$2.multiplyMatrices(
25673
- camera.projectionMatrix,
25674
- camera.matrixWorldInverse
25675
- );
25935
+ this.coordinateSystem = source.coordinateSystem;
25676
25936
 
25677
- _frustum$1.setFromProjectionMatrix(
25678
- _projScreenMatrix$2,
25679
- camera.coordinateSystem,
25680
- camera.reversedDepth
25681
- );
25937
+ const frustums = this._frustums;
25938
+ const sourceFrustums = source._frustums;
25682
25939
 
25683
- if ( _frustum$1.containsPoint( point ) ) {
25940
+ for ( let i = 0; i < source._count; i ++ ) {
25684
25941
 
25685
- return true; // Point is visible in at least one camera
25942
+ if ( frustums[ i ] === undefined ) frustums[ i ] = new Frustum();
25686
25943
 
25687
- }
25944
+ frustums[ i ].copy( sourceFrustums[ i ] );
25688
25945
 
25689
25946
  }
25690
25947
 
25691
- return false; // Not visible in any camera
25948
+ this._count = source._count;
25949
+
25950
+ return this;
25692
25951
 
25693
25952
  }
25694
25953
 
@@ -25699,7 +25958,7 @@ class FrustumArray {
25699
25958
  */
25700
25959
  clone() {
25701
25960
 
25702
- return new FrustumArray();
25961
+ return new FrustumArray().copy( this );
25703
25962
 
25704
25963
  }
25705
25964
 
@@ -26970,7 +27229,7 @@ class BatchedMesh extends Mesh {
26970
27229
  // throw an error if it can't be shrunk to the desired size
26971
27230
  if ( maxInstanceCount < instanceInfo.length ) {
26972
27231
 
26973
- throw new Error( `BatchedMesh: Instance ids outside the range ${ maxInstanceCount } are being used. Cannot shrink instance count.` );
27232
+ throw new Error( `THREE.BatchedMesh: Instance ids outside the range ${ maxInstanceCount } are being used. Cannot shrink instance count.` );
26974
27233
 
26975
27234
  }
26976
27235
 
@@ -27022,7 +27281,7 @@ class BatchedMesh extends Mesh {
27022
27281
  const requiredVertexLength = Math.max( ...validRanges.map( range => range.vertexStart + range.reservedVertexCount ) );
27023
27282
  if ( requiredVertexLength > maxVertexCount ) {
27024
27283
 
27025
- throw new Error( `BatchedMesh: Geometry vertex values are being used outside the range ${ maxIndexCount }. Cannot shrink further.` );
27284
+ throw new Error( `THREE.BatchedMesh: Geometry vertex values are being used outside the range ${ maxIndexCount }. Cannot shrink further.` );
27026
27285
 
27027
27286
  }
27028
27287
 
@@ -27032,7 +27291,7 @@ class BatchedMesh extends Mesh {
27032
27291
  const requiredIndexLength = Math.max( ...validRanges.map( range => range.indexStart + range.reservedIndexCount ) );
27033
27292
  if ( requiredIndexLength > maxIndexCount ) {
27034
27293
 
27035
- throw new Error( `BatchedMesh: Geometry index values are being used outside the range ${ maxIndexCount }. Cannot shrink further.` );
27294
+ throw new Error( `THREE.BatchedMesh: Geometry index values are being used outside the range ${ maxIndexCount }. Cannot shrink further.` );
27036
27295
 
27037
27296
  }
27038
27297
 
@@ -27245,17 +27504,25 @@ class BatchedMesh extends Mesh {
27245
27504
 
27246
27505
  const frustum = camera.isArrayCamera ? _frustumArray : _frustum;
27247
27506
  // prepare the frustum in the local frame
27248
- if ( perObjectFrustumCulled && ! camera.isArrayCamera ) {
27507
+ if ( perObjectFrustumCulled ) {
27249
27508
 
27250
- _matrix$1
27251
- .multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse )
27252
- .multiply( this.matrixWorld );
27509
+ if ( camera.isArrayCamera ) {
27253
27510
 
27254
- _frustum.setFromProjectionMatrix(
27255
- _matrix$1,
27256
- camera.coordinateSystem,
27257
- camera.reversedDepth
27258
- );
27511
+ frustum.setFromArrayCamera( camera );
27512
+
27513
+ } else {
27514
+
27515
+ _matrix$1
27516
+ .multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse )
27517
+ .multiply( this.matrixWorld );
27518
+
27519
+ frustum.setFromProjectionMatrix(
27520
+ _matrix$1,
27521
+ camera.coordinateSystem,
27522
+ camera.reversedDepth
27523
+ );
27524
+
27525
+ }
27259
27526
 
27260
27527
  }
27261
27528
 
@@ -27281,7 +27548,7 @@ class BatchedMesh extends Mesh {
27281
27548
  let culled = false;
27282
27549
  if ( perObjectFrustumCulled ) {
27283
27550
 
27284
- culled = ! frustum.intersectsSphere( _sphere$2, camera );
27551
+ culled = ! frustum.intersectsSphere( _sphere$2 );
27285
27552
 
27286
27553
  }
27287
27554
 
@@ -27338,7 +27605,7 @@ class BatchedMesh extends Mesh {
27338
27605
  // get the bounds in world space
27339
27606
  this.getMatrixAt( i, _matrix$1 );
27340
27607
  this.getBoundingSphereAt( geometryId, _sphere$2 ).applyMatrix4( _matrix$1 );
27341
- culled = ! frustum.intersectsSphere( _sphere$2, camera );
27608
+ culled = ! frustum.intersectsSphere( _sphere$2 );
27342
27609
 
27343
27610
  }
27344
27611
 
@@ -27421,6 +27688,10 @@ class LineBasicMaterial extends Material {
27421
27688
  * Sets the color of the lines using data from a texture. The texture map
27422
27689
  * color is modulated by the diffuse `color`.
27423
27690
  *
27691
+ * `map` represents color data, and the texture must be assigned a
27692
+ * {@link Texture#colorSpace}. Most `map` textures set
27693
+ * `texture.colorSpace = SRGBColorSpace`.
27694
+ *
27424
27695
  * @type {?Texture}
27425
27696
  * @default null
27426
27697
  */
@@ -27974,6 +28245,10 @@ class PointsMaterial extends Material {
27974
28245
  * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map
27975
28246
  * color is modulated by the diffuse `color`.
27976
28247
  *
28248
+ * `map` represents color data, and the texture must be assigned a
28249
+ * {@link Texture#colorSpace}. Most `map` textures set
28250
+ * `texture.colorSpace = SRGBColorSpace`.
28251
+ *
27977
28252
  * @type {?Texture}
27978
28253
  * @default null
27979
28254
  */
@@ -27989,6 +28264,9 @@ class PointsMaterial extends Material {
27989
28264
  * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
27990
28265
  * luminance/alpha textures will also still work as expected.
27991
28266
  *
28267
+ * `alphaMap` represents non-color data. Any texture assigned must have
28268
+ * `texture.colorSpace = NoColorSpace` (default).
28269
+ *
27992
28270
  * @type {?Texture}
27993
28271
  * @default null
27994
28272
  */
@@ -28966,7 +29244,7 @@ class DepthTexture extends Texture {
28966
29244
 
28967
29245
  if ( format !== DepthFormat && format !== DepthStencilFormat ) {
28968
29246
 
28969
- throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );
29247
+ throw new Error( 'THREE.DepthTexture: format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );
28970
29248
 
28971
29249
  }
28972
29250
 
@@ -29116,9 +29394,6 @@ class CubeDepthTexture extends DepthTexture {
29116
29394
  * This may be a texture from a protected media stream, device camera feed,
29117
29395
  * or other data feeds like a depth sensor.
29118
29396
  *
29119
- * Note that this class is only supported in {@link WebGLRenderer}, and in
29120
- * the {@link WebGPURenderer} WebGPU backend.
29121
- *
29122
29397
  * @augments Texture
29123
29398
  */
29124
29399
  class ExternalTexture extends Texture {
@@ -36240,6 +36515,10 @@ class SphereGeometry extends BufferGeometry {
36240
36515
  const verticesRow = [];
36241
36516
 
36242
36517
  const v = iy / heightSegments;
36518
+ const theta = thetaStart + v * thetaLength;
36519
+
36520
+ const y = radius * Math.cos( theta );
36521
+ const ringRadius = Math.sqrt( radius * radius - y * y );
36243
36522
 
36244
36523
  // special case for the poles
36245
36524
 
@@ -36258,12 +36537,13 @@ class SphereGeometry extends BufferGeometry {
36258
36537
  for ( let ix = 0; ix <= widthSegments; ix ++ ) {
36259
36538
 
36260
36539
  const u = ix / widthSegments;
36540
+ const phi = phiStart + u * phiLength;
36261
36541
 
36262
36542
  // vertex
36263
36543
 
36264
- vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
36265
- vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
36266
- vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
36544
+ vertex.x = - ringRadius * Math.cos( phi );
36545
+ vertex.y = y;
36546
+ vertex.z = ringRadius * Math.sin( phi );
36267
36547
 
36268
36548
  vertices.push( vertex.x, vertex.y, vertex.z );
36269
36549
 
@@ -37834,6 +38114,86 @@ class ShaderMaterial extends Material {
37834
38114
 
37835
38115
  }
37836
38116
 
38117
+ /**
38118
+ * Deserializes the material from the given JSON.
38119
+ *
38120
+ * @param {Object} json - The JSON holding the serialized material.
38121
+ * @param {Object<string,Texture>} textures - A dictionary holding textures referenced by the material.
38122
+ * @return {ShaderMaterial} A reference to this material.
38123
+ */
38124
+ fromJSON( json, textures ) {
38125
+
38126
+ super.fromJSON( json, textures );
38127
+
38128
+ if ( json.uniforms !== undefined ) {
38129
+
38130
+ for ( const name in json.uniforms ) {
38131
+
38132
+ const uniform = json.uniforms[ name ];
38133
+
38134
+ this.uniforms[ name ] = {};
38135
+
38136
+ switch ( uniform.type ) {
38137
+
38138
+ case 't':
38139
+ this.uniforms[ name ].value = textures[ uniform.value ] || null;
38140
+ break;
38141
+
38142
+ case 'c':
38143
+ this.uniforms[ name ].value = new Color().setHex( uniform.value );
38144
+ break;
38145
+
38146
+ case 'v2':
38147
+ this.uniforms[ name ].value = new Vector2().fromArray( uniform.value );
38148
+ break;
38149
+
38150
+ case 'v3':
38151
+ this.uniforms[ name ].value = new Vector3().fromArray( uniform.value );
38152
+ break;
38153
+
38154
+ case 'v4':
38155
+ this.uniforms[ name ].value = new Vector4().fromArray( uniform.value );
38156
+ break;
38157
+
38158
+ case 'm3':
38159
+ this.uniforms[ name ].value = new Matrix3().fromArray( uniform.value );
38160
+ break;
38161
+
38162
+ case 'm4':
38163
+ this.uniforms[ name ].value = new Matrix4().fromArray( uniform.value );
38164
+ break;
38165
+
38166
+ default:
38167
+ this.uniforms[ name ].value = uniform.value;
38168
+
38169
+ }
38170
+
38171
+ }
38172
+
38173
+ }
38174
+
38175
+ if ( json.defines !== undefined ) this.defines = json.defines;
38176
+ if ( json.vertexShader !== undefined ) this.vertexShader = json.vertexShader;
38177
+ if ( json.fragmentShader !== undefined ) this.fragmentShader = json.fragmentShader;
38178
+ if ( json.glslVersion !== undefined ) this.glslVersion = json.glslVersion;
38179
+
38180
+ if ( json.extensions !== undefined ) {
38181
+
38182
+ for ( const key in json.extensions ) {
38183
+
38184
+ this.extensions[ key ] = json.extensions[ key ];
38185
+
38186
+ }
38187
+
38188
+ }
38189
+
38190
+ if ( json.lights !== undefined ) this.lights = json.lights;
38191
+ if ( json.clipping !== undefined ) this.clipping = json.clipping;
38192
+
38193
+ return this;
38194
+
38195
+ }
38196
+
37837
38197
  }
37838
38198
 
37839
38199
  /**
@@ -37971,6 +38331,10 @@ class MeshStandardMaterial extends Material {
37971
38331
  * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map
37972
38332
  * color is modulated by the diffuse `color`.
37973
38333
  *
38334
+ * `map` represents color data, and the texture must be assigned a
38335
+ * {@link Texture#colorSpace}. Most `map` textures set
38336
+ * `texture.colorSpace = SRGBColorSpace`.
38337
+ *
37974
38338
  * @type {?Texture}
37975
38339
  * @default null
37976
38340
  */
@@ -37979,6 +38343,11 @@ class MeshStandardMaterial extends Material {
37979
38343
  /**
37980
38344
  * The light map. Requires a second set of UVs.
37981
38345
  *
38346
+ * `lightMap` represents pre-baked illuminance data, and the texture must be assigned
38347
+ * a {@link Texture#colorSpace}. Most `lightMap` textures set
38348
+ * `texture.colorSpace = LinearSRGBColorSpace` and use float-type formats
38349
+ * such as `.exr` or `.hdr`.
38350
+ *
37982
38351
  * @type {?Texture}
37983
38352
  * @default null
37984
38353
  */
@@ -37996,6 +38365,9 @@ class MeshStandardMaterial extends Material {
37996
38365
  * The red channel of this texture is used as the ambient occlusion map.
37997
38366
  * Requires a second set of UVs.
37998
38367
  *
38368
+ * `aoMap` represents non-color data. Any texture assigned must have
38369
+ * `texture.colorSpace = NoColorSpace` (default).
38370
+ *
37999
38371
  * @type {?Texture}
38000
38372
  * @default null
38001
38373
  */
@@ -38033,6 +38405,10 @@ class MeshStandardMaterial extends Material {
38033
38405
  * emissive color and the emissive intensity. If you have an emissive map,
38034
38406
  * be sure to set the emissive color to something other than black.
38035
38407
  *
38408
+ * `emissiveMap` represents color data, and the texture must be assigned a
38409
+ * {@link Texture#colorSpace}. Most `emissiveMap` textures set
38410
+ * `texture.colorSpace = SRGBColorSpace`.
38411
+ *
38036
38412
  * @type {?Texture}
38037
38413
  * @default null
38038
38414
  */
@@ -38044,6 +38420,9 @@ class MeshStandardMaterial extends Material {
38044
38420
  * the geometry of the object, only the lighting. If a normal map is defined
38045
38421
  * this will be ignored.
38046
38422
  *
38423
+ * `bumpMap` represents non-color data. Any texture assigned must have
38424
+ * `texture.colorSpace = NoColorSpace` (default).
38425
+ *
38047
38426
  * @type {?Texture}
38048
38427
  * @default null
38049
38428
  */
@@ -38065,6 +38444,9 @@ class MeshStandardMaterial extends Material {
38065
38444
  * convention, the `y` component of `normalScale` should be negated to compensate
38066
38445
  * for the different handedness.
38067
38446
  *
38447
+ * `normalMap` represents non-color data. Any texture assigned must have
38448
+ * `texture.colorSpace = NoColorSpace` (default).
38449
+ *
38068
38450
  * @type {?Texture}
38069
38451
  * @default null
38070
38452
  */
@@ -38092,7 +38474,12 @@ class MeshStandardMaterial extends Material {
38092
38474
  * displaced vertices can cast shadows, block other objects, and otherwise
38093
38475
  * act as real geometry. The displacement texture is an image where the value
38094
38476
  * of each pixel (white being the highest) is mapped against, and
38095
- * repositions, the vertices of the mesh.
38477
+ * repositions, the vertices of the mesh. For best results, pair a
38478
+ * displacement map with a matching normal map, since the renderer can
38479
+ * not recompute surface normals from the displaced vertices.
38480
+ *
38481
+ * `displacementMap` represents non-color data. Any texture assigned must have
38482
+ * `texture.colorSpace = NoColorSpace` (default).
38096
38483
  *
38097
38484
  * @type {?Texture}
38098
38485
  * @default null
@@ -38123,6 +38510,9 @@ class MeshStandardMaterial extends Material {
38123
38510
  * The green channel of this texture is used to alter the roughness of the
38124
38511
  * material.
38125
38512
  *
38513
+ * `roughnessMap` represents non-color data. Any texture assigned must have
38514
+ * `texture.colorSpace = NoColorSpace` (default).
38515
+ *
38126
38516
  * @type {?Texture}
38127
38517
  * @default null
38128
38518
  */
@@ -38132,6 +38522,9 @@ class MeshStandardMaterial extends Material {
38132
38522
  * The blue channel of this texture is used to alter the metalness of the
38133
38523
  * material.
38134
38524
  *
38525
+ * `metalnessMap` represents non-color data. Any texture assigned must have
38526
+ * `texture.colorSpace = NoColorSpace` (default).
38527
+ *
38135
38528
  * @type {?Texture}
38136
38529
  * @default null
38137
38530
  */
@@ -38147,6 +38540,9 @@ class MeshStandardMaterial extends Material {
38147
38540
  * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
38148
38541
  * luminance/alpha textures will also still work as expected.
38149
38542
  *
38543
+ * `alphaMap` represents non-color data. Any texture assigned must have
38544
+ * `texture.colorSpace = NoColorSpace` (default).
38545
+ *
38150
38546
  * @type {?Texture}
38151
38547
  * @default null
38152
38548
  */
@@ -38156,6 +38552,11 @@ class MeshStandardMaterial extends Material {
38156
38552
  * The environment map. To ensure a physically correct rendering, environment maps
38157
38553
  * are internally pre-processed with {@link PMREMGenerator}.
38158
38554
  *
38555
+ * `envMap` represents luminance data, and the texture must be assigned
38556
+ * a {@link Texture#colorSpace}. Most `envMap` textures set
38557
+ * `texture.colorSpace = LinearSRGBColorSpace` and use float-type formats
38558
+ * such as `.exr` or `.hdr`.
38559
+ *
38159
38560
  * @type {?Texture}
38160
38561
  * @default null
38161
38562
  */
@@ -38367,6 +38768,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38367
38768
  * bitangent space, to be rotated by `anisotropyRotation`. The blue channel
38368
38769
  * contains strength as `[0, 1]` to be multiplied by `anisotropy`.
38369
38770
  *
38771
+ * `anisotropyMap` represents non-color data. Any texture assigned must have
38772
+ * `texture.colorSpace = NoColorSpace` (default).
38773
+ *
38370
38774
  * @type {?Texture}
38371
38775
  * @default null
38372
38776
  */
@@ -38376,6 +38780,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38376
38780
  * The red channel of this texture is multiplied against `clearcoat`,
38377
38781
  * for per-pixel control over a coating's intensity.
38378
38782
  *
38783
+ * `clearcoatMap` represents non-color data. Any texture assigned must have
38784
+ * `texture.colorSpace = NoColorSpace` (default).
38785
+ *
38379
38786
  * @type {?Texture}
38380
38787
  * @default null
38381
38788
  */
@@ -38393,6 +38800,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38393
38800
  * The green channel of this texture is multiplied against
38394
38801
  * `clearcoatRoughness`, for per-pixel control over a coating's roughness.
38395
38802
  *
38803
+ * `clearcoatRoughnessMap` represents non-color data. Any texture assigned must have
38804
+ * `texture.colorSpace = NoColorSpace` (default).
38805
+ *
38396
38806
  * @type {?Texture}
38397
38807
  * @default null
38398
38808
  */
@@ -38410,6 +38820,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38410
38820
  /**
38411
38821
  * Can be used to enable independent normals for the clear coat layer.
38412
38822
  *
38823
+ * `clearcoatNormalMap` represents non-color data. Any texture assigned must have
38824
+ * `texture.colorSpace = NoColorSpace` (default).
38825
+ *
38413
38826
  * @type {?Texture}
38414
38827
  * @default null
38415
38828
  */
@@ -38451,6 +38864,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38451
38864
  * The red channel of this texture is multiplied against `iridescence`, for per-pixel
38452
38865
  * control over iridescence.
38453
38866
  *
38867
+ * `iridescenceMap` represents non-color data. Any texture assigned must have
38868
+ * `texture.colorSpace = NoColorSpace` (default).
38869
+ *
38454
38870
  * @type {?Texture}
38455
38871
  * @default null
38456
38872
  */
@@ -38481,6 +38897,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38481
38897
  * - `1.0` in the green channel will result in thickness equal to second element of the array.
38482
38898
  * - Values in-between will linearly interpolate between the elements of the array.
38483
38899
  *
38900
+ * `iridescenceThicknessMap` represents non-color data. Any texture assigned must have
38901
+ * `texture.colorSpace = NoColorSpace` (default).
38902
+ *
38484
38903
  * @type {?Texture}
38485
38904
  * @default null
38486
38905
  */
@@ -38498,6 +38917,10 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38498
38917
  * The RGB channels of this texture are multiplied against `sheenColor`, for per-pixel control
38499
38918
  * over sheen tint.
38500
38919
  *
38920
+ * `sheenColorMap` represents color data, and the texture must be assigned a
38921
+ * {@link Texture#colorSpace}. Most `sheenColorMap` textures set
38922
+ * `texture.colorSpace = SRGBColorSpace`.
38923
+ *
38501
38924
  * @type {?Texture}
38502
38925
  * @default null
38503
38926
  */
@@ -38515,6 +38938,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38515
38938
  * The alpha channel of this texture is multiplied against `sheenRoughness`, for per-pixel control
38516
38939
  * over sheen roughness.
38517
38940
  *
38941
+ * `sheenRoughnessMap` represents non-color data. Any texture assigned must have
38942
+ * `texture.colorSpace = NoColorSpace` (default).
38943
+ *
38518
38944
  * @type {?Texture}
38519
38945
  * @default null
38520
38946
  */
@@ -38524,6 +38950,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38524
38950
  * The red channel of this texture is multiplied against `transmission`, for per-pixel control over
38525
38951
  * optical transparency.
38526
38952
  *
38953
+ * `transmissionMap` represents non-color data. Any texture assigned must have
38954
+ * `texture.colorSpace = NoColorSpace` (default).
38955
+ *
38527
38956
  * @type {?Texture}
38528
38957
  * @default null
38529
38958
  */
@@ -38543,6 +38972,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38543
38972
  * A texture that defines the thickness, stored in the green channel. This will
38544
38973
  * be multiplied by `thickness`.
38545
38974
  *
38975
+ * `thicknessMap` represents non-color data. Any texture assigned must have
38976
+ * `texture.colorSpace = NoColorSpace` (default).
38977
+ *
38546
38978
  * @type {?Texture}
38547
38979
  * @default null
38548
38980
  */
@@ -38580,6 +39012,9 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38580
39012
  * The alpha channel of this texture is multiplied against `specularIntensity`,
38581
39013
  * for per-pixel control over specular intensity.
38582
39014
  *
39015
+ * `specularIntensityMap` represents non-color data. Any texture assigned must have
39016
+ * `texture.colorSpace = NoColorSpace` (default).
39017
+ *
38583
39018
  * @type {?Texture}
38584
39019
  * @default null
38585
39020
  */
@@ -38597,6 +39032,10 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
38597
39032
  * The RGB channels of this texture are multiplied against `specularColor`,
38598
39033
  * for per-pixel control over specular color.
38599
39034
  *
39035
+ * `specularColorMap` represents color data, and the texture must be assigned a
39036
+ * {@link Texture#colorSpace}. Most `specularColorMap` textures set
39037
+ * `texture.colorSpace = SRGBColorSpace`.
39038
+ *
38600
39039
  * @type {?Texture}
38601
39040
  * @default null
38602
39041
  */
@@ -38894,6 +39333,10 @@ class MeshPhongMaterial extends Material {
38894
39333
  * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map
38895
39334
  * color is modulated by the diffuse `color`.
38896
39335
  *
39336
+ * `map` represents color data, and the texture must be assigned a
39337
+ * {@link Texture#colorSpace}. Most `map` textures set
39338
+ * `texture.colorSpace = SRGBColorSpace`.
39339
+ *
38897
39340
  * @type {?Texture}
38898
39341
  * @default null
38899
39342
  */
@@ -38902,6 +39345,11 @@ class MeshPhongMaterial extends Material {
38902
39345
  /**
38903
39346
  * The light map. Requires a second set of UVs.
38904
39347
  *
39348
+ * `lightMap` represents pre-baked illuminance data, and the texture must be assigned
39349
+ * a {@link Texture#colorSpace}. Most `lightMap` textures set
39350
+ * `texture.colorSpace = LinearSRGBColorSpace` and use float-type formats
39351
+ * such as `.exr` or `.hdr`.
39352
+ *
38905
39353
  * @type {?Texture}
38906
39354
  * @default null
38907
39355
  */
@@ -38919,6 +39367,9 @@ class MeshPhongMaterial extends Material {
38919
39367
  * The red channel of this texture is used as the ambient occlusion map.
38920
39368
  * Requires a second set of UVs.
38921
39369
  *
39370
+ * `aoMap` represents non-color data. Any texture assigned must have
39371
+ * `texture.colorSpace = NoColorSpace` (default).
39372
+ *
38922
39373
  * @type {?Texture}
38923
39374
  * @default null
38924
39375
  */
@@ -38956,6 +39407,10 @@ class MeshPhongMaterial extends Material {
38956
39407
  * emissive color and the emissive intensity. If you have an emissive map,
38957
39408
  * be sure to set the emissive color to something other than black.
38958
39409
  *
39410
+ * `emissiveMap` represents color data, and the texture must be assigned a
39411
+ * {@link Texture#colorSpace}. Most `emissiveMap` textures set
39412
+ * `texture.colorSpace = SRGBColorSpace`.
39413
+ *
38959
39414
  * @type {?Texture}
38960
39415
  * @default null
38961
39416
  */
@@ -38967,6 +39422,9 @@ class MeshPhongMaterial extends Material {
38967
39422
  * the geometry of the object, only the lighting. If a normal map is defined
38968
39423
  * this will be ignored.
38969
39424
  *
39425
+ * `bumpMap` represents non-color data. Any texture assigned must have
39426
+ * `texture.colorSpace = NoColorSpace` (default).
39427
+ *
38970
39428
  * @type {?Texture}
38971
39429
  * @default null
38972
39430
  */
@@ -38988,6 +39446,9 @@ class MeshPhongMaterial extends Material {
38988
39446
  * convention, the `y` component of `normalScale` should be negated to compensate
38989
39447
  * for the different handedness.
38990
39448
  *
39449
+ * `normalMap` represents non-color data. Any texture assigned must have
39450
+ * `texture.colorSpace = NoColorSpace` (default).
39451
+ *
38991
39452
  * @type {?Texture}
38992
39453
  * @default null
38993
39454
  */
@@ -39015,7 +39476,12 @@ class MeshPhongMaterial extends Material {
39015
39476
  * displaced vertices can cast shadows, block other objects, and otherwise
39016
39477
  * act as real geometry. The displacement texture is an image where the value
39017
39478
  * of each pixel (white being the highest) is mapped against, and
39018
- * repositions, the vertices of the mesh.
39479
+ * repositions, the vertices of the mesh. For best results, pair a
39480
+ * displacement map with a matching normal map, since the renderer can
39481
+ * not recompute surface normals from the displaced vertices.
39482
+ *
39483
+ * `displacementMap` represents non-color data. Any texture assigned must have
39484
+ * `texture.colorSpace = NoColorSpace` (default).
39019
39485
  *
39020
39486
  * @type {?Texture}
39021
39487
  * @default null
@@ -39047,6 +39513,10 @@ class MeshPhongMaterial extends Material {
39047
39513
  * highlight contributes and how much of the environment map affects the
39048
39514
  * surface.
39049
39515
  *
39516
+ * `specularMap` represents color data, and the texture must be assigned a
39517
+ * {@link Texture#colorSpace}. Most `specularMap` textures set
39518
+ * `texture.colorSpace = SRGBColorSpace`.
39519
+ *
39050
39520
  * @type {?Texture}
39051
39521
  * @default null
39052
39522
  */
@@ -39062,6 +39532,9 @@ class MeshPhongMaterial extends Material {
39062
39532
  * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
39063
39533
  * luminance/alpha textures will also still work as expected.
39064
39534
  *
39535
+ * `alphaMap` represents non-color data. Any texture assigned must have
39536
+ * `texture.colorSpace = NoColorSpace` (default).
39537
+ *
39065
39538
  * @type {?Texture}
39066
39539
  * @default null
39067
39540
  */
@@ -39070,6 +39543,11 @@ class MeshPhongMaterial extends Material {
39070
39543
  /**
39071
39544
  * The environment map.
39072
39545
  *
39546
+ * `envMap` represents luminance data, and the texture must be assigned
39547
+ * a {@link Texture#colorSpace}. Most `envMap` textures set
39548
+ * `texture.colorSpace = LinearSRGBColorSpace` and use float-type formats
39549
+ * such as `.exr` or `.hdr`.
39550
+ *
39073
39551
  * @type {?Texture}
39074
39552
  * @default null
39075
39553
  */
@@ -39284,6 +39762,10 @@ class MeshToonMaterial extends Material {
39284
39762
  * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map
39285
39763
  * color is modulated by the diffuse `color`.
39286
39764
  *
39765
+ * `map` represents color data, and the texture must be assigned a
39766
+ * {@link Texture#colorSpace}. Most `map` textures set
39767
+ * `texture.colorSpace = SRGBColorSpace`.
39768
+ *
39287
39769
  * @type {?Texture}
39288
39770
  * @default null
39289
39771
  */
@@ -39294,6 +39776,9 @@ class MeshToonMaterial extends Material {
39294
39776
  * {@link Texture#minFilter} and {@link Texture#magFilter} to {@link NearestFilter}
39295
39777
  * when using this type of texture.
39296
39778
  *
39779
+ * `gradientMap` represents non-color data. Any texture assigned must have
39780
+ * `texture.colorSpace = NoColorSpace` (default).
39781
+ *
39297
39782
  * @type {?Texture}
39298
39783
  * @default null
39299
39784
  */
@@ -39302,6 +39787,11 @@ class MeshToonMaterial extends Material {
39302
39787
  /**
39303
39788
  * The light map. Requires a second set of UVs.
39304
39789
  *
39790
+ * `lightMap` represents pre-baked illuminance data, and the texture must be assigned
39791
+ * a {@link Texture#colorSpace}. Most `lightMap` textures set
39792
+ * `texture.colorSpace = LinearSRGBColorSpace` and use float-type formats
39793
+ * such as `.exr` or `.hdr`.
39794
+ *
39305
39795
  * @type {?Texture}
39306
39796
  * @default null
39307
39797
  */
@@ -39319,6 +39809,9 @@ class MeshToonMaterial extends Material {
39319
39809
  * The red channel of this texture is used as the ambient occlusion map.
39320
39810
  * Requires a second set of UVs.
39321
39811
  *
39812
+ * `aoMap` represents non-color data. Any texture assigned must have
39813
+ * `texture.colorSpace = NoColorSpace` (default).
39814
+ *
39322
39815
  * @type {?Texture}
39323
39816
  * @default null
39324
39817
  */
@@ -39356,6 +39849,10 @@ class MeshToonMaterial extends Material {
39356
39849
  * emissive color and the emissive intensity. If you have an emissive map,
39357
39850
  * be sure to set the emissive color to something other than black.
39358
39851
  *
39852
+ * `emissiveMap` represents color data, and the texture must be assigned a
39853
+ * {@link Texture#colorSpace}. Most `emissiveMap` textures set
39854
+ * `texture.colorSpace = SRGBColorSpace`.
39855
+ *
39359
39856
  * @type {?Texture}
39360
39857
  * @default null
39361
39858
  */
@@ -39367,228 +39864,8 @@ class MeshToonMaterial extends Material {
39367
39864
  * the geometry of the object, only the lighting. If a normal map is defined
39368
39865
  * this will be ignored.
39369
39866
  *
39370
- * @type {?Texture}
39371
- * @default null
39372
- */
39373
- this.bumpMap = null;
39374
-
39375
- /**
39376
- * How much the bump map affects the material. Typical range is `[0,1]`.
39377
- *
39378
- * @type {number}
39379
- * @default 1
39380
- */
39381
- this.bumpScale = 1;
39382
-
39383
- /**
39384
- * The texture to create a normal map. The RGB values affect the surface
39385
- * normal for each pixel fragment and change the way the color is lit. Normal
39386
- * maps do not change the actual shape of the surface, only the lighting. In
39387
- * case the material has a normal map authored using the left handed
39388
- * convention, the `y` component of `normalScale` should be negated to compensate
39389
- * for the different handedness.
39390
- *
39391
- * @type {?Texture}
39392
- * @default null
39393
- */
39394
- this.normalMap = null;
39395
-
39396
- /**
39397
- * The type of normal map.
39398
- *
39399
- * @type {(TangentSpaceNormalMap|ObjectSpaceNormalMap)}
39400
- * @default TangentSpaceNormalMap
39401
- */
39402
- this.normalMapType = TangentSpaceNormalMap;
39403
-
39404
- /**
39405
- * How much the normal map affects the material. Typical value range is `[0,1]`.
39406
- *
39407
- * @type {Vector2}
39408
- * @default (1,1)
39409
- */
39410
- this.normalScale = new Vector2( 1, 1 );
39411
-
39412
- /**
39413
- * The displacement map affects the position of the mesh's vertices. Unlike
39414
- * other maps which only affect the light and shade of the material the
39415
- * displaced vertices can cast shadows, block other objects, and otherwise
39416
- * act as real geometry. The displacement texture is an image where the value
39417
- * of each pixel (white being the highest) is mapped against, and
39418
- * repositions, the vertices of the mesh.
39419
- *
39420
- * @type {?Texture}
39421
- * @default null
39422
- */
39423
- this.displacementMap = null;
39424
-
39425
- /**
39426
- * How much the displacement map affects the mesh (where black is no
39427
- * displacement, and white is maximum displacement). Without a displacement
39428
- * map set, this value is not applied.
39429
- *
39430
- * @type {number}
39431
- * @default 0
39432
- */
39433
- this.displacementScale = 1;
39434
-
39435
- /**
39436
- * The offset of the displacement map's values on the mesh's vertices.
39437
- * The bias is added to the scaled sample of the displacement map.
39438
- * Without a displacement map set, this value is not applied.
39439
- *
39440
- * @type {number}
39441
- * @default 0
39442
- */
39443
- this.displacementBias = 0;
39444
-
39445
- /**
39446
- * The alpha map is a grayscale texture that controls the opacity across the
39447
- * surface (black: fully transparent; white: fully opaque).
39448
- *
39449
- * Only the color of the texture is used, ignoring the alpha channel if one
39450
- * exists. For RGB and RGBA textures, the renderer will use the green channel
39451
- * when sampling this texture due to the extra bit of precision provided for
39452
- * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
39453
- * luminance/alpha textures will also still work as expected.
39454
- *
39455
- * @type {?Texture}
39456
- * @default null
39457
- */
39458
- this.alphaMap = null;
39459
-
39460
- /**
39461
- * Renders the geometry as a wireframe.
39462
- *
39463
- * @type {boolean}
39464
- * @default false
39465
- */
39466
- this.wireframe = false;
39467
-
39468
- /**
39469
- * Controls the thickness of the wireframe.
39470
- *
39471
- * Can only be used with {@link SVGRenderer}.
39472
- *
39473
- * @type {number}
39474
- * @default 1
39475
- */
39476
- this.wireframeLinewidth = 1;
39477
-
39478
- /**
39479
- * Defines appearance of wireframe ends.
39480
- *
39481
- * Can only be used with {@link SVGRenderer}.
39482
- *
39483
- * @type {('round'|'bevel'|'miter')}
39484
- * @default 'round'
39485
- */
39486
- this.wireframeLinecap = 'round';
39487
-
39488
- /**
39489
- * Defines appearance of wireframe joints.
39490
- *
39491
- * Can only be used with {@link SVGRenderer}.
39492
- *
39493
- * @type {('round'|'bevel'|'miter')}
39494
- * @default 'round'
39495
- */
39496
- this.wireframeLinejoin = 'round';
39497
-
39498
- /**
39499
- * Whether the material is affected by fog or not.
39500
- *
39501
- * @type {boolean}
39502
- * @default true
39503
- */
39504
- this.fog = true;
39505
-
39506
- this.setValues( parameters );
39507
-
39508
- }
39509
-
39510
- copy( source ) {
39511
-
39512
- super.copy( source );
39513
-
39514
- this.color.copy( source.color );
39515
-
39516
- this.map = source.map;
39517
- this.gradientMap = source.gradientMap;
39518
-
39519
- this.lightMap = source.lightMap;
39520
- this.lightMapIntensity = source.lightMapIntensity;
39521
-
39522
- this.aoMap = source.aoMap;
39523
- this.aoMapIntensity = source.aoMapIntensity;
39524
-
39525
- this.emissive.copy( source.emissive );
39526
- this.emissiveMap = source.emissiveMap;
39527
- this.emissiveIntensity = source.emissiveIntensity;
39528
-
39529
- this.bumpMap = source.bumpMap;
39530
- this.bumpScale = source.bumpScale;
39531
-
39532
- this.normalMap = source.normalMap;
39533
- this.normalMapType = source.normalMapType;
39534
- this.normalScale.copy( source.normalScale );
39535
-
39536
- this.displacementMap = source.displacementMap;
39537
- this.displacementScale = source.displacementScale;
39538
- this.displacementBias = source.displacementBias;
39539
-
39540
- this.alphaMap = source.alphaMap;
39541
-
39542
- this.wireframe = source.wireframe;
39543
- this.wireframeLinewidth = source.wireframeLinewidth;
39544
- this.wireframeLinecap = source.wireframeLinecap;
39545
- this.wireframeLinejoin = source.wireframeLinejoin;
39546
-
39547
- this.fog = source.fog;
39548
-
39549
- return this;
39550
-
39551
- }
39552
-
39553
- }
39554
-
39555
- /**
39556
- * A material that maps the normal vectors to RGB colors.
39557
- *
39558
- * @augments Material
39559
- * @demo scenes/material-browser.html#MeshNormalMaterial
39560
- */
39561
- class MeshNormalMaterial extends Material {
39562
-
39563
- /**
39564
- * Constructs a new mesh normal material.
39565
- *
39566
- * @param {Object} [parameters] - An object with one or more properties
39567
- * defining the material's appearance. Any property of the material
39568
- * (including any property from inherited materials) can be passed
39569
- * in here. Color values can be passed any type of value accepted
39570
- * by {@link Color#set}.
39571
- */
39572
- constructor( parameters ) {
39573
-
39574
- super();
39575
-
39576
- /**
39577
- * This flag can be used for type testing.
39578
- *
39579
- * @type {boolean}
39580
- * @readonly
39581
- * @default true
39582
- */
39583
- this.isMeshNormalMaterial = true;
39584
-
39585
- this.type = 'MeshNormalMaterial';
39586
-
39587
- /**
39588
- * The texture to create a bump map. The black and white values map to the
39589
- * perceived depth in relation to the lights. Bump doesn't actually affect
39590
- * the geometry of the object, only the lighting. If a normal map is defined
39591
- * this will be ignored.
39867
+ * `bumpMap` represents non-color data. Any texture assigned must have
39868
+ * `texture.colorSpace = NoColorSpace` (default).
39592
39869
  *
39593
39870
  * @type {?Texture}
39594
39871
  * @default null
@@ -39611,6 +39888,9 @@ class MeshNormalMaterial extends Material {
39611
39888
  * convention, the `y` component of `normalScale` should be negated to compensate
39612
39889
  * for the different handedness.
39613
39890
  *
39891
+ * `normalMap` represents non-color data. Any texture assigned must have
39892
+ * `texture.colorSpace = NoColorSpace` (default).
39893
+ *
39614
39894
  * @type {?Texture}
39615
39895
  * @default null
39616
39896
  */
@@ -39638,7 +39918,246 @@ class MeshNormalMaterial extends Material {
39638
39918
  * displaced vertices can cast shadows, block other objects, and otherwise
39639
39919
  * act as real geometry. The displacement texture is an image where the value
39640
39920
  * of each pixel (white being the highest) is mapped against, and
39641
- * repositions, the vertices of the mesh.
39921
+ * repositions, the vertices of the mesh. For best results, pair a
39922
+ * displacement map with a matching normal map, since the renderer can
39923
+ * not recompute surface normals from the displaced vertices.
39924
+ *
39925
+ * `displacementMap` represents non-color data. Any texture assigned must have
39926
+ * `texture.colorSpace = NoColorSpace` (default).
39927
+ *
39928
+ * @type {?Texture}
39929
+ * @default null
39930
+ */
39931
+ this.displacementMap = null;
39932
+
39933
+ /**
39934
+ * How much the displacement map affects the mesh (where black is no
39935
+ * displacement, and white is maximum displacement). Without a displacement
39936
+ * map set, this value is not applied.
39937
+ *
39938
+ * @type {number}
39939
+ * @default 0
39940
+ */
39941
+ this.displacementScale = 1;
39942
+
39943
+ /**
39944
+ * The offset of the displacement map's values on the mesh's vertices.
39945
+ * The bias is added to the scaled sample of the displacement map.
39946
+ * Without a displacement map set, this value is not applied.
39947
+ *
39948
+ * @type {number}
39949
+ * @default 0
39950
+ */
39951
+ this.displacementBias = 0;
39952
+
39953
+ /**
39954
+ * The alpha map is a grayscale texture that controls the opacity across the
39955
+ * surface (black: fully transparent; white: fully opaque).
39956
+ *
39957
+ * Only the color of the texture is used, ignoring the alpha channel if one
39958
+ * exists. For RGB and RGBA textures, the renderer will use the green channel
39959
+ * when sampling this texture due to the extra bit of precision provided for
39960
+ * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
39961
+ * luminance/alpha textures will also still work as expected.
39962
+ *
39963
+ * `alphaMap` represents non-color data. Any texture assigned must have
39964
+ * `texture.colorSpace = NoColorSpace` (default).
39965
+ *
39966
+ * @type {?Texture}
39967
+ * @default null
39968
+ */
39969
+ this.alphaMap = null;
39970
+
39971
+ /**
39972
+ * Renders the geometry as a wireframe.
39973
+ *
39974
+ * @type {boolean}
39975
+ * @default false
39976
+ */
39977
+ this.wireframe = false;
39978
+
39979
+ /**
39980
+ * Controls the thickness of the wireframe.
39981
+ *
39982
+ * Can only be used with {@link SVGRenderer}.
39983
+ *
39984
+ * @type {number}
39985
+ * @default 1
39986
+ */
39987
+ this.wireframeLinewidth = 1;
39988
+
39989
+ /**
39990
+ * Defines appearance of wireframe ends.
39991
+ *
39992
+ * Can only be used with {@link SVGRenderer}.
39993
+ *
39994
+ * @type {('round'|'bevel'|'miter')}
39995
+ * @default 'round'
39996
+ */
39997
+ this.wireframeLinecap = 'round';
39998
+
39999
+ /**
40000
+ * Defines appearance of wireframe joints.
40001
+ *
40002
+ * Can only be used with {@link SVGRenderer}.
40003
+ *
40004
+ * @type {('round'|'bevel'|'miter')}
40005
+ * @default 'round'
40006
+ */
40007
+ this.wireframeLinejoin = 'round';
40008
+
40009
+ /**
40010
+ * Whether the material is affected by fog or not.
40011
+ *
40012
+ * @type {boolean}
40013
+ * @default true
40014
+ */
40015
+ this.fog = true;
40016
+
40017
+ this.setValues( parameters );
40018
+
40019
+ }
40020
+
40021
+ copy( source ) {
40022
+
40023
+ super.copy( source );
40024
+
40025
+ this.color.copy( source.color );
40026
+
40027
+ this.map = source.map;
40028
+ this.gradientMap = source.gradientMap;
40029
+
40030
+ this.lightMap = source.lightMap;
40031
+ this.lightMapIntensity = source.lightMapIntensity;
40032
+
40033
+ this.aoMap = source.aoMap;
40034
+ this.aoMapIntensity = source.aoMapIntensity;
40035
+
40036
+ this.emissive.copy( source.emissive );
40037
+ this.emissiveMap = source.emissiveMap;
40038
+ this.emissiveIntensity = source.emissiveIntensity;
40039
+
40040
+ this.bumpMap = source.bumpMap;
40041
+ this.bumpScale = source.bumpScale;
40042
+
40043
+ this.normalMap = source.normalMap;
40044
+ this.normalMapType = source.normalMapType;
40045
+ this.normalScale.copy( source.normalScale );
40046
+
40047
+ this.displacementMap = source.displacementMap;
40048
+ this.displacementScale = source.displacementScale;
40049
+ this.displacementBias = source.displacementBias;
40050
+
40051
+ this.alphaMap = source.alphaMap;
40052
+
40053
+ this.wireframe = source.wireframe;
40054
+ this.wireframeLinewidth = source.wireframeLinewidth;
40055
+ this.wireframeLinecap = source.wireframeLinecap;
40056
+ this.wireframeLinejoin = source.wireframeLinejoin;
40057
+
40058
+ this.fog = source.fog;
40059
+
40060
+ return this;
40061
+
40062
+ }
40063
+
40064
+ }
40065
+
40066
+ /**
40067
+ * A material that maps the normal vectors to RGB colors.
40068
+ *
40069
+ * @augments Material
40070
+ * @demo scenes/material-browser.html#MeshNormalMaterial
40071
+ */
40072
+ class MeshNormalMaterial extends Material {
40073
+
40074
+ /**
40075
+ * Constructs a new mesh normal material.
40076
+ *
40077
+ * @param {Object} [parameters] - An object with one or more properties
40078
+ * defining the material's appearance. Any property of the material
40079
+ * (including any property from inherited materials) can be passed
40080
+ * in here. Color values can be passed any type of value accepted
40081
+ * by {@link Color#set}.
40082
+ */
40083
+ constructor( parameters ) {
40084
+
40085
+ super();
40086
+
40087
+ /**
40088
+ * This flag can be used for type testing.
40089
+ *
40090
+ * @type {boolean}
40091
+ * @readonly
40092
+ * @default true
40093
+ */
40094
+ this.isMeshNormalMaterial = true;
40095
+
40096
+ this.type = 'MeshNormalMaterial';
40097
+
40098
+ /**
40099
+ * The texture to create a bump map. The black and white values map to the
40100
+ * perceived depth in relation to the lights. Bump doesn't actually affect
40101
+ * the geometry of the object, only the lighting. If a normal map is defined
40102
+ * this will be ignored.
40103
+ *
40104
+ * `bumpMap` represents non-color data. Any texture assigned must have
40105
+ * `texture.colorSpace = NoColorSpace` (default).
40106
+ *
40107
+ * @type {?Texture}
40108
+ * @default null
40109
+ */
40110
+ this.bumpMap = null;
40111
+
40112
+ /**
40113
+ * How much the bump map affects the material. Typical range is `[0,1]`.
40114
+ *
40115
+ * @type {number}
40116
+ * @default 1
40117
+ */
40118
+ this.bumpScale = 1;
40119
+
40120
+ /**
40121
+ * The texture to create a normal map. The RGB values affect the surface
40122
+ * normal for each pixel fragment and change the way the color is lit. Normal
40123
+ * maps do not change the actual shape of the surface, only the lighting. In
40124
+ * case the material has a normal map authored using the left handed
40125
+ * convention, the `y` component of `normalScale` should be negated to compensate
40126
+ * for the different handedness.
40127
+ *
40128
+ * `normalMap` represents non-color data. Any texture assigned must have
40129
+ * `texture.colorSpace = NoColorSpace` (default).
40130
+ *
40131
+ * @type {?Texture}
40132
+ * @default null
40133
+ */
40134
+ this.normalMap = null;
40135
+
40136
+ /**
40137
+ * The type of normal map.
40138
+ *
40139
+ * @type {(TangentSpaceNormalMap|ObjectSpaceNormalMap)}
40140
+ * @default TangentSpaceNormalMap
40141
+ */
40142
+ this.normalMapType = TangentSpaceNormalMap;
40143
+
40144
+ /**
40145
+ * How much the normal map affects the material. Typical value range is `[0,1]`.
40146
+ *
40147
+ * @type {Vector2}
40148
+ * @default (1,1)
40149
+ */
40150
+ this.normalScale = new Vector2( 1, 1 );
40151
+
40152
+ /**
40153
+ * The displacement map affects the position of the mesh's vertices. Unlike
40154
+ * other maps which only affect the light and shade of the material the
40155
+ * displaced vertices can cast shadows, block other objects, and otherwise
40156
+ * act as real geometry. The displacement texture is an image where the value
40157
+ * of each pixel (white being the highest) is mapped against, and
40158
+ * repositions, the vertices of the mesh. For best results, pair a
40159
+ * displacement map with a matching normal map, since the renderer can
40160
+ * not recompute surface normals from the displaced vertices.
39642
40161
  *
39643
40162
  * @type {?Texture}
39644
40163
  * @default null
@@ -39778,6 +40297,10 @@ class MeshLambertMaterial extends Material {
39778
40297
  * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map
39779
40298
  * color is modulated by the diffuse `color`.
39780
40299
  *
40300
+ * `map` represents color data, and the texture must be assigned a
40301
+ * {@link Texture#colorSpace}. Most `map` textures set
40302
+ * `texture.colorSpace = SRGBColorSpace`.
40303
+ *
39781
40304
  * @type {?Texture}
39782
40305
  * @default null
39783
40306
  */
@@ -39786,6 +40309,11 @@ class MeshLambertMaterial extends Material {
39786
40309
  /**
39787
40310
  * The light map. Requires a second set of UVs.
39788
40311
  *
40312
+ * `lightMap` represents pre-baked illuminance data, and the texture must be assigned
40313
+ * a {@link Texture#colorSpace}. Most `lightMap` textures set
40314
+ * `texture.colorSpace = LinearSRGBColorSpace` and use float-type formats
40315
+ * such as `.exr` or `.hdr`.
40316
+ *
39789
40317
  * @type {?Texture}
39790
40318
  * @default null
39791
40319
  */
@@ -39803,6 +40331,9 @@ class MeshLambertMaterial extends Material {
39803
40331
  * The red channel of this texture is used as the ambient occlusion map.
39804
40332
  * Requires a second set of UVs.
39805
40333
  *
40334
+ * `aoMap` represents non-color data. Any texture assigned must have
40335
+ * `texture.colorSpace = NoColorSpace` (default).
40336
+ *
39806
40337
  * @type {?Texture}
39807
40338
  * @default null
39808
40339
  */
@@ -39840,6 +40371,10 @@ class MeshLambertMaterial extends Material {
39840
40371
  * emissive color and the emissive intensity. If you have an emissive map,
39841
40372
  * be sure to set the emissive color to something other than black.
39842
40373
  *
40374
+ * `emissiveMap` represents color data, and the texture must be assigned a
40375
+ * {@link Texture#colorSpace}. Most `emissiveMap` textures set
40376
+ * `texture.colorSpace = SRGBColorSpace`.
40377
+ *
39843
40378
  * @type {?Texture}
39844
40379
  * @default null
39845
40380
  */
@@ -39851,6 +40386,9 @@ class MeshLambertMaterial extends Material {
39851
40386
  * the geometry of the object, only the lighting. If a normal map is defined
39852
40387
  * this will be ignored.
39853
40388
  *
40389
+ * `bumpMap` represents non-color data. Any texture assigned must have
40390
+ * `texture.colorSpace = NoColorSpace` (default).
40391
+ *
39854
40392
  * @type {?Texture}
39855
40393
  * @default null
39856
40394
  */
@@ -39872,6 +40410,9 @@ class MeshLambertMaterial extends Material {
39872
40410
  * convention, the `y` component of `normalScale` should be negated to compensate
39873
40411
  * for the different handedness.
39874
40412
  *
40413
+ * `normalMap` represents non-color data. Any texture assigned must have
40414
+ * `texture.colorSpace = NoColorSpace` (default).
40415
+ *
39875
40416
  * @type {?Texture}
39876
40417
  * @default null
39877
40418
  */
@@ -39899,7 +40440,12 @@ class MeshLambertMaterial extends Material {
39899
40440
  * displaced vertices can cast shadows, block other objects, and otherwise
39900
40441
  * act as real geometry. The displacement texture is an image where the value
39901
40442
  * of each pixel (white being the highest) is mapped against, and
39902
- * repositions, the vertices of the mesh.
40443
+ * repositions, the vertices of the mesh. For best results, pair a
40444
+ * displacement map with a matching normal map, since the renderer can
40445
+ * not recompute surface normals from the displaced vertices.
40446
+ *
40447
+ * `displacementMap` represents non-color data. Any texture assigned must have
40448
+ * `texture.colorSpace = NoColorSpace` (default).
39903
40449
  *
39904
40450
  * @type {?Texture}
39905
40451
  * @default null
@@ -39929,6 +40475,10 @@ class MeshLambertMaterial extends Material {
39929
40475
  /**
39930
40476
  * Specular map used by the material.
39931
40477
  *
40478
+ * `specularMap` represents color data, and the texture must be assigned a
40479
+ * {@link Texture#colorSpace}. Most `specularMap` textures set
40480
+ * `texture.colorSpace = SRGBColorSpace`.
40481
+ *
39932
40482
  * @type {?Texture}
39933
40483
  * @default null
39934
40484
  */
@@ -39944,6 +40494,9 @@ class MeshLambertMaterial extends Material {
39944
40494
  * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
39945
40495
  * luminance/alpha textures will also still work as expected.
39946
40496
  *
40497
+ * `alphaMap` represents non-color data. Any texture assigned must have
40498
+ * `texture.colorSpace = NoColorSpace` (default).
40499
+ *
39947
40500
  * @type {?Texture}
39948
40501
  * @default null
39949
40502
  */
@@ -39952,6 +40505,11 @@ class MeshLambertMaterial extends Material {
39952
40505
  /**
39953
40506
  * The environment map.
39954
40507
  *
40508
+ * `envMap` represents luminance data, and the texture must be assigned
40509
+ * a {@link Texture#colorSpace}. Most `envMap` textures set
40510
+ * `texture.colorSpace = LinearSRGBColorSpace` and use float-type formats
40511
+ * such as `.exr` or `.hdr`.
40512
+ *
39955
40513
  * @type {?Texture}
39956
40514
  * @default null
39957
40515
  */
@@ -40162,6 +40720,10 @@ class MeshDepthMaterial extends Material {
40162
40720
  * The color map. May optionally include an alpha channel, typically combined
40163
40721
  * with {@link Material#transparent} or {@link Material#alphaTest}.
40164
40722
  *
40723
+ * `map` represents color data, and the texture must be assigned a
40724
+ * {@link Texture#colorSpace}. Most `map` textures set
40725
+ * `texture.colorSpace = SRGBColorSpace`.
40726
+ *
40165
40727
  * @type {?Texture}
40166
40728
  * @default null
40167
40729
  */
@@ -40177,6 +40739,9 @@ class MeshDepthMaterial extends Material {
40177
40739
  * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
40178
40740
  * luminance/alpha textures will also still work as expected.
40179
40741
  *
40742
+ * `alphaMap` represents non-color data. Any texture assigned must have
40743
+ * `texture.colorSpace = NoColorSpace` (default).
40744
+ *
40180
40745
  * @type {?Texture}
40181
40746
  * @default null
40182
40747
  */
@@ -40190,6 +40755,9 @@ class MeshDepthMaterial extends Material {
40190
40755
  * of each pixel (white being the highest) is mapped against, and
40191
40756
  * repositions, the vertices of the mesh.
40192
40757
  *
40758
+ * `displacementMap` represents non-color data. Any texture assigned must have
40759
+ * `texture.colorSpace = NoColorSpace` (default).
40760
+ *
40193
40761
  * @type {?Texture}
40194
40762
  * @default null
40195
40763
  */
@@ -40302,6 +40870,10 @@ class MeshDistanceMaterial extends Material {
40302
40870
  * The color map. May optionally include an alpha channel, typically combined
40303
40871
  * with {@link Material#transparent} or {@link Material#alphaTest}.
40304
40872
  *
40873
+ * `map` represents color data, and the texture must be assigned a
40874
+ * {@link Texture#colorSpace}. Most `map` textures set
40875
+ * `texture.colorSpace = SRGBColorSpace`.
40876
+ *
40305
40877
  * @type {?Texture}
40306
40878
  * @default null
40307
40879
  */
@@ -40317,6 +40889,9 @@ class MeshDistanceMaterial extends Material {
40317
40889
  * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
40318
40890
  * luminance/alpha textures will also still work as expected.
40319
40891
  *
40892
+ * `alphaMap` represents non-color data. Any texture assigned must have
40893
+ * `texture.colorSpace = NoColorSpace` (default).
40894
+ *
40320
40895
  * @type {?Texture}
40321
40896
  * @default null
40322
40897
  */
@@ -40330,6 +40905,9 @@ class MeshDistanceMaterial extends Material {
40330
40905
  * of each pixel (white being the highest) is mapped against, and
40331
40906
  * repositions, the vertices of the mesh.
40332
40907
  *
40908
+ * `displacementMap` represents non-color data. Any texture assigned must have
40909
+ * `texture.colorSpace = NoColorSpace` (default).
40910
+ *
40333
40911
  * @type {?Texture}
40334
40912
  * @default null
40335
40913
  */
@@ -40428,6 +41006,12 @@ class MeshMatcapMaterial extends Material {
40428
41006
  /**
40429
41007
  * The matcap map.
40430
41008
  *
41009
+ * `matcap` represents luminance data, and the texture must be assigned
41010
+ * a {@link Texture#colorSpace}. HDR `matcap` textures (e.g. `.exr`)
41011
+ * typically set `texture.colorSpace = LinearSRGBColorSpace`, while LDR
41012
+ * `matcap` textures (e.g. `.png`, `.jpg`, `.webp`) typically set
41013
+ * `texture.colorSpace = SRGBColorSpace`.
41014
+ *
40431
41015
  * @type {?Texture}
40432
41016
  * @default null
40433
41017
  */
@@ -40438,6 +41022,10 @@ class MeshMatcapMaterial extends Material {
40438
41022
  * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map
40439
41023
  * color is modulated by the diffuse `color`.
40440
41024
  *
41025
+ * `map` represents color data, and the texture must be assigned a
41026
+ * {@link Texture#colorSpace}. Most `map` textures set
41027
+ * `texture.colorSpace = SRGBColorSpace`.
41028
+ *
40441
41029
  * @type {?Texture}
40442
41030
  * @default null
40443
41031
  */
@@ -40449,6 +41037,9 @@ class MeshMatcapMaterial extends Material {
40449
41037
  * the geometry of the object, only the lighting. If a normal map is defined
40450
41038
  * this will be ignored.
40451
41039
  *
41040
+ * `bumpMap` represents non-color data. Any texture assigned must have
41041
+ * `texture.colorSpace = NoColorSpace` (default).
41042
+ *
40452
41043
  * @type {?Texture}
40453
41044
  * @default null
40454
41045
  */
@@ -40470,6 +41061,9 @@ class MeshMatcapMaterial extends Material {
40470
41061
  * convention, the `y` component of `normalScale` should be negated to compensate
40471
41062
  * for the different handedness.
40472
41063
  *
41064
+ * `normalMap` represents non-color data. Any texture assigned must have
41065
+ * `texture.colorSpace = NoColorSpace` (default).
41066
+ *
40473
41067
  * @type {?Texture}
40474
41068
  * @default null
40475
41069
  */
@@ -40497,7 +41091,12 @@ class MeshMatcapMaterial extends Material {
40497
41091
  * displaced vertices can cast shadows, block other objects, and otherwise
40498
41092
  * act as real geometry. The displacement texture is an image where the value
40499
41093
  * of each pixel (white being the highest) is mapped against, and
40500
- * repositions, the vertices of the mesh.
41094
+ * repositions, the vertices of the mesh. For best results, pair a
41095
+ * displacement map with a matching normal map, since the renderer can
41096
+ * not recompute surface normals from the displaced vertices.
41097
+ *
41098
+ * `displacementMap` represents non-color data. Any texture assigned must have
41099
+ * `texture.colorSpace = NoColorSpace` (default).
40501
41100
  *
40502
41101
  * @type {?Texture}
40503
41102
  * @default null
@@ -40534,6 +41133,9 @@ class MeshMatcapMaterial extends Material {
40534
41133
  * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
40535
41134
  * luminance/alpha textures will also still work as expected.
40536
41135
  *
41136
+ * `alphaMap` represents non-color data. Any texture assigned must have
41137
+ * `texture.colorSpace = NoColorSpace` (default).
41138
+ *
40537
41139
  * @type {?Texture}
40538
41140
  * @default null
40539
41141
  */
@@ -41479,7 +42081,7 @@ class Interpolant {
41479
42081
  */
41480
42082
  interpolate_( /* i1, t0, t, t1 */ ) {
41481
42083
 
41482
- throw new Error( 'call to abstract method' );
42084
+ throw new Error( 'THREE.Interpolant: Call to abstract method.' );
41483
42085
  // implementations shall return this.resultBuffer
41484
42086
 
41485
42087
  }
@@ -41738,9 +42340,8 @@ class DiscreteInterpolant extends Interpolant {
41738
42340
  * each keyframe has explicit in/out tangent control points specified as
41739
42341
  * 2D coordinates (time, value).
41740
42342
  *
41741
- * The tangent data must be provided via the `settings` object:
41742
- * - `settings.inTangents`: Float32Array with [time, value] pairs per keyframe per component
41743
- * - `settings.outTangents`: Float32Array with [time, value] pairs per keyframe per component
42343
+ * Tangent data is read from `inTangents` and `outTangents` on the interpolant
42344
+ * (populated by `KeyframeTrack.InterpolantFactoryMethodBezier`).
41744
42345
  *
41745
42346
  * For a track with N keyframes and stride S:
41746
42347
  * - Each tangent array has N * S * 2 values
@@ -41760,9 +42361,8 @@ class BezierInterpolant extends Interpolant {
41760
42361
  const offset1 = i1 * stride;
41761
42362
  const offset0 = offset1 - stride;
41762
42363
 
41763
- const settings = this.settings || this.DefaultSettings_;
41764
- const inTangents = settings.inTangents;
41765
- const outTangents = settings.outTangents;
42364
+ const inTangents = this.inTangents;
42365
+ const outTangents = this.outTangents;
41766
42366
 
41767
42367
  // If no tangent data, fall back to linear interpolation
41768
42368
  if ( ! inTangents || ! outTangents ) {
@@ -41983,10 +42583,10 @@ class KeyframeTrack {
41983
42583
 
41984
42584
  const interpolant = new BezierInterpolant( this.times, this.values, this.getValueSize(), result );
41985
42585
 
41986
- // Pass tangent data from track settings to interpolant
41987
42586
  if ( this.settings ) {
41988
42587
 
41989
- interpolant.settings = this.settings;
42588
+ interpolant.inTangents = this.settings.inTangents;
42589
+ interpolant.outTangents = this.settings.outTangents;
41990
42590
 
41991
42591
  }
41992
42592
 
@@ -43028,144 +43628,6 @@ class AnimationClip {
43028
43628
 
43029
43629
  }
43030
43630
 
43031
- /**
43032
- * Parses the `animation.hierarchy` format and returns a new animation clip.
43033
- *
43034
- * @static
43035
- * @deprecated since r175.
43036
- * @param {Object} animation - A serialized animation clip as JSON.
43037
- * @param {Array<Bone>} bones - An array of bones.
43038
- * @return {?AnimationClip} The new animation clip.
43039
- */
43040
- static parseAnimation( animation, bones ) {
43041
-
43042
- warn( 'AnimationClip: parseAnimation() is deprecated and will be removed with r185' );
43043
-
43044
- if ( ! animation ) {
43045
-
43046
- error( 'AnimationClip: No animation in JSONLoader data.' );
43047
- return null;
43048
-
43049
- }
43050
-
43051
- const addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) {
43052
-
43053
- // only return track if there are actually keys.
43054
- if ( animationKeys.length !== 0 ) {
43055
-
43056
- const times = [];
43057
- const values = [];
43058
-
43059
- flattenJSON( animationKeys, times, values, propertyName );
43060
-
43061
- // empty keys are filtered out, so check again
43062
- if ( times.length !== 0 ) {
43063
-
43064
- destTracks.push( new trackType( trackName, times, values ) );
43065
-
43066
- }
43067
-
43068
- }
43069
-
43070
- };
43071
-
43072
- const tracks = [];
43073
-
43074
- const clipName = animation.name || 'default';
43075
- const fps = animation.fps || 30;
43076
- const blendMode = animation.blendMode;
43077
-
43078
- // automatic length determination in AnimationClip.
43079
- let duration = animation.length || -1;
43080
-
43081
- const hierarchyTracks = animation.hierarchy || [];
43082
-
43083
- for ( let h = 0; h < hierarchyTracks.length; h ++ ) {
43084
-
43085
- const animationKeys = hierarchyTracks[ h ].keys;
43086
-
43087
- // skip empty tracks
43088
- if ( ! animationKeys || animationKeys.length === 0 ) continue;
43089
-
43090
- // process morph targets
43091
- if ( animationKeys[ 0 ].morphTargets ) {
43092
-
43093
- // figure out all morph targets used in this track
43094
- const morphTargetNames = {};
43095
-
43096
- let k;
43097
-
43098
- for ( k = 0; k < animationKeys.length; k ++ ) {
43099
-
43100
- if ( animationKeys[ k ].morphTargets ) {
43101
-
43102
- for ( let m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) {
43103
-
43104
- morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = -1;
43105
-
43106
- }
43107
-
43108
- }
43109
-
43110
- }
43111
-
43112
- // create a track for each morph target with all zero
43113
- // morphTargetInfluences except for the keys in which
43114
- // the morphTarget is named.
43115
- for ( const morphTargetName in morphTargetNames ) {
43116
-
43117
- const times = [];
43118
- const values = [];
43119
-
43120
- for ( let m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) {
43121
-
43122
- const animationKey = animationKeys[ k ];
43123
-
43124
- times.push( animationKey.time );
43125
- values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );
43126
-
43127
- }
43128
-
43129
- tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) );
43130
-
43131
- }
43132
-
43133
- duration = morphTargetNames.length * fps;
43134
-
43135
- } else {
43136
-
43137
- // ...assume skeletal animation
43138
-
43139
- const boneName = '.bones[' + bones[ h ].name + ']';
43140
-
43141
- addNonemptyTrack(
43142
- VectorKeyframeTrack, boneName + '.position',
43143
- animationKeys, 'pos', tracks );
43144
-
43145
- addNonemptyTrack(
43146
- QuaternionKeyframeTrack, boneName + '.quaternion',
43147
- animationKeys, 'rot', tracks );
43148
-
43149
- addNonemptyTrack(
43150
- VectorKeyframeTrack, boneName + '.scale',
43151
- animationKeys, 'scl', tracks );
43152
-
43153
- }
43154
-
43155
- }
43156
-
43157
- if ( tracks.length === 0 ) {
43158
-
43159
- return null;
43160
-
43161
- }
43162
-
43163
- const clip = new this( clipName, duration, tracks, blendMode );
43164
-
43165
- return clip;
43166
-
43167
- }
43168
-
43169
43631
  /**
43170
43632
  * Sets the duration of this clip to the duration of its longest keyframe track.
43171
43633
  *
@@ -43630,6 +44092,11 @@ class LoadingManager {
43630
44092
  */
43631
44093
  this.resolveURL = function ( url ) {
43632
44094
 
44095
+ // Normalize to NFC so that Unicode URIs (e.g. from glTF)
44096
+ // are percent-encoded correctly per RFC 3987.
44097
+
44098
+ url = url.normalize( 'NFC' );
44099
+
43633
44100
  if ( urlModifier ) {
43634
44101
 
43635
44102
  return urlModifier( url );
@@ -44947,77 +45414,108 @@ class DataTextureLoader extends Loader {
44947
45414
 
44948
45415
  }
44949
45416
 
44950
- if ( texData.image !== undefined ) {
45417
+ scope._applyTexData( texture, texData );
44951
45418
 
44952
- texture.image = texData.image;
45419
+ if ( onLoad ) onLoad( texture, texData );
44953
45420
 
44954
- } else if ( texData.data !== undefined ) {
45421
+ }, onProgress, onError );
44955
45422
 
44956
- texture.image.width = texData.width;
44957
- texture.image.height = texData.height;
44958
- texture.image.data = texData.data;
44959
45423
 
44960
- }
45424
+ return texture;
44961
45425
 
44962
- texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping;
44963
- texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping;
45426
+ }
44964
45427
 
44965
- texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter;
44966
- texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter;
45428
+ /**
45429
+ * Parses the given buffer and returns a configured data texture. Use this method
45430
+ * for parsing texture data that is already in memory (e.g. drag and drop or data
45431
+ * loaded from a server) without going through {@link DataTextureLoader#load}.
45432
+ *
45433
+ * @param {ArrayBuffer} buffer - The raw texture data.
45434
+ * @return {DataTexture} The data texture.
45435
+ */
45436
+ createDataTexture( buffer ) {
44967
45437
 
44968
- texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;
45438
+ const texture = new DataTexture();
44969
45439
 
44970
- if ( texData.colorSpace !== undefined ) {
45440
+ this._applyTexData( texture, this.parse( buffer ) );
44971
45441
 
44972
- texture.colorSpace = texData.colorSpace;
45442
+ return texture;
44973
45443
 
44974
- }
45444
+ }
44975
45445
 
44976
- if ( texData.flipY !== undefined ) {
45446
+ /**
45447
+ * Applies the given parsed texture data to the given data texture.
45448
+ *
45449
+ * @private
45450
+ * @param {DataTexture} texture - The data texture.
45451
+ * @param {DataTextureLoader~TexData} texData - The parsed texture data.
45452
+ */
45453
+ _applyTexData( texture, texData ) {
44977
45454
 
44978
- texture.flipY = texData.flipY;
45455
+ if ( texData.image !== undefined ) {
44979
45456
 
44980
- }
45457
+ texture.image = texData.image;
44981
45458
 
44982
- if ( texData.format !== undefined ) {
45459
+ } else if ( texData.data !== undefined ) {
44983
45460
 
44984
- texture.format = texData.format;
45461
+ texture.image.width = texData.width;
45462
+ texture.image.height = texData.height;
45463
+ texture.image.data = texData.data;
44985
45464
 
44986
- }
45465
+ }
44987
45466
 
44988
- if ( texData.type !== undefined ) {
45467
+ texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping;
45468
+ texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping;
44989
45469
 
44990
- texture.type = texData.type;
45470
+ texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter;
45471
+ texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter;
44991
45472
 
44992
- }
45473
+ texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;
44993
45474
 
44994
- if ( texData.mipmaps !== undefined ) {
45475
+ if ( texData.colorSpace !== undefined ) {
44995
45476
 
44996
- texture.mipmaps = texData.mipmaps;
44997
- texture.minFilter = LinearMipmapLinearFilter; // presumably...
45477
+ texture.colorSpace = texData.colorSpace;
44998
45478
 
44999
- }
45479
+ }
45000
45480
 
45001
- if ( texData.mipmapCount === 1 ) {
45481
+ if ( texData.flipY !== undefined ) {
45002
45482
 
45003
- texture.minFilter = LinearFilter;
45483
+ texture.flipY = texData.flipY;
45004
45484
 
45005
- }
45485
+ }
45006
45486
 
45007
- if ( texData.generateMipmaps !== undefined ) {
45487
+ if ( texData.format !== undefined ) {
45008
45488
 
45009
- texture.generateMipmaps = texData.generateMipmaps;
45489
+ texture.format = texData.format;
45010
45490
 
45011
- }
45491
+ }
45012
45492
 
45013
- texture.needsUpdate = true;
45493
+ if ( texData.type !== undefined ) {
45014
45494
 
45015
- if ( onLoad ) onLoad( texture, texData );
45495
+ texture.type = texData.type;
45016
45496
 
45017
- }, onProgress, onError );
45497
+ }
45018
45498
 
45499
+ if ( texData.mipmaps !== undefined ) {
45019
45500
 
45020
- return texture;
45501
+ texture.mipmaps = texData.mipmaps;
45502
+ texture.minFilter = LinearMipmapLinearFilter; // presumably...
45503
+
45504
+ }
45505
+
45506
+ if ( texData.mipmapCount === 1 ) {
45507
+
45508
+ texture.minFilter = LinearFilter;
45509
+
45510
+ }
45511
+
45512
+ if ( texData.generateMipmaps !== undefined ) {
45513
+
45514
+ texture.generateMipmaps = texData.generateMipmaps;
45515
+
45516
+ }
45517
+
45518
+ texture.needsUpdate = true;
45021
45519
 
45022
45520
  }
45023
45521
 
@@ -45707,9 +46205,9 @@ class Camera extends Object3D {
45707
46205
 
45708
46206
  }
45709
46207
 
45710
- updateWorldMatrix( updateParents, updateChildren ) {
46208
+ updateWorldMatrix( updateParents, updateChildren, force = false ) {
45711
46209
 
45712
- super.updateWorldMatrix( updateParents, updateChildren );
46210
+ super.updateWorldMatrix( updateParents, updateChildren, force );
45713
46211
 
45714
46212
  // exclude scale from view matrix to be glTF conform
45715
46213
 
@@ -47491,6 +47989,8 @@ class LightProbe extends Light {
47491
47989
 
47492
47990
  }
47493
47991
 
47992
+ const _customMaterials = {};
47993
+
47494
47994
  /**
47495
47995
  * Class for loading materials. The files are internally
47496
47996
  * loaded via {@link FileLoader}.
@@ -47573,265 +48073,9 @@ class MaterialLoader extends Loader {
47573
48073
  */
47574
48074
  parse( json ) {
47575
48075
 
47576
- const textures = this.textures;
47577
-
47578
- function getTexture( name ) {
47579
-
47580
- if ( textures[ name ] === undefined ) {
47581
-
47582
- warn( 'MaterialLoader: Undefined texture', name );
47583
-
47584
- }
47585
-
47586
- return textures[ name ];
47587
-
47588
- }
47589
-
47590
48076
  const material = this.createMaterialFromType( json.type );
47591
48077
 
47592
- if ( json.uuid !== undefined ) material.uuid = json.uuid;
47593
- if ( json.name !== undefined ) material.name = json.name;
47594
- if ( json.color !== undefined && material.color !== undefined ) material.color.setHex( json.color );
47595
- if ( json.roughness !== undefined ) material.roughness = json.roughness;
47596
- if ( json.metalness !== undefined ) material.metalness = json.metalness;
47597
- if ( json.sheen !== undefined ) material.sheen = json.sheen;
47598
- if ( json.sheenColor !== undefined ) material.sheenColor = new Color().setHex( json.sheenColor );
47599
- if ( json.sheenRoughness !== undefined ) material.sheenRoughness = json.sheenRoughness;
47600
- if ( json.emissive !== undefined && material.emissive !== undefined ) material.emissive.setHex( json.emissive );
47601
- if ( json.specular !== undefined && material.specular !== undefined ) material.specular.setHex( json.specular );
47602
- if ( json.specularIntensity !== undefined ) material.specularIntensity = json.specularIntensity;
47603
- if ( json.specularColor !== undefined && material.specularColor !== undefined ) material.specularColor.setHex( json.specularColor );
47604
- if ( json.shininess !== undefined ) material.shininess = json.shininess;
47605
- if ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat;
47606
- if ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness;
47607
- if ( json.dispersion !== undefined ) material.dispersion = json.dispersion;
47608
- if ( json.iridescence !== undefined ) material.iridescence = json.iridescence;
47609
- if ( json.iridescenceIOR !== undefined ) material.iridescenceIOR = json.iridescenceIOR;
47610
- if ( json.iridescenceThicknessRange !== undefined ) material.iridescenceThicknessRange = json.iridescenceThicknessRange;
47611
- if ( json.transmission !== undefined ) material.transmission = json.transmission;
47612
- if ( json.thickness !== undefined ) material.thickness = json.thickness;
47613
- if ( json.attenuationDistance !== undefined ) material.attenuationDistance = json.attenuationDistance;
47614
- if ( json.attenuationColor !== undefined && material.attenuationColor !== undefined ) material.attenuationColor.setHex( json.attenuationColor );
47615
- if ( json.anisotropy !== undefined ) material.anisotropy = json.anisotropy;
47616
- if ( json.anisotropyRotation !== undefined ) material.anisotropyRotation = json.anisotropyRotation;
47617
- if ( json.fog !== undefined ) material.fog = json.fog;
47618
- if ( json.flatShading !== undefined ) material.flatShading = json.flatShading;
47619
- if ( json.blending !== undefined ) material.blending = json.blending;
47620
- if ( json.combine !== undefined ) material.combine = json.combine;
47621
- if ( json.side !== undefined ) material.side = json.side;
47622
- if ( json.shadowSide !== undefined ) material.shadowSide = json.shadowSide;
47623
- if ( json.opacity !== undefined ) material.opacity = json.opacity;
47624
- if ( json.transparent !== undefined ) material.transparent = json.transparent;
47625
- if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
47626
- if ( json.alphaHash !== undefined ) material.alphaHash = json.alphaHash;
47627
- if ( json.depthFunc !== undefined ) material.depthFunc = json.depthFunc;
47628
- if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
47629
- if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
47630
- if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
47631
- if ( json.blendSrc !== undefined ) material.blendSrc = json.blendSrc;
47632
- if ( json.blendDst !== undefined ) material.blendDst = json.blendDst;
47633
- if ( json.blendEquation !== undefined ) material.blendEquation = json.blendEquation;
47634
- if ( json.blendSrcAlpha !== undefined ) material.blendSrcAlpha = json.blendSrcAlpha;
47635
- if ( json.blendDstAlpha !== undefined ) material.blendDstAlpha = json.blendDstAlpha;
47636
- if ( json.blendEquationAlpha !== undefined ) material.blendEquationAlpha = json.blendEquationAlpha;
47637
- if ( json.blendColor !== undefined && material.blendColor !== undefined ) material.blendColor.setHex( json.blendColor );
47638
- if ( json.blendAlpha !== undefined ) material.blendAlpha = json.blendAlpha;
47639
- if ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask;
47640
- if ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc;
47641
- if ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef;
47642
- if ( json.stencilFuncMask !== undefined ) material.stencilFuncMask = json.stencilFuncMask;
47643
- if ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail;
47644
- if ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail;
47645
- if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass;
47646
- if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite;
47647
-
47648
- if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
47649
- if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
47650
- if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;
47651
- if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;
47652
-
47653
- if ( json.rotation !== undefined ) material.rotation = json.rotation;
47654
-
47655
- if ( json.linewidth !== undefined ) material.linewidth = json.linewidth;
47656
- if ( json.dashSize !== undefined ) material.dashSize = json.dashSize;
47657
- if ( json.gapSize !== undefined ) material.gapSize = json.gapSize;
47658
- if ( json.scale !== undefined ) material.scale = json.scale;
47659
-
47660
- if ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset;
47661
- if ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor;
47662
- if ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits;
47663
-
47664
- if ( json.dithering !== undefined ) material.dithering = json.dithering;
47665
-
47666
- if ( json.alphaToCoverage !== undefined ) material.alphaToCoverage = json.alphaToCoverage;
47667
- if ( json.premultipliedAlpha !== undefined ) material.premultipliedAlpha = json.premultipliedAlpha;
47668
- if ( json.forceSinglePass !== undefined ) material.forceSinglePass = json.forceSinglePass;
47669
- if ( json.allowOverride !== undefined ) material.allowOverride = json.allowOverride;
47670
-
47671
- if ( json.visible !== undefined ) material.visible = json.visible;
47672
-
47673
- if ( json.toneMapped !== undefined ) material.toneMapped = json.toneMapped;
47674
-
47675
- if ( json.userData !== undefined ) material.userData = json.userData;
47676
-
47677
- if ( json.vertexColors !== undefined ) {
47678
-
47679
- if ( typeof json.vertexColors === 'number' ) {
47680
-
47681
- material.vertexColors = json.vertexColors > 0;
47682
-
47683
- } else {
47684
-
47685
- material.vertexColors = json.vertexColors;
47686
-
47687
- }
47688
-
47689
- }
47690
-
47691
- // Shader Material
47692
-
47693
- if ( json.uniforms !== undefined ) {
47694
-
47695
- for ( const name in json.uniforms ) {
47696
-
47697
- const uniform = json.uniforms[ name ];
47698
-
47699
- material.uniforms[ name ] = {};
47700
-
47701
- switch ( uniform.type ) {
47702
-
47703
- case 't':
47704
- material.uniforms[ name ].value = getTexture( uniform.value );
47705
- break;
47706
-
47707
- case 'c':
47708
- material.uniforms[ name ].value = new Color().setHex( uniform.value );
47709
- break;
47710
-
47711
- case 'v2':
47712
- material.uniforms[ name ].value = new Vector2().fromArray( uniform.value );
47713
- break;
47714
-
47715
- case 'v3':
47716
- material.uniforms[ name ].value = new Vector3().fromArray( uniform.value );
47717
- break;
47718
-
47719
- case 'v4':
47720
- material.uniforms[ name ].value = new Vector4().fromArray( uniform.value );
47721
- break;
47722
-
47723
- case 'm3':
47724
- material.uniforms[ name ].value = new Matrix3().fromArray( uniform.value );
47725
- break;
47726
-
47727
- case 'm4':
47728
- material.uniforms[ name ].value = new Matrix4().fromArray( uniform.value );
47729
- break;
47730
-
47731
- default:
47732
- material.uniforms[ name ].value = uniform.value;
47733
-
47734
- }
47735
-
47736
- }
47737
-
47738
- }
47739
-
47740
- if ( json.defines !== undefined ) material.defines = json.defines;
47741
- if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
47742
- if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
47743
- if ( json.glslVersion !== undefined ) material.glslVersion = json.glslVersion;
47744
-
47745
- if ( json.extensions !== undefined ) {
47746
-
47747
- for ( const key in json.extensions ) {
47748
-
47749
- material.extensions[ key ] = json.extensions[ key ];
47750
-
47751
- }
47752
-
47753
- }
47754
-
47755
- if ( json.lights !== undefined ) material.lights = json.lights;
47756
- if ( json.clipping !== undefined ) material.clipping = json.clipping;
47757
-
47758
- // for PointsMaterial
47759
-
47760
- if ( json.size !== undefined ) material.size = json.size;
47761
- if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;
47762
-
47763
- // maps
47764
-
47765
- if ( json.map !== undefined ) material.map = getTexture( json.map );
47766
- if ( json.matcap !== undefined ) material.matcap = getTexture( json.matcap );
47767
-
47768
- if ( json.alphaMap !== undefined ) material.alphaMap = getTexture( json.alphaMap );
47769
-
47770
- if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );
47771
- if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;
47772
-
47773
- if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );
47774
- if ( json.normalMapType !== undefined ) material.normalMapType = json.normalMapType;
47775
- if ( json.normalScale !== undefined ) {
47776
-
47777
- let normalScale = json.normalScale;
47778
-
47779
- if ( Array.isArray( normalScale ) === false ) {
47780
-
47781
- // Blender exporter used to export a scalar. See #7459
47782
-
47783
- normalScale = [ normalScale, normalScale ];
47784
-
47785
- }
47786
-
47787
- material.normalScale = new Vector2().fromArray( normalScale );
47788
-
47789
- }
47790
-
47791
- if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );
47792
- if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;
47793
- if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;
47794
-
47795
- if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );
47796
- if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );
47797
-
47798
- if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );
47799
- if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;
47800
-
47801
- if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );
47802
- if ( json.specularIntensityMap !== undefined ) material.specularIntensityMap = getTexture( json.specularIntensityMap );
47803
- if ( json.specularColorMap !== undefined ) material.specularColorMap = getTexture( json.specularColorMap );
47804
-
47805
- if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );
47806
- if ( json.envMapRotation !== undefined ) material.envMapRotation.fromArray( json.envMapRotation );
47807
- if ( json.envMapIntensity !== undefined ) material.envMapIntensity = json.envMapIntensity;
47808
-
47809
- if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;
47810
- if ( json.refractionRatio !== undefined ) material.refractionRatio = json.refractionRatio;
47811
-
47812
- if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );
47813
- if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;
47814
-
47815
- if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );
47816
- if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;
47817
-
47818
- if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );
47819
-
47820
- if ( json.clearcoatMap !== undefined ) material.clearcoatMap = getTexture( json.clearcoatMap );
47821
- if ( json.clearcoatRoughnessMap !== undefined ) material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap );
47822
- if ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap );
47823
- if ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale );
47824
-
47825
- if ( json.iridescenceMap !== undefined ) material.iridescenceMap = getTexture( json.iridescenceMap );
47826
- if ( json.iridescenceThicknessMap !== undefined ) material.iridescenceThicknessMap = getTexture( json.iridescenceThicknessMap );
47827
-
47828
- if ( json.transmissionMap !== undefined ) material.transmissionMap = getTexture( json.transmissionMap );
47829
- if ( json.thicknessMap !== undefined ) material.thicknessMap = getTexture( json.thicknessMap );
47830
-
47831
- if ( json.anisotropyMap !== undefined ) material.anisotropyMap = getTexture( json.anisotropyMap );
47832
-
47833
- if ( json.sheenColorMap !== undefined ) material.sheenColorMap = getTexture( json.sheenColorMap );
47834
- if ( json.sheenRoughnessMap !== undefined ) material.sheenRoughnessMap = getTexture( json.sheenRoughnessMap );
48078
+ material.fromJSON( json, this.textures );
47835
48079
 
47836
48080
  return material;
47837
48081
 
@@ -47890,10 +48134,40 @@ class MaterialLoader extends Loader {
47890
48134
  MeshMatcapMaterial,
47891
48135
  LineDashedMaterial,
47892
48136
  LineBasicMaterial,
47893
- Material
48137
+ Material,
48138
+ ... _customMaterials
47894
48139
  };
47895
48140
 
47896
- return new materialLib[ type ]();
48141
+ const MaterialType = materialLib[ type ];
48142
+
48143
+ let materialInstance;
48144
+
48145
+ if ( MaterialType === undefined ) {
48146
+
48147
+ warnOnce( `MaterialLoader: Unknown material type "${ type }". Use .registerMaterial() before starting the deserialization process.` );
48148
+ materialInstance = new Material();
48149
+
48150
+ } else {
48151
+
48152
+ materialInstance = new MaterialType();
48153
+
48154
+ }
48155
+
48156
+ return materialInstance;
48157
+
48158
+ }
48159
+
48160
+ /**
48161
+ * Registers the given material at the internal
48162
+ * material library.
48163
+ *
48164
+ * @static
48165
+ * @param {string} type - The material type.
48166
+ * @param {Material.constructor} materialClass - The material class.
48167
+ */
48168
+ static registerMaterial( type, materialClass ) {
48169
+
48170
+ _customMaterials[ type ] = materialClass;
47897
48171
 
47898
48172
  }
47899
48173
 
@@ -48359,7 +48633,7 @@ class ObjectLoader extends Loader {
48359
48633
 
48360
48634
  } catch ( e ) {
48361
48635
 
48362
- throw new Error( 'ObjectLoader: Can\'t parse ' + url + '. ' + e.message );
48636
+ throw new Error( 'THREE.ObjectLoader: Can\'t parse ' + url + '. ' + e.message );
48363
48637
 
48364
48638
  }
48365
48639
 
@@ -48638,6 +48912,8 @@ class ObjectLoader extends Loader {
48638
48912
 
48639
48913
  function loadImage( url ) {
48640
48914
 
48915
+ url = scope.manager.resolveURL( url );
48916
+
48641
48917
  scope.manager.itemStart( url );
48642
48918
 
48643
48919
  return loader.load( url, function () {
@@ -49975,8 +50251,11 @@ class StereoCamera {
49975
50251
 
49976
50252
  }
49977
50253
 
49978
- this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft );
49979
- this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight );
50254
+ this.cameraL.matrix.copy( camera.matrixWorld ).multiply( _eyeLeft );
50255
+ this.cameraL.matrixWorldNeedsUpdate = true;
50256
+
50257
+ this.cameraR.matrix.copy( camera.matrixWorld ).multiply( _eyeRight );
50258
+ this.cameraR.matrixWorldNeedsUpdate = true;
49980
50259
 
49981
50260
  }
49982
50261
 
@@ -52393,7 +52672,7 @@ class PropertyBinding {
52393
52672
 
52394
52673
  if ( matches === null ) {
52395
52674
 
52396
- throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
52675
+ throw new Error( 'THREE.PropertyBinding: Cannot parse trackName: ' + trackName );
52397
52676
 
52398
52677
  }
52399
52678
 
@@ -52427,7 +52706,7 @@ class PropertyBinding {
52427
52706
 
52428
52707
  if ( results.propertyName === null || results.propertyName.length === 0 ) {
52429
52708
 
52430
- throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
52709
+ throw new Error( 'THREE.PropertyBinding: can not parse propertyName from trackName: ' + trackName );
52431
52710
 
52432
52711
  }
52433
52712
 
@@ -53418,15 +53697,6 @@ class AnimationAction {
53418
53697
 
53419
53698
  const interpolant = tracks[ i ].createInterpolant( null );
53420
53699
  interpolants[ i ] = interpolant;
53421
-
53422
- // preserve interpolant settings (like tangent data from BezierInterpolant)
53423
-
53424
- if ( interpolant.settings ) {
53425
-
53426
- Object.assign( interpolantSettings, interpolant.settings );
53427
-
53428
- }
53429
-
53430
53700
  interpolant.settings = interpolantSettings;
53431
53701
 
53432
53702
  }
@@ -53442,6 +53712,7 @@ class AnimationAction {
53442
53712
  this._byClipCacheIndex = null; // for the memory manager
53443
53713
 
53444
53714
  this._timeScaleInterpolant = null;
53715
+ this._restoreTimeScale = null;
53445
53716
  this._weightInterpolant = null;
53446
53717
 
53447
53718
  /**
@@ -53729,6 +54000,10 @@ class AnimationAction {
53729
54000
  startEndRatio = fadeOutDuration / fadeInDuration,
53730
54001
  endStartRatio = fadeInDuration / fadeOutDuration;
53731
54002
 
54003
+
54004
+ fadeOutAction._restoreTimeScale = fadeOutAction.timeScale;
54005
+ this._restoreTimeScale = this.timeScale;
54006
+
53732
54007
  fadeOutAction.warp( 1.0, startEndRatio, duration );
53733
54008
  this.warp( endStartRatio, 1.0, duration );
53734
54009
 
@@ -53897,6 +54172,8 @@ class AnimationAction {
53897
54172
 
53898
54173
  }
53899
54174
 
54175
+ this._restoreTimeScale = null;
54176
+
53900
54177
  return this;
53901
54178
 
53902
54179
  }
@@ -54069,8 +54346,6 @@ class AnimationAction {
54069
54346
 
54070
54347
  if ( time > interpolant.parameterPositions[ 1 ] ) {
54071
54348
 
54072
- this.stopWarping();
54073
-
54074
54349
  if ( timeScale === 0 ) {
54075
54350
 
54076
54351
  // motion has halted, pause
@@ -54078,11 +54353,19 @@ class AnimationAction {
54078
54353
 
54079
54354
  } else {
54080
54355
 
54356
+ if ( this._restoreTimeScale !== null ) {
54357
+
54358
+ timeScale = this._restoreTimeScale;
54359
+
54360
+ }
54361
+
54081
54362
  // warp done - apply final time scale
54082
54363
  this.timeScale = timeScale;
54083
54364
 
54084
54365
  }
54085
54366
 
54367
+ this.stopWarping();
54368
+
54086
54369
  }
54087
54370
 
54088
54371
  }
@@ -55795,7 +56078,7 @@ class Raycaster {
55795
56078
 
55796
56079
  } else if ( camera.isOrthographicCamera ) {
55797
56080
 
55798
- this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
56081
+ this.ray.origin.set( coords.x, coords.y, camera.projectionMatrix.elements[ 14 ] ).unproject( camera ); // set origin in plane of camera
55799
56082
  this.ray.direction.set( 0, 0, -1 ).transformDirection( camera.matrixWorld );
55800
56083
  this.camera = camera;
55801
56084
 
@@ -57283,7 +57566,7 @@ class SpotLightHelper extends Object3D {
57283
57566
 
57284
57567
  }
57285
57568
 
57286
- this.matrixWorld.copy( this.light.matrixWorld );
57569
+ this.matrixWorldNeedsUpdate = true;
57287
57570
 
57288
57571
  const coneLength = this.light.distance ? this.light.distance : 1000;
57289
57572
  const coneWidth = coneLength * Math.tan( this.light.angle );
@@ -57566,6 +57849,8 @@ class PointLightHelper extends Mesh {
57566
57849
  */
57567
57850
  update() {
57568
57851
 
57852
+ this.matrixWorldNeedsUpdate = true;
57853
+
57569
57854
  this.light.updateWorldMatrix( true, false );
57570
57855
 
57571
57856
  if ( this.color !== undefined ) {
@@ -57709,6 +57994,8 @@ class HemisphereLightHelper extends Object3D {
57709
57994
 
57710
57995
  }
57711
57996
 
57997
+ this.matrixWorldNeedsUpdate = true;
57998
+
57712
57999
  this.light.updateWorldMatrix( true, false );
57713
58000
 
57714
58001
  mesh.lookAt( _vector$1.setFromMatrixPosition( this.light.matrixWorld ).negate() );
@@ -58020,6 +58307,8 @@ class DirectionalLightHelper extends Object3D {
58020
58307
  */
58021
58308
  update() {
58022
58309
 
58310
+ this.matrixWorldNeedsUpdate = true;
58311
+
58023
58312
  this.light.updateWorldMatrix( true, false );
58024
58313
  this.light.target.updateWorldMatrix( true, false );
58025
58314
 
@@ -58973,6 +59262,14 @@ class ShapePath {
58973
59262
  */
58974
59263
  this.currentPath = null;
58975
59264
 
59265
+ /**
59266
+ * An object that can be used to store custom data about the shape path.
59267
+ * Mainly used by SVGLoader to store style information.
59268
+ *
59269
+ * @type {Object}
59270
+ */
59271
+ this.userData = {};
59272
+
58976
59273
  }
58977
59274
 
58978
59275
  /**
@@ -59064,235 +59361,213 @@ class ShapePath {
59064
59361
  /**
59065
59362
  * Converts the paths into an array of shapes.
59066
59363
  *
59067
- * @param {boolean} isCCW - By default solid shapes are defined clockwise (CW) and holes are defined counterclockwise (CCW).
59068
- * If this flag is set to `true`, then those are flipped.
59069
59364
  * @return {Array<Shape>} An array of shapes.
59070
59365
  */
59071
- toShapes( isCCW ) {
59366
+ toShapes() {
59072
59367
 
59073
- function toShapesNoHoles( inSubpaths ) {
59368
+ // Point-in-polygon test using the even-odd ray-casting rule. Valid for
59369
+ // simple (non self-intersecting) polygons.
59370
+ function pointInPolygon( p, polygon ) {
59074
59371
 
59075
- const shapes = [];
59076
-
59077
- for ( let i = 0, l = inSubpaths.length; i < l; i ++ ) {
59078
-
59079
- const tmpPath = inSubpaths[ i ];
59080
-
59081
- const tmpShape = new Shape();
59082
- tmpShape.curves = tmpPath.curves;
59083
-
59084
- shapes.push( tmpShape );
59085
-
59086
- }
59087
-
59088
- return shapes;
59089
-
59090
- }
59091
-
59092
- function isPointInsidePolygon( inPt, inPolygon ) {
59093
-
59094
- const polyLen = inPolygon.length;
59095
-
59096
- // inPt on polygon contour => immediate success or
59097
- // toggling of inside/outside at every single! intersection point of an edge
59098
- // with the horizontal line through inPt, left of inPt
59099
- // not counting lowerY endpoints of edges and whole edges on that line
59100
59372
  let inside = false;
59101
- for ( let p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {
59102
-
59103
- let edgeLowPt = inPolygon[ p ];
59104
- let edgeHighPt = inPolygon[ q ];
59373
+ const n = polygon.length;
59105
59374
 
59106
- let edgeDx = edgeHighPt.x - edgeLowPt.x;
59107
- let edgeDy = edgeHighPt.y - edgeLowPt.y;
59375
+ for ( let i = 0, j = n - 1; i < n; j = i ++ ) {
59108
59376
 
59109
- if ( Math.abs( edgeDy ) > Number.EPSILON ) {
59377
+ const a = polygon[ i ];
59378
+ const b = polygon[ j ];
59110
59379
 
59111
- // not parallel
59112
- if ( edgeDy < 0 ) {
59113
-
59114
- edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;
59115
- edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;
59116
-
59117
- }
59118
-
59119
- if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue;
59120
-
59121
- if ( inPt.y === edgeLowPt.y ) {
59122
-
59123
- if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ?
59124
- // continue; // no intersection or edgeLowPt => doesn't count !!!
59125
-
59126
- } else {
59127
-
59128
- const perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );
59129
- if ( perpEdge === 0 ) return true; // inPt is on contour ?
59130
- if ( perpEdge < 0 ) continue;
59131
- inside = ! inside; // true intersection left of inPt
59132
-
59133
- }
59134
-
59135
- } else {
59380
+ if ( ( a.y > p.y ) !== ( b.y > p.y ) &&
59381
+ p.x < ( b.x - a.x ) * ( p.y - a.y ) / ( b.y - a.y ) + a.x ) {
59136
59382
 
59137
- // parallel or collinear
59138
- if ( inPt.y !== edgeLowPt.y ) continue; // parallel
59139
- // edge lies on the same horizontal line as inPt
59140
- if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||
59141
- ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour !
59142
- // continue;
59383
+ inside = ! inside;
59143
59384
 
59144
59385
  }
59145
59386
 
59146
59387
  }
59147
59388
 
59148
- return inside;
59389
+ return inside;
59149
59390
 
59150
59391
  }
59151
59392
 
59152
- const isClockWise = ShapeUtils.isClockWise;
59153
-
59154
- const subPaths = this.subPaths;
59155
- if ( subPaths.length === 0 ) return [];
59156
-
59157
- let solid, tmpPath, tmpShape;
59158
- const shapes = [];
59159
-
59160
- if ( subPaths.length === 1 ) {
59393
+ // Returns a point guaranteed to be strictly inside the given simple
59394
+ // polygon. First tries the bounding-box center; if that falls outside
59395
+ // the polygon, casts a horizontal ray at the center's y and picks the
59396
+ // midpoint between the first two sorted intercepts.
59397
+ //
59398
+ // Port of paper.js' Path#getInteriorPoint()
59399
+ // https://github.com/paperjs/paper.js/blob/develop/src/path/PathItem.Boolean.js
59400
+ function getInteriorPoint( polygon, boundingBox ) {
59161
59401
 
59162
- tmpPath = subPaths[ 0 ];
59163
- tmpShape = new Shape();
59164
- tmpShape.curves = tmpPath.curves;
59165
- shapes.push( tmpShape );
59166
- return shapes;
59402
+ const point = boundingBox.getCenter( new Vector2() );
59167
59403
 
59168
- }
59404
+ if ( pointInPolygon( point, polygon ) ) return point;
59169
59405
 
59170
- let holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );
59171
- holesFirst = isCCW ? ! holesFirst : holesFirst;
59406
+ const y = point.y;
59407
+ const intercepts = [];
59408
+ const n = polygon.length;
59172
59409
 
59173
- // log("Holes first", holesFirst);
59410
+ for ( let i = 0; i < n; i ++ ) {
59174
59411
 
59175
- const betterShapeHoles = [];
59176
- const newShapes = [];
59177
- let newShapeHoles = [];
59178
- let mainIdx = 0;
59179
- let tmpPoints;
59412
+ const a = polygon[ i ];
59413
+ const b = polygon[ ( i + 1 ) % n ];
59180
59414
 
59181
- newShapes[ mainIdx ] = undefined;
59182
- newShapeHoles[ mainIdx ] = [];
59415
+ // Half-open crossing rule — counts each vertex exactly once and
59416
+ // skips horizontal edges.
59417
+ if ( ( a.y > y ) !== ( b.y > y ) ) {
59183
59418
 
59184
- for ( let i = 0, l = subPaths.length; i < l; i ++ ) {
59419
+ const x = a.x + ( y - a.y ) * ( b.x - a.x ) / ( b.y - a.y );
59420
+ intercepts.push( x );
59185
59421
 
59186
- tmpPath = subPaths[ i ];
59187
- tmpPoints = tmpPath.getPoints();
59188
- solid = isClockWise( tmpPoints );
59189
- solid = isCCW ? ! solid : solid;
59422
+ }
59190
59423
 
59191
- if ( solid ) {
59424
+ }
59192
59425
 
59193
- if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++;
59426
+ if ( intercepts.length > 1 ) {
59194
59427
 
59195
- newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };
59196
- newShapes[ mainIdx ].s.curves = tmpPath.curves;
59428
+ intercepts.sort( ( a, b ) => a - b );
59429
+ point.x = ( intercepts[ 0 ] + intercepts[ 1 ] ) / 2;
59197
59430
 
59198
- if ( holesFirst ) mainIdx ++;
59199
- newShapeHoles[ mainIdx ] = [];
59431
+ }
59200
59432
 
59201
- //log('cw', i);
59433
+ return point;
59202
59434
 
59203
- } else {
59435
+ }
59204
59436
 
59205
- newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );
59437
+ // Resolve fill-rule. Defaults to 'nonzero'.
59438
+ let fillRule = ( this.userData.style && this.userData.style.fillRule ) || 'nonzero';
59206
59439
 
59207
- //log('ccw', i);
59440
+ if ( fillRule !== 'nonzero' && fillRule !== 'evenodd' ) {
59208
59441
 
59209
- }
59442
+ warn( 'Fill-rule "' + fillRule + '" is not supported, falling back to "nonzero".' );
59443
+ fillRule = 'nonzero';
59210
59444
 
59211
59445
  }
59212
59446
 
59213
- // only Holes? -> probably all Shapes with wrong orientation
59214
- if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths );
59447
+ // Predicate that decides whether a winding number falls inside the fill
59448
+ // region, per the SVG fill-rule spec. Works for negative windings too,
59449
+ // because JavaScript's bitwise AND preserves odd/even under two's
59450
+ // complement.
59451
+ const isInside = fillRule === 'nonzero'
59452
+ ? ( w => w !== 0 )
59453
+ : ( w => ( w & 1 ) !== 0 );
59215
59454
 
59455
+ // Build an entry per usable subpath. Self-winding follows the standard
59456
+ // convention used by ShapeUtils: counter-clockwise (signed area > 0)
59457
+ // contributes +1 to the winding number at an interior point,
59458
+ // clockwise contributes -1.
59459
+ const entries = [];
59216
59460
 
59217
- if ( newShapes.length > 1 ) {
59461
+ for ( const subPath of this.subPaths ) {
59218
59462
 
59219
- let ambiguous = false;
59220
- let toChange = 0;
59463
+ const points = subPath.getPoints();
59464
+ if ( points.length < 3 ) continue;
59221
59465
 
59222
- for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
59466
+ const area = ShapeUtils.area( points );
59467
+ if ( area === 0 ) continue;
59223
59468
 
59224
- betterShapeHoles[ sIdx ] = [];
59469
+ const boundingBox = new Box2();
59470
+ for ( let i = 0; i < points.length; i ++ ) boundingBox.expandByPoint( points[ i ] );
59225
59471
 
59226
- }
59227
-
59228
- for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
59229
-
59230
- const sho = newShapeHoles[ sIdx ];
59472
+ entries.push( {
59473
+ subPath: subPath,
59474
+ points: points,
59475
+ boundingBox: boundingBox,
59476
+ interiorPoint: getInteriorPoint( points, boundingBox ),
59477
+ absArea: Math.abs( area ),
59478
+ winding: area < 0 ? -1 : 1,
59479
+ container: null,
59480
+ exclude: false,
59481
+ role: null
59482
+ } );
59231
59483
 
59232
- for ( let hIdx = 0; hIdx < sho.length; hIdx ++ ) {
59484
+ }
59233
59485
 
59234
- const ho = sho[ hIdx ];
59235
- let hole_unassigned = true;
59486
+ // Sort by area descending. This guarantees that any subpath that could
59487
+ // contain `entries[i]` is located at a smaller index and has already
59488
+ // been processed when it's entries[i]'s turn. Port of paper.js'
59489
+ // reorientPaths() algorithm.
59490
+ entries.sort( ( a, b ) => b.absArea - a.absArea );
59236
59491
 
59237
- for ( let s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {
59492
+ // Walk already-processed entries from closest-in-size to largest,
59493
+ // stopping at the innermost container. Accumulate the container's
59494
+ // cumulative winding into this entry's winding so that the final value
59495
+ // equals the winding number at this entry's interior point.
59496
+ //
59497
+ // A subpath only contributes to the fill boundary when crossing it
59498
+ // actually flips the "insideness" per the fill rule; otherwise it's a
59499
+ // redundant overlap and gets excluded to avoid double-counting.
59500
+ for ( let i = 0; i < entries.length; i ++ ) {
59238
59501
 
59239
- if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {
59502
+ const entry = entries[ i ];
59503
+ let containerWinding = 0;
59240
59504
 
59241
- if ( sIdx !== s2Idx ) toChange ++;
59505
+ for ( let j = i - 1; j >= 0; j -- ) {
59242
59506
 
59243
- if ( hole_unassigned ) {
59507
+ const candidate = entries[ j ];
59244
59508
 
59245
- hole_unassigned = false;
59246
- betterShapeHoles[ s2Idx ].push( ho );
59509
+ if ( ! candidate.boundingBox.containsBox( entry.boundingBox ) ) continue;
59510
+ if ( ! pointInPolygon( entry.interiorPoint, candidate.points ) ) continue;
59247
59511
 
59248
- } else {
59512
+ entry.container = candidate.exclude ? candidate.container : candidate;
59513
+ containerWinding = candidate.winding;
59514
+ entry.winding += containerWinding;
59515
+ break;
59249
59516
 
59250
- ambiguous = true;
59517
+ }
59251
59518
 
59252
- }
59519
+ if ( isInside( entry.winding ) === isInside( containerWinding ) ) {
59253
59520
 
59254
- }
59521
+ entry.exclude = true;
59255
59522
 
59256
- }
59523
+ }
59257
59524
 
59258
- if ( hole_unassigned ) {
59525
+ }
59259
59526
 
59260
- betterShapeHoles[ sIdx ].push( ho );
59527
+ // Classify retained entries. An entry is an outer shape if it has no
59528
+ // container or if its container is itself a hole (a solid nested inside
59529
+ // a hole becomes a new top-level shape); otherwise it's a hole in its
59530
+ // container. Entries were already sorted outermost-first, so each
59531
+ // container's role is known by the time we look at it.
59532
+ for ( const entry of entries ) {
59261
59533
 
59262
- }
59534
+ if ( entry.exclude ) continue;
59535
+ entry.role = ( entry.container === null || entry.container.role === 'hole' ) ? 'outer' : 'hole';
59263
59536
 
59264
- }
59537
+ }
59265
59538
 
59266
- }
59539
+ // Build Shapes for outers first, then attach holes to their container's
59540
+ // Shape.
59541
+ const shapes = [];
59542
+ const shapeByEntry = new Map();
59267
59543
 
59268
- if ( toChange > 0 && ambiguous === false ) {
59544
+ for ( const entry of entries ) {
59269
59545
 
59270
- newShapeHoles = betterShapeHoles;
59546
+ if ( entry.exclude || entry.role !== 'outer' ) continue;
59271
59547
 
59272
- }
59548
+ const shape = new Shape();
59549
+ shape.curves = entry.subPath.curves;
59550
+ shapes.push( shape );
59551
+ shapeByEntry.set( entry, shape );
59273
59552
 
59274
59553
  }
59275
59554
 
59276
- let tmpHoles;
59555
+ for ( const entry of entries ) {
59277
59556
 
59278
- for ( let i = 0, il = newShapes.length; i < il; i ++ ) {
59557
+ if ( entry.exclude || entry.role !== 'hole' ) continue;
59279
59558
 
59280
- tmpShape = newShapes[ i ].s;
59281
- shapes.push( tmpShape );
59282
- tmpHoles = newShapeHoles[ i ];
59559
+ const shape = shapeByEntry.get( entry.container );
59560
+ if ( ! shape ) continue;
59283
59561
 
59284
- for ( let j = 0, jl = tmpHoles.length; j < jl; j ++ ) {
59285
-
59286
- tmpShape.holes.push( tmpHoles[ j ].h );
59287
-
59288
- }
59562
+ const hole = new Path();
59563
+ hole.curves = entry.subPath.curves;
59564
+ shape.holes.push( hole );
59289
59565
 
59290
59566
  }
59291
59567
 
59292
- //log("shape", shapes);
59293
-
59294
59568
  return shapes;
59295
59569
 
59570
+
59296
59571
  }
59297
59572
 
59298
59573
  }
@@ -59637,7 +59912,7 @@ function getTextureTypeByteLength( type ) {
59637
59912
 
59638
59913
  }
59639
59914
 
59640
- throw new Error( `Unknown texture type ${type}.` );
59915
+ throw new Error( `THREE.TextureUtils: Unknown texture type ${type}.` );
59641
59916
 
59642
59917
  }
59643
59918
 
@@ -59718,14 +59993,22 @@ class TextureUtils {
59718
59993
  * __gnsx_profiler.downloadTrace() // download gnsx-trace.json for Speedscope / Perfetto
59719
59994
  * __gnsx_profiler.reset() // clear samples and trace
59720
59995
  * __gnsx_profiler.disable()
59996
+ *
59997
+ * Chrome trace: `tid=1` is synchronous work; `@profile` on async methods records the
59998
+ * promise lifetime on `tid=2` so long async does not flatten the main row. For manual
59999
+ * spans, use `beginSpan` / `endSpan` with `{ asyncTimeline: true }` in a `.finally()`.
59721
60000
  */
59722
60001
 
59723
60002
  const RING_SIZE = 120;
59724
60003
  const FRAME_BUDGET_MS = 1000 / 60;
59725
- /** Max events in the trace log (~50s at 60fps with 8 labels). */
59726
- const MAX_TRACE_EVENTS = 50_000;
60004
+ const TRACE_TID_MAIN = 1;
60005
+ const TRACE_TID_ASYNC = 2;
59727
60006
  const NOOP = () => {};
59728
60007
 
60008
+ const DUMMY_SPAN = Object.freeze( { label: '', t0: 0, _seq: 0 } );
60009
+ const NOOP_BEGIN_SPAN = () => DUMMY_SPAN;
60010
+ const NOOP_END_SPAN = () => {};
60011
+
59729
60012
  class ProfilerServiceClass {
59730
60013
 
59731
60014
  constructor() {
@@ -59739,7 +60022,7 @@ class ProfilerServiceClass {
59739
60022
  this.cursors = new Map();
59740
60023
  /** @type {Map<string, number>} */
59741
60024
  this.counts = new Map();
59742
- /** @type {Map<string, Array<{ startTime: number, startMark: string, traced: boolean }>>} */
60025
+ /** @type {Map<string, Array<{ startTime: number, startMark: string }>>} */
59743
60026
  this.marks = new Map();
59744
60027
  /** @type {ChromeTraceEvent[]} */
59745
60028
  this.traceEvents = [];
@@ -59765,6 +60048,8 @@ class ProfilerServiceClass {
59765
60048
  this.traceStartTime = performance.now();
59766
60049
  this.begin = this._beginImpl.bind( this );
59767
60050
  this.end = this._endImpl.bind( this );
60051
+ this.beginSpan = this._beginSpanImpl.bind( this );
60052
+ this.endSpan = this._endSpanImpl.bind( this );
59768
60053
  this._exposeGlobal();
59769
60054
  console.log( `[ProfilerService] auto-started from env (profile: ${this._profile})` );
59770
60055
 
@@ -59772,6 +60057,8 @@ class ProfilerServiceClass {
59772
60057
 
59773
60058
  this.begin = NOOP;
59774
60059
  this.end = NOOP;
60060
+ this.beginSpan = NOOP_BEGIN_SPAN;
60061
+ this.endSpan = NOOP_END_SPAN;
59775
60062
 
59776
60063
  }
59777
60064
 
@@ -59803,6 +60090,8 @@ class ProfilerServiceClass {
59803
60090
  this._enabled = true;
59804
60091
  this.begin = this._beginImpl.bind( this );
59805
60092
  this.end = this._endImpl.bind( this );
60093
+ this.beginSpan = this._beginSpanImpl.bind( this );
60094
+ this.endSpan = this._endSpanImpl.bind( this );
59806
60095
  this._exposeGlobal();
59807
60096
  console.log( `[ProfilerService] enabled (profile: ${this._profile}) — call __gnsx_profiler.report() or downloadTrace() from the console` );
59808
60097
 
@@ -59814,6 +60103,8 @@ class ProfilerServiceClass {
59814
60103
  this._enabled = false;
59815
60104
  this.begin = NOOP;
59816
60105
  this.end = NOOP;
60106
+ this.beginSpan = NOOP_BEGIN_SPAN;
60107
+ this.endSpan = NOOP_END_SPAN;
59817
60108
  console.log( '[ProfilerService] disabled' );
59818
60109
 
59819
60110
  }
@@ -59849,22 +60140,8 @@ class ProfilerServiceClass {
59849
60140
 
59850
60141
  }
59851
60142
 
59852
- const traced = this._profile === 'full' && this.traceEvents.length < MAX_TRACE_EVENTS;
59853
- if ( traced ) {
59854
-
59855
- this.traceEvents.push( {
59856
- name: label,
59857
- ph: 'B',
59858
- ts: this._getTraceTimestamp( startTime ),
59859
- pid: 1,
59860
- tid: 1,
59861
- cat: 'gnsx',
59862
- } );
59863
-
59864
- }
59865
-
59866
60143
  performance.mark( startMark );
59867
- stack.push( { startTime, startMark, traced } );
60144
+ stack.push( { startTime, startMark } );
59868
60145
 
59869
60146
  // Push onto the global call stack for exclusive-time tracking.
59870
60147
  this.callStack.push( { label, childTime: 0 } );
@@ -59882,13 +60159,61 @@ class ProfilerServiceClass {
59882
60159
  if ( stack.length === 0 ) this.marks.delete( label );
59883
60160
 
59884
60161
  const now = performance.now();
59885
- const { startTime, startMark, traced } = mark;
60162
+ const { startTime, startMark } = mark;
59886
60163
  const duration = now - startTime;
59887
60164
  const endMark = `gnsx:${label}:end:${++ this._markId}`;
59888
60165
 
59889
60166
  performance.mark( endMark );
59890
60167
  performance.measure( `gnsx:${label}`, startMark, endMark );
59891
60168
 
60169
+ this._commitDurationSample( label, startTime, duration, TRACE_TID_MAIN );
60170
+
60171
+ }
60172
+
60173
+ /**
60174
+ * Per-invocation span start (pair with {@link ProfilerServiceClass#endSpan}).
60175
+ * Safe for concurrent async with the same label.
60176
+ *
60177
+ * @param {string} label
60178
+ * @return {import('./ProfilerService.js').SpanHandle}
60179
+ */
60180
+ _beginSpanImpl( label ) {
60181
+
60182
+ const seq = ++ this._markId;
60183
+ const t0 = performance.now();
60184
+ const startMark = `gnsx:${label}:s${seq}:start`;
60185
+ performance.mark( startMark );
60186
+ return { label, t0, _seq: seq, _startMark: startMark };
60187
+
60188
+ }
60189
+
60190
+ /**
60191
+ * @param {import('./ProfilerService.js').SpanHandle} handle
60192
+ * @param {import('./ProfilerService.js').EndSpanOptions} [opts]
60193
+ */
60194
+ _endSpanImpl( handle, opts ) {
60195
+
60196
+ if ( handle._seq === 0 ) return;
60197
+
60198
+ const now = performance.now();
60199
+ const duration = now - handle.t0;
60200
+ const endMark = `gnsx:${handle.label}:s${handle._seq}:end`;
60201
+ performance.mark( endMark );
60202
+ performance.measure( `gnsx:${handle.label}#${handle._seq}`, handle._startMark, endMark );
60203
+
60204
+ const traceTid = opts?.asyncTimeline === true ? TRACE_TID_ASYNC : TRACE_TID_MAIN;
60205
+ this._commitDurationSample( handle.label, handle.t0, duration, traceTid );
60206
+
60207
+ }
60208
+
60209
+ /**
60210
+ * @param {string} label
60211
+ * @param {number} startTime
60212
+ * @param {number} durationMs
60213
+ * @param {typeof TRACE_TID_MAIN|typeof TRACE_TID_ASYNC} traceTid
60214
+ */
60215
+ _commitDurationSample( label, startTime, durationMs, traceTid ) {
60216
+
59892
60217
  let buffer = this.buffers.get( label );
59893
60218
  if ( ! buffer ) {
59894
60219
 
@@ -59900,7 +60225,7 @@ class ProfilerServiceClass {
59900
60225
  }
59901
60226
 
59902
60227
  const cursor = this.cursors.get( label );
59903
- buffer[ cursor ] = duration;
60228
+ buffer[ cursor ] = durationMs;
59904
60229
  this.cursors.set( label, ( cursor + 1 ) % RING_SIZE );
59905
60230
  this.counts.set( label, Math.min( ( this.counts.get( label ) + 1 ), RING_SIZE ) );
59906
60231
 
@@ -59912,7 +60237,7 @@ class ProfilerServiceClass {
59912
60237
  if ( top !== undefined && top.label === label ) {
59913
60238
 
59914
60239
  this.callStack.pop();
59915
- const selfTime = Math.max( 0, duration - top.childTime );
60240
+ const selfTime = Math.max( 0, durationMs - top.childTime );
59916
60241
 
59917
60242
  let selfBuffer = this.selfBuffers.get( label );
59918
60243
  if ( ! selfBuffer ) {
@@ -59931,7 +60256,7 @@ class ProfilerServiceClass {
59931
60256
 
59932
60257
  // Propagate inclusive duration to the parent scope's child accumulator.
59933
60258
  const parent = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
59934
- if ( parent !== undefined ) parent.childTime += duration;
60259
+ if ( parent !== undefined ) parent.childTime += durationMs;
59935
60260
 
59936
60261
  } else {
59937
60262
 
@@ -59940,14 +60265,16 @@ class ProfilerServiceClass {
59940
60265
 
59941
60266
  }
59942
60267
 
59943
- if ( traced ) {
60268
+ if ( traceTid ) {
59944
60269
 
60270
+ const traceName = traceTid === TRACE_TID_ASYNC ? `${label} (promise)` : label;
59945
60271
  this.traceEvents.push( {
59946
- name: label,
59947
- ph: 'E',
59948
- ts: this._getTraceTimestamp( now ),
60272
+ name: traceName,
60273
+ ph: 'X',
60274
+ ts: Math.round( this._getTraceTimestamp( startTime ) ),
60275
+ dur: Math.max( 1, Math.round( durationMs * 1000 ) ),
59949
60276
  pid: 1,
59950
- tid: 1,
60277
+ tid: traceTid,
59951
60278
  cat: 'gnsx',
59952
60279
  } );
59953
60280
 
@@ -60058,13 +60385,53 @@ class ProfilerServiceClass {
60058
60385
  */
60059
60386
  exportChromeTrace() {
60060
60387
 
60388
+ const slices = [ ...this.traceEvents ];
60389
+ slices.sort( ( a, b ) => {
60390
+
60391
+ if ( a.ts !== b.ts ) return a.ts - b.ts;
60392
+ if ( a.tid !== b.tid ) return a.tid - b.tid;
60393
+ return a.name.localeCompare( b.name );
60394
+
60395
+ } );
60396
+ const hasAsync = slices.some( e => e.tid === TRACE_TID_ASYNC );
60397
+ /** @type {import('./ProfilerService.js').ChromeTraceMetadataEvent[]} */
60398
+ const prefix = [
60399
+ {
60400
+ cat: '__metadata',
60401
+ name: 'process_name',
60402
+ ph: 'M',
60403
+ pid: 1,
60404
+ tid: 0,
60405
+ ts: 0,
60406
+ args: { name: 'Genesys Profiler' },
60407
+ },
60408
+ {
60409
+ cat: '__metadata',
60410
+ name: 'thread_name',
60411
+ ph: 'M',
60412
+ pid: 1,
60413
+ tid: TRACE_TID_MAIN,
60414
+ ts: 0,
60415
+ args: { name: 'Main thread' },
60416
+ },
60417
+ ];
60418
+ if ( hasAsync ) {
60419
+
60420
+ prefix.push( {
60421
+ cat: '__metadata',
60422
+ name: 'thread_name',
60423
+ ph: 'M',
60424
+ pid: 1,
60425
+ tid: TRACE_TID_ASYNC,
60426
+ ts: 0,
60427
+ args: { name: 'Async (promise lifetime)' },
60428
+ } );
60429
+
60430
+ }
60431
+
60061
60432
  return {
60062
60433
  displayTimeUnit: 'ms',
60063
- traceEvents: [
60064
- { name: 'process_name', ph: 'M', pid: 1, args: { name: 'Genesys Profiler' } },
60065
- { name: 'thread_name', ph: 'M', pid: 1, tid: 1, args: { name: 'Main Thread' } },
60066
- ...this.traceEvents,
60067
- ],
60434
+ traceEvents: [ ...prefix, ...slices ],
60068
60435
  };
60069
60436
 
60070
60437
  }
@@ -60169,22 +60536,38 @@ class ProfilerServiceClass {
60169
60536
  * @property {number|undefined} selfFrameBudget Exclusive time as percentage of a 60 fps frame budget.
60170
60537
  */
60171
60538
 
60539
+ /**
60540
+ * @typedef {Object} SpanHandle
60541
+ * @property {string} label
60542
+ * @property {number} t0
60543
+ * @property {number} _seq
60544
+ * @property {string} _startMark
60545
+ */
60546
+
60547
+ /**
60548
+ * @typedef {Object} EndSpanOptions
60549
+ * @property {boolean} [asyncTimeline] When true, trace slice uses `tid=2` (virtual async row).
60550
+ */
60551
+
60172
60552
  /**
60173
60553
  * @typedef {Object} ChromeTraceEvent
60174
60554
  * @property {string} name
60175
- * @property {'B'|'E'} ph
60555
+ * @property {'X'} ph
60176
60556
  * @property {number} ts
60557
+ * @property {number} dur
60177
60558
  * @property {1} pid
60178
- * @property {1} tid
60559
+ * @property {number} tid
60179
60560
  * @property {'gnsx'} cat
60180
60561
  */
60181
60562
 
60182
60563
  /**
60183
60564
  * @typedef {Object} ChromeTraceMetadataEvent
60565
+ * @property {'__metadata'} cat
60184
60566
  * @property {'process_name'|'thread_name'} name
60185
60567
  * @property {'M'} ph
60186
60568
  * @property {1} pid
60187
- * @property {1} [tid]
60569
+ * @property {number} [tid]
60570
+ * @property {0} ts
60188
60571
  * @property {{ name: string }} args
60189
60572
  */
60190
60573
 
@@ -60200,28 +60583,38 @@ class ProfilerServiceClass {
60200
60583
 
60201
60584
  const ProfilerService = new ProfilerServiceClass();
60202
60585
 
60586
+ function isThenable( x ) {
60587
+
60588
+ return (
60589
+ ( typeof x === 'object' || typeof x === 'function' ) &&
60590
+ x !== null &&
60591
+ typeof x.then === 'function'
60592
+ );
60593
+
60594
+ }
60595
+
60203
60596
  function applyProfileToMethod( label, descriptor ) {
60204
60597
 
60205
60598
  const original = descriptor.value;
60206
60599
 
60207
60600
  function profiled( ...args ) {
60208
60601
 
60209
- ProfilerService.begin( label );
60602
+ const span = ProfilerService.beginSpan( label );
60210
60603
  try {
60211
60604
 
60212
60605
  const result = original.apply( this, args );
60213
- if ( result instanceof Promise ) {
60606
+ if ( isThenable( result ) ) {
60214
60607
 
60215
- return result.finally( () => ProfilerService.end( label ) );
60608
+ return Promise.resolve( result ).finally( () => ProfilerService.endSpan( span, { asyncTimeline: true } ) );
60216
60609
 
60217
60610
  }
60218
60611
 
60219
- ProfilerService.end( label );
60612
+ ProfilerService.endSpan( span );
60220
60613
  return result;
60221
60614
 
60222
60615
  } catch ( error ) {
60223
60616
 
60224
- ProfilerService.end( label );
60617
+ ProfilerService.endSpan( span );
60225
60618
  throw error;
60226
60619
 
60227
60620
  }
@@ -60235,14 +60628,39 @@ function applyProfileToMethod( label, descriptor ) {
60235
60628
 
60236
60629
  /**
60237
60630
  * Method decorator that profiles the decorated method.
60238
- * The label is automatically set to `ClassName.methodName`.
60631
+ * Default label: `ClassName.methodName`. Pass a custom tag via `@profile('My tag')`.
60239
60632
  *
60633
+ * @param {Object|string} [targetOrTag]
60634
+ * @param {string|symbol} [propertyKey]
60635
+ * @param {PropertyDescriptor} [descriptor]
60636
+ * @return {PropertyDescriptor|function(Object, string|symbol, PropertyDescriptor): PropertyDescriptor}
60637
+ */
60638
+ function profile( targetOrTag, propertyKey, descriptor ) {
60639
+
60640
+ if ( arguments.length === 0 ) {
60641
+
60642
+ return defaultProfileDecorator;
60643
+
60644
+ }
60645
+
60646
+ if ( arguments.length === 1 && typeof targetOrTag === 'string' ) {
60647
+
60648
+ const customTag = targetOrTag;
60649
+ return ( target, key, desc ) => applyProfileToMethod( customTag, desc );
60650
+
60651
+ }
60652
+
60653
+ return defaultProfileDecorator( targetOrTag, propertyKey, descriptor );
60654
+
60655
+ }
60656
+
60657
+ /**
60240
60658
  * @param {Object} target
60241
60659
  * @param {string|symbol} propertyKey
60242
60660
  * @param {PropertyDescriptor} descriptor
60243
60661
  * @return {PropertyDescriptor}
60244
60662
  */
60245
- function profile( target, propertyKey, descriptor ) {
60663
+ function defaultProfileDecorator( target, propertyKey, descriptor ) {
60246
60664
 
60247
60665
  const className = target.constructor?.name ?? 'Unknown';
60248
60666
  return applyProfileToMethod( `${className}.${String( propertyKey )}`, descriptor );
@@ -60636,11 +61054,11 @@ var color_pars_vertex = "#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )
60636
61054
 
60637
61055
  var color_vertex = "#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvColor = vec4( 1.0 );\n#endif\n#ifdef USE_COLOR_ALPHA\n\tvColor *= color;\n#elif defined( USE_COLOR )\n\tvColor.rgb *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.rgb *= instanceColor.rgb;\n#endif\n#ifdef USE_BATCHING_COLOR\n\tvColor *= getBatchingColor( getIndirectIndex( gl_DrawID ) );\n#endif";
60638
61056
 
60639
- var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n\tvarying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated";
61057
+ var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n\tvarying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\n#define inverseTransformDirection transformDirectionByInverseViewMatrix\nvec3 transformNormalByInverseViewMatrix( in vec3 normal, in mat4 viewMatrix ) {\n\treturn normalize( ( vec4( normal, 0.0 ) * viewMatrix ).xyz );\n}\nvec3 transformDirectionByInverseViewMatrix( in vec3 dir, in mat4 viewMatrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * viewMatrix ).xyz );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated";
60640
61058
 
60641
61059
  var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\thighp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif";
60642
61060
 
60643
- var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n\tmat3 bm = mat3( batchingMatrix );\n\ttransformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n\ttransformedNormal = bm * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = bm * transformedTangent;\n\t#endif\n#endif\n#ifdef USE_INSTANCING\n\tmat3 im = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n\ttransformedNormal = im * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = im * transformedTangent;\n\t#endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\ttransformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif";
61061
+ var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n\tmat3 bm = mat3( batchingMatrix );\n\ttransformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n\ttransformedNormal = bm * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = bm * transformedTangent;\n\t#endif\n#endif\n#ifdef USE_INSTANCING\n\tmat3 im = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n\ttransformedNormal = im * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = im * transformedTangent;\n\t#endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\ttransformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n#endif";
60644
61062
 
60645
61063
  var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";
60646
61064
 
@@ -60654,7 +61072,7 @@ var colorspace_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";
60654
61072
 
60655
61073
  var colorspace_pars_fragment = "vec4 LinearTransferOETF( in vec4 value ) {\n\treturn value;\n}\nvec4 sRGBTransferEOTF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 sRGBTransferOETF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}";
60656
61074
 
60657
- var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, envMapRotation * reflectVec );\n\t\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t\t#endif\n\t#endif\n#endif";
61075
+ var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, envMapRotation * reflectVec );\n\t\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t\t#endif\n\t#endif\n#endif";
60658
61076
 
60659
61077
  var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform mat3 envMapRotation;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n#endif";
60660
61078
 
@@ -60662,7 +61080,7 @@ var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t
60662
61080
 
60663
61081
  var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif";
60664
61082
 
60665
- var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif";
61083
+ var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = transformNormalByInverseViewMatrix( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif";
60666
61084
 
60667
61085
  var fog_vertex = "#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif";
60668
61086
 
@@ -60680,9 +61098,9 @@ var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor
60680
61098
 
60681
61099
  var lights_lambert_pars_fragment = "varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert";
60682
61100
 
60683
- var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n\tuniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif ( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif\n#include <lightprobes_pars_fragment>";
61101
+ var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n\tuniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif ( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif\n#include <lightprobes_pars_fragment>";
60684
61102
 
60685
- var envmap_physical_pars_fragment = "#ifdef USE_ENVMAP\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\t#ifdef USE_ANISOTROPY\n\t\tvec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n\t\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\t\tvec3 bentNormal = cross( bitangent, viewDir );\n\t\t\t\tbentNormal = normalize( cross( bentNormal, bitangent ) );\n\t\t\t\tbentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n\t\t\t\treturn getIBLRadiance( viewDir, bentNormal, roughness );\n\t\t\t#else\n\t\t\t\treturn vec3( 0.0 );\n\t\t\t#endif\n\t\t}\n\t#endif\n#endif";
61103
+ var envmap_physical_pars_fragment = "#ifdef USE_ENVMAP\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) );\n\t\t\treflectVec = transformDirectionByInverseViewMatrix( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\t#ifdef USE_ANISOTROPY\n\t\tvec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n\t\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\t\tvec3 bentNormal = cross( bitangent, viewDir );\n\t\t\t\tbentNormal = normalize( cross( bentNormal, bitangent ) );\n\t\t\t\tbentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n\t\t\t\treturn getIBLRadiance( viewDir, bentNormal, roughness );\n\t\t\t#else\n\t\t\t\treturn vec3( 0.0 );\n\t\t\t#endif\n\t\t}\n\t#endif\n#endif";
60686
61104
 
60687
61105
  var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;";
60688
61106
 
@@ -60696,7 +61114,7 @@ var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColo
60696
61114
 
60697
61115
  var lights_physical_pars_fragment = "uniform sampler2D dfgLUT;\nstruct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tvec3 diffuseContribution;\n\tvec3 specularColor;\n\tvec3 specularColorBlended;\n\tfloat roughness;\n\tfloat metalness;\n\tfloat specularF90;\n\tfloat dispersion;\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\tvec3 iridescenceFresnelDielectric;\n\t\tvec3 iridescenceFresnelMetallic;\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\treturn 0.5 / max( gv + gl, EPSILON );\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.specularColorBlended;\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 * transpose( 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 rInv = 1.0 / ( roughness + 0.1 );\n\tfloat a = -1.9362 + 1.0678 * roughness + 0.4573 * r2 - 0.8469 * rInv;\n\tfloat b = -0.6014 + 0.5538 * roughness - 0.4670 * r2 - 0.1255 * rInv;\n\tfloat DG = exp( a * dotNV + b );\n\treturn saturate( DG );\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\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\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\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}\nvec3 BRDF_GGX_Multiscatter( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 singleScatter = BRDF_GGX( lightDir, viewDir, normal, material );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 dfgV = texture2D( dfgLUT, vec2( material.roughness, dotNV ) ).rg;\n\tvec2 dfgL = texture2D( dfgLUT, vec2( material.roughness, dotNL ) ).rg;\n\tvec3 FssEss_V = material.specularColorBlended * dfgV.x + material.specularF90 * dfgV.y;\n\tvec3 FssEss_L = material.specularColorBlended * dfgL.x + material.specularF90 * dfgL.y;\n\tfloat Ess_V = dfgV.x + dfgV.y;\n\tfloat Ess_L = dfgL.x + dfgL.y;\n\tfloat Ems_V = 1.0 - Ess_V;\n\tfloat Ems_L = 1.0 - Ess_L;\n\tvec3 Favg = material.specularColorBlended + ( 1.0 - material.specularColorBlended ) * 0.047619;\n\tvec3 Fms = FssEss_V * FssEss_L * Favg / ( 1.0 - Ems_V * Ems_L * Favg + EPSILON );\n\tfloat compensationFactor = Ems_V * Ems_L;\n\tvec3 multiScatter = Fms * compensationFactor;\n\treturn singleScatter + multiScatter;\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.specularColorBlended * t2.x + ( material.specularF90 - material.specularColorBlended ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseContribution * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t\t#ifdef USE_CLEARCOAT\n\t\t\tvec3 Ncc = geometryClearcoatNormal;\n\t\t\tvec2 uvClearcoat = LTC_Uv( Ncc, viewDir, material.clearcoatRoughness );\n\t\t\tvec4 t1Clearcoat = texture2D( ltc_1, uvClearcoat );\n\t\t\tvec4 t2Clearcoat = texture2D( ltc_2, uvClearcoat );\n\t\t\tmat3 mInvClearcoat = mat3(\n\t\t\t\tvec3( t1Clearcoat.x, 0, t1Clearcoat.y ),\n\t\t\t\tvec3( 0, 1, 0 ),\n\t\t\t\tvec3( t1Clearcoat.z, 0, t1Clearcoat.w )\n\t\t\t);\n\t\t\tvec3 fresnelClearcoat = material.clearcoatF0 * t2Clearcoat.x + ( material.clearcoatF90 - material.clearcoatF0 ) * t2Clearcoat.y;\n\t\t\tclearcoatSpecularDirect += lightColor * fresnelClearcoat * LTC_Evaluate( Ncc, viewDir, position, mInvClearcoat, rectCoords );\n\t\t#endif\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 \n \t\tsheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n \n \t\tfloat sheenAlbedoV = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n \t\tfloat sheenAlbedoL = IBLSheenBRDF( geometryNormal, directLight.direction, material.sheenRoughness );\n \n \t\tfloat sheenEnergyComp = 1.0 - max3( material.sheenColor ) * max( sheenAlbedoV, sheenAlbedoL );\n \n \t\tirradiance *= sheenEnergyComp;\n \n \t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX_Multiscatter( directLight.direction, geometryViewDir, geometryNormal, material );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseContribution );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 diffuse = irradiance * BRDF_Lambert( material.diffuseContribution );\n\t#ifdef USE_SHEEN\n\t\tfloat sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t\tfloat sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n\t\tdiffuse *= sheenEnergyComp;\n\t#endif\n\treflectedLight.indirectDiffuse += diffuse;\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\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 ) * RECIPROCAL_PI;\n \t#endif\n\tvec3 singleScatteringDielectric = vec3( 0.0 );\n\tvec3 multiScatteringDielectric = vec3( 0.0 );\n\tvec3 singleScatteringMetallic = vec3( 0.0 );\n\tvec3 multiScatteringMetallic = vec3( 0.0 );\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnelDielectric, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.iridescence, material.iridescenceFresnelMetallic, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n\t#else\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n\t#endif\n\tvec3 singleScattering = mix( singleScatteringDielectric, singleScatteringMetallic, material.metalness );\n\tvec3 multiScattering = mix( multiScatteringDielectric, multiScatteringMetallic, material.metalness );\n\tvec3 totalScatteringDielectric = singleScatteringDielectric + multiScatteringDielectric;\n\tvec3 diffuse = material.diffuseContribution * ( 1.0 - totalScatteringDielectric );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tvec3 indirectSpecular = radiance * singleScattering;\n\tindirectSpecular += multiScattering * cosineWeightedIrradiance;\n\tvec3 indirectDiffuse = diffuse * cosineWeightedIrradiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t\tfloat sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n\t\tindirectSpecular *= sheenEnergyComp;\n\t\tindirectDiffuse *= sheenEnergyComp;\n\t#endif\n\treflectedLight.indirectSpecular += indirectSpecular;\n\treflectedLight.indirectDiffuse += indirectDiffuse;\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}";
60698
61116
 
60699
- 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.iridescenceFresnelDielectric = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceFresnelMetallic = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.diffuseColor );\n\t\tmaterial.iridescenceFresnel = mix( material.iridescenceFresnelDielectric, material.iridescenceFresnelMetallic, material.metalness );\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 ) && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, 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.shadowIntensity, 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.shadowIntensity, 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\t#ifdef USE_LIGHT_PROBES_GRID\n\t\tvec3 probeWorldPos = ( ( vec4( geometryPosition, 1.0 ) - viewMatrix[ 3 ] ) * viewMatrix ).xyz;\n\t\tvec3 probeWorldNormal = inverseTransformDirection( geometryNormal, viewMatrix );\n\t\tirradiance += getLightProbeGridIrradiance( probeWorldPos, probeWorldNormal );\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
61117
+ 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.iridescenceFresnelDielectric = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceFresnelMetallic = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.diffuseColor );\n\t\tmaterial.iridescenceFresnel = mix( material.iridescenceFresnelDielectric, material.iridescenceFresnelMetallic, material.metalness );\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 ) && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, 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.shadowIntensity, 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.shadowIntensity, 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\t#ifdef USE_LIGHT_PROBES_GRID\n\t\tvec3 probeWorldPos = ( ( vec4( geometryPosition, 1.0 ) - viewMatrix[ 3 ] ) * viewMatrix ).xyz;\n\t\tvec3 probeWorldNormal = transformNormalByInverseViewMatrix( geometryNormal, viewMatrix );\n\t\tirradiance += getLightProbeGridIrradiance( probeWorldPos, probeWorldNormal );\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
60700
61118
 
60701
61119
  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( ENVMAP_TYPE_CUBE_UV )\n\t\t#if defined( STANDARD ) || defined( LAMBERT ) || defined( PHONG )\n\t\t\tiblIrradiance += getIBLIrradiance( geometryNormal );\n\t\t#endif\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";
60702
61120
 
@@ -60734,7 +61152,7 @@ var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_INSTANCING
60734
61152
 
60735
61153
  var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif";
60736
61154
 
60737
- var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal *= faceDirection;\n\t#endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn = getTangentFrame( - vViewPosition, normal,\n\t\t#if defined( USE_NORMALMAP )\n\t\t\tvNormalMapUv\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tvClearcoatNormalMapUv\n\t\t#else\n\t\t\tvUv\n\t\t#endif\n\t\t);\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn[0] *= faceDirection;\n\t\ttbn[1] *= faceDirection;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn2[0] *= faceDirection;\n\t\ttbn2[1] *= faceDirection;\n\t#endif\n#endif\nvec3 nonPerturbedNormal = normal;";
61155
+ var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal *= faceDirection;\n\t#endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn = getTangentFrame( - vViewPosition, normal,\n\t\t#if defined( USE_NORMALMAP )\n\t\t\tvNormalMapUv\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tvClearcoatNormalMapUv\n\t\t#else\n\t\t\tvUv\n\t\t#endif\n\t\t);\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\ttbn[0] *= faceDirection;\n\t\ttbn[1] *= faceDirection;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\ttbn2[0] *= faceDirection;\n\t\ttbn2[1] *= faceDirection;\n\t#endif\n#endif\nvec3 nonPerturbedNormal = normal;";
60738
61156
 
60739
61157
  var normal_fragment_maps = "#ifdef USE_NORMALMAP_OBJECTSPACE\n\tnormal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( USE_NORMALMAP_TANGENTSPACE )\n\tvec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\t#if defined( USE_PACKED_NORMALMAP )\n\t\tmapN = vec3( mapN.xy, sqrt( saturate( 1.0 - dot( mapN.xy, mapN.xy ) ) ) );\n\t#endif\n\tmapN.xy *= normalScale;\n\tnormal = normalize( tbn * mapN );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif";
60740
61158
 
@@ -60742,7 +61160,7 @@ var normal_pars_fragment = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifd
60742
61160
 
60743
61161
  var normal_pars_vertex = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif";
60744
61162
 
60745
- var normal_vertex = "#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif";
61163
+ var normal_vertex = "#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t\t#ifdef FLIP_SIDED\n\t\t\tvBitangent = - vBitangent;\n\t\t#endif\n\t#endif\n#endif";
60746
61164
 
60747
61165
  var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef USE_NORMALMAP_OBJECTSPACE\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )\n\tmat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( uv.st );\n\t\tvec2 st1 = dFdy( uv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det );\n\t\treturn mat3( T * scale, B * scale, N );\n\t}\n#endif";
60748
61166
 
@@ -60774,7 +61192,7 @@ var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n\tvarying vec4 vSp
60774
61192
 
60775
61193
  var shadowmap_pars_vertex = "#if NUM_SPOT_LIGHT_COORDS > 0\n\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif";
60776
61194
 
60777
- var shadowmap_vertex = "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\t#ifdef HAS_NORMAL\n\t\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t#else\n\t\tvec3 shadowWorldNormal = vec3( 0.0 );\n\t#endif\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n#endif";
61195
+ var shadowmap_vertex = "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\t#ifdef HAS_NORMAL\n\t\tvec3 shadowWorldNormal = transformNormalByInverseViewMatrix( transformedNormal, viewMatrix );\n\t#else\n\t\tvec3 shadowWorldNormal = vec3( 0.0 );\n\t#endif\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n#endif";
60778
61196
 
60779
61197
  var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0 && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}";
60780
61198
 
@@ -60794,7 +61212,7 @@ var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = to
60794
61212
 
60795
61213
  var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 CineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n\tvec3( 1.6605, - 0.1246, - 0.0182 ),\n\tvec3( - 0.5876, 1.1329, - 0.1006 ),\n\tvec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n\tvec3( 0.6274, 0.0691, 0.0164 ),\n\tvec3( 0.3293, 0.9195, 0.0880 ),\n\tvec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n\tvec3 x2 = x * x;\n\tvec3 x4 = x2 * x2;\n\treturn + 15.5 * x4 * x2\n\t\t- 40.14 * x4 * x\n\t\t+ 31.96 * x4\n\t\t- 6.868 * x2 * x\n\t\t+ 0.4298 * x2\n\t\t+ 0.1191 * x\n\t\t- 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n\tconst mat3 AgXInsetMatrix = mat3(\n\t\tvec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n\t\tvec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n\t\tvec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n\t);\n\tconst mat3 AgXOutsetMatrix = mat3(\n\t\tvec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n\t\tvec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n\t\tvec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n\t);\n\tconst float AgxMinEv = - 12.47393;\tconst float AgxMaxEv = 4.026069;\n\tcolor *= toneMappingExposure;\n\tcolor = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n\tcolor = AgXInsetMatrix * color;\n\tcolor = max( color, 1e-10 );\tcolor = log2( color );\n\tcolor = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n\tcolor = clamp( color, 0.0, 1.0 );\n\tcolor = agxDefaultContrastApprox( color );\n\tcolor = AgXOutsetMatrix * color;\n\tcolor = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n\tcolor = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n\tcolor = clamp( color, 0.0, 1.0 );\n\treturn color;\n}\nvec3 NeutralToneMapping( vec3 color ) {\n\tconst float StartCompression = 0.8 - 0.04;\n\tconst float Desaturation = 0.15;\n\tcolor *= toneMappingExposure;\n\tfloat x = min( color.r, min( color.g, color.b ) );\n\tfloat offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n\tcolor -= offset;\n\tfloat peak = max( color.r, max( color.g, color.b ) );\n\tif ( peak < StartCompression ) return color;\n\tfloat d = 1. - StartCompression;\n\tfloat newPeak = 1. - d * d / ( peak + d - StartCompression );\n\tcolor *= newPeak / peak;\n\tfloat g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );\n\treturn mix( color, vec3( newPeak ), g );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }";
60796
61214
 
60797
- var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmitted = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseContribution, material.specularColorBlended, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif";
61215
+ var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = transformNormalByInverseViewMatrix( normal, viewMatrix );\n\tvec4 transmitted = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseContribution, material.specularColorBlended, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif";
60798
61216
 
60799
61217
  var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tfloat w0( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );\n\t}\n\tfloat w1( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 );\n\t}\n\tfloat w2( float a ){\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );\n\t}\n\tfloat w3( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * a );\n\t}\n\tfloat g0( float a ) {\n\t\treturn w0( a ) + w1( a );\n\t}\n\tfloat g1( float a ) {\n\t\treturn w2( a ) + w3( a );\n\t}\n\tfloat h0( float a ) {\n\t\treturn - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );\n\t}\n\tfloat h1( float a ) {\n\t\treturn 1.0 + w3( a ) / ( w2( a ) + w3( a ) );\n\t}\n\tvec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {\n\t\tuv = uv * texelSize.zw + 0.5;\n\t\tvec2 iuv = floor( uv );\n\t\tvec2 fuv = fract( uv );\n\t\tfloat g0x = g0( fuv.x );\n\t\tfloat g1x = g1( fuv.x );\n\t\tfloat h0x = h0( fuv.x );\n\t\tfloat h1x = h1( fuv.x );\n\t\tfloat h0y = h0( fuv.y );\n\t\tfloat h1y = h1( fuv.y );\n\t\tvec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\treturn g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +\n\t\t\tg1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );\n\t}\n\tvec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {\n\t\tvec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );\n\t\tvec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );\n\t\tvec2 fLodSizeInv = 1.0 / fLodSize;\n\t\tvec2 cLodSizeInv = 1.0 / cLodSize;\n\t\tvec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );\n\t\tvec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );\n\t\treturn mix( fSample, cSample, fract( lod ) );\n\t}\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\treturn textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );\n\t}\n\tvec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn vec3( 1.0 );\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec4 transmittedLight;\n\t\tvec3 transmittance;\n\t\t#ifdef USE_DISPERSION\n\t\t\tfloat halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;\n\t\t\tvec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );\n\t\t\tfor ( int i = 0; i < 3; i ++ ) {\n\t\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );\n\t\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\t\trefractionCoords += 1.0;\n\t\t\t\trefractionCoords /= 2.0;\n\t\t\t\tvec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );\n\t\t\t\ttransmittedLight[ i ] = transmissionSample[ i ];\n\t\t\t\ttransmittedLight.a += transmissionSample.a;\n\t\t\t\ttransmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];\n\t\t\t}\n\t\t\ttransmittedLight.a /= 3.0;\n\t\t#else\n\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\trefractionCoords += 1.0;\n\t\t\trefractionCoords /= 2.0;\n\t\t\ttransmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\t\ttransmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\t#endif\n\t\tvec3 attenuatedColor = transmittance * transmittedLight.rgb;\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\tfloat transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );\n\t}\n#endif";
60800
61218
 
@@ -60824,7 +61242,7 @@ const fragment$e = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\
60824
61242
 
60825
61243
  const vertex$d = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <skinbase_vertex>\n\t#include <morphinstance_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}";
60826
61244
 
60827
- const fragment$d = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <clipping_planes_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = vec4( dist, 0.0, 0.0, 1.0 );\n}";
61245
+ const fragment$d = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <clipping_planes_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = vec4( dist, 0.0, 0.0, 1.0 );\n}";
60828
61246
 
60829
61247
  const vertex$c = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}";
60830
61248
 
@@ -63035,8 +63453,9 @@ class PMREMGenerator {
63035
63453
 
63036
63454
  /**
63037
63455
  * Generates a PMREM from an equirectangular texture, which can be either LDR
63038
- * or HDR. The ideal input image size is 1k (1024 x 512),
63039
- * as this matches best with the 256 x 256 cubemap output.
63456
+ * or HDR. The ideal input image size is 1k (1024 x 512), as this matches best
63457
+ * with the 256 x 256 cubemap output. The minimum supported input image size
63458
+ * is 64 x 32.
63040
63459
  *
63041
63460
  * @param {Texture} equirectangular - The equirectangular texture to be converted.
63042
63461
  * @param {?WebGLRenderTarget} [renderTarget=null] - The render target to use.
@@ -63050,8 +63469,9 @@ class PMREMGenerator {
63050
63469
 
63051
63470
  /**
63052
63471
  * Generates a PMREM from an cubemap texture, which can be either LDR
63053
- * or HDR. The ideal input cube size is 256 x 256,
63054
- * as this matches best with the 256 x 256 cubemap output.
63472
+ * or HDR. The ideal input cube size is 256 x 256, as this matches best
63473
+ * with the 256 x 256 cubemap output. The minimum supported input cube
63474
+ * size is 16 x 16 per face.
63055
63475
  *
63056
63476
  * @param {Texture} cubemap - The cubemap texture to be converted.
63057
63477
  * @param {?WebGLRenderTarget} [renderTarget=null] - The render target to use.
@@ -65089,13 +65509,14 @@ const toneMappingMap = {
65089
65509
  [ CustomToneMapping ]: 'CUSTOM_TONE_MAPPING'
65090
65510
  };
65091
65511
 
65092
- function WebGLOutput( type, width, height, depth, stencil ) {
65512
+ function WebGLOutput( type, width, height, antialias, depth, stencil ) {
65093
65513
 
65094
65514
  // render targets for scene and post-processing
65095
65515
  const targetA = new WebGLRenderTarget( width, height, {
65096
65516
  type: type,
65097
65517
  depthBuffer: depth,
65098
65518
  stencilBuffer: stencil,
65519
+ samples: antialias ? 4 : 0,
65099
65520
  depthTexture: depth ? new DepthTexture( width, height ) : undefined
65100
65521
  } );
65101
65522
 
@@ -66792,7 +67213,7 @@ function includeReplacer( match, include ) {
66792
67213
 
66793
67214
  } else {
66794
67215
 
66795
- throw new Error( 'Can not resolve #include <' + include + '>' );
67216
+ throw new Error( 'THREE.WebGLProgram: Can not resolve #include <' + include + '>' );
66796
67217
 
66797
67218
  }
66798
67219
 
@@ -67374,9 +67795,10 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
67374
67795
 
67375
67796
  gl.bindAttribLocation( program, 0, parameters.index0AttributeName );
67376
67797
 
67377
- } else if ( parameters.morphTargets === true ) {
67798
+ } else if ( parameters.hasPositionAttribute === true ) {
67799
+
67800
+ // below avoids the "Attribute 0 is disabled" performance penalty
67378
67801
 
67379
- // programs with morphTargets displace position out of attribute 0
67380
67802
  gl.bindAttribLocation( program, 0, 'position' );
67381
67803
 
67382
67804
  }
@@ -67415,7 +67837,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
67415
67837
  const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
67416
67838
 
67417
67839
  error(
67418
- 'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' +
67840
+ 'WebGLProgram: Shader Error ' + gl.getError() + ' - ' +
67419
67841
  'VALIDATE_STATUS ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) + '\n\n' +
67420
67842
  'Material Name: ' + self.name + '\n' +
67421
67843
  'Material Type: ' + self.type + '\n\n' +
@@ -67566,13 +67988,7 @@ class WebGLShaderCache {
67566
67988
 
67567
67989
  }
67568
67990
 
67569
- update( material ) {
67570
-
67571
- const vertexShader = material.vertexShader;
67572
- const fragmentShader = material.fragmentShader;
67573
-
67574
- const vertexShaderStage = this._getShaderStage( vertexShader );
67575
- const fragmentShaderStage = this._getShaderStage( fragmentShader );
67991
+ update( material, vertexShaderStage, fragmentShaderStage ) {
67576
67992
 
67577
67993
  const materialShaders = this._getShaderCacheForMaterial( material );
67578
67994
 
@@ -67612,15 +68028,15 @@ class WebGLShaderCache {
67612
68028
 
67613
68029
  }
67614
68030
 
67615
- getVertexShaderID( material ) {
68031
+ getVertexShaderStage( material ) {
67616
68032
 
67617
- return this._getShaderStage( material.vertexShader ).id;
68033
+ return this._getShaderStage( material.vertexShader );
67618
68034
 
67619
68035
  }
67620
68036
 
67621
- getFragmentShaderID( material ) {
68037
+ getFragmentShaderStage( material ) {
67622
68038
 
67623
- return this._getShaderStage( material.fragmentShader ).id;
68039
+ return this._getShaderStage( material.fragmentShader );
67624
68040
 
67625
68041
  }
67626
68042
 
@@ -67779,10 +68195,13 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67779
68195
  vertexShader = material.vertexShader;
67780
68196
  fragmentShader = material.fragmentShader;
67781
68197
 
67782
- _customShaders.update( material );
68198
+ const vertexShaderStage = _customShaders.getVertexShaderStage( material );
68199
+ const fragmentShaderStage = _customShaders.getFragmentShaderStage( material );
67783
68200
 
67784
- customVertexShaderID = _customShaders.getVertexShaderID( material );
67785
- customFragmentShaderID = _customShaders.getFragmentShaderID( material );
68201
+ _customShaders.update( material, vertexShaderStage, fragmentShaderStage );
68202
+
68203
+ customVertexShaderID = vertexShaderStage.id;
68204
+ customFragmentShaderID = fragmentShaderStage.id;
67786
68205
 
67787
68206
  }
67788
68207
 
@@ -67797,7 +68216,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67797
68216
  const HAS_ENVMAP = !! envMap;
67798
68217
  const HAS_AOMAP = !! material.aoMap;
67799
68218
  const HAS_LIGHTMAP = !! material.lightMap;
67800
- const HAS_BUMPMAP = !! material.bumpMap;
68219
+ const HAS_BUMPMAP = !! material.bumpMap && material.wireframe === false;
67801
68220
  const HAS_NORMALMAP = !! material.normalMap;
67802
68221
  const HAS_DISPLACEMENTMAP = !! material.displacementMap;
67803
68222
  const HAS_EMISSIVEMAP = !! material.emissiveMap;
@@ -67995,6 +68414,8 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67995
68414
 
67996
68415
  skinning: object.isSkinnedMesh === true,
67997
68416
 
68417
+ hasPositionAttribute: geometry.attributes.position !== undefined,
68418
+
67998
68419
  morphTargets: geometry.morphAttributes.position !== undefined,
67999
68420
  morphNormals: geometry.morphAttributes.normal !== undefined,
68000
68421
  morphColors: geometry.morphAttributes.color !== undefined,
@@ -68256,6 +68677,8 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
68256
68677
  _programLayers.enable( 21 );
68257
68678
  if ( parameters.numLightProbeGrids > 0 )
68258
68679
  _programLayers.enable( 22 );
68680
+ if ( parameters.hasPositionAttribute )
68681
+ _programLayers.enable( 23 );
68259
68682
 
68260
68683
  array.push( _programLayers.mask );
68261
68684
 
@@ -68561,12 +68984,20 @@ function WebGLRenderList() {
68561
68984
 
68562
68985
  }
68563
68986
 
68564
- function sort( customOpaqueSort, customTransparentSort ) {
68987
+ function sort( customOpaqueSort, customTransparentSort, reversedDepth ) {
68565
68988
 
68566
68989
  if ( opaque.length > 1 ) opaque.sort( customOpaqueSort || painterSortStable );
68567
68990
  if ( transmissive.length > 1 ) transmissive.sort( customTransparentSort || reversePainterSortStable );
68568
68991
  if ( transparent.length > 1 ) transparent.sort( customTransparentSort || reversePainterSortStable );
68569
68992
 
68993
+ if ( reversedDepth ) {
68994
+
68995
+ opaque.reverse();
68996
+ transmissive.reverse();
68997
+ transparent.reverse();
68998
+
68999
+ }
69000
+
68570
69001
  }
68571
69002
 
68572
69003
  function finish() {
@@ -72660,12 +73091,25 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
72660
73091
 
72661
73092
  }
72662
73093
 
72663
- const level = 0;
72664
- const internalFormat = _gl.RGBA;
72665
- const srcFormat = _gl.RGBA;
72666
- const srcType = _gl.UNSIGNED_BYTE;
73094
+ if ( _gl.texElementImage2D.length === 3 ) {
73095
+
73096
+ // Chrome 150+
73097
+
73098
+ _gl.texElementImage2D( _gl.TEXTURE_2D, _gl.RGBA8, image );
73099
+
73100
+ } else {
73101
+
73102
+ // Chrome 138 - 149
73103
+
73104
+ const level = 0;
73105
+ const internalFormat = _gl.RGBA;
73106
+ const srcFormat = _gl.RGBA;
73107
+ const srcType = _gl.UNSIGNED_BYTE;
73108
+
73109
+ _gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
73110
+
73111
+ }
72667
73112
 
72668
- _gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
72669
73113
  _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR );
72670
73114
  _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
72671
73115
  _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
@@ -73112,7 +73556,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
73112
73556
 
73113
73557
  if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {
73114
73558
 
73115
- throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' );
73559
+ throw new Error( 'THREE.WebGLTextures: renderTarget.depthTexture must be an instance of THREE.DepthTexture.' );
73116
73560
 
73117
73561
  }
73118
73562
 
@@ -73210,7 +73654,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
73210
73654
 
73211
73655
  } else {
73212
73656
 
73213
- throw new Error( 'Unknown depthTexture format' );
73657
+ throw new Error( 'THREE.WebGLTextures: Unknown depthTexture format.' );
73214
73658
 
73215
73659
  }
73216
73660
 
@@ -76009,73 +76453,101 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
76009
76453
 
76010
76454
  for ( let i = 0, il = uniforms.length; i < il; i ++ ) {
76011
76455
 
76012
- const uniformArray = Array.isArray( uniforms[ i ] ) ? uniforms[ i ] : [ uniforms[ i ] ];
76456
+ const uniformItem = uniforms[ i ];
76013
76457
 
76014
- for ( let j = 0, jl = uniformArray.length; j < jl; j ++ ) {
76458
+ if ( Array.isArray( uniformItem ) ) {
76015
76459
 
76016
- const uniform = uniformArray[ j ];
76460
+ for ( let j = 0, jl = uniformItem.length; j < jl; j ++ ) {
76017
76461
 
76018
- if ( hasUniformChanged( uniform, i, j, cache ) === true ) {
76462
+ updateUniform( uniformItem[ j ], i, j, cache );
76019
76463
 
76020
- const offset = uniform.__offset;
76464
+ }
76021
76465
 
76022
- const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
76466
+ } else {
76023
76467
 
76024
- let arrayOffset = 0;
76468
+ updateUniform( uniformItem, i, 0, cache );
76025
76469
 
76026
- for ( let k = 0; k < values.length; k ++ ) {
76470
+ }
76027
76471
 
76028
- const value = values[ k ];
76472
+ }
76029
76473
 
76030
- const info = getUniformSize( value );
76474
+ gl.bindBuffer( gl.UNIFORM_BUFFER, null );
76031
76475
 
76032
- // TODO add integer and struct support
76033
- if ( typeof value === 'number' || typeof value === 'boolean' ) {
76476
+ }
76034
76477
 
76035
- uniform.__data[ 0 ] = value;
76036
- gl.bufferSubData( gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data );
76478
+ function updateUniform( uniform, index, indexArray, cache ) {
76037
76479
 
76038
- } else if ( value.isMatrix3 ) {
76480
+ if ( hasUniformChanged( uniform, index, indexArray, cache ) === true ) {
76039
76481
 
76040
- // manually converting 3x3 to 3x4
76482
+ const offset = uniform.__offset;
76483
+ const value = uniform.value;
76041
76484
 
76042
- uniform.__data[ 0 ] = value.elements[ 0 ];
76043
- uniform.__data[ 1 ] = value.elements[ 1 ];
76044
- uniform.__data[ 2 ] = value.elements[ 2 ];
76045
- uniform.__data[ 3 ] = 0;
76046
- uniform.__data[ 4 ] = value.elements[ 3 ];
76047
- uniform.__data[ 5 ] = value.elements[ 4 ];
76048
- uniform.__data[ 6 ] = value.elements[ 5 ];
76049
- uniform.__data[ 7 ] = 0;
76050
- uniform.__data[ 8 ] = value.elements[ 6 ];
76051
- uniform.__data[ 9 ] = value.elements[ 7 ];
76052
- uniform.__data[ 10 ] = value.elements[ 8 ];
76053
- uniform.__data[ 11 ] = 0;
76485
+ if ( Array.isArray( value ) ) {
76054
76486
 
76055
- } else if ( ArrayBuffer.isView( value ) ) {
76487
+ let arrayOffset = 0;
76056
76488
 
76057
- // copy the buffer data using "set"
76058
- uniform.__data.set( new value.constructor( value.buffer, value.byteOffset, uniform.__data.length ) );
76489
+ for ( let k = 0; k < value.length; k ++ ) {
76059
76490
 
76060
- } else {
76491
+ const val = value[ k ];
76492
+ const info = getUniformSize( val );
76061
76493
 
76062
- value.toArray( uniform.__data, arrayOffset );
76494
+ writeUniformValue( val, uniform.__data, arrayOffset );
76063
76495
 
76064
- arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT;
76496
+ // only toArray() values advance arrayOffset
76497
+ if ( typeof val !== 'number' && typeof val !== 'boolean' && ! val.isMatrix3 && ! ArrayBuffer.isView( val ) ) {
76065
76498
 
76066
- }
76499
+ arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT;
76067
76500
 
76068
76501
  }
76069
76502
 
76070
- gl.bufferSubData( gl.UNIFORM_BUFFER, offset, uniform.__data );
76071
-
76072
76503
  }
76073
76504
 
76505
+ } else {
76506
+
76507
+ writeUniformValue( value, uniform.__data, 0 );
76508
+
76074
76509
  }
76075
76510
 
76511
+ gl.bufferSubData( gl.UNIFORM_BUFFER, offset, uniform.__data );
76512
+
76076
76513
  }
76077
76514
 
76078
- gl.bindBuffer( gl.UNIFORM_BUFFER, null );
76515
+ }
76516
+
76517
+ function writeUniformValue( value, data, offset ) {
76518
+
76519
+ // TODO add integer and struct support
76520
+ if ( typeof value === 'number' || typeof value === 'boolean' ) {
76521
+
76522
+ data[ 0 ] = value;
76523
+
76524
+ } else if ( value.isMatrix3 ) {
76525
+
76526
+ // manually converting 3x3 to 3x4
76527
+
76528
+ data[ 0 ] = value.elements[ 0 ];
76529
+ data[ 1 ] = value.elements[ 1 ];
76530
+ data[ 2 ] = value.elements[ 2 ];
76531
+ data[ 3 ] = 0;
76532
+ data[ 4 ] = value.elements[ 3 ];
76533
+ data[ 5 ] = value.elements[ 4 ];
76534
+ data[ 6 ] = value.elements[ 5 ];
76535
+ data[ 7 ] = 0;
76536
+ data[ 8 ] = value.elements[ 6 ];
76537
+ data[ 9 ] = value.elements[ 7 ];
76538
+ data[ 10 ] = value.elements[ 8 ];
76539
+ data[ 11 ] = 0;
76540
+
76541
+ } else if ( ArrayBuffer.isView( value ) ) {
76542
+
76543
+ // copy the buffer data using "set"
76544
+ data.set( new value.constructor( value.buffer, value.byteOffset, data.length ) );
76545
+
76546
+ } else {
76547
+
76548
+ value.toArray( data, offset );
76549
+
76550
+ }
76079
76551
 
76080
76552
  }
76081
76553
 
@@ -76610,6 +77082,10 @@ class WebGLRenderer {
76610
77082
  let _isContextLost = false;
76611
77083
  let _nodesHandler = null;
76612
77084
 
77085
+ let _scratchFramebuffer = null;
77086
+ let _srcFramebuffer = null;
77087
+ let _dstFramebuffer = null;
77088
+
76613
77089
  // internal state cache
76614
77090
 
76615
77091
  this._outputColorSpace = SRGBColorSpace;
@@ -76709,11 +77185,11 @@ class WebGLRenderer {
76709
77185
 
76710
77186
  if ( getContext( contextName ) ) {
76711
77187
 
76712
- throw new Error( 'Error creating WebGL context with your selected attributes.' );
77188
+ throw new Error( 'THREE.WebGLRenderer: Error creating WebGL context with your selected attributes.' );
76713
77189
 
76714
77190
  } else {
76715
77191
 
76716
- throw new Error( 'Error creating WebGL context.' );
77192
+ throw new Error( 'THREE.WebGLRenderer: Error creating WebGL context.' );
76717
77193
 
76718
77194
  }
76719
77195
 
@@ -76753,6 +77229,10 @@ class WebGLRenderer {
76753
77229
 
76754
77230
  }
76755
77231
 
77232
+ _scratchFramebuffer = _gl.createFramebuffer();
77233
+ _srcFramebuffer = _gl.createFramebuffer();
77234
+ _dstFramebuffer = _gl.createFramebuffer();
77235
+
76756
77236
  info = new WebGLInfo( _gl );
76757
77237
  properties = new WebGLProperties();
76758
77238
  textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
@@ -76859,7 +77339,7 @@ class WebGLRenderer {
76859
77339
 
76860
77340
  if ( _outputBufferType !== UnsignedByteType ) {
76861
77341
 
76862
- output = new WebGLOutput( _outputBufferType, canvas.width, canvas.height, depth, stencil );
77342
+ output = new WebGLOutput( _outputBufferType, canvas.width, canvas.height, antialias, depth, stencil );
76863
77343
 
76864
77344
  }
76865
77345
 
@@ -77043,7 +77523,7 @@ class WebGLRenderer {
77043
77523
 
77044
77524
  if ( _outputBufferType === UnsignedByteType ) {
77045
77525
 
77046
- error( 'THREE.WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType.' );
77526
+ error( 'WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType.' );
77047
77527
  return;
77048
77528
 
77049
77529
  }
@@ -77054,7 +77534,7 @@ class WebGLRenderer {
77054
77534
 
77055
77535
  if ( effects[ i ].isOutputPass === true ) {
77056
77536
 
77057
- warn( 'THREE.WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically.' );
77537
+ warn( 'WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically.' );
77058
77538
  break;
77059
77539
 
77060
77540
  }
@@ -77492,7 +77972,7 @@ class WebGLRenderer {
77492
77972
 
77493
77973
  if ( scene === null ) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null)
77494
77974
 
77495
- const frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
77975
+ const frontFaceCW = ( object.isMesh && object.matrixWorld.determinantAffine() < 0 );
77496
77976
 
77497
77977
  const program = setProgram( camera, scene, geometry, material, object );
77498
77978
 
@@ -78026,7 +78506,9 @@ class WebGLRenderer {
78026
78506
  // WITH_GENESYS
78027
78507
  ProfilerService.begin( 'sortRenderList' );
78028
78508
  // !WITH_GENESYS
78029
- currentRenderList.sort( _opaqueSort, _transparentSort );
78509
+
78510
+ currentRenderList.sort( _opaqueSort, _transparentSort, camera.reversedDepth );
78511
+
78030
78512
  // WITH_GENESYS
78031
78513
  ProfilerService.end( 'sortRenderList' );
78032
78514
  // !WITH_GENESYS
@@ -78048,6 +78530,8 @@ class WebGLRenderer {
78048
78530
 
78049
78531
  this.info.render.frame ++;
78050
78532
 
78533
+ if ( this.info.autoReset === true ) this.info.reset();
78534
+
78051
78535
  if ( _clippingEnabled === true ) clipping.beginShadows();
78052
78536
 
78053
78537
  const shadowsArray = currentRenderState.state.shadowsArray;
@@ -78064,8 +78548,6 @@ class WebGLRenderer {
78064
78548
 
78065
78549
  //
78066
78550
 
78067
- if ( this.info.autoReset === true ) this.info.reset();
78068
-
78069
78551
  // render scene (skip if first effect is a render pass - it will render the scene itself)
78070
78552
 
78071
78553
  const skipSceneRender = useOutput && output.hasRenderPass();
@@ -79271,8 +79753,6 @@ class WebGLRenderer {
79271
79753
 
79272
79754
  };
79273
79755
 
79274
- const _scratchFrameBuffer = _gl.createFramebuffer();
79275
-
79276
79756
  /**
79277
79757
  * Sets the active rendertarget.
79278
79758
  *
@@ -79336,7 +79816,7 @@ class WebGLRenderer {
79336
79816
  ( renderTarget.width !== depthTexture.image.width || renderTarget.height !== depthTexture.image.height )
79337
79817
  ) {
79338
79818
 
79339
- throw new Error( 'WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.' );
79819
+ throw new Error( 'THREE.WebGLRenderer: Attached DepthTexture is initialized to the incorrect size.' );
79340
79820
 
79341
79821
  }
79342
79822
 
@@ -79405,7 +79885,7 @@ class WebGLRenderer {
79405
79885
  // being bound that are different sizes.
79406
79886
  if ( activeMipmapLevel !== 0 ) {
79407
79887
 
79408
- framebuffer = _scratchFrameBuffer;
79888
+ framebuffer = _scratchFramebuffer;
79409
79889
 
79410
79890
  }
79411
79891
 
@@ -79648,8 +80128,6 @@ class WebGLRenderer {
79648
80128
 
79649
80129
  };
79650
80130
 
79651
- const _srcFramebuffer = _gl.createFramebuffer();
79652
- const _dstFramebuffer = _gl.createFramebuffer();
79653
80131
 
79654
80132
  /**
79655
80133
  * Copies data of the given source texture into a destination texture.