@nice2dev/ui-3d 1.3.15 → 1.3.17

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 (108) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/collaborative/collaborativeScene.js +160 -206
  3. package/dist/cjs/core/editorAsk.js +51 -41
  4. package/dist/cjs/core/i18n.js +13 -14
  5. package/dist/cjs/core/threeCompat.js +29 -42
  6. package/dist/cjs/dance/DanceBridge.js +148 -177
  7. package/dist/cjs/dance/DanceScoreEngine.js +209 -221
  8. package/dist/cjs/dance/PoseDetector.js +302 -275
  9. package/dist/cjs/index.js +110 -113
  10. package/dist/cjs/material/MaterialEditor.module.css.js +242 -5
  11. package/dist/cjs/material/NiceMaterialEditor.js +1213 -757
  12. package/dist/cjs/material/materialEditorTypes.js +35 -49
  13. package/dist/cjs/material/materialEditorUtils.js +684 -747
  14. package/dist/cjs/material/materialNodeDefinitions.js +1411 -1459
  15. package/dist/cjs/model/ModelEditor.js +90 -40
  16. package/dist/cjs/model/ModelEditor.module.css.js +257 -5
  17. package/dist/cjs/model/ModelEditorLeftPanel.js +126 -47
  18. package/dist/cjs/model/ModelEditorMenuBar.js +359 -32
  19. package/dist/cjs/model/ModelEditorRightPanel.js +647 -131
  20. package/dist/cjs/model/ModelEditorSubComponents.js +277 -112
  21. package/dist/cjs/model/ModelEditorTimeline.js +232 -34
  22. package/dist/cjs/model/ModelEditorToolbar.js +170 -14
  23. package/dist/cjs/model/ModelEditorViewport.js +231 -39
  24. package/dist/cjs/model/ModelViewer.js +388 -63
  25. package/dist/cjs/model/ModelViewer.module.css.js +77 -5
  26. package/dist/cjs/model/NiceArmatureEditor.js +473 -274
  27. package/dist/cjs/model/NiceMorphTargetEditor.js +333 -227
  28. package/dist/cjs/model/NiceOctree.js +372 -320
  29. package/dist/cjs/model/NicePhysicsSimulation.js +528 -298
  30. package/dist/cjs/model/NiceProceduralGeometry.js +673 -300
  31. package/dist/cjs/model/NiceTerrainEditor.js +595 -385
  32. package/dist/cjs/model/NiceWeightPainter.js +384 -261
  33. package/dist/cjs/model/NiceXRPreview.js +385 -308
  34. package/dist/cjs/model/cadModeUtils.js +103 -106
  35. package/dist/cjs/model/editorShortcuts.js +171 -194
  36. package/dist/cjs/model/modelEditorTypes.js +100 -118
  37. package/dist/cjs/model/modelEditorUtils.js +1061 -1146
  38. package/dist/cjs/model/simsModeUtils.js +1023 -1053
  39. package/dist/cjs/model/useModelEditor.js +1977 -1933
  40. package/dist/cjs/model/useModelViewer.js +633 -665
  41. package/dist/cjs/nice2dev-ui-3d.css +1 -1
  42. package/dist/cjs/particle/NiceParticleEditor.js +1186 -571
  43. package/dist/cjs/particle/ParticleEditor.module.css.js +122 -5
  44. package/dist/cjs/particle/particleEditorTypes.js +62 -70
  45. package/dist/cjs/particle/particleEditorUtils.js +998 -1013
  46. package/dist/cjs/rendering/NiceCascadedShadows.js +381 -259
  47. package/dist/cjs/rendering/NiceRenderExport.js +424 -337
  48. package/dist/cjs/rendering/NiceSSAO.js +454 -337
  49. package/dist/cjs/rendering/NiceSSR.js +387 -261
  50. package/dist/cjs/rendering/NiceWebGPURenderer.js +359 -230
  51. package/dist/cjs/uv/NiceUVEditor.js +787 -550
  52. package/dist/cjs/uv/UVEditor.module.css.js +53 -5
  53. package/dist/cjs/uv/uvEditorTypes.js +59 -76
  54. package/dist/cjs/uv/uvEditorUtils.js +501 -575
  55. package/dist/esm/collaborative/collaborativeScene.js +163 -205
  56. package/dist/esm/core/editorAsk.js +53 -40
  57. package/dist/esm/core/i18n.js +15 -13
  58. package/dist/esm/core/threeCompat.js +18 -26
  59. package/dist/esm/dance/DanceBridge.js +151 -176
  60. package/dist/esm/dance/DanceScoreEngine.js +211 -220
  61. package/dist/esm/dance/PoseDetector.js +304 -274
  62. package/dist/esm/index.js +258 -36
  63. package/dist/esm/material/MaterialEditor.module.css.js +242 -3
  64. package/dist/esm/material/NiceMaterialEditor.js +1215 -756
  65. package/dist/esm/material/materialEditorTypes.js +45 -48
  66. package/dist/esm/material/materialEditorUtils.js +713 -746
  67. package/dist/esm/material/materialNodeDefinitions.js +1415 -1458
  68. package/dist/esm/model/ModelEditor.js +91 -39
  69. package/dist/esm/model/ModelEditor.module.css.js +257 -3
  70. package/dist/esm/model/ModelEditorLeftPanel.js +126 -45
  71. package/dist/esm/model/ModelEditorMenuBar.js +359 -30
  72. package/dist/esm/model/ModelEditorRightPanel.js +634 -114
  73. package/dist/esm/model/ModelEditorSubComponents.js +265 -94
  74. package/dist/esm/model/ModelEditorTimeline.js +232 -32
  75. package/dist/esm/model/ModelEditorToolbar.js +170 -12
  76. package/dist/esm/model/ModelEditorViewport.js +231 -37
  77. package/dist/esm/model/ModelViewer.js +389 -62
  78. package/dist/esm/model/ModelViewer.module.css.js +77 -3
  79. package/dist/esm/model/NiceArmatureEditor.js +462 -258
  80. package/dist/esm/model/NiceMorphTargetEditor.js +322 -211
  81. package/dist/esm/model/NiceOctree.js +361 -304
  82. package/dist/esm/model/NicePhysicsSimulation.js +517 -282
  83. package/dist/esm/model/NiceProceduralGeometry.js +667 -284
  84. package/dist/esm/model/NiceTerrainEditor.js +584 -369
  85. package/dist/esm/model/NiceWeightPainter.js +373 -245
  86. package/dist/esm/model/NiceXRPreview.js +374 -292
  87. package/dist/esm/model/cadModeUtils.js +95 -88
  88. package/dist/esm/model/editorShortcuts.js +172 -193
  89. package/dist/esm/model/modelEditorTypes.js +90 -100
  90. package/dist/esm/model/modelEditorUtils.js +1056 -1128
  91. package/dist/esm/model/simsModeUtils.js +1021 -1035
  92. package/dist/esm/model/useModelEditor.js +1946 -1920
  93. package/dist/esm/model/useModelViewer.js +619 -647
  94. package/dist/esm/nice2dev-ui-3d.css +1 -1
  95. package/dist/esm/particle/NiceParticleEditor.js +1188 -570
  96. package/dist/esm/particle/ParticleEditor.module.css.js +122 -3
  97. package/dist/esm/particle/particleEditorTypes.js +69 -69
  98. package/dist/esm/particle/particleEditorUtils.js +1027 -1012
  99. package/dist/esm/rendering/NiceCascadedShadows.js +370 -243
  100. package/dist/esm/rendering/NiceRenderExport.js +413 -321
  101. package/dist/esm/rendering/NiceSSAO.js +450 -328
  102. package/dist/esm/rendering/NiceSSR.js +383 -252
  103. package/dist/esm/rendering/NiceWebGPURenderer.js +326 -214
  104. package/dist/esm/uv/NiceUVEditor.js +788 -549
  105. package/dist/esm/uv/UVEditor.module.css.js +53 -3
  106. package/dist/esm/uv/uvEditorTypes.js +68 -75
  107. package/dist/esm/uv/uvEditorUtils.js +515 -557
  108. package/package.json +7 -12
