@plastic-software/three 0.183.4 → 0.184.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/build/three.cjs +773 -286
  2. package/build/three.core.js +372 -110
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +426 -180
  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 +19 -3
  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;
@@ -67120,7 +67321,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67120
67321
  instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null,
67121
67322
  instancingMorph: IS_INSTANCEDMESH && object.morphTexture !== null,
67122
67323
 
67123
- outputColorSpace: ( currentRenderTarget === null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace ),
67324
+ outputColorSpace: ( currentRenderTarget === null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : ColorManagement.workingColorSpace ),
67124
67325
  alphaToCoverage: !! material.alphaToCoverage,
67125
67326
 
67126
67327
  map: HAS_MAP,
@@ -67137,6 +67338,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67137
67338
 
67138
67339
  normalMapObjectSpace: HAS_NORMALMAP && material.normalMapType === ObjectSpaceNormalMap,
67139
67340
  normalMapTangentSpace: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap,
67341
+ packedNormalMap: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap && isPackedRGFormat( material.normalMap.format ),
67140
67342
 
67141
67343
  metalnessMap: HAS_METALNESSMAP,
67142
67344
  roughnessMap: HAS_ROUGHNESSMAP,
@@ -67221,6 +67423,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67221
67423
  //
67222
67424
 
67223
67425
  vertexTangents: !! geometry.attributes.tangent && ( HAS_NORMALMAP || HAS_ANISOTROPY ),
67426
+ vertexNormals: !! geometry.attributes.normal,
67224
67427
  vertexColors: material.vertexColors,
67225
67428
  vertexAlphas: material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4,
67226
67429
 
@@ -67263,6 +67466,8 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67263
67466
 
67264
67467
  numLightProbes: lights.numLightProbes,
67265
67468
 
67469
+ numLightProbeGrids: lightProbeGrids.length,
67470
+
67266
67471
  numClippingPlanes: clipping.numPlanes,
67267
67472
  numClipIntersection: clipping.numIntersection,
67268
67473
 
@@ -67459,6 +67664,10 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67459
67664
  _programLayers.enable( 22 );
67460
67665
  if ( parameters.normalOctahedral )
67461
67666
  _programLayers.enable( 23 );
67667
+ if ( parameters.packedNormalMap )
67668
+ _programLayers.enable( 24 );
67669
+ if ( parameters.vertexNormals )
67670
+ _programLayers.enable( 25 );
67462
67671
 
67463
67672
  array.push( _programLayers.mask );
67464
67673
  _programLayers.disableAll();
@@ -67507,6 +67716,8 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
67507
67716
  _programLayers.enable( 20 );
67508
67717
  if ( parameters.alphaToCoverage )
67509
67718
  _programLayers.enable( 21 );
67719
+ if ( parameters.numLightProbeGrids > 0 )
67720
+ _programLayers.enable( 22 );
67510
67721
 
67511
67722
  array.push( _programLayers.mask );
67512
67723
 
