@plastic-software/three 0.183.4 → 0.184.1

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 (277) hide show
  1. package/build/three.cjs +775 -287
  2. package/build/three.core.js +372 -110
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +428 -181
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +7 -1
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +2979 -1281
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +2942 -1281
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +11 -0
  13. package/examples/jsm/animation/CCDIKSolver.js +5 -1
  14. package/examples/jsm/controls/ArcballControls.js +4 -1
  15. package/examples/jsm/controls/DragControls.js +2 -2
  16. package/examples/jsm/controls/FirstPersonControls.js +58 -54
  17. package/examples/jsm/controls/FlyControls.js +4 -0
  18. package/examples/jsm/controls/OrbitControls.js +2 -2
  19. package/examples/jsm/controls/TrackballControls.js +2 -2
  20. package/examples/jsm/controls/TransformControls.js +34 -2
  21. package/examples/jsm/csm/CSMShadowNode.js +6 -2
  22. package/examples/jsm/exporters/GLTFExporter.js +21 -5
  23. package/examples/jsm/geometries/TextGeometry.js +18 -0
  24. package/examples/jsm/helpers/LightProbeGridHelper.js +221 -0
  25. package/examples/jsm/inspector/Extension.js +13 -0
  26. package/examples/jsm/inspector/Inspector.js +169 -114
  27. package/examples/jsm/inspector/RendererInspector.js +2 -2
  28. package/examples/jsm/inspector/extensions/extensions.json +6 -0
  29. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +916 -0
  30. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +281 -0
  31. package/examples/jsm/inspector/tabs/Memory.js +128 -0
  32. package/examples/jsm/inspector/tabs/Parameters.js +34 -2
  33. package/examples/jsm/inspector/tabs/Performance.js +2 -2
  34. package/examples/jsm/inspector/tabs/Settings.js +264 -0
  35. package/examples/jsm/inspector/tabs/Timeline.js +1611 -0
  36. package/examples/jsm/inspector/tabs/Viewer.js +105 -3
  37. package/examples/jsm/inspector/ui/Graph.js +2 -2
  38. package/examples/jsm/inspector/ui/List.js +1 -1
  39. package/examples/jsm/inspector/ui/Profiler.js +273 -176
  40. package/examples/jsm/inspector/ui/Style.js +64 -10
  41. package/examples/jsm/inspector/ui/Tab.js +39 -7
  42. package/examples/jsm/inspector/ui/Values.js +39 -2
  43. package/examples/jsm/inspector/ui/utils.js +13 -0
  44. package/examples/jsm/interaction/InteractionManager.js +226 -0
  45. package/examples/jsm/libs/meshopt_decoder.module.js +8 -8
  46. package/examples/jsm/lighting/DynamicLighting.js +82 -0
  47. package/examples/jsm/lighting/LightProbeGrid.js +651 -0
  48. package/examples/jsm/lines/LineMaterial.js +1 -1
  49. package/examples/jsm/loaders/EXRLoader.js +682 -43
  50. package/examples/jsm/loaders/FBXLoader.js +233 -33
  51. package/examples/jsm/loaders/GLTFLoader.js +24 -7
  52. package/examples/jsm/loaders/HDRLoader.js +1 -1
  53. package/examples/jsm/loaders/KTX2Loader.js +8 -2
  54. package/examples/jsm/loaders/LDrawLoader.js +39 -47
  55. package/examples/jsm/loaders/SVGLoader.js +1 -1
  56. package/examples/jsm/loaders/VTKLoader.js +5 -1
  57. package/examples/jsm/loaders/collada/ColladaComposer.js +101 -7
  58. package/examples/jsm/loaders/collada/ColladaParser.js +19 -4
  59. package/examples/jsm/loaders/usd/USDAParser.js +6 -0
  60. package/examples/jsm/loaders/usd/USDCParser.js +26 -0
  61. package/examples/jsm/loaders/usd/USDComposer.js +656 -103
  62. package/examples/jsm/misc/GPUComputationRenderer.js +2 -0
  63. package/examples/jsm/misc/RollerCoaster.js +42 -4
  64. package/examples/jsm/modifiers/TessellateModifier.js +1 -1
  65. package/examples/jsm/objects/Reflector.js +73 -25
  66. package/examples/jsm/objects/Sky.js +14 -2
  67. package/examples/jsm/objects/SkyMesh.js +23 -6
  68. package/examples/jsm/renderers/Projector.js +18 -38
  69. package/examples/jsm/renderers/SVGRenderer.js +6 -25
  70. package/examples/jsm/transpiler/GLSLDecoder.js +2 -2
  71. package/examples/jsm/tsl/WebGLNodesHandler.js +605 -0
  72. package/examples/jsm/tsl/display/AfterImageNode.js +10 -0
  73. package/examples/jsm/tsl/display/AnamorphicNode.js +11 -0
  74. package/examples/jsm/tsl/display/BilateralBlurNode.js +10 -0
  75. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +3 -36
  76. package/examples/jsm/tsl/display/FSR1Node.js +477 -0
  77. package/examples/jsm/tsl/display/GTAONode.js +2 -1
  78. package/examples/jsm/tsl/display/GaussianBlurNode.js +10 -0
  79. package/examples/jsm/tsl/display/GodraysNode.js +2 -11
  80. package/examples/jsm/tsl/display/OutlineNode.js +66 -16
  81. package/examples/jsm/tsl/display/SSGINode.js +0 -4
  82. package/examples/jsm/tsl/display/SharpenNode.js +283 -0
  83. package/examples/jsm/tsl/display/TAAUNode.js +835 -0
  84. package/examples/jsm/tsl/display/TRAANode.js +48 -7
  85. package/examples/jsm/tsl/lighting/DynamicLightsNode.js +300 -0
  86. package/examples/jsm/tsl/lighting/data/AmbientLightDataNode.js +61 -0
  87. package/examples/jsm/tsl/lighting/data/DirectionalLightDataNode.js +111 -0
  88. package/examples/jsm/tsl/lighting/data/HemisphereLightDataNode.js +99 -0
  89. package/examples/jsm/tsl/lighting/data/PointLightDataNode.js +134 -0
  90. package/examples/jsm/tsl/lighting/data/SpotLightDataNode.js +161 -0
  91. package/examples/jsm/tsl/math/Bayer.js +13 -2
  92. package/examples/jsm/utils/BufferGeometryUtils.js +2 -3
  93. package/examples/jsm/utils/ColorUtils.js +76 -0
  94. package/examples/jsm/utils/SkeletonUtils.js +14 -8
  95. package/examples/jsm/webxr/XRHandMeshModel.js +36 -10
  96. package/examples/jsm/webxr/XRHandModelFactory.js +2 -1
  97. package/package.json +4 -4
  98. package/src/Three.Core.js +1 -0
  99. package/src/Three.TSL.js +6 -0
  100. package/src/Three.WebGPU.Nodes.js +3 -0
  101. package/src/Three.WebGPU.js +6 -0
  102. package/src/animation/AnimationAction.js +11 -1
  103. package/src/audio/AudioContext.js +2 -2
  104. package/src/constants.js +1 -1
  105. package/src/core/BufferAttribute.js +13 -1
  106. package/src/core/Clock.js +1 -1
  107. package/src/core/Object3D.js +1 -5
  108. package/src/core/RenderTarget.js +1 -0
  109. package/src/extras/curves/CatmullRomCurve3.js +3 -2
  110. package/src/loaders/AudioLoader.js +11 -1
  111. package/src/loaders/DataTextureLoader.js +6 -4
  112. package/src/loaders/FileLoader.js +1 -2
  113. package/src/loaders/ImageBitmapLoader.js +4 -6
  114. package/src/loaders/MaterialLoader.js +1 -1
  115. package/src/loaders/ObjectLoader.js +25 -4
  116. package/src/loaders/nodes/NodeObjectLoader.js +18 -0
  117. package/src/materials/MeshToonMaterial.js +1 -1
  118. package/src/materials/nodes/Line2NodeMaterial.js +27 -0
  119. package/src/materials/nodes/NodeMaterial.js +0 -27
  120. package/src/materials/nodes/manager/NodeMaterialObserver.js +188 -89
  121. package/src/math/Line3.js +3 -0
  122. package/src/math/Matrix2.js +13 -9
  123. package/src/math/Matrix3.js +13 -9
  124. package/src/math/Matrix4.js +13 -9
  125. package/src/math/Plane.js +4 -3
  126. package/src/math/Triangle.js +1 -1
  127. package/src/math/Vector2.js +11 -7
  128. package/src/math/Vector3.js +12 -8
  129. package/src/math/Vector4.js +13 -9
  130. package/src/nodes/Nodes.js +0 -1
  131. package/src/nodes/TSL.js +1 -1
  132. package/src/nodes/accessors/BufferAttributeNode.js +9 -3
  133. package/src/nodes/accessors/CubeTextureNode.js +7 -1
  134. package/src/nodes/accessors/MaterialProperties.js +2 -5
  135. package/src/nodes/accessors/Object3DNode.js +1 -1
  136. package/src/nodes/accessors/ReferenceBaseNode.js +2 -2
  137. package/src/nodes/accessors/ReferenceNode.js +4 -4
  138. package/src/nodes/accessors/SceneProperties.js +2 -8
  139. package/src/nodes/accessors/StorageBufferNode.js +10 -4
  140. package/src/nodes/accessors/StorageTextureNode.js +4 -9
  141. package/src/nodes/accessors/TextureNode.js +10 -2
  142. package/src/nodes/accessors/UniformArrayNode.js +2 -2
  143. package/src/nodes/code/FunctionCallNode.js +1 -1
  144. package/src/nodes/code/FunctionNode.js +1 -1
  145. package/src/nodes/core/ArrayNode.js +1 -1
  146. package/src/nodes/core/AssignNode.js +1 -1
  147. package/src/nodes/core/AttributeNode.js +1 -1
  148. package/src/nodes/core/BypassNode.js +1 -1
  149. package/src/nodes/core/ContextNode.js +1 -1
  150. package/src/nodes/core/IndexNode.js +2 -1
  151. package/src/nodes/core/InputNode.js +1 -1
  152. package/src/nodes/core/InspectorNode.js +1 -1
  153. package/src/nodes/core/IsolateNode.js +1 -1
  154. package/src/nodes/core/Node.js +83 -12
  155. package/src/nodes/core/NodeBuilder.js +117 -16
  156. package/src/nodes/core/NodeUtils.js +1 -1
  157. package/src/nodes/core/OutputStructNode.js +1 -1
  158. package/src/nodes/core/ParameterNode.js +1 -1
  159. package/src/nodes/core/StackNode.js +1 -1
  160. package/src/nodes/core/StructNode.js +1 -1
  161. package/src/nodes/core/StructTypeNode.js +1 -1
  162. package/src/nodes/core/SubBuildNode.js +1 -1
  163. package/src/nodes/core/UniformGroupNode.js +36 -6
  164. package/src/nodes/core/VarNode.js +1 -1
  165. package/src/nodes/core/VaryingNode.js +1 -1
  166. package/src/nodes/display/NormalMapNode.js +2 -2
  167. package/src/nodes/display/PassNode.js +27 -7
  168. package/src/nodes/display/RenderOutputNode.js +4 -4
  169. package/src/nodes/display/ScreenNode.js +1 -1
  170. package/src/nodes/display/ViewportDepthTextureNode.js +11 -15
  171. package/src/nodes/display/ViewportTextureNode.js +18 -7
  172. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +2 -2
  173. package/src/nodes/geometry/RangeNode.js +1 -1
  174. package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
  175. package/src/nodes/gpgpu/BarrierNode.js +9 -0
  176. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
  177. package/src/nodes/gpgpu/ComputeNode.js +69 -44
  178. package/src/nodes/gpgpu/SubgroupFunctionNode.js +1 -1
  179. package/src/nodes/lighting/LightsNode.js +6 -27
  180. package/src/nodes/lighting/ShadowNode.js +24 -2
  181. package/src/nodes/math/BitcastNode.js +1 -1
  182. package/src/nodes/math/ConditionalNode.js +1 -1
  183. package/src/nodes/math/MathNode.js +73 -1
  184. package/src/nodes/math/OperatorNode.js +1 -1
  185. package/src/nodes/math/PackFloatNode.js +1 -1
  186. package/src/nodes/math/UnpackFloatNode.js +1 -1
  187. package/src/nodes/tsl/TSLBase.js +1 -1
  188. package/src/nodes/tsl/TSLCore.js +21 -3
  189. package/src/nodes/utils/ArrayElementNode.js +1 -1
  190. package/src/nodes/utils/ConvertNode.js +1 -1
  191. package/src/nodes/utils/DebugNode.js +1 -1
  192. package/src/nodes/utils/EventNode.js +30 -0
  193. package/src/nodes/utils/FlipNode.js +1 -1
  194. package/src/nodes/utils/FunctionOverloadingNode.js +1 -1
  195. package/src/nodes/utils/JoinNode.js +1 -1
  196. package/src/nodes/utils/MemberNode.js +1 -1
  197. package/src/nodes/utils/Remap.js +48 -0
  198. package/src/nodes/utils/RotateNode.js +1 -1
  199. package/src/nodes/utils/SetNode.js +1 -1
  200. package/src/nodes/utils/SplitNode.js +1 -1
  201. package/src/objects/BatchedMesh.js +17 -2
  202. package/src/objects/InstancedMesh.js +19 -3
  203. package/src/objects/SkinnedMesh.js +26 -9
  204. package/src/renderers/WebGLRenderer.js +147 -48
  205. package/src/renderers/common/Animation.js +3 -3
  206. package/src/renderers/common/Attributes.js +15 -1
  207. package/src/renderers/common/Backend.js +0 -8
  208. package/src/renderers/common/Background.js +2 -2
  209. package/src/renderers/common/BindGroup.js +1 -8
  210. package/src/renderers/common/Bindings.js +2 -2
  211. package/src/renderers/common/ComputePipeline.js +1 -1
  212. package/src/renderers/common/CubeRenderTarget.js +1 -1
  213. package/src/renderers/common/Info.js +333 -4
  214. package/src/renderers/common/InspectorBase.js +6 -1
  215. package/src/renderers/common/Pipelines.js +36 -3
  216. package/src/renderers/common/ReadbackBuffer.js +78 -0
  217. package/src/renderers/common/RenderBundle.js +3 -1
  218. package/src/renderers/common/RenderBundles.js +5 -2
  219. package/src/renderers/common/RenderObject.js +2 -2
  220. package/src/renderers/common/RenderObjects.js +3 -3
  221. package/src/renderers/common/RenderPipeline.js +35 -6
  222. package/src/renderers/common/Renderer.js +232 -53
  223. package/src/renderers/common/Textures.js +72 -3
  224. package/src/renderers/common/UniformsGroup.js +1 -1
  225. package/src/renderers/common/XRManager.js +34 -27
  226. package/src/renderers/common/extras/PMREMGenerator.js +23 -15
  227. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  228. package/src/renderers/common/nodes/NodeManager.js +230 -99
  229. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +0 -1
  230. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  231. package/src/renderers/shaders/ShaderChunk/lightprobes_pars_fragment.glsl.js +80 -0
  232. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +8 -0
  233. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +2 -0
  234. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +1 -3
  235. package/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js +7 -0
  236. package/src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl.js +0 -1
  237. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +12 -2
  238. package/src/renderers/shaders/ShaderChunk.js +2 -0
  239. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +1 -2
  240. package/src/renderers/shaders/ShaderLib.js +0 -1
  241. package/src/renderers/shaders/UniformsLib.js +7 -2
  242. package/src/renderers/shaders/UniformsUtils.js +27 -5
  243. package/src/renderers/webgl/WebGLAnimation.js +2 -1
  244. package/src/renderers/webgl/WebGLBackground.js +13 -13
  245. package/src/renderers/webgl/WebGLBufferRenderer.js +0 -32
  246. package/src/renderers/webgl/WebGLCapabilities.js +6 -0
  247. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +0 -32
  248. package/src/renderers/webgl/WebGLMaterials.js +12 -13
  249. package/src/renderers/webgl/WebGLOutput.js +4 -1
  250. package/src/renderers/webgl/WebGLProgram.js +4 -0
  251. package/src/renderers/webgl/WebGLPrograms.js +21 -4
  252. package/src/renderers/webgl/WebGLRenderStates.js +13 -2
  253. package/src/renderers/webgl/WebGLState.js +43 -0
  254. package/src/renderers/webgl/WebGLTextures.js +129 -26
  255. package/src/renderers/webgl/WebGLUniformsGroups.js +19 -0
  256. package/src/renderers/webgl-fallback/WebGLBackend.js +106 -65
  257. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +0 -41
  258. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +29 -51
  259. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +53 -19
  260. package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +25 -0
  261. package/src/renderers/webgl-fallback/utils/WebGLState.js +42 -1
  262. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +63 -50
  263. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +1 -1
  264. package/src/renderers/webgpu/WebGPUBackend.js +160 -146
  265. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +55 -33
  266. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +103 -17
  267. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +1 -1
  268. package/src/renderers/webgpu/utils/WebGPUCapabilities.js +48 -0
  269. package/src/renderers/webgpu/utils/WebGPUConstants.js +8 -0
  270. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +91 -17
  271. package/src/renderers/webgpu/utils/WebGPUUtils.js +18 -2
  272. package/src/renderers/webxr/WebXRController.js +12 -0
  273. package/src/textures/HTMLTexture.js +74 -0
  274. package/src/textures/Source.js +1 -1
  275. package/src/textures/Texture.js +13 -2
  276. package/src/utils.js +23 -1
  277. package/src/nodes/utils/RemapNode.js +0 -125