@@ -1,1485 +1,1437 @@
1
- 'use strict';
2
-
3
- /* ════════════════════════════════════════════════════════════════════════════
4
- Material Node Definitions — Built-in Shader Nodes
5
-
6
- Comprehensive library of 60+ shader nodes:
7
- - Input nodes (constants, parameters, textures)
8
- - Output nodes (PBR, unlit, custom)
9
- - Math operations
10
- - Vector operations
11
- - Color manipulation
12
- - Texture sampling
13
- - Procedural generation
14
- - Utility functions
15
- - Logic/branching
16
- ════════════════════════════════════════════════════════════════════════════ */
17
- /* ═══════════════════════════════════════════════════════════════════════════
18
- INPUT NODES
19
- ═══════════════════════════════════════════════════════════════════════════ */
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
20
3
  const inputNodes = [
21
- {
22
- type: 'constant_float',
23
- category: 'input',
24
- name: 'Float',
25
- description: 'Constant float value',
26
- icon: 'number',
27
- inputs: [],
28
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'float' }],
29
- properties: [
30
- { id: 'value', name: 'Value', type: 'float', default: 0, min: -100, max: 100, step: 0.01 },
31
- ],
32
- shaderFunction: 'float {{nodeId}}_value = {{value}};',
33
- },
34
- {
35
- type: 'constant_vec2',
36
- category: 'input',
37
- name: 'Vector 2',
38
- description: 'Constant 2D vector',
39
- icon: 'vector2',
40
- inputs: [],
41
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'vec2' }],
42
- properties: [
43
- { id: 'x', name: 'X', type: 'float', default: 0 },
44
- { id: 'y', name: 'Y', type: 'float', default: 0 },
45
- ],
46
- shaderFunction: 'vec2 {{nodeId}}_value = vec2({{x}}, {{y}});',
47
- },
48
- {
49
- type: 'constant_vec3',
50
- category: 'input',
51
- name: 'Vector 3',
52
- description: 'Constant 3D vector',
53
- icon: 'vector3',
54
- inputs: [],
55
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'vec3' }],
56
- properties: [
57
- { id: 'x', name: 'X', type: 'float', default: 0 },
58
- { id: 'y', name: 'Y', type: 'float', default: 0 },
59
- { id: 'z', name: 'Z', type: 'float', default: 0 },
60
- ],
61
- shaderFunction: 'vec3 {{nodeId}}_value = vec3({{x}}, {{y}}, {{z}});',
62
- },
63
- {
64
- type: 'constant_vec4',
65
- category: 'input',
66
- name: 'Vector 4',
67
- description: 'Constant 4D vector',
68
- icon: 'vector4',
69
- inputs: [],
70
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'vec4' }],
71
- properties: [
72
- { id: 'x', name: 'X', type: 'float', default: 0 },
73
- { id: 'y', name: 'Y', type: 'float', default: 0 },
74
- { id: 'z', name: 'Z', type: 'float', default: 0 },
75
- { id: 'w', name: 'W', type: 'float', default: 1 },
76
- ],
77
- shaderFunction: 'vec4 {{nodeId}}_value = vec4({{x}}, {{y}}, {{z}}, {{w}});',
78
- },
79
- {
80
- type: 'constant_color',
81
- category: 'input',
82
- name: 'Color',
83
- description: 'Constant color value',
84
- icon: 'palette',
85
- inputs: [],
86
- outputs: [
87
- { id: 'rgb', name: 'RGB', direction: 'output', dataType: 'vec3' },
88
- { id: 'rgba', name: 'RGBA', direction: 'output', dataType: 'vec4' },
89
- { id: 'r', name: 'R', direction: 'output', dataType: 'float' },
90
- { id: 'g', name: 'G', direction: 'output', dataType: 'float' },
91
- { id: 'b', name: 'B', direction: 'output', dataType: 'float' },
92
- { id: 'a', name: 'A', direction: 'output', dataType: 'float' },
93
- ],
94
- properties: [{ id: 'color', name: 'Color', type: 'color', default: 'var(--nice-bg, #fff)' }],
95
- previewable: true,
96
- },
97
- {
98
- type: 'texture_2d',
99
- category: 'input',
100
- name: 'Texture 2D',
101
- description: '2D texture input',
102
- icon: 'image',
103
- inputs: [],
104
- outputs: [{ id: 'texture', name: 'Texture', direction: 'output', dataType: 'texture2d' }],
105
- properties: [{ id: 'texture', name: 'Texture', type: 'texture', default: null }],
106
- },
107
- {
108
- type: 'texture_cube',
109
- category: 'input',
110
- name: 'Cubemap',
111
- description: 'Cubemap texture input',
112
- icon: 'cube',
113
- inputs: [],
114
- outputs: [{ id: 'texture', name: 'Texture', direction: 'output', dataType: 'textureCube' }],
115
- properties: [{ id: 'texture', name: 'Texture', type: 'texture', default: null }],
116
- },
117
- {
118
- type: 'param_float',
119
- category: 'input',
120
- name: 'Float Parameter',
121
- description: 'Exposed float parameter',
122
- icon: 'slider',
123
- inputs: [],
124
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'float' }],
125
- properties: [
126
- { id: 'name', name: 'Name', type: 'string', default: 'myFloat' },
127
- { id: 'default', name: 'Default', type: 'float', default: 0 },
128
- { id: 'min', name: 'Min', type: 'float', default: 0 },
129
- { id: 'max', name: 'Max', type: 'float', default: 1 },
130
- ],
131
- shaderFunction: 'uniform float {{name}};',
132
- },
133
- {
134
- type: 'param_color',
135
- category: 'input',
136
- name: 'Color Parameter',
137
- description: 'Exposed color parameter',
138
- icon: 'palette',
139
- inputs: [],
140
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'vec4' }],
141
- properties: [
142
- { id: 'name', name: 'Name', type: 'string', default: 'myColor' },
143
- { id: 'default', name: 'Default', type: 'color', default: 'var(--nice-bg, #fff)' },
144
- ],
145
- shaderFunction: 'uniform vec4 {{name}};',
146
- },
147
- {
148
- type: 'uv',
149
- category: 'input',
150
- name: 'UV Coordinates',
151
- description: 'Mesh UV coordinates',
152
- icon: 'grid',
153
- inputs: [],
154
- outputs: [
155
- { id: 'uv', name: 'UV', direction: 'output', dataType: 'vec2' },
156
- { id: 'u', name: 'U', direction: 'output', dataType: 'float' },
157
- { id: 'v', name: 'V', direction: 'output', dataType: 'float' },
158
- ],
159
- properties: [{ id: 'channel', name: 'Channel', type: 'int', default: 0, min: 0, max: 3 }],
160
- shaderFunction: 'vec2 {{nodeId}}_uv = vUv{{channel}};',
161
- },
162
- {
163
- type: 'position',
164
- category: 'input',
165
- name: 'Position',
166
- description: 'Vertex position',
167
- icon: 'crosshair',
168
- inputs: [],
169
- outputs: [
170
- { id: 'world', name: 'World', direction: 'output', dataType: 'vec3' },
171
- { id: 'object', name: 'Object', direction: 'output', dataType: 'vec3' },
172
- { id: 'view', name: 'View', direction: 'output', dataType: 'vec3' },
173
- ],
174
- },
175
- {
176
- type: 'normal',
177
- category: 'input',
178
- name: 'Normal',
179
- description: 'Surface normal',
180
- icon: 'arrow-up',
181
- inputs: [],
182
- outputs: [
183
- { id: 'world', name: 'World', direction: 'output', dataType: 'vec3' },
184
- { id: 'object', name: 'Object', direction: 'output', dataType: 'vec3' },
185
- { id: 'view', name: 'View', direction: 'output', dataType: 'vec3' },
186
- { id: 'tangent', name: 'Tangent', direction: 'output', dataType: 'vec3' },
187
- { id: 'bitangent', name: 'Bitangent', direction: 'output', dataType: 'vec3' },
188
- ],
189
- },
190
- {
191
- type: 'view_direction',
192
- category: 'input',
193
- name: 'View Direction',
194
- description: 'Camera view direction',
195
- icon: 'eye',
196
- inputs: [],
197
- outputs: [{ id: 'direction', name: 'Direction', direction: 'output', dataType: 'vec3' }],
198
- },
199
- {
200
- type: 'time',
201
- category: 'input',
202
- name: 'Time',
203
- description: 'Shader time values',
204
- icon: 'clock',
205
- inputs: [],
206
- outputs: [
207
- { id: 'time', name: 'Time', direction: 'output', dataType: 'float' },
208
- { id: 'sin', name: 'Sin Time', direction: 'output', dataType: 'float' },
209
- { id: 'cos', name: 'Cos Time', direction: 'output', dataType: 'float' },
210
- { id: 'delta', name: 'Delta', direction: 'output', dataType: 'float' },
211
- ],
212
- shaderFunction: 'float {{nodeId}}_time = uTime;',
213
- },
214
- {
215
- type: 'screen_position',
216
- category: 'input',
217
- name: 'Screen Position',
218
- description: 'Screen-space position',
219
- icon: 'monitor',
220
- inputs: [],
221
- outputs: [
222
- { id: 'position', name: 'Position', direction: 'output', dataType: 'vec4' },
223
- { id: 'normalized', name: 'Normalized', direction: 'output', dataType: 'vec2' },
224
- ],
225
- },
4
+ {
5
+ type: "constant_float",
6
+ category: "input",
7
+ name: "Float",
8
+ description: "Constant float value",
9
+ icon: "number",
10
+ inputs: [],
11
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "float" }],
12
+ properties: [
13
+ { id: "value", name: "Value", type: "float", default: 0, min: -100, max: 100, step: 0.01 }
14
+ ],
15
+ shaderFunction: "float {{nodeId}}_value = {{value}};"
16
+ },
17
+ {
18
+ type: "constant_vec2",
19
+ category: "input",
20
+ name: "Vector 2",
21
+ description: "Constant 2D vector",
22
+ icon: "vector2",
23
+ inputs: [],
24
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "vec2" }],
25
+ properties: [
26
+ { id: "x", name: "X", type: "float", default: 0 },
27
+ { id: "y", name: "Y", type: "float", default: 0 }
28
+ ],
29
+ shaderFunction: "vec2 {{nodeId}}_value = vec2({{x}}, {{y}});"
30
+ },
31
+ {
32
+ type: "constant_vec3",
33
+ category: "input",
34
+ name: "Vector 3",
35
+ description: "Constant 3D vector",
36
+ icon: "vector3",
37
+ inputs: [],
38
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "vec3" }],
39
+ properties: [
40
+ { id: "x", name: "X", type: "float", default: 0 },
41
+ { id: "y", name: "Y", type: "float", default: 0 },
42
+ { id: "z", name: "Z", type: "float", default: 0 }
43
+ ],
44
+ shaderFunction: "vec3 {{nodeId}}_value = vec3({{x}}, {{y}}, {{z}});"
45
+ },
46
+ {
47
+ type: "constant_vec4",
48
+ category: "input",
49
+ name: "Vector 4",
50
+ description: "Constant 4D vector",
51
+ icon: "vector4",
52
+ inputs: [],
53
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "vec4" }],
54
+ properties: [
55
+ { id: "x", name: "X", type: "float", default: 0 },
56
+ { id: "y", name: "Y", type: "float", default: 0 },
57
+ { id: "z", name: "Z", type: "float", default: 0 },
58
+ { id: "w", name: "W", type: "float", default: 1 }
59
+ ],
60
+ shaderFunction: "vec4 {{nodeId}}_value = vec4({{x}}, {{y}}, {{z}}, {{w}});"
61
+ },
62
+ {
63
+ type: "constant_color",
64
+ category: "input",
65
+ name: "Color",
66
+ description: "Constant color value",
67
+ icon: "palette",
68
+ inputs: [],
69
+ outputs: [
70
+ { id: "rgb", name: "RGB", direction: "output", dataType: "vec3" },
71
+ { id: "rgba", name: "RGBA", direction: "output", dataType: "vec4" },
72
+ { id: "r", name: "R", direction: "output", dataType: "float" },
73
+ { id: "g", name: "G", direction: "output", dataType: "float" },
74
+ { id: "b", name: "B", direction: "output", dataType: "float" },
75
+ { id: "a", name: "A", direction: "output", dataType: "float" }
76
+ ],
77
+ properties: [{ id: "color", name: "Color", type: "color", default: "var(--nice-bg, #fff)" }],
78
+ previewable: true
79
+ },
80
+ {
81
+ type: "texture_2d",
82
+ category: "input",
83
+ name: "Texture 2D",
84
+ description: "2D texture input",
85
+ icon: "image",
86
+ inputs: [],
87
+ outputs: [{ id: "texture", name: "Texture", direction: "output", dataType: "texture2d" }],
88
+ properties: [{ id: "texture", name: "Texture", type: "texture", default: null }]
89
+ },
90
+ {
91
+ type: "texture_cube",
92
+ category: "input",
93
+ name: "Cubemap",
94
+ description: "Cubemap texture input",
95
+ icon: "cube",
96
+ inputs: [],
97
+ outputs: [{ id: "texture", name: "Texture", direction: "output", dataType: "textureCube" }],
98
+ properties: [{ id: "texture", name: "Texture", type: "texture", default: null }]
99
+ },
100
+ {
101
+ type: "param_float",
102
+ category: "input",
103
+ name: "Float Parameter",
104
+ description: "Exposed float parameter",
105
+ icon: "slider",
106
+ inputs: [],
107
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "float" }],
108
+ properties: [
109
+ { id: "name", name: "Name", type: "string", default: "myFloat" },
110
+ { id: "default", name: "Default", type: "float", default: 0 },
111
+ { id: "min", name: "Min", type: "float", default: 0 },
112
+ { id: "max", name: "Max", type: "float", default: 1 }
113
+ ],
114
+ shaderFunction: "uniform float {{name}};"
115
+ },
116
+ {
117
+ type: "param_color",
118
+ category: "input",
119
+ name: "Color Parameter",
120
+ description: "Exposed color parameter",
121
+ icon: "palette",
122
+ inputs: [],
123
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "vec4" }],
124
+ properties: [
125
+ { id: "name", name: "Name", type: "string", default: "myColor" },
126
+ { id: "default", name: "Default", type: "color", default: "var(--nice-bg, #fff)" }
127
+ ],
128
+ shaderFunction: "uniform vec4 {{name}};"
129
+ },
130
+ {
131
+ type: "uv",
132
+ category: "input",
133
+ name: "UV Coordinates",
134
+ description: "Mesh UV coordinates",
135
+ icon: "grid",
136
+ inputs: [],
137
+ outputs: [
138
+ { id: "uv", name: "UV", direction: "output", dataType: "vec2" },
139
+ { id: "u", name: "U", direction: "output", dataType: "float" },
140
+ { id: "v", name: "V", direction: "output", dataType: "float" }
141
+ ],
142
+ properties: [{ id: "channel", name: "Channel", type: "int", default: 0, min: 0, max: 3 }],
143
+ shaderFunction: "vec2 {{nodeId}}_uv = vUv{{channel}};"
144
+ },
145
+ {
146
+ type: "position",
147
+ category: "input",
148
+ name: "Position",
149
+ description: "Vertex position",
150
+ icon: "crosshair",
151
+ inputs: [],
152
+ outputs: [
153
+ { id: "world", name: "World", direction: "output", dataType: "vec3" },
154
+ { id: "object", name: "Object", direction: "output", dataType: "vec3" },
155
+ { id: "view", name: "View", direction: "output", dataType: "vec3" }
156
+ ]
157
+ },
158
+ {
159
+ type: "normal",
160
+ category: "input",
161
+ name: "Normal",
162
+ description: "Surface normal",
163
+ icon: "arrow-up",
164
+ inputs: [],
165
+ outputs: [
166
+ { id: "world", name: "World", direction: "output", dataType: "vec3" },
167
+ { id: "object", name: "Object", direction: "output", dataType: "vec3" },
168
+ { id: "view", name: "View", direction: "output", dataType: "vec3" },
169
+ { id: "tangent", name: "Tangent", direction: "output", dataType: "vec3" },
170
+ { id: "bitangent", name: "Bitangent", direction: "output", dataType: "vec3" }
171
+ ]
172
+ },
173
+ {
174
+ type: "view_direction",
175
+ category: "input",
176
+ name: "View Direction",
177
+ description: "Camera view direction",
178
+ icon: "eye",
179
+ inputs: [],
180
+ outputs: [{ id: "direction", name: "Direction", direction: "output", dataType: "vec3" }]
181
+ },
182
+ {
183
+ type: "time",
184
+ category: "input",
185
+ name: "Time",
186
+ description: "Shader time values",
187
+ icon: "clock",
188
+ inputs: [],
189
+ outputs: [
190
+ { id: "time", name: "Time", direction: "output", dataType: "float" },
191
+ { id: "sin", name: "Sin Time", direction: "output", dataType: "float" },
192
+ { id: "cos", name: "Cos Time", direction: "output", dataType: "float" },
193
+ { id: "delta", name: "Delta", direction: "output", dataType: "float" }
194
+ ],
195
+ shaderFunction: "float {{nodeId}}_time = uTime;"
196
+ },
197
+ {
198
+ type: "screen_position",
199
+ category: "input",
200
+ name: "Screen Position",
201
+ description: "Screen-space position",
202
+ icon: "monitor",
203
+ inputs: [],
204
+ outputs: [
205
+ { id: "position", name: "Position", direction: "output", dataType: "vec4" },
206
+ { id: "normalized", name: "Normalized", direction: "output", dataType: "vec2" }
207
+ ]
208
+ }
226
209
  ];
227
- /* ═══════════════════════════════════════════════════════════════════════════
228
- OUTPUT NODES
229
- ═══════════════════════════════════════════════════════════════════════════ */
230
210
  const outputNodes = [
231
- {
232
- type: 'output_pbr',
233
- category: 'output',
234
- name: 'PBR Output',
235
- description: 'Physically-based rendering output',
236
- icon: 'sphere',
237
- color: 'var(--nice-danger, #f44336)',
238
- inputs: [
239
- {
240
- id: 'albedo',
241
- name: 'Albedo',
242
- direction: 'input',
243
- dataType: 'vec3',
244
- defaultValue: [1, 1, 1],
245
- },
246
- {
247
- id: 'metallic',
248
- name: 'Metallic',
249
- direction: 'input',
250
- dataType: 'float',
251
- defaultValue: 0,
252
- min: 0,
253
- max: 1,
254
- },
255
- {
256
- id: 'roughness',
257
- name: 'Roughness',
258
- direction: 'input',
259
- dataType: 'float',
260
- defaultValue: 0.5,
261
- min: 0,
262
- max: 1,
263
- },
264
- { id: 'normal', name: 'Normal', direction: 'input', dataType: 'vec3' },
265
- {
266
- id: 'ao',
267
- name: 'AO',
268
- direction: 'input',
269
- dataType: 'float',
270
- defaultValue: 1,
271
- min: 0,
272
- max: 1,
273
- },
274
- {
275
- id: 'emissive',
276
- name: 'Emissive',
277
- direction: 'input',
278
- dataType: 'vec3',
279
- defaultValue: [0, 0, 0],
280
- },
281
- {
282
- id: 'alpha',
283
- name: 'Alpha',
284
- direction: 'input',
285
- dataType: 'float',
286
- defaultValue: 1,
287
- min: 0,
288
- max: 1,
289
- },
290
- ],
291
- outputs: [],
292
- previewable: true,
293
- },
294
- {
295
- type: 'output_unlit',
296
- category: 'output',
297
- name: 'Unlit Output',
298
- description: 'Unlit material output',
299
- icon: 'sun',
300
- color: 'var(--nice-danger, #f44336)',
301
- inputs: [
302
- { id: 'color', name: 'Color', direction: 'input', dataType: 'vec3', defaultValue: [1, 1, 1] },
303
- { id: 'alpha', name: 'Alpha', direction: 'input', dataType: 'float', defaultValue: 1 },
304
- ],
305
- outputs: [],
306
- previewable: true,
307
- },
308
- {
309
- type: 'output_custom',
310
- category: 'output',
311
- name: 'Custom Output',
312
- description: 'Custom shader output',
313
- icon: 'code',
314
- color: 'var(--nice-danger, #f44336)',
315
- inputs: [{ id: 'fragColor', name: 'Frag Color', direction: 'input', dataType: 'vec4' }],
316
- outputs: [],
317
- properties: [
318
- { id: 'vertexCode', name: 'Vertex Code', type: 'string', default: '' },
319
- { id: 'fragmentCode', name: 'Fragment Code', type: 'string', default: '' },
320
- ],
321
- },
211
+ {
212
+ type: "output_pbr",
213
+ category: "output",
214
+ name: "PBR Output",
215
+ description: "Physically-based rendering output",
216
+ icon: "sphere",
217
+ color: "var(--nice-danger, #f44336)",
218
+ inputs: [
219
+ {
220
+ id: "albedo",
221
+ name: "Albedo",
222
+ direction: "input",
223
+ dataType: "vec3",
224
+ defaultValue: [1, 1, 1]
225
+ },
226
+ {
227
+ id: "metallic",
228
+ name: "Metallic",
229
+ direction: "input",
230
+ dataType: "float",
231
+ defaultValue: 0,
232
+ min: 0,
233
+ max: 1
234
+ },
235
+ {
236
+ id: "roughness",
237
+ name: "Roughness",
238
+ direction: "input",
239
+ dataType: "float",
240
+ defaultValue: 0.5,
241
+ min: 0,
242
+ max: 1
243
+ },
244
+ { id: "normal", name: "Normal", direction: "input", dataType: "vec3" },
245
+ {
246
+ id: "ao",
247
+ name: "AO",
248
+ direction: "input",
249
+ dataType: "float",
250
+ defaultValue: 1,
251
+ min: 0,
252
+ max: 1
253
+ },
254
+ {
255
+ id: "emissive",
256
+ name: "Emissive",
257
+ direction: "input",
258
+ dataType: "vec3",
259
+ defaultValue: [0, 0, 0]
260
+ },
261
+ {
262
+ id: "alpha",
263
+ name: "Alpha",
264
+ direction: "input",
265
+ dataType: "float",
266
+ defaultValue: 1,
267
+ min: 0,
268
+ max: 1
269
+ }
270
+ ],
271
+ outputs: [],
272
+ previewable: true
273
+ },
274
+ {
275
+ type: "output_unlit",
276
+ category: "output",
277
+ name: "Unlit Output",
278
+ description: "Unlit material output",
279
+ icon: "sun",
280
+ color: "var(--nice-danger, #f44336)",
281
+ inputs: [
282
+ { id: "color", name: "Color", direction: "input", dataType: "vec3", defaultValue: [1, 1, 1] },
283
+ { id: "alpha", name: "Alpha", direction: "input", dataType: "float", defaultValue: 1 }
284
+ ],
285
+ outputs: [],
286
+ previewable: true
287
+ },
288
+ {
289
+ type: "output_custom",
290
+ category: "output",
291
+ name: "Custom Output",
292
+ description: "Custom shader output",
293
+ icon: "code",
294
+ color: "var(--nice-danger, #f44336)",
295
+ inputs: [{ id: "fragColor", name: "Frag Color", direction: "input", dataType: "vec4" }],
296
+ outputs: [],
297
+ properties: [
298
+ { id: "vertexCode", name: "Vertex Code", type: "string", default: "" },
299
+ { id: "fragmentCode", name: "Fragment Code", type: "string", default: "" }
300
+ ]
301
+ }
322
302
  ];
