Point Attributes
Sets per-element attributes on points, either from a spatial field or a uniform value. Attributes are read by downstream Draw and Clone nodes.
Category: Point Ops Menu path: Point Ops > Point Attributes
Ports
| Port | Type | Direction | Description |
|---|---|---|---|
points_in | points | input | Source points |
field_in | scalarField | input | Spatial field to sample at each point position (also accepts vectorField and colorField) |
out | points | output | Points with attributes set |
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
target | enum | Scale | Which attribute to write: Scale, Scale X/Y, Opacity, Rotation, Color, Index, or Custom |
source | enum | Field | Where the value comes from: Field / Value (literal), or a ramp source — Index, Age, Random, Speed — that samples the curve / colour ramp below. See Sources |
value | scalar | 1.0 | Uniform value (used when source=Value, or as fallback when source=Field with no field connected) |
valueXY | vec2 | 1, 1 | Per-axis uniform value for the Scale X/Y target (linked pair; unlink for independent X/Y) |
colorValue | color | white | Color value (used when source=Value, target=Color) |
customAttribute | string | custom | Attribute key name (used when target is Custom) |
indexCurve | curveRamp | 0→1 linear | Ramp sources + scalar target. The curve is sampled at t (see Sources) and its value is written. Shown as the Curve widget in the Output section |
indexColorRamp | gradientRamp | black→white | Ramp sources + target=Color. The gradient is sampled at t. Shown as the Color Ramp widget in the Output section |
indexCycle | scalar, keyframeable | 0 | Offsets t before the repeat mode — animate it to scroll the ramp along the points (or along each particle's life) |
indexRepeatMode | enum | Clamp | What happens outside 0–1 after cycling: Clamp, Repeat, Mirror |
randomSeed | scalar | 0 | Source=Random. Changes which fixed random value each element gets |
ageRange | scalar | 60 | Source=Age, in frames. Only applies to points without life (or with life ≤ 0): t = age / ageRange. Emitted particles carry their own life and ignore it. Properties shows a live hint under the row — input age: 0 → 61 read from the connected points, or unused — input points carry Life (70) when they have one |
speedRange | scalar | 500 | Source=Speed, in px per second. t = speed / speedRange, so a particle moving at this speed reads the end of the ramp. Properties shows the connected points' actual speed under the row (input speed: 12 → 540 px/s — velocity length × comp fps) so the range can be sized against it |
outputMin | scalar | 0 | Lerp the [0,1] ramp / field output into [outputMin, outputMax]. Hidden for Color and Rotation targets and for source=Value. Default 0/1 is identity |
outputMax | scalar | 1 | See outputMin |
How It Works
PointAttributes evaluates per point. For each point in the input it computes a value according to source, optionally remaps it through Output Min / Max, and writes it under the target's attribute key.
Sources
| Source | Per-point value | Typical use |
|---|---|---|
| Field | field_in sampled at the point's position (origin-centred comp pixels); falls back to value / colorValue when nothing is connected | Spatial variation — bigger near the centre, coloured by a gradient |
| Value | The literal value / valueXY / colorValue | A uniform base scale, opacity or colour |
| Index | Curve / ramp sampled at t = normalized index (0 for the first point, 1 for the last) | Progressive per-copy animation (the AE Repeater pattern) |
| Age | Curve / ramp sampled at t = age / life; immortal points use age / ageRange | Over-life ramps on particles: size, opacity, colour that change from birth to death |
| Random | Curve / ramp sampled at t = a hash of the point's stable id and randomSeed | Per-element randomness that stays fixed for the element's whole life, wherever it moves |
| Speed | Curve / ramp sampled at t = ` | velocity |
age, life and velocity are the standard particle attributes written by Point Solver (Track Points writes velocity and age too). A point without them reads age 0 and speed 0 — the start of the ramp. Random hashes the point's id, not its position or list index, so it is stable across motion and across neighbours dying; Grid, Point Scatter and every other producer give their points ids, so Random works on any stream, not only particles. indexCycle and indexRepeatMode apply to all four ramp sources.
The result is stored as a named attribute on each point:
| Target | Attribute key | Read by |
|---|---|---|
| Scale | scale | DrawPoints (radius multiplier), CloneToPoints (uniform scale) |
| Scale X/Y | scale (per-axis) | Same key, stored per-axis: DrawPoints renders ellipses, CloneToPoints stretches instances. A vector field drives per-axis magnitudes; a scalar field or the uniform valueXY broadcasts/sets both axes |
| Opacity | opacity | DrawPoints (alpha), CloneToPoints (path-level opacity) |
| Rotation | rotation | CloneToPoints (instance rotation in radians), PointDeform (Normal/Tangent local frame) |
| Color | color | DrawPoints (RGBA override), CloneToPoints (path-level color) |
| Index | index | DrawInstances time offsets (default offsetAttribute) and ConnectPoints Sequential traversal order (default orderBy), so a field-driven Index re-routes the polyline — e.g. connect points in SDF-distance order. Not variant selection: index is an order, renumbered 0…n by every membership change, so CloneToPoints / DrawInstances "Point Index" read shapeIndex instead — write that with the Custom target (attribute name shapeIndex). Values there are floored and wrapped modulo the variant count, so remap via outputMin/outputMax to span 0..N |
| Custom | user-defined | Available for custom pipelines. One name other nodes read by convention: shapeIndex (see the Index row above), which DrawInstances reads in Point Index mode |
Field type handling:
- ScalarField for rotation uses
v * TAUmapping: [0, 1] maps to [0, 2pi]. - VectorField for rotation uses
eval_bipolar()[-1, 1] for fullatan2range [-pi, pi]. - ColorField writes RGBA directly per point.
Custom target output type: The Custom target follows the field type of the connected input:
- ColorField -> Vec4 (RGBA stored per point)
- VectorField (alone) -> Vec2 (bipolar [-1,1] vectors stored per point)
- ScalarField or uniform value -> Scalar
This lets Custom carry any of the four attribute array types (Scalar, Vec2, Vec4) — whatever matches the field semantics you wired in.
Usage Examples
Basic: Spatially varying size
Grid -> PointAttributes (target: Scale, field: Noise.scalarField) -> DrawPoints. Points near noise peaks are larger, near troughs smaller.
Per-point color from a gradient
Grid -> PointAttributes (target: Color, field: Gradient.colorField) -> DrawPoints. Each point picks up the gradient color at its position.
Rotation for instancing
Grid -> PointAttributes (target: Rotation, field: Noise.scalarField) -> CloneToPoints (shape: small arrow). Each instance rotates based on the noise field, creating a flow visualization.
Curve-aligned rotation
For rotation that follows a curve's tangent (e.g. branches along a stem), use ShapeAttributes with target: Rotation, source: Tangent upstream of ShapeToPoints → CloneToPoints. The Tangent mode on ShapeAttributes computes the angle directly from the shape's geometry, which is cleaner than wiring up a VectorField for the same result.
Size over life (particles)
PointEmitter -> PointSolver -> PointAttributes (target: Scale, source: Age, Curve: 1 -> 0) -> DrawPoints. Every particle is born full size and shrinks to nothing exactly as it dies, whatever its individual life. Chain a second node with target: Opacity for a fade-out, or target: Color with a ramp (white -> orange -> transparent) for cooling embers.
Per-particle random size
PointSolver -> PointAttributes (target: Scale, source: Random, Output Min/Max: 0.5 / 2) -> DrawPoints. Each particle picks a size once, at birth, and keeps it — unlike a Random field, which would re-roll as the particle moves through the grid of cells.
Colour by speed
PointSolver -> PointAttributes (target: Color, source: Speed, speedRange: 800, Color Ramp: blue -> white) -> DrawPoints. Fast particles glow white, slow ones stay blue.
Tips
- You can chain multiple PointAttributes nodes to set different attributes (e.g., one for Scale, another for Color)
- When no field is connected, all points get the same uniform
value-- useful for setting a base scale or opacity - The
field_inport accepts scalarField, vectorField, and colorField despite showing as scalarField type - Missing attributes in downstream nodes use backward-compatible defaults (scale=1, opacity=1, color=white)
- Properties: the literal value rows show for Field / Value; the Curve or Color Ramp (whichever the target needs) plus Cycle / Repeat show for the four ramp sources; Age Range, Seed and Speed Range appear only with their own source
- Age Range and Speed Range carry a live hint of what the input points actually have — their age span in frames, or their speed range in px/s — read from the same capture the Details panel shows. Age Range's hint says
unusedwhen the points carry Life, because Age is already normalised by each particle's own life. The hint is blank until the upstream node has been inspected (selecting this node captures one hop upstream) - For "random but different every frame" use a Random field with animated
evolution; for "random once per element" use source: Random or the@rand01intrinsic in an Apply To rule
Related Nodes
- ShapeAttributes -- same concept for shape vertices, plus Tangent rotation mode for curve alignment
- PointSolver / PointEmitter -- write the
age,lifeandvelocitythe Age and Speed sources read - DrawPoints -- reads scale, opacity, and color attributes per point
- CloneToPoints -- reads rotation, scale, opacity, and color per point; supports pivot modes and group filtering
- PointDeform -- reads rotation attribute for Normal/Tangent mode local frame
- Noise -- common field source for spatial variation
- Random -- positional random field; see the per-element note above
- DistanceField -- shape-proximity-based field source