Skip to content

Draw Shape

Rasterizes shape geometry into a texture using lyon tessellation and GPU 4x MSAA rendering. Supports fill, stroke, per-path grouping, per-vertex color interpolation, and texture sources.

Category: Render Menu path: Render > DrawShape

Ports

PortTypeDirectionDescription
shape_inshapeinputShape geometry to rasterize
fill_sourceimageRgba16finputTexture to use as fill (overrides fill color)
stroke_sourceimageRgba16finputTexture to use as stroke (overrides stroke color)
outimageRgba16foutputRasterized image

Parameters

ParamTypeDefaultDescription
fillEnabledbooleantrueEnable shape fill
fillColorcolorwhiteFill color (ignored when fill_source connected)
fillOpacityscalar1.0Fill opacity (0-1)
fillRuleenumnonZeroFill rule: nonZero or evenOdd
strokeEnabledbooleantrueEnable shape stroke
strokeColorcolorwhiteStroke color (ignored when stroke_source connected)
strokeWidthscalar2Stroke width in pixels
strokeOpacityscalar1.0Stroke opacity (0-1)
strokeJoinenummiterLine join style: miter, round, or bevel
strokeCapenumbuttLine cap style: butt, round, or square
miterLimitscalar4.0Maximum miter join extent before switching to bevel
paintOrderenumStrokeOverFillDraw order: StrokeOverFill = fill first, stroke on top (SVG default). FillOverStroke = stroke first, fill on top — inner half of the centered stroke is hidden by the fill, equivalent to "outside" alignment.
strokeUvModeenumCanvasHow a connected stroke_source texture maps onto the stroke. Canvas = sample at canvas-space UV (the texture occupies the full comp; the stroke clips it). Stroke = sample at lyon's arc-length UV — U flows along the path, V is across the stroke width. Has no effect when stroke_source is unconnected.
dashEnabledbooleanfalseEnable dashed stroke (fill is never dashed)
dashscalar12Dash length in shape-local pixels
gapscalar6Gap between dashes in shape-local pixels
dashOffsetscalar0Phase offset — animate for marching-ants effect

Expose Channels

When enabled (E button on node header), adds input ports that override params via edge connections:

PortTypeOverrides
fillOpacity_inscalarfillOpacity
strokeWidth_inscalarstrokeWidth
strokeOpacity_inscalarstrokeOpacity

How It Works

DrawShape tessellates input shape geometry on the CPU using the lyon library, producing vertex and index buffers that are rendered on the GPU with 4x MSAA for smooth anti-aliased edges.

Three render paths are selected automatically based on the input shape's attributes:

  1. Uniform color -- all paths share the same color/opacity. Single draw call, zero overhead. This is the default when no per-path or per-vertex attributes are present.

  2. Per-path grouped -- paths carry individual color, opacity, or strokeWidth attributes (set by ShapeAttributes). Paths are grouped by their effective appearance, with one draw call per group. The per-path strokeWidth attribute multiplies the DrawShape strokeWidth param.

  3. Per-vertex color -- vertices carry RGBA color attributes (set by ShapeAttributes with a field input like a Gradient or DistanceField). Uses a dedicated GPU pipeline that interpolates color across triangles for smooth gradients.

Detection priority: per-vertex > per-path > uniform. If both fill_source and per-vertex color exist, the texture source wins for fill.

Fill and stroke are rendered in separate passes within the same MSAA render target. The fill rule controls how overlapping sub-paths are handled: nonZero fills all enclosed regions (standard), evenOdd alternates filled/unfilled regions based on winding count.

Usage Examples

Basic: Draw a colored shape

Rectangle -> Transform2D -> DrawShape -> Output. Set fill color and stroke width in DrawShape's params. This is the standard geometry rendering pipeline.

Textured fill

Connect an ImageSource or Noise texture to the fill_source port. The shape acts as a clip mask over the texture, which is sampled at canvas-space UV coordinates.

Path-following gradient stroke (Vogel-style ribbon)

EditableShape (a flowing curve) -> DrawShape, with a horizontal Gradient connected to stroke_source and strokeUvMode = Stroke. The gradient flows along the spline — U follows the path's arc length, V is constant across the stroke width. Combine with a thick strokeWidth for a ribbon. For a gradient that bands across the stroke width instead, rotate the gradient 90° (vertical) so V drives the color stops.

When dashEnabled is on, each dash gets its own 0→1 U range — the gradient repeats per dash. With LineCap: round you get pill-shaped dashes that each carry a fresh gradient sweep.

Per-vertex gradient

Rectangle -> SubdivideShape -> ShapeAttributes (target: Color, field: Gradient or DistanceField) -> DrawShape. The SubdivideShape fills the interior with a triangle mesh, ShapeAttributes assigns per-vertex colors from a field, and DrawShape renders with smooth GPU-interpolated gradients.

Per-path styling

Grid -> ShapeToPoints -> CloneToPoints (with a Circle source) -> ShapeAttributes (target: Color, field: Noise) -> DrawShape. Each cloned circle gets its own path-level color from the noise field.

Dashed stroke

Enable dashEnabled, set dash / gap (in shape-local pixels). Dashes are split along path arc length, preserving bezier fidelity — curves stay curved inside each dash. Combine with strokeCap: round for pill-shaped dashes. Keyframe dashOffset for marching-ants / selection-marquee animation. Dashing affects stroke only; fill renders solid.

Tips

  • Shelf tools (R, O, P, G, T) auto-create a Geometry -> T2D -> DrawShape -> Output chain
  • Stroke geometry is always centered on the path. paintOrder = FillOverStroke reproduces the visual of "outside" alignment (stroke's inner half hidden by the fill) without a stencil pass. There is no built-in "inside-only" mode — clip the stroke to the fill region by routing the shape through a Matte node if you need that effect.
  • fill_source defaults to canvas-space UV. stroke_source defaults to canvas-space UV (strokeUvMode = Canvas); set strokeUvMode = Stroke for path-following arc-length UV.
  • DrawShape is a passthrough in chain walks -- it does not affect overscan or content bounds computation beyond inflating the AABB by stroke/point radius
  • For text rendering, use DrawText instead -- it accepts TextData directly

Caddis — professional motion design.