323
- /* ═══════════════════════════════════════════════════════════════════════════
324
- MATH NODES
325
- ═══════════════════════════════════════════════════════════════════════════ */
326
303
  const mathNodes = [
327
- {
328
- type: 'add',
329
- category: 'math',
330
- name: 'Add',
331
- description: 'Add two values',
332
- icon: 'plus',
333
- inputs: [
334
- { id: 'a', name: 'A', direction: 'input', dataType: 'any', defaultValue: 0 },
335
- { id: 'b', name: 'B', direction: 'input', dataType: 'any', defaultValue: 0 },
336
- ],
337
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
338
- shaderFunction: '{{typeA}} {{nodeId}}_result = {{a}} + {{b}};',
339
- },
340
- {
341
- type: 'subtract',
342
- category: 'math',
343
- name: 'Subtract',
344
- description: 'Subtract two values',
345
- icon: 'minus',
346
- inputs: [
347
- { id: 'a', name: 'A', direction: 'input', dataType: 'any', defaultValue: 0 },
348
- { id: 'b', name: 'B', direction: 'input', dataType: 'any', defaultValue: 0 },
349
- ],
350
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
351
- shaderFunction: '{{typeA}} {{nodeId}}_result = {{a}} - {{b}};',
352
- },
353
- {
354
- type: 'multiply',
355
- category: 'math',
356
- name: 'Multiply',
357
- description: 'Multiply two values',
358
- icon: 'x',
359
- inputs: [
360
- { id: 'a', name: 'A', direction: 'input', dataType: 'any', defaultValue: 1 },
361
- { id: 'b', name: 'B', direction: 'input', dataType: 'any', defaultValue: 1 },
362
- ],
363
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
364
- shaderFunction: '{{typeA}} {{nodeId}}_result = {{a}} * {{b}};',
365
- },
366
- {
367
- type: 'divide',
368
- category: 'math',
369
- name: 'Divide',
370
- description: 'Divide two values',
371
- icon: 'divide',
372
- inputs: [
373
- { id: 'a', name: 'A', direction: 'input', dataType: 'any', defaultValue: 1 },
374
- { id: 'b', name: 'B', direction: 'input', dataType: 'any', defaultValue: 1 },
375
- ],
376
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
377
- shaderFunction: '{{typeA}} {{nodeId}}_result = {{a}} / max({{b}}, 0.0001);',
378
- },
379
- {
380
- type: 'power',
381
- category: 'math',
382
- name: 'Power',
383
- description: 'Raise to power',
384
- icon: 'superscript',
385
- inputs: [
386
- { id: 'base', name: 'Base', direction: 'input', dataType: 'any', defaultValue: 2 },
387
- { id: 'exp', name: 'Exponent', direction: 'input', dataType: 'float', defaultValue: 2 },
388
- ],
389
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
390
- shaderFunction: '{{typeBase}} {{nodeId}}_result = pow({{base}}, {{exp}});',
391
- },
392
- {
393
- type: 'sqrt',
394
- category: 'math',
395
- name: 'Square Root',
396
- description: 'Square root of value',
397
- icon: 'radical',
398
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 1 }],
399
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
400
- shaderFunction: '{{typeValue}} {{nodeId}}_result = sqrt({{value}});',
401
- },
402
- {
403
- type: 'abs',
404
- category: 'math',
405
- name: 'Absolute',
406
- description: 'Absolute value',
407
- icon: 'bar-chart',
408
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
409
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
410
- shaderFunction: '{{typeValue}} {{nodeId}}_result = abs({{value}});',
411
- },
412
- {
413
- type: 'negate',
414
- category: 'math',
415
- name: 'Negate',
416
- description: 'Negate value',
417
- icon: 'minus-circle',
418
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
419
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
420
- shaderFunction: '{{typeValue}} {{nodeId}}_result = -{{value}};',
421
- },
422
- {
423
- type: 'sin',
424
- category: 'math',
425
- name: 'Sine',
426
- description: 'Sine function',
427
- icon: 'activity',
428
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
429
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
430
- shaderFunction: '{{typeValue}} {{nodeId}}_result = sin({{value}});',
431
- },
432
- {
433
- type: 'cos',
434
- category: 'math',
435
- name: 'Cosine',
436
- description: 'Cosine function',
437
- icon: 'activity',
438
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
439
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
440
- shaderFunction: '{{typeValue}} {{nodeId}}_result = cos({{value}});',
441
- },
442
- {
443
- type: 'tan',
444
- category: 'math',
445
- name: 'Tangent',
446
- description: 'Tangent function',
447
- icon: 'activity',
448
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
449
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
450
- shaderFunction: '{{typeValue}} {{nodeId}}_result = tan({{value}});',
451
- },
452
- {
453
- type: 'floor',
454
- category: 'math',
455
- name: 'Floor',
456
- description: 'Floor value',
457
- icon: 'corner-down-left',
458
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
459
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
460
- shaderFunction: '{{typeValue}} {{nodeId}}_result = floor({{value}});',
461
- },
462
- {
463
- type: 'ceil',
464
- category: 'math',
465
- name: 'Ceiling',
466
- description: 'Ceiling value',
467
- icon: 'corner-up-right',
468
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
469
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
470
- shaderFunction: '{{typeValue}} {{nodeId}}_result = ceil({{value}});',
471
- },
472
- {
473
- type: 'round',
474
- category: 'math',
475
- name: 'Round',
476
- description: 'Round value',
477
- icon: 'circle',
478
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
479
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
480
- shaderFunction: '{{typeValue}} {{nodeId}}_result = round({{value}});',
481
- },
482
- {
483
- type: 'fract',
484
- category: 'math',
485
- name: 'Fraction',
486
- description: 'Fractional part',
487
- icon: 'percent',
488
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
489
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
490
- shaderFunction: '{{typeValue}} {{nodeId}}_result = fract({{value}});',
491
- },
492
- {
493
- type: 'mod',
494
- category: 'math',
495
- name: 'Modulo',
496
- description: 'Modulo operation',
497
- icon: 'percent',
498
- inputs: [
499
- { id: 'a', name: 'A', direction: 'input', dataType: 'any', defaultValue: 0 },
500
- { id: 'b', name: 'B', direction: 'input', dataType: 'any', defaultValue: 1 },
501
- ],
502
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
503
- shaderFunction: '{{typeA}} {{nodeId}}_result = mod({{a}}, {{b}});',
504
- },
505
- {
506
- type: 'min',
507
- category: 'math',
508
- name: 'Minimum',
509
- description: 'Minimum of two values',
510
- icon: 'chevron-down',
511
- inputs: [
512
- { id: 'a', name: 'A', direction: 'input', dataType: 'any', defaultValue: 0 },
513
- { id: 'b', name: 'B', direction: 'input', dataType: 'any', defaultValue: 1 },
514
- ],
515
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
516
- shaderFunction: '{{typeA}} {{nodeId}}_result = min({{a}}, {{b}});',
517
- },
518
- {
519
- type: 'max',
520
- category: 'math',
521
- name: 'Maximum',
522
- description: 'Maximum of two values',
523
- icon: 'chevron-up',
524
- inputs: [
525
- { id: 'a', name: 'A', direction: 'input', dataType: 'any', defaultValue: 0 },
526
- { id: 'b', name: 'B', direction: 'input', dataType: 'any', defaultValue: 1 },
527
- ],
528
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
529
- shaderFunction: '{{typeA}} {{nodeId}}_result = max({{a}}, {{b}});',
530
- },
531
- {
532
- type: 'exp',
533
- category: 'math',
534
- name: 'Exponential',
535
- description: 'e^x',
536
- icon: 'trending-up',
537
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
538
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
539
- shaderFunction: '{{typeValue}} {{nodeId}}_result = exp({{value}});',
540
- },
541
- {
542
- type: 'log',
543
- category: 'math',
544
- name: 'Logarithm',
545
- description: 'Natural logarithm',
546
- icon: 'trending-down',
547
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 1 }],
548
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
549
- shaderFunction: '{{typeValue}} {{nodeId}}_result = log(max({{value}}, 0.0001));',
550
- },
304
+ {
305
+ type: "add",
306
+ category: "math",
307
+ name: "Add",
308
+ description: "Add two values",
309
+ icon: "plus",
310
+ inputs: [
311
+ { id: "a", name: "A", direction: "input", dataType: "any", defaultValue: 0 },
312
+ { id: "b", name: "B", direction: "input", dataType: "any", defaultValue: 0 }
313
+ ],
314
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
315
+ shaderFunction: "{{typeA}} {{nodeId}}_result = {{a}} + {{b}};"
316
+ },
317
+ {
318
+ type: "subtract",
319
+ category: "math",
320
+ name: "Subtract",
321
+ description: "Subtract two values",
322
+ icon: "minus",
323
+ inputs: [
324
+ { id: "a", name: "A", direction: "input", dataType: "any", defaultValue: 0 },
325
+ { id: "b", name: "B", direction: "input", dataType: "any", defaultValue: 0 }
326
+ ],
327
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
328
+ shaderFunction: "{{typeA}} {{nodeId}}_result = {{a}} - {{b}};"
329
+ },
330
+ {
331
+ type: "multiply",
332
+ category: "math",
333
+ name: "Multiply",
334
+ description: "Multiply two values",
335
+ icon: "x",
336
+ inputs: [
337
+ { id: "a", name: "A", direction: "input", dataType: "any", defaultValue: 1 },
338
+ { id: "b", name: "B", direction: "input", dataType: "any", defaultValue: 1 }
339
+ ],
340
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
341
+ shaderFunction: "{{typeA}} {{nodeId}}_result = {{a}} * {{b}};"
342
+ },
343
+ {
344
+ type: "divide",
345
+ category: "math",
346
+ name: "Divide",
347
+ description: "Divide two values",
348
+ icon: "divide",
349
+ inputs: [
350
+ { id: "a", name: "A", direction: "input", dataType: "any", defaultValue: 1 },
351
+ { id: "b", name: "B", direction: "input", dataType: "any", defaultValue: 1 }
352
+ ],
353
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
354
+ shaderFunction: "{{typeA}} {{nodeId}}_result = {{a}} / max({{b}}, 0.0001);"
355
+ },
356
+ {
357
+ type: "power",
358
+ category: "math",
359
+ name: "Power",
360
+ description: "Raise to power",
361
+ icon: "superscript",
362
+ inputs: [
363
+ { id: "base", name: "Base", direction: "input", dataType: "any", defaultValue: 2 },
364
+ { id: "exp", name: "Exponent", direction: "input", dataType: "float", defaultValue: 2 }
365
+ ],
366
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
367
+ shaderFunction: "{{typeBase}} {{nodeId}}_result = pow({{base}}, {{exp}});"
368
+ },
369
+ {
370
+ type: "sqrt",
371
+ category: "math",
372
+ name: "Square Root",
373
+ description: "Square root of value",
374
+ icon: "radical",
375
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 1 }],
376
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
377
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = sqrt({{value}});"
378
+ },
379
+ {
380
+ type: "abs",
381
+ category: "math",
382
+ name: "Absolute",
383
+ description: "Absolute value",
384
+ icon: "bar-chart",
385
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
386
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
387
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = abs({{value}});"
388
+ },
389
+ {
390
+ type: "negate",
391
+ category: "math",
392
+ name: "Negate",
393
+ description: "Negate value",
394
+ icon: "minus-circle",
395
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
396
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
397
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = -{{value}};"
398
+ },
399
+ {
400
+ type: "sin",
401
+ category: "math",
402
+ name: "Sine",
403
+ description: "Sine function",
404
+ icon: "activity",
405
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
406
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
407
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = sin({{value}});"
408
+ },
409
+ {
410
+ type: "cos",
411
+ category: "math",
412
+ name: "Cosine",
413
+ description: "Cosine function",
414
+ icon: "activity",
415
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
416
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
417
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = cos({{value}});"
418
+ },
419
+ {
420
+ type: "tan",
421
+ category: "math",
422
+ name: "Tangent",
423
+ description: "Tangent function",
424
+ icon: "activity",
425
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
426
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
427
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = tan({{value}});"
428
+ },
429
+ {
430
+ type: "floor",
431
+ category: "math",
432
+ name: "Floor",
433
+ description: "Floor value",
434
+ icon: "corner-down-left",
435
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
436
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
437
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = floor({{value}});"
438
+ },
439
+ {
440
+ type: "ceil",
441
+ category: "math",
442
+ name: "Ceiling",
443
+ description: "Ceiling value",
444
+ icon: "corner-up-right",
445
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
446
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
447
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = ceil({{value}});"
448
+ },
449
+ {
450
+ type: "round",
451
+ category: "math",
452
+ name: "Round",
453
+ description: "Round value",
454
+ icon: "circle",
455
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
456
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
457
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = round({{value}});"
458
+ },
459
+ {
460
+ type: "fract",
461
+ category: "math",
462
+ name: "Fraction",
463
+ description: "Fractional part",
464
+ icon: "percent",
465
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
466
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
467
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = fract({{value}});"
468
+ },
469
+ {
470
+ type: "mod",
471
+ category: "math",
472
+ name: "Modulo",
473
+ description: "Modulo operation",
474
+ icon: "percent",
475
+ inputs: [
476
+ { id: "a", name: "A", direction: "input", dataType: "any", defaultValue: 0 },
477
+ { id: "b", name: "B", direction: "input", dataType: "any", defaultValue: 1 }
478
+ ],
479
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
480
+ shaderFunction: "{{typeA}} {{nodeId}}_result = mod({{a}}, {{b}});"
481
+ },
482
+ {
483
+ type: "min",
484
+ category: "math",
485
+ name: "Minimum",
486
+ description: "Minimum of two values",
487
+ icon: "chevron-down",
488
+ inputs: [
489
+ { id: "a", name: "A", direction: "input", dataType: "any", defaultValue: 0 },
490
+ { id: "b", name: "B", direction: "input", dataType: "any", defaultValue: 1 }
491
+ ],
492
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
493
+ shaderFunction: "{{typeA}} {{nodeId}}_result = min({{a}}, {{b}});"
494
+ },
495
+ {
496
+ type: "max",
497
+ category: "math",
498
+ name: "Maximum",
499
+ description: "Maximum of two values",
500
+ icon: "chevron-up",
501
+ inputs: [
502
+ { id: "a", name: "A", direction: "input", dataType: "any", defaultValue: 0 },
503
+ { id: "b", name: "B", direction: "input", dataType: "any", defaultValue: 1 }
504
+ ],
505
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
506
+ shaderFunction: "{{typeA}} {{nodeId}}_result = max({{a}}, {{b}});"
507
+ },
508
+ {
509
+ type: "exp",
510
+ category: "math",
511
+ name: "Exponential",
512
+ description: "e^x",
513
+ icon: "trending-up",
514
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
515
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
516
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = exp({{value}});"
517
+ },
518
+ {
519
+ type: "log",
520
+ category: "math",
521
+ name: "Logarithm",
522
+ description: "Natural logarithm",
523
+ icon: "trending-down",
524
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 1 }],
525
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
526
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = log(max({{value}}, 0.0001));"
527
+ }
551
528
  ];
