@plastic-software/three 0.179.0 → 0.180.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/build/three.cjs +167 -107
  2. package/build/three.core.js +112 -20
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +56 -90
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +30 -5
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +2896 -1048
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +2896 -1048
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +1 -1
  13. package/examples/jsm/controls/ArcballControls.js +7 -7
  14. package/examples/jsm/controls/DragControls.js +6 -56
  15. package/examples/jsm/controls/FirstPersonControls.js +2 -2
  16. package/examples/jsm/controls/PointerLockControls.js +0 -8
  17. package/examples/jsm/exporters/GLTFExporter.js +30 -22
  18. package/examples/jsm/exporters/KTX2Exporter.js +4 -2
  19. package/examples/jsm/exporters/PLYExporter.js +1 -1
  20. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  21. package/examples/jsm/lines/Line2.js +3 -3
  22. package/examples/jsm/lines/LineGeometry.js +1 -1
  23. package/examples/jsm/lines/LineSegments2.js +2 -2
  24. package/examples/jsm/lines/Wireframe.js +2 -2
  25. package/examples/jsm/lines/WireframeGeometry2.js +1 -1
  26. package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
  27. package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
  28. package/examples/jsm/loaders/ColladaLoader.js +1 -1
  29. package/examples/jsm/loaders/EXRLoader.js +5 -5
  30. package/examples/jsm/loaders/GLTFLoader.js +9 -5
  31. package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
  32. package/examples/jsm/loaders/HDRLoader.js +486 -0
  33. package/examples/jsm/loaders/KTX2Loader.js +112 -32
  34. package/examples/jsm/loaders/RGBELoader.js +7 -473
  35. package/examples/jsm/loaders/TTFLoader.js +4 -4
  36. package/examples/jsm/loaders/UltraHDRLoader.js +1 -1
  37. package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
  38. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  39. package/examples/jsm/math/ColorSpaces.js +19 -1
  40. package/examples/jsm/math/ConvexHull.js +2 -2
  41. package/examples/jsm/math/Lut.js +2 -2
  42. package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
  43. package/examples/jsm/misc/ProgressiveLightMap.js +1 -1
  44. package/examples/jsm/misc/Volume.js +1 -1
  45. package/examples/jsm/postprocessing/OutlinePass.js +1 -1
  46. package/examples/jsm/postprocessing/SSRPass.js +37 -8
  47. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +1 -1
  48. package/examples/jsm/transpiler/GLSLDecoder.js +22 -19
  49. package/examples/jsm/transpiler/TSLEncoder.js +2 -10
  50. package/examples/jsm/transpiler/WGSLEncoder.js +24 -0
  51. package/examples/jsm/tsl/display/AnamorphicNode.js +27 -4
  52. package/examples/jsm/tsl/display/BloomNode.js +3 -3
  53. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +2 -1
  54. package/examples/jsm/tsl/display/DepthOfFieldNode.js +439 -90
  55. package/examples/jsm/tsl/display/GTAONode.js +8 -0
  56. package/examples/jsm/tsl/display/GaussianBlurNode.js +47 -35
  57. package/examples/jsm/tsl/display/OutlineNode.js +2 -2
  58. package/examples/jsm/tsl/display/SSRNode.js +180 -65
  59. package/examples/jsm/tsl/display/TRAANode.js +1 -1
  60. package/examples/jsm/tsl/display/boxBlur.js +64 -0
  61. package/examples/jsm/tsl/display/hashBlur.js +15 -18
  62. package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
  63. package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
  64. package/examples/jsm/webxr/OculusHandModel.js +1 -1
  65. package/package.json +1 -1
  66. package/src/Three.Core.js +1 -0
  67. package/src/Three.TSL.js +29 -4
  68. package/src/animation/AnimationClip.js +17 -2
  69. package/src/constants.js +11 -3
  70. package/src/core/BufferGeometry.js +2 -2
  71. package/src/extras/TextureUtils.js +2 -1
  72. package/src/extras/lib/earcut.js +1 -1
  73. package/src/lights/webgpu/ProjectorLight.js +1 -1
  74. package/src/materials/Material.js +12 -0
  75. package/src/materials/MeshDistanceMaterial.js +1 -1
  76. package/src/materials/nodes/PointsNodeMaterial.js +81 -28
  77. package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
  78. package/src/materials/nodes/manager/NodeMaterialObserver.js +1 -1
  79. package/src/math/ColorManagement.js +7 -1
  80. package/src/nodes/Nodes.js +3 -0
  81. package/src/nodes/TSL.js +3 -0
  82. package/src/nodes/accessors/BufferNode.js +1 -1
  83. package/src/nodes/accessors/Camera.js +133 -7
  84. package/src/nodes/accessors/ClippingNode.js +6 -5
  85. package/src/nodes/accessors/CubeTextureNode.js +2 -2
  86. package/src/nodes/accessors/InstanceNode.js +3 -1
  87. package/src/nodes/accessors/Object3DNode.js +1 -1
  88. package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
  89. package/src/nodes/accessors/ReferenceNode.js +1 -1
  90. package/src/nodes/accessors/Texture3DNode.js +13 -0
  91. package/src/nodes/accessors/TextureNode.js +71 -19
  92. package/src/nodes/code/FunctionCallNode.js +19 -0
  93. package/src/nodes/code/FunctionNode.js +23 -0
  94. package/src/nodes/core/AssignNode.js +4 -3
  95. package/src/nodes/core/ContextNode.js +24 -0
  96. package/src/nodes/core/Node.js +16 -20
  97. package/src/nodes/core/NodeBuilder.js +48 -14
  98. package/src/nodes/core/NodeFrame.js +1 -1
  99. package/src/nodes/core/NodeUniform.js +1 -1
  100. package/src/nodes/core/NodeUtils.js +1 -2
  101. package/src/nodes/core/StackNode.js +29 -4
  102. package/src/nodes/core/StructNode.js +5 -5
  103. package/src/nodes/core/StructTypeNode.js +1 -0
  104. package/src/nodes/core/SubBuildNode.js +2 -2
  105. package/src/nodes/core/UniformNode.js +16 -9
  106. package/src/nodes/core/VarNode.js +0 -21
  107. package/src/nodes/display/FrontFacingNode.js +4 -8
  108. package/src/nodes/display/PassNode.js +1 -1
  109. package/src/nodes/display/ScreenNode.js +42 -13
  110. package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
  111. package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
  112. package/src/nodes/display/ViewportTextureNode.js +42 -12
  113. package/src/nodes/gpgpu/SubgroupFunctionNode.js +430 -0
  114. package/src/nodes/lighting/LightsNode.js +1 -1
  115. package/src/nodes/math/BitcastNode.js +156 -0
  116. package/src/nodes/math/ConditionalNode.js +18 -2
  117. package/src/nodes/math/MathNode.js +3 -15
  118. package/src/nodes/math/OperatorNode.js +4 -3
  119. package/src/nodes/tsl/TSLCore.js +432 -152
  120. package/src/nodes/utils/JoinNode.js +3 -1
  121. package/src/nodes/utils/MemberNode.js +58 -7
  122. package/src/nodes/utils/RTTNode.js +1 -1
  123. package/src/nodes/utils/ReflectorNode.js +51 -7
  124. package/src/nodes/utils/SampleNode.js +12 -2
  125. package/src/nodes/utils/SplitNode.js +11 -0
  126. package/src/nodes/utils/Timer.js +0 -47
  127. package/src/objects/BatchedMesh.js +2 -2
  128. package/src/objects/LOD.js +1 -1
  129. package/src/objects/Sprite.js +2 -2
  130. package/src/renderers/WebGLRenderer.js +1 -10
  131. package/src/renderers/common/Attributes.js +1 -1
  132. package/src/renderers/common/Backend.js +19 -1
  133. package/src/renderers/common/Bindings.js +2 -0
  134. package/src/renderers/common/ChainMap.js +1 -1
  135. package/src/renderers/common/DataMap.js +1 -1
  136. package/src/renderers/common/Pipelines.js +1 -1
  137. package/src/renderers/common/RenderContext.js +2 -2
  138. package/src/renderers/common/RenderObject.js +14 -2
  139. package/src/renderers/common/Renderer.js +39 -19
  140. package/src/renderers/common/SampledTexture.js +1 -1
  141. package/src/renderers/common/Sampler.js +25 -13
  142. package/src/renderers/common/Textures.js +34 -12
  143. package/src/renderers/common/TimestampQueryPool.js +3 -3
  144. package/src/renderers/common/XRManager.js +35 -19
  145. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  146. package/src/renderers/common/nodes/NodeLibrary.js +5 -5
  147. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  148. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  149. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  150. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  151. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +7 -15
  152. package/src/renderers/shaders/ShaderLib/depth.glsl.js +1 -1
  153. package/src/renderers/webgl/WebGLProgram.js +4 -4
  154. package/src/renderers/webgl/WebGLShadowMap.js +1 -1
  155. package/src/renderers/webgl/WebGLTextures.js +1 -0
  156. package/src/renderers/webgl/WebGLUtils.js +3 -2
  157. package/src/renderers/webgl-fallback/WebGLBackend.js +186 -135
  158. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +110 -17
  159. package/src/renderers/webgl-fallback/utils/WebGLState.js +1 -1
  160. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -3
  161. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -10
  162. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
  163. package/src/renderers/webgpu/WebGPUBackend.js +35 -31
  164. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +124 -34
  165. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -2
  166. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +9 -18
  167. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +114 -25
  168. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +3 -3
  169. package/src/renderers/webxr/WebXRManager.js +39 -24
  170. package/src/textures/ExternalTexture.js +15 -4
  171. package/src/textures/Source.js +1 -1
  172. package/src/textures/VideoTexture.js +0 -3
  173. package/examples/jsm/loaders/RGBMLoader.js +0 -1148
