Skip to content

Shape Deform ​

Displaces shape vertices procedurally using a vector/scalar field or a uniform value. Preserves topology -- only vertex positions change.

Category: Shape Ops Menu path: Shape Ops > ShapeDeform

Ports ​

PortTypeDirectionDescription
shape_inshapeinputShape to deform
field_invectorFieldinputSpatially varying displacement field (also accepts scalarField)
value_invec2inputUniform displacement vector (also accepts scalar)
amplitude_inscalarinputOverride for amplitude param
outshapeoutputDeformed shape

Parameters ​

ParamTypeDefaultDescription
modeenumNormalDisplacement direction: Normal, Tangent, XY, X, or Y
amplitudevec250, 50Displacement magnitude in pixels, per axis. Linked by default; unlink to weight X and Y independently in XY mode. Normal/Tangent/X/Y modes show a single value (only one component applies)
sourceenumFieldSignal source: Field or Value
deformOperationenumDisplaceDisplace adds the field as an offset (pixels, via amplitude); Scale multiplies the coordinate by it (ratio, via scaleAmount)
scaleAmountscalar1.0Scale only. 0 leaves the shape alone, 1 hands the multiplier entirely to the field

How It Works ​

ShapeDeform visits every vertex in the input shape and displaces it based on the selected mode and signal source:

  • Field source: The field_in port provides a spatially varying signal. Each vertex samples the field at its position using eval_bipolar() (range [-1, 1]). A scalarField connected to field_in is also accepted.
  • Value source: The value_in port provides a uniform displacement applied equally to all vertices.

The amplitude parameter scales the displacement. The mode determines the direction:

  • Normal -- displace along the vertex normal (perpendicular to the path)
  • Tangent -- displace along the path tangent (parallel to the path)
  • XY -- displace in both X and Y, each axis scaled by its own amplitude component
  • X / Y -- displace along a single axis only

In XY mode the amplitude's X and Y components scale each axis independently -- unlink the pair in the Properties panel to, say, ripple a shape horizontally more than vertically. A scalar wired into amplitude_in applies to both axes.

Only vertex positions are modified; path topology, point IDs, and attributes are preserved. This means downstream nodes like DrawShape see the same structure but different vertex locations.

Bezier handles are displaced too, each one sampling the field at its own position rather than inheriting its endpoint's displacement. That distinction matters as soon as the field changes quickly across a single segment — a handle sits about a third of the way along the chord, so inheriting the endpoint's value leaves it short and every segment bulges the same way, which reads as a scalloped curve. Sampling at the handle keeps the curve tracking the deformation. In Normal and Tangent modes the handle still uses its endpoint's normal/tangent frame, since a control point is off-curve and has no frame of its own.

ShapeDeform runs in the value pre-pass (before GPU evaluation) so that downstream nodes like Transform2D and DrawShape use accurate deformed bounds for overscan computation.

Displace vs Scale ​

Displace adds the field to a coordinate. Scale multiplies by it, which is a different family of shapes entirely — anything where one axis is a function of the other: twists, tapers, pinches, bulges, flares.

In Scale mode the factor is mix(1, field, scaleAmount), applied about the origin on the axis mode selects. With scaleAmount at 1 the field is the multiplier outright, so a field reading -1 mirrors that part of the shape and 0 collapses it onto the axis. Normal and Tangent have no meaning here — there is no "along the normal" version of multiplying a coordinate — so they fall through to both axes.

Only one of amplitude and scaleAmount is live at a time, and Properties hides the other; a pixel amplitude sitting next to a 0–1 ratio with no indication of which one matters is worse than an extra click.

The distinction is why a twist needs Scale. In Displace mode the offset would have to already contain the coordinate you are scaling, which means multiplying two fields together just to reach it. See Twist for the ready-made version.

Usage Examples ​

Basic: Wavy edges ​

Rectangle -> ShapeDeform (mode: Normal, field: Noise.scalarField) -> T2D -> DrawShape -> Output. The rectangle's edges ripple based on the noise field. Animate Noise evolution for flowing deformation.

Organic shapes ​

Circle -> ResampleShape (count: 64) -> ShapeDeform (mode: Normal, field: Noise.vectorField, amplitude: 30) -> DrawShape. Resample first to add enough vertices for smooth deformation, then displace along normals for blob-like organic shapes.

Uniform shift ​

Rectangle -> ShapeDeform (source: Value, mode: XY, value_in: MakeVector) -> DrawShape. Use a MakeVector node to create a displacement offset, applying the same shift to all vertices.

Tips ​

  • Resample your shape upstream (ResampleShape) if it doesn't have enough vertices for smooth deformation -- a Rectangle with only 4 corners will deform coarsely
  • Noise with Curl type produces smooth, divergence-free deformation that avoids self-intersection
  • ShapeDeform is terminal in content bounds computation -- it reads the pre-pass AABB rather than passing through, because deformation changes the shape's bounding box
  • Amplitude is animatable -- keyframe it for deformation that grows or shrinks over time
  • ResampleShape -- add more vertices before deforming for smoother results
  • Noise -- primary field source for procedural deformation
  • DistanceField -- SDF field source for distance-based deformation
  • Transform2D -- rigid spatial transform (no deformation)
  • DrawShape -- rasterize the deformed shape