552
- /* ═══════════════════════════════════════════════════════════════════════════
553
- VECTOR NODES
554
- ═══════════════════════════════════════════════════════════════════════════ */
555
529
  const vectorNodes = [
556
- {
557
- type: 'split_vec2',
558
- category: 'vector',
559
- name: 'Split Vec2',
560
- description: 'Split vector into components',
561
- icon: 'git-branch',
562
- inputs: [{ id: 'vector', name: 'Vector', direction: 'input', dataType: 'vec2' }],
563
- outputs: [
564
- { id: 'x', name: 'X', direction: 'output', dataType: 'float' },
565
- { id: 'y', name: 'Y', direction: 'output', dataType: 'float' },
566
- ],
567
- },
568
- {
569
- type: 'split_vec3',
570
- category: 'vector',
571
- name: 'Split Vec3',
572
- description: 'Split vector into components',
573
- icon: 'git-branch',
574
- inputs: [{ id: 'vector', name: 'Vector', direction: 'input', dataType: 'vec3' }],
575
- outputs: [
576
- { id: 'x', name: 'X', direction: 'output', dataType: 'float' },
577
- { id: 'y', name: 'Y', direction: 'output', dataType: 'float' },
578
- { id: 'z', name: 'Z', direction: 'output', dataType: 'float' },
579
- ],
580
- },
581
- {
582
- type: 'split_vec4',
583
- category: 'vector',
584
- name: 'Split Vec4',
585
- description: 'Split vector into components',
586
- icon: 'git-branch',
587
- inputs: [{ id: 'vector', name: 'Vector', direction: 'input', dataType: 'vec4' }],
588
- outputs: [
589
- { id: 'x', name: 'X', direction: 'output', dataType: 'float' },
590
- { id: 'y', name: 'Y', direction: 'output', dataType: 'float' },
591
- { id: 'z', name: 'Z', direction: 'output', dataType: 'float' },
592
- { id: 'w', name: 'W', direction: 'output', dataType: 'float' },
593
- ],
594
- },
595
- {
596
- type: 'combine_vec2',
597
- category: 'vector',
598
- name: 'Combine Vec2',
599
- description: 'Combine components into vector',
600
- icon: 'git-merge',
601
- inputs: [
602
- { id: 'x', name: 'X', direction: 'input', dataType: 'float', defaultValue: 0 },
603
- { id: 'y', name: 'Y', direction: 'input', dataType: 'float', defaultValue: 0 },
604
- ],
605
- outputs: [{ id: 'vector', name: 'Vector', direction: 'output', dataType: 'vec2' }],
606
- shaderFunction: 'vec2 {{nodeId}}_vector = vec2({{x}}, {{y}});',
607
- },
608
- {
609
- type: 'combine_vec3',
610
- category: 'vector',
611
- name: 'Combine Vec3',
612
- description: 'Combine components into vector',
613
- icon: 'git-merge',
614
- inputs: [
615
- { id: 'x', name: 'X', direction: 'input', dataType: 'float', defaultValue: 0 },
616
- { id: 'y', name: 'Y', direction: 'input', dataType: 'float', defaultValue: 0 },
617
- { id: 'z', name: 'Z', direction: 'input', dataType: 'float', defaultValue: 0 },
618
- ],
619
- outputs: [{ id: 'vector', name: 'Vector', direction: 'output', dataType: 'vec3' }],
620
- shaderFunction: 'vec3 {{nodeId}}_vector = vec3({{x}}, {{y}}, {{z}});',
621
- },
622
- {
623
- type: 'combine_vec4',
624
- category: 'vector',
625
- name: 'Combine Vec4',
626
- description: 'Combine components into vector',
627
- icon: 'git-merge',
628
- inputs: [
629
- { id: 'x', name: 'X', direction: 'input', dataType: 'float', defaultValue: 0 },
630
- { id: 'y', name: 'Y', direction: 'input', dataType: 'float', defaultValue: 0 },
631
- { id: 'z', name: 'Z', direction: 'input', dataType: 'float', defaultValue: 0 },
632
- { id: 'w', name: 'W', direction: 'input', dataType: 'float', defaultValue: 1 },
633
- ],
634
- outputs: [{ id: 'vector', name: 'Vector', direction: 'output', dataType: 'vec4' }],
635
- shaderFunction: 'vec4 {{nodeId}}_vector = vec4({{x}}, {{y}}, {{z}}, {{w}});',
636
- },
637
- {
638
- type: 'normalize',
639
- category: 'vector',
640
- name: 'Normalize',
641
- description: 'Normalize vector to unit length',
642
- icon: 'maximize-2',
643
- inputs: [{ id: 'vector', name: 'Vector', direction: 'input', dataType: 'vec3' }],
644
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
645
- shaderFunction: 'vec3 {{nodeId}}_result = normalize({{vector}});',
646
- },
647
- {
648
- type: 'length',
649
- category: 'vector',
650
- name: 'Length',
651
- description: 'Vector length/magnitude',
652
- icon: 'move',
653
- inputs: [{ id: 'vector', name: 'Vector', direction: 'input', dataType: 'vec3' }],
654
- outputs: [{ id: 'length', name: 'Length', direction: 'output', dataType: 'float' }],
655
- shaderFunction: 'float {{nodeId}}_length = length({{vector}});',
656
- },
657
- {
658
- type: 'distance',
659
- category: 'vector',
660
- name: 'Distance',
661
- description: 'Distance between two points',
662
- icon: 'maximize',
663
- inputs: [
664
- { id: 'a', name: 'A', direction: 'input', dataType: 'vec3' },
665
- { id: 'b', name: 'B', direction: 'input', dataType: 'vec3' },
666
- ],
667
- outputs: [{ id: 'distance', name: 'Distance', direction: 'output', dataType: 'float' }],
668
- shaderFunction: 'float {{nodeId}}_distance = distance({{a}}, {{b}});',
669
- },
670
- {
671
- type: 'dot',
672
- category: 'vector',
673
- name: 'Dot Product',
674
- description: 'Dot product of two vectors',
675
- icon: 'target',
676
- inputs: [
677
- { id: 'a', name: 'A', direction: 'input', dataType: 'vec3' },
678
- { id: 'b', name: 'B', direction: 'input', dataType: 'vec3' },
679
- ],
680
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'float' }],
681
- shaderFunction: 'float {{nodeId}}_result = dot({{a}}, {{b}});',
682
- },
683
- {
684
- type: 'cross',
685
- category: 'vector',
686
- name: 'Cross Product',
687
- description: 'Cross product of two vectors',
688
- icon: 'x',
689
- inputs: [
690
- { id: 'a', name: 'A', direction: 'input', dataType: 'vec3' },
691
- { id: 'b', name: 'B', direction: 'input', dataType: 'vec3' },
692
- ],
693
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
694
- shaderFunction: 'vec3 {{nodeId}}_result = cross({{a}}, {{b}});',
695
- },
696
- {
697
- type: 'reflect',
698
- category: 'vector',
699
- name: 'Reflect',
700
- description: 'Reflect vector off surface',
701
- icon: 'corner-up-left',
702
- inputs: [
703
- { id: 'incident', name: 'Incident', direction: 'input', dataType: 'vec3' },
704
- { id: 'normal', name: 'Normal', direction: 'input', dataType: 'vec3' },
705
- ],
706
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
707
- shaderFunction: 'vec3 {{nodeId}}_result = reflect({{incident}}, {{normal}});',
708
- },
709
- {
710
- type: 'refract',
711
- category: 'vector',
712
- name: 'Refract',
713
- description: 'Refract vector through surface',
714
- icon: 'corner-down-right',
715
- inputs: [
716
- { id: 'incident', name: 'Incident', direction: 'input', dataType: 'vec3' },
717
- { id: 'normal', name: 'Normal', direction: 'input', dataType: 'vec3' },
718
- { id: 'ior', name: 'IOR', direction: 'input', dataType: 'float', defaultValue: 1.5 },
719
- ],
720
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
721
- shaderFunction: 'vec3 {{nodeId}}_result = refract({{incident}}, {{normal}}, {{ior}});',
722
- },
723
- {
724
- type: 'transform',
725
- category: 'vector',
726
- name: 'Transform',
727
- description: 'Transform vector by matrix',
728
- icon: 'rotate-cw',
729
- inputs: [
730
- { id: 'vector', name: 'Vector', direction: 'input', dataType: 'vec3' },
731
- { id: 'matrix', name: 'Matrix', direction: 'input', dataType: 'matrix4' },
732
- ],
733
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
734
- },
530
+ {
531
+ type: "split_vec2",
532
+ category: "vector",
533
+ name: "Split Vec2",
534
+ description: "Split vector into components",
535
+ icon: "git-branch",
536
+ inputs: [{ id: "vector", name: "Vector", direction: "input", dataType: "vec2" }],
537
+ outputs: [
538
+ { id: "x", name: "X", direction: "output", dataType: "float" },
539
+ { id: "y", name: "Y", direction: "output", dataType: "float" }
540
+ ]
541
+ },
542
+ {
543
+ type: "split_vec3",
544
+ category: "vector",
545
+ name: "Split Vec3",
546
+ description: "Split vector into components",
547
+ icon: "git-branch",
548
+ inputs: [{ id: "vector", name: "Vector", direction: "input", dataType: "vec3" }],
549
+ outputs: [
550
+ { id: "x", name: "X", direction: "output", dataType: "float" },
551
+ { id: "y", name: "Y", direction: "output", dataType: "float" },
552
+ { id: "z", name: "Z", direction: "output", dataType: "float" }
553
+ ]
554
+ },
555
+ {
556
+ type: "split_vec4",
557
+ category: "vector",
558
+ name: "Split Vec4",
559
+ description: "Split vector into components",
560
+ icon: "git-branch",
561
+ inputs: [{ id: "vector", name: "Vector", direction: "input", dataType: "vec4" }],
562
+ outputs: [
563
+ { id: "x", name: "X", direction: "output", dataType: "float" },
564
+ { id: "y", name: "Y", direction: "output", dataType: "float" },
565
+ { id: "z", name: "Z", direction: "output", dataType: "float" },
566
+ { id: "w", name: "W", direction: "output", dataType: "float" }
567
+ ]
568
+ },
569
+ {
570
+ type: "combine_vec2",
571
+ category: "vector",
572
+ name: "Combine Vec2",
573
+ description: "Combine components into vector",
574
+ icon: "git-merge",
575
+ inputs: [
576
+ { id: "x", name: "X", direction: "input", dataType: "float", defaultValue: 0 },
577
+ { id: "y", name: "Y", direction: "input", dataType: "float", defaultValue: 0 }
578
+ ],
579
+ outputs: [{ id: "vector", name: "Vector", direction: "output", dataType: "vec2" }],
580
+ shaderFunction: "vec2 {{nodeId}}_vector = vec2({{x}}, {{y}});"
581
+ },
582
+ {
583
+ type: "combine_vec3",
584
+ category: "vector",
585
+ name: "Combine Vec3",
586
+ description: "Combine components into vector",
587
+ icon: "git-merge",
588
+ inputs: [
589
+ { id: "x", name: "X", direction: "input", dataType: "float", defaultValue: 0 },
590
+ { id: "y", name: "Y", direction: "input", dataType: "float", defaultValue: 0 },
591
+ { id: "z", name: "Z", direction: "input", dataType: "float", defaultValue: 0 }
592
+ ],
593
+ outputs: [{ id: "vector", name: "Vector", direction: "output", dataType: "vec3" }],
594
+ shaderFunction: "vec3 {{nodeId}}_vector = vec3({{x}}, {{y}}, {{z}});"
595
+ },
596
+ {
597
+ type: "combine_vec4",
598
+ category: "vector",
599
+ name: "Combine Vec4",
600
+ description: "Combine components into vector",
601
+ icon: "git-merge",
602
+ inputs: [
603
+ { id: "x", name: "X", direction: "input", dataType: "float", defaultValue: 0 },
604
+ { id: "y", name: "Y", direction: "input", dataType: "float", defaultValue: 0 },
605
+ { id: "z", name: "Z", direction: "input", dataType: "float", defaultValue: 0 },
606
+ { id: "w", name: "W", direction: "input", dataType: "float", defaultValue: 1 }
607
+ ],
608
+ outputs: [{ id: "vector", name: "Vector", direction: "output", dataType: "vec4" }],
609
+ shaderFunction: "vec4 {{nodeId}}_vector = vec4({{x}}, {{y}}, {{z}}, {{w}});"
610
+ },
611
+ {
612
+ type: "normalize",
613
+ category: "vector",
614
+ name: "Normalize",
615
+ description: "Normalize vector to unit length",
616
+ icon: "maximize-2",
617
+ inputs: [{ id: "vector", name: "Vector", direction: "input", dataType: "vec3" }],
618
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }],
619
+ shaderFunction: "vec3 {{nodeId}}_result = normalize({{vector}});"
620
+ },
621
+ {
622
+ type: "length",
623
+ category: "vector",
624
+ name: "Length",
625
+ description: "Vector length/magnitude",
626
+ icon: "move",
627
+ inputs: [{ id: "vector", name: "Vector", direction: "input", dataType: "vec3" }],
628
+ outputs: [{ id: "length", name: "Length", direction: "output", dataType: "float" }],
629
+ shaderFunction: "float {{nodeId}}_length = length({{vector}});"
630
+ },
631
+ {
632
+ type: "distance",
633
+ category: "vector",
634
+ name: "Distance",
635
+ description: "Distance between two points",
636
+ icon: "maximize",
637
+ inputs: [
638
+ { id: "a", name: "A", direction: "input", dataType: "vec3" },
639
+ { id: "b", name: "B", direction: "input", dataType: "vec3" }
640
+ ],
641
+ outputs: [{ id: "distance", name: "Distance", direction: "output", dataType: "float" }],
642
+ shaderFunction: "float {{nodeId}}_distance = distance({{a}}, {{b}});"
643
+ },
644
+ {
645
+ type: "dot",
646
+ category: "vector",
647
+ name: "Dot Product",
648
+ description: "Dot product of two vectors",
649
+ icon: "target",
650
+ inputs: [
651
+ { id: "a", name: "A", direction: "input", dataType: "vec3" },
652
+ { id: "b", name: "B", direction: "input", dataType: "vec3" }
653
+ ],
654
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "float" }],
655
+ shaderFunction: "float {{nodeId}}_result = dot({{a}}, {{b}});"
656
+ },
657
+ {
658
+ type: "cross",
659
+ category: "vector",
660
+ name: "Cross Product",
661
+ description: "Cross product of two vectors",
662
+ icon: "x",
663
+ inputs: [
664
+ { id: "a", name: "A", direction: "input", dataType: "vec3" },
665
+ { id: "b", name: "B", direction: "input", dataType: "vec3" }
666
+ ],
667
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }],
668
+ shaderFunction: "vec3 {{nodeId}}_result = cross({{a}}, {{b}});"
669
+ },
670
+ {
671
+ type: "reflect",
672
+ category: "vector",
673
+ name: "Reflect",
674
+ description: "Reflect vector off surface",
675
+ icon: "corner-up-left",
676
+ inputs: [
677
+ { id: "incident", name: "Incident", direction: "input", dataType: "vec3" },
678
+ { id: "normal", name: "Normal", direction: "input", dataType: "vec3" }
679
+ ],
680
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }],
681
+ shaderFunction: "vec3 {{nodeId}}_result = reflect({{incident}}, {{normal}});"
682
+ },
683
+ {
684
+ type: "refract",
685
+ category: "vector",
686
+ name: "Refract",
687
+ description: "Refract vector through surface",
688
+ icon: "corner-down-right",
689
+ inputs: [
690
+ { id: "incident", name: "Incident", direction: "input", dataType: "vec3" },
691
+ { id: "normal", name: "Normal", direction: "input", dataType: "vec3" },
692
+ { id: "ior", name: "IOR", direction: "input", dataType: "float", defaultValue: 1.5 }
693
+ ],
694
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }],
695
+ shaderFunction: "vec3 {{nodeId}}_result = refract({{incident}}, {{normal}}, {{ior}});"
696
+ },
697
+ {
698
+ type: "transform",
699
+ category: "vector",
700
+ name: "Transform",
701
+ description: "Transform vector by matrix",
702
+ icon: "rotate-cw",
703
+ inputs: [
704
+ { id: "vector", name: "Vector", direction: "input", dataType: "vec3" },
705
+ { id: "matrix", name: "Matrix", direction: "input", dataType: "matrix4" }
706
+ ],
707
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }]
708
+ }
735
709
  ];