package/build/three.cjs CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  'use strict';
7
7
 
8
- const REVISION = '183';
8
+ const REVISION = '184';
9
9
 
10
10
  /**
11
11
  * Represents mouse buttons and interaction types in context of controls.
@@ -3010,13 +3010,7 @@ const MathUtils = {
3010
3010
  */
3011
3011
  class Vector2 {
3012
3012
 
3013
- /**
3014
- * Constructs a new 2D vector.
3015
- *
3016
- * @param {number} [x=0] - The x value of this vector.
3017
- * @param {number} [y=0] - The y value of this vector.
3018
- */
3019
- constructor( x = 0, y = 0 ) {
3013
+ static {
3020
3014
 
3021
3015
  /**
3022
3016
  * This flag can be used for type testing.
@@ -3027,6 +3021,16 @@ class Vector2 {
3027
3021
  */
3028
3022
  Vector2.prototype.isVector2 = true;
3029
3023
 
3024
+ }
3025
+
3026
+ /**
3027
+ * Constructs a new 2D vector.
3028
+ *
3029
+ * @param {number} [x=0] - The x value of this vector.
3030
+ * @param {number} [y=0] - The y value of this vector.
3031
+ */
3032
+ constructor( x = 0, y = 0 ) {
3033
+
3030
3034
  /**
3031
3035
  * The x value of this vector.
3032
3036
  *
@@ -4787,14 +4791,7 @@ class Quaternion {
4787
4791
  */
4788
4792
  class Vector3 {
4789
4793
 
4790
- /**
4791
- * Constructs a new 3D vector.
4792
- *
4793
- * @param {number} [x=0] - The x value of this vector.
4794
- * @param {number} [y=0] - The y value of this vector.
4795
- * @param {number} [z=0] - The z value of this vector.
4796
- */
4797
- constructor( x = 0, y = 0, z = 0 ) {
4794
+ static {
4798
4795
 
4799
4796
  /**
4800
4797
  * This flag can be used for type testing.
@@ -4805,6 +4802,17 @@ class Vector3 {
4805
4802
  */
4806
4803
  Vector3.prototype.isVector3 = true;
4807
4804
 
4805
+ }
4806
+
4807
+ /**
4808
+ * Constructs a new 3D vector.
4809
+ *
4810
+ * @param {number} [x=0] - The x value of this vector.
4811
+ * @param {number} [y=0] - The y value of this vector.
4812
+ * @param {number} [z=0] - The z value of this vector.
4813
+ */
4814
+ constructor( x = 0, y = 0, z = 0 ) {
4815
+
4808
4816
  /**
4809
4817
  * The x value of this vector.
4810
4818
  *
@@ -6045,6 +6053,19 @@ const _quaternion$5 = /*@__PURE__*/ new Quaternion();
6045
6053
  */
6046
6054
  class Matrix3 {
6047
6055
 
6056
+ static {
6057
+
6058
+ /**
6059
+ * This flag can be used for type testing.
6060
+ *
6061
+ * @type {boolean}
6062
+ * @readonly
6063
+ * @default true
6064
+ */
6065
+ Matrix3.prototype.isMatrix3 = true;
6066
+
6067
+ }
6068
+
6048
6069
  /**
6049
6070
  * Constructs a new 3x3 matrix. The arguments are supposed to be
6050
6071
  * in row-major order. If no arguments are provided, the constructor
@@ -6062,15 +6083,6 @@ class Matrix3 {
6062
6083
  */
6063
6084
  constructor( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
6064
6085
 
6065
- /**
6066
- * This flag can be used for type testing.
6067
- *
6068
- * @type {boolean}
6069
- * @readonly
6070
- * @default true
6071
- */
6072
- Matrix3.prototype.isMatrix3 = true;
6073
-
6074
6086
  /**
6075
6087
  * A column-major list of matrix values.
6076
6088
  *
@@ -7060,7 +7072,7 @@ class Source {
7060
7072
 
7061
7073
  } else if ( ( typeof VideoFrame !== 'undefined' ) && ( data instanceof VideoFrame ) ) {
7062
7074
 
7063
- target.set( data.displayHeight, data.displayWidth, 0 );
7075
+ target.set( data.displayWidth, data.displayHeight, 0 );
7064
7076
 
7065
7077
  } else if ( data !== null ) {
7066
7078
 
@@ -7548,6 +7560,15 @@ class Texture extends EventDispatcher {
7548
7560
  */
7549
7561
  this.pmremVersion = 0;
7550
7562
 
7563
+ /**
7564
+ * Whether the texture should use one of the 16 bit integer formats which are normalized
7565
+ * to [0, 1] or [-1, 1] (depending on signed/unsigned) when sampled.
7566
+ *
7567
+ * @type {boolean}
7568
+ * @default false
7569
+ */
7570
+ this.normalized = false;
7571
+
7551
7572
  }
7552
7573
 
7553
7574
  /**
@@ -7588,14 +7609,14 @@ class Texture extends EventDispatcher {
7588
7609
 
7589
7610
  }
7590
7611
 
7591
- set image( value = null ) {
7612
+ set image( value ) {
7592
7613
 
7593
7614
  this.source.data = value;
7594
7615
 
7595
7616
  }
7596
7617
 
7597
7618
  /**
7598
- * Updates the texture transformation matrix from the from the properties {@link Texture#offset},
7619
+ * Updates the texture transformation matrix from the properties {@link Texture#offset},
7599
7620
  * {@link Texture#repeat}, {@link Texture#rotation}, and {@link Texture#center}.
7600
7621
  */
7601
7622
  updateMatrix() {
@@ -7663,6 +7684,7 @@ class Texture extends EventDispatcher {
7663
7684
  this.format = source.format;
7664
7685
  this.internalFormat = source.internalFormat;
7665
7686
  this.type = source.type;
7687
+ this.normalized = source.normalized;
7666
7688
 
7667
7689
  this.offset.copy( source.offset );
7668
7690
  this.repeat.copy( source.repeat );
@@ -7781,6 +7803,7 @@ class Texture extends EventDispatcher {
7781
7803
  format: this.format,
7782
7804
  internalFormat: this.internalFormat,
7783
7805
  type: this.type,
7806
+ normalized: this.normalized,
7784
7807
  colorSpace: this.colorSpace,
7785
7808
 
7786
7809
  minFilter: this.minFilter,
@@ -8004,15 +8027,7 @@ Texture.DEFAULT_ANISOTROPY = 1;
8004
8027
  */
8005
8028
  class Vector4 {
8006
8029
 
8007
- /**
8008
- * Constructs a new 4D vector.
8009
- *
8010
- * @param {number} [x=0] - The x value of this vector.
8011
- * @param {number} [y=0] - The y value of this vector.
8012
- * @param {number} [z=0] - The z value of this vector.
8013
- * @param {number} [w=1] - The w value of this vector.
8014
- */
8015
- constructor( x = 0, y = 0, z = 0, w = 1 ) {
8030
+ static {
8016
8031
 
8017
8032
  /**
8018
8033
  * This flag can be used for type testing.
@@ -8023,6 +8038,18 @@ class Vector4 {
8023
8038
  */
8024
8039
  Vector4.prototype.isVector4 = true;
8025
8040
 
8041
+ }
8042
+
8043
+ /**
8044
+ * Constructs a new 4D vector.
8045
+ *
8046
+ * @param {number} [x=0] - The x value of this vector.
8047
+ * @param {number} [y=0] - The y value of this vector.
8048
+ * @param {number} [z=0] - The z value of this vector.
8049
+ * @param {number} [w=1] - The w value of this vector.
8050
+ */
8051
+ constructor( x = 0, y = 0, z = 0, w = 1 ) {
8052
+
8026
8053
  /**
8027
8054
  * The x value of this vector.
8028
8055
  *
@@ -9403,6 +9430,7 @@ class RenderTarget extends EventDispatcher {
9403
9430
  if ( source.depthTexture !== null ) this.depthTexture = source.depthTexture.clone();
9404
9431
 
9405
9432
  this.samples = source.samples;
9433
+ this.multiview = source.multiview;
9406
9434
 
9407
9435
  return this;
9408
9436
 
@@ -9819,6 +9847,19 @@ class WebGL3DRenderTarget extends WebGLRenderTarget {
9819
9847
  */
9820
9848
  class Matrix4 {
9821
9849
 
9850
+ static {
9851
+
9852
+ /**
9853
+ * This flag can be used for type testing.
9854
+ *
9855
+ * @type {boolean}
9856
+ * @readonly
9857
+ * @default true
9858
+ */
9859
+ Matrix4.prototype.isMatrix4 = true;
9860
+
9861
+ }
9862
+
9822
9863
  /**
9823
9864
  * Constructs a new 4x4 matrix. The arguments are supposed to be
9824
9865
  * in row-major order. If no arguments are provided, the constructor
@@ -9843,15 +9884,6 @@ class Matrix4 {
9843
9884
  */
9844
9885
  constructor( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
9845
9886
 
9846
- /**
9847
- * This flag can be used for type testing.
9848
- *
9849
- * @type {boolean}
9850
- * @readonly
9851
- * @default true
9852
- */
9853
- Matrix4.prototype.isMatrix4 = true;
9854
-
9855
9887
  /**
9856
9888
  * A column-major list of matrix values.
9857
9889
  *
@@ -13231,11 +13263,7 @@ class Object3D extends EventDispatcher {
13231
13263
  this.quaternion.copy( source.quaternion );
13232
13264
  this.scale.copy( source.scale );
13233
13265
 
13234
- if ( source.pivot !== null ) {
13235
-
13236
- this.pivot = source.pivot.clone();
13237
-
13238
- }
13266
+ this.pivot = ( source.pivot !== null ) ? source.pivot.clone() : null;
13239
13267
 
13240
13268
  this.matrix.copy( source.matrix );
13241
13269
  this.matrixWorld.copy( source.matrixWorld );
@@ -13453,6 +13481,7 @@ class WebXRController {
13453
13481
  this._grip.linearVelocity = new Vector3();
13454
13482
  this._grip.hasAngularVelocity = false;
13455
13483
  this._grip.angularVelocity = new Vector3();
13484
+ this._grip.eventsEnabled = false;
13456
13485
 
13457
13486
  }
13458
13487
 
@@ -13665,6 +13694,17 @@ class WebXRController {
13665
13694
 
13666
13695
  }
13667
13696
 
13697
+ // grip update event if enabled
13698
+ if ( grip.eventsEnabled ) {
13699
+
13700
+ grip.dispatchEvent( {
13701
+ type: 'gripUpdated',
13702
+ data: inputSource,
13703
+ target: this
13704
+ } );
13705
+
13706
+ }
13707
+
13668
13708
  }
13669
13709
 
13670
13710
  }
@@ -15295,7 +15335,7 @@ class Triangle {
15295
15335
  _v1$5.subVectors( a, b );
15296
15336
 
15297
15337
  // strictly front facing
15298
- return ( _v0$3.cross( _v1$5 ).dot( direction ) < 0 ) ? true : false;
15338
+ return _v0$3.cross( _v1$5 ).dot( direction ) < 0;
15299
15339
 
15300
15340
  }
15301
15341
 
@@ -16627,7 +16667,7 @@ let _id$3 = 0;
16627
16667
  * When working with vector-like data, the `fromBufferAttribute( attribute, index )`
16628
16668
  * helper methods on vector and color class might be helpful. E.g. {@link Vector3#fromBufferAttribute}.
16629
16669
  */
16630
- class BufferAttribute {
16670
+ class BufferAttribute extends EventDispatcher {
16631
16671
 
16632
16672
  /**
16633
16673
  * Constructs a new buffer attribute.
@@ -16638,6 +16678,8 @@ class BufferAttribute {
16638
16678
  */
16639
16679
  constructor( array, itemSize, normalized = false ) {
16640
16680
 
16681
+ super();
16682
+
16641
16683
  if ( Array.isArray( array ) ) {
16642
16684
 
16643
16685
  throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
@@ -17284,6 +17326,15 @@ class BufferAttribute {
17284
17326
 
17285
17327
  }
17286
17328
 
17329
+ /**
17330
+ * Disposes of the buffer attribute. Available only in {@link WebGPURenderer}.
17331
+ */
17332
+ dispose() {
17333
+
17334
+ this.dispatchEvent( { type: 'dispose' } );
17335
+
17336
+ }
17337
+
17287
17338
  }
17288
17339
 
17289
17340
  /**
@@ -23407,12 +23458,12 @@ function checkGeometryIntersection( object, material, raycaster, ray, uv, uv1, n
23407
23458
 
23408
23459
  }
23409
23460
 
23410
- const _basePosition = /*@__PURE__*/ new Vector3();
23461
+ const _baseVector = /*@__PURE__*/ new Vector4();
23411
23462
 
23412
23463
  const _skinIndex = /*@__PURE__*/ new Vector4();
23413
23464
  const _skinWeight = /*@__PURE__*/ new Vector4();
23414
23465
 
23415
- const _vector3 = /*@__PURE__*/ new Vector3();
23466
+ const _vector4 = /*@__PURE__*/ new Vector4();
23416
23467
  const _matrix4 = /*@__PURE__*/ new Matrix4();
23417
23468
  const _vertex = /*@__PURE__*/ new Vector3();
23418
23469
 
@@ -23708,12 +23759,12 @@ class SkinnedMesh extends Mesh {
23708
23759
 
23709
23760
  /**
23710
23761
  * Applies the bone transform associated with the given index to the given
23711
- * vertex position. Returns the updated vector.
23762
+ * vector. Can be used to transform positions or direction vectors by providing
23763
+ * a Vector4 with 1 or 0 in the w component respectively. Returns the updated vector.
23712
23764
  *
23713
23765
  * @param {number} index - The vertex index.
23714
- * @param {Vector3} target - The target object that is used to store the method's result.
23715
- * the skinned mesh's world matrix will be used instead.
23716
- * @return {Vector3} The updated vertex position.
23766
+ * @param {Vector3|Vector4} target - The target object that is used to store the method's result.
23767
+ * @return {Vector3|Vector4} The updated vertex attribute data.
23717
23768
  */
23718
23769
  applyBoneTransform( index, target ) {
23719
23770
 
@@ -23723,9 +23774,19 @@ class SkinnedMesh extends Mesh {
23723
23774
  _skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );
23724
23775
  _skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );
23725
23776
 
23726
- _basePosition.copy( target ).applyMatrix4( this.bindMatrix );
23777
+ if ( target.isVector4 ) {
23778
+
23779
+ _baseVector.copy( target );
23780
+ target.set( 0, 0, 0, 0 );
23727
23781
 
23728
- target.set( 0, 0, 0 );
23782
+ } else {
23783
+
23784
+ _baseVector.set( ...target, 1 );
23785
+ target.set( 0, 0, 0 );
23786
+
23787
+ }
23788
+
23789
+ _baseVector.applyMatrix4( this.bindMatrix );
23729
23790
 
23730
23791
  for ( let i = 0; i < 4; i ++ ) {
23731
23792
 
@@ -23737,12 +23798,19 @@ class SkinnedMesh extends Mesh {
23737
23798
 
23738
23799
  _matrix4.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
23739
23800
 
23740
- target.addScaledVector( _vector3.copy( _basePosition ).applyMatrix4( _matrix4 ), weight );
23801
+ target.addScaledVector( _vector4.copy( _baseVector ).applyMatrix4( _matrix4 ), weight );
23741
23802
 
23742
23803
  }
23743
23804
 
23744
23805
  }
23745
23806
 
23807
+ if ( target.isVector4 ) {
23808
+
23809
+ // ensure the homogenous coordinate remains unchanged after vector operations
23810
+ target.w = _baseVector.w;
23811
+
23812
+ }
23813
+
23746
23814
  return target.applyMatrix4( this.bindMatrixInverse );
23747
23815
 
23748
23816
  }
@@ -24523,10 +24591,19 @@ class InstancedMesh extends Mesh {
24523
24591
  *
24524
24592
  * @param {number} index - The instance index.
24525
24593
  * @param {Color} color - The target object that is used to store the method's result.
24594
+ * @return {Color} A reference to the target color.
24526
24595
  */
24527
24596
  getColorAt( index, color ) {
24528
24597
 
24529
- color.fromArray( this.instanceColor.array, index * 3 );
24598
+ if ( this.instanceColor === null ) {
24599
+
24600
+ return color.setRGB( 1, 1, 1 );
24601
+
24602
+ } else {
24603
+
24604
+ return color.fromArray( this.instanceColor.array, index * 3 );
24605
+
24606
+ }
24530
24607
 
24531
24608
  }
24532
24609
 
@@ -24535,10 +24612,11 @@ class InstancedMesh extends Mesh {
24535
24612
  *
24536
24613
  * @param {number} index - The instance index.
24537
24614
  * @param {Matrix4} matrix - The target object that is used to store the method's result.
24615
+ * @return {Matrix4} A reference to the target matrix.
24538
24616
  */
24539
24617
  getMatrixAt( index, matrix ) {
24540
24618
 
24541
- matrix.fromArray( this.instanceMatrix.array, index * 16 );
24619
+ return matrix.fromArray( this.instanceMatrix.array, index * 16 );
24542
24620
 
24543
24621
  }
24544
24622
 
@@ -24624,6 +24702,7 @@ class InstancedMesh extends Mesh {
24624
24702
  *
24625
24703
  * @param {number} index - The instance index.
24626
24704
  * @param {Color} color - The instance color.
24705
+ * @return {InstancedMesh} A reference to this instanced mesh.
24627
24706
  */
24628
24707
  setColorAt( index, color ) {
24629
24708
 
@@ -24634,19 +24713,22 @@ class InstancedMesh extends Mesh {
24634
24713
  }
24635
24714
 
24636
24715
  color.toArray( this.instanceColor.array, index * 3 );
24716
+ return this;
24637
24717
 
24638
24718
  }
24639
24719
 
24640
24720
  /**
24641
24721
  * Sets the given local transformation matrix to the defined instance. Make sure you set the `needsUpdate` flag of
24642
- * {@link InstancedMesh#instanceMatrix} to `true` after updating all the colors.
24722
+ * {@link InstancedMesh#instanceMatrix} to `true` after updating all the matrices.
24643
24723
  *
24644
24724
  * @param {number} index - The instance index.
24645
24725
  * @param {Matrix4} matrix - The local transformation.
24726
+ * @return {InstancedMesh} A reference to this instanced mesh.
24646
24727
  */
24647
24728
  setMatrixAt( index, matrix ) {
24648
24729
 
24649
24730
  matrix.toArray( this.instanceMatrix.array, index * 16 );
24731
+ return this;
24650
24732
 
24651
24733
  }
24652
24734
 
@@ -24657,6 +24739,7 @@ class InstancedMesh extends Mesh {
24657
24739
  * @param {number} index - The instance index.
24658
24740
  * @param {Mesh} object - A mesh which `morphTargetInfluences` property containing the morph target weights
24659
24741
  * of a single instance.
24742
+ * @return {InstancedMesh} A reference to this instanced mesh.
24660
24743
  */
24661
24744
  setMorphAt( index, object ) {
24662
24745
 
@@ -24687,6 +24770,7 @@ class InstancedMesh extends Mesh {
24687
24770
  array[ dataIndex ] = morphBaseInfluence;
24688
24771
 
24689
24772
  array.set( objectInfluences, dataIndex + 1 );
24773
+ return this;
24690
24774
 
24691
24775
  }
24692
24776
 
@@ -24922,9 +25006,10 @@ class Plane {
24922
25006
  *
24923
25007
  * @param {Line3} line - The line to compute the intersection for.
24924
25008
  * @param {Vector3} target - The target vector that is used to store the method's result.
24925
- * @return {?Vector3} The intersection point.
25009
+ * @param {boolean} [clampToLine=true] - Whether to clamp the intersection to the line segment.
25010
+ * @return {?Vector3} The intersection point. Returns `null` if no intersection is detected.
24926
25011
  */
24927
- intersectLine( line, target ) {
25012
+ intersectLine( line, target, clampToLine = true ) {
24928
25013
 
24929
25014
  const direction = line.delta( _vector1 );
24930
25015
 
@@ -24946,7 +25031,7 @@ class Plane {
24946
25031
 
24947
25032
  const t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
24948
25033
 
24949
- if ( t < 0 || t > 1 ) {
25034
+ if ( ( clampToLine === true ) && ( t < 0 || t > 1 ) ) {
24950
25035
 
24951
25036
  return null;
24952
25037
 
@@ -25866,7 +25951,6 @@ class BatchedMesh extends Mesh {
25866
25951
  this._multiDrawCounts = new Int32Array( maxInstanceCount );
25867
25952
  this._multiDrawStarts = new Int32Array( maxInstanceCount );
25868
25953
  this._multiDrawCount = 0;
25869
- this._multiDrawInstances = null;
25870
25954
 
25871
25955
  // Local matrix per geometry by using data texture
25872
25956
  this._matricesTexture = null;
@@ -26727,7 +26811,23 @@ class BatchedMesh extends Mesh {
26727
26811
  getColorAt( instanceId, color ) {
26728
26812
 
26729
26813
  this.validateInstanceId( instanceId );
26730
- return color.fromArray( this._colorsTexture.image.data, instanceId * 4 );
26814
+ if ( this._colorsTexture === null ) {
26815
+
26816
+ if ( color.isVector4 ) {
26817
+
26818
+ return color.set( 1, 1, 1, 1 );
26819
+
26820
+ } else {
26821
+
26822
+ return color.setRGB( 1, 1, 1 );
26823
+
26824
+ }
26825
+
26826
+ } else {
26827
+
26828
+ return color.fromArray( this._colorsTexture.image.data, instanceId * 4 );
26829
+
26830
+ }
26731
26831
 
26732
26832
  }
26733
26833
 
@@ -28754,6 +28854,77 @@ class CanvasTexture extends Texture {
28754
28854
 
28755
28855
  }
28756
28856
 
28857
+ /**
28858
+ * Creates a texture from an HTML element.
28859
+ *
28860
+ * This is almost the same as the base texture class, except that it sets {@link Texture#needsUpdate}
28861
+ * to `true` immediately and listens for the parent canvas's paint events to trigger updates.
28862
+ *
28863
+ * @augments Texture
28864
+ */
28865
+ class HTMLTexture extends Texture {
28866
+
28867
+ /**
28868
+ * Constructs a new texture.
28869
+ *
28870
+ * @param {HTMLElement} [element] - The HTML element.
28871
+ * @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping.
28872
+ * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value.
28873
+ * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value.
28874
+ * @param {number} [magFilter=LinearFilter] - The mag filter value.
28875
+ * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value.
28876
+ * @param {number} [format=RGBAFormat] - The texture format.
28877
+ * @param {number} [type=UnsignedByteType] - The texture type.
28878
+ * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value.
28879
+ */
28880
+ constructor( element, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
28881
+
28882
+ super( element, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
28883
+
28884
+ /**
28885
+ * This flag can be used for type testing.
28886
+ *
28887
+ * @type {boolean}
28888
+ * @readonly
28889
+ * @default true
28890
+ */
28891
+ this.isHTMLTexture = true;
28892
+ this.generateMipmaps = false;
28893
+
28894
+ this.needsUpdate = true;
28895
+
28896
+ const parent = element ? element.parentNode : null;
28897
+
28898
+ if ( parent !== null && 'requestPaint' in parent ) {
28899
+
28900
+ parent.onpaint = () => {
28901
+
28902
+ this.needsUpdate = true;
28903
+
28904
+ };
28905
+
28906
+ parent.requestPaint();
28907
+
28908
+ }
28909
+
28910
+ }
28911
+
28912
+ dispose() {
28913
+
28914
+ const parent = this.image ? this.image.parentNode : null;
28915
+
28916
+ if ( parent !== null && 'onpaint' in parent ) {
28917
+
28918
+ parent.onpaint = null;
28919
+
28920
+ }
28921
+
28922
+ super.dispose();
28923
+
28924
+ }
28925
+
28926
+ }
28927
+
28757
28928
  /**
28758
28929
  * This class can be used to automatically save the depth information of a
28759
28930
  * rendering into a texture.
@@ -31419,6 +31590,7 @@ function CubicPoly() {
31419
31590
  //
31420
31591
 
31421
31592
  const tmp = /*@__PURE__*/ new Vector3();
31593
+ const tmp2 = /*@__PURE__*/ new Vector3();
31422
31594
  const px = /*@__PURE__*/ new CubicPoly();
31423
31595
  const py = /*@__PURE__*/ new CubicPoly();
31424
31596
  const pz = /*@__PURE__*/ new CubicPoly();
@@ -31543,8 +31715,8 @@ class CatmullRomCurve3 extends Curve {
31543
31715
  } else {
31544
31716
 
31545
31717
  // extrapolate first point
31546
- tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
31547
- p0 = tmp;
31718
+ tmp2.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
31719
+ p0 = tmp2;
31548
31720
 
31549
31721
  }
31550
31722
 
@@ -37127,10 +37299,7 @@ function cloneUniforms( src ) {
37127
37299
 
37128
37300
  const property = src[ u ][ p ];
37129
37301
 
37130
- if ( property && ( property.isColor ||
37131
- property.isMatrix3 || property.isMatrix4 ||
37132
- property.isVector2 || property.isVector3 || property.isVector4 ||
37133
- property.isTexture || property.isQuaternion ) ) {
37302
+ if ( isThreeObject( property ) ) {
37134
37303
 
37135
37304
  if ( property.isRenderTargetTexture ) {
37136
37305
 
@@ -37145,7 +37314,23 @@ function cloneUniforms( src ) {
37145
37314
 
37146
37315
  } else if ( Array.isArray( property ) ) {
37147
37316
 
37148
- dst[ u ][ p ] = property.slice();
37317
+ if ( isThreeObject( property[ 0 ] ) ) {
37318
+
37319
+ const clonedProperty = [];
37320
+
37321
+ for ( let i = 0, l = property.length; i < l; i ++ ) {
37322
+
37323
+ clonedProperty[ i ] = property[ i ].clone();
37324
+
37325
+ }
37326
+
37327
+ dst[ u ][ p ] = clonedProperty;
37328
+
37329
+ } else {
37330
+
37331
+ dst[ u ][ p ] = property.slice();
37332
+
37333
+ }
37149
37334
 
37150
37335
  } else {
37151
37336
 
@@ -37189,6 +37374,15 @@ function mergeUniforms( uniforms ) {
37189
37374
 
37190
37375
  }
37191
37376
 
37377
+ function isThreeObject( property ) {
37378
+
37379
+ return ( property && ( property.isColor ||
37380
+ property.isMatrix3 || property.isMatrix4 ||
37381
+ property.isVector2 || property.isVector3 || property.isVector4 ||
37382
+ property.isTexture || property.isQuaternion ) );
37383
+
37384
+ }
37385
+
37192
37386
  function cloneUniformsGroups( src ) {
37193
37387
 
37194
37388
  const dst = [];
@@ -39083,7 +39277,7 @@ class MeshToonMaterial extends Material {
39083
39277
 
39084
39278
  /**
39085
39279
  * Gradient map for toon shading. It's required to set
39086
- * {@link Texture#minFilter} and {@link Texture#magFilter} to {@linkNearestFilter}
39280
+ * {@link Texture#minFilter} and {@link Texture#magFilter} to {@link NearestFilter}
39087
39281
  * when using this type of texture.
39088
39282
  *
39089
39283
  * @type {?Texture}
@@ -43883,7 +44077,6 @@ class FileLoader extends Loader {
43883
44077
  * @param {function(any)} onLoad - Executed when the loading process has been finished.
43884
44078
  * @param {onProgressCallback} [onProgress] - Executed while the loading is in progress.
43885
44079
  * @param {onErrorCallback} [onError] - Executed when errors occur.
43886
- * @return {any|undefined} The cached resource if available.
43887
44080
  */
43888
44081
  load( url, onLoad, onProgress, onError ) {
43889
44082
 
@@ -43907,7 +44100,7 @@ class FileLoader extends Loader {
43907
44100
 
43908
44101
  }, 0 );
43909
44102
 
43910
- return cached;
44103
+ return;
43911
44104
 
43912
44105
  }
43913
44106
 
@@ -44724,19 +44917,20 @@ class DataTextureLoader extends Loader {
44724
44917
 
44725
44918
  texData = scope.parse( buffer );
44726
44919
 
44727
- } catch ( error ) {
44920
+ } catch ( e ) {
44728
44921
 
44729
44922
  if ( onError !== undefined ) {
44730
44923
 
44731
- onError( error );
44924
+ onError( e );
44732
44925
 
44733
44926
  } else {
44734
44927
 
44735
- error( error );
44736
- return;
44928
+ error( e );
44737
44929
 
44738
44930
  }
44739
44931
 
44932
+ return;
44933
+
44740
44934
  }
44741
44935
 
44742
44936
  if ( texData.image !== undefined ) {
@@ -47470,7 +47664,7 @@ class MaterialLoader extends Loader {
47470
47664
 
47471
47665
  if ( typeof json.vertexColors === 'number' ) {
47472
47666
 
47473
- material.vertexColors = ( json.vertexColors > 0 ) ? true : false;
47667
+ material.vertexColors = json.vertexColors > 0;
47474
47668
 
47475
47669
  } else {
47476
47670
 
@@ -48036,6 +48230,8 @@ class BufferGeometryLoader extends Loader {
48036
48230
 
48037
48231
  }
48038
48232
 
48233
+ const _customGeometries = {};
48234
+
48039
48235
  /**
48040
48236
  * A loader for loading a JSON resource in the [JSON Object/Scene format](https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4).
48041
48237
  * The files are internally loaded via {@link FileLoader}.
@@ -48092,11 +48288,11 @@ class ObjectLoader extends Loader {
48092
48288
 
48093
48289
  json = JSON.parse( text );
48094
48290
 
48095
- } catch ( error ) {
48291
+ } catch ( e ) {
48096
48292
 
48097
- if ( onError !== undefined ) onError( error );
48293
+ if ( onError !== undefined ) onError( e );
48098
48294
 
48099
- error( 'ObjectLoader: Can\'t parse ' + url + '.', error.message );
48295
+ error( 'ObjectLoader: Can\'t parse ' + url + '.', e.message );
48100
48296
 
48101
48297
  return;
48102
48298
 
@@ -48246,6 +48442,20 @@ class ObjectLoader extends Loader {
48246
48442
 
48247
48443
  }
48248
48444
 
48445
+ /**
48446
+ * Registers the given geometry at the internal
48447
+ * geometry library.
48448
+ *
48449
+ * @static
48450
+ * @param {string} type - The geometry type.
48451
+ * @param {BufferGeometry.constructor} geometryClass - The geometry class.
48452
+ */
48453
+ static registerGeometry( type, geometryClass ) {
48454
+
48455
+ _customGeometries[ type ] = geometryClass;
48456
+
48457
+ }
48458
+
48249
48459
  // internals
48250
48460
 
48251
48461
  parseShapes( json ) {
@@ -48326,9 +48536,13 @@ class ObjectLoader extends Loader {
48326
48536
 
48327
48537
  geometry = Geometries[ data.type ].fromJSON( data, shapes );
48328
48538
 
48539
+ } else if ( data.type in _customGeometries ) {
48540
+
48541
+ geometry = _customGeometries[ data.type ].fromJSON( data, shapes );
48542
+
48329
48543
  } else {
48330
48544
 
48331
- warn( `ObjectLoader: Unsupported geometry type "${ data.type }"` );
48545
+ warn( `ObjectLoader: Unknown geometry type "${ data.type }". Use .registerGeometry() before starting the deserialization process.` );
48332
48546
 
48333
48547
  }
48334
48548
 
@@ -48708,6 +48922,7 @@ class ObjectLoader extends Loader {
48708
48922
  if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha;
48709
48923
  if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment;
48710
48924
  if ( data.compareFunction !== undefined ) texture.compareFunction = data.compareFunction;
48925
+ if ( data.normalized !== undefined ) texture.normalized = data.normalized;
48711
48926
 
48712
48927
  if ( data.userData !== undefined ) texture.userData = data.userData;
48713
48928
 
@@ -49337,6 +49552,9 @@ class ImageBitmapLoader extends Loader {
49337
49552
  * Sets the given loader options. The structure of the object must match the `options` parameter of
49338
49553
  * [createImageBitmap](https://developer.mozilla.org/en-US/docs/Web/API/Window/createImageBitmap).
49339
49554
  *
49555
+ * Note: When caching is enabled, the cache key is based on the URL only. Loading the same URL with
49556
+ * different options will return the cached result of the first request.
49557
+ *
49340
49558
  * @param {Object} options - The loader options to set.
49341
49559
  * @return {ImageBitmapLoader} A reference to this image bitmap loader.
49342
49560
  */
@@ -49355,7 +49573,6 @@ class ImageBitmapLoader extends Loader {
49355
49573
  * @param {function(ImageBitmap)} onLoad - Executed when the loading process has been finished.
49356
49574
  * @param {onProgressCallback} onProgress - Unsupported in this loader.
49357
49575
  * @param {onErrorCallback} onError - Executed when errors occur.
49358
- * @return {ImageBitmap|undefined} The image bitmap.
49359
49576
  */
49360
49577
  load( url, onLoad, onProgress, onError ) {
49361
49578
 
@@ -49393,8 +49610,6 @@ class ImageBitmapLoader extends Loader {
49393
49610
 
49394
49611
  scope.manager.itemEnd( url );
49395
49612
 
49396
- return imageBitmap;
49397
-
49398
49613
  }
49399
49614
 
49400
49615
  } );
@@ -49412,7 +49627,7 @@ class ImageBitmapLoader extends Loader {
49412
49627
 
49413
49628
  }, 0 );
49414
49629
 
49415
- return cached;
49630
+ return;
49416
49631
 
49417
49632
  }
49418
49633
 
@@ -49437,8 +49652,6 @@ class ImageBitmapLoader extends Loader {
49437
49652
 
49438
49653
  scope.manager.itemEnd( url );
49439
49654
 
49440
- return imageBitmap;
49441
-
49442
49655
  } ).catch( function ( e ) {
49443
49656
 
49444
49657
  if ( onError ) onError( e );
@@ -49485,7 +49698,7 @@ class AudioContext {
49485
49698
  /**
49486
49699
  * Returns the global native audio context.
49487
49700
  *
49488
- * @return {AudioContext} The native audio context.
49701
+ * @return {Window.AudioContext} The native audio context.
49489
49702
  */
49490
49703
  static getContext() {
49491
49704
 
@@ -49502,7 +49715,7 @@ class AudioContext {
49502
49715
  /**
49503
49716
  * Allows to set the global native audio context from outside.
49504
49717
  *
49505
- * @param {AudioContext} value - The native context to set.
49718
+ * @param {Window.AudioContext} value - The native context to set.
49506
49719
  */
49507
49720
  static setContext( value ) {
49508
49721
 
@@ -49569,11 +49782,21 @@ class AudioLoader extends Loader {
49569
49782
  const bufferCopy = buffer.slice( 0 );
49570
49783
 
49571
49784
  const context = AudioContext.getContext();
49785
+
49786
+ const decodeUrl = url + '#decode';
49787
+ scope.manager.itemStart( decodeUrl ); // prevent loading manager from completing too early, see #33378
49788
+
49572
49789
  context.decodeAudioData( bufferCopy, function ( audioBuffer ) {
49573
49790
 
49574
49791
  onLoad( audioBuffer );
49792
+ scope.manager.itemEnd( decodeUrl );
49793
+
49794
+ } ).catch( function ( e ) {
49575
49795
 
49576
- } ).catch( handleError );
49796
+ handleError( e );
49797
+ scope.manager.itemEnd( decodeUrl );
49798
+
49799
+ } );
49577
49800
 
49578
49801
  } catch ( e ) {
49579
49802
 
@@ -53180,6 +53403,15 @@ class AnimationAction {
53180
53403
 
53181
53404
  const interpolant = tracks[ i ].createInterpolant( null );
53182
53405
  interpolants[ i ] = interpolant;
53406
+
53407
+ // preserve interpolant settings (like tangent data from BezierInterpolant)
53408
+
53409
+ if ( interpolant.settings ) {
53410
+
53411
+ Object.assign( interpolantSettings, interpolant.settings );
53412
+
53413
+ }
53414
+
53183
53415
  interpolant.settings = interpolantSettings;
53184
53416
 
53185
53417
  }
@@ -53986,6 +54218,7 @@ class AnimationAction {
53986
54218
 
53987
54219
  } else {
53988
54220
 
54221
+ this._loopCount = loopCount;
53989
54222
  this.time = time;
53990
54223
 
53991
54224
  }
@@ -54033,7 +54266,7 @@ class AnimationAction {
54033
54266
 
54034
54267
  } else {
54035
54268
 
54036
- settings.endingEnd = WrapAroundEnding;
54269
+ settings.endingEnd = WrapAroundEnding;
54037
54270
 
54038
54271
  }
54039
54272
 
@@ -55738,7 +55971,7 @@ class Clock {
55738
55971
  */
55739
55972
  this.running = false;
55740
55973
 
55741
- warn( 'THREE.Clock: This module has been deprecated. Please use THREE.Timer instead.' ); // @deprecated, r183
55974
+ warn( 'Clock: This module has been deprecated. Please use THREE.Timer instead.' ); // @deprecated, r183
55742
55975
 
55743
55976
  }
55744
55977
 
@@ -56103,6 +56336,19 @@ class Cylindrical {
56103
56336
  */
56104
56337
  class Matrix2 {
56105
56338
 
56339
+ static {
56340
+
56341
+ /**
56342
+ * This flag can be used for type testing.
56343
+ *
56344
+ * @type {boolean}
56345
+ * @readonly
56346
+ * @default true
56347
+ */
56348
+ Matrix2.prototype.isMatrix2 = true;
56349
+
56350
+ }
56351
+
56106
56352
  /**
56107
56353
  * Constructs a new 2x2 matrix. The arguments are supposed to be
56108
56354
  * in row-major order. If no arguments are provided, the constructor
@@ -56115,15 +56361,6 @@ class Matrix2 {
56115
56361
  */
56116
56362
  constructor( n11, n12, n21, n22 ) {
56117
56363
 
56118
- /**
56119
- * This flag can be used for type testing.
56120
- *
56121
- * @type {boolean}
56122
- * @readonly
56123
- * @default true
56124
- */
56125
- Matrix2.prototype.isMatrix2 = true;
56126
-
56127
56364
  /**
56128
56365
  * A column-major list of matrix values.
56129
56366
  *
@@ -56719,6 +56956,9 @@ class Line3 {
56719
56956
  _startEnd.subVectors( this.end, this.start );
56720
56957
 
56721
56958
  const startEnd2 = _startEnd.dot( _startEnd );
56959
+
56960
+ if ( startEnd2 === 0 ) return 0;
56961
+
56722
56962
  const startEnd_startP = _startEnd.dot( _startP );
56723
56963
 
56724
56964
  let t = startEnd_startP / startEnd2;
@@ -59495,6 +59735,7 @@ function WebGLAnimation() {
59495
59735
 
59496
59736
  if ( isAnimating === true ) return;
59497
59737
  if ( animationLoop === null ) return;
59738
+ if ( context === null ) return;
59498
59739
 
59499
59740
  requestId = context.requestAnimationFrame( onAnimationFrame );
59500
59741
 
@@ -59504,7 +59745,7 @@ function WebGLAnimation() {
59504
59745
 
59505
59746
  stop: function () {
59506
59747
 
59507
- context.cancelAnimationFrame( requestId );
59748
+ if ( context !== null ) context.cancelAnimationFrame( requestId );
59508
59749
 
59509
59750
  isAnimating = false;
59510
59751
 
@@ -59825,9 +60066,9 @@ var colorspace_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";
59825
60066
 
59826
60067
  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}";
59827
60068
 
59828
- 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 * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\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";
60069
+ 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";
59829
60070
 
59830
- var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\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";
60071
+ 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";
59831
60072
 
59832
60073
  var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\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\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif";
59833
60074
 
@@ -59851,7 +60092,7 @@ var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor
59851
60092
 
59852
60093
  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";
59853
60094
 
59854
- 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";
60095
+ 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>";
59855
60096
 
59856
60097
  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";
59857
60098
 
@@ -59865,14 +60106,16 @@ var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhong
59865
60106
 
59866
60107
  var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.diffuseContribution = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.metalness = metalnessFactor;\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor;\n\tmaterial.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = vec3( 0.04 );\n\tmaterial.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n\tmaterial.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.0001, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif";
59867
60108
 
59868
- 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\tfloat v = 0.5 / ( gv + gl );\n\t\treturn v;\n\t}\n\tfloat D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n\t\tfloat a2 = alphaT * alphaB;\n\t\thighp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n\t\thighp float v2 = dot( v, v );\n\t\tfloat w2 = a2 / v2;\n\t\treturn RECIPROCAL_PI * a2 * pow2 ( w2 );\n\t}\n#endif\n#ifdef USE_CLEARCOAT\n\tvec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n\t\tvec3 f0 = material.clearcoatF0;\n\t\tfloat f90 = material.clearcoatF90;\n\t\tfloat roughness = material.clearcoatRoughness;\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 f0 = material.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}";
60109
+ 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}";
59869
60110
 
59870
- 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#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
60111
+ 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";
59871
60112
 
59872
60113
  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";
59873
60114
 
59874
60115
  var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\t#if defined( LAMBERT ) || defined( PHONG )\n\t\tirradiance += iblIrradiance;\n\t#endif\n\tRE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif";
59875
60116
 
60117
+ var lightprobes_pars_fragment = "#ifdef USE_LIGHT_PROBES_GRID\nuniform highp sampler3D probesSH;\nuniform vec3 probesMin;\nuniform vec3 probesMax;\nuniform vec3 probesResolution;\nvec3 getLightProbeGridIrradiance( vec3 worldPos, vec3 worldNormal ) {\n\tvec3 res = probesResolution;\n\tvec3 gridRange = probesMax - probesMin;\n\tvec3 resMinusOne = res - 1.0;\n\tvec3 probeSpacing = gridRange / resMinusOne;\n\tvec3 samplePos = worldPos + worldNormal * probeSpacing * 0.5;\n\tvec3 uvw = clamp( ( samplePos - probesMin ) / gridRange, 0.0, 1.0 );\n\tuvw = uvw * resMinusOne / res + 0.5 / res;\n\tfloat nz = res.z;\n\tfloat paddedSlices = nz + 2.0;\n\tfloat atlasDepth = 7.0 * paddedSlices;\n\tfloat uvZBase = uvw.z * nz + 1.0;\n\tvec4 s0 = texture( probesSH, vec3( uvw.xy, ( uvZBase ) / atlasDepth ) );\n\tvec4 s1 = texture( probesSH, vec3( uvw.xy, ( uvZBase + paddedSlices ) / atlasDepth ) );\n\tvec4 s2 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 2.0 * paddedSlices ) / atlasDepth ) );\n\tvec4 s3 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 3.0 * paddedSlices ) / atlasDepth ) );\n\tvec4 s4 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 4.0 * paddedSlices ) / atlasDepth ) );\n\tvec4 s5 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 5.0 * paddedSlices ) / atlasDepth ) );\n\tvec4 s6 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 6.0 * paddedSlices ) / atlasDepth ) );\n\tvec3 c0 = s0.xyz;\n\tvec3 c1 = vec3( s0.w, s1.xy );\n\tvec3 c2 = vec3( s1.zw, s2.x );\n\tvec3 c3 = s2.yzw;\n\tvec3 c4 = s3.xyz;\n\tvec3 c5 = vec3( s3.w, s4.xy );\n\tvec3 c6 = vec3( s4.zw, s5.x );\n\tvec3 c7 = s5.yzw;\n\tvec3 c8 = s6.xyz;\n\tfloat x = worldNormal.x, y = worldNormal.y, z = worldNormal.z;\n\tvec3 result = c0 * 0.886227;\n\tresult += c1 * 2.0 * 0.511664 * y;\n\tresult += c2 * 2.0 * 0.511664 * z;\n\tresult += c3 * 2.0 * 0.511664 * x;\n\tresult += c4 * 2.0 * 0.429043 * x * y;\n\tresult += c5 * 2.0 * 0.429043 * y * z;\n\tresult += c6 * ( 0.743125 * z * z - 0.247708 );\n\tresult += c7 * 2.0 * 0.429043 * x * z;\n\tresult += c8 * 0.429043 * ( x * x - y * y );\n\treturn max( result, vec3( 0.0 ) );\n}\n#endif";
60118
+
59876
60119
  var logdepthbuf_fragment = "#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n\tgl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif";
59877
60120
 
59878
60121
  var logdepthbuf_pars_fragment = "#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif";
@@ -59907,7 +60150,7 @@ var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetB
59907
60150
 
59908
60151
  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#if defined( USE_TANGENT )\n\t\tmat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n #elif defined( USE_NORMALMAP_UV )\n\t mat3 tbn = getTangentFrame( - vViewPosition, normal, vNormalMapUv );\n #elif defined( USE_NORMALMAP_CYLINDRICAL ) || defined( USE_CLEARCOAT_NORMALMAP_CYLINDRICAL ) || (defined( USE_ANISOTROPY ) && !defined( USE_UV1 ) || !defined( USE_UV2 ) && !defined( USE_UV3 ))\n \n #if defined( USE_NORMALMAP_CYLINDRICAL )\n vec2 vNormalMapUv = ( normalMapTransform * vec3( positionBasedUv, 1 ) ).xy;\n #endif\n #if defined( USE_CLEARCOAT_NORMALMAP_CYLINDRICAL )\n vec2 vClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( positionBasedUv, 1 ) ).xy;\n #endif\n vec3 tangent = normalize(cross(normal, mat3(modelViewMatrix) * transpose(mat3(texture3DMatrix)) * vec3(0, 1, 0)));\n vec3 bitangent = cross(tangent, normal);\n \tmat3 tbn = mat3(tangent, bitangent, normal);\n \n\t#elif defined( USE_CLEARCOAT_NORMALMAP_UV )\n\t mat3 tbn = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t#else\n\t mat3 tbn = getTangentFrame( - vViewPosition, normal, vUv );\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#if !defined( USE_CLEARCOAT_NORMALMAP_TRIPLANAR )\n\t\t#ifdef USE_TANGENT\n\t\t\tmat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP_CYLINDRICAL )\n\t\t\tvec3 tangent2 = normalize(cross(normal, mat3(modelViewMatrix) * transpose(mat3(texture3DMatrix)) * vec3(0, 1, 0)));\n\t\t\tvec3 bitangent2 = cross(tangent2, normal);\n\t\t\tmat3 tbn2 = mat3(tangent2, bitangent2, normal);\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP_UV )\n\t\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t\t#else\n\t\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vUv );\n\t\t#endif\n\t\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\t\ttbn2[0] *= faceDirection;\n\t\t\ttbn2[1] *= faceDirection;\n\t\t#endif\n\t#endif\n#endif\nvec3 nonPerturbedNormal = normal;";
59909
60152
 
59910
- var normal_fragment_maps = "#ifdef USE_NORMALMAP_TRIPLANAR\n\tnormal = normalize(normalMatrix * transpose(mat3(texture3DMatrix)) * texture2DTriplanarNormal( normalMap, normalMapTransform, normalScale, normalize(mat3(texture3DMatrix) * vModelNormal.xyz), triplanarCoords, triplanarWeights ));\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#elif defined( 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\tmapN.xy *= normalScale;\n\tnormal = normalize( tbn * mapN );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif";
60153
+ var normal_fragment_maps = "#ifdef USE_NORMALMAP_TRIPLANAR\n\tnormal = normalize(normalMatrix * transpose(mat3(texture3DMatrix)) * texture2DTriplanarNormal( normalMap, normalMapTransform, normalScale, normalize(mat3(texture3DMatrix) * vModelNormal.xyz), triplanarCoords, triplanarWeights ));\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#elif defined( 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";
59911
60154
 
59912
60155
  var normal_pars_fragment = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#if defined( USE_TANGENT )\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif";
59913
60156
 
@@ -59945,7 +60188,7 @@ var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n\tvarying vec4 vSp
59945
60188
 
59946
60189
  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";
59947
60190
 
59948
- var shadowmap_vertex = "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\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";
60191
+ 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";
59949
60192
 
59950
60193
  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}";
59951
60194
 
@@ -59983,7 +60226,7 @@ const fragment$h = "uniform sampler2D t2D;\nuniform float backgroundIntensity;\n
59983
60226
 
59984
60227
  const vertex$g = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}";
59985
60228
 
59986
- const fragment$g = "#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}";
60229
+ const fragment$g = "#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, backgroundRotation * vWorldDirection );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}";
59987
60230
 
59988
60231
  const vertex$f = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}";
59989
60232
 
@@ -60102,6 +60345,7 @@ const ShaderChunk = {
60102
60345
  lights_fragment_begin: lights_fragment_begin,
60103
60346
  lights_fragment_maps: lights_fragment_maps,
60104
60347
  lights_fragment_end: lights_fragment_end,
60348
+ lightprobes_pars_fragment: lightprobes_pars_fragment,
60105
60349
  logdepthbuf_fragment: logdepthbuf_fragment,
60106
60350
  logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
60107
60351
  logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
@@ -60223,7 +60467,6 @@ const UniformsLib = {
60223
60467
 
60224
60468
  envMap: { value: null },
60225
60469
  envMapRotation: { value: /*@__PURE__*/ new Matrix3() },
60226
- flipEnvMap: { value: -1 },
60227
60470
  reflectivity: { value: 1.0 }, // basic, lambert, phong
60228
60471
  ior: { value: 1.5 }, // physical
60229
60472
  refractionRatio: { value: 0.98 }, // basic, lambert, phong
@@ -60384,7 +60627,12 @@ const UniformsLib = {
60384
60627
  } },
60385
60628
 
60386
60629
  ltc_1: { value: null },
60387
- ltc_2: { value: null }
60630
+ ltc_2: { value: null },
60631
+
60632
+ probesSH: { value: null },
60633
+ probesMin: { value: /*@__PURE__*/ new Vector3() },
60634
+ probesMax: { value: /*@__PURE__*/ new Vector3() },
60635
+ probesResolution: { value: /*@__PURE__*/ new Vector3() }
60388
60636
 
60389
60637
  },
60390
60638
 
@@ -60644,7 +60892,6 @@ const ShaderLib = {
60644
60892
 
60645
60893
  uniforms: {
60646
60894
  envMap: { value: null },
60647
- flipEnvMap: { value: -1 },
60648
60895
  backgroundBlurriness: { value: 0 },
60649
60896
  backgroundIntensity: { value: 1 },
60650
60897
  backgroundRotation: { value: /*@__PURE__*/ new Matrix3() }
@@ -60772,8 +61019,10 @@ ShaderLib.physical = {
60772
61019
  };
60773
61020
 
60774
61021
  const _rgb = { r: 0, b: 0, g: 0 };
60775
- const _e1$1 = /*@__PURE__*/ new Euler();
60776
61022
  const _m1$1 = /*@__PURE__*/ new Matrix4();
61023
+ const _m$1 = /*@__PURE__*/ new Matrix3();
61024
+
61025
+ _m$1.set( -1, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 );
60777
61026
 
60778
61027
  function WebGLBackground( renderer, environments, state, objects, alpha, premultipliedAlpha ) {
60779
61028
 
@@ -60891,24 +61140,22 @@ function WebGLBackground( renderer, environments, state, objects, alpha, premult
60891
61140
 
60892
61141
  }
60893
61142
 
60894
- _e1$1.copy( scene.backgroundRotation );
60895
61143
 
60896
- // accommodate left-handed frame
60897
- _e1$1.x *= -1; _e1$1.y *= -1; _e1$1.z *= -1;
61144
+ boxMesh.material.uniforms.envMap.value = background;
61145
+ boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness;
61146
+ boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity;
61147
+
61148
+
61149
+ // note: since the matrix is orthonormal, we can use the more-efficient transpose() in lieu of invert()
61150
+ boxMesh.material.uniforms.backgroundRotation.value.setFromMatrix4( _m1$1.makeRotationFromEuler( scene.backgroundRotation ) ).transpose();
60898
61151
 
60899
61152
  if ( background.isCubeTexture && background.isRenderTargetTexture === false ) {
60900
61153
 
60901
- // environment maps which are not cube render targets or PMREMs follow a different convention
60902
- _e1$1.y *= -1;
60903
- _e1$1.z *= -1;
61154
+ boxMesh.material.uniforms.backgroundRotation.value.premultiply( _m$1 );
60904
61155
 
60905
61156
  }
60906
61157
 
60907
- boxMesh.material.uniforms.envMap.value = background;
60908
- boxMesh.material.uniforms.flipEnvMap.value = ( background.isCubeTexture && background.isRenderTargetTexture === false ) ? -1 : 1;
60909
- boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness;
60910
- boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity;
60911
- boxMesh.material.uniforms.backgroundRotation.value.setFromMatrix4( _m1$1.makeRotationFromEuler( _e1$1 ) );
61158
+
60912
61159
  boxMesh.material.toneMapped = ColorManagement.getTransfer( background.colorSpace ) !== SRGBTransfer;
60913
61160
 
60914
61161
  if ( currentBackground !== background ||
@@ -61768,44 +62015,12 @@ function WebGLBufferRenderer( gl, extensions, info ) {
61768
62015
 
61769
62016
  }
61770
62017
 
61771
- function renderMultiDrawInstances( starts, counts, drawCount, primcount ) {
61772
-
61773
- if ( drawCount === 0 ) return;
61774
-
61775
- const extension = extensions.get( 'WEBGL_multi_draw' );
61776
-
61777
- if ( extension === null ) {
61778
-
61779
- for ( let i = 0; i < starts.length; i ++ ) {
61780
-
61781
- renderInstances( starts[ i ], counts[ i ], primcount[ i ] );
61782
-
61783
- }
61784
-
61785
- } else {
61786
-
61787
- extension.multiDrawArraysInstancedWEBGL( mode, starts, 0, counts, 0, primcount, 0, drawCount );
61788
-
61789
- let elementCount = 0;
61790
- for ( let i = 0; i < drawCount; i ++ ) {
61791
-
61792
- elementCount += counts[ i ] * primcount[ i ];
61793
-
61794
- }
61795
-
61796
- info.update( elementCount, mode, 1 );
61797
-
61798
- }
61799
-
61800
- }
61801
-
61802
62018
  //
61803
62019
 
61804
62020
  this.setMode = setMode;
61805
62021
  this.render = render;
61806
62022
  this.renderInstances = renderInstances;
61807
62023
  this.renderMultiDraw = renderMultiDraw;
61808
- this.renderMultiDrawInstances = renderMultiDrawInstances;
61809
62024
 
61810
62025
  }
61811
62026
 
@@ -61903,6 +62118,12 @@ function WebGLCapabilities( gl, extensions, parameters, utils ) {
61903
62118
  const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;
61904
62119
  const reversedDepthBuffer = parameters.reversedDepthBuffer === true && extensions.has( 'EXT_clip_control' );
61905
62120
 
62121
+ if ( parameters.reversedDepthBuffer === true && reversedDepthBuffer === false ) {
62122
+
62123
+ warn( 'WebGLRenderer: Unable to use reversed depth buffer due to missing EXT_clip_control extension. Fallback to default depth buffer.' );
62124
+
62125
+ }
62126
+
61906
62127
  const maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
61907
62128
  const maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
61908
62129
  const maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );
@@ -63944,37 +64165,6 @@ function WebGLIndexedBufferRenderer( gl, extensions, info ) {
63944
64165
 
63945
64166
  }
63946
64167
 
63947
- function renderMultiDrawInstances( starts, counts, drawCount, primcount ) {
63948
-
63949
- if ( drawCount === 0 ) return;
63950
-
63951
- const extension = extensions.get( 'WEBGL_multi_draw' );
63952
-
63953
- if ( extension === null ) {
63954
-
63955
- for ( let i = 0; i < starts.length; i ++ ) {
63956
-
63957
- renderInstances( starts[ i ] / bytesPerElement, counts[ i ], primcount[ i ] );
63958
-
63959
- }
63960
-
63961
- } else {
63962
-
63963
- extension.multiDrawElementsInstancedWEBGL( mode, counts, 0, type, starts, 0, primcount, 0, drawCount );
63964
-
63965
- let elementCount = 0;
63966
- for ( let i = 0; i < drawCount; i ++ ) {
63967
-
63968
- elementCount += counts[ i ] * primcount[ i ];
63969
-
63970
- }
63971
-
63972
- info.update( elementCount, mode, 1 );
63973
-
63974
- }
63975
-
63976
- }
63977
-
63978
64168
  //
63979
64169
 
63980
64170
  this.setMode = setMode;
@@ -63982,7 +64172,6 @@ function WebGLIndexedBufferRenderer( gl, extensions, info ) {
63982
64172
  this.render = render;
63983
64173
  this.renderInstances = renderInstances;
63984
64174
  this.renderMultiDraw = renderMultiDraw;
63985
- this.renderMultiDrawInstances = renderMultiDrawInstances;
63986
64175
 
63987
64176
  }
63988
64177
 
@@ -64324,7 +64513,8 @@ function WebGLOutput( type, width, height, depth, stencil ) {
64324
64513
  const targetA = new WebGLRenderTarget( width, height, {
64325
64514
  type: type,
64326
64515
  depthBuffer: depth,
64327
- stencilBuffer: stencil
64516
+ stencilBuffer: stencil,
64517
+ depthTexture: depth ? new DepthTexture( width, height ) : undefined
64328
64518
  } );
64329
64519
 
64330
64520
  const targetB = new WebGLRenderTarget( width, height, {
@@ -64545,6 +64735,7 @@ function WebGLOutput( type, width, height, depth, stencil ) {
64545
64735
 
64546
64736
  this.dispose = function () {
64547
64737
 
64738
+ if ( targetA.depthTexture ) targetA.depthTexture.dispose();
64548
64739
  targetA.dispose();
64549
64740
  targetB.dispose();
64550
64741
  geometry.dispose();
@@ -66328,6 +66519,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
66328
66519
  //
66329
66520
 
66330
66521
  parameters.vertexTangents && parameters.flatShading === false ? '#define USE_TANGENT' : '',
66522
+ parameters.vertexNormals ? '#define HAS_NORMAL' : '',
66331
66523
  parameters.vertexColors ? '#define USE_COLOR' : '',
66332
66524
  parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',
66333
66525
  parameters.vertexUv1s ? '#define USE_UV1' : '',
@@ -66464,6 +66656,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
66464
66656
  parameters.normalMapMode === TriPlanarMapping ? '#define USE_NORMALMAP_TRIPLANAR' : parameters.normalMapMode === CylindricalMapping ? '#define USE_NORMALMAP_CYLINDRICAL' : parameters.normalMapMode === UVMapping ? '#define USE_NORMALMAP_UV' : '',
66465
66657
  parameters.normalMapObjectSpace && [ UVMapping, CylindricalMapping ].includes( parameters.normalMapMode ) ? '#define USE_NORMALMAP_OBJECTSPACE' : '',
66466
66658
  parameters.normalMapTangentSpace && [ UVMapping, CylindricalMapping ].includes( parameters.normalMapMode ) ? '#define USE_NORMALMAP_TANGENTSPACE' : '',
66659
+ parameters.packedNormalMap ? '#define USE_PACKED_NORMALMAP' : '',
66467
66660
  parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
66468
66661
 
66469
66662
  parameters.anisotropy ? '#define USE_ANISOTROPY' : '',
@@ -66528,6 +66721,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
66528
66721
 
66529
66722
  parameters.numLightProbes > 0 ? '#define USE_LIGHT_PROBES' : '',
66530
66723
 
66724
+ parameters.numLightProbeGrids > 0 ? '#define USE_LIGHT_PROBES_GRID' : '',
66725
+
66531
66726
  parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '',
66532
66727
  parameters.decodeVideoTextureEmissive ? '#define DECODE_VIDEO_TEXTURE_EMISSIVE' : '',
66533
66728
 
@@ -66923,6 +67118,12 @@ class WebGLShaderStage {
66923
67118
 
66924
67119
  }
66925
67120
 
67121
+ function isPackedRGFormat( format ) {
67122
+
67123
+ return format === RGFormat || format === RG11_EAC_Format || format === RED_GREEN_RGTC2_Format;
67124
+
67125
+ }
67126
+
66926
67127
  function WebGLPrograms( renderer, environments, extensions, capabilities, bindingStates, clipping ) {
66927
67128
 
66928
67129
  const _programLayers = new Layers();
@@ -66963,7 +67164,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
66963
67164
 
66964
67165
  }
66965
67166
 
66966
- function getParameters( material, lights, shadows, scene, object ) {
67167
+ function getParameters( material, lights, shadows, scene, object, lightProbeGrids ) {
66967
67168
 
66968
67169
  const fog = scene.fog;
66969
67170
  const geometry = object.geometry;
@@ -67079,6 +67280,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67079
67280
  const HAS_ALPHAHASH = !! material.alphaHash;
67080
67281
 
67081
67282
  const HAS_OCTAHEDRAL_NORMALS = object.geometry.attributes.normalOctahedral !== undefined;
67283
+ const HAS_VERTEX_NORMALS = geometry.attributes.normal !== undefined || HAS_OCTAHEDRAL_NORMALS;
67082
67284
 
67083
67285
  const HAS_EXTENSIONS = !! material.extensions;
67084
67286
 
@@ -67120,7 +67322,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67120
67322
  instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null,
67121
67323
  instancingMorph: IS_INSTANCEDMESH && object.morphTexture !== null,
67122
67324
 
67123
- outputColorSpace: ( currentRenderTarget === null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace ),
67325
+ outputColorSpace: ( currentRenderTarget === null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : ColorManagement.workingColorSpace ),
67124
67326
  alphaToCoverage: !! material.alphaToCoverage,
67125
67327
 
67126
67328
  map: HAS_MAP,
@@ -67137,6 +67339,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67137
67339
 
67138
67340
  normalMapObjectSpace: HAS_NORMALMAP && material.normalMapType === ObjectSpaceNormalMap,
67139
67341
  normalMapTangentSpace: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap,
67342
+ packedNormalMap: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap && isPackedRGFormat( material.normalMap.format ),
67140
67343
 
67141
67344
  metalnessMap: HAS_METALNESSMAP,
67142
67345
  roughnessMap: HAS_ROUGHNESSMAP,
@@ -67221,6 +67424,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67221
67424
  //
67222
67425
 
67223
67426
  vertexTangents: !! geometry.attributes.tangent && ( HAS_NORMALMAP || HAS_ANISOTROPY ),
67427
+ vertexNormals: HAS_VERTEX_NORMALS,
67224
67428
  vertexColors: material.vertexColors,
67225
67429
  vertexAlphas: material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4,
67226
67430
 
@@ -67232,7 +67436,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67232
67436
 
67233
67437
  flatShading: material.wireframe === false && (
67234
67438
  material.flatShading === true ||
67235
- ( geometry.attributes.normal === undefined && HAS_NORMALMAP === false &&
67439
+ ( HAS_VERTEX_NORMALS === false && HAS_NORMALMAP === false &&
67236
67440
  ( material.isMeshLambertMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isMeshPhysicalMaterial )
67237
67441
  )
67238
67442
  ),
@@ -67263,6 +67467,8 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67263
67467
 
67264
67468
  numLightProbes: lights.numLightProbes,
67265
67469
 
67470
+ numLightProbeGrids: lightProbeGrids.length,
67471
+
67266
67472
  numClippingPlanes: clipping.numPlanes,
67267
67473
  numClipIntersection: clipping.numIntersection,
67268
67474
 
@@ -67459,6 +67665,10 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67459
67665
  _programLayers.enable( 22 );
67460
67666
  if ( parameters.normalOctahedral )
67461
67667
  _programLayers.enable( 23 );
67668
+ if ( parameters.packedNormalMap )
67669
+ _programLayers.enable( 24 );
67670
+ if ( parameters.vertexNormals )
67671
+ _programLayers.enable( 25 );
67462
67672
 
67463
67673
  array.push( _programLayers.mask );
67464
67674
  _programLayers.disableAll();
@@ -67507,6 +67717,8 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67507
67717
  _programLayers.enable( 20 );
67508
67718
  if ( parameters.alphaToCoverage )
67509
67719
  _programLayers.enable( 21 );
67720
+ if ( parameters.numLightProbeGrids > 0 )
67721
+ _programLayers.enable( 22 );
67510
67722
 
67511
67723
  array.push( _programLayers.mask );
67512
67724
 
@@ -68483,6 +68695,7 @@ function WebGLRenderState( extensions ) {
68483
68695
 
68484
68696
  const lightsArray = [];
68485
68697
  const shadowsArray = [];
68698
+ const lightProbeGridArray = [];
68486
68699
 
68487
68700
  function init( camera ) {
68488
68701
 
@@ -68490,6 +68703,7 @@ function WebGLRenderState( extensions ) {
68490
68703
 
68491
68704
  lightsArray.length = 0;
68492
68705
  shadowsArray.length = 0;
68706
+ lightProbeGridArray.length = 0;
68493
68707
 
68494
68708
  }
68495
68709
 
@@ -68505,6 +68719,12 @@ function WebGLRenderState( extensions ) {
68505
68719
 
68506
68720
  }
68507
68721
 
68722
+ function pushLightProbeGrid( volume ) {
68723
+
68724
+ lightProbeGridArray.push( volume );
68725
+
68726
+ }
68727
+
68508
68728
  function setupLights() {
68509
68729
 
68510
68730
  lights.setup( lightsArray );
@@ -68520,12 +68740,14 @@ function WebGLRenderState( extensions ) {
68520
68740
  const state = {
68521
68741
  lightsArray: lightsArray,
68522
68742
  shadowsArray: shadowsArray,
68743
+ lightProbeGridArray: lightProbeGridArray,
68523
68744
 
68524
68745
  camera: null,
68525
68746
 
68526
68747
  lights: lights,
68527
68748
 
68528
- transmissionRenderTarget: {}
68749
+ transmissionRenderTarget: {},
68750
+ textureUnits: 0
68529
68751
  };
68530
68752
 
68531
68753
  return {
@@ -68535,7 +68757,8 @@ function WebGLRenderState( extensions ) {
68535
68757
  setupLightsView: setupLightsView,
68536
68758
 
68537
68759
  pushLight: pushLight,
68538
- pushShadow: pushShadow
68760
+ pushShadow: pushShadow,
68761
+ pushLightProbeGrid: pushLightProbeGrid
68539
68762
  };
68540
68763
 
68541
68764
  }
@@ -69518,6 +69741,7 @@ function WebGLState( gl, extensions ) {
69518
69741
  const uboProgramMap = new WeakMap();
69519
69742
 
69520
69743
  let enabledCapabilities = {};
69744
+ let parameters = {};
69521
69745
 
69522
69746
  let currentBoundFramebuffers = {};
69523
69747
  let currentDrawbuffers = new WeakMap();
@@ -70277,6 +70501,31 @@ function WebGLState( gl, extensions ) {
70277
70501
 
70278
70502
  }
70279
70503
 
70504
+ function getParameter( name ) {
70505
+
70506
+ if ( parameters[ name ] !== undefined ) {
70507
+
70508
+ return parameters[ name ];
70509
+
70510
+ } else {
70511
+
70512
+ return gl.getParameter( name );
70513
+
70514
+ }
70515
+
70516
+ }
70517
+
70518
+ function pixelStorei( name, value ) {
70519
+
70520
+ if ( parameters[ name ] !== value ) {
70521
+
70522
+ gl.pixelStorei( name, value );
70523
+ parameters[ name ] = value;
70524
+
70525
+ }
70526
+
70527
+ }
70528
+
70280
70529
  //
70281
70530
 
70282
70531
  function scissor( scissor ) {
@@ -70393,9 +70642,24 @@ function WebGLState( gl, extensions ) {
70393
70642
  gl.scissor( 0, 0, gl.canvas.width, gl.canvas.height );
70394
70643
  gl.viewport( 0, 0, gl.canvas.width, gl.canvas.height );
70395
70644
 
70645
+ gl.pixelStorei( gl.PACK_ALIGNMENT, 4 );
70646
+ gl.pixelStorei( gl.UNPACK_ALIGNMENT, 4 );
70647
+ gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false );
70648
+ gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false );
70649
+ gl.pixelStorei( gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.BROWSER_DEFAULT_WEBGL );
70650
+ gl.pixelStorei( gl.PACK_ROW_LENGTH, 0 );
70651
+ gl.pixelStorei( gl.PACK_SKIP_PIXELS, 0 );
70652
+ gl.pixelStorei( gl.PACK_SKIP_ROWS, 0 );
70653
+ gl.pixelStorei( gl.UNPACK_ROW_LENGTH, 0 );
70654
+ gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, 0 );
70655
+ gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, 0 );
70656
+ gl.pixelStorei( gl.UNPACK_SKIP_ROWS, 0 );
70657
+ gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, 0 );
70658
+
70396
70659
  // reset internals
70397
70660
 
70398
70661
  enabledCapabilities = {};
70662
+ parameters = {};
70399
70663
 
70400
70664
  currentTextureSlot = null;
70401
70665
  currentBoundTextures = {};
@@ -70469,6 +70733,8 @@ function WebGLState( gl, extensions ) {
70469
70733
  compressedTexImage3D: compressedTexImage3D,
70470
70734
  texImage2D: texImage2D,
70471
70735
  texImage3D: texImage3D,
70736
+ pixelStorei: pixelStorei,
70737
+ getParameter: getParameter,
70472
70738
 
70473
70739
  updateUBOMapping: updateUBOMapping,
70474
70740
  uniformBlockBinding: uniformBlockBinding,
@@ -70496,6 +70762,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70496
70762
 
70497
70763
  const _imageDimensions = new Vector2();
70498
70764
  const _videoTextures = new WeakMap();
70765
+ const _htmlTextures = new Set();
70499
70766
  let _canvas;
70500
70767
 
70501
70768
  const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source
@@ -70610,7 +70877,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70610
70877
 
70611
70878
  }
70612
70879
 
70613
- function getInternalFormat( internalFormatName, glFormat, glType, colorSpace, forceLinearTransfer = false ) {
70880
+ function getInternalFormat( internalFormatName, glFormat, glType, normalized, colorSpace, forceLinearTransfer = false ) {
70614
70881
 
70615
70882
  if ( internalFormatName !== null ) {
70616
70883
 
@@ -70620,6 +70887,20 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70620
70887
 
70621
70888
  }
70622
70889
 
70890
+ let ext_texture_norm16;
70891
+
70892
+ if ( normalized ) {
70893
+
70894
+ ext_texture_norm16 = extensions.get( 'EXT_texture_norm16' );
70895
+
70896
+ if ( ! ext_texture_norm16 ) {
70897
+
70898
+ warn( 'WebGLRenderer: Unable to use normalized textures without EXT_texture_norm16 extension' );
70899
+
70900
+ }
70901
+
70902
+ }
70903
+
70623
70904
  let internalFormat = glFormat;
70624
70905
 
70625
70906
  if ( glFormat === _gl.RED ) {
@@ -70627,6 +70908,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70627
70908
  if ( glType === _gl.FLOAT ) internalFormat = _gl.R32F;
70628
70909
  if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.R16F;
70629
70910
  if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.R8;
70911
+ if ( glType === _gl.UNSIGNED_SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.R16_EXT;
70912
+ if ( glType === _gl.SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.R16_SNORM_EXT;
70630
70913
 
70631
70914
  }
70632
70915
 
@@ -70646,6 +70929,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70646
70929
  if ( glType === _gl.FLOAT ) internalFormat = _gl.RG32F;
70647
70930
  if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RG16F;
70648
70931
  if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.RG8;
70932
+ if ( glType === _gl.UNSIGNED_SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RG16_EXT;
70933
+ if ( glType === _gl.SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RG16_SNORM_EXT;
70649
70934
 
70650
70935
  }
70651
70936
 
@@ -70684,6 +70969,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70684
70969
 
70685
70970
  if ( glFormat === _gl.RGB ) {
70686
70971
 
70972
+ if ( glType === _gl.UNSIGNED_SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RGB16_EXT;
70973
+ if ( glType === _gl.SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RGB16_SNORM_EXT;
70687
70974
  if ( glType === _gl.UNSIGNED_INT_5_9_9_9_REV ) internalFormat = _gl.RGB9_E5;
70688
70975
  if ( glType === _gl.UNSIGNED_INT_10F_11F_11F_REV ) internalFormat = _gl.R11F_G11F_B10F;
70689
70976
 
@@ -70696,6 +70983,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70696
70983
  if ( glType === _gl.FLOAT ) internalFormat = _gl.RGBA32F;
70697
70984
  if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RGBA16F;
70698
70985
  if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( transfer === SRGBTransfer ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
70986
+ if ( glType === _gl.UNSIGNED_SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RGBA16_EXT;
70987
+ if ( glType === _gl.SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RGBA16_SNORM_EXT;
70699
70988
  if ( glType === _gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = _gl.RGBA4;
70700
70989
  if ( glType === _gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = _gl.RGB5_A1;
70701
70990
 
@@ -70797,6 +71086,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70797
71086
 
70798
71087
  }
70799
71088
 
71089
+ if ( texture.isHTMLTexture ) {
71090
+
71091
+ _htmlTextures.delete( texture );
71092
+
71093
+ }
71094
+
70800
71095
  }
70801
71096
 
70802
71097
  function onRenderTargetDispose( event ) {
@@ -70953,6 +71248,18 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70953
71248
 
70954
71249
  }
70955
71250
 
71251
+ function getTextureUnits() {
71252
+
71253
+ return textureUnits;
71254
+
71255
+ }
71256
+
71257
+ function setTextureUnits( value ) {
71258
+
71259
+ textureUnits = value;
71260
+
71261
+ }
71262
+
70956
71263
  function allocateTextureUnit() {
70957
71264
 
70958
71265
  const textureUnit = textureUnits;
@@ -71304,11 +71611,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71304
71611
  // Trim the array to only contain the merged ranges.
71305
71612
  updateRanges.length = mergeIndex + 1;
71306
71613
 
71307
- const currentUnpackRowLen = _gl.getParameter( _gl.UNPACK_ROW_LENGTH );
71308
- const currentUnpackSkipPixels = _gl.getParameter( _gl.UNPACK_SKIP_PIXELS );
71309
- const currentUnpackSkipRows = _gl.getParameter( _gl.UNPACK_SKIP_ROWS );
71614
+ const currentUnpackRowLen = state.getParameter( _gl.UNPACK_ROW_LENGTH );
71615
+ const currentUnpackSkipPixels = state.getParameter( _gl.UNPACK_SKIP_PIXELS );
71616
+ const currentUnpackSkipRows = state.getParameter( _gl.UNPACK_SKIP_ROWS );
71310
71617
 
71311
- _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
71618
+ state.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
71312
71619
 
71313
71620
  for ( let i = 0, l = updateRanges.length; i < l; i ++ ) {
71314
71621
 
@@ -71324,8 +71631,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71324
71631
  const width = pixelCount;
71325
71632
  const height = 1;
71326
71633
 
71327
- _gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, x );
71328
- _gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, y );
71634
+ state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, x );
71635
+ state.pixelStorei( _gl.UNPACK_SKIP_ROWS, y );
71329
71636
 
71330
71637
  state.texSubImage2D( _gl.TEXTURE_2D, 0, x, y, width, height, glFormat, glType, image.data );
71331
71638
 
@@ -71333,9 +71640,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71333
71640
 
71334
71641
  texture.clearUpdateRanges();
71335
71642
 
71336
- _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
71337
- _gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
71338
- _gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
71643
+ state.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
71644
+ state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
71645
+ state.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
71339
71646
 
71340
71647
  }
71341
71648
 
@@ -71359,14 +71666,21 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71359
71666
 
71360
71667
  state.activeTexture( _gl.TEXTURE0 + slot );
71361
71668
 
71362
- const workingPrimaries = ColorManagement.getPrimaries( ColorManagement.workingColorSpace );
71363
- const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries( texture.colorSpace );
71364
- const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL;
71669
+ const isImageBitmap = ( typeof ImageBitmap !== 'undefined' && texture.image instanceof ImageBitmap );
71670
+
71671
+ if ( isImageBitmap === false ) {
71672
+
71673
+ const workingPrimaries = ColorManagement.getPrimaries( ColorManagement.workingColorSpace );
71674
+ const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries( texture.colorSpace );
71675
+ const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL;
71676
+
71677
+ state.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
71678
+ state.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
71679
+ state.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );
71680
+
71681
+ }
71365
71682
 
71366
- _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
71367
- _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
71368
- _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
71369
- _gl.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );
71683
+ state.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
71370
71684
 
71371
71685
  let image = resizeImage( texture.image, false, capabilities.maxTextureSize );
71372
71686
  image = verifyColorSpace( texture, image );
@@ -71374,7 +71688,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71374
71688
  const glFormat = utils.convert( texture.format, texture.colorSpace );
71375
71689
 
71376
71690
  const glType = utils.convert( texture.type );
71377
- let glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace, texture.isVideoTexture );
71691
+ let glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace, texture.isVideoTexture );
71378
71692
 
71379
71693
  setTextureParameters( textureType, texture );
71380
71694
 
@@ -71691,6 +72005,59 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71691
72005
 
71692
72006
  }
71693
72007
 
72008
+ } else if ( texture.isHTMLTexture ) {
72009
+
72010
+ if ( 'texElementImage2D' in _gl ) {
72011
+
72012
+ const canvas = _gl.canvas;
72013
+
72014
+ // Ensure the canvas supports HTML-in-Canvas and the element is a child.
72015
+ if ( ! canvas.hasAttribute( 'layoutsubtree' ) ) {
72016
+
72017
+ canvas.setAttribute( 'layoutsubtree', 'true' );
72018
+
72019
+ }
72020
+
72021
+ if ( image.parentNode !== canvas ) {
72022
+
72023
+ canvas.appendChild( image );
72024
+
72025
+ // Register and set up a shared paint callback for all HTMLTextures.
72026
+ _htmlTextures.add( texture );
72027
+
72028
+ canvas.onpaint = ( event ) => {
72029
+
72030
+ const changed = event.changedElements;
72031
+
72032
+ for ( const t of _htmlTextures ) {
72033
+
72034
+ if ( changed.includes( t.image ) ) {
72035
+
72036
+ t.needsUpdate = true;
72037
+
72038
+ }
72039
+
72040
+ }
72041
+
72042
+ };
72043
+
72044
+ canvas.requestPaint();
72045
+ return;
72046
+
72047
+ }
72048
+
72049
+ const level = 0;
72050
+ const internalFormat = _gl.RGBA;
72051
+ const srcFormat = _gl.RGBA;
72052
+ const srcType = _gl.UNSIGNED_BYTE;
72053
+
72054
+ _gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
72055
+ _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR );
72056
+ _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
72057
+ _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
72058
+
72059
+ }
72060
+
71694
72061
  } else {
71695
72062
 
71696
72063
  // regular Texture (image, video, canvas)
@@ -71794,10 +72161,10 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71794
72161
  const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries( texture.colorSpace );
71795
72162
  const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL;
71796
72163
 
71797
- _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
71798
- _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
71799
- _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
71800
- _gl.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );
72164
+ state.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
72165
+ state.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
72166
+ state.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
72167
+ state.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );
71801
72168
 
71802
72169
  const isCompressed = ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture );
71803
72170
  const isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
@@ -71823,7 +72190,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71823
72190
  const image = cubeImage[ 0 ],
71824
72191
  glFormat = utils.convert( texture.format, texture.colorSpace ),
71825
72192
  glType = utils.convert( texture.type ),
71826
- glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace );
72193
+ glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace );
71827
72194
 
71828
72195
  const useTexStorage = ( texture.isVideoTexture !== true );
71829
72196
  const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true );
@@ -72019,7 +72386,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
72019
72386
 
72020
72387
  const glFormat = utils.convert( texture.format, texture.colorSpace );
72021
72388
  const glType = utils.convert( texture.type );
72022
- const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace );
72389
+ const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace );
72023
72390
  const renderTargetProperties = properties.get( renderTarget );
72024
72391
  const textureProperties = properties.get( texture );
72025
72392
 
@@ -72098,7 +72465,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
72098
72465
 
72099
72466
  const glFormat = utils.convert( texture.format, texture.colorSpace );
72100
72467
  const glType = utils.convert( texture.type );
72101
- const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace );
72468
+ const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace );
72102
72469
 
72103
72470
  if ( useMultisampledRTT( renderTarget ) ) {
72104
72471
 
@@ -72488,7 +72855,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
72488
72855
 
72489
72856
  const glFormat = utils.convert( texture.format, texture.colorSpace );
72490
72857
  const glType = utils.convert( texture.type );
72491
- const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace, renderTarget.isXRRenderTarget === true );
72858
+ const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace, renderTarget.isXRRenderTarget === true );
72492
72859
  const samples = getRenderTargetSamples( renderTarget );
72493
72860
  _gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );
72494
72861
 
@@ -72864,6 +73231,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
72864
73231
 
72865
73232
  this.allocateTextureUnit = allocateTextureUnit;
72866
73233
  this.resetTextureUnits = resetTextureUnits;
73234
+ this.getTextureUnits = getTextureUnits;
73235
+ this.setTextureUnits = setTextureUnits;
72867
73236
 
72868
73237
  this.setTexture2D = setTexture2D;
72869
73238
  this.setTexture2DArray = setTexture2DArray;
@@ -74332,8 +74701,10 @@ class WebXRManager extends EventDispatcher {
74332
74701
 
74333
74702
  }
74334
74703
 
74335
- const _e1 = /*@__PURE__*/ new Euler();
74336
74704
  const _m1 = /*@__PURE__*/ new Matrix4();
74705
+ const _m = /*@__PURE__*/ new Matrix3();
74706
+
74707
+ _m.set( -1, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 );
74337
74708
 
74338
74709
  function WebGLMaterials( renderer, properties ) {
74339
74710
 
@@ -74368,7 +74739,11 @@ function WebGLMaterials( renderer, properties ) {
74368
74739
 
74369
74740
  function refreshMaterialUniforms( uniforms, material, pixelRatio, height, transmissionRenderTarget ) {
74370
74741
 
74371
- if ( material.isMeshBasicMaterial ) {
74742
+ if ( material.isNodeMaterial ) {
74743
+
74744
+ material.uniformsNeedUpdate = false;
74745
+
74746
+ } else if ( material.isMeshBasicMaterial ) {
74372
74747
 
74373
74748
  refreshUniformsCommon( uniforms, material );
74374
74749
 
@@ -74576,23 +74951,16 @@ function WebGLMaterials( renderer, properties ) {
74576
74951
 
74577
74952
  uniforms.envMap.value = envMap;
74578
74953
 
74579
- _e1.copy( envMapRotation );
74954
+ // note: since the matrix is orthonormal, we can use the more-efficient transpose() in lieu of invert()
74955
+ uniforms.envMapRotation.value.setFromMatrix4( _m1.makeRotationFromEuler( envMapRotation ) ).transpose();
74580
74956
 
74581
- // accommodate left-handed frame
74582
- _e1.x *= -1; _e1.y *= -1; _e1.z *= -1;
74583
74957
 
74584
74958
  if ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) {
74585
74959
 
74586
- // environment maps which are not cube render targets or PMREMs follow a different convention
74587
- _e1.y *= -1;
74588
- _e1.z *= -1;
74960
+ uniforms.envMapRotation.value.premultiply( _m );
74589
74961
 
74590
74962
  }
74591
74963
 
74592
- uniforms.envMapRotation.value.setFromMatrix4( _m1.makeRotationFromEuler( _e1 ) );
74593
-
74594
- uniforms.flipEnvMap.value = ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) ? -1 : 1;
74595
-
74596
74964
  uniforms.reflectivity.value = material.reflectivity;
74597
74965
  uniforms.ior.value = material.ior;
74598
74966
  uniforms.refractionRatio.value = material.refractionRatio;
@@ -75082,6 +75450,11 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
75082
75450
  uniform.__data[ 10 ] = value.elements[ 8 ];
75083
75451
  uniform.__data[ 11 ] = 0;
75084
75452
 
75453
+ } else if ( ArrayBuffer.isView( value ) ) {
75454
+
75455
+ // copy the buffer data using "set"
75456
+ uniform.__data.set( new value.constructor( value.buffer, value.byteOffset, uniform.__data.length ) );
75457
+
75085
75458
  } else {
75086
75459
 
75087
75460
  value.toArray( uniform.__data, arrayOffset );
@@ -75117,6 +75490,10 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
75117
75490
 
75118
75491
  cache[ indexString ] = value;
75119
75492
 
75493
+ } else if ( ArrayBuffer.isView( value ) ) {
75494
+
75495
+ cache[ indexString ] = value.slice();
75496
+
75120
75497
  } else {
75121
75498
 
75122
75499
  cache[ indexString ] = value.clone();
@@ -75140,6 +75517,11 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
75140
75517
 
75141
75518
  }
75142
75519
 
75520
+ } else if ( ArrayBuffer.isView( value ) ) {
75521
+
75522
+ // always update the array buffers
75523
+ return true;
75524
+
75143
75525
  } else {
75144
75526
 
75145
75527
  if ( cachedObject.equals( value ) === false ) {
@@ -75280,6 +75662,11 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
75280
75662
 
75281
75663
  warn( 'WebGLRenderer: Texture samplers can not be part of an uniforms group.' );
75282
75664
 
75665
+ } else if ( ArrayBuffer.isView( value ) ) {
75666
+
75667
+ info.boundary = 16;
75668
+ info.storage = value.byteLength;
75669
+
75283
75670
  } else {
75284
75671
 
75285
75672
  warn( 'WebGLRenderer: Unsupported uniform value type.', value );
@@ -75454,6 +75841,7 @@ class WebGLRenderer {
75454
75841
 
75455
75842
  const uintClearColor = new Uint32Array( 4 );
75456
75843
  const intClearColor = new Int32Array( 4 );
75844
+ const objectPosition = new Vector3();
75457
75845
 
75458
75846
  let currentRenderList = null;
75459
75847
  let currentRenderState = null;
@@ -75616,6 +76004,7 @@ class WebGLRenderer {
75616
76004
  const _this = this;
75617
76005
 
75618
76006
  let _isContextLost = false;
76007
+ let _nodesHandler = null;
75619
76008
 
75620
76009
  // internal state cache
75621
76010
 
@@ -76050,7 +76439,7 @@ class WebGLRenderer {
76050
76439
 
76051
76440
  if ( _outputBufferType === UnsignedByteType ) {
76052
76441
 
76053
- console.error( 'THREE.WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType.' );
76442
+ error( 'THREE.WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType.' );
76054
76443
  return;
76055
76444
 
76056
76445
  }
@@ -76061,7 +76450,7 @@ class WebGLRenderer {
76061
76450
 
76062
76451
  if ( effects[ i ].isOutputPass === true ) {
76063
76452
 
76064
- console.warn( 'THREE.WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically.' );
76453
+ warn( 'THREE.WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically.' );
76065
76454
  break;
76066
76455
 
76067
76456
  }
@@ -76321,6 +76710,7 @@ class WebGLRenderer {
76321
76710
  if ( depth ) {
76322
76711
 
76323
76712
  bits |= _gl.DEPTH_BUFFER_BIT;
76713
+ this.state.buffers.depth.setMask( true );
76324
76714
 
76325
76715
  }
76326
76716
 
@@ -76366,6 +76756,20 @@ class WebGLRenderer {
76366
76756
 
76367
76757
  };
76368
76758
 
76759
+ /**
76760
+ * Sets a compatibility node builder for rendering node materials with WebGLRenderer.
76761
+ * This enables using TSL (Three.js Shading Language) node materials to prepare
76762
+ * for migration to WebGPURenderer.
76763
+ *
76764
+ * @param {WebGLNodesHandler} nodesHandler - The node builder instance.
76765
+ */
76766
+ this.setNodesHandler = function ( nodesHandler ) {
76767
+
76768
+ nodesHandler.setRenderer( this );
76769
+ _nodesHandler = nodesHandler;
76770
+
76771
+ };
76772
+
76369
76773
  /**
76370
76774
  * Frees the GPU-related resources allocated by this instance. Call this
76371
76775
  * method whenever this instance is no longer used in your app.
@@ -76601,33 +77005,23 @@ class WebGLRenderer {
76601
77005
 
76602
77006
  if ( object.isBatchedMesh ) {
76603
77007
 
76604
- if ( object._multiDrawInstances !== null ) {
76605
-
76606
- // @deprecated, r174
76607
- warnOnce( 'WebGLRenderer: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection.' );
76608
- renderer.renderMultiDrawInstances( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount, object._multiDrawInstances );
76609
-
76610
- } else {
77008
+ if ( ! extensions.get( 'WEBGL_multi_draw' ) ) {
76611
77009
 
76612
- if ( ! extensions.get( 'WEBGL_multi_draw' ) ) {
77010
+ const starts = object._multiDrawStarts;
77011
+ const counts = object._multiDrawCounts;
77012
+ const drawCount = object._multiDrawCount;
77013
+ const bytesPerElement = index ? attributes.get( index ).bytesPerElement : 1;
77014
+ const uniforms = properties.get( material ).currentProgram.getUniforms();
77015
+ for ( let i = 0; i < drawCount; i ++ ) {
76613
77016
 
76614
- const starts = object._multiDrawStarts;
76615
- const counts = object._multiDrawCounts;
76616
- const drawCount = object._multiDrawCount;
76617
- const bytesPerElement = index ? attributes.get( index ).bytesPerElement : 1;
76618
- const uniforms = properties.get( material ).currentProgram.getUniforms();
76619
- for ( let i = 0; i < drawCount; i ++ ) {
77017
+ uniforms.setValue( _gl, '_gl_DrawID', i );
77018
+ renderer.render( starts[ i ] / bytesPerElement, counts[ i ] );
76620
77019
 
76621
- uniforms.setValue( _gl, '_gl_DrawID', i );
76622
- renderer.render( starts[ i ] / bytesPerElement, counts[ i ] );
76623
-
76624
- }
76625
-
76626
- } else {
77020
+ }
76627
77021
 
76628
- renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );
77022
+ } else {
76629
77023
 
76630
- }
77024
+ renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );
76631
77025
 
76632
77026
  }
76633
77027
 
@@ -76926,6 +77320,13 @@ class WebGLRenderer {
76926
77320
 
76927
77321
  if ( _isContextLost === true ) return;
76928
77322
 
77323
+ // update node builder if available
77324
+ if ( _nodesHandler !== null ) {
77325
+
77326
+ _nodesHandler.renderStart( scene, camera );
77327
+
77328
+ }
77329
+
76929
77330
  // use internal render target for HalfFloatType color buffer (only when tone mapping is enabled)
76930
77331
 
76931
77332
  const isXRPresenting = xr.enabled === true && xr.isPresenting === true;
@@ -76954,6 +77355,7 @@ class WebGLRenderer {
76954
77355
  currentRenderState = renderStates.get( scene, renderStateStack.length );
76955
77356
  currentRenderState.init( camera );
76956
77357
 
77358
+ currentRenderState.state.textureUnits = textures.getTextureUnits();
76957
77359
  renderStateStack.push( currentRenderState );
76958
77360
 
76959
77361
  _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
@@ -77099,6 +77501,8 @@ class WebGLRenderer {
77099
77501
 
77100
77502
  currentRenderState = renderStateStack[ renderStateStack.length - 1 ];
77101
77503
 
77504
+ textures.setTextureUnits( currentRenderState.state.textureUnits );
77505
+
77102
77506
  if ( _clippingEnabled === true ) clipping.setGlobalState( _this.clippingPlanes, currentRenderState.state.camera );
77103
77507
 
77104
77508
  } else {
@@ -77119,6 +77523,12 @@ class WebGLRenderer {
77119
77523
 
77120
77524
  }
77121
77525
 
77526
+ if ( _nodesHandler !== null ) {
77527
+
77528
+ _nodesHandler.renderEnd();
77529
+
77530
+ }
77531
+
77122
77532
  };
77123
77533
 
77124
77534
  function projectObject( object, camera, groupOrder, sortObjects ) {
@@ -77137,6 +77547,10 @@ class WebGLRenderer {
77137
77547
 
77138
77548
  if ( object.autoUpdate === true ) object.update( camera );
77139
77549
 
77550
+ } else if ( object.isLightProbeGrid ) {
77551
+
77552
+ currentRenderState.pushLightProbeGrid( object );
77553
+
77140
77554
  } else if ( object.isLight ) {
77141
77555
 
77142
77556
  currentRenderState.pushLight( object );
@@ -77452,7 +77866,7 @@ class WebGLRenderer {
77452
77866
 
77453
77867
  const lightsStateVersion = lights.state.version;
77454
77868
 
77455
- const parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, object );
77869
+ const parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, object, currentRenderState.state.lightProbeGridArray );
77456
77870
  const programCacheKey = programCache.getProgramCacheKey( parameters );
77457
77871
 
77458
77872
  let programs = materialProperties.programs;
@@ -77495,6 +77909,13 @@ class WebGLRenderer {
77495
77909
 
77496
77910
  parameters.uniforms = programCache.getUniforms( material );
77497
77911
 
77912
+ // Use node builder for node materials if available
77913
+ if ( _nodesHandler !== null && material.isNodeMaterial ) {
77914
+
77915
+ _nodesHandler.build( material, object, parameters );
77916
+
77917
+ }
77918
+
77498
77919
  material.onBeforeCompile( parameters, _this );
77499
77920
 
77500
77921
  program = programCache.acquireProgram( parameters, programCacheKey );
@@ -77544,6 +77965,8 @@ class WebGLRenderer {
77544
77965
 
77545
77966
  }
77546
77967
 
77968
+ materialProperties.lightProbeGrid = currentRenderState.state.lightProbeGridArray.length > 0;
77969
+
77547
77970
  materialProperties.currentProgram = program;
77548
77971
  materialProperties.uniformsList = null;
77549
77972
 
@@ -77587,6 +78010,30 @@ class WebGLRenderer {
77587
78010
 
77588
78011
  }
77589
78012
 
78013
+ function findLightProbeGrid( volumes, object ) {
78014
+
78015
+ if ( volumes.length === 0 ) return null;
78016
+
78017
+ if ( volumes.length === 1 ) {
78018
+
78019
+ return volumes[ 0 ].texture !== null ? volumes[ 0 ] : null;
78020
+
78021
+ }
78022
+
78023
+ objectPosition.setFromMatrixPosition( object.matrixWorld );
78024
+
78025
+ for ( let i = 0, l = volumes.length; i < l; i ++ ) {
78026
+
78027
+ const v = volumes[ i ];
78028
+
78029
+ if ( v.texture !== null && v.boundingBox.containsPoint( objectPosition ) ) return v;
78030
+
78031
+ }
78032
+
78033
+ return null;
78034
+
78035
+ }
78036
+
77590
78037
  function setProgram( camera, scene, geometry, material, object ) {
77591
78038
 
77592
78039
  if ( scene.isScene !== true ) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...
@@ -77595,7 +78042,7 @@ class WebGLRenderer {
77595
78042
 
77596
78043
  const fog = scene.fog;
77597
78044
  const environment = ( material.isMeshStandardMaterial || material.isMeshLambertMaterial || material.isMeshPhongMaterial ) ? scene.environment : null;
77598
- const colorSpace = ( _currentRenderTarget === null ) ? _this.outputColorSpace : ( _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace );
78045
+ const colorSpace = ( _currentRenderTarget === null ) ? _this.outputColorSpace : ( _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.colorSpace : ColorManagement.workingColorSpace );
77599
78046
  const usePMREM = material.isMeshStandardMaterial || ( material.isMeshLambertMaterial && ! material.envMap ) || ( material.isMeshPhongMaterial && ! material.envMap );
77600
78047
  const envMap = environments.get( material.envMap || environment, usePMREM );
77601
78048
  const vertexAlphas = material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4;
@@ -77751,6 +78198,10 @@ class WebGLRenderer {
77751
78198
 
77752
78199
  needsProgramChange = true;
77753
78200
 
78201
+ } else if ( !! materialProperties.lightProbeGrid !== ( currentRenderState.state.lightProbeGridArray.length > 0 ) ) {
78202
+
78203
+ needsProgramChange = true;
78204
+
77754
78205
  }
77755
78206
 
77756
78207
  } else {
@@ -77768,6 +78219,14 @@ class WebGLRenderer {
77768
78219
 
77769
78220
  program = getProgram( material, scene, object );
77770
78221
 
78222
+ // notify the node builder that the program has changed so uniforms and update nodes can
78223
+ // be cached and triggered.
78224
+ if ( _nodesHandler && material.isNodeMaterial ) {
78225
+
78226
+ _nodesHandler.onUpdateProgram( material, program, materialProperties );
78227
+
78228
+ }
78229
+
77771
78230
  }
77772
78231
 
77773
78232
  let refreshProgram = false;
@@ -77793,6 +78252,19 @@ class WebGLRenderer {
77793
78252
 
77794
78253
  }
77795
78254
 
78255
+ if ( materialProperties.needsLights ) {
78256
+
78257
+ const objectVolume = findLightProbeGrid( currentRenderState.state.lightProbeGridArray, object );
78258
+
78259
+ if ( materialProperties.lightProbeGrid !== objectVolume ) {
78260
+
78261
+ materialProperties.lightProbeGrid = objectVolume;
78262
+ refreshMaterial = true;
78263
+
78264
+ }
78265
+
78266
+ }
78267
+
77796
78268
  if ( refreshProgram || _currentCamera !== camera ) {
77797
78269
 
77798
78270
  // common camera uniforms
@@ -77980,6 +78452,19 @@ class WebGLRenderer {
77980
78452
 
77981
78453
  materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, currentRenderState.state.transmissionRenderTarget[ camera.id ] );
77982
78454
 
78455
+ // light probe volume
78456
+
78457
+ if ( materialProperties.needsLights && materialProperties.lightProbeGrid ) {
78458
+
78459
+ const volume = materialProperties.lightProbeGrid;
78460
+
78461
+ m_uniforms.probesSH.value = volume.texture;
78462
+ m_uniforms.probesMin.value.copy( volume.boundingBox.min );
78463
+ m_uniforms.probesMax.value.copy( volume.boundingBox.max );
78464
+ m_uniforms.probesResolution.value.copy( volume.resolution );
78465
+
78466
+ }
78467
+
77983
78468
  WebGLUniforms.upload( _gl, getUniformList( materialProperties ), m_uniforms, textures );
77984
78469
 
77985
78470
  }
@@ -78005,7 +78490,7 @@ class WebGLRenderer {
78005
78490
 
78006
78491
  // UBOs
78007
78492
 
78008
- if ( material.isShaderMaterial || material.isRawShaderMaterial ) {
78493
+ if ( material.uniformsGroups !== undefined ) {
78009
78494
 
78010
78495
  const groups = material.uniformsGroups;
78011
78496
 
@@ -78581,22 +79066,24 @@ class WebGLRenderer {
78581
79066
 
78582
79067
  }
78583
79068
 
78584
- _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
78585
- _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
78586
- _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
79069
+ state.activeTexture( _gl.TEXTURE0 ); // see #33153
79070
+
79071
+ state.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
79072
+ state.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
79073
+ state.pixelStorei( _gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
78587
79074
 
78588
79075
  // used for copying data from cpu
78589
- const currentUnpackRowLen = _gl.getParameter( _gl.UNPACK_ROW_LENGTH );
78590
- const currentUnpackImageHeight = _gl.getParameter( _gl.UNPACK_IMAGE_HEIGHT );
78591
- const currentUnpackSkipPixels = _gl.getParameter( _gl.UNPACK_SKIP_PIXELS );
78592
- const currentUnpackSkipRows = _gl.getParameter( _gl.UNPACK_SKIP_ROWS );
78593
- const currentUnpackSkipImages = _gl.getParameter( _gl.UNPACK_SKIP_IMAGES );
78594
-
78595
- _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
78596
- _gl.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, image.height );
78597
- _gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, minX );
78598
- _gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, minY );
78599
- _gl.pixelStorei( _gl.UNPACK_SKIP_IMAGES, minZ );
79076
+ const currentUnpackRowLen = state.getParameter( _gl.UNPACK_ROW_LENGTH );
79077
+ const currentUnpackImageHeight = state.getParameter( _gl.UNPACK_IMAGE_HEIGHT );
79078
+ const currentUnpackSkipPixels = state.getParameter( _gl.UNPACK_SKIP_PIXELS );
79079
+ const currentUnpackSkipRows = state.getParameter( _gl.UNPACK_SKIP_ROWS );
79080
+ const currentUnpackSkipImages = state.getParameter( _gl.UNPACK_SKIP_IMAGES );
79081
+
79082
+ state.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
79083
+ state.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, image.height );
79084
+ state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, minX );
79085
+ state.pixelStorei( _gl.UNPACK_SKIP_ROWS, minY );
79086
+ state.pixelStorei( _gl.UNPACK_SKIP_IMAGES, minZ );
78600
79087
 
78601
79088
  // set up the src texture
78602
79089
  const isSrc3D = srcTexture.isDataArrayTexture || srcTexture.isData3DTexture;
@@ -78722,11 +79209,11 @@ class WebGLRenderer {
78722
79209
  }
78723
79210
 
78724
79211
  // reset values
78725
- _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
78726
- _gl.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
78727
- _gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
78728
- _gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
78729
- _gl.pixelStorei( _gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
79212
+ state.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
79213
+ state.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
79214
+ state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
79215
+ state.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
79216
+ state.pixelStorei( _gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
78730
79217
 
78731
79218
  // Generate mipmaps only when copying level 0
78732
79219
  if ( dstLevel === 0 && dstTexture.generateMipmaps ) {
@@ -78989,6 +79476,7 @@ exports.GreaterEqualStencilFunc = GreaterEqualStencilFunc;
78989
79476
  exports.GreaterStencilFunc = GreaterStencilFunc;
78990
79477
  exports.GridHelper = GridHelper;
78991
79478
  exports.Group = Group;
79479
+ exports.HTMLTexture = HTMLTexture;
78992
79480
  exports.HalfFloatType = HalfFloatType;
78993
79481
  exports.HemisphereLight = HemisphereLight;
78994
79482
  exports.HemisphereLightHelper = HemisphereLightHelper;