Shape Attributes
Sets per-vertex and per-path attributes on shape data, either from a spatial field or a uniform value. Enables per-path coloring, opacity, and stroke width in DrawShape.
Category: Shape Ops Menu path: Shape Ops > Shape Attributes
Ports
| Port | Type | Direction | Description |
|---|---|---|---|
shape_in | shape | input | Source shape |
field_in | scalarField | input | Spatial field to sample at each vertex (also accepts vectorField and colorField) |
out | shape | output | Shape with attributes set |
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
target | enum | Color | Which attribute to write: Color, StrokeWidth, Opacity, Rotation, or Custom |
source | enum | Field | Field (use field_in or uniform value), Value (always uniform), Tangent (Rotation only — use per-vertex tangent), Index (sample ramp by per-path index) |
value | scalar | 1.0 | Uniform value (used when source is Field with no connection, or source is Value) |
colorValue | color | white | Color value (used when target is Color and source is Field/Value) |
customAttribute | string | custom | Attribute key name (used when target is Custom) |
tangentOffset | scalar | 0 | Degrees added to the computed tangent (only when target=Rotation, source=Tangent) |
indexCurve | CurveRamp | 0→1 linear | Sampled by per-path normalized index for scalar targets (source=Index) |
indexColorRamp | GradientRamp | black→white | Sampled by per-path normalized index for Color target (source=Index) |
groupAttribute | string | (empty) | Optional path attribute name. When set, paths sharing the same value form a group and share the sampled value — essential for text workflows (use glyphIndex) so multi-contour glyphs stay consistent. |
outputMin | scalar | 0 | Lerp the [0,1] ramp / field output into [outputMin, outputMax]. Hidden for Color target and for source=Tangent or source=Value. Default 0/1 is identity |
outputMax | scalar | 1 | See outputMin |
How It Works
ShapeAttributes evaluates per vertex. For each vertex in the input shape:
- If a field is connected to
field_in, it is sampled at the vertex's position (origin-centered comp-pixel coordinates). - If no field is connected, the
valueorcolorValueparam is used uniformly for all vertices.
Attributes are written at two levels:
- Per-vertex (
shape.points.attributes) -- used by DrawShape's per-vertex color pipeline for smooth GPU-interpolated gradients across triangles. - Per-path (
path.attributes, using the first vertex's value) -- used by DrawShape's grouped rendering for per-path color, opacity, and stroke width.
| Target | Attribute key | Effect in DrawShape |
|---|---|---|
| Color | color | Per-vertex: smooth GPU-interpolated gradients. Per-path: uniform path color. |
| StrokeWidth | strokeWidth | Multiplier on DrawShape's strokeWidth param per path |
| Opacity | opacity | Per-path alpha multiplier |
| Custom | user-defined | Available for custom pipelines (consumer nodes decide what to do) |
Custom target output type: The Custom target follows the field type of the connected input:
- ColorField -> Vec4 per vertex (and per path, from first vertex)
- VectorField (alone) -> Vec2 per vertex (bipolar [-1,1])
- ScalarField or uniform value -> Scalar per vertex
This mirrors PointAttributes' Custom target, so the same convention applies across points and shape vertices.
DrawShape rendering priority: When per-vertex color attributes are present, DrawShape automatically uses its DrawShapeVertexColor pipeline for smooth gradient fills. When only per-path attributes exist, it uses grouped rendering (one draw call per unique color/opacity/strokeWidth group). When neither is set, it uses a single uniform-color draw call.
Usage Examples
Basic: Gradient-colored shape
Rectangle -> SubdivideShape (gridSize: 10) -> ShapeAttributes (target: Color, field: Gradient.colorField) -> DrawShape. The rectangle fills with a smooth color gradient interpolated across its subdivided mesh.
Per-path stroke width
Grid -> CloneToPoints (shape: Circle) -> ShapeAttributes (target: StrokeWidth, field: Noise.scalarField) -> DrawShape. Each cloned circle gets a different stroke width based on its position in the noise field.
Opacity fade
EditableShape -> ShapeAttributes (target: Opacity, field: DistanceField.scalarField) -> DrawShape. Parts of the shape closer to another shape fade out.
Per-letter text coloring (Index source + glyphIndex grouping)
Text("HELLO") -> TextToShape -> ShapeAttributes (target: Color, source: Index, groupAttribute: "glyphIndex", indexColorRamp: red->blue) -> DrawShape. Each letter gets a distinct color sampled along the ramp; multi-contour glyphs like "O" keep their outer and inner paths the same color thanks to glyphIndex grouping.
Per-path progressive stroke width
A shape with N paths -> ShapeAttributes (target: StrokeWidth, source: Index, indexCurve: 0 -> 2). The first path has strokeWidth multiplier 0, the last has 2, linearly.
Tips
- For smooth color gradients, the shape needs interior vertices -- use SubdivideShape upstream to create a mesh with enough resolution for the gradient
- StrokeWidth is a multiplier on DrawShape's
strokeWidthparam, not an absolute value -- a value of 2.0 doubles the base stroke width - ShapeAttributes does not change vertex positions -- it only writes attribute data. Use ShapeDeform for position changes.
- You can chain multiple ShapeAttributes nodes for different targets (e.g., one for Color, another for StrokeWidth)
Related Nodes
- PointAttributes -- same concept for points instead of shape vertices
- SubdivideShape -- create interior mesh vertices for smooth per-vertex gradients
- DrawShape -- reads color, strokeWidth, and opacity attributes
- CloneToPoints -- creates multi-path shapes ideal for per-path attributes
- Gradient -- colorField source for spatial color mapping
- DistanceField -- scalarField source for proximity-based attributes