Parametron

@parametron/svg — plan-view SVG renderer

The smallest reference renderer: it consumes the same one-shot contract as @parametron/three (Model.toScene()SceneJSON) and returns a standalone SVG document string — the scene projected onto the XY plane (world Y up, flipped to SVG's y-down). No DOM, no dependencies: it runs in a Web Worker or Node just as well as in the browser, which makes it the natural adapter for 2D consumers — texture layouts (texturic), cut profiles, plans, .svg file export.

import { sceneToSvg } from "@parametron/svg"

const scene = model.toScene()
const svg = sceneToSvg(scene, {
    background: "#a8a098",
    fill: "#b2644e",
    materialColors: { accent: "#4477aa" },
})
// display: <img src={"data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg)}>
// or save as a .svg file — the string is a complete document.

What each scene entity becomes

SceneJSONSVG output
SceneNode<g id="key"> — the SVG keeps the model's node tree (empty groups are skipped, duplicate keys deduped)
Mesh from a planar faceone <path fill-rule="evenodd"> — boundary loops (profile + holes), not triangles
Mesh from a closed solid<path fill-rule="nonzero"> of projected triangles — the filled silhouette
Curve (already a polyline)<polyline fill="none">
Point<circle>

Face fill uses SVG's own cascade: the root <svg> carries the default fill, a node with a material puts fill on its <g>, and an entity with its own material overrides on the element — which is exactly the nearest-ancestor material rule SceneJSON specifies, enforced by the format itself. Opening the file in Inkscape/Illustrator/Figma shows the model structure, and recoloring a group recolors its subtree.

Faces come out as clean outline paths because the renderer re-derives the tessellation boundary: an edge used by exactly one triangle lies on the face border, and chaining those edges reconstructs the exact profile and hole loops. A closed solid has no boundary edges, so it degrades to its silhouette (interior triangle edges cancel pairwise under nonzero fill — no seams).

Options

All geometry is in world units (mm).

  • viewBox — explicit world-space window (Y up); defaults to scene bounds.
  • padding — extra world units around auto bounds.
  • background — backdrop <rect> color; omitted → transparent.
  • fill / stroke / strokeWidth — defaults when no material color resolves.
  • materialColorsSceneJSON references materials by name only (bodies live in the Store); map names to CSS colors here.
  • pointRadius — point marker radius.

Material resolution follows the scene contract: an entity's own material, else the nearest ancestor node's — same nearest-ancestor rule the Three.js renderer applies.

📖 2 min read