Every points wire carries a small table of per-point data — position, scale, rotation, group — and can carry your own named channels (“attributes”) on top, like Blender’s geometry attributes. The Spreadsheet panel shows that table live for whatever node you select.
Click any panel’s editor-kind chip (top-left corner) and pick Spreadsheet. The panel follows your selection: click a node in the node editor and the table shows the data flowing out of it — one row per point, one column per channel. It updates live while the graph plays.
The table works even on a node whose branch isn’t connected to anything — the panel quietly forces that node to evaluate, exactly like the hover peek on an output socket.
Every points value has a fixed set of built-in channels. Some are always present, the rest exist only when a node upstream produced them:
| Column | Meaning |
|---|---|
index | The point’s position in the list — its identity. Not stored anywhere; it simply is the row number. |
x, y (and z for 3D) | Position. 2D points are normalized canvas space; 3D points are world-space meters. |
scale x, scale y | Per-point scale, consumed by Copy to Points and friends. |
rotation | Per-point rotation (shown in degrees). |
group | An identity tag assigned by Collect and friends — which source a point came from. Group-aware nodes (Group Pick, Copy to Points’ variant picking) key off it. |
nx, ny, nz | Surface normals on 3D scattered points. |
On top of the built-ins, points can carry any number of named channels you define — a weight per point, an age, a color. A channel has a name, a type (float, vec2–vec4, or color), and one value per point. Once written, it travels down the wire through every point node — transforms, filters, merges, simulations — and shows up as an extra column in the Spreadsheet. Grid stamps ix / iy (column and row); Points to Spline’s grid layout uses those to walk rows and columns instead of chaining in index order, so a warped lattice stays a lattice.
name.x, name.y, …).x, y, index, rotation, scale, group, …) — those are reserved and writes to them are ignored.agechannel: seconds since each point joined that node’s state. Accumulator in spline mode stamps the same name on each piled subpath’s attrs. Map Attribute can drive scale from it; Filter Points can drop old points. The node owns the name — an incoming age is overwritten.The Set Named Attribute node (point category) is the direct way to author a channel. Wire points (or a spline — see below) through it, type the name right on the node body, pick a type, and choose where the values come from:
Sample Texture at Points can write the sampled value onto a named channel instead of scale or rotation: set Target to Named attribute and Name to e.g. lum, then read it with attr("lum") or Copy to Points. That keeps luminance data off the geometry channels.
Stagger(point category) is per-point timing as a channel — Cavalry’s stagger or an After Effects index-offset expression, without the code. Every point gets its own start time from its place in an order, and the node writes a 0→1 phase channel: 0 before the point starts, a linear ramp over Duration, 1 after.
x, y, group). Equal values start together, so ordering a grid by y starts a whole row at once.Then read phasedownstream: Map Attribute drives scale, rotation, or position from it (its curve is the per-point easing), Filter Points can hide points that haven’t started, and Copy to Points can use it as an opacity or variant pick. Turn on Write t0 & active for two more channels: phase_t0 (each point’s start) and phase_active (1 only while a point is mid-ramp).
Attribute Readpulls one point’s column off the wire as a number you can drive anything with — a Transform, a Math input, a Copy-to-Points scale. Wire points in, type the name (a named channel, a dotted component like color.y, or a built-in: index, x, y, position, scale, rotation, group), pick Type (scalar or vec2), and Index selects the point. A missing channel reads as 0; Index clamps to the live count.
position and scale are the two-axis built-ins; a float channel pads as [value, 0].attr("name") or Map Attribute.Point Expression can read and write channels from code, which makes attributes programmable:
attr("weight")reads the current point’s weight (0 if absent). attr("color", 1) reads a specific component of a multi-component channel.setattr("age", t) writes a float channel at the current point, creating it if needed.For example, cull by a channel written upstream: keep = attr("weight") > 0.5. Partition points into subpaths with groupIndex = floor(index / k)— Points to Spline chain, Select by Index, and Copy to Points all key off that tag. For a uniform window (pairs, triples, …) Points to Spline’s stride layout does the same split without the expression. Or bake a computed value for downstream inspection: setattr("dist", hypot(px - 0.5, py - 0.5)).
setattr in the same expression isn’t visible to attr, so results never depend on the order points are processed in.Wire a velocity field (Perlin Noise curl, Spline Flow Field, Vector Field) into the field input and sample it from the expression: fieldX() / fieldY() read the encoded vector at the current point, fieldAt() returns [vx, vy], and fieldX(u, v) samples at any UV. Unwired, they read 0. A one-shot warp is x = px + fieldX() * ch("amount", 0.05); y = py + fieldY() * ch("amount", 0.05).
ch() is one of six channel kinds — tunables declared in the code that Sync turns into real controls on the node (and, for the wireable kinds, input sockets). ch("k", 0.5, 0, 1) is a slider, toggle("on", true) an on/off pill, pick("mode", "a", "b") a two- or three-way pill (a dropdown past three options), color("tint", "#ff8800") a swatch returning [r, g, b, a], ramp("ink", t, "#000000", "#ffffff") a gradient editor sampled at t, and curve("falloff", x, 1, 0) a float-curve editor sampled at x. The literals after the name are the seed (hex lists space ramp stops evenly, number lists space curve points); the code runs with those seeds until you Sync, and Sync never overwrites a control you have already tuned. GLSL Expression declares the same channels as one-line // comments and reads them as uniforms — a ramp becomes vec4 ink(float t), a curve float falloff(float x).
Point Expression also runs on spline anchors: set its Target to “spline anchors” and the same code runs once per anchor — read px/py, the handle offsets inx0/iny0/outx0/outy0, width0, and subpath; write x, y, inx, iny, outx, outy, width, and keep. attr()reads anchor channels (falling back to the subpath’s) and setattr() writes them.
Three companion nodes operate on channels directly — on points, or on spline anchors when Target is set. Everywhere a node asks for an attribute name, the field offers a dropdown of the channels actually present on the wired input — pick one, or type a new name freely.
step(edge, x), inclusive on the edge) and a Remap that fits a range onto another. Writes in place, or to a new name via the Output field. Target can be points or spline anchors.index, x, y, scale.x, rotation, group) through In/Out ranges, shape it with a 0–1 curve, and apply it as a scale multiplier, rotation offset, or position offset.Channels also drive three existing nodes: Filter Points has an attribute mode (keep points whose channel clears a threshold) and can write the predicate as a 0/1 flag instead of dropping points — Index mode also selects first, last, first and last, a single index, or a range; Copy to Pointsreads channels three ways — a Tint attribute (each copy’s color, image mode), an Opacity attribute (each copy’s alpha, image mode), and an “attribute” variant pick (which variant lands on each point, every mode — the channel’s 0–1 value spreads across the variant set exactly like image luminance); and Point Labels / Points to Text templates accept {attr:name} alongside {x} and friends. Points to Stringjoins a column (built-in or named) into one caption — comma-separated, one per line, or a grid — and wires into a Text node’s text.
Splines carry named channels too, on two domains: per anchor (like the built-in width profile) and per subpath(like the group tag). Set Named Attribute’s Target parameter picks the domain; the input socket retypes to spline automatically. Spline channels survive the editing operations that copy anchors — trims, joins, transforms — and show in the Spreadsheet’s spline table (subpath channels repeat across their anchors, labeled “(subpath)”). Points to Spline writes each point’s channels onto the matching anchors; Spline to Points (and Points on Path, which interpolates along the curve) bring them back onto points. Rope Simulator bakes them onto particles at reset so they stay glued as the string moves. Rebuilds that rewrite anchors — Resample, Offset, Set Spline Type, Trim Path, Round Corners — interpolate or copy those channels so they survive the new topology.
Attribute Math, Blur, and Transfer take the same Target switch as Set Named Attribute (points or spline anchors). On a spline, Blur in Index domain runs per subpath; Transfer flattens anchors to authored xy and rebinds by proximity.
Stroke and Rasterize Spline can color along a path two ways: Driver is one value per subpath (a named subpath channel, or the producer-authored driver scalar); Attribute ramps along the curve from an interpolated named anchor channel (component 0 — a subpath-only channel acts as a constant). Missing samples read as 0, not as progress. Fill ramps stay per-subpath.
You shouldn’t have to think about this — channels just follow the points — but the rules are simple and worth knowing:
age after that (points on the channel, piled spline subpaths on attrs.age). Rope Simulator is the exception: it resamples the input, so named channels are baked onto particles at reset (the same rest-pose sample as its material maps) and travel with the string.setattr writes float channels only — use Set Named Attribute for vectors and colors.points3d values, but the attribute nodes accept 2D points only, and 3D instancing doesn’t read channels yet (Instance Color’s attribute source is planned).