736
- /* ═══════════════════════════════════════════════════════════════════════════
737
- COLOR NODES
738
- ═══════════════════════════════════════════════════════════════════════════ */
739
710
  const colorNodes = [
740
- {
741
- type: 'hsv_to_rgb',
742
- category: 'color',
743
- name: 'HSV to RGB',
744
- description: 'Convert HSV to RGB',
745
- icon: 'droplet',
746
- inputs: [
747
- {
748
- id: 'h',
749
- name: 'H',
750
- direction: 'input',
751
- dataType: 'float',
752
- defaultValue: 0,
753
- min: 0,
754
- max: 1,
755
- },
756
- {
757
- id: 's',
758
- name: 'S',
759
- direction: 'input',
760
- dataType: 'float',
761
- defaultValue: 1,
762
- min: 0,
763
- max: 1,
764
- },
765
- {
766
- id: 'v',
767
- name: 'V',
768
- direction: 'input',
769
- dataType: 'float',
770
- defaultValue: 1,
771
- min: 0,
772
- max: 1,
773
- },
774
- ],
775
- outputs: [{ id: 'rgb', name: 'RGB', direction: 'output', dataType: 'vec3' }],
776
- previewable: true,
777
- },
778
- {
779
- type: 'rgb_to_hsv',
780
- category: 'color',
781
- name: 'RGB to HSV',
782
- description: 'Convert RGB to HSV',
783
- icon: 'droplet',
784
- inputs: [{ id: 'rgb', name: 'RGB', direction: 'input', dataType: 'vec3' }],
785
- outputs: [
786
- { id: 'h', name: 'H', direction: 'output', dataType: 'float' },
787
- { id: 's', name: 'S', direction: 'output', dataType: 'float' },
788
- { id: 'v', name: 'V', direction: 'output', dataType: 'float' },
789
- ],
790
- },
791
- {
792
- type: 'blend',
793
- category: 'color',
794
- name: 'Blend',
795
- description: 'Blend two colors',
796
- icon: 'layers',
797
- inputs: [
798
- { id: 'base', name: 'Base', direction: 'input', dataType: 'vec3' },
799
- { id: 'blend', name: 'Blend', direction: 'input', dataType: 'vec3' },
800
- {
801
- id: 'factor',
802
- name: 'Factor',
803
- direction: 'input',
804
- dataType: 'float',
805
- defaultValue: 0.5,
806
- min: 0,
807
- max: 1,
808
- },
809
- ],
810
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
811
- properties: [
812
- {
813
- id: 'mode',
814
- name: 'Mode',
815
- type: 'enum',
816
- default: 'normal',
817
- options: [
818
- { label: 'Normal', value: 'normal' },
819
- { label: 'Multiply', value: 'multiply' },
820
- { label: 'Screen', value: 'screen' },
821
- { label: 'Overlay', value: 'overlay' },
822
- { label: 'Add', value: 'add' },
823
- { label: 'Subtract', value: 'subtract' },
824
- { label: 'Difference', value: 'difference' },
825
- ],
826
- },
827
- ],
828
- previewable: true,
829
- },
830
- {
831
- type: 'brightness_contrast',
832
- category: 'color',
833
- name: 'Brightness/Contrast',
834
- description: 'Adjust brightness and contrast',
835
- icon: 'sun',
836
- inputs: [
837
- { id: 'color', name: 'Color', direction: 'input', dataType: 'vec3' },
838
- {
839
- id: 'brightness',
840
- name: 'Brightness',
841
- direction: 'input',
842
- dataType: 'float',
843
- defaultValue: 0,
844
- min: -1,
845
- max: 1,
846
- },
847
- {
848
- id: 'contrast',
849
- name: 'Contrast',
850
- direction: 'input',
851
- dataType: 'float',
852
- defaultValue: 1,
853
- min: 0,
854
- max: 2,
855
- },
856
- ],
857
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
858
- previewable: true,
859
- },
860
- {
861
- type: 'hue_saturation',
862
- category: 'color',
863
- name: 'Hue/Saturation',
864
- description: 'Adjust hue, saturation, value',
865
- icon: 'sliders',
866
- inputs: [
867
- { id: 'color', name: 'Color', direction: 'input', dataType: 'vec3' },
868
- {
869
- id: 'hue',
870
- name: 'Hue',
871
- direction: 'input',
872
- dataType: 'float',
873
- defaultValue: 0,
874
- min: -1,
875
- max: 1,
876
- },
877
- {
878
- id: 'saturation',
879
- name: 'Saturation',
880
- direction: 'input',
881
- dataType: 'float',
882
- defaultValue: 1,
883
- min: 0,
884
- max: 2,
885
- },
886
- {
887
- id: 'value',
888
- name: 'Value',
889
- direction: 'input',
890
- dataType: 'float',
891
- defaultValue: 1,
892
- min: 0,
893
- max: 2,
894
- },
895
- ],
896
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
897
- previewable: true,
898
- },
899
- {
900
- type: 'invert',
901
- category: 'color',
902
- name: 'Invert',
903
- description: 'Invert color',
904
- icon: 'refresh-cw',
905
- inputs: [{ id: 'color', name: 'Color', direction: 'input', dataType: 'vec3' }],
906
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
907
- shaderFunction: 'vec3 {{nodeId}}_result = vec3(1.0) - {{color}};',
908
- previewable: true,
909
- },
910
- {
911
- type: 'gamma',
912
- category: 'color',
913
- name: 'Gamma',
914
- description: 'Apply gamma correction',
915
- icon: 'zap',
916
- inputs: [
917
- { id: 'color', name: 'Color', direction: 'input', dataType: 'vec3' },
918
- { id: 'gamma', name: 'Gamma', direction: 'input', dataType: 'float', defaultValue: 2.2 },
919
- ],
920
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'vec3' }],
921
- shaderFunction: 'vec3 {{nodeId}}_result = pow({{color}}, vec3(1.0 / {{gamma}}));',
922
- previewable: true,
923
- },
924
- {
925
- type: 'grayscale',
926
- category: 'color',
927
- name: 'Grayscale',
928
- description: 'Convert to grayscale',
929
- icon: 'circle',
930
- inputs: [{ id: 'color', name: 'Color', direction: 'input', dataType: 'vec3' }],
931
- outputs: [
932
- { id: 'gray', name: 'Gray', direction: 'output', dataType: 'float' },
933
- { id: 'rgb', name: 'RGB', direction: 'output', dataType: 'vec3' },
934
- ],
935
- shaderFunction: 'float {{nodeId}}_gray = dot({{color}}, vec3(0.299, 0.587, 0.114));',
936
- previewable: true,
937
- },
711
+ {
712
+ type: "hsv_to_rgb",
713
+ category: "color",
714
+ name: "HSV to RGB",
715
+ description: "Convert HSV to RGB",
716
+ icon: "droplet",
717
+ inputs: [
718
+ {
719
+ id: "h",
720
+ name: "H",
721
+ direction: "input",
722
+ dataType: "float",
723
+ defaultValue: 0,
724
+ min: 0,
725
+ max: 1
726
+ },
727
+ {
728
+ id: "s",
729
+ name: "S",
730
+ direction: "input",
731
+ dataType: "float",
732
+ defaultValue: 1,
733
+ min: 0,
734
+ max: 1
735
+ },
736
+ {
737
+ id: "v",
738
+ name: "V",
739
+ direction: "input",
740
+ dataType: "float",
741
+ defaultValue: 1,
742
+ min: 0,
743
+ max: 1
744
+ }
745
+ ],
746
+ outputs: [{ id: "rgb", name: "RGB", direction: "output", dataType: "vec3" }],
747
+ previewable: true
748
+ },
749
+ {
750
+ type: "rgb_to_hsv",
751
+ category: "color",
752
+ name: "RGB to HSV",
753
+ description: "Convert RGB to HSV",
754
+ icon: "droplet",
755
+ inputs: [{ id: "rgb", name: "RGB", direction: "input", dataType: "vec3" }],
756
+ outputs: [
757
+ { id: "h", name: "H", direction: "output", dataType: "float" },
758
+ { id: "s", name: "S", direction: "output", dataType: "float" },
759
+ { id: "v", name: "V", direction: "output", dataType: "float" }
760
+ ]
761
+ },
762
+ {
763
+ type: "blend",
764
+ category: "color",
765
+ name: "Blend",
766
+ description: "Blend two colors",
767
+ icon: "layers",
768
+ inputs: [
769
+ { id: "base", name: "Base", direction: "input", dataType: "vec3" },
770
+ { id: "blend", name: "Blend", direction: "input", dataType: "vec3" },
771
+ {
772
+ id: "factor",
773
+ name: "Factor",
774
+ direction: "input",
775
+ dataType: "float",
776
+ defaultValue: 0.5,
777
+ min: 0,
778
+ max: 1
779
+ }
780
+ ],
781
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }],
782
+ properties: [
783
+ {
784
+ id: "mode",
785
+ name: "Mode",
786
+ type: "enum",
787
+ default: "normal",
788
+ options: [
789
+ { label: "Normal", value: "normal" },
790
+ { label: "Multiply", value: "multiply" },
791
+ { label: "Screen", value: "screen" },
792
+ { label: "Overlay", value: "overlay" },
793
+ { label: "Add", value: "add" },
794
+ { label: "Subtract", value: "subtract" },
795
+ { label: "Difference", value: "difference" }
796
+ ]
797
+ }
798
+ ],
799
+ previewable: true
800
+ },
801
+ {
802
+ type: "brightness_contrast",
803
+ category: "color",
804
+ name: "Brightness/Contrast",
805
+ description: "Adjust brightness and contrast",
806
+ icon: "sun",
807
+ inputs: [
808
+ { id: "color", name: "Color", direction: "input", dataType: "vec3" },
809
+ {
810
+ id: "brightness",
811
+ name: "Brightness",
812
+ direction: "input",
813
+ dataType: "float",
814
+ defaultValue: 0,
815
+ min: -1,
816
+ max: 1
817
+ },
818
+ {
819
+ id: "contrast",
820
+ name: "Contrast",
821
+ direction: "input",
822
+ dataType: "float",
823
+ defaultValue: 1,
824
+ min: 0,
825
+ max: 2
826
+ }
827
+ ],
828
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }],
829
+ previewable: true
830
+ },
831
+ {
832
+ type: "hue_saturation",
833
+ category: "color",
834
+ name: "Hue/Saturation",
835
+ description: "Adjust hue, saturation, value",
836
+ icon: "sliders",
837
+ inputs: [
838
+ { id: "color", name: "Color", direction: "input", dataType: "vec3" },
839
+ {
840
+ id: "hue",
841
+ name: "Hue",
842
+ direction: "input",
843
+ dataType: "float",
844
+ defaultValue: 0,
845
+ min: -1,
846
+ max: 1
847
+ },
848
+ {
849
+ id: "saturation",
850
+ name: "Saturation",
851
+ direction: "input",
852
+ dataType: "float",
853
+ defaultValue: 1,
854
+ min: 0,
855
+ max: 2
856
+ },
857
+ {
858
+ id: "value",
859
+ name: "Value",
860
+ direction: "input",
861
+ dataType: "float",
862
+ defaultValue: 1,
863
+ min: 0,
864
+ max: 2
865
+ }
866
+ ],
867
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }],
868
+ previewable: true
869
+ },
870
+ {
871
+ type: "invert",
872
+ category: "color",
873
+ name: "Invert",
874
+ description: "Invert color",
875
+ icon: "refresh-cw",
876
+ inputs: [{ id: "color", name: "Color", direction: "input", dataType: "vec3" }],
877
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }],
878
+ shaderFunction: "vec3 {{nodeId}}_result = vec3(1.0) - {{color}};",
879
+ previewable: true
880
+ },
881
+ {
882
+ type: "gamma",
883
+ category: "color",
884
+ name: "Gamma",
885
+ description: "Apply gamma correction",
886
+ icon: "zap",
887
+ inputs: [
888
+ { id: "color", name: "Color", direction: "input", dataType: "vec3" },
889
+ { id: "gamma", name: "Gamma", direction: "input", dataType: "float", defaultValue: 2.2 }
890
+ ],
891
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "vec3" }],
892
+ shaderFunction: "vec3 {{nodeId}}_result = pow({{color}}, vec3(1.0 / {{gamma}}));",
893
+ previewable: true
894
+ },
895
+ {
896
+ type: "grayscale",
897
+ category: "color",
898
+ name: "Grayscale",
899
+ description: "Convert to grayscale",
900
+ icon: "circle",
901
+ inputs: [{ id: "color", name: "Color", direction: "input", dataType: "vec3" }],
902
+ outputs: [
903
+ { id: "gray", name: "Gray", direction: "output", dataType: "float" },
904
+ { id: "rgb", name: "RGB", direction: "output", dataType: "vec3" }
905
+ ],
906
+ shaderFunction: "float {{nodeId}}_gray = dot({{color}}, vec3(0.299, 0.587, 0.114));",
907
+ previewable: true
908
+ }
938
909
  ];