@@ -68483,6 +68694,7 @@ function WebGLRenderState( extensions ) {
68483
68694
 
68484
68695
  const lightsArray = [];
68485
68696
  const shadowsArray = [];
68697
+ const lightProbeGridArray = [];
68486
68698
 
68487
68699
  function init( camera ) {
68488
68700
 
@@ -68490,6 +68702,7 @@ function WebGLRenderState( extensions ) {
68490
68702
 
68491
68703
  lightsArray.length = 0;
68492
68704
  shadowsArray.length = 0;
68705
+ lightProbeGridArray.length = 0;
68493
68706
 
68494
68707
  }
68495
68708
 
@@ -68505,6 +68718,12 @@ function WebGLRenderState( extensions ) {
68505
68718
 
68506
68719
  }
68507
68720
 
68721
+ function pushLightProbeGrid( volume ) {
68722
+
68723
+ lightProbeGridArray.push( volume );
68724
+
68725
+ }
68726
+
68508
68727
  function setupLights() {
68509
68728
 
68510
68729
  lights.setup( lightsArray );
@@ -68520,12 +68739,14 @@ function WebGLRenderState( extensions ) {
68520
68739
  const state = {
68521
68740
  lightsArray: lightsArray,
68522
68741
  shadowsArray: shadowsArray,
68742
+ lightProbeGridArray: lightProbeGridArray,
68523
68743
 
68524
68744
  camera: null,
68525
68745
 
68526
68746
  lights: lights,
68527
68747
 
68528
- transmissionRenderTarget: {}
68748
+ transmissionRenderTarget: {},
68749
+ textureUnits: 0
68529
68750
  };
68530
68751
 
68531
68752
  return {
@@ -68535,7 +68756,8 @@ function WebGLRenderState( extensions ) {
68535
68756
  setupLightsView: setupLightsView,
68536
68757
 
68537
68758
  pushLight: pushLight,
68538
- pushShadow: pushShadow
68759
+ pushShadow: pushShadow,
68760
+ pushLightProbeGrid: pushLightProbeGrid
68539
68761
  };
68540
68762
 
68541
68763
  }
@@ -69518,6 +69740,7 @@ function WebGLState( gl, extensions ) {
69518
69740
  const uboProgramMap = new WeakMap();
69519
69741
 
69520
69742
  let enabledCapabilities = {};
69743
+ let parameters = {};
69521
69744
 
69522
69745
  let currentBoundFramebuffers = {};
69523
69746
  let currentDrawbuffers = new WeakMap();
@@ -70277,6 +70500,31 @@ function WebGLState( gl, extensions ) {
70277
70500
 
70278
70501
  }
70279
70502
 
70503
+ function getParameter( name ) {
70504
+
70505
+ if ( parameters[ name ] !== undefined ) {
70506
+
70507
+ return parameters[ name ];
70508
+
70509
+ } else {
70510
+
70511
+ return gl.getParameter( name );
70512
+
70513
+ }
70514
+
70515
+ }
70516
+
70517
+ function pixelStorei( name, value ) {
70518
+
70519
+ if ( parameters[ name ] !== value ) {
70520
+
70521
+ gl.pixelStorei( name, value );
70522
+ parameters[ name ] = value;
70523
+
70524
+ }
70525
+
70526
+ }
70527
+
70280
70528
  //
70281
70529
 
70282
70530
  function scissor( scissor ) {
@@ -70393,9 +70641,24 @@ function WebGLState( gl, extensions ) {
70393
70641
  gl.scissor( 0, 0, gl.canvas.width, gl.canvas.height );
70394
70642
  gl.viewport( 0, 0, gl.canvas.width, gl.canvas.height );
70395
70643
 
70644
+ gl.pixelStorei( gl.PACK_ALIGNMENT, 4 );
70645
+ gl.pixelStorei( gl.UNPACK_ALIGNMENT, 4 );
70646
+ gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false );
70647
+ gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false );
70648
+ gl.pixelStorei( gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.BROWSER_DEFAULT_WEBGL );
70649
+ gl.pixelStorei( gl.PACK_ROW_LENGTH, 0 );
70650
+ gl.pixelStorei( gl.PACK_SKIP_PIXELS, 0 );
70651
+ gl.pixelStorei( gl.PACK_SKIP_ROWS, 0 );
70652
+ gl.pixelStorei( gl.UNPACK_ROW_LENGTH, 0 );
70653
+ gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, 0 );
70654
+ gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, 0 );
70655
+ gl.pixelStorei( gl.UNPACK_SKIP_ROWS, 0 );
70656
+ gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, 0 );
70657
+
70396
70658
  // reset internals
70397
70659
 
70398
70660
  enabledCapabilities = {};
70661
+ parameters = {};
70399
70662
 
70400
70663
  currentTextureSlot = null;
70401
70664
  currentBoundTextures = {};
@@ -70469,6 +70732,8 @@ function WebGLState( gl, extensions ) {
70469
70732
  compressedTexImage3D: compressedTexImage3D,
70470
70733
  texImage2D: texImage2D,
70471
70734
  texImage3D: texImage3D,
70735
+ pixelStorei: pixelStorei,
70736
+ getParameter: getParameter,
70472
70737
 
70473
70738
  updateUBOMapping: updateUBOMapping,
70474
70739
  uniformBlockBinding: uniformBlockBinding,
@@ -70496,6 +70761,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70496
70761
 
70497
70762
  const _imageDimensions = new Vector2();
70498
70763
  const _videoTextures = new WeakMap();
70764
+ const _htmlTextures = new Set();
70499
70765
  let _canvas;
70500
70766
 
70501
70767
  const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source
@@ -70610,7 +70876,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70610
70876
 
70611
70877
  }
70612
70878
 
70613
- function getInternalFormat( internalFormatName, glFormat, glType, colorSpace, forceLinearTransfer = false ) {
70879
+ function getInternalFormat( internalFormatName, glFormat, glType, normalized, colorSpace, forceLinearTransfer = false ) {
70614
70880
 
70615
70881
  if ( internalFormatName !== null ) {
70616
70882
 
@@ -70620,6 +70886,20 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70620
70886
 
70621
70887
  }
70622
70888
 
70889
+ let ext_texture_norm16;
70890
+
70891
+ if ( normalized ) {
70892
+
70893
+ ext_texture_norm16 = extensions.get( 'EXT_texture_norm16' );
70894
+
70895
+ if ( ! ext_texture_norm16 ) {
70896
+
70897
+ warn( 'WebGLRenderer: Unable to use normalized textures without EXT_texture_norm16 extension' );
70898
+
70899
+ }
70900
+
70901
+ }
70902
+
70623
70903
  let internalFormat = glFormat;
70624
70904
 
70625
70905
  if ( glFormat === _gl.RED ) {
@@ -70627,6 +70907,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70627
70907
  if ( glType === _gl.FLOAT ) internalFormat = _gl.R32F;
70628
70908
  if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.R16F;
70629
70909
  if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.R8;
70910
+ if ( glType === _gl.UNSIGNED_SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.R16_EXT;
70911
+ if ( glType === _gl.SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.R16_SNORM_EXT;
70630
70912
 
70631
70913
  }
70632
70914
 
@@ -70646,6 +70928,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70646
70928
  if ( glType === _gl.FLOAT ) internalFormat = _gl.RG32F;
70647
70929
  if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RG16F;
70648
70930
  if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.RG8;
70931
+ if ( glType === _gl.UNSIGNED_SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RG16_EXT;
70932
+ if ( glType === _gl.SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RG16_SNORM_EXT;
70649
70933
 
70650
70934
  }
70651
70935
 
@@ -70684,6 +70968,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70684
70968
 
70685
70969
  if ( glFormat === _gl.RGB ) {
70686
70970
 
70971
+ if ( glType === _gl.UNSIGNED_SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RGB16_EXT;
70972
+ if ( glType === _gl.SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RGB16_SNORM_EXT;
70687
70973
  if ( glType === _gl.UNSIGNED_INT_5_9_9_9_REV ) internalFormat = _gl.RGB9_E5;
70688
70974
  if ( glType === _gl.UNSIGNED_INT_10F_11F_11F_REV ) internalFormat = _gl.R11F_G11F_B10F;
70689
70975
 
@@ -70696,6 +70982,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70696
70982
  if ( glType === _gl.FLOAT ) internalFormat = _gl.RGBA32F;
70697
70983
  if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RGBA16F;
70698
70984
  if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( transfer === SRGBTransfer ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
70985
+ if ( glType === _gl.UNSIGNED_SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RGBA16_EXT;
70986
+ if ( glType === _gl.SHORT && ext_texture_norm16 ) internalFormat = ext_texture_norm16.RGBA16_SNORM_EXT;
70699
70987
  if ( glType === _gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = _gl.RGBA4;
70700
70988
  if ( glType === _gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = _gl.RGB5_A1;
70701
70989
 
@@ -70797,6 +71085,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70797
71085
 
70798
71086
  }
70799
71087
 
71088
+ if ( texture.isHTMLTexture ) {
71089
+
71090
+ _htmlTextures.delete( texture );
71091
+
71092
+ }
71093
+
70800
71094
  }
70801
71095
 
70802
71096
  function onRenderTargetDispose( event ) {
@@ -70953,6 +71247,18 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
70953
71247
 
70954
71248
  }
70955
71249
 
71250
+ function getTextureUnits() {
71251
+
71252
+ return textureUnits;
71253
+
71254
+ }
71255
+
71256
+ function setTextureUnits( value ) {
71257
+
71258
+ textureUnits = value;
71259
+
71260
+ }
71261
+
70956
71262
  function allocateTextureUnit() {
70957
71263
 
70958
71264
  const textureUnit = textureUnits;
@@ -71304,11 +71610,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71304
71610
  // Trim the array to only contain the merged ranges.
71305
71611
  updateRanges.length = mergeIndex + 1;
71306
71612
 
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 );
71613
+ const currentUnpackRowLen = state.getParameter( _gl.UNPACK_ROW_LENGTH );
71614
+ const currentUnpackSkipPixels = state.getParameter( _gl.UNPACK_SKIP_PIXELS );
71615
+ const currentUnpackSkipRows = state.getParameter( _gl.UNPACK_SKIP_ROWS );
71310
71616
 
71311
- _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
71617
+ state.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
71312
71618
 
71313
71619
  for ( let i = 0, l = updateRanges.length; i < l; i ++ ) {
71314
71620
 
@@ -71324,8 +71630,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71324
71630
  const width = pixelCount;
71325
71631
  const height = 1;
71326
71632
 
71327
- _gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, x );
71328
- _gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, y );
71633
+ state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, x );
71634
+ state.pixelStorei( _gl.UNPACK_SKIP_ROWS, y );
71329
71635
 
71330
71636
  state.texSubImage2D( _gl.TEXTURE_2D, 0, x, y, width, height, glFormat, glType, image.data );
71331
71637
 
@@ -71333,9 +71639,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71333
71639
 
71334
71640
  texture.clearUpdateRanges();
71335
71641
 
71336
- _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
71337
- _gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
71338
- _gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
71642
+ state.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
71643
+ state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
71644
+ state.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
71339
71645
 
71340
71646
  }
71341
71647
 
@@ -71359,14 +71665,21 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71359
71665
 
71360
71666
  state.activeTexture( _gl.TEXTURE0 + slot );
71361
71667
 
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;
71668
+ const isImageBitmap = ( typeof ImageBitmap !== 'undefined' && texture.image instanceof ImageBitmap );
71669
+
71670
+ if ( isImageBitmap === false ) {
71671
+
71672
+ const workingPrimaries = ColorManagement.getPrimaries( ColorManagement.workingColorSpace );
71673
+ const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries( texture.colorSpace );
71674
+ const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL;
71675
+
71676
+ state.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
71677
+ state.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
71678
+ state.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );
71679
+
71680
+ }
71365
71681
 
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 );
71682
+ state.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
71370
71683
 
71371
71684
  let image = resizeImage( texture.image, false, capabilities.maxTextureSize );
71372
71685
  image = verifyColorSpace( texture, image );
@@ -71374,7 +71687,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71374
71687
  const glFormat = utils.convert( texture.format, texture.colorSpace );
71375
71688
 
71376
71689
  const glType = utils.convert( texture.type );
71377
- let glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace, texture.isVideoTexture );
71690
+ let glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace, texture.isVideoTexture );
71378
71691
 
71379
71692
  setTextureParameters( textureType, texture );
71380
71693
 
@@ -71691,6 +72004,59 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71691
72004
 
71692
72005
  }
71693
72006
 
72007
+ } else if ( texture.isHTMLTexture ) {
72008
+
72009
+ if ( 'texElementImage2D' in _gl ) {
72010
+
72011
+ const canvas = _gl.canvas;
72012
+
72013
+ // Ensure the canvas supports HTML-in-Canvas and the element is a child.
72014
+ if ( ! canvas.hasAttribute( 'layoutsubtree' ) ) {
72015
+
72016
+ canvas.setAttribute( 'layoutsubtree', 'true' );
72017
+
72018
+ }
72019
+
72020
+ if ( image.parentNode !== canvas ) {
72021
+
72022
+ canvas.appendChild( image );
72023
+
72024
+ // Register and set up a shared paint callback for all HTMLTextures.
72025
+ _htmlTextures.add( texture );
72026
+
72027
+ canvas.onpaint = ( event ) => {
72028
+
72029
+ const changed = event.changedElements;
72030
+
72031
+ for ( const t of _htmlTextures ) {
72032
+
72033
+ if ( changed.includes( t.image ) ) {
72034
+
72035
+ t.needsUpdate = true;
72036
+
72037
+ }
72038
+
72039
+ }
72040
+
72041
+ };
72042
+
72043
+ canvas.requestPaint();
72044
+ return;
72045
+
72046
+ }
72047
+
72048
+ const level = 0;
72049
+ const internalFormat = _gl.RGBA;
72050
+ const srcFormat = _gl.RGBA;
72051
+ const srcType = _gl.UNSIGNED_BYTE;
72052
+
72053
+ _gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
72054
+ _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR );
72055
+ _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
72056
+ _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
72057
+
72058
+ }
72059
+
71694
72060
  } else {
71695
72061
 
71696
72062
  // regular Texture (image, video, canvas)
@@ -71794,10 +72160,10 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71794
72160
  const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries( texture.colorSpace );
71795
72161
  const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL;
71796
72162
 
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 );
72163
+ state.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
72164
+ state.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
72165
+ state.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
72166
+ state.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );
71801
72167
 
71802
72168
  const isCompressed = ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture );
71803
72169
  const isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
@@ -71823,7 +72189,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
71823
72189
  const image = cubeImage[ 0 ],
71824
72190
  glFormat = utils.convert( texture.format, texture.colorSpace ),
71825
72191
  glType = utils.convert( texture.type ),
71826
- glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace );
72192
+ glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace );
71827
72193
 
71828
72194
  const useTexStorage = ( texture.isVideoTexture !== true );
71829
72195
  const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true );
@@ -72019,7 +72385,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
72019
72385
 
72020
72386
  const glFormat = utils.convert( texture.format, texture.colorSpace );
72021
72387
  const glType = utils.convert( texture.type );
72022
- const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace );
72388
+ const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace );
72023
72389
  const renderTargetProperties = properties.get( renderTarget );
72024
72390
  const textureProperties = properties.get( texture );
72025
72391
 
@@ -72098,7 +72464,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
72098
72464
 
72099
72465
  const glFormat = utils.convert( texture.format, texture.colorSpace );
72100
72466
  const glType = utils.convert( texture.type );
72101
- const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace );
72467
+ const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace );
72102
72468
 
72103
72469
  if ( useMultisampledRTT( renderTarget ) ) {
72104
72470
 
@@ -72488,7 +72854,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
72488
72854
 
72489
72855
  const glFormat = utils.convert( texture.format, texture.colorSpace );
72490
72856
  const glType = utils.convert( texture.type );
72491
- const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace, renderTarget.isXRRenderTarget === true );
72857
+ const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace, renderTarget.isXRRenderTarget === true );
72492
72858
  const samples = getRenderTargetSamples( renderTarget );
