super-three 0.133.2 → 0.135.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 (246) hide show
  1. package/build/three.js +619 -538
  2. package/build/three.min.js +1 -1
  3. package/build/three.module.js +763 -616
  4. package/examples/fonts/open-sans/open-sans-v15-cyrillic-ext_greek_greek-ext_cyrillic_latin_latin-ext_vietnamese-regular.woff +0 -0
  5. package/examples/fonts/open-sans/open-sans-v15-cyrillic-ext_greek_greek-ext_cyrillic_latin_latin-ext_vietnamese-regular.woff2 +0 -0
  6. package/examples/fonts/open-sans/open-sans.css +9 -0
  7. package/examples/fonts/tabler-icons/fonts/tabler-icons.eot +0 -0
  8. package/examples/fonts/tabler-icons/fonts/tabler-icons.ttf +0 -0
  9. package/examples/fonts/tabler-icons/fonts/tabler-icons.woff +0 -0
  10. package/examples/fonts/tabler-icons/fonts/tabler-icons.woff2 +0 -0
  11. package/examples/fonts/tabler-icons/tabler-icons.min.css +4 -0
  12. package/examples/js/controls/ArcballControls.js +68 -27
  13. package/examples/js/controls/DragControls.js +7 -0
  14. package/examples/js/controls/OrbitControls.js +5 -36
  15. package/examples/js/controls/TrackballControls.js +3 -2
  16. package/examples/js/csm/CSM.js +2 -2
  17. package/examples/js/csm/CSMFrustum.js +133 -0
  18. package/examples/js/exporters/GLTFExporter.js +147 -63
  19. package/examples/js/exporters/USDZExporter.js +45 -26
  20. package/examples/js/lines/LineMaterial.js +58 -20
  21. package/examples/js/lines/LineSegments2.js +29 -24
  22. package/examples/js/loaders/3DMLoader.js +24 -11
  23. package/examples/js/loaders/3MFLoader.js +2 -2
  24. package/examples/js/loaders/ColladaLoader.js +61 -3
  25. package/examples/js/loaders/FBXLoader.js +1 -1
  26. package/examples/js/loaders/GLTFLoader.js +94 -31
  27. package/examples/js/loaders/KTX2Loader.js +12 -0
  28. package/examples/js/loaders/LWOLoader.js +8 -6
  29. package/examples/js/loaders/LogLuvLoader.js +766 -0
  30. package/examples/js/loaders/PLYLoader.js +32 -7
  31. package/examples/js/loaders/RGBELoader.js +2 -1
  32. package/examples/js/loaders/SVGLoader.js +7 -3
  33. package/examples/js/loaders/TDSLoader.js +237 -271
  34. package/examples/js/loaders/lwo/LWO2Parser.js +1 -0
  35. package/examples/js/loaders/lwo/LWO3Parser.js +4 -2
  36. package/examples/js/objects/MarchingCubes.js +42 -128
  37. package/examples/js/renderers/CSS2DRenderer.js +4 -4
  38. package/examples/js/renderers/CSS3DRenderer.js +4 -4
  39. package/examples/js/utils/RoughnessMipmapper.js +1 -0
  40. package/examples/jsm/controls/ArcballControls.js +61 -29
  41. package/examples/jsm/controls/DragControls.js +7 -0
  42. package/examples/jsm/controls/OrbitControls.js +9 -51
  43. package/examples/jsm/controls/TrackballControls.js +1 -1
  44. package/examples/jsm/csm/CSM.js +3 -3
  45. package/examples/jsm/csm/{Frustum.js → CSMFrustum.js} +3 -3
  46. package/examples/jsm/exporters/GLTFExporter.js +160 -74
  47. package/examples/jsm/exporters/USDZExporter.js +47 -26
  48. package/examples/jsm/libs/flow.module.js +3218 -0
  49. package/examples/jsm/libs/lil-gui.module.min.js +8 -0
  50. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  51. package/examples/jsm/lines/LineMaterial.js +59 -23
  52. package/examples/jsm/lines/LineSegments2.js +22 -18
  53. package/examples/jsm/loaders/3DMLoader.js +18 -12
  54. package/examples/jsm/loaders/3MFLoader.js +2 -2
  55. package/examples/jsm/loaders/ColladaLoader.js +61 -3
  56. package/examples/jsm/loaders/FBXLoader.js +1 -1
  57. package/examples/jsm/loaders/GLTFLoader.js +99 -35
  58. package/examples/jsm/loaders/KTX2Loader.js +19 -0
  59. package/examples/jsm/loaders/LWOLoader.js +8 -6
  60. package/examples/jsm/loaders/LogLuvLoader.js +606 -0
  61. package/examples/jsm/loaders/PLYLoader.js +33 -7
  62. package/examples/jsm/loaders/SVGLoader.js +7 -4
  63. package/examples/jsm/loaders/TDSLoader.js +225 -285
  64. package/examples/jsm/loaders/lwo/LWO2Parser.js +1 -0
  65. package/examples/jsm/loaders/lwo/LWO3Parser.js +2 -2
  66. package/examples/jsm/node-editor/NodeEditor.js +455 -0
  67. package/examples/jsm/node-editor/accessors/NormalEditor.js +30 -0
  68. package/examples/jsm/node-editor/accessors/PositionEditor.js +30 -0
  69. package/examples/jsm/node-editor/accessors/UVEditor.js +26 -0
  70. package/examples/jsm/node-editor/display/BlendEditor.js +43 -0
  71. package/examples/jsm/node-editor/examples/animate-uv.json +1 -0
  72. package/examples/jsm/node-editor/examples/fake-top-light.json +1 -0
  73. package/examples/jsm/node-editor/examples/oscillator-color.json +1 -0
  74. package/examples/jsm/node-editor/examples/rim.json +1 -0
  75. package/examples/jsm/node-editor/inputs/ColorEditor.js +91 -0
  76. package/examples/jsm/node-editor/inputs/FloatEditor.js +24 -0
  77. package/examples/jsm/node-editor/inputs/SliderEditor.js +68 -0
  78. package/examples/jsm/node-editor/inputs/Vector2Editor.js +28 -0
  79. package/examples/jsm/node-editor/inputs/Vector3Editor.js +30 -0
  80. package/examples/jsm/node-editor/inputs/Vector4Editor.js +37 -0
  81. package/examples/jsm/node-editor/materials/StandardMaterialEditor.js +69 -0
  82. package/examples/jsm/node-editor/math/DotEditor.js +36 -0
  83. package/examples/jsm/node-editor/math/InvertEditor.js +38 -0
  84. package/examples/jsm/node-editor/math/LimiterEditor.js +48 -0
  85. package/examples/jsm/node-editor/math/NormalizeEditor.js +26 -0
  86. package/examples/jsm/node-editor/math/OperatorEditor.js +50 -0
  87. package/examples/jsm/node-editor/math/PowerEditor.js +34 -0
  88. package/examples/jsm/node-editor/math/TrigonometryEditor.js +39 -0
  89. package/examples/jsm/node-editor/procedural/CheckerEditor.js +26 -0
  90. package/examples/jsm/node-editor/utils/OscillatorEditor.js +42 -0
  91. package/examples/jsm/node-editor/utils/TimerEditor.js +57 -0
  92. package/examples/jsm/nodes/materials/StandardNodeMaterial.js +1 -1
  93. package/examples/jsm/nodes/materials/nodes/StandardNode.js +6 -6
  94. package/examples/jsm/nodes/utils/ColorSpaceNode.js +1 -49
  95. package/examples/jsm/objects/MarchingCubes.js +46 -152
  96. package/examples/jsm/postprocessing/AdaptiveToneMappingPass.js +1 -1
  97. package/examples/jsm/postprocessing/AfterimagePass.js +1 -1
  98. package/examples/jsm/postprocessing/BloomPass.js +1 -1
  99. package/examples/jsm/postprocessing/BokehPass.js +1 -1
  100. package/examples/jsm/postprocessing/ClearPass.js +1 -1
  101. package/examples/jsm/postprocessing/CubeTexturePass.js +1 -1
  102. package/examples/jsm/postprocessing/DotScreenPass.js +1 -1
  103. package/examples/jsm/postprocessing/EffectComposer.js +3 -3
  104. package/examples/jsm/postprocessing/FilmPass.js +1 -1
  105. package/examples/jsm/postprocessing/GlitchPass.js +1 -1
  106. package/examples/jsm/postprocessing/HalftonePass.js +1 -1
  107. package/examples/jsm/postprocessing/MaskPass.js +1 -1
  108. package/examples/jsm/postprocessing/OutlinePass.js +1 -1
  109. package/examples/jsm/postprocessing/RenderPass.js +1 -1
  110. package/examples/jsm/postprocessing/SAOPass.js +1 -1
  111. package/examples/jsm/postprocessing/SMAAPass.js +1 -1
  112. package/examples/jsm/postprocessing/SSAARenderPass.js +1 -1
  113. package/examples/jsm/postprocessing/SSAOPass.js +1 -1
  114. package/examples/jsm/postprocessing/SSRPass.js +1 -1
  115. package/examples/jsm/postprocessing/SSRrPass.js +1 -1
  116. package/examples/jsm/postprocessing/SavePass.js +1 -1
  117. package/examples/jsm/postprocessing/ShaderPass.js +1 -1
  118. package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
  119. package/examples/jsm/postprocessing/TexturePass.js +1 -1
  120. package/examples/jsm/postprocessing/UnrealBloomPass.js +1 -1
  121. package/examples/jsm/renderers/CSS2DRenderer.js +5 -4
  122. package/examples/jsm/renderers/CSS3DRenderer.js +5 -4
  123. package/examples/jsm/renderers/nodes/Nodes.js +14 -13
  124. package/examples/jsm/renderers/nodes/ShaderNode.js +193 -41
  125. package/examples/jsm/renderers/nodes/accessors/MaterialNode.js +6 -6
  126. package/examples/jsm/renderers/nodes/accessors/ModelViewProjectionNode.js +5 -5
  127. package/examples/jsm/renderers/nodes/accessors/NormalNode.js +14 -3
  128. package/examples/jsm/renderers/nodes/accessors/PointUVNode.js +3 -3
  129. package/examples/jsm/renderers/nodes/accessors/PositionNode.js +15 -5
  130. package/examples/jsm/renderers/nodes/accessors/SkinningNode.js +107 -0
  131. package/examples/jsm/renderers/nodes/accessors/UVNode.js +7 -5
  132. package/examples/jsm/renderers/nodes/core/ArrayInputNode.js +3 -3
  133. package/examples/jsm/renderers/nodes/core/AttributeNode.js +6 -0
  134. package/examples/jsm/renderers/nodes/core/BypassNode.js +38 -0
  135. package/examples/jsm/renderers/nodes/core/CodeNode.js +3 -3
  136. package/examples/jsm/renderers/nodes/core/ContextNode.js +4 -19
  137. package/examples/jsm/renderers/nodes/core/ExpressionNode.js +13 -2
  138. package/examples/jsm/renderers/nodes/core/FunctionNode.js +19 -132
  139. package/examples/jsm/renderers/nodes/core/InputNode.js +13 -3
  140. package/examples/jsm/renderers/nodes/core/Node.js +32 -10
  141. package/examples/jsm/renderers/nodes/core/NodeBuilder.js +146 -128
  142. package/examples/jsm/renderers/nodes/core/NodeFunction.js +22 -0
  143. package/examples/jsm/renderers/nodes/core/NodeFunctionInput.js +4 -4
  144. package/examples/jsm/renderers/nodes/core/NodeKeywords.js +18 -179
  145. package/examples/jsm/renderers/nodes/core/NodeParser.js +11 -0
  146. package/examples/jsm/renderers/nodes/core/NodeVar.js +2 -2
  147. package/examples/jsm/renderers/nodes/core/PropertyNode.js +14 -2
  148. package/examples/jsm/renderers/nodes/core/TempNode.js +10 -13
  149. package/examples/jsm/renderers/nodes/core/VarNode.js +12 -7
  150. package/examples/jsm/renderers/nodes/core/VaryNode.js +23 -8
  151. package/examples/jsm/renderers/nodes/core/constants.js +2 -0
  152. package/examples/jsm/renderers/nodes/display/ColorSpaceNode.js +47 -25
  153. package/examples/jsm/renderers/nodes/display/NormalMapNode.js +21 -22
  154. package/examples/jsm/renderers/nodes/functions/BSDFs.js +64 -101
  155. package/examples/jsm/renderers/nodes/inputs/BufferNode.js +25 -0
  156. package/examples/jsm/renderers/nodes/inputs/IntNode.js +17 -0
  157. package/examples/jsm/renderers/nodes/inputs/TextureNode.js +10 -2
  158. package/examples/jsm/renderers/nodes/lights/LightContextNode.js +20 -14
  159. package/examples/jsm/renderers/nodes/lights/LightNode.js +32 -36
  160. package/examples/jsm/renderers/nodes/math/CondNode.js +60 -0
  161. package/examples/jsm/renderers/nodes/math/MathNode.js +87 -36
  162. package/examples/jsm/renderers/nodes/math/OperatorNode.js +124 -31
  163. package/examples/jsm/renderers/nodes/parsers/GLSLNodeFunction.js +137 -0
  164. package/examples/jsm/renderers/nodes/parsers/GLSLNodeParser.js +14 -0
  165. package/examples/jsm/renderers/nodes/parsers/WGSLNodeFunction.js +89 -0
  166. package/examples/jsm/renderers/nodes/parsers/WGSLNodeParser.js +14 -0
  167. package/examples/jsm/renderers/nodes/procedural/CheckerNode.js +7 -9
  168. package/examples/jsm/renderers/nodes/utils/ArrayElementNode.js +31 -0
  169. package/examples/jsm/renderers/nodes/utils/ConvertNode.js +33 -0
  170. package/examples/jsm/renderers/nodes/utils/JoinNode.js +7 -7
  171. package/examples/jsm/renderers/nodes/utils/OscNode.js +58 -0
  172. package/examples/jsm/renderers/nodes/utils/SplitNode.js +18 -8
  173. package/examples/jsm/renderers/nodes/utils/SpriteSheetUVNode.js +7 -7
  174. package/examples/jsm/renderers/webgl/nodes/SlotNode.js +22 -0
  175. package/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js +191 -94
  176. package/examples/jsm/renderers/webgl/nodes/WebGLNodes.js +2 -2
  177. package/examples/jsm/renderers/webgl/nodes/WebGLPhysicalContextNode.js +2 -2
  178. package/examples/jsm/renderers/webgpu/WebGPUBackground.js +1 -1
  179. package/examples/jsm/renderers/webgpu/WebGPUBindings.js +3 -3
  180. package/examples/jsm/renderers/webgpu/WebGPUComputePipelines.js +2 -4
  181. package/examples/jsm/renderers/webgpu/WebGPUProgrammableStage.js +2 -4
  182. package/examples/jsm/renderers/webgpu/WebGPURenderPipeline.js +15 -23
  183. package/examples/jsm/renderers/webgpu/WebGPURenderPipelines.js +3 -5
  184. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +11 -27
  185. package/examples/jsm/renderers/webgpu/WebGPUTextureUtils.js +62 -28
  186. package/examples/jsm/renderers/webgpu/WebGPUTextures.js +34 -27
  187. package/examples/jsm/renderers/webgpu/constants.js +2 -2
  188. package/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js +430 -98
  189. package/examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js +1 -1
  190. package/examples/jsm/utils/RoughnessMipmapper.js +1 -0
  191. package/examples/jsm/webxr/OculusHandPointerModel.js +6 -6
  192. package/package.json +10 -10
  193. package/src/Three.Legacy.js +6 -0
  194. package/src/Three.js +0 -1
  195. package/src/cameras/StereoCamera.js +8 -7
  196. package/src/constants.js +1 -2
  197. package/src/core/Layers.js +7 -1
  198. package/src/core/Object3D.js +2 -0
  199. package/src/extras/PMREMGenerator.js +11 -6
  200. package/src/loaders/FileLoader.js +89 -152
  201. package/src/loaders/ImageLoader.js +9 -4
  202. package/src/loaders/LoaderUtils.js +26 -0
  203. package/src/loaders/MaterialLoader.js +7 -4
  204. package/src/loaders/ObjectLoader.js +2 -0
  205. package/src/materials/Material.js +4 -4
  206. package/src/materials/MeshPhysicalMaterial.js +20 -14
  207. package/src/math/MathUtils.js +5 -16
  208. package/src/renderers/WebGLMultisampleRenderTarget.js +7 -1
  209. package/src/renderers/WebGLRenderer.js +83 -117
  210. package/src/renderers/shaders/ShaderChunk/bsdfs.glsl.js +2 -2
  211. package/src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl.js +0 -27
  212. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +0 -1
  213. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +19 -6
  214. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +2 -2
  215. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  216. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +1 -1
  217. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +13 -5
  218. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +2 -1
  219. package/src/renderers/shaders/ShaderLib.js +6 -4
  220. package/src/renderers/shaders/UniformsLib.js +1 -2
  221. package/src/renderers/webgl/WebGLExtensions.js +1 -0
  222. package/src/renderers/webgl/WebGLMaterials.js +27 -15
  223. package/src/renderers/webgl/WebGLProgram.js +10 -6
  224. package/src/renderers/webgl/WebGLPrograms.js +17 -12
  225. package/src/renderers/webgl/WebGLShadowMap.js +14 -5
  226. package/src/renderers/webgl/WebGLState.js +31 -17
  227. package/src/renderers/webgl/WebGLTextures.js +188 -51
  228. package/src/renderers/webgl/WebGLUniforms.js +45 -1
  229. package/src/renderers/webxr/WebXRManager.js +71 -110
  230. package/src/textures/Texture.js +6 -0
  231. package/src/utils.js +37 -1
  232. package/examples/js/controls/DeviceOrientationControls.js +0 -147
  233. package/examples/js/libs/dat.gui.min.js +0 -14
  234. package/examples/jsm/controls/DeviceOrientationControls.js +0 -153
  235. package/examples/jsm/libs/dat.gui.module.js +0 -3575
  236. package/examples/jsm/libs/glslang.js +0 -78
  237. package/examples/jsm/libs/glslang.wasm +0 -0
  238. package/examples/jsm/renderers/nodes/consts/MathConsts.js +0 -7
  239. package/examples/jsm/renderers/nodes/core/ConstNode.js +0 -39
  240. package/examples/jsm/renderers/nodes/core/NodeSlot.js +0 -13
  241. package/examples/jsm/renderers/nodes/core/StructNode.js +0 -80
  242. package/examples/jsm/renderers/nodes/core/StructVarNode.js +0 -75
  243. package/examples/jsm/renderers/nodes/functions/EncodingFunctions.js +0 -99
  244. package/examples/jsm/renderers/nodes/functions/MathFunctions.js +0 -47
  245. package/examples/jsm/renderers/webgpu/nodes/ShaderLib.js +0 -152
  246. package/src/extras/objects/ImmediateRenderObject.js +0 -31
