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
| Port | Type | Direction | Description |
|---|---|---|---|
shape_in | shape | input | Shape geometry to rasterize |
fill_source | imageRgba16f | input | Texture to use as fill (overrides fill color) |
stroke_source | imageRgba16f | input | Texture to use as stroke (overrides stroke color) |
out | imageRgba16f | output | Rasterized image |
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
fillEnabled | boolean | true | Enable shape fill |
fillColor | color | white | Fill color (ignored when fill_source connected) |
fillOpacity | scalar | 1.0 | Fill opacity (0-1) |
fillRule | enum | nonZero | Fill rule: nonZero or evenOdd |
strokeEnabled | boolean | true | Enable shape stroke |
strokeColor | color | white | Stroke color (ignored when stroke_source connected) |
strokeWidth | scalar | 2 | Stroke width in pixels |
strokeOpacity | scalar | 1.0 | Stroke opacity (0-1) |
strokeJoin | enum | miter | Line join style: miter, round, or bevel |
strokeCap | enum | butt | Line cap style: butt, round, or square |
miterLimit | scalar | 4.0 | Maximum miter join extent before switching to bevel |
paintOrder | enum | StrokeOverFill | Draw 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. |
strokeUvMode | enum | Canvas | How 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. |
dashEnabled | boolean | false | Enable dashed stroke (fill is never dashed) |
dash | scalar | 12 | Dash length in shape-local pixels |
gap | scalar | 6 | Gap between dashes in shape-local pixels |
dashOffset | scalar | 0 | Phase offset — animate for marching-ants effect |
Expose Channels
When enabled (E button on node header), adds input ports that override params via edge connections:
| Port | Type | Overrides |
|---|---|---|
fillOpacity_in | scalar | fillOpacity |
strokeWidth_in | scalar | strokeWidth |
strokeOpacity_in | scalar | strokeOpacity |
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:
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.
Per-path grouped -- paths carry individual
color,opacity, orstrokeWidthattributes (set by ShapeAttributes). Paths are grouped by their effective appearance, with one draw call per group. The per-pathstrokeWidthattribute multiplies the DrawShapestrokeWidthparam.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 = FillOverStrokereproduces 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_sourcedefaults to canvas-space UV.stroke_sourcedefaults to canvas-space UV (strokeUvMode = Canvas); setstrokeUvMode = Strokefor 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
Related Nodes
- Transform2D -- positions shapes before rasterization
- DrawPoints -- rasterizes point clouds instead of shapes
- SubdivideShape -- generates interior mesh for per-vertex gradients
- ShapeAttributes -- sets per-path/per-vertex color, opacity, stroke width