OverviewFilesCommitsIssuesDocsReleasesPeers

proc-nodes commits / 4d65e35

docs: the README claimed 59 nodes, its own catalog listed 62, there are 122
Three different node counts in one file, none of them right. src/nodes/*.h defines 122 classes, every one deriving directly from ProcNode (no abstract intermediates inflating the count), and _create_node_by_type() in graph_importer.cpp can build 121 of them by name. The README's hand-maintained catalog documented roughly half the system. Rather than transcribe 122 nodes into a README that was already too long at 305 lines, the catalog is now a 14-row category table with counts derived from the factory, pointing at docs/nodes.md. README is 191 lines. docs/nodes.md opened with "Every node type documented". It documents 63. Both files now say which number is which and name the factory as the authority, so the next person measures instead of trusting. "Extending: Adding a New Node Type" moved to docs/extending.md, and the Documentation section now lists all seven docs -- four of them (spec-graph-composition, glsl-emitter-design, cpu-twin-design, output-terminals-design, performance-audit-vs-blender) were unlinked from the README entirely. License said "See the project license file for details". There is no license file; it now says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4d65e35cedca2fe89d72ff4a437f249853df9a25
by plankatron <fleeky@gmail.com> · 2026-09-10T15:09:26.000Z

Changed files (3) +80 -139

README.md +24 -138
……@@ -4,7 +4,7 @@ A procedural geometry node graph system for Godot 4, implemented as a GDExtensio
44
55## Features
66
7- **59 node types** across 11 categories (mesh primitives, math, geometry ops, mesh ops, curves, points, instances, attributes, noise, zones, utility)
7- **122 node types** across 14 categories (mesh primitives, math, geometry ops, mesh ops, curves, points, instances, attributes, noise, volume, zones, utility)
88- **GPU compute pipeline** using Vulkan compute shaders via Godot's RenderingDevice API, with automatic CPU fallback
99- **Zone system** with Repeat, ForEach, and Simulation zones for iterative and per-element operations
1010- **Graph serialization** to Godot `.tres` resources via custom `_get_property_list`/`_set`/`_get`, with delta-only default storage
……@@ -65,91 +65,24 @@ Automatic type conversions are applied when reading inputs (e.g., Float to Vecto
6565
6666## Node Catalog
6767
68### Input (4 nodes)
69- **Group Input** -- Configurable graph entry point (Geometry output)
70- **Group Output** -- Configurable graph exit point (Geometry passthrough)
71- **Value** -- Outputs a single float constant (GPU)
72- **Vector** -- Outputs a Vector3 constant (GPU)
73
74### Math (4 nodes)
75- **Math** -- 21 scalar operations: Add, Subtract, Multiply, Divide, Power, Sqrt, Abs, Min, Max, Modulo, Sin, Cos, Tan, Atan2, Floor, Ceil, Round, Fract, Clamp, Lerp, Smoothstep, Negate (GPU + GLSL)
76- **Vector Math** -- 11 vector operations: Add, Subtract, Multiply, Divide, Cross, Dot, Normalize, Length, Distance, Scale, Negate (GPU + GLSL)
77- **Combine XYZ** -- 3 floats to Vector3 (GPU)
78- **Separate XYZ** -- Vector3 to 3 floats (GPU)
79
80### Mesh Primitives (7 nodes)
81- **Mesh Cube** -- Box with per-face normals and UVs (Size: Vector3)
82- **Mesh Grid** -- Subdivided XZ plane (Size X, Size Y, Vertices X, Vertices Y) (GPU)
83- **Mesh Circle** -- Polygon or edge ring (Vertices, Radius, Fill)
84- **Mesh Cylinder** -- Cylinder with optional caps (Vertices, Radius, Depth, Fill Caps)
85- **Mesh UV Sphere** -- Latitude/longitude sphere (Segments, Rings, Radius)
86- **Mesh Ico Sphere** -- Subdivided icosahedron (Radius, Subdivisions 0-6)
87- **Mesh Line** -- Point cloud along a line (Count, Start, End) (GPU)
88
89### Geometry Operations (7 nodes)
90- **Transform Geometry** -- Full TRS transform on all components (Translation, Rotation, Scale) (GPU flag, CPU execution)
91- **Set Position** -- Offset all positions by a vector (GPU compute)
92- **Join Geometry** -- Merge two geometries into one
93- **Delete Geometry** -- Remove geometry based on boolean selection
94- **Merge by Distance** -- Weld nearby vertices (Distance threshold)
95- **Bounding Box** -- Compute AABB (outputs Min, Max, Center, Size)
96- **Separate Components** -- Split into Mesh, Curves, Point Cloud, Instances
97
98### Mesh Operations (7 nodes)
99- **Flip Faces** -- Reverse triangle winding and negate normals
100- **Set Shade Smooth** -- Toggle smooth (area-weighted vertex normals) or flat (per-face normals with vertex splitting)
101- **Subdivide Mesh** -- Loop-style edge midpoint subdivision (Level 0-5)
102- **Scale Elements** -- Scale vertices around a center point
103- **Extrude Mesh** -- Duplicate and offset vertices along normals
104- **Merge by Distance** -- Weld vertices within distance threshold
105- **Dual Mesh** -- Topological dual (faces become vertices, vertices become faces)
106
107### Curve Primitives (3 nodes)
108- **Curve Circle** -- Closed circular polyline (Radius, Resolution)
109- **Curve Line** -- 2-point polyline (Start, End)
110- **Bezier Segment** -- 4-point cubic bezier (Start, Handle 1, Handle 2, End)
111
112### Curve Operations (5 nodes)
113- **Curve to Mesh** -- Sweep profile along path with Frenet framing, cap fill, and closed path support (Path, Profile, Resolution, Closed, Fill Caps)
114- **Curve to Points** -- Sample points along curve as point cloud (Count)
115- **Resample Curve** -- Evenly redistribute control points (Count)
116- **Set Curve Radius** -- Set uniform radius for all points (GPU)
117- **Trim Curve** -- Extract sub-range by parameter (Start 0-1, End 0-1)
118
119### Point Operations (3 nodes)
120- **Points** -- Create N points at origin (Count)
121- **Points to Vertices** -- Convert point cloud to mesh vertices
122- **Distribute Points on Faces** -- Area-weighted random scatter on mesh triangles (Count, Seed)
123
124### Instance Operations (5 nodes)
125- **Instance on Points** -- Place geometry at each point position (Points, Instance, Scale)
126- **Rotate Instances** -- Apply Euler rotation to all instance transforms (GPU)
127- **Scale Instances** -- Scale all instance transforms (GPU)
128- **Translate Instances** -- Offset all instance origins (GPU)
129- **Realize Instances** -- Flatten instance hierarchy into a single merged mesh
130
131### Attribute Operations (7 nodes)
132- **Position** -- Read mesh centroid position (GPU)
133- **Normal** -- Read average mesh normal (GPU)
134- **Index** -- Output element index (GPU)
135- **Store Named Attribute** -- Write a value to a named attribute (name, domain, type)
136- **Named Attribute** -- Read a named attribute value
137- **Capture Attribute** -- Snapshot a scalar as "captured" attribute on all points
138- **Remove Named Attribute** -- Delete a named attribute from all domains
139- **Domain Size** -- Output element counts (Point, Face, Corner, Curve, Instance)
140
141### Noise (2 nodes)
142- **Noise Texture** -- 3D simplex noise with fBM (Vector, Scale, Detail) outputs Value + Color (GPU + GLSL)
143- **Displace** -- Displace mesh vertices along normals using fBM noise (Strength, Scale, Detail, Roughness) (GPU compute)
144
145### Utility (2 nodes)
146- **Switch** -- Select between two geometry inputs based on boolean
147- **Random Value** -- Hash-based pseudo-random float (Min, Max, Seed) (GPU)
148
149### Zone Nodes (6 nodes)
150- **Repeat Zone Input/Output** -- Loop body N times, passing geometry between iterations
151- **ForEach Zone Input/Output** -- Execute body once per mesh vertex, collecting results
152- **Simulation Zone Input/Output** -- Frame-persistent state with delta time, cached across evaluations
68122 node classes, all deriving directly from `ProcNode`; 121 are creatable by name through
69`GraphImporter`'s factory.
70
71| category | nodes | | category | nodes |
72|---|---:|---|---|---:|
73| Utility | 20 | | Mesh Primitives | 7 |
74| Noise | 13 | | Zones | 6 |
75| Math | 12 | | Volume | 6 |
76| Input | 12 | | Instances | 5 |
77| Geometry Operations | 11 | | Attributes | 5 |
78| Mesh Operations | 11 | | Points | 3 |
79| Curves | 8 | | Selection/Utility | 2 |
80
81**[Every node with its inputs, outputs, defaults and GPU support → `docs/nodes.md`](docs/nodes.md)**
82— though note that file currently covers 63 of the 122.
83
84The authority for what exists is `_create_node_by_type()` in
85`src/graph/graph_importer.cpp`; the class definitions are in `src/nodes/*.h`.
15386
15487## GPU Compute Pipeline
15588
……@@ -246,60 +179,13 @@ scons target=template_release -j$(nproc)
246179
247180Output goes to `bin/<platform>/`. Register the GDExtension in your project's `.gdextension` file.
248181
249## Extending: Adding a New Node Type
250
2511. **Declare** the class in the appropriate `src/nodes/<category>_nodes.h`:
252
253```cpp
254class MyCustomNode : public ProcNode {
255 GDCLASS(MyCustomNode, ProcNode);
256protected:
257 static void _bind_methods();
258public:
259 StringName get_node_type() const override { return "MyCustom"; }
260 String get_node_title() const override { return "My Custom Node"; }
261 String get_node_category() const override { return "Custom"; }
262 void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
263 MyCustomNode();
264};
265```
266
2672. **Implement** the constructor (define input/output sockets) and `execute()`:
268
269```cpp
270MyCustomNode::MyCustomNode() {
271 input_defs.push_back({ "Geometry", SocketType::Geometry, Variant() });
272 input_defs.push_back({ "Amount", SocketType::Float, 1.0f });
273 output_defs.push_back({ "Geometry", SocketType::Geometry, Variant() });
274}
275
276void MyCustomNode::execute(ProcEvalContext &p_ctx, int p_node_idx) {
277 Ref<ProcGeometry> geo = p_ctx.read_geometry(p_node_idx, 0);
278 float amount = p_ctx.read_float(p_node_idx, 1);
279 // ... process geometry ...
280 p_ctx.write_geometry(p_node_idx, 0, geo);
281}
282```
283
2843. **Register** in `src/register_types.cpp`:
285
286```cpp
287GDREGISTER_CLASS(MyCustomNode);
288```
289
2904. **Add to importer** factory in `src/graph/graph_importer.cpp`:
291
292```cpp
293if (p_type == "MyCustom") return Ref<ProcNode>(memnew(MyCustomNode));
294```
295
2965. For **GPU support**, override `supports_gpu()` to return `true` and implement `compile_glsl()` returning a GLSL snippet that operates on `pos` and `normal` variables.
297
298182## Documentation
299183
300- [API Reference](docs/api.md) -- Complete API for ProcNodeGraph, ProcNode, ProcEvalContext, serialization format, GPU compilation
301- [Node Reference](docs/nodes.md) -- Every node type with inputs, outputs, defaults, and behavior
184- [API Reference](docs/api.md) — ProcNodeGraph, ProcNode, ProcEvalContext, serialization format, GPU compilation
185- [Node Reference](docs/nodes.md) — per-node inputs, outputs, defaults, behaviour and GPU support (63 of 122 nodes so far)
186- [Extending](docs/extending.md) — adding a new node type
187- [Graph composition spec](docs/spec-graph-composition.md) · [GLSL emitter](docs/glsl-emitter-design.md) · [CPU twin](docs/cpu-twin-design.md) · [Output terminals](docs/output-terminals-design.md) · [Performance vs Blender](docs/performance-audit-vs-blender.md)
302188
303189## License
304190
305GDExtension for Godot 4. See the project license file for details.
191Not yet declared — there is no LICENSE file in this repo.
docs/extending.md +51 -0
……@@ -0,0 +1,51 @@
1# Extending: adding a new node type
2
31. **Declare** the class in the appropriate `src/nodes/<category>_nodes.h`:
4
5```cpp
6class MyCustomNode : public ProcNode {
7 GDCLASS(MyCustomNode, ProcNode);
8protected:
9 static void _bind_methods();
10public:
11 StringName get_node_type() const override { return "MyCustom"; }
12 String get_node_title() const override { return "My Custom Node"; }
13 String get_node_category() const override { return "Custom"; }
14 void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
15 MyCustomNode();
16};
17```
18
192. **Implement** the constructor (define input/output sockets) and `execute()`:
20
21```cpp
22MyCustomNode::MyCustomNode() {
23 input_defs.push_back({ "Geometry", SocketType::Geometry, Variant() });
24 input_defs.push_back({ "Amount", SocketType::Float, 1.0f });
25 output_defs.push_back({ "Geometry", SocketType::Geometry, Variant() });
26}
27
28void MyCustomNode::execute(ProcEvalContext &p_ctx, int p_node_idx) {
29 Ref<ProcGeometry> geo = p_ctx.read_geometry(p_node_idx, 0);
30 float amount = p_ctx.read_float(p_node_idx, 1);
31 // ... process geometry ...
32 p_ctx.write_geometry(p_node_idx, 0, geo);
33}
34```
35
363. **Register** in `src/register_types.cpp`:
37
38```cpp
39GDREGISTER_CLASS(MyCustomNode);
40```
41
424. **Add to importer** factory in `src/graph/graph_importer.cpp`:
43
44```cpp
45if (p_type == "MyCustom") return Ref<ProcNode>(memnew(MyCustomNode));
46```
47
485. For **GPU support**, override `supports_gpu()` to return `true` and implement `compile_glsl()` returning a GLSL snippet that operates on `pos` and `normal` variables.
49
50
51See also [API Reference](api.md) and [Node Reference](nodes.md).
docs/nodes.md +5 -1
……@@ -1,6 +1,10 @@
11# Proc-Nodes: Node Reference
22
3Every node type documented with inputs, outputs, default values, behavior, and GPU support status.
3Per-node inputs, outputs, default values, behaviour and GPU support status.
4
5⚠ This file covers 63 of the 122 node classes that exist. The authority for what exists is
6`_create_node_by_type()` in `src/graph/graph_importer.cpp` and the class definitions in
7`src/nodes/*.h`.
48
59---
610