@@ -6,22 +6,70 @@ import {
6
6
  import WebGPUNodeSampler from './WebGPUNodeSampler.js';
7
7
  import { WebGPUNodeSampledTexture } from './WebGPUNodeSampledTexture.js';
8
8
 
9
+ import WebGPUUniformBuffer from '../WebGPUUniformBuffer.js';
9
10
  import { getVectorLength, getStrideLength } from '../WebGPUBufferUtils.js';
10
11
 
11
- import NodeSlot from '../../nodes/core/NodeSlot.js';
12
12
  import VarNode from '../../nodes/core/VarNode.js';
13
+ import CodeNode from '../../nodes/core/CodeNode.js';
14
+ import BypassNode from '../../nodes/core/BypassNode.js';
15
+ import ExpressionNode from '../../nodes/core/ExpressionNode.js';
13
16
  import NodeBuilder from '../../nodes/core/NodeBuilder.js';
14
17
  import MaterialNode from '../../nodes/accessors/MaterialNode.js';
18
+ import PositionNode from '../../nodes/accessors/PositionNode.js';
15
19
  import NormalNode from '../../nodes/accessors/NormalNode.js';
16
20
  import ModelViewProjectionNode from '../../nodes/accessors/ModelViewProjectionNode.js';
21
+ import SkinningNode from '../../nodes/accessors/SkinningNode.js';
17
22
  import LightContextNode from '../../nodes/lights/LightContextNode.js';
18
- import ShaderLib from './ShaderLib.js';
23
+ import OperatorNode from '../../nodes/math/OperatorNode.js';
24
+ import WGSLNodeParser from '../../nodes/parsers/WGSLNodeParser.js';
25
+
26
+ const wgslTypeLib = {
27
+ float: 'f32',
28
+ int: 'i32',
29
+ vec2: 'vec2<f32>',
30
+ vec3: 'vec3<f32>',
31
+ vec4: 'vec4<f32>',
32
+ uvec4: 'vec4<u32>',
33
+ mat3: 'mat3x3<f32>',
34
+ mat4: 'mat4x4<f32>'
35
+ };
36
+
37
+ const wgslMethods = {
38
+ dFdx: 'dpdx',
39
+ dFdy: 'dpdy'
40
+ };
41
+
42
+ const wgslPolyfill = {
43
+ mod: new CodeNode( `
44
+ fn mod( x : f32, y : f32 ) -> f32 {
45
+
46
+ return x - y * floor( x / y );
47
+
48
+ }
49
+ ` ),
50
+ repeatWrapping: new CodeNode( `
51
+ fn repeatWrapping( uv : vec2<f32>, dimension : vec2<i32> ) -> vec2<i32> {
52
+
53
+ let uvScaled = vec2<i32>( uv * vec2<f32>( dimension ) );
54
+
55
+ return ( ( uvScaled % dimension ) + dimension ) % dimension;
56
+
57
+ }
58
+ ` ),
59
+ inversesqrt: new CodeNode( `
60
+ fn inversesqrt( x : f32 ) -> f32 {
61
+
62
+ return 1.0 / sqrt( x );
63
+
64
+ }
65
+ ` )
66
+ };
19
67
 
20
68
  class WebGPUNodeBuilder extends NodeBuilder {
21
69
 
22
- constructor( material, renderer, lightNode = null ) {
70
+ constructor( object, renderer, lightNode = null ) {
23
71
 
24
- super( material, renderer );
72
+ super( object, renderer, new WGSLNodeParser() );
25
73
 
26
74
  this.lightNode = lightNode;
27
75
 
@@ -30,106 +78,147 @@ class WebGPUNodeBuilder extends NodeBuilder {
30
78
 
31
79
  this.uniformsGroup = {};
32
80
 
33
- this.nativeShader = null;
34
-
35
- this._parseMaterial();
81
+ this._parseObject();
36
82
 
37
83
  }
38
84
 
39
- _parseMaterial() {
85
+ _parseObject() {
40
86
 
87
+ const object = this.object;
41
88
  const material = this.material;
42
89
 
43
- // get shader
90
+ // parse inputs
44
91
 
45
- let shader = null;
92
+ if ( material.isMeshStandardMaterial || material.isMeshBasicMaterial || material.isPointsMaterial || material.isLineBasicMaterial ) {
46
93
 
47
- if ( material.isMeshStandardMaterial ) {
94
+ let lightNode = material.lightNode;
48
95
 
49
- shader = ShaderLib.standard;
96
+ // VERTEX STAGE
50
97
 
51
- } else {
98
+ let vertex = new PositionNode( PositionNode.GEOMETRY );
52
99
 
53
- shader = ShaderLib.common;
100
+ if ( lightNode === null && this.lightNode && this.lightNode.hasLights === true ) {
54
101
 
55
- }
102
+ lightNode = this.lightNode;
56
103
 
57
- this.nativeShader = shader;
104
+ }
58
105
 
59
- // parse inputs
106
+ if ( material.positionNode && material.positionNode.isNode ) {
60
107
 
61
- if ( material.isMeshStandardMaterial || material.isMeshBasicMaterial || material.isPointsMaterial || material.isLineBasicMaterial ) {
108
+ const assignPositionNode = new OperatorNode( '=', new PositionNode( PositionNode.LOCAL ), material.positionNode );
62
109
 
63
- const mvpNode = new ModelViewProjectionNode();
110
+ vertex = new BypassNode( vertex, assignPositionNode );
64
111
 
65
- let lightNode = material.lightNode;
112
+ }
66
113
 
67
- if ( lightNode === null && this.lightNode && this.lightNode.hasLights === true ) {
114
+ if ( object.isSkinnedMesh === true ) {
68
115
 
69
- lightNode = this.lightNode;
116
+ vertex = new BypassNode( vertex, new SkinningNode( object ) );
70
117
 
71
118
  }
72
119
 
73
- if ( material.positionNode && material.positionNode.isNode ) {
120
+ this.context.vertex = vertex;
74
121
 
75
- mvpNode.position = material.positionNode;
122
+ this.addFlow( 'vertex', new VarNode( new ModelViewProjectionNode(), 'MVP', 'vec4' ) );
76
123
 
77
- }
124
+ // COLOR
78
125
 
79
- this.addSlot( 'vertex', new NodeSlot( mvpNode, 'MVP', 'vec4' ) );
126
+ let colorNode = null;
80
127
 
81
- if ( material.alphaTestNode && material.alphaTestNode.isNode ) {
128
+ if ( material.colorNode && material.colorNode.isNode ) {
82
129
 
83
- this.addSlot( 'fragment', new NodeSlot( material.alphaTestNode, 'ALPHA_TEST', 'float' ) );
130
+ colorNode = material.colorNode;
84
131
 
85
132
  } else {
86
133
 
87
- this.addSlot( 'fragment', new NodeSlot( new MaterialNode( MaterialNode.ALPHA_TEST ), 'ALPHA_TEST', 'float' ) );
134
+ colorNode = new MaterialNode( MaterialNode.COLOR );
88
135
 
89
136
  }
90
137
 
91
- if ( material.colorNode && material.colorNode.isNode ) {
138
+ colorNode = this.addFlow( 'fragment', new VarNode( colorNode, 'DiffuseColor', 'vec4' ) );
139
+
140
+ // OPACITY
141
+
142
+ let opacityNode = null;
143
+
144
+ if ( material.opacityNode && material.opacityNode.isNode ) {
92
145
 
93
- this.addSlot( 'fragment', new NodeSlot( material.colorNode, 'COLOR', 'vec4' ) );
146
+ opacityNode = material.opacityNode;
94
147
 
95
148
  } else {
96
149
 
97
- this.addSlot( 'fragment', new NodeSlot( new MaterialNode( MaterialNode.COLOR ), 'COLOR', 'vec4' ) );
150
+ opacityNode = new VarNode( new MaterialNode( MaterialNode.OPACITY ) );
98
151
 
99
152
  }
100
153
 
101
- if ( material.opacityNode && material.opacityNode.isNode ) {
154
+ this.addFlow( 'fragment', new VarNode( opacityNode, 'OPACITY', 'float' ) );
102
155
 
103
- this.addSlot( 'fragment', new NodeSlot( material.opacityNode, 'OPACITY', 'float' ) );
156
+ this.addFlow( 'fragment', new ExpressionNode( 'DiffuseColor.a = DiffuseColor.a * OPACITY;' ) );
104
157
 
105
- } else {
158
+ // ALPHA TEST
159
+
160
+ let alphaTest = null;
161
+
162
+ if ( material.alphaTestNode && material.alphaTestNode.isNode ) {
163
+
164
+ alphaTest = material.alphaTestNode;
106
165
 
107
- this.addSlot( 'fragment', new NodeSlot( new MaterialNode( MaterialNode.OPACITY ), 'OPACITY', 'float' ) );
166
+ } else if ( material.alphaTest > 0 ) {
167
+
168
+ alphaTest = new MaterialNode( MaterialNode.ALPHA_TEST );
169
+
170
+ }
171
+
172
+ if ( alphaTest !== null ) {
173
+
174
+ this.addFlow( 'fragment', new VarNode( alphaTest, 'AlphaTest', 'float' ) );
175
+
176
+ this.addFlow( 'fragment', new ExpressionNode( 'if ( DiffuseColor.a <= AlphaTest ) { discard; }' ) );
108
177
 
109
178
  }
110
179
 
111
180
  if ( material.isMeshStandardMaterial ) {
112
181
 
182
+ // METALNESS
183
+
184
+ let metalnessNode = null;
185
+
113
186
  if ( material.metalnessNode && material.metalnessNode.isNode ) {
114
187
 
115
- this.addSlot( 'fragment', new NodeSlot( material.metalnessNode, 'METALNESS', 'float' ) );
188
+ metalnessNode = material.metalnessNode;
116
189
 
117
190
  } else {
118
191
 
119
- this.addSlot( 'fragment', new NodeSlot( new MaterialNode( MaterialNode.METALNESS ), 'METALNESS', 'float' ) );
192
+ metalnessNode = new MaterialNode( MaterialNode.METALNESS );
120
193
 
121
194
  }
122
195
 
196
+ this.addFlow( 'fragment', new VarNode( metalnessNode, 'Metalness', 'float' ) );
197
+
198
+ this.addFlow( 'fragment', new ExpressionNode( 'DiffuseColor = vec4<f32>( DiffuseColor.rgb * ( 1.0 - Metalness ), DiffuseColor.a );' ) );
199
+
200
+ // ROUGHNESS
201
+
202
+ let roughnessNode = null;
203
+
123
204
  if ( material.roughnessNode && material.roughnessNode.isNode ) {
124
205
 
125
- this.addSlot( 'fragment', new NodeSlot( material.roughnessNode, 'ROUGHNESS', 'float' ) );
206
+ roughnessNode = material.roughnessNode;
126
207
 
127
208
  } else {
128
209
 
129
- this.addSlot( 'fragment', new NodeSlot( new MaterialNode( MaterialNode.ROUGHNESS ), 'ROUGHNESS', 'float' ) );
210
+ roughnessNode = new MaterialNode( MaterialNode.ROUGHNESS );
130
211
 
131
212
  }
132
213
 
214
+ this.addFlow( 'fragment', new VarNode( roughnessNode, 'Roughness', 'float' ) );
215
+
216
+ // SPECULAR_TINT
217
+
218
+ this.addFlow( 'fragment', new VarNode( new ExpressionNode( 'mix( vec3<f32>( 0.04 ), DiffuseColor.rgb, Metalness )', 'vec3' ), 'SpecularColor', 'color' ) );
219
+
220
+ // NORMAL_VIEW
221
+
133
222
  let normalNode = null;
134
223
 
135
224
  if ( material.normalNode && material.normalNode.isNode ) {
@@ -142,61 +231,71 @@ class WebGPUNodeBuilder extends NodeBuilder {
142
231
 
143
232
  }
144
233
 
145
- this.addSlot( 'fragment', new NodeSlot( new VarNode( normalNode, 'TransformedNormalView', 'vec3' ), 'NORMAL', 'vec3' ) );
146
-
147
- } else if ( material.isMeshPhongMaterial ) {
234
+ this.addFlow( 'fragment', new VarNode( normalNode, 'TransformedNormalView', 'vec3' ) );
148
235
 
149
- if ( material.specularNode && material.specularNode.isNode ) {
150
-
151
- this.addSlot( 'fragment', new NodeSlot( material.specularNode, 'SPECULAR', 'vec3' ) );
236
+ }
152
237
 
153
- } else {
238
+ // LIGHT
154
239
 
155
- this.addSlot( 'fragment', new NodeSlot( new MaterialNode( MaterialNode.SPECULAR ), 'SPECULAR', 'vec3' ) );
240
+ let outputNode = colorNode;
156
241
 
157
- }
242
+ if ( lightNode && lightNode.isNode ) {
158
243
 
159
- if ( material.shininessNode && material.shininessNode.isNode ) {
244
+ const lightContextNode = new LightContextNode( lightNode );
160
245
 
161
- this.addSlot( 'fragment', new NodeSlot( material.shininessNode, 'SHININESS', 'float' ) );
246
+ outputNode = this.addFlow( 'fragment', new VarNode( lightContextNode, 'Light', 'vec3' ) );
162
247
 
163
- } else {
248
+ }
164
249
 
165
- this.addSlot( 'fragment', new NodeSlot( new MaterialNode( MaterialNode.SHININESS ), 'SHININESS', 'float' ) );
250
+ // RESULT
166
251
 
167
- }
252
+ this.addFlow( 'fragment', new VarNode( outputNode, 'Output', 'vec4' ) );
168
253
 
169
- }
254
+ }
170
255
 
171
- if ( lightNode && lightNode.isNode ) {
256
+ }
172
257
 
173
- const lightContextNode = new LightContextNode( lightNode );
258
+ addFlowCode( code ) {
174
259
 
175
- this.addSlot( 'fragment', new NodeSlot( lightContextNode, 'LIGHT', 'vec3' ) );
260
+ if ( ! /;\s*$/.test( code ) ) {
176
261
 
177
- }
262
+ code += ';';
178
263
 
179
264
  }
180
265
 
266
+ super.addFlowCode( code + '\n\t' );
267
+
181
268
  }
182
269
 
183
- getTexture( textureProperty, uvSnippet, biasSnippet = null ) {
270
+ getTexture( textureProperty, uvSnippet, biasSnippet = null, shaderStage = this.shaderStage ) {
184
271
 
185
- if ( biasSnippet !== null ) {
272
+ if ( shaderStage === 'fragment' ) {
186
273
 
187
- return `texture( sampler2D( ${textureProperty}, ${textureProperty}_sampler ), ${uvSnippet}, ${biasSnippet} )`;
274
+ return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet} )`;
188
275
 
189
276
  } else {
190
277
 
191
- return `texture( sampler2D( ${textureProperty}, ${textureProperty}_sampler ), ${uvSnippet} )`;
278
+ this._include( 'repeatWrapping' );
279
+
280
+ const dimension = `textureDimensions( ${textureProperty}, 0 )`;
281
+
282
+ return `textureLoad( ${textureProperty}, repeatWrapping( ${uvSnippet}, ${dimension} ), 0 )`;
192
283
 
193
284
  }
194
285
 
195
286
  }
196
287
 
197
- getPropertyName( node ) {
288
+ getPropertyName( node, shaderStage = this.shaderStage ) {
289
+
290
+ if ( node.isNodeVary === true ) {
291
+
292
+ if ( shaderStage === 'vertex' ) {
293
+
294
+ return `NodeVarys.${ node.name }`;
198
295
 
199
- if ( node.isNodeUniform === true ) {
296
+ }
297
+
298
+ } else if ( node.isNodeUniform === true ) {
200
299
 
201
300
  const name = node.name;
202
301
  const type = node.type;
@@ -205,9 +304,13 @@ class WebGPUNodeBuilder extends NodeBuilder {
205
304
 
206
305
  return name;
207
306
 
307
+ } else if ( type === 'buffer' ) {
308
+
309
+ return `NodeBuffer.${name}`;
310
+
208
311
  } else {
209
312
 
210
- return `nodeUniforms.${name}`;
313
+ return `NodeUniforms.${name}`;
211
314
 
212
315
  }
213
316
 
@@ -245,9 +348,33 @@ class WebGPUNodeBuilder extends NodeBuilder {
245
348
  const lastBinding = bindings[ bindings.length - 1 ];
246
349
  const index = lastBinding && lastBinding.isUniformsGroup ? bindings.length - 1 : bindings.length;
247
350
 
248
- bindings.splice( index, 0, sampler, texture );
351
+ if ( shaderStage === 'fragment' ) {
352
+
353
+ bindings.splice( index, 0, sampler, texture );
354
+
355
+ uniformGPU = [ sampler, texture ];
356
+
357
+ } else {
358
+
359
+ bindings.splice( index, 0, texture );
360
+
361
+ uniformGPU = [ texture ];
362
+
363
+
364
+ }
365
+
366
+
367
+ } else if ( type === 'buffer' ) {
368
+
369
+ const buffer = new WebGPUUniformBuffer( 'NodeBuffer', node.value );
370
+
371
+ // add first textures in sequence and group for last
372
+ const lastBinding = bindings[ bindings.length - 1 ];
373
+ const index = lastBinding && lastBinding.isUniformsGroup ? bindings.length - 1 : bindings.length;
374
+
375
+ bindings.splice( index, 0, buffer );
249
376
 
250
- uniformGPU = [ sampler, texture ];
377
+ uniformGPU = buffer;
251
378
 
252
379
  } else {
253
380
 
@@ -267,7 +394,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
267
394
 
268
395
  uniformGPU = [];
269
396
 
270
- for ( const inputNode of node.value ) {
397
+ for ( const inputNode of node.nodes ) {
271
398
 
272
399
  const uniformNodeGPU = this._getNodeUniform( inputNode, type );
273
400
 
@@ -312,15 +439,49 @@ class WebGPUNodeBuilder extends NodeBuilder {
312
439
  if ( shaderStage === 'vertex' ) {
313
440
 
314
441
  const attributes = this.attributes;
442
+ const length = attributes.length;
315
443
 
316
- for ( let index = 0; index < attributes.length; index ++ ) {
444
+ snippet += '\n';
445
+
446
+ for ( let index = 0; index < length; index ++ ) {
317
447
 
318
448
  const attribute = attributes[ index ];
449
+ const name = attribute.name;
450
+ const type = this.getType( attribute.type );
451
+
452
+ snippet += `\t[[ location( ${index} ) ]] ${ name } : ${ type }`;
453
+
454
+ if ( index + 1 < length ) {
319
455
 
320
- snippet += `layout(location = ${index}) in ${attribute.type} ${attribute.name}; `;
456
+ snippet += ',\n';
457
+
458
+ }
321
459
 
322
460
  }
323
461
 
462
+ snippet += '\n';
463
+
464
+ }
465
+
466
+ return snippet;
467
+
468
+ }
469
+
470
+ getVars( shaderStage ) {
471
+
472
+ let snippet = '';
473
+
474
+ const vars = this.vars[ shaderStage ];
475
+
476
+ for ( let index = 0; index < vars.length; index ++ ) {
477
+
478
+ const variable = vars[ index ];
479
+
480
+ const name = variable.name;
481
+ const type = this.getType( variable.type );
482
+
483
+ snippet += `var ${name} : ${type}; `;
484
+
324
485
  }
325
486
 
326
487
  return snippet;
@@ -331,15 +492,43 @@ class WebGPUNodeBuilder extends NodeBuilder {
331
492
 
332
493
  let snippet = '';
333
494
 
334
- const varys = this.varys;
495
+ if ( shaderStage === 'vertex' ) {
496
+
497
+ snippet += '\t[[ builtin( position ) ]] Vertex: vec4<f32>;\n';
498
+
499
+ const varys = this.varys;
500
+
501
+ for ( let index = 0; index < varys.length; index ++ ) {
502
+
503
+ const vary = varys[ index ];
504
+
505
+ snippet += `\t[[ location( ${index} ) ]] ${ vary.name } : ${ this.getType( vary.type ) };\n`;
506
+
507
+ }
508
+
509
+ snippet = this._getWGSLStruct( 'NodeVarysStruct', snippet );
510
+
511
+ } else if ( shaderStage === 'fragment' ) {
512
+
513
+ const varys = this.varys;
514
+
515
+ snippet += '\n';
516
+
517
+ for ( let index = 0; index < varys.length; index ++ ) {
335
518
 
336
- const ioStage = shaderStage === 'vertex' ? 'out' : 'in';
519
+ const vary = varys[ index ];
337
520
 
338
- for ( let index = 0; index < varys.length; index ++ ) {
521
+ snippet += `\t[[ location( ${index} ) ]] ${ vary.name } : ${ this.getType( vary.type ) }`;
339
522
 
340
- const vary = varys[ index ];
523
+ if ( index + 1 < varys.length ) {
341
524
 
342
- snippet += `layout(location = ${index}) ${ioStage} ${vary.type} ${vary.name}; `;
525
+ snippet += ',\n';
526
+
527
+ }
528
+
529
+ }
530
+
531
+ snippet += '\n';
343
532
 
344
533
  }
345
534
 
@@ -360,12 +549,27 @@ class WebGPUNodeBuilder extends NodeBuilder {
360
549
 
361
550
  if ( uniform.type === 'texture' ) {
362
551
 
363
- snippet += `layout(set = 0, binding = ${index ++}) uniform sampler ${uniform.name}_sampler; `;
364
- snippet += `layout(set = 0, binding = ${index ++}) uniform texture2D ${uniform.name}; `;
552
+ if ( shaderStage === 'fragment' ) {
553
+
554
+ snippet += `[[ group( 0 ), binding( ${index ++} ) ]] var ${uniform.name}_sampler : sampler; `;
555
+
556
+ }
557
+
558
+ snippet += `[[ group( 0 ), binding( ${index ++} ) ]] var ${uniform.name} : texture_2d<f32>; `;
559
+
560
+ } else if ( uniform.type === 'buffer' ) {
561
+
562
+ const bufferNode = uniform.node;
563
+ const bufferType = this.getType( bufferNode.bufferType );
564
+ const bufferCount = bufferNode.bufferCount;
565
+
566
+ const bufferSnippet = `\t${uniform.name} : array< ${bufferType}, ${bufferCount} >;\n`;
567
+
568
+ snippet += this._getWGSLUniforms( 'NodeBuffer', bufferSnippet, index ++ ) + '\n\n';
365
569
 
366
570
  } else {
367
571
 
368
- const vectorType = this.getVectorType( uniform.type );
572
+ const vectorType = this.getType( this.getVectorType( uniform.type ) );
369
573
 
370
574
  if ( Array.isArray( uniform.value ) === true ) {
371
575
 
@@ -375,7 +579,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
375
579
 
376
580
  } else {
377
581
 
378
- groupSnippet += `uniform ${vectorType} ${uniform.name}; `;
582
+ groupSnippet += `\t${uniform.name} : ${ vectorType};\n`;
379
583
 
380
584
  }
381
585
 
@@ -385,7 +589,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
385
589
 
386
590
  if ( groupSnippet ) {
387
591
 
388
- snippet += `layout(set = 0, binding = ${index ++}) uniform NodeUniforms { ${groupSnippet} } nodeUniforms; `;
592
+ snippet += this._getWGSLUniforms( 'NodeUniforms', groupSnippet, index ++ );
389
593
 
390
594
  }
391
595
 
@@ -393,39 +597,91 @@ class WebGPUNodeBuilder extends NodeBuilder {
393
597
 
394
598
  }
395
599
 
396
- build() {
600
+ buildCode() {
397
601
 
398
- const keywords = this.getContextValue( 'keywords' );
602
+ const shadersData = { fragment: {}, vertex: {} };
399
603
 
400
- for ( const shaderStage of [ 'vertex', 'fragment' ] ) {
604
+ for ( const shaderStage in shadersData ) {
401
605
 
402
- this.shaderStage = shaderStage;
606
+ let flow = '// code\n';
607
+ flow += `\t${ this.flowCode[ shaderStage ] }`;
608
+ flow += '\n';
403
609
 
404
- keywords.include( this, this.nativeShader.fragmentShader );
610
+ const flowNodes = this.flowNodes[ shaderStage ];
611
+ const mainNode = flowNodes[ flowNodes.length - 1 ];
405
612
 
406
- }
613
+ for ( const node of flowNodes ) {
614
+
615
+ const flowSlotData = this.getFlowData( shaderStage, node );
616
+ const slotName = node.name;
617
+
618
+ if ( slotName ) {
619
+
620
+ if ( flow.length > 0 ) flow += '\n';
621
+
622
+ flow += `\t// FLOW -> ${ slotName }\n\t`;
623
+
624
+ }
407
625
 
408
- super.build();
626
+ flow += `${ flowSlotData.code }\n\t`;
409
627
 
410
- this.vertexShader = this._composeShaderCode( this.nativeShader.vertexShader, this.vertexShader );
411
- this.fragmentShader = this._composeShaderCode( this.nativeShader.fragmentShader, this.fragmentShader );
628
+ if ( node === mainNode ) {
412
629
 
413
- return this;
630
+ flow += '// FLOW RESULT\n\t';
631
+
632
+ if ( shaderStage === 'vertex' ) {
633
+
634
+ flow += 'NodeVarys.Vertex = ';
635
+
636
+ } else if ( shaderStage === 'fragment' ) {
637
+
638
+ flow += 'return ';
639
+
640
+ }
641
+
642
+ flow += `${ flowSlotData.result };`;
643
+
644
+ }
645
+
646
+ }
647
+
648
+ const stageData = shadersData[ shaderStage ];
649
+
650
+ stageData.uniforms = this.getUniforms( shaderStage );
651
+ stageData.attributes = this.getAttributes( shaderStage );
652
+ stageData.varys = this.getVarys( shaderStage );
653
+ stageData.vars = this.getVars( shaderStage );
654
+ stageData.codes = this.getCodes( shaderStage );
655
+ stageData.flow = flow;
656
+
657
+ }
658
+
659
+ this.vertexShader = this._getWGSLVertexCode( shadersData.vertex );
660
+ this.fragmentShader = this._getWGSLFragmentCode( shadersData.fragment );
414
661
 
415
662
  }
416
663
 
417
- _composeShaderCode( code, snippet ) {
664
+ getMethod( method ) {
665
+
666
+ if ( wgslPolyfill[ method ] !== undefined ) {
667
+
668
+ this._include( method );
669
+
670
+ }
671
+
672
+ return wgslMethods[ method ] || method;
418
673
 
419
- // use regex maybe for security?
420
- const versionStrIndex = code.indexOf( '\n' );
674
+ }
421
675
 
422
- let finalCode = code.substr( 0, versionStrIndex ) + '\n\n';
676
+ getType( type ) {
423
677
 
424
- finalCode += snippet;
678
+ return wgslTypeLib[ type ] || type;
425
679
 
426
- finalCode += code.substr( versionStrIndex );
680
+ }
427
681
 
428
- return finalCode;
682
+ _include( name ) {
683
+
684
+ wgslPolyfill[ name ].build( this );
429
685
 
430
686
  }
431
687
 
@@ -443,6 +699,82 @@ class WebGPUNodeBuilder extends NodeBuilder {
443
699
 
444
700
  }
445
701
 
702
+ _getWGSLVertexCode( shaderData ) {
703
+
704
+ return `${ this.getSignature() }
705
+
706
+ // uniforms
707
+ ${shaderData.uniforms}
708
+
709
+ // varys
710
+ ${shaderData.varys}
711
+
712
+ // codes
713
+ ${shaderData.codes}
714
+
715
+ [[ stage( vertex ) ]]
716
+ fn main( ${shaderData.attributes} ) -> NodeVarysStruct {
717
+
718
+ // system
719
+ var NodeVarys: NodeVarysStruct;
720
+
721
+ // vars
722
+ ${shaderData.vars}
723
+
724
+ // flow
725
+ ${shaderData.flow}
726
+
727
+ return NodeVarys;
728
+
729
+ }
730
+ `;
731
+
732
+ }
733
+
734
+ _getWGSLFragmentCode( shaderData ) {
735
+
736
+ return `${ this.getSignature() }
737
+
738
+ // uniforms
739
+ ${shaderData.uniforms}
740
+
741
+ // codes
742
+ ${shaderData.codes}
743
+
744
+ [[ stage( fragment ) ]]
745
+ fn main( ${shaderData.varys} ) -> [[ location( 0 ) ]] vec4<f32> {
746
+
747
+ // vars
748
+ ${shaderData.vars}
749
+
750
+ // flow
751
+ ${shaderData.flow}
752
+
753
+ }
754
+ `;
755
+
756
+ }
757
+
758
+ _getWGSLStruct( name, vars ) {
759
+
760
+ return `[[ block ]]
761
+ struct ${name} {
762
+ \n${vars}
763
+ };`;
764
+
765
+ }
766
+
767
+ _getWGSLUniforms( name, vars, binding = 0, group = 0 ) {
768
+
769
+ const structName = name + 'Struct';
770
+ const structSnippet = this._getWGSLStruct( structName, vars );
771
+
772
+ return `${structSnippet}
773
+ [[ binding( ${binding} ), group( ${group} ) ]]
774
+ var<uniform> ${name} : ${structName};`;
775
+
776
+ }
777
+
446
778
  }
447
779
 
448
780
  export default WebGPUNodeBuilder;