@@ -0,0 +1,430 @@
1
+ import TempNode from '../core/TempNode.js';
2
+ import { nodeProxyIntent } from '../tsl/TSLCore.js';
3
+
4
+
5
+ /**
6
+ * This class represents a set of built in WGSL shader functions that sync
7
+ * synchronously execute an operation across a subgroup, or 'warp', of compute
8
+ * or fragment shader invocations within a workgroup. Typically, these functions
9
+ * will synchronously execute an operation using data from all active invocations
10
+ * within the subgroup, then broadcast that result to all active invocations. In
11
+ * other graphics APIs, subgroup functions are also referred to as wave intrinsics
12
+ * (DirectX/HLSL) or warp intrinsics (CUDA).
13
+ *
14
+ * @augments TempNode
15
+ */
16
+ class SubgroupFunctionNode extends TempNode {
17
+
18
+ static get type() {
19
+
20
+ return 'SubgroupFunctionNode';
21
+
22
+ }
23
+
24
+ /**
25
+ * Constructs a new function node.
26
+ *
27
+ * @param {string} method - The subgroup/wave intrinsic method to construct.
28
+ * @param {Node} [aNode=null] - The method's first argument.
29
+ * @param {Node} [bNode=null] - The method's second argument.
30
+ */
31
+ constructor( method, aNode = null, bNode = null ) {
32
+
33
+ super();
34
+
35
+ /**
36
+ * The subgroup/wave intrinsic method to construct.
37
+ *
38
+ * @type {String}
39
+ */
40
+ this.method = method;
41
+
42
+ /**
43
+ * The method's first argument.
44
+ *
45
+ * @type {Node}
46
+ */
47
+ this.aNode = aNode;
48
+
49
+ /**
50
+ * The method's second argument.
51
+ *
52
+ * @type {Node}
53
+ */
54
+ this.bNode = bNode;
55
+
56
+ }
57
+
58
+ getInputType( builder ) {
59
+
60
+ const aType = this.aNode ? this.aNode.getNodeType( builder ) : null;
61
+ const bType = this.bNode ? this.bNode.getNodeType( builder ) : null;
62
+
63
+ const aLen = builder.isMatrix( aType ) ? 0 : builder.getTypeLength( aType );
64
+ const bLen = builder.isMatrix( bType ) ? 0 : builder.getTypeLength( bType );
65
+
66
+ if ( aLen > bLen ) {
67
+
68
+ return aType;
69
+
70
+ } else {
71
+
72
+ return bType;
73
+
74
+ }
75
+
76
+ }
77
+
78
+ getNodeType( builder ) {
79
+
80
+ const method = this.method;
81
+
82
+ if ( method === SubgroupFunctionNode.SUBGROUP_ELECT ) {
83
+
84
+ return 'bool';
85
+
86
+ } else if ( method === SubgroupFunctionNode.SUBGROUP_BALLOT ) {
87
+
88
+ return 'uvec4';
89
+
90
+ } else {
91
+
92
+ return this.getInputType( builder );
93
+
94
+ }
95
+
96
+ }
97
+
98
+ generate( builder, output ) {
99
+
100
+ const method = this.method;
101
+
102
+ const type = this.getNodeType( builder );
103
+ const inputType = this.getInputType( builder );
104
+
105
+ const a = this.aNode;
106
+ const b = this.bNode;
107
+
108
+ const params = [];
109
+
110
+ if (
111
+ method === SubgroupFunctionNode.SUBGROUP_BROADCAST ||
112
+ method === SubgroupFunctionNode.SUBGROUP_SHUFFLE ||
113
+ method === SubgroupFunctionNode.QUAD_BROADCAST
114
+ ) {
115
+
116
+ const bType = b.getNodeType( builder );
117
+
118
+ params.push(
119
+ a.build( builder, type ),
120
+ b.build( builder, bType === 'float' ? 'int' : type )
121
+ );
122
+
123
+ } else if (
124
+ method === SubgroupFunctionNode.SUBGROUP_SHUFFLE_XOR ||
125
+ method === SubgroupFunctionNode.SUBGROUP_SHUFFLE_DOWN ||
126
+ method === SubgroupFunctionNode.SUBGROUP_SHUFFLE_UP
127
+ ) {
128
+
129
+ params.push(
130
+ a.build( builder, type ),
131
+ b.build( builder, 'uint' )
132
+ );
133
+
134
+ } else {
135
+
136
+ if ( a !== null ) params.push( a.build( builder, inputType ) );
137
+ if ( b !== null ) params.push( b.build( builder, inputType ) );
138
+
139
+ }
140
+
141
+ const paramsString = params.length === 0 ? '()' : `( ${params.join( ', ' )} )`;
142
+
143
+ return builder.format( `${ builder.getMethod( method, type ) }${paramsString}`, type, output );
144
+
145
+
146
+
147
+ }
148
+
149
+ serialize( data ) {
150
+
151
+ super.serialize( data );
152
+
153
+ data.method = this.method;
154
+
155
+ }
156
+
157
+ deserialize( data ) {
158
+
159
+ super.deserialize( data );
160
+
161
+ this.method = data.method;
162
+
163
+ }
164
+
165
+ }
166
+
167
+ // 0 inputs
168
+ SubgroupFunctionNode.SUBGROUP_ELECT = 'subgroupElect';
169
+
170
+ // 1 input
171
+ SubgroupFunctionNode.SUBGROUP_BALLOT = 'subgroupBallot';
172
+ SubgroupFunctionNode.SUBGROUP_ADD = 'subgroupAdd';
173
+ SubgroupFunctionNode.SUBGROUP_INCLUSIVE_ADD = 'subgroupInclusiveAdd';
174
+ SubgroupFunctionNode.SUBGROUP_EXCLUSIVE_AND = 'subgroupExclusiveAdd';
175
+ SubgroupFunctionNode.SUBGROUP_MUL = 'subgroupMul';
176
+ SubgroupFunctionNode.SUBGROUP_INCLUSIVE_MUL = 'subgroupInclusiveMul';
177
+ SubgroupFunctionNode.SUBGROUP_EXCLUSIVE_MUL = 'subgroupExclusiveMul';
178
+ SubgroupFunctionNode.SUBGROUP_AND = 'subgroupAnd';
179
+ SubgroupFunctionNode.SUBGROUP_OR = 'subgroupOr';
180
+ SubgroupFunctionNode.SUBGROUP_XOR = 'subgroupXor';
181
+ SubgroupFunctionNode.SUBGROUP_MIN = 'subgroupMin';
182
+ SubgroupFunctionNode.SUBGROUP_MAX = 'subgroupMax';
183
+ SubgroupFunctionNode.SUBGROUP_ALL = 'subgroupAll';
184
+ SubgroupFunctionNode.SUBGROUP_ANY = 'subgroupAny';
185
+ SubgroupFunctionNode.SUBGROUP_BROADCAST_FIRST = 'subgroupBroadcastFirst';
186
+ SubgroupFunctionNode.QUAD_SWAP_X = 'quadSwapX';
187
+ SubgroupFunctionNode.QUAD_SWAP_Y = 'quadSwapY';
188
+ SubgroupFunctionNode.QUAD_SWAP_DIAGONAL = 'quadSwapDiagonal';
189
+
190
+ // 2 inputs
191
+ SubgroupFunctionNode.SUBGROUP_BROADCAST = 'subgroupBroadcast';
192
+ SubgroupFunctionNode.SUBGROUP_SHUFFLE = 'subgroupShuffle';
193
+ SubgroupFunctionNode.SUBGROUP_SHUFFLE_XOR = 'subgroupShuffleXor';
194
+ SubgroupFunctionNode.SUBGROUP_SHUFFLE_UP = 'subgroupShuffleUp';
195
+ SubgroupFunctionNode.SUBGROUP_SHUFFLE_DOWN = 'subgroupShuffleDown';
196
+ SubgroupFunctionNode.QUAD_BROADCAST = 'quadBroadcast';
197
+
198
+ export default SubgroupFunctionNode;
199
+
200
+
201
+
202
+ /**
203
+ * Returns true if this invocation has the lowest subgroup_invocation_id
204
+ * among active invocations in the subgroup.
205
+ *
206
+ * @method
207
+ * @return {bool} The result of the computation.
208
+ */
209
+ export const subgroupElect = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_ELECT ).setParameterLength( 0 );
210
+
211
+ /**
212
+ * Returns a set of bitfields where the bit corresponding to subgroup_invocation_id
213
+ * is 1 if pred is true for that active invocation and 0 otherwise.
214
+ *
215
+ * @method
216
+ * @param {bool} pred - A boolean that sets the bit corresponding to the invocations subgroup invocation id.
217
+ * @return {vec4<u32>}- A bitfield corresponding to the pred value of each subgroup invocation.
218
+ */
219
+ export const subgroupBallot = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_BALLOT ).setParameterLength( 1 );
220
+
221
+ /**
222
+ * A reduction that adds e among all active invocations and returns that result.
223
+ *
224
+ * @method
225
+ * @param {number} e - The value provided to the reduction by the current invocation.
226
+ * @return {number} The accumulated result of the reduction operation.
227
+ */
228
+ export const subgroupAdd = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_ADD ).setParameterLength( 1 );
229
+
230
+ /**
231
+ * An inclusive scan returning the sum of e for all active invocations with subgroup_invocation_id less than or equal to this invocation.
232
+ *
233
+ * @method
234
+ * @param {number} e - The value provided to the inclusive scan by the current invocation.
235
+ * @return {number} The accumulated result of the inclusive scan operation.
236
+ */
237
+ export const subgroupInclusiveAdd = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_INCLUSIVE_ADD ).setParameterLength( 1 );
238
+
239
+ /**
240
+ * An exclusive scan that returns the sum of e for all active invocations with subgroup_invocation_id less than this invocation.
241
+ *
242
+ * @method
243
+ * @param {number} e - The value provided to the exclusive scan by the current invocation.
244
+ * @return {number} The accumulated result of the exclusive scan operation.
245
+ */
246
+ export const subgroupExclusiveAdd = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_EXCLUSIVE_AND ).setParameterLength( 1 );
247
+
248
+ /**
249
+ * A reduction that multiplies e among all active invocations and returns that result.
250
+ *
251
+ * @method
252
+ * @param {number} e - The value provided to the reduction by the current invocation.
253
+ * @return {number} The accumulated result of the reduction operation.
254
+ */
255
+ export const subgroupMul = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_MUL ).setParameterLength( 1 );
256
+
257
+ /**
258
+ * An inclusive scan returning the product of e for all active invocations with subgroup_invocation_id less than or equal to this invocation.
259
+ *
260
+ * @method
261
+ * @param {number} e - The value provided to the inclusive scan by the current invocation.
262
+ * @return {number} The accumulated result of the inclusive scan operation.
263
+ */
264
+ export const subgroupInclusiveMul = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_INCLUSIVE_MUL ).setParameterLength( 1 );
265
+
266
+ /**
267
+ * An exclusive scan that returns the product of e for all active invocations with subgroup_invocation_id less than this invocation.
268
+ *
269
+ * @method
270
+ * @param {number} e - The value provided to the exclusive scan by the current invocation.
271
+ * @return {number} The accumulated result of the exclusive scan operation.
272
+ */
273
+ export const subgroupExclusiveMul = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_EXCLUSIVE_MUL ).setParameterLength( 1 );
274
+
275
+ /**
276
+ * A reduction that performs a bitwise and of e among all active invocations and returns that result.
277
+ *
278
+ * @method
279
+ * @param {number} e - The value provided to the reduction by the current invocation.
280
+ * @return {number} The result of the reduction operation.
281
+ */
282
+ export const subgroupAnd = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_AND ).setParameterLength( 1 );
283
+
284
+ /**
285
+ * A reduction that performs a bitwise or of e among all active invocations and returns that result.
286
+ *
287
+ * @method
288
+ * @param {number} e - The value provided to the reduction by the current invocation.
289
+ * @return {number} The result of the reduction operation.
290
+ */
291
+ export const subgroupOr = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_OR ).setParameterLength( 1 );
292
+
293
+ /**
294
+ * A reduction that performs a bitwise xor of e among all active invocations and returns that result.
295
+ *
296
+ * @method
297
+ * @param {number} e - The value provided to the reduction by the current invocation.
298
+ * @return {number} The result of the reduction operation.
299
+ */
300
+ export const subgroupXor = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_XOR ).setParameterLength( 1 );
301
+
302
+ /**
303
+ * A reduction that performs a min of e among all active invocations and returns that result.
304
+ *
305
+ * @method
306
+ * @param {number} e - The value provided to the reduction by the current invocation.
307
+ * @return {number} The result of the reduction operation.
308
+ */
309
+ export const subgroupMin = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_MIN ).setParameterLength( 1 );
310
+
311
+ /**
312
+ * A reduction that performs a max of e among all active invocations and returns that result.
313
+ *
314
+ * @method
315
+ * @param {number} e - The value provided to the reduction by the current invocation.
316
+ * @return {number} The result of the reduction operation.
317
+ */
318
+ export const subgroupMax = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_MAX ).setParameterLength( 1 );
319
+
320
+ /**
321
+ * Returns true if e is true for all active invocations in the subgroup.
322
+ *
323
+ * @method
324
+ * @return {bool} The result of the computation.
325
+ */
326
+ export const subgroupAll = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_ALL ).setParameterLength( 0 );
327
+
328
+ /**
329
+ * Returns true if e is true for any active invocation in the subgroup
330
+ *
331
+ * @method
332
+ * @return {bool} The result of the computation.
333
+ */
334
+ export const subgroupAny = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_ANY ).setParameterLength( 0 );
335
+
336
+ /**
337
+ * Broadcasts e from the active invocation with the lowest subgroup_invocation_id in the subgroup to all other active invocations.
338
+ *
339
+ * @method
340
+ * @param {number} e - The value to broadcast from the lowest subgroup invocation.
341
+ * @param {number} id - The subgroup invocation to broadcast from.
342
+ * @return {number} The broadcast value.
343
+ */
344
+ export const subgroupBroadcastFirst = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_BROADCAST_FIRST ).setParameterLength( 2 );
345
+
346
+ /**
347
+ * Swaps e between invocations in the quad in the X direction.
348
+ *
349
+ * @method
350
+ * @param {number} e - The value to swap from the current invocation.
351
+ * @return {number} The value received from the swap operation.
352
+ */
353
+ export const quadSwapX = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.QUAD_SWAP_X ).setParameterLength( 1 );
354
+
355
+ /**
356
+ * Swaps e between invocations in the quad in the Y direction.
357
+ *
358
+ * @method
359
+ * @param {number} e - The value to swap from the current invocation.
360
+ * @return {number} The value received from the swap operation.
361
+ */
362
+ export const quadSwapY = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.QUAD_SWAP_Y ).setParameterLength( 1 );
363
+
364
+ /**
365
+ * Swaps e between invocations in the quad diagonally.
366
+ *
367
+ * @method
368
+ * @param {number} e - The value to swap from the current invocation.
369
+ * @return {number} The value received from the swap operation.
370
+ */
371
+ export const quadSwapDiagonal = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.QUAD_SWAP_DIAGONAL ).setParameterLength( 1 );
372
+
373
+ /**
374
+ * Broadcasts e from the invocation whose subgroup_invocation_id matches id, to all active invocations.
375
+ *
376
+ * @method
377
+ * @param {number} e - The value to broadcast from subgroup invocation 'id'.
378
+ * @param {number} id - The subgroup invocation to broadcast from.
379
+ * @return {number} The broadcast value.
380
+ */
381
+ export const subgroupBroadcast = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_BROADCAST ).setParameterLength( 2 );
382
+
383
+ /**
384
+ * Returns v from the active invocation whose subgroup_invocation_id matches id
385
+ *
386
+ * @method
387
+ * @param {number} v - The value to return from subgroup invocation id^mask.
388
+ * @param {number} id - The subgroup invocation which returns the value v.
389
+ * @return {number} The broadcast value.
390
+ */
391
+ export const subgroupShuffle = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_SHUFFLE ).setParameterLength( 2 );
392
+
393
+ /**
394
+ * Returns v from the active invocation whose subgroup_invocation_id matches subgroup_invocation_id ^ mask.
395
+ *
396
+ * @method
397
+ * @param {number} v - The value to return from subgroup invocation id^mask.
398
+ * @param {number} mask - A bitmask that determines the target invocation via a XOR operation.
399
+ * @return {number} The broadcast value.
400
+ */
401
+ export const subgroupShuffleXor = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_SHUFFLE_XOR ).setParameterLength( 2 );
402
+
403
+ /**
404
+ * Returns v from the active invocation whose subgroup_invocation_id matches subgroup_invocation_id - delta
405
+ *
406
+ * @method
407
+ * @param {number} v - The value to return from subgroup invocation id^mask.
408
+ * @param {number} delta - A value that offsets the current in.
409
+ * @return {number} The broadcast value.
410
+ */
411
+ export const subgroupShuffleUp = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_SHUFFLE_UP ).setParameterLength( 2 );
412
+
413
+ /**
414
+ * Returns v from the active invocation whose subgroup_invocation_id matches subgroup_invocation_id + delta
415
+ *
416
+ * @method
417
+ * @param {number} v - The value to return from subgroup invocation id^mask.
418
+ * @param {number} delta - A value that offsets the current subgroup invocation.
419
+ * @return {number} The broadcast value.
420
+ */
421
+ export const subgroupShuffleDown = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.SUBGROUP_SHUFFLE_DOWN ).setParameterLength( 2 );
422
+
423
+ /**
424
+ * Broadcasts e from the quad invocation with id equal to id.
425
+ *
426
+ * @method
427
+ * @param {number} e - The value to broadcast.
428
+ * @return {number} The broadcast value.
429
+ */
430
+ export const quadBroadcast = /*@__PURE__*/ nodeProxyIntent( SubgroupFunctionNode, SubgroupFunctionNode.QUAD_BROADCAST ).setParameterLength( 1 );
@@ -159,7 +159,7 @@ class LightsNode extends Node {
159
159
 
160
160
  for ( const lightNode of this._lightNodes ) {
161
161
 
162
- hash.push( lightNode.getSelf().getHash() );
162
+ hash.push( lightNode.getHash() );
163
163
 
164
164
  }
165
165
 
@@ -0,0 +1,156 @@
1
+ import TempNode from '../core/TempNode.js';
2
+ import { nodeProxyIntent } from '../tsl/TSLCore.js';
3
+ /**
4
+ * This node represents an operation that reinterprets the bit representation of a value
5
+ * in one type as a value in another type.
6
+ *
7
+ * @augments TempNode
8
+ */
9
+ class BitcastNode extends TempNode {
10
+
11
+ static get type() {
12
+
13
+ return 'BitcastNode';
14
+
15
+ }
16
+
17
+ /**
18
+ * Constructs a new bitcast node.
19
+ *
20
+ * @param {Node} valueNode - The value to convert.
21
+ * @param {string} conversionType - The type to convert to.
22
+ * @param {?string} [inputType = null] - The expected input data type of the bitcast operation.
23
+ */
24
+ constructor( valueNode, conversionType, inputType = null ) {
25
+
26
+ super();
27
+
28
+ /**
29
+ * The data to bitcast to a new type.
30
+ *
31
+ * @type {Node}
32
+ */
33
+ this.valueNode = valueNode;
34
+
35
+ /**
36
+ * The type the value will be converted to.
37
+ *
38
+ * @type {string}
39
+ */
40
+ this.conversionType = conversionType;
41
+
42
+
43
+ /**
44
+ * The expected input data type of the bitcast operation.
45
+ *
46
+ *
47
+ * @type {string}
48
+ * @default null
49
+ */
50
+ this.inputType = inputType;
51
+
52
+ /**
53
+ * This flag can be used for type testing.
54
+ *
55
+ * @type {boolean}
56
+ * @readonly
57
+ * @default true
58
+ */
59
+ this.isBitcastNode = true;
60
+
61
+ }
62
+
63
+ getNodeType( builder ) {
64
+
65
+ // GLSL aliasing
66
+ if ( this.inputType !== null ) {
67
+
68
+ const valueType = this.valueNode.getNodeType( builder );
69
+ const valueLength = builder.getTypeLength( valueType );
70
+
71
+ return builder.getTypeFromLength( valueLength, this.conversionType );
72
+
73
+ }
74
+
75
+ return this.conversionType;
76
+
77
+ }
78
+
79
+
80
+ generate( builder ) {
81
+
82
+ const type = this.getNodeType( builder );
83
+ let inputType = '';
84
+
85
+ if ( this.inputType !== null ) {
86
+
87
+ const valueType = this.valueNode.getNodeType( builder );
88
+ const valueTypeLength = builder.getTypeLength( valueType );
89
+
90
+ inputType = valueTypeLength === 1 ? this.inputType : builder.changeComponentType( valueType, this.inputType );
91
+
92
+ } else {
93
+
94
+ inputType = this.valueNode.getNodeType( builder );
95
+
96
+ }
97
+
98
+ return `${ builder.getBitcastMethod( type, inputType ) }( ${ this.valueNode.build( builder, inputType ) } )`;
99
+
100
+
101
+ }
102
+
103
+ }
104
+
105
+ export default BitcastNode;
106
+
107
+ /**
108
+ * Reinterpret the bit representation of a value in one type as a value in another type.
109
+ *
110
+ * @tsl
111
+ * @function
112
+ * @param {Node | number} x - The parameter.
113
+ * @param {string} y - The new type.
114
+ * @returns {Node}
115
+ */
116
+ export const bitcast = /*@__PURE__*/ nodeProxyIntent( BitcastNode ).setParameterLength( 2 );
117
+
118
+ /**
119
+ * Bitcasts a float or a vector of floats to a corresponding integer type with the same element size.
120
+ *
121
+ * @tsl
122
+ * @function
123
+ * @param {Node<float>} value - The float or vector of floats to bitcast.
124
+ * @returns {BitcastNode}
125
+ */
126
+ export const floatBitsToInt = ( value ) => new BitcastNode( value, 'int', 'float' );
127
+
128
+ /**
129
+ * Bitcasts a float or a vector of floats to a corresponding unsigned integer type with the same element size.
130
+ *
131
+ * @tsl
132
+ * @function
133
+ * @param {Node<float>} value - The float or vector of floats to bitcast.
134
+ * @returns {BitcastNode}
135
+ */
136
+ export const floatBitsToUint = ( value ) => new BitcastNode( value, 'uint', 'float' );
137
+
138
+ /**
139
+ * Bitcasts an integer or a vector of integers to a corresponding float type with the same element size.
140
+ *
141
+ * @tsl
142
+ * @function
143
+ * @param {Node<int>} value - The integer or vector of integers to bitcast.
144
+ * @returns {BitcastNode}
145
+ */
146
+ export const intBitsToFloat = ( value ) => new BitcastNode( value, 'float', 'int' );
147
+
148
+ /**
149
+ * Bitcast an unsigned integer or a vector of unsigned integers to a corresponding float type with the same element size.
150
+ *
151
+ * @tsl
152
+ * @function
153
+ * @param {Node<uint>} value - The unsigned integer or vector of unsigned integers to bitcast.
154
+ * @returns {BitcastNode}
155
+ */
156
+ export const uintBitsToFloat = ( value ) => new BitcastNode( value, 'float', 'uint' );
@@ -112,10 +112,12 @@ class ConditionalNode extends Node {
112
112
 
113
113
  //
114
114
 
115
+ const isUniformFlow = builder.context.uniformFlow;
116
+
115
117
  const properties = builder.getNodeProperties( this );
116
118
  properties.condNode = condNode;
117
- properties.ifNode = ifNode.context( { nodeBlock: ifNode } );
118
- properties.elseNode = elseNode ? elseNode.context( { nodeBlock: elseNode } ) : null;
119
+ properties.ifNode = isUniformFlow ? ifNode : ifNode.context( { nodeBlock: ifNode } );
120
+ properties.elseNode = elseNode ? ( isUniformFlow ? elseNode : elseNode.context( { nodeBlock: elseNode } ) ) : null;
119
121
 
120
122
  }
121
123
 
@@ -140,6 +142,20 @@ class ConditionalNode extends Node {
140
142
  nodeData.nodeProperty = nodeProperty;
141
143
 
142
144
  const nodeSnippet = condNode.build( builder, 'bool' );
145
+ const isUniformFlow = builder.context.uniformFlow;
146
+
147
+ if ( isUniformFlow && elseNode !== null ) {
148
+
149
+ const ifSnippet = ifNode.build( builder, type );
150
+ const elseSnippet = elseNode.build( builder, type );
151
+
152
+ const mathSnippet = builder.getTernary( nodeSnippet, ifSnippet, elseSnippet );
153
+
154
+ // TODO: If node property already exists return something else
155
+
156
+ return builder.format( mathSnippet, type, output );
157
+
158
+ }
143
159
 
144
160
  builder.addFlowCode( `\n${ builder.tab }if ( ${ nodeSnippet } ) {\n\n` ).addFlowTab();
145
161
 
@@ -366,7 +366,6 @@ MathNode.INVERSE = 'inverse';
366
366
 
367
367
  // 2 inputs
368
368
 
369
- MathNode.BITCAST = 'bitcast';
370
369
  MathNode.EQUALS = 'equals';
371
370
  MathNode.MIN = 'min';
372
371
  MathNode.MAX = 'max';
@@ -767,17 +766,6 @@ export const inverse = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.INVERSE
767
766
 
768
767
  // 2 inputs
769
768
 
770
- /**
771
- * Reinterpret the bit representation of a value in one type as a value in another type.
772
- *
773
- * @tsl
774
- * @function
775
- * @param {Node | number} x - The parameter.
776
- * @param {string} y - The new type.
777
- * @returns {Node}
778
- */
779
- export const bitcast = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.BITCAST ).setParameterLength( 2 );
780
-
781
769
  /**
782
770
  * Returns `true` if `x` equals `y`.
783
771
  *
@@ -900,7 +888,7 @@ export const pow = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW ).setPa
900
888
  * @param {Node | number} x - The first parameter.
901
889
  * @returns {Node}
902
890
  */
903
- export const pow2 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW, 2 ).setParameterLength( 1 );
891
+ export const pow2 = ( x ) => mul( x, x );
904
892
 
905
893
  /**
906
894
  * Returns the cube of the parameter.
@@ -910,7 +898,7 @@ export const pow2 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW, 2 ).s
910
898
  * @param {Node | number} x - The first parameter.
911
899
  * @returns {Node}
912
900
  */
913
- export const pow3 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW, 3 ).setParameterLength( 1 );
901
+ export const pow3 = ( x ) => mul( x, x, x );
914
902
 
915
903
  /**
916
904
  * Returns the fourth power of the parameter.
@@ -920,7 +908,7 @@ export const pow3 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW, 3 ).s
920
908
  * @param {Node | number} x - The first parameter.
921
909
  * @returns {Node}
922
910
  */
923
- export const pow4 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW, 4 ).setParameterLength( 1 );
911
+ export const pow4 = ( x ) => mul( x, x, x, x );
924
912
 
925
913
  /**
926
914
  * Transforms the direction of a vector by a matrix and then normalizes the result.