@nice2dev/ui-3d 1.3.14 → 1.3.16

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