@plastic-software/three 0.181.3 → 0.182.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 (253) hide show
  1. package/README.md +3 -4
  2. package/build/three.cjs +1192 -522
  3. package/build/three.core.js +345 -219
  4. package/build/three.core.min.js +1 -1
  5. package/build/three.module.js +864 -328
  6. package/build/three.module.min.js +1 -1
  7. package/build/three.tsl.js +15 -3
  8. package/build/three.tsl.min.js +1 -1
  9. package/build/three.webgpu.js +3660 -1545
  10. package/build/three.webgpu.min.js +1 -1
  11. package/build/three.webgpu.nodes.js +3659 -1544
  12. package/build/three.webgpu.nodes.min.js +1 -1
  13. package/examples/jsm/controls/MapControls.js +55 -1
  14. package/examples/jsm/controls/OrbitControls.js +6 -6
  15. package/examples/jsm/controls/TrackballControls.js +6 -6
  16. package/examples/jsm/csm/CSM.js +2 -1
  17. package/examples/jsm/environments/RoomEnvironment.js +2 -0
  18. package/examples/jsm/geometries/DecalGeometry.js +1 -1
  19. package/examples/jsm/helpers/LightProbeHelperGPU.js +1 -1
  20. package/examples/jsm/helpers/TextureHelperGPU.js +1 -1
  21. package/examples/jsm/inspector/Inspector.js +53 -9
  22. package/examples/jsm/inspector/RendererInspector.js +12 -2
  23. package/examples/jsm/inspector/tabs/Console.js +2 -2
  24. package/examples/jsm/inspector/tabs/Parameters.js +2 -2
  25. package/examples/jsm/inspector/tabs/Performance.js +2 -2
  26. package/examples/jsm/inspector/tabs/Viewer.js +4 -4
  27. package/examples/jsm/inspector/ui/Profiler.js +1836 -31
  28. package/examples/jsm/inspector/ui/Style.js +948 -13
  29. package/examples/jsm/inspector/ui/Tab.js +188 -1
  30. package/examples/jsm/inspector/ui/Values.js +17 -1
  31. package/examples/jsm/loaders/3DMLoader.js +5 -4
  32. package/examples/jsm/loaders/DRACOLoader.js +5 -5
  33. package/examples/jsm/loaders/FBXLoader.js +0 -2
  34. package/examples/jsm/loaders/HDRLoader.js +0 -1
  35. package/examples/jsm/loaders/KTX2Loader.js +16 -0
  36. package/examples/jsm/loaders/LDrawLoader.js +2 -3
  37. package/examples/jsm/loaders/PCDLoader.js +1 -0
  38. package/examples/jsm/loaders/SVGLoader.js +1 -1
  39. package/examples/jsm/loaders/TDSLoader.js +0 -2
  40. package/examples/jsm/loaders/TGALoader.js +0 -2
  41. package/examples/jsm/loaders/UltraHDRLoader.js +110 -137
  42. package/examples/jsm/loaders/VOXLoader.js +660 -117
  43. package/examples/jsm/loaders/VRMLLoader.js +2 -2
  44. package/examples/jsm/loaders/usd/USDCParser.js +1 -1
  45. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +1 -1
  46. package/examples/jsm/materials/MeshGouraudMaterial.js +0 -1
  47. package/examples/jsm/materials/WoodNodeMaterial.js +11 -11
  48. package/examples/jsm/math/Octree.js +131 -1
  49. package/examples/jsm/misc/Volume.js +0 -1
  50. package/examples/jsm/misc/VolumeSlice.js +0 -1
  51. package/examples/jsm/objects/SkyMesh.js +13 -3
  52. package/examples/jsm/physics/AmmoPhysics.js +12 -7
  53. package/examples/jsm/physics/JoltPhysics.js +3 -1
  54. package/examples/jsm/physics/RapierPhysics.js +3 -1
  55. package/examples/jsm/postprocessing/OutputPass.js +9 -0
  56. package/examples/jsm/postprocessing/RenderPass.js +10 -0
  57. package/examples/jsm/postprocessing/UnrealBloomPass.js +48 -18
  58. package/examples/jsm/renderers/Projector.js +268 -30
  59. package/examples/jsm/renderers/SVGRenderer.js +191 -58
  60. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -4
  61. package/examples/jsm/transpiler/AST.js +44 -0
  62. package/examples/jsm/transpiler/GLSLDecoder.js +61 -4
  63. package/examples/jsm/transpiler/ShaderToyDecoder.js +2 -0
  64. package/examples/jsm/transpiler/TSLEncoder.js +46 -3
  65. package/examples/jsm/transpiler/TranspilerUtils.js +3 -3
  66. package/examples/jsm/transpiler/WGSLEncoder.js +27 -0
  67. package/examples/jsm/tsl/display/AnaglyphPassNode.js +2 -0
  68. package/examples/jsm/tsl/display/BloomNode.js +11 -1
  69. package/examples/jsm/tsl/display/GTAONode.js +3 -2
  70. package/examples/jsm/tsl/display/PixelationPassNode.js +2 -1
  71. package/examples/jsm/tsl/display/SSGINode.js +7 -19
  72. package/examples/jsm/tsl/display/SSRNode.js +1 -1
  73. package/examples/jsm/tsl/display/SSSNode.js +4 -2
  74. package/examples/jsm/tsl/display/StereoCompositePassNode.js +8 -1
  75. package/examples/jsm/tsl/display/TRAANode.js +265 -114
  76. package/examples/jsm/tsl/display/radialBlur.js +68 -0
  77. package/examples/jsm/utils/ShadowMapViewer.js +24 -10
  78. package/examples/jsm/utils/ShadowMapViewerGPU.js +1 -1
  79. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  80. package/package.json +14 -12
  81. package/src/Three.Core.js +1 -0
  82. package/src/Three.TSL.js +14 -2
  83. package/src/animation/AnimationUtils.js +1 -12
  84. package/src/animation/KeyframeTrack.js +1 -1
  85. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  86. package/src/animation/tracks/ColorKeyframeTrack.js +1 -1
  87. package/src/animation/tracks/NumberKeyframeTrack.js +1 -1
  88. package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -1
  89. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  90. package/src/animation/tracks/VectorKeyframeTrack.js +1 -1
  91. package/src/constants.js +61 -5
  92. package/src/core/BufferGeometry.js +14 -2
  93. package/src/core/Raycaster.js +2 -2
  94. package/src/extras/PMREMGenerator.js +3 -10
  95. package/src/extras/TextureUtils.js +5 -1
  96. package/src/geometries/ExtrudeGeometry.js +2 -2
  97. package/src/geometries/PolyhedronGeometry.js +1 -1
  98. package/src/helpers/PointLightHelper.js +1 -1
  99. package/src/lights/DirectionalLight.js +13 -0
  100. package/src/lights/HemisphereLight.js +10 -0
  101. package/src/lights/Light.js +1 -11
  102. package/src/lights/LightProbe.js +0 -15
  103. package/src/lights/LightShadow.js +0 -3
  104. package/src/lights/PointLight.js +15 -0
  105. package/src/lights/PointLightShadow.js +0 -86
  106. package/src/lights/SpotLight.js +22 -1
  107. package/src/loaders/MaterialLoader.js +2 -1
  108. package/src/loaders/ObjectLoader.js +3 -1
  109. package/src/loaders/nodes/NodeLoader.js +2 -2
  110. package/src/materials/Material.js +2 -0
  111. package/src/materials/ShaderMaterial.js +20 -1
  112. package/src/materials/nodes/Line2NodeMaterial.js +2 -2
  113. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +3 -2
  114. package/src/materials/nodes/MeshStandardNodeMaterial.js +5 -4
  115. package/src/materials/nodes/NodeMaterial.js +59 -3
  116. package/src/materials/nodes/manager/NodeMaterialObserver.js +1 -1
  117. package/src/math/Matrix4.js +40 -40
  118. package/src/math/Sphere.js +1 -1
  119. package/src/math/Vector3.js +0 -2
  120. package/src/nodes/TSL.js +4 -1
  121. package/src/nodes/accessors/BatchNode.js +10 -10
  122. package/src/nodes/accessors/BufferAttributeNode.js +98 -12
  123. package/src/nodes/accessors/BufferNode.js +29 -2
  124. package/src/nodes/accessors/ClippingNode.js +4 -4
  125. package/src/nodes/accessors/CubeTextureNode.js +20 -1
  126. package/src/nodes/accessors/InstanceNode.js +69 -29
  127. package/src/nodes/accessors/MaterialNode.js +9 -1
  128. package/src/nodes/accessors/MaterialReferenceNode.js +1 -2
  129. package/src/nodes/accessors/ModelNode.js +1 -1
  130. package/src/nodes/accessors/Normal.js +2 -2
  131. package/src/nodes/accessors/ReferenceBaseNode.js +4 -4
  132. package/src/nodes/accessors/ReferenceNode.js +4 -4
  133. package/src/nodes/accessors/RendererReferenceNode.js +1 -2
  134. package/src/nodes/accessors/SkinningNode.js +15 -2
  135. package/src/nodes/accessors/StorageBufferNode.js +4 -2
  136. package/src/nodes/accessors/Tangent.js +1 -11
  137. package/src/nodes/accessors/Texture3DNode.js +26 -1
  138. package/src/nodes/accessors/UniformArrayNode.js +2 -2
  139. package/src/nodes/accessors/UserDataNode.js +1 -2
  140. package/src/nodes/accessors/VertexColorNode.js +1 -2
  141. package/src/nodes/code/FunctionNode.js +1 -2
  142. package/src/nodes/core/ArrayNode.js +20 -1
  143. package/src/nodes/core/AssignNode.js +2 -2
  144. package/src/nodes/core/AttributeNode.js +2 -2
  145. package/src/nodes/core/ContextNode.js +103 -4
  146. package/src/nodes/core/NodeBuilder.js +56 -14
  147. package/src/nodes/core/NodeFrame.js +12 -4
  148. package/src/nodes/core/NodeUtils.js +5 -5
  149. package/src/nodes/core/ParameterNode.js +1 -2
  150. package/src/nodes/core/PropertyNode.js +19 -3
  151. package/src/nodes/core/StackNode.js +56 -8
  152. package/src/nodes/core/StructNode.js +1 -2
  153. package/src/nodes/core/StructTypeNode.js +11 -17
  154. package/src/nodes/core/UniformNode.js +19 -4
  155. package/src/nodes/core/VarNode.js +46 -21
  156. package/src/nodes/display/NormalMapNode.js +37 -2
  157. package/src/nodes/display/PassNode.js +77 -7
  158. package/src/nodes/display/ScreenNode.js +1 -0
  159. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +3 -3
  160. package/src/nodes/functions/BSDF/DFGLUT.js +56 -0
  161. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  162. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +1 -1
  163. package/src/nodes/functions/PhysicalLightingModel.js +102 -43
  164. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -2
  165. package/src/nodes/gpgpu/SubgroupFunctionNode.js +1 -1
  166. package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -3
  167. package/src/nodes/lighting/AnalyticLightNode.js +53 -0
  168. package/src/nodes/lighting/LightsNode.js +2 -2
  169. package/src/nodes/lighting/PointShadowNode.js +141 -140
  170. package/src/nodes/lighting/ShadowFilterNode.js +53 -37
  171. package/src/nodes/lighting/ShadowNode.js +53 -19
  172. package/src/nodes/math/BitcountNode.js +433 -0
  173. package/src/nodes/math/PackFloatNode.js +98 -0
  174. package/src/nodes/math/UnpackFloatNode.js +96 -0
  175. package/src/nodes/pmrem/PMREMNode.js +1 -1
  176. package/src/nodes/tsl/TSLCore.js +4 -4
  177. package/src/nodes/utils/ArrayElementNode.js +13 -0
  178. package/src/nodes/utils/EventNode.js +1 -2
  179. package/src/nodes/utils/Packing.js +13 -1
  180. package/src/nodes/utils/PostProcessingUtils.js +33 -1
  181. package/src/nodes/utils/ReflectorNode.js +1 -1
  182. package/src/nodes/utils/SampleNode.js +1 -1
  183. package/src/nodes/utils/UVUtils.js +26 -0
  184. package/src/objects/BatchedMesh.js +5 -2
  185. package/src/objects/Line.js +1 -1
  186. package/src/objects/Mesh.js +1 -1
  187. package/src/objects/Points.js +1 -1
  188. package/src/objects/Skeleton.js +9 -0
  189. package/src/renderers/WebGLRenderer.js +145 -33
  190. package/src/renderers/common/Backend.js +8 -0
  191. package/src/renderers/common/Background.js +19 -9
  192. package/src/renderers/common/Binding.js +11 -0
  193. package/src/renderers/common/Bindings.js +7 -7
  194. package/src/renderers/common/Buffer.js +40 -0
  195. package/src/renderers/common/ChainMap.js +30 -6
  196. package/src/renderers/common/Geometries.js +12 -0
  197. package/src/renderers/common/RenderContexts.js +8 -1
  198. package/src/renderers/common/RenderObject.js +14 -1
  199. package/src/renderers/common/Renderer.js +53 -35
  200. package/src/renderers/common/Textures.js +1 -1
  201. package/src/renderers/common/UniformsGroup.js +1 -0
  202. package/src/renderers/common/XRManager.js +1 -0
  203. package/src/renderers/common/extras/PMREMGenerator.js +2 -8
  204. package/src/renderers/common/nodes/NodeUniformBuffer.js +52 -0
  205. package/src/renderers/shaders/DFGLUTData.js +19 -34
  206. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +5 -2
  207. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +8 -4
  208. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +90 -51
  209. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +194 -186
  210. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +1 -1
  211. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  212. package/src/renderers/shaders/ShaderChunk.js +3 -3
  213. package/src/renderers/shaders/ShaderLib/depth.glsl.js +3 -0
  214. package/src/renderers/shaders/ShaderLib/{distanceRGBA.glsl.js → distance.glsl.js} +1 -2
  215. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +0 -1
  216. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -2
  217. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +0 -1
  218. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -9
  219. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +0 -1
  220. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +0 -1
  221. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +4 -6
  222. package/src/renderers/shaders/ShaderLib.js +3 -3
  223. package/src/renderers/webgl/WebGLCapabilities.js +3 -4
  224. package/src/renderers/webgl/WebGLLights.js +18 -1
  225. package/src/renderers/webgl/WebGLOutput.js +267 -0
  226. package/src/renderers/webgl/WebGLProgram.js +43 -107
  227. package/src/renderers/webgl/WebGLPrograms.js +35 -45
  228. package/src/renderers/webgl/WebGLShadowMap.js +188 -25
  229. package/src/renderers/webgl/WebGLState.js +20 -20
  230. package/src/renderers/webgl/WebGLTextures.js +89 -28
  231. package/src/renderers/webgl/WebGLUniforms.js +40 -3
  232. package/src/renderers/webgl/WebGLUtils.js +6 -2
  233. package/src/renderers/webgl-fallback/WebGLBackend.js +79 -13
  234. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +59 -7
  235. package/src/renderers/webgl-fallback/utils/WebGLState.js +18 -3
  236. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +5 -3
  237. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -9
  238. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +6 -2
  239. package/src/renderers/webgpu/WebGPUBackend.js +61 -4
  240. package/src/renderers/webgpu/WebGPURenderer.js +1 -1
  241. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +65 -23
  242. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -17
  243. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +354 -186
  244. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -0
  245. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +20 -7
  246. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +40 -17
  247. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +7 -7
  248. package/src/renderers/webgpu/utils/WebGPUUtils.js +7 -5
  249. package/src/textures/CubeDepthTexture.js +76 -0
  250. package/src/textures/Source.js +1 -1
  251. package/src/textures/Texture.js +1 -1
  252. package/src/utils.js +13 -1
  253. package/src/nodes/functions/BSDF/DFGApprox.js +0 -71