72493
72859
  _gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );
72494
72860
 
@@ -72864,6 +73230,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
72864
73230
 
72865
73231
  this.allocateTextureUnit = allocateTextureUnit;
72866
73232
  this.resetTextureUnits = resetTextureUnits;
73233
+ this.getTextureUnits = getTextureUnits;
73234
+ this.setTextureUnits = setTextureUnits;
72867
73235
 
72868
73236
  this.setTexture2D = setTexture2D;
72869
73237
  this.setTexture2DArray = setTexture2DArray;
@@ -74332,8 +74700,10 @@ class WebXRManager extends EventDispatcher {
74332
74700
 
74333
74701
  }
74334
74702
 
74335
- const _e1 = /*@__PURE__*/ new Euler();
74336
74703
  const _m1 = /*@__PURE__*/ new Matrix4();
74704
+ const _m = /*@__PURE__*/ new Matrix3();
74705
+
74706
+ _m.set( -1, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 );
74337
74707
 
74338
74708
  function WebGLMaterials( renderer, properties ) {
74339
74709
 
@@ -74368,7 +74738,11 @@ function WebGLMaterials( renderer, properties ) {
74368
74738
 
74369
74739
  function refreshMaterialUniforms( uniforms, material, pixelRatio, height, transmissionRenderTarget ) {
74370
74740
 
74371
- if ( material.isMeshBasicMaterial ) {
74741
+ if ( material.isNodeMaterial ) {
74742
+
74743
+ material.uniformsNeedUpdate = false;
74744
+
74745
+ } else if ( material.isMeshBasicMaterial ) {
74372
74746
 
74373
74747
  refreshUniformsCommon( uniforms, material );
74374
74748
 
@@ -74576,23 +74950,16 @@ function WebGLMaterials( renderer, properties ) {
74576
74950
 
74577
74951
  uniforms.envMap.value = envMap;
74578
74952
 
74579
- _e1.copy( envMapRotation );
74953
+ // note: since the matrix is orthonormal, we can use the more-efficient transpose() in lieu of invert()
74954
+ uniforms.envMapRotation.value.setFromMatrix4( _m1.makeRotationFromEuler( envMapRotation ) ).transpose();
74580
74955
 
74581
- // accommodate left-handed frame
74582
- _e1.x *= -1; _e1.y *= -1; _e1.z *= -1;
74583
74956
 
74584
74957
  if ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) {
74585
74958
 
74586
- // environment maps which are not cube render targets or PMREMs follow a different convention
74587
- _e1.y *= -1;
74588
- _e1.z *= -1;
74959
+ uniforms.envMapRotation.value.premultiply( _m );
74589
74960
 
74590
74961
  }
74591
74962
 
74592
- uniforms.envMapRotation.value.setFromMatrix4( _m1.makeRotationFromEuler( _e1 ) );
74593
-
74594
- uniforms.flipEnvMap.value = ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) ? -1 : 1;
74595
-
74596
74963
  uniforms.reflectivity.value = material.reflectivity;
74597
74964
  uniforms.ior.value = material.ior;
74598
74965
  uniforms.refractionRatio.value = material.refractionRatio;
@@ -75082,6 +75449,11 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
75082
75449
  uniform.__data[ 10 ] = value.elements[ 8 ];
75083
75450
  uniform.__data[ 11 ] = 0;
75084
75451
 
75452
+ } else if ( ArrayBuffer.isView( value ) ) {
75453
+
75454
+ // copy the buffer data using "set"
75455
+ uniform.__data.set( new value.constructor( value.buffer, value.byteOffset, uniform.__data.length ) );
75456
+
75085
75457
  } else {
75086
75458
 
75087
75459
  value.toArray( uniform.__data, arrayOffset );
@@ -75117,6 +75489,10 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
75117
75489
 
75118
75490
  cache[ indexString ] = value;
75119
75491
 
75492
+ } else if ( ArrayBuffer.isView( value ) ) {
75493
+
75494
+ cache[ indexString ] = value.slice();
75495
+
75120
75496
  } else {
75121
75497
 
75122
75498
  cache[ indexString ] = value.clone();
@@ -75140,6 +75516,11 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
75140
75516
 
75141
75517
  }
75142
75518
 
75519
+ } else if ( ArrayBuffer.isView( value ) ) {
75520
+
75521
+ // always update the array buffers
75522
+ return true;
75523
+
75143
75524
  } else {
75144
75525
 
75145
75526
  if ( cachedObject.equals( value ) === false ) {
@@ -75280,6 +75661,11 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
75280
75661
 
75281
75662
  warn( 'WebGLRenderer: Texture samplers can not be part of an uniforms group.' );
75282
75663
 
75664
+ } else if ( ArrayBuffer.isView( value ) ) {
75665
+
75666
+ info.boundary = 16;
75667
+ info.storage = value.byteLength;
75668
+
75283
75669
  } else {
75284
75670
 
75285
75671
  warn( 'WebGLRenderer: Unsupported uniform value type.', value );
@@ -75454,6 +75840,7 @@ class WebGLRenderer {
75454
75840
 
75455
75841
  const uintClearColor = new Uint32Array( 4 );
75456
75842
  const intClearColor = new Int32Array( 4 );
75843
+ const objectPosition = new Vector3();
75457
75844
 
75458
75845
  let currentRenderList = null;
75459
75846
  let currentRenderState = null;
@@ -75616,6 +76003,7 @@ class WebGLRenderer {
75616
76003
  const _this = this;
75617
76004
 
75618
76005
  let _isContextLost = false;
76006
+ let _nodesHandler = null;
75619
76007
 
75620
76008
  // internal state cache
75621
76009
 
@@ -76050,7 +76438,7 @@ class WebGLRenderer {
76050
76438
 
76051
76439
  if ( _outputBufferType === UnsignedByteType ) {
76052
76440
 
76053
- console.error( 'THREE.WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType.' );
76441
+ error( 'THREE.WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType.' );
76054
76442
  return;
76055
76443
 
76056
76444
  }
@@ -76061,7 +76449,7 @@ class WebGLRenderer {
76061
76449
 
76062
76450
  if ( effects[ i ].isOutputPass === true ) {
76063
76451
 
76064
- console.warn( 'THREE.WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically.' );
76452
+ warn( 'THREE.WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically.' );
76065
76453
  break;
76066
76454
 
76067
76455
  }
@@ -76321,6 +76709,7 @@ class WebGLRenderer {
76321
76709
  if ( depth ) {
76322
76710
 
76323
76711
  bits |= _gl.DEPTH_BUFFER_BIT;
76712
+ this.state.buffers.depth.setMask( true );
76324
76713
 
76325
76714
  }
76326
76715
 
@@ -76366,6 +76755,20 @@ class WebGLRenderer {
76366
76755
 
76367
76756
  };
76368
76757
 
76758
+ /**
76759
+ * Sets a compatibility node builder for rendering node materials with WebGLRenderer.
76760
+ * This enables using TSL (Three.js Shading Language) node materials to prepare
76761
+ * for migration to WebGPURenderer.
76762
+ *
76763
+ * @param {WebGLNodesHandler} nodesHandler - The node builder instance.
76764
+ */
76765
+ this.setNodesHandler = function ( nodesHandler ) {
76766
+
76767
+ nodesHandler.setRenderer( this );
76768
+ _nodesHandler = nodesHandler;
76769
+
76770
+ };
76771
+
76369
76772
  /**
76370
76773
  * Frees the GPU-related resources allocated by this instance. Call this
76371
76774
  * method whenever this instance is no longer used in your app.
@@ -76601,33 +77004,23 @@ class WebGLRenderer {
76601
77004
 
76602
77005
  if ( object.isBatchedMesh ) {
76603
77006
 
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 {
77007
+ if ( ! extensions.get( 'WEBGL_multi_draw' ) ) {
76611
77008
 
76612
- if ( ! extensions.get( 'WEBGL_multi_draw' ) ) {
77009
+ const starts = object._multiDrawStarts;
77010
+ const counts = object._multiDrawCounts;
77011
+ const drawCount = object._multiDrawCount;
77012
+ const bytesPerElement = index ? attributes.get( index ).bytesPerElement : 1;
77013
+ const uniforms = properties.get( material ).currentProgram.getUniforms();
77014
+ for ( let i = 0; i < drawCount; i ++ ) {
76613
77015
 
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 ++ ) {
77016
+ uniforms.setValue( _gl, '_gl_DrawID', i );
77017
+ renderer.render( starts[ i ] / bytesPerElement, counts[ i ] );
76620
77018
 
76621
- uniforms.setValue( _gl, '_gl_DrawID', i );
76622
- renderer.render( starts[ i ] / bytesPerElement, counts[ i ] );
76623
-
76624
- }
76625
-
76626
- } else {
77019
+ }
76627
77020
 
76628
- renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );
77021
+ } else {
76629
77022
 
76630
- }
77023
+ renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );
76631
77024
 
76632
77025
  }
76633
77026
 
@@ -76926,6 +77319,13 @@ class WebGLRenderer {
76926
77319
 
76927
77320
  if ( _isContextLost === true ) return;
76928
77321
 
77322
+ // update node builder if available
77323
+ if ( _nodesHandler !== null ) {
77324
+
77325
+ _nodesHandler.renderStart( scene, camera );
77326
+
77327
+ }
77328
+
76929
77329
  // use internal render target for HalfFloatType color buffer (only when tone mapping is enabled)
76930
77330
 
76931
77331
  const isXRPresenting = xr.enabled === true && xr.isPresenting === true;
@@ -76954,6 +77354,7 @@ class WebGLRenderer {
76954
77354
  currentRenderState = renderStates.get( scene, renderStateStack.length );
76955
77355
  currentRenderState.init( camera );
76956
77356
 
77357
+ currentRenderState.state.textureUnits = textures.getTextureUnits();
76957
77358
  renderStateStack.push( currentRenderState );
76958
77359
 
76959
77360
  _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
@@ -77099,6 +77500,8 @@ class WebGLRenderer {
77099
77500
 
77100
77501
  currentRenderState = renderStateStack[ renderStateStack.length - 1 ];
77101
77502
 
77503
+ textures.setTextureUnits( currentRenderState.state.textureUnits );
77504
+
77102
77505
  if ( _clippingEnabled === true ) clipping.setGlobalState( _this.clippingPlanes, currentRenderState.state.camera );
77103
77506
 
77104
77507
  } else {
@@ -77119,6 +77522,12 @@ class WebGLRenderer {
77119
77522
 
77120
77523
  }
77121
77524
 
77525
+ if ( _nodesHandler !== null ) {
77526
+
77527
+ _nodesHandler.renderEnd();
77528
+
77529
+ }
77530
+
77122
77531
  };
77123
77532
 
77124
77533
  function projectObject( object, camera, groupOrder, sortObjects ) {
@@ -77137,6 +77546,10 @@ class WebGLRenderer {
77137
77546
 
77138
77547
  if ( object.autoUpdate === true ) object.update( camera );
77139
77548
 
77549
+ } else if ( object.isLightProbeGrid ) {
77550
+
77551
+ currentRenderState.pushLightProbeGrid( object );
77552
+
77140
77553
  } else if ( object.isLight ) {
77141
77554
 
77142
77555
  currentRenderState.pushLight( object );
@@ -77452,7 +77865,7 @@ class WebGLRenderer {
77452
77865
 
77453
77866
  const lightsStateVersion = lights.state.version;
77454
77867
 
77455
- const parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, object );
77868
+ const parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, object, currentRenderState.state.lightProbeGridArray );
77456
77869
  const programCacheKey = programCache.getProgramCacheKey( parameters );
77457
77870
 
77458
77871
  let programs = materialProperties.programs;
@@ -77495,6 +77908,13 @@ class WebGLRenderer {
77495
77908
 
77496
77909
  parameters.uniforms = programCache.getUniforms( material );
77497
77910
 
77911
+ // Use node builder for node materials if available
77912
+ if ( _nodesHandler !== null && material.isNodeMaterial ) {
77913
+
77914
+ _nodesHandler.build( material, object, parameters );
77915
+
77916
+ }
77917
+
77498
77918
  material.onBeforeCompile( parameters, _this );
77499
77919
 
77500
77920
  program = programCache.acquireProgram( parameters, programCacheKey );
@@ -77544,6 +77964,8 @@ class WebGLRenderer {
77544
77964
 
77545
77965
  }
77546
77966
 
77967
+ materialProperties.lightProbeGrid = currentRenderState.state.lightProbeGridArray.length > 0;
77968
+
77547
77969
  materialProperties.currentProgram = program;
77548
77970
  materialProperties.uniformsList = null;
77549
77971
 
@@ -77587,6 +78009,30 @@ class WebGLRenderer {
77587
78009
 
77588
78010
  }
77589
78011
 
78012
+ function findLightProbeGrid( volumes, object ) {
78013
+
78014
+ if ( volumes.length === 0 ) return null;
78015
+
78016
+ if ( volumes.length === 1 ) {
78017
+
78018
+ return volumes[ 0 ].texture !== null ? volumes[ 0 ] : null;
78019
+
78020
+ }
78021
+
78022
+ objectPosition.setFromMatrixPosition( object.matrixWorld );
78023
+
78024
+ for ( let i = 0, l = volumes.length; i < l; i ++ ) {
78025
+
78026
+ const v = volumes[ i ];
78027
+
78028
+ if ( v.texture !== null && v.boundingBox.containsPoint( objectPosition ) ) return v;
78029
+
78030
+ }
78031
+
78032
+ return null;
78033
+
78034
+ }
78035
+
77590
78036
  function setProgram( camera, scene, geometry, material, object ) {
77591
78037
 
77592
78038
  if ( scene.isScene !== true ) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...
@@ -77595,7 +78041,7 @@ class WebGLRenderer {
77595
78041
 
77596
78042
  const fog = scene.fog;
77597
78043
  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 );
78044
+ const colorSpace = ( _currentRenderTarget === null ) ? _this.outputColorSpace : ( _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.colorSpace : ColorManagement.workingColorSpace );
77599
78045
  const usePMREM = material.isMeshStandardMaterial || ( material.isMeshLambertMaterial && ! material.envMap ) || ( material.isMeshPhongMaterial && ! material.envMap );
77600
78046
  const envMap = environments.get( material.envMap || environment, usePMREM );
77601
78047
  const vertexAlphas = material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4;
@@ -77751,6 +78197,10 @@ class WebGLRenderer {
77751
78197
 
77752
78198
  needsProgramChange = true;
77753
78199
 
78200
+ } else if ( !! materialProperties.lightProbeGrid !== ( currentRenderState.state.lightProbeGridArray.length > 0 ) ) {
78201
+
78202
+ needsProgramChange = true;
78203
+
77754
78204
  }
77755
78205
 
77756
78206
  } else {
@@ -77768,6 +78218,14 @@ class WebGLRenderer {
77768
78218
 
77769
78219
  program = getProgram( material, scene, object );
77770
78220
 
78221
+ // notify the node builder that the program has changed so uniforms and update nodes can
78222
+ // be cached and triggered.
78223
+ if ( _nodesHandler && material.isNodeMaterial ) {
78224
+
78225
+ _nodesHandler.onUpdateProgram( material, program, materialProperties );
78226
+
78227
+ }
78228
+
77771
78229
  }
77772
78230
 
77773
78231
  let refreshProgram = false;
@@ -77793,6 +78251,19 @@ class WebGLRenderer {
77793
78251
 
77794
78252
  }
77795
78253
 
78254
+ if ( materialProperties.needsLights ) {
78255
+
78256
+ const objectVolume = findLightProbeGrid( currentRenderState.state.lightProbeGridArray, object );
78257
+
78258
+ if ( materialProperties.lightProbeGrid !== objectVolume ) {
78259
+
78260
+ materialProperties.lightProbeGrid = objectVolume;
78261
+ refreshMaterial = true;
78262
+
78263
+ }
78264
+
78265
+ }
78266
+
77796
78267
  if ( refreshProgram || _currentCamera !== camera ) {
77797
78268
 
77798
78269
  // common camera uniforms
@@ -77980,6 +78451,19 @@ class WebGLRenderer {
77980
78451
 
77981
78452
  materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, currentRenderState.state.transmissionRenderTarget[ camera.id ] );
77982
78453
 
78454
+ // light probe volume
78455
+
78456
+ if ( materialProperties.needsLights && materialProperties.lightProbeGrid ) {
78457
+
78458
+ const volume = materialProperties.lightProbeGrid;
78459
+
78460
+ m_uniforms.probesSH.value = volume.texture;
78461
+ m_uniforms.probesMin.value.copy( volume.boundingBox.min );
78462
+ m_uniforms.probesMax.value.copy( volume.boundingBox.max );
78463
+ m_uniforms.probesResolution.value.copy( volume.resolution );
78464
+
78465
+ }
78466
+
77983
78467
  WebGLUniforms.upload( _gl, getUniformList( materialProperties ), m_uniforms, textures );
77984
78468
 
77985
78469
  }
@@ -78005,7 +78489,7 @@ class WebGLRenderer {
78005
78489
 
78006
78490
  // UBOs
78007
78491
 
78008
- if ( material.isShaderMaterial || material.isRawShaderMaterial ) {
78492
+ if ( material.uniformsGroups !== undefined ) {
78009
78493
 
78010
78494
  const groups = material.uniformsGroups;
78011
78495
 
@@ -78581,22 +79065,24 @@ class WebGLRenderer {
78581
79065
 
78582
79066
  }
78583
79067
 
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 );
79068
+ state.activeTexture( _gl.TEXTURE0 ); // see #33153
79069
+
79070
+ state.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
79071
+ state.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
79072
+ state.pixelStorei( _gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
78587
79073
 
78588
79074
  // 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 );
79075
+ const currentUnpackRowLen = state.getParameter( _gl.UNPACK_ROW_LENGTH );
79076
+ const currentUnpackImageHeight = state.getParameter( _gl.UNPACK_IMAGE_HEIGHT );
79077
+ const currentUnpackSkipPixels = state.getParameter( _gl.UNPACK_SKIP_PIXELS );
79078
+ const currentUnpackSkipRows = state.getParameter( _gl.UNPACK_SKIP_ROWS );
79079
+ const currentUnpackSkipImages = state.getParameter( _gl.UNPACK_SKIP_IMAGES );
79080
+
79081
+ state.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
79082
+ state.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, image.height );
79083
+ state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, minX );
79084
+ state.pixelStorei( _gl.UNPACK_SKIP_ROWS, minY );
79085
+ state.pixelStorei( _gl.UNPACK_SKIP_IMAGES, minZ );
78600
79086
 
78601
79087
  // set up the src texture
78602
79088
  const isSrc3D = srcTexture.isDataArrayTexture || srcTexture.isData3DTexture;
@@ -78722,11 +79208,11 @@ class WebGLRenderer {
78722
79208
  }
78723
79209
 
78724
79210
  // 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 );
79211
+ state.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
79212
+ state.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
79213
+ state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
79214
+ state.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
79215
+ state.pixelStorei( _gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
78730
79216
 
78731
79217
  // Generate mipmaps only when copying level 0
78732
79218
  if ( dstLevel === 0 && dstTexture.generateMipmaps ) {
@@ -78989,6 +79475,7 @@ exports.GreaterEqualStencilFunc = GreaterEqualStencilFunc;
78989
79475
  exports.GreaterStencilFunc = GreaterStencilFunc;
78990
79476
  exports.GridHelper = GridHelper;
78991
79477
  exports.Group = Group;
79478
+ exports.HTMLTexture = HTMLTexture;
78992
79479
  exports.HalfFloatType = HalfFloatType;
78993
79480
  exports.HemisphereLight = HemisphereLight;
78994
79481
  exports.HemisphereLightHelper = HemisphereLightHelper;