939
- /* ═══════════════════════════════════════════════════════════════════════════
940
- TEXTURE NODES
941
- ═══════════════════════════════════════════════════════════════════════════ */
942
910
  const textureNodes = [
943
- {
944
- type: 'sample_texture',
945
- category: 'texture',
946
- name: 'Sample Texture',
947
- description: 'Sample 2D texture',
948
- icon: 'image',
949
- inputs: [
950
- { id: 'texture', name: 'Texture', direction: 'input', dataType: 'texture2d' },
951
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
952
- ],
953
- outputs: [
954
- { id: 'rgba', name: 'RGBA', direction: 'output', dataType: 'vec4' },
955
- { id: 'rgb', name: 'RGB', direction: 'output', dataType: 'vec3' },
956
- { id: 'r', name: 'R', direction: 'output', dataType: 'float' },
957
- { id: 'g', name: 'G', direction: 'output', dataType: 'float' },
958
- { id: 'b', name: 'B', direction: 'output', dataType: 'float' },
959
- { id: 'a', name: 'A', direction: 'output', dataType: 'float' },
960
- ],
961
- shaderFunction: 'vec4 {{nodeId}}_rgba = texture2D({{texture}}, {{uv}});',
962
- previewable: true,
963
- },
964
- {
965
- type: 'sample_cubemap',
966
- category: 'texture',
967
- name: 'Sample Cubemap',
968
- description: 'Sample cubemap texture',
969
- icon: 'box',
970
- inputs: [
971
- { id: 'texture', name: 'Texture', direction: 'input', dataType: 'textureCube' },
972
- { id: 'direction', name: 'Direction', direction: 'input', dataType: 'vec3' },
973
- ],
974
- outputs: [
975
- { id: 'rgba', name: 'RGBA', direction: 'output', dataType: 'vec4' },
976
- { id: 'rgb', name: 'RGB', direction: 'output', dataType: 'vec3' },
977
- ],
978
- shaderFunction: 'vec4 {{nodeId}}_rgba = textureCube({{texture}}, {{direction}});',
979
- previewable: true,
980
- },
981
- {
982
- type: 'normal_map',
983
- category: 'texture',
984
- name: 'Normal Map',
985
- description: 'Unpack normal map',
986
- icon: 'arrow-up-right',
987
- inputs: [
988
- { id: 'texture', name: 'Texture', direction: 'input', dataType: 'texture2d' },
989
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
990
- {
991
- id: 'strength',
992
- name: 'Strength',
993
- direction: 'input',
994
- dataType: 'float',
995
- defaultValue: 1,
996
- min: 0,
997
- max: 2,
998
- },
999
- ],
1000
- outputs: [{ id: 'normal', name: 'Normal', direction: 'output', dataType: 'vec3' }],
1001
- previewable: true,
1002
- },
1003
- {
1004
- type: 'uv_tiling',
1005
- category: 'texture',
1006
- name: 'UV Tiling/Offset',
1007
- description: 'Tile and offset UVs',
1008
- icon: 'grid',
1009
- inputs: [
1010
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1011
- { id: 'tiling', name: 'Tiling', direction: 'input', dataType: 'vec2', defaultValue: [1, 1] },
1012
- { id: 'offset', name: 'Offset', direction: 'input', dataType: 'vec2', defaultValue: [0, 0] },
1013
- ],
1014
- outputs: [{ id: 'uv', name: 'UV', direction: 'output', dataType: 'vec2' }],
1015
- shaderFunction: 'vec2 {{nodeId}}_uv = {{uv}} * {{tiling}} + {{offset}};',
1016
- },
1017
- {
1018
- type: 'uv_rotate',
1019
- category: 'texture',
1020
- name: 'UV Rotate',
1021
- description: 'Rotate UVs',
1022
- icon: 'rotate-cw',
1023
- inputs: [
1024
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1025
- { id: 'angle', name: 'Angle', direction: 'input', dataType: 'float', defaultValue: 0 },
1026
- {
1027
- id: 'center',
1028
- name: 'Center',
1029
- direction: 'input',
1030
- dataType: 'vec2',
1031
- defaultValue: [0.5, 0.5],
1032
- },
1033
- ],
1034
- outputs: [{ id: 'uv', name: 'UV', direction: 'output', dataType: 'vec2' }],
1035
- },
1036
- {
1037
- type: 'parallax',
1038
- category: 'texture',
1039
- name: 'Parallax',
1040
- description: 'Parallax mapping',
1041
- icon: 'layers',
1042
- inputs: [
1043
- { id: 'heightMap', name: 'Height Map', direction: 'input', dataType: 'texture2d' },
1044
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1045
- { id: 'viewDir', name: 'View Dir', direction: 'input', dataType: 'vec3' },
1046
- { id: 'scale', name: 'Scale', direction: 'input', dataType: 'float', defaultValue: 0.1 },
1047
- ],
1048
- outputs: [{ id: 'uv', name: 'UV', direction: 'output', dataType: 'vec2' }],
1049
- },
1050
- {
1051
- type: 'triplanar',
1052
- category: 'texture',
1053
- name: 'Triplanar',
1054
- description: 'Triplanar texture projection',
1055
- icon: 'box',
1056
- inputs: [
1057
- { id: 'texture', name: 'Texture', direction: 'input', dataType: 'texture2d' },
1058
- { id: 'position', name: 'Position', direction: 'input', dataType: 'vec3' },
1059
- { id: 'normal', name: 'Normal', direction: 'input', dataType: 'vec3' },
1060
- { id: 'scale', name: 'Scale', direction: 'input', dataType: 'float', defaultValue: 1 },
1061
- { id: 'blend', name: 'Blend', direction: 'input', dataType: 'float', defaultValue: 0.5 },
1062
- ],
1063
- outputs: [{ id: 'color', name: 'Color', direction: 'output', dataType: 'vec4' }],
1064
- previewable: true,
1065
- },
911
+ {
912
+ type: "sample_texture",
913
+ category: "texture",
914
+ name: "Sample Texture",
915
+ description: "Sample 2D texture",
916
+ icon: "image",
917
+ inputs: [
918
+ { id: "texture", name: "Texture", direction: "input", dataType: "texture2d" },
919
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" }
920
+ ],
921
+ outputs: [
922
+ { id: "rgba", name: "RGBA", direction: "output", dataType: "vec4" },
923
+ { id: "rgb", name: "RGB", direction: "output", dataType: "vec3" },
924
+ { id: "r", name: "R", direction: "output", dataType: "float" },
925
+ { id: "g", name: "G", direction: "output", dataType: "float" },
926
+ { id: "b", name: "B", direction: "output", dataType: "float" },
927
+ { id: "a", name: "A", direction: "output", dataType: "float" }
928
+ ],
929
+ shaderFunction: "vec4 {{nodeId}}_rgba = texture2D({{texture}}, {{uv}});",
930
+ previewable: true
931
+ },
932
+ {
933
+ type: "sample_cubemap",
934
+ category: "texture",
935
+ name: "Sample Cubemap",
936
+ description: "Sample cubemap texture",
937
+ icon: "box",
938
+ inputs: [
939
+ { id: "texture", name: "Texture", direction: "input", dataType: "textureCube" },
940
+ { id: "direction", name: "Direction", direction: "input", dataType: "vec3" }
941
+ ],
942
+ outputs: [
943
+ { id: "rgba", name: "RGBA", direction: "output", dataType: "vec4" },
944
+ { id: "rgb", name: "RGB", direction: "output", dataType: "vec3" }
945
+ ],
946
+ shaderFunction: "vec4 {{nodeId}}_rgba = textureCube({{texture}}, {{direction}});",
947
+ previewable: true
948
+ },
949
+ {
950
+ type: "normal_map",
951
+ category: "texture",
952
+ name: "Normal Map",
953
+ description: "Unpack normal map",
954
+ icon: "arrow-up-right",
955
+ inputs: [
956
+ { id: "texture", name: "Texture", direction: "input", dataType: "texture2d" },
957
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
958
+ {
959
+ id: "strength",
960
+ name: "Strength",
961
+ direction: "input",
962
+ dataType: "float",
963
+ defaultValue: 1,
964
+ min: 0,
965
+ max: 2
966
+ }
967
+ ],
968
+ outputs: [{ id: "normal", name: "Normal", direction: "output", dataType: "vec3" }],
969
+ previewable: true
970
+ },
971
+ {
972
+ type: "uv_tiling",
973
+ category: "texture",
974
+ name: "UV Tiling/Offset",
975
+ description: "Tile and offset UVs",
976
+ icon: "grid",
977
+ inputs: [
978
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
979
+ { id: "tiling", name: "Tiling", direction: "input", dataType: "vec2", defaultValue: [1, 1] },
980
+ { id: "offset", name: "Offset", direction: "input", dataType: "vec2", defaultValue: [0, 0] }
981
+ ],
982
+ outputs: [{ id: "uv", name: "UV", direction: "output", dataType: "vec2" }],
983
+ shaderFunction: "vec2 {{nodeId}}_uv = {{uv}} * {{tiling}} + {{offset}};"
984
+ },
985
+ {
986
+ type: "uv_rotate",
987
+ category: "texture",
988
+ name: "UV Rotate",
989
+ description: "Rotate UVs",
990
+ icon: "rotate-cw",
991
+ inputs: [
992
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
993
+ { id: "angle", name: "Angle", direction: "input", dataType: "float", defaultValue: 0 },
994
+ {
995
+ id: "center",
996
+ name: "Center",
997
+ direction: "input",
998
+ dataType: "vec2",
999
+ defaultValue: [0.5, 0.5]
1000
+ }
1001
+ ],
1002
+ outputs: [{ id: "uv", name: "UV", direction: "output", dataType: "vec2" }]
1003
+ },
1004
+ {
1005
+ type: "parallax",
1006
+ category: "texture",
1007
+ name: "Parallax",
1008
+ description: "Parallax mapping",
1009
+ icon: "layers",
1010
+ inputs: [
1011
+ { id: "heightMap", name: "Height Map", direction: "input", dataType: "texture2d" },
1012
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
1013
+ { id: "viewDir", name: "View Dir", direction: "input", dataType: "vec3" },
1014
+ { id: "scale", name: "Scale", direction: "input", dataType: "float", defaultValue: 0.1 }
1015
+ ],
1016
+ outputs: [{ id: "uv", name: "UV", direction: "output", dataType: "vec2" }]
1017
+ },
1018
+ {
1019
+ type: "triplanar",
1020
+ category: "texture",
1021
+ name: "Triplanar",
1022
+ description: "Triplanar texture projection",
1023
+ icon: "box",
1024
+ inputs: [
1025
+ { id: "texture", name: "Texture", direction: "input", dataType: "texture2d" },
1026
+ { id: "position", name: "Position", direction: "input", dataType: "vec3" },
1027
+ { id: "normal", name: "Normal", direction: "input", dataType: "vec3" },
1028
+ { id: "scale", name: "Scale", direction: "input", dataType: "float", defaultValue: 1 },
1029
+ { id: "blend", name: "Blend", direction: "input", dataType: "float", defaultValue: 0.5 }
1030
+ ],
1031
+ outputs: [{ id: "color", name: "Color", direction: "output", dataType: "vec4" }],
1032
+ previewable: true
1033
+ }
1066
1034
  ];