@@ -68,6 +68,15 @@ class StackNode extends Node {
68
68
  */
69
69
  this._expressionNode = null;
70
70
 
71
+ /**
72
+ * The current node being processed.
73
+ *
74
+ * @private
75
+ * @type {Node}
76
+ * @default null
77
+ */
78
+ this._currentNode = null;
79
+
71
80
  /**
72
81
  * This flag can be used for type testing.
73
82
  *
@@ -101,9 +110,10 @@ class StackNode extends Node {
101
110
  * Adds a node to this stack.
102
111
  *
103
112
  * @param {Node} node - The node to add.
113
+ * @param {number} [index=this.nodes.length] - The index where the node should be added.
104
114
  * @return {StackNode} A reference to this stack node.
105
115
  */
106
- addToStack( node ) {
116
+ addToStack( node, index = this.nodes.length ) {
107
117
 
108
118
  if ( node.isNode !== true ) {
109
119
 
@@ -112,12 +122,26 @@ class StackNode extends Node {
112
122
 
113
123
  }
114
124
 
115
- this.nodes.push( node );
125
+ this.nodes.splice( index, 0, node );
116
126
 
117
127
  return this;
118
128
 
119
129
  }
120
130
 
131
+ /**
132
+ * Adds a node to the stack before the current node.
133
+ *
134
+ * @param {Node} node - The node to add.
135
+ * @return {StackNode} A reference to this stack node.
136
+ */
137
+ addToStackBefore( node ) {
138
+
139
+ const index = this._currentNode ? this.nodes.indexOf( this._currentNode ) : 0;
140
+
141
+ return this.addToStack( node, index );
142
+
143
+ }
144
+
121
145
  /**
122
146
  * Represent an `if` statement in TSL.
123
147
  *
@@ -267,7 +291,7 @@ class StackNode extends Node {
267
291
 
268
292
  for ( const childNode of this.getChildren() ) {
269
293
 
270
- if ( childNode.isVarNode && childNode.intent === true ) {
294
+ if ( childNode.isVarNode && childNode.isIntent( builder ) ) {
271
295
 
272
296
  if ( childNode.isAssign( builder ) !== true ) {
273
297
 
@@ -297,19 +321,23 @@ class StackNode extends Node {
297
321
 
298
322
  const previousStack = getCurrentStack();
299
323
 
324
+ const buildStage = builder.buildStage;
325
+
300
326
  setCurrentStack( this );
301
327
 
302
328
  builder.setActiveStack( this );
303
329
 
304
- const buildStage = builder.buildStage;
330
+ //
305
331
 
306
- for ( const node of this.nodes ) {
332
+ const buildNode = ( node ) => {
307
333
 
308
- if ( node.isVarNode && node.intent === true ) {
334
+ this._currentNode = node;
335
+
336
+ if ( node.isVarNode && node.isIntent( builder ) ) {
309
337
 
310
338
  if ( node.isAssign( builder ) !== true ) {
311
339
 
312
- continue;
340
+ return;
313
341
 
314
342
  }
315
343
 
@@ -330,7 +358,7 @@ class StackNode extends Node {
330
358
 
331
359
  if ( node.isVarNode && parents && parents.length === 1 && parents[ 0 ] && parents[ 0 ].isStackNode ) {
332
360
 
333
- continue; // skip var nodes that are only used in .toVarying()
361
+ return; // skip var nodes that are only used in .toVarying()
334
362
 
335
363
  }
336
364
 
@@ -338,6 +366,26 @@ class StackNode extends Node {
338
366
 
339
367
  }
340
368
 
369
+ };
370
+
371
+ //
372
+
373
+ const nodes = [ ...this.nodes ];
374
+
375
+ for ( const node of nodes ) {
376
+
377
+ buildNode( node );
378
+
379
+ }
380
+
381
+ this._currentNode = null;
382
+
383
+ const newNodes = this.nodes.filter( ( node ) => nodes.indexOf( node ) === - 1 );
384
+
385
+ for ( const node of newNodes ) {
386
+
387
+ buildNode( node );
388
+
341
389
  }
342
390
 
343
391
  //
@@ -1,6 +1,5 @@
1
1
  import Node from './Node.js';
2
2
  import StructTypeNode from './StructTypeNode.js';
3
- import { nodeObject } from '../tsl/TSLCore.js';
4
3
 
5
4
  /**
6
5
  * StructNode allows to create custom structures with multiple members.
@@ -108,7 +107,7 @@ export const struct = ( membersLayout, name = null ) => {
108
107
 
109
108
  }
110
109
 
111
- return nodeObject( new StructNode( structLayout, values ) );
110
+ return new StructNode( structLayout, values );
112
111
 
113
112
  };
114
113
 
@@ -1,6 +1,6 @@
1
1
 
2
2
  import Node from './Node.js';
3
- import { getByteBoundaryFromType, getMemoryLengthFromType } from './NodeUtils.js';
3
+ import { getAlignmentFromType, getMemoryLengthFromType } from './NodeUtils.js';
4
4
 
5
5
  /**
6
6
  * Generates a layout for struct members.
@@ -86,29 +86,23 @@ class StructTypeNode extends Node {
86
86
  */
87
87
  getLength() {
88
88
 
89
- const GPU_CHUNK_BYTES = 8;
90
89
  const BYTES_PER_ELEMENT = Float32Array.BYTES_PER_ELEMENT;
91
-
92
- let offset = 0; // global buffer offset in bytes
90
+ let maxAlignment = 1; // maximum alignment value in this struct
91
+ let offset = 0; // global buffer offset in 4 byte elements
93
92
 
94
93
  for ( const member of this.membersLayout ) {
95
94
 
96
95
  const type = member.type;
97
96
 
98
- const itemSize = getMemoryLengthFromType( type ) * BYTES_PER_ELEMENT;
99
- const boundary = getByteBoundaryFromType( type );
100
-
101
- const chunkOffset = offset % GPU_CHUNK_BYTES; // offset in the current chunk
102
- const chunkPadding = chunkOffset % boundary; // required padding to match boundary
103
- const chunkStart = chunkOffset + chunkPadding; // start position in the current chunk for the data
104
-
105
- offset += chunkPadding;
97
+ const itemSize = getMemoryLengthFromType( type );
98
+ const alignment = getAlignmentFromType( type ) / BYTES_PER_ELEMENT;
99
+ maxAlignment = Math.max( maxAlignment, alignment );
106
100
 
107
- // Check for chunk overflow
108
- if ( chunkStart !== 0 && ( GPU_CHUNK_BYTES - chunkStart ) < itemSize ) {
101
+ const chunkOffset = offset % maxAlignment; // offset in the current chunk of maxAlignment elements
102
+ const overhang = chunkOffset % alignment; // distance from the last aligned offset
103
+ if ( overhang !== 0 ) {
109
104
 
110
- // Add padding to the end of the chunk
111
- offset += ( GPU_CHUNK_BYTES - chunkStart );
105
+ offset += alignment - overhang; // move to next aligned offset
112
106
 
113
107
  }
114
108
 
@@ -116,7 +110,7 @@ class StructTypeNode extends Node {
116
110
 
117
111
  }
118
112
 
119
- return ( Math.ceil( offset / GPU_CHUNK_BYTES ) * GPU_CHUNK_BYTES ) / BYTES_PER_ELEMENT;
113
+ return ( Math.ceil( offset / maxAlignment ) * maxAlignment ); // ensure length is a multiple of maxAlignment
120
114
 
121
115
  }
122
116
 
@@ -1,6 +1,6 @@
1
1
  import InputNode from './InputNode.js';
2
2
  import { objectGroup } from './UniformGroupNode.js';
3
- import { nodeObject, getConstNodeType } from '../tsl/TSLCore.js';
3
+ import { getConstNodeType } from '../tsl/TSLCore.js';
4
4
  import { getValueFromType } from './NodeUtils.js';
5
5
  import { warn } from '../../utils.js';
6
6
 
@@ -235,9 +235,24 @@ export const uniform = ( value, type ) => {
235
235
 
236
236
  }
237
237
 
238
- // @TODO: get ConstNode from .traverse() in the future
239
- value = ( value && value.isNode === true ) ? ( value.node && value.node.value ) || value.value : value;
238
+ if ( value && value.isNode === true ) {
240
239
 
241
- return nodeObject( new UniformNode( value, nodeType ) );
240
+ let v = value.value;
241
+
242
+ value.traverse( n => {
243
+
244
+ if ( n.isConstNode === true ) {
245
+
246
+ v = n.value;
247
+
248
+ }
249
+
250
+ } );
251
+
252
+ value = v;
253
+
254
+ }
255
+
256
+ return new UniformNode( value, nodeType );
242
257
 
243
258
  };
@@ -112,6 +112,22 @@ class VarNode extends Node {
112
112
 
113
113
  }
114
114
 
115
+ /**
116
+ * Checks if this node is used for intent.
117
+ *
118
+ * @param {NodeBuilder} builder - The node builder.
119
+ * @returns {boolean} Whether this node is used for intent.
120
+ */
121
+ isIntent( builder ) {
122
+
123
+ const data = builder.getDataFromNode( this );
124
+
125
+ if ( data.forceDeclaration === true ) return false;
126
+
127
+ return this.intent;
128
+
129
+ }
130
+
115
131
  /**
116
132
  * Returns the intent flag of this node.
117
133
  *
@@ -149,49 +165,58 @@ class VarNode extends Node {
149
165
 
150
166
  isAssign( builder ) {
151
167
 
152
- const properties = builder.getNodeProperties( this );
168
+ const data = builder.getDataFromNode( this );
153
169
 
154
- let assign = properties.assign;
170
+ return data.assign;
155
171
 
156
- if ( assign !== true ) {
172
+ }
157
173
 
158
- if ( this.node.isShaderCallNodeInternal && this.node.shaderNode.getLayout() === null ) {
174
+ build( ...params ) {
159
175
 
160
- if ( builder.fnCall && builder.fnCall.shaderNode ) {
176
+ const builder = params[ 0 ];
161
177
 
162
- const shaderNodeData = builder.getDataFromNode( this.node.shaderNode );
178
+ if ( this._hasStack( builder ) === false && builder.buildStage === 'setup' ) {
163
179
 
164
- if ( shaderNodeData.hasLoop ) {
180
+ if ( builder.context.nodeLoop || builder.context.nodeBlock ) {
165
181
 
166
- assign = true;
182
+ let addBefore = false;
167
183
 
168
- }
184
+ if ( this.node.isShaderCallNodeInternal && this.node.shaderNode.getLayout() === null ) {
169
185
 
170
- }
186
+ if ( builder.fnCall && builder.fnCall.shaderNode ) {
171
187
 
172
- }
188
+ const shaderNodeData = builder.getDataFromNode( this.node.shaderNode );
173
189
 
174
- }
190
+ if ( shaderNodeData.hasLoop ) {
175
191
 
176
- return assign;
192
+ const data = builder.getDataFromNode( this );
193
+ data.forceDeclaration = true;
177
194
 
178
- }
195
+ addBefore = true;
179
196
 
180
- build( ...params ) {
197
+ }
181
198
 
182
- const builder = params[ 0 ];
199
+ }
183
200
 
184
- if ( this._hasStack( builder ) === false && builder.buildStage === 'setup' ) {
201
+ }
185
202
 
186
- if ( builder.context.nodeLoop || builder.context.nodeBlock ) {
203
+ const baseStack = builder.getBaseStack();
204
+
205
+ if ( addBefore ) {
206
+
207
+ baseStack.addToStackBefore( this );
187
208
 
188
- builder.getBaseStack().addToStack( this );
209
+ } else {
210
+
211
+ baseStack.addToStack( this );
212
+
213
+ }
189
214
 
190
215
  }
191
216
 
192
217
  }
193
218
 
194
- if ( this.intent === true ) {
219
+ if ( this.isIntent( builder ) ) {
195
220
 
196
221
  if ( this.isAssign( builder ) !== true ) {
197
222
 
@@ -227,7 +252,7 @@ class VarNode extends Node {
227
252
 
228
253
  if ( nodeType == 'void' ) {
229
254
 
230
- if ( this.intent !== true ) {
255
+ if ( this.isIntent( builder ) !== true ) {
231
256
 
232
257
  error( 'TSL: ".toVar()" can not be used with void type.' );
233
258
 
@@ -4,8 +4,9 @@ import { normalView, transformNormalToView } from '../accessors/Normal.js';
4
4
  import { TBNViewMatrix } from '../accessors/AccessorsUtils.js';
5
5
  import { nodeProxy, vec3 } from '../tsl/TSLBase.js';
6
6
 
7
- import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from '../../constants.js';
7
+ import { TangentSpaceNormalMap, ObjectSpaceNormalMap, NoNormalPacking, NormalRGPacking, NormalGAPacking } from '../../constants.js';
8
8
  import { directionToFaceDirection } from './FrontFacingNode.js';
9
+ import { unpackNormal } from '../utils/Packing.js';
9
10
  import { error } from '../../utils.js';
10
11
 
11
12
  /**
@@ -58,14 +59,48 @@ class NormalMapNode extends TempNode {
58
59
  */
59
60
  this.normalMapType = TangentSpaceNormalMap;
60
61
 
62
+ /**
63
+ * Controls how to unpack the sampled normal map values.
64
+ *
65
+ * @type {string}
66
+ * @default NoNormalPacking
67
+ */
68
+ this.unpackNormalMode = NoNormalPacking;
69
+
61
70
  }
62
71
 
63
72
  setup( { material } ) {
64
73
 
65
- const { normalMapType, scaleNode } = this;
74
+ const { normalMapType, scaleNode, unpackNormalMode } = this;
66
75
 
67
76
  let normalMap = this.node.mul( 2.0 ).sub( 1.0 );
68
77
 
78
+ if ( normalMapType === TangentSpaceNormalMap ) {
79
+
80
+ if ( unpackNormalMode === NormalRGPacking ) {
81
+
82
+ normalMap = unpackNormal( normalMap.xy );
83
+
84
+ } else if ( unpackNormalMode === NormalGAPacking ) {
85
+
86
+ normalMap = unpackNormal( normalMap.yw );
87
+
88
+ } else if ( unpackNormalMode !== NoNormalPacking ) {
89
+
90
+ console.error( `THREE.NodeMaterial: Unexpected unpack normal mode: ${ unpackNormalMode }` );
91
+
92
+ }
93
+
94
+ } else {
95
+
96
+ if ( unpackNormalMode !== NoNormalPacking ) {
97
+
98
+ console.error( `THREE.NodeMaterial: Normal map type '${ normalMapType }' is not compatible with unpack normal mode '${ unpackNormalMode }'` );
99
+
100
+ }
101
+
102
+ }
103
+
69
104
  if ( scaleNode !== null ) {
70
105
 
71
106
  let scale = scaleNode;
@@ -1,7 +1,7 @@
1
1
  import TempNode from '../core/TempNode.js';
2
2
  import { default as TextureNode/*, texture*/ } from '../accessors/TextureNode.js';
3
3
  import { NodeUpdateType } from '../core/constants.js';
4
- import { nodeObject } from '../tsl/TSLBase.js';
4
+ import { context } from '../tsl/TSLBase.js';
5
5
  import { uniform } from '../core/UniformNode.js';
6
6
  import { viewZToOrthographicDepth, perspectiveDepthToViewZ } from './ViewportDepthNode.js';
7
7
 
@@ -248,6 +248,45 @@ class PassNode extends TempNode {
248
248
  */
249
249
  this.renderTarget = renderTarget;
250
250
 
251
+ /**
252
+ * An optional override material for the pass.
253
+ *
254
+ * @type {Material|null}
255
+ */
256
+ this.overrideMaterial = null;
257
+
258
+ /**
259
+ * Whether the pass is transparent.
260
+ *
261
+ * @type {boolean}
262
+ * @default false
263
+ */
264
+ this.transparent = true;
265
+
266
+ /**
267
+ * Whether the pass is opaque.
268
+ *
269
+ * @type {boolean}
270
+ * @default true
271
+ */
272
+ this.opaque = true;
273
+
274
+ /**
275
+ * An optional global context for the pass.
276
+ *
277
+ * @type {ContextNode|null}
278
+ */
279
+ this.contextNode = null;
280
+
281
+ /**
282
+ * A cache for the context node.
283
+ *
284
+ * @private
285
+ * @type {?Object}
286
+ * @default null
287
+ */
288
+ this._contextNodeCache = null;
289
+
251
290
  /**
252
291
  * A dictionary holding the internal result textures.
253
292
  *
@@ -584,7 +623,7 @@ class PassNode extends TempNode {
584
623
 
585
624
  if ( textureNode === undefined ) {
586
625
 
587
- textureNode = nodeObject( new PassMultipleTextureNode( this, name ) );
626
+ textureNode = new PassMultipleTextureNode( this, name );
588
627
  textureNode.updateTexture();
589
628
  this._textureNodes[ name ] = textureNode;
590
629
 
@@ -608,7 +647,7 @@ class PassNode extends TempNode {
608
647
 
609
648
  if ( this._textureNodes[ name ] === undefined ) this.getTextureNode( name );
610
649
 
611
- textureNode = nodeObject( new PassMultipleTextureNode( this, name, true ) );
650
+ textureNode = new PassMultipleTextureNode( this, name, true );
612
651
  textureNode.updateTexture();
613
652
  this._previousTextureNodes[ name ] = textureNode;
614
653
 
@@ -697,7 +736,7 @@ class PassNode extends TempNode {
697
736
 
698
737
  this.renderTarget.samples = this.options.samples === undefined ? renderer.samples : this.options.samples;
699
738
 
700
- this.renderTarget.texture.type = renderer.getColorBufferType();
739
+ this.renderTarget.texture.type = renderer.getOutputBufferType();
701
740
 
702
741
  return this.scope === PassNode.COLOR ? this.getTextureNode() : this.getLinearDepthNode();
703
742
 
@@ -738,7 +777,11 @@ class PassNode extends TempNode {
738
777
  const currentRenderTarget = renderer.getRenderTarget();
739
778
  const currentMRT = renderer.getMRT();
740
779
  const currentAutoClear = renderer.autoClear;
780
+ const currentTransparent = renderer.transparent;
781
+ const currentOpaque = renderer.opaque;
741
782
  const currentMask = camera.layers.mask;
783
+ const currentContextNode = renderer.contextNode;
784
+ const currentOverrideMaterial = scene.overrideMaterial;
742
785
 
743
786
  this._cameraNear.value = camera.near;
744
787
  this._cameraFar.value = camera.far;
@@ -755,9 +798,32 @@ class PassNode extends TempNode {
755
798
 
756
799
  }
757
800
 
801
+ if ( this.overrideMaterial !== null ) {
802
+
803
+ scene.overrideMaterial = this.overrideMaterial;
804
+
805
+ }
806
+
758
807
  renderer.setRenderTarget( this.renderTarget );
759
808
  renderer.setMRT( this._mrt );
760
809
  renderer.autoClear = true;
810
+ renderer.transparent = this.transparent;
811
+ renderer.opaque = this.opaque;
812
+
813
+ if ( this.contextNode !== null ) {
814
+
815
+ if ( this._contextNodeCache === null || this._contextNodeCache.version !== this.version ) {
816
+
817
+ this._contextNodeCache = {
818
+ version: this.version,
819
+ context: context( { ...renderer.contextNode.getFlowContextData(), ...this.contextNode.getFlowContextData() } )
820
+ };
821
+
822
+ }
823
+
824
+ renderer.contextNode = this._contextNodeCache.context;
825
+
826
+ }
761
827
 
762
828
  const currentSceneName = scene.name;
763
829
 
@@ -766,10 +832,14 @@ class PassNode extends TempNode {
766
832
  renderer.render( scene, camera );
767
833
 
768
834
  scene.name = currentSceneName;
835
+ scene.overrideMaterial = currentOverrideMaterial;
769
836
 
770
837
  renderer.setRenderTarget( currentRenderTarget );
771
838
  renderer.setMRT( currentMRT );
772
839
  renderer.autoClear = currentAutoClear;
840
+ renderer.transparent = currentTransparent;
841
+ renderer.opaque = currentOpaque;
842
+ renderer.contextNode = currentContextNode;
773
843
 
774
844
  camera.layers.mask = currentMask;
775
845
 
@@ -920,7 +990,7 @@ export default PassNode;
920
990
  * @param {Object} options - Options for the internal render target.
921
991
  * @returns {PassNode}
922
992
  */
923
- export const pass = ( scene, camera, options ) => nodeObject( new PassNode( PassNode.COLOR, scene, camera, options ) );
993
+ export const pass = ( scene, camera, options ) => new PassNode( PassNode.COLOR, scene, camera, options );
924
994
 
925
995
  /**
926
996
  * TSL function for creating a pass texture node.
@@ -931,7 +1001,7 @@ export const pass = ( scene, camera, options ) => nodeObject( new PassNode( Pass
931
1001
  * @param {Texture} texture - The output texture.
932
1002
  * @returns {PassTextureNode}
933
1003
  */
934
- export const passTexture = ( pass, texture ) => nodeObject( new PassTextureNode( pass, texture ) );
1004
+ export const passTexture = ( pass, texture ) => new PassTextureNode( pass, texture );
935
1005
 
936
1006
  /**
937
1007
  * TSL function for creating a depth pass node.
@@ -943,4 +1013,4 @@ export const passTexture = ( pass, texture ) => nodeObject( new PassTextureNode(
943
1013
  * @param {Object} options - Options for the internal render target.
944
1014
  * @returns {PassNode}
945
1015
  */
946
- export const depthPass = ( scene, camera, options ) => nodeObject( new PassNode( PassNode.DEPTH, scene, camera, options ) );
1016
+ export const depthPass = ( scene, camera, options ) => new PassNode( PassNode.DEPTH, scene, camera, options );
@@ -49,6 +49,7 @@ class ScreenNode extends Node {
49
49
  /**
50
50
  * This output node.
51
51
  *
52
+ * @private
52
53
  * @type {?Node}
53
54
  * @default null
54
55
  */
@@ -1,5 +1,5 @@
1
1
  import BRDF_GGX from './BRDF_GGX.js';
2
- import DFGApprox from './DFGApprox.js';
2
+ import DFGLUT from './DFGLUT.js';
3
3
  import { normalView } from '../../accessors/Normal.js';
4
4
  import { positionViewDirection } from '../../accessors/Position.js';
5
5
  import { EPSILON } from '../../math/MathNode.js';
@@ -19,8 +19,8 @@ const BRDF_GGX_Multiscatter = /*@__PURE__*/ Fn( ( { lightDirection, f0, f90, rou
19
19
  const dotNV = normalView.dot( positionViewDirection ).clamp();
20
20
 
21
21
  // Precomputed DFG values for view and light directions
22
- const dfgV = DFGApprox( { roughness: _roughness, dotNV } );
23
- const dfgL = DFGApprox( { roughness: _roughness, dotNV: dotNL } );
22
+ const dfgV = DFGLUT( { roughness: _roughness, dotNV } );
23
+ const dfgL = DFGLUT( { roughness: _roughness, dotNV: dotNL } );
24
24
 
25
25
  // Single-scattering energy for view and light
26
26
  const FssEss_V = f0.mul( dfgV.x ).add( f90.mul( dfgV.y ) );
@@ -0,0 +1,56 @@
1
+ import { Fn, vec2 } from '../../tsl/TSLBase.js';
2
+ import { texture } from '../../accessors/TextureNode.js';
3
+
4
+ import { DataTexture } from '../../../textures/DataTexture.js';
5
+ import { RGFormat, HalfFloatType, LinearFilter, ClampToEdgeWrapping } from '../../../constants.js';
6
+
7
+ /**
8
+ * Precomputed DFG LUT for Image-Based Lighting
9
+ * Resolution: 16x16
10
+ * Samples: 4096 per texel
11
+ * Format: RG16F (2 half floats per texel: scale, bias)
12
+ */
13
+
14
+ const DATA = new Uint16Array( [
15
+ 0x30b5, 0x3ad1, 0x314c, 0x3a4d, 0x33d2, 0x391c, 0x35ef, 0x3828, 0x37f3, 0x36a6, 0x38d1, 0x3539, 0x3979, 0x3410, 0x39f8, 0x3252, 0x3a53, 0x30f0, 0x3a94, 0x2fc9, 0x3abf, 0x2e35, 0x3ada, 0x2d05, 0x3ae8, 0x2c1f, 0x3aed, 0x2ae0, 0x3aea, 0x29d1, 0x3ae1, 0x28ff,
16
+ 0x3638, 0x38e4, 0x364a, 0x38ce, 0x3699, 0x385e, 0x374e, 0x372c, 0x3839, 0x35a4, 0x38dc, 0x3462, 0x396e, 0x32c4, 0x39de, 0x3134, 0x3a2b, 0x3003, 0x3a59, 0x2e3a, 0x3a6d, 0x2ce1, 0x3a6e, 0x2bba, 0x3a5f, 0x2a33, 0x3a49, 0x290a, 0x3a2d, 0x2826, 0x3a0a, 0x26e8,
17
+ 0x3894, 0x36d7, 0x3897, 0x36c9, 0x38a3, 0x3675, 0x38bc, 0x35ac, 0x38ee, 0x349c, 0x393e, 0x3332, 0x3997, 0x3186, 0x39e2, 0x3038, 0x3a13, 0x2e75, 0x3a29, 0x2cf5, 0x3a2d, 0x2bac, 0x3a21, 0x29ff, 0x3a04, 0x28bc, 0x39dc, 0x2790, 0x39ad, 0x261a, 0x3978, 0x24fa,
18
+ 0x39ac, 0x34a8, 0x39ac, 0x34a3, 0x39ae, 0x3480, 0x39ae, 0x3423, 0x39b1, 0x330e, 0x39c2, 0x31a9, 0x39e0, 0x3063, 0x39fc, 0x2eb5, 0x3a0c, 0x2d1d, 0x3a14, 0x2bcf, 0x3a07, 0x29ff, 0x39e9, 0x28a3, 0x39be, 0x273c, 0x3989, 0x25b3, 0x394a, 0x2488, 0x3907, 0x2345,
19
+ 0x3a77, 0x3223, 0x3a76, 0x321f, 0x3a73, 0x3204, 0x3a6a, 0x31b3, 0x3a58, 0x3114, 0x3a45, 0x303b, 0x3a34, 0x2eb6, 0x3a26, 0x2d31, 0x3a1e, 0x2bef, 0x3a0b, 0x2a0d, 0x39ec, 0x28a1, 0x39c0, 0x271b, 0x3987, 0x2580, 0x3944, 0x2449, 0x38fa, 0x22bd, 0x38ac, 0x2155,
20
+ 0x3b07, 0x2fca, 0x3b06, 0x2fca, 0x3b00, 0x2fb8, 0x3af4, 0x2f7c, 0x3adb, 0x2eea, 0x3ab4, 0x2e00, 0x3a85, 0x2cec, 0x3a5e, 0x2bc5, 0x3a36, 0x2a00, 0x3a0d, 0x2899, 0x39dc, 0x2707, 0x39a0, 0x2562, 0x395a, 0x2424, 0x390b, 0x2268, 0x38b7, 0x20fd, 0x385f, 0x1fd1,
21
+ 0x3b69, 0x2cb9, 0x3b68, 0x2cbb, 0x3b62, 0x2cbb, 0x3b56, 0x2cae, 0x3b3b, 0x2c78, 0x3b0d, 0x2c0a, 0x3acf, 0x2ae3, 0x3a92, 0x2998, 0x3a54, 0x2867, 0x3a17, 0x26d0, 0x39d3, 0x253c, 0x3989, 0x2402, 0x3935, 0x2226, 0x38dc, 0x20bd, 0x387d, 0x1f54, 0x381d, 0x1db3,
22
+ 0x3ba9, 0x296b, 0x3ba8, 0x296f, 0x3ba3, 0x297b, 0x3b98, 0x2987, 0x3b7f, 0x2976, 0x3b4e, 0x2927, 0x3b0e, 0x2895, 0x3ac2, 0x27b7, 0x3a73, 0x263b, 0x3a23, 0x24e7, 0x39d0, 0x239b, 0x3976, 0x21d9, 0x3917, 0x207e, 0x38b2, 0x1ee7, 0x384b, 0x1d53, 0x37c7, 0x1c1e,
23
+ 0x3bd2, 0x25cb, 0x3bd1, 0x25d3, 0x3bcd, 0x25f0, 0x3bc2, 0x261f, 0x3bad, 0x2645, 0x3b7d, 0x262d, 0x3b3e, 0x25c4, 0x3aec, 0x250f, 0x3a93, 0x243a, 0x3a32, 0x22ce, 0x39d0, 0x215b, 0x3969, 0x202a, 0x38fe, 0x1e6e, 0x388f, 0x1cf1, 0x381f, 0x1b9b, 0x3762, 0x19dd,
24
+ 0x3be9, 0x21ab, 0x3be9, 0x21b7, 0x3be5, 0x21e5, 0x3bdd, 0x2241, 0x3bc9, 0x22a7, 0x3ba0, 0x22ec, 0x3b62, 0x22cd, 0x3b0f, 0x2247, 0x3aae, 0x2175, 0x3a44, 0x2088, 0x39d4, 0x1f49, 0x3960, 0x1dbe, 0x38e9, 0x1c77, 0x3870, 0x1ae8, 0x37f1, 0x1953, 0x3708, 0x181b,
25
+ 0x3bf6, 0x1cea, 0x3bf6, 0x1cfb, 0x3bf3, 0x1d38, 0x3bec, 0x1dbd, 0x3bda, 0x1e7c, 0x3bb7, 0x1f25, 0x3b7d, 0x1f79, 0x3b2c, 0x1f4c, 0x3ac6, 0x1ea6, 0x3a55, 0x1dbb, 0x39da, 0x1cbd, 0x395a, 0x1b9d, 0x38d8, 0x1a00, 0x3855, 0x18ac, 0x37ab, 0x173c, 0x36b7, 0x1598,
26
+ 0x3bfc, 0x1736, 0x3bfc, 0x1759, 0x3bf9, 0x17e7, 0x3bf4, 0x1896, 0x3be4, 0x1997, 0x3bc6, 0x1aa8, 0x3b91, 0x1b84, 0x3b43, 0x1bd2, 0x3ade, 0x1b8a, 0x3a65, 0x1acd, 0x39e2, 0x19d3, 0x3957, 0x18cd, 0x38ca, 0x17b3, 0x383e, 0x1613, 0x376d, 0x14bf, 0x366f, 0x135e,
27
+ 0x3bff, 0x101b, 0x3bff, 0x1039, 0x3bfc, 0x10c8, 0x3bf9, 0x1226, 0x3bea, 0x1428, 0x3bcf, 0x1584, 0x3b9f, 0x16c5, 0x3b54, 0x179a, 0x3af0, 0x17ce, 0x3a76, 0x1771, 0x39ea, 0x16a4, 0x3956, 0x15a7, 0x38bf, 0x14a7, 0x3829, 0x1379, 0x3735, 0x11ea, 0x362d, 0x10a1,
28
+ 0x3c00, 0x061b, 0x3c00, 0x066a, 0x3bfe, 0x081c, 0x3bfa, 0x0a4c, 0x3bed, 0x0d16, 0x3bd5, 0x0fb3, 0x3ba9, 0x114d, 0x3b63, 0x127c, 0x3b01, 0x132f, 0x3a85, 0x1344, 0x39f4, 0x12d2, 0x3957, 0x120d, 0x38b5, 0x1122, 0x3817, 0x103c, 0x3703, 0x0ed3, 0x35f0, 0x0d6d,
29
+ 0x3c00, 0x007a, 0x3c00, 0x0089, 0x3bfe, 0x011d, 0x3bfb, 0x027c, 0x3bf0, 0x04fa, 0x3bda, 0x0881, 0x3bb1, 0x0acd, 0x3b6f, 0x0c97, 0x3b10, 0x0d7b, 0x3a93, 0x0df1, 0x39fe, 0x0def, 0x3959, 0x0d8a, 0x38af, 0x0ce9, 0x3808, 0x0c31, 0x36d5, 0x0af0, 0x35b9, 0x09a3,
30
+ 0x3c00, 0x0000, 0x3c00, 0x0001, 0x3bff, 0x0015, 0x3bfb, 0x0059, 0x3bf2, 0x00fd, 0x3bdd, 0x01df, 0x3bb7, 0x031c, 0x3b79, 0x047c, 0x3b1d, 0x05d4, 0x3aa0, 0x06d5, 0x3a08, 0x075a, 0x395d, 0x075e, 0x38aa, 0x06f7, 0x37f4, 0x0648, 0x36ac, 0x0576, 0x3586, 0x049f
31
+ ] );
32
+
33
+ let lut = null;
34
+
35
+ const DFGLUT = /*@__PURE__*/ Fn( ( { roughness, dotNV } ) => {
36
+
37
+ if ( lut === null ) {
38
+
39
+ lut = new DataTexture( DATA, 16, 16, RGFormat, HalfFloatType );
40
+ lut.name = 'DFG_LUT';
41
+ lut.minFilter = LinearFilter;
42
+ lut.magFilter = LinearFilter;
43
+ lut.wrapS = ClampToEdgeWrapping;
44
+ lut.wrapT = ClampToEdgeWrapping;
45
+ lut.generateMipmaps = false;
46
+ lut.needsUpdate = true;
47
+
48
+ }
49
+
50
+ const uv = vec2( roughness, dotNV );
51
+
52
+ return texture( lut, uv ).rg;
53
+
54
+ } );
55
+
56
+ export default DFGLUT;
@@ -1,11 +1,11 @@
1
- import DFGApprox from './DFGApprox.js';
1
+ import DFGLUT from './DFGLUT.js';
2
2
  import { Fn } from '../../tsl/TSLBase.js';
3
3
 
4
4
  const EnvironmentBRDF = /*@__PURE__*/ Fn( ( inputs ) => {
5
5
 
6
6
  const { dotNV, specularColor, specularF90, roughness } = inputs;
7
7
 
8
- const fab = DFGApprox( { dotNV, roughness } );
8
+ const fab = DFGLUT( { dotNV, roughness } );
9
9
  return specularColor.mul( fab.x ).add( specularF90.mul( fab.y ) );
10
10
 
11
11
  } );
@@ -9,7 +9,7 @@ const V_GGX_SmithCorrelated_Anisotropic = /*@__PURE__*/ Fn( ( { alphaT, alphaB,
9
9
  const gl = dotNV.mul( vec3( alphaT.mul( dotTL ), alphaB.mul( dotBL ), dotNL ).length() );
10
10
  const v = div( 0.5, gv.add( gl ) );
11
11
 
12
- return v.saturate();
12
+ return v;
13
13
 
14
14
  } ).setLayout( {
15
15
  name: 'V_GGX_SmithCorrelated_Anisotropic',