1067
- /* ═══════════════════════════════════════════════════════════════════════════
1068
- PROCEDURAL NODES
1069
- ═══════════════════════════════════════════════════════════════════════════ */
1070
1035
  const proceduralNodes = [
1071
- {
1072
- type: 'noise_perlin',
1073
- category: 'procedural',
1074
- name: 'Perlin Noise',
1075
- description: 'Perlin noise generator',
1076
- icon: 'hash',
1077
- inputs: [
1078
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1079
- { id: 'scale', name: 'Scale', direction: 'input', dataType: 'float', defaultValue: 10 },
1080
- { id: 'octaves', name: 'Octaves', direction: 'input', dataType: 'int', defaultValue: 4 },
1081
- ],
1082
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'float' }],
1083
- previewable: true,
1084
- },
1085
- {
1086
- type: 'noise_simplex',
1087
- category: 'procedural',
1088
- name: 'Simplex Noise',
1089
- description: 'Simplex noise generator',
1090
- icon: 'hash',
1091
- inputs: [
1092
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1093
- { id: 'scale', name: 'Scale', direction: 'input', dataType: 'float', defaultValue: 10 },
1094
- ],
1095
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'float' }],
1096
- previewable: true,
1097
- },
1098
- {
1099
- type: 'noise_voronoi',
1100
- category: 'procedural',
1101
- name: 'Voronoi',
1102
- description: 'Voronoi/Worley noise',
1103
- icon: 'hexagon',
1104
- inputs: [
1105
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1106
- { id: 'scale', name: 'Scale', direction: 'input', dataType: 'float', defaultValue: 10 },
1107
- { id: 'jitter', name: 'Jitter', direction: 'input', dataType: 'float', defaultValue: 1 },
1108
- ],
1109
- outputs: [
1110
- { id: 'distance', name: 'Distance', direction: 'output', dataType: 'float' },
1111
- { id: 'cellId', name: 'Cell ID', direction: 'output', dataType: 'float' },
1112
- ],
1113
- previewable: true,
1114
- },
1115
- {
1116
- type: 'noise_fbm',
1117
- category: 'procedural',
1118
- name: 'FBM Noise',
1119
- description: 'Fractional Brownian Motion',
1120
- icon: 'cloud',
1121
- inputs: [
1122
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1123
- { id: 'scale', name: 'Scale', direction: 'input', dataType: 'float', defaultValue: 5 },
1124
- { id: 'octaves', name: 'Octaves', direction: 'input', dataType: 'int', defaultValue: 6 },
1125
- {
1126
- id: 'lacunarity',
1127
- name: 'Lacunarity',
1128
- direction: 'input',
1129
- dataType: 'float',
1130
- defaultValue: 2,
1131
- },
1132
- { id: 'gain', name: 'Gain', direction: 'input', dataType: 'float', defaultValue: 0.5 },
1133
- ],
1134
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'float' }],
1135
- previewable: true,
1136
- },
1137
- {
1138
- type: 'gradient_linear',
1139
- category: 'procedural',
1140
- name: 'Linear Gradient',
1141
- description: 'Linear gradient',
1142
- icon: 'arrow-right',
1143
- inputs: [{ id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' }],
1144
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'float' }],
1145
- properties: [
1146
- {
1147
- id: 'direction',
1148
- name: 'Direction',
1149
- type: 'enum',
1150
- default: 'horizontal',
1151
- options: [
1152
- { label: 'Horizontal', value: 'horizontal' },
1153
- { label: 'Vertical', value: 'vertical' },
1154
- { label: 'Diagonal', value: 'diagonal' },
1155
- ],
1156
- },
1157
- ],
1158
- previewable: true,
1159
- },
1160
- {
1161
- type: 'gradient_radial',
1162
- category: 'procedural',
1163
- name: 'Radial Gradient',
1164
- description: 'Radial gradient',
1165
- icon: 'circle',
1166
- inputs: [
1167
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1168
- {
1169
- id: 'center',
1170
- name: 'Center',
1171
- direction: 'input',
1172
- dataType: 'vec2',
1173
- defaultValue: [0.5, 0.5],
1174
- },
1175
- { id: 'radius', name: 'Radius', direction: 'input', dataType: 'float', defaultValue: 0.5 },
1176
- ],
1177
- outputs: [{ id: 'value', name: 'Value', direction: 'output', dataType: 'float' }],
1178
- previewable: true,
1179
- },
1180
- {
1181
- type: 'checker',
1182
- category: 'procedural',
1183
- name: 'Checker',
1184
- description: 'Checkerboard pattern',
1185
- icon: 'grid',
1186
- inputs: [
1187
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1188
- { id: 'scale', name: 'Scale', direction: 'input', dataType: 'float', defaultValue: 8 },
1189
- {
1190
- id: 'colorA',
1191
- name: 'Color A',
1192
- direction: 'input',
1193
- dataType: 'vec3',
1194
- defaultValue: [0, 0, 0],
1195
- },
1196
- {
1197
- id: 'colorB',
1198
- name: 'Color B',
1199
- direction: 'input',
1200
- dataType: 'vec3',
1201
- defaultValue: [1, 1, 1],
1202
- },
1203
- ],
1204
- outputs: [
1205
- { id: 'color', name: 'Color', direction: 'output', dataType: 'vec3' },
1206
- { id: 'value', name: 'Value', direction: 'output', dataType: 'float' },
1207
- ],
1208
- previewable: true,
1209
- },
1210
- {
1211
- type: 'brick',
1212
- category: 'procedural',
1213
- name: 'Brick',
1214
- description: 'Brick pattern',
1215
- icon: 'layout',
1216
- inputs: [
1217
- { id: 'uv', name: 'UV', direction: 'input', dataType: 'vec2' },
1218
- {
1219
- id: 'brickWidth',
1220
- name: 'Brick Width',
1221
- direction: 'input',
1222
- dataType: 'float',
1223
- defaultValue: 0.5,
1224
- },
1225
- {
1226
- id: 'brickHeight',
1227
- name: 'Brick Height',
1228
- direction: 'input',
1229
- dataType: 'float',
1230
- defaultValue: 0.25,
1231
- },
1232
- {
1233
- id: 'mortarSize',
1234
- name: 'Mortar Size',
1235
- direction: 'input',
1236
- dataType: 'float',
1237
- defaultValue: 0.02,
1238
- },
1239
- ],
1240
- outputs: [
1241
- { id: 'mask', name: 'Mask', direction: 'output', dataType: 'float' },
1242
- { id: 'brickId', name: 'Brick ID', direction: 'output', dataType: 'vec2' },
1243
- ],
1244
- previewable: true,
1245
- },
1036
+ {
1037
+ type: "noise_perlin",
1038
+ category: "procedural",
1039
+ name: "Perlin Noise",
1040
+ description: "Perlin noise generator",
1041
+ icon: "hash",
1042
+ inputs: [
1043
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
1044
+ { id: "scale", name: "Scale", direction: "input", dataType: "float", defaultValue: 10 },
1045
+ { id: "octaves", name: "Octaves", direction: "input", dataType: "int", defaultValue: 4 }
1046
+ ],
1047
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "float" }],
1048
+ previewable: true
1049
+ },
1050
+ {
1051
+ type: "noise_simplex",
1052
+ category: "procedural",
1053
+ name: "Simplex Noise",
1054
+ description: "Simplex noise generator",
1055
+ icon: "hash",
1056
+ inputs: [
1057
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
1058
+ { id: "scale", name: "Scale", direction: "input", dataType: "float", defaultValue: 10 }
1059
+ ],
1060
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "float" }],
1061
+ previewable: true
1062
+ },
1063
+ {
1064
+ type: "noise_voronoi",
1065
+ category: "procedural",
1066
+ name: "Voronoi",
1067
+ description: "Voronoi/Worley noise",
1068
+ icon: "hexagon",
1069
+ inputs: [
1070
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
1071
+ { id: "scale", name: "Scale", direction: "input", dataType: "float", defaultValue: 10 },
1072
+ { id: "jitter", name: "Jitter", direction: "input", dataType: "float", defaultValue: 1 }
1073
+ ],
1074
+ outputs: [
1075
+ { id: "distance", name: "Distance", direction: "output", dataType: "float" },
1076
+ { id: "cellId", name: "Cell ID", direction: "output", dataType: "float" }
1077
+ ],
1078
+ previewable: true
1079
+ },
1080
+ {
1081
+ type: "noise_fbm",
1082
+ category: "procedural",
1083
+ name: "FBM Noise",
1084
+ description: "Fractional Brownian Motion",
1085
+ icon: "cloud",
1086
+ inputs: [
1087
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
1088
+ { id: "scale", name: "Scale", direction: "input", dataType: "float", defaultValue: 5 },
1089
+ { id: "octaves", name: "Octaves", direction: "input", dataType: "int", defaultValue: 6 },
1090
+ {
1091
+ id: "lacunarity",
1092
+ name: "Lacunarity",
1093
+ direction: "input",
1094
+ dataType: "float",
1095
+ defaultValue: 2
1096
+ },
1097
+ { id: "gain", name: "Gain", direction: "input", dataType: "float", defaultValue: 0.5 }
1098
+ ],
1099
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "float" }],
1100
+ previewable: true
1101
+ },
1102
+ {
1103
+ type: "gradient_linear",
1104
+ category: "procedural",
1105
+ name: "Linear Gradient",
1106
+ description: "Linear gradient",
1107
+ icon: "arrow-right",
1108
+ inputs: [{ id: "uv", name: "UV", direction: "input", dataType: "vec2" }],
1109
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "float" }],
1110
+ properties: [
1111
+ {
1112
+ id: "direction",
1113
+ name: "Direction",
1114
+ type: "enum",
1115
+ default: "horizontal",
1116
+ options: [
1117
+ { label: "Horizontal", value: "horizontal" },
1118
+ { label: "Vertical", value: "vertical" },
1119
+ { label: "Diagonal", value: "diagonal" }
1120
+ ]
1121
+ }
1122
+ ],
1123
+ previewable: true
1124
+ },
1125
+ {
1126
+ type: "gradient_radial",
1127
+ category: "procedural",
1128
+ name: "Radial Gradient",
1129
+ description: "Radial gradient",
1130
+ icon: "circle",
1131
+ inputs: [
1132
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
1133
+ {
1134
+ id: "center",
1135
+ name: "Center",
1136
+ direction: "input",
1137
+ dataType: "vec2",
1138
+ defaultValue: [0.5, 0.5]
1139
+ },
1140
+ { id: "radius", name: "Radius", direction: "input", dataType: "float", defaultValue: 0.5 }
1141
+ ],
1142
+ outputs: [{ id: "value", name: "Value", direction: "output", dataType: "float" }],
1143
+ previewable: true
1144
+ },
1145
+ {
1146
+ type: "checker",
1147
+ category: "procedural",
1148
+ name: "Checker",
1149
+ description: "Checkerboard pattern",
1150
+ icon: "grid",
1151
+ inputs: [
1152
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
1153
+ { id: "scale", name: "Scale", direction: "input", dataType: "float", defaultValue: 8 },
1154
+ {
1155
+ id: "colorA",
1156
+ name: "Color A",
1157
+ direction: "input",
1158
+ dataType: "vec3",
1159
+ defaultValue: [0, 0, 0]
1160
+ },
1161
+ {
1162
+ id: "colorB",
1163
+ name: "Color B",
1164
+ direction: "input",
1165
+ dataType: "vec3",
1166
+ defaultValue: [1, 1, 1]
1167
+ }
1168
+ ],
1169
+ outputs: [
1170
+ { id: "color", name: "Color", direction: "output", dataType: "vec3" },
1171
+ { id: "value", name: "Value", direction: "output", dataType: "float" }
1172
+ ],
1173
+ previewable: true
1174
+ },
1175
+ {
1176
+ type: "brick",
1177
+ category: "procedural",
1178
+ name: "Brick",
1179
+ description: "Brick pattern",
1180
+ icon: "layout",
1181
+ inputs: [
1182
+ { id: "uv", name: "UV", direction: "input", dataType: "vec2" },
1183
+ {
1184
+ id: "brickWidth",
1185
+ name: "Brick Width",
1186
+ direction: "input",
1187
+ dataType: "float",
1188
+ defaultValue: 0.5
1189
+ },
1190
+ {
1191
+ id: "brickHeight",
1192
+ name: "Brick Height",
1193
+ direction: "input",
1194
+ dataType: "float",
1195
+ defaultValue: 0.25
1196
+ },
1197
+ {
1198
+ id: "mortarSize",
1199
+ name: "Mortar Size",
1200
+ direction: "input",
1201
+ dataType: "float",
1202
+ defaultValue: 0.02
1203
+ }
1204
+ ],
1205
+ outputs: [
1206
+ { id: "mask", name: "Mask", direction: "output", dataType: "float" },
1207
+ { id: "brickId", name: "Brick ID", direction: "output", dataType: "vec2" }
1208
+ ],
1209
+ previewable: true
1210
+ }
1246
1211
  ];
1247
- /* ═══════════════════════════════════════════════════════════════════════════
1248
- UTILITY NODES
1249
- ═══════════════════════════════════════════════════════════════════════════ */
1250
1212
  const utilityNodes = [
1251
- {
1252
- type: 'lerp',
1253
- category: 'utility',
1254
- name: 'Lerp',
1255
- description: 'Linear interpolation',
1256
- icon: 'sliders',
1257
- inputs: [
1258
- { id: 'a', name: 'A', direction: 'input', dataType: 'any', defaultValue: 0 },
1259
- { id: 'b', name: 'B', direction: 'input', dataType: 'any', defaultValue: 1 },
1260
- {
1261
- id: 't',
1262
- name: 'T',
1263
- direction: 'input',
1264
- dataType: 'float',
1265
- defaultValue: 0.5,
1266
- min: 0,
1267
- max: 1,
1268
- },
1269
- ],
1270
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
1271
- shaderFunction: '{{typeA}} {{nodeId}}_result = mix({{a}}, {{b}}, {{t}});',
1272
- },
1273
- {
1274
- type: 'clamp',
1275
- category: 'utility',
1276
- name: 'Clamp',
1277
- description: 'Clamp value to range',
1278
- icon: 'minus-square',
1279
- inputs: [
1280
- { id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 },
1281
- { id: 'min', name: 'Min', direction: 'input', dataType: 'any', defaultValue: 0 },
1282
- { id: 'max', name: 'Max', direction: 'input', dataType: 'any', defaultValue: 1 },
1283
- ],
1284
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
1285
- shaderFunction: '{{typeValue}} {{nodeId}}_result = clamp({{value}}, {{min}}, {{max}});',
1286
- },
1287
- {
1288
- type: 'saturate',
1289
- category: 'utility',
1290
- name: 'Saturate',
1291
- description: 'Clamp to 0-1',
1292
- icon: 'minimize-2',
1293
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
1294
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
1295
- shaderFunction: '{{typeValue}} {{nodeId}}_result = clamp({{value}}, 0.0, 1.0);',
1296
- },
1297
- {
1298
- type: 'remap',
1299
- category: 'utility',
1300
- name: 'Remap',
1301
- description: 'Remap value from one range to another',
1302
- icon: 'repeat',
1303
- inputs: [
1304
- { id: 'value', name: 'Value', direction: 'input', dataType: 'float', defaultValue: 0.5 },
1305
- { id: 'inMin', name: 'In Min', direction: 'input', dataType: 'float', defaultValue: 0 },
1306
- { id: 'inMax', name: 'In Max', direction: 'input', dataType: 'float', defaultValue: 1 },
1307
- { id: 'outMin', name: 'Out Min', direction: 'input', dataType: 'float', defaultValue: 0 },
1308
- { id: 'outMax', name: 'Out Max', direction: 'input', dataType: 'float', defaultValue: 1 },
1309
- ],
1310
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'float' }],
1311
- },
1312
- {
1313
- type: 'smoothstep',
1314
- category: 'utility',
1315
- name: 'Smoothstep',
1316
- description: 'Smooth Hermite interpolation',
1317
- icon: 'activity',
1318
- inputs: [
1319
- { id: 'edge0', name: 'Edge 0', direction: 'input', dataType: 'float', defaultValue: 0 },
1320
- { id: 'edge1', name: 'Edge 1', direction: 'input', dataType: 'float', defaultValue: 1 },
1321
- { id: 'x', name: 'X', direction: 'input', dataType: 'float', defaultValue: 0.5 },
1322
- ],
1323
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'float' }],
1324
- shaderFunction: 'float {{nodeId}}_result = smoothstep({{edge0}}, {{edge1}}, {{x}});',
1325
- },
1326
- {
1327
- type: 'step',
1328
- category: 'utility',
1329
- name: 'Step',
1330
- description: 'Step function (threshold)',
1331
- icon: 'corner-down-right',
1332
- inputs: [
1333
- { id: 'edge', name: 'Edge', direction: 'input', dataType: 'any', defaultValue: 0.5 },
1334
- { id: 'x', name: 'X', direction: 'input', dataType: 'any', defaultValue: 0 },
1335
- ],
1336
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
1337
- shaderFunction: '{{typeEdge}} {{nodeId}}_result = step({{edge}}, {{x}});',
1338
- },
1339
- {
1340
- type: 'one_minus',
1341
- category: 'utility',
1342
- name: 'One Minus',
1343
- description: '1 - x',
1344
- icon: 'minus',
1345
- inputs: [{ id: 'value', name: 'Value', direction: 'input', dataType: 'any', defaultValue: 0 }],
1346
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
1347
- shaderFunction: '{{typeValue}} {{nodeId}}_result = 1.0 - {{value}};',
1348
- },
1349
- {
1350
- type: 'fresnel',
1351
- category: 'utility',
1352
- name: 'Fresnel',
1353
- description: 'Fresnel effect',
1354
- icon: 'circle',
1355
- inputs: [
1356
- { id: 'normal', name: 'Normal', direction: 'input', dataType: 'vec3' },
1357
- { id: 'viewDir', name: 'View Dir', direction: 'input', dataType: 'vec3' },
1358
- { id: 'power', name: 'Power', direction: 'input', dataType: 'float', defaultValue: 5 },
1359
- ],
1360
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'float' }],
1361
- previewable: true,
1362
- },
1213
+ {
1214
+ type: "lerp",
1215
+ category: "utility",
1216
+ name: "Lerp",
1217
+ description: "Linear interpolation",
1218
+ icon: "sliders",
1219
+ inputs: [
1220
+ { id: "a", name: "A", direction: "input", dataType: "any", defaultValue: 0 },
1221
+ { id: "b", name: "B", direction: "input", dataType: "any", defaultValue: 1 },
1222
+ {
1223
+ id: "t",
1224
+ name: "T",
1225
+ direction: "input",
1226
+ dataType: "float",
1227
+ defaultValue: 0.5,
1228
+ min: 0,
1229
+ max: 1
1230
+ }
1231
+ ],
1232
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
1233
+ shaderFunction: "{{typeA}} {{nodeId}}_result = mix({{a}}, {{b}}, {{t}});"
1234
+ },
1235
+ {
1236
+ type: "clamp",
1237
+ category: "utility",
1238
+ name: "Clamp",
1239
+ description: "Clamp value to range",
1240
+ icon: "minus-square",
1241
+ inputs: [
1242
+ { id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 },
1243
+ { id: "min", name: "Min", direction: "input", dataType: "any", defaultValue: 0 },
1244
+ { id: "max", name: "Max", direction: "input", dataType: "any", defaultValue: 1 }
1245
+ ],
1246
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
1247
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = clamp({{value}}, {{min}}, {{max}});"
1248
+ },
1249
+ {
1250
+ type: "saturate",
1251
+ category: "utility",
1252
+ name: "Saturate",
1253
+ description: "Clamp to 0-1",
1254
+ icon: "minimize-2",
1255
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
1256
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
1257
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = clamp({{value}}, 0.0, 1.0);"
1258
+ },
1259
+ {
1260
+ type: "remap",
1261
+ category: "utility",
1262
+ name: "Remap",
1263
+ description: "Remap value from one range to another",
1264
+ icon: "repeat",
1265
+ inputs: [
1266
+ { id: "value", name: "Value", direction: "input", dataType: "float", defaultValue: 0.5 },
1267
+ { id: "inMin", name: "In Min", direction: "input", dataType: "float", defaultValue: 0 },
1268
+ { id: "inMax", name: "In Max", direction: "input", dataType: "float", defaultValue: 1 },
1269
+ { id: "outMin", name: "Out Min", direction: "input", dataType: "float", defaultValue: 0 },
1270
+ { id: "outMax", name: "Out Max", direction: "input", dataType: "float", defaultValue: 1 }
1271
+ ],
1272
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "float" }]
1273
+ },
1274
+ {
1275
+ type: "smoothstep",
1276
+ category: "utility",
1277
+ name: "Smoothstep",
1278
+ description: "Smooth Hermite interpolation",
1279
+ icon: "activity",
1280
+ inputs: [
1281
+ { id: "edge0", name: "Edge 0", direction: "input", dataType: "float", defaultValue: 0 },
1282
+ { id: "edge1", name: "Edge 1", direction: "input", dataType: "float", defaultValue: 1 },
1283
+ { id: "x", name: "X", direction: "input", dataType: "float", defaultValue: 0.5 }
1284
+ ],
1285
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "float" }],
1286
+ shaderFunction: "float {{nodeId}}_result = smoothstep({{edge0}}, {{edge1}}, {{x}});"
1287
+ },
1288
+ {
1289
+ type: "step",
1290
+ category: "utility",
1291
+ name: "Step",
1292
+ description: "Step function (threshold)",
1293
+ icon: "corner-down-right",
1294
+ inputs: [
1295
+ { id: "edge", name: "Edge", direction: "input", dataType: "any", defaultValue: 0.5 },
1296
+ { id: "x", name: "X", direction: "input", dataType: "any", defaultValue: 0 }
1297
+ ],
1298
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
1299
+ shaderFunction: "{{typeEdge}} {{nodeId}}_result = step({{edge}}, {{x}});"
1300
+ },
1301
+ {
1302
+ type: "one_minus",
1303
+ category: "utility",
1304
+ name: "One Minus",
1305
+ description: "1 - x",
1306
+ icon: "minus",
1307
+ inputs: [{ id: "value", name: "Value", direction: "input", dataType: "any", defaultValue: 0 }],
1308
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }],
1309
+ shaderFunction: "{{typeValue}} {{nodeId}}_result = 1.0 - {{value}};"
1310
+ },
1311
+ {
1312
+ type: "fresnel",
1313
+ category: "utility",
1314
+ name: "Fresnel",
1315
+ description: "Fresnel effect",
1316
+ icon: "circle",
1317
+ inputs: [
1318
+ { id: "normal", name: "Normal", direction: "input", dataType: "vec3" },
1319
+ { id: "viewDir", name: "View Dir", direction: "input", dataType: "vec3" },
1320
+ { id: "power", name: "Power", direction: "input", dataType: "float", defaultValue: 5 }
1321
+ ],
1322
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "float" }],
1323
+ previewable: true
1324
+ }
1363
1325
  ];
1364
- /* ═══════════════════════════════════════════════════════════════════════════
1365
- LOGIC NODES
1366
- ═══════════════════════════════════════════════════════════════════════════ */
1367
1326
  const logicNodes = [
1368
- {
1369
- type: 'branch',
1370
- category: 'logic',
1371
- name: 'Branch',
1372
- description: 'Conditional branch (if/else)',
1373
- icon: 'git-branch',
1374
- inputs: [
1375
- {
1376
- id: 'condition',
1377
- name: 'Condition',
1378
- direction: 'input',
1379
- dataType: 'bool',
1380
- defaultValue: false,
1381
- },
1382
- { id: 'true', name: 'True', direction: 'input', dataType: 'any' },
1383
- { id: 'false', name: 'False', direction: 'input', dataType: 'any' },
1384
- ],
1385
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'any' }],
1386
- },
1387
- {
1388
- type: 'compare',
1389
- category: 'logic',
1390
- name: 'Compare',
1391
- description: 'Compare two values',
1392
- icon: 'git-pull-request',
1393
- inputs: [
1394
- { id: 'a', name: 'A', direction: 'input', dataType: 'float', defaultValue: 0 },
1395
- { id: 'b', name: 'B', direction: 'input', dataType: 'float', defaultValue: 0 },
1396
- ],
1397
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'bool' }],
1398
- properties: [
1399
- {
1400
- id: 'operator',
1401
- name: 'Operator',
1402
- type: 'enum',
1403
- default: 'equal',
1404
- options: [
1405
- { label: 'Equal', value: 'equal' },
1406
- { label: 'Not Equal', value: 'notEqual' },
1407
- { label: 'Greater', value: 'greater' },
1408
- { label: 'Less', value: 'less' },
1409
- { label: 'Greater Equal', value: 'greaterEqual' },
1410
- { label: 'Less Equal', value: 'lessEqual' },
1411
- ],
1412
- },
1413
- ],
1414
- },
1415
- {
1416
- type: 'and',
1417
- category: 'logic',
1418
- name: 'And',
1419
- description: 'Logical AND',
1420
- icon: 'check-square',
1421
- inputs: [
1422
- { id: 'a', name: 'A', direction: 'input', dataType: 'bool', defaultValue: false },
1423
- { id: 'b', name: 'B', direction: 'input', dataType: 'bool', defaultValue: false },
1424
- ],
1425
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'bool' }],
1426
- },
1427
- {
1428
- type: 'or',
1429
- category: 'logic',
1430
- name: 'Or',
1431
- description: 'Logical OR',
1432
- icon: 'check-square',
1433
- inputs: [
1434
- { id: 'a', name: 'A', direction: 'input', dataType: 'bool', defaultValue: false },
1435
- { id: 'b', name: 'B', direction: 'input', dataType: 'bool', defaultValue: false },
1436
- ],
1437
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'bool' }],
1438
- },
1439
- {
1440
- type: 'not',
1441
- category: 'logic',
1442
- name: 'Not',
1443
- description: 'Logical NOT',
1444
- icon: 'x-square',
1445
- inputs: [
1446
- { id: 'value', name: 'Value', direction: 'input', dataType: 'bool', defaultValue: false },
1447
- ],
1448
- outputs: [{ id: 'result', name: 'Result', direction: 'output', dataType: 'bool' }],
1449
- },
1327
+ {
1328
+ type: "branch",
1329
+ category: "logic",
1330
+ name: "Branch",
1331
+ description: "Conditional branch (if/else)",
1332
+ icon: "git-branch",
1333
+ inputs: [
1334
+ {
1335
+ id: "condition",
1336
+ name: "Condition",
1337
+ direction: "input",
1338
+ dataType: "bool",
1339
+ defaultValue: false
1340
+ },
1341
+ { id: "true", name: "True", direction: "input", dataType: "any" },
1342
+ { id: "false", name: "False", direction: "input", dataType: "any" }
1343
+ ],
1344
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "any" }]
1345
+ },
1346
+ {
1347
+ type: "compare",
1348
+ category: "logic",
1349
+ name: "Compare",
1350
+ description: "Compare two values",
1351
+ icon: "git-pull-request",
1352
+ inputs: [
1353
+ { id: "a", name: "A", direction: "input", dataType: "float", defaultValue: 0 },
1354
+ { id: "b", name: "B", direction: "input", dataType: "float", defaultValue: 0 }
1355
+ ],
1356
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "bool" }],
1357
+ properties: [
1358
+ {
1359
+ id: "operator",
1360
+ name: "Operator",
1361
+ type: "enum",
1362
+ default: "equal",
1363
+ options: [
1364
+ { label: "Equal", value: "equal" },
1365
+ { label: "Not Equal", value: "notEqual" },
1366
+ { label: "Greater", value: "greater" },
1367
+ { label: "Less", value: "less" },
1368
+ { label: "Greater Equal", value: "greaterEqual" },
1369
+ { label: "Less Equal", value: "lessEqual" }
1370
+ ]
1371
+ }
1372
+ ]
1373
+ },
1374
+ {
1375
+ type: "and",
1376
+ category: "logic",
1377
+ name: "And",
1378
+ description: "Logical AND",
1379
+ icon: "check-square",
1380
+ inputs: [
1381
+ { id: "a", name: "A", direction: "input", dataType: "bool", defaultValue: false },
1382
+ { id: "b", name: "B", direction: "input", dataType: "bool", defaultValue: false }
1383
+ ],
1384
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "bool" }]
1385
+ },
1386
+ {
1387
+ type: "or",
1388
+ category: "logic",
1389
+ name: "Or",
1390
+ description: "Logical OR",
1391
+ icon: "check-square",
1392
+ inputs: [
1393
+ { id: "a", name: "A", direction: "input", dataType: "bool", defaultValue: false },
1394
+ { id: "b", name: "B", direction: "input", dataType: "bool", defaultValue: false }
1395
+ ],
1396
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "bool" }]
1397
+ },
1398
+ {
1399
+ type: "not",
1400
+ category: "logic",
1401
+ name: "Not",
1402
+ description: "Logical NOT",
1403
+ icon: "x-square",
1404
+ inputs: [
1405
+ { id: "value", name: "Value", direction: "input", dataType: "bool", defaultValue: false }
1406
+ ],
1407
+ outputs: [{ id: "result", name: "Result", direction: "output", dataType: "bool" }]
1408
+ }
1450
1409
  ];
1451
- /* ═══════════════════════════════════════════════════════════════════════════
1452
- EXPORTS
1453
- ═══════════════════════════════════════════════════════════════════════════ */
1454
- /** All built-in node definitions */
1455
- const MATERIAL_NODE_DEFINITIONS =
1456
- /* @__PURE__ */ (function () {
1457
- return [
1458
- ...inputNodes,
1459
- ...outputNodes,
1460
- ...mathNodes,
1461
- ...vectorNodes,
1462
- ...colorNodes,
1463
- ...textureNodes,
1464
- ...proceduralNodes,
1465
- ...utilityNodes,
1466
- ...logicNodes,
1467
- ];
1410
+ const MATERIAL_NODE_DEFINITIONS = /* @__PURE__ */ (function() {
1411
+ return [
1412
+ ...inputNodes,
1413
+ ...outputNodes,
1414
+ ...mathNodes,
1415
+ ...vectorNodes,
1416
+ ...colorNodes,
1417
+ ...textureNodes,
1418
+ ...proceduralNodes,
1419
+ ...utilityNodes,
1420
+ ...logicNodes
1421
+ ];
1468
1422
  })();
1469
- /** Node definitions map by type */
1470
- const MATERIAL_NODE_MAP = new Map(MATERIAL_NODE_DEFINITIONS.map((def) => [def.type, def]));
1471
- /** Get nodes by category */
1423
+ const MATERIAL_NODE_MAP = new Map(
1424
+ MATERIAL_NODE_DEFINITIONS.map((def) => [def.type, def])
1425
+ );
1472
1426
  function getNodesByCategory(category) {
1473
- return MATERIAL_NODE_DEFINITIONS.filter((def) => def.category === category);
1427
+ return MATERIAL_NODE_DEFINITIONS.filter((def) => def.category === category);
1474
1428
  }
1475
- /** Search nodes by name/description */
1476
1429
  function searchNodes(query) {
1477
- const lowerQuery = query.toLowerCase();
1478
- return MATERIAL_NODE_DEFINITIONS.filter((def) => def.name.toLowerCase().includes(lowerQuery) ||
1479
- def.description.toLowerCase().includes(lowerQuery) ||
1480
- def.type.toLowerCase().includes(lowerQuery));
1430
+ const lowerQuery = query.toLowerCase();
1431
+ return MATERIAL_NODE_DEFINITIONS.filter(
1432
+ (def) => def.name.toLowerCase().includes(lowerQuery) || def.description.toLowerCase().includes(lowerQuery) || def.type.toLowerCase().includes(lowerQuery)
1433
+ );
1481
1434
  }
1482
-
1483
1435
  exports.MATERIAL_NODE_DEFINITIONS = MATERIAL_NODE_DEFINITIONS;
1484
1436
  exports.MATERIAL_NODE_MAP = MATERIAL_NODE_MAP;
1485
1437
  exports.getNodesByCategory = getNodesByCategory;