Collections

A collection is a spreadsheet of things: each row is one item, each column is an attribute those items carry.

Almost everything that flows between nodes in DNA travels as a collection. Points, mesh vertices, shapes, even plain rows of numbers — they all share the same shape: a table with rows (the items) and columns (the data each item holds). Once you see a collection as a spreadsheet, every node becomes "a thing that adds rows, removes rows, or edits a column".

Rows and columns

Picture a small table:

@P (position)@Cd (colour)@pscale (size)
0, 0, 0red1.0
1, 0, 0green0.5
2, 0, 0blue2.0

Three rows means three items. Each column is an attribute — a named piece of data every row carries. Attribute names use an @ prefix when you reference them (so @P is the position column, @Cd is colour). You'll meet these names everywhere: in the spreadsheet view, in The Expression language, and in node parameters.

Some attributes are standard and show up again and again:

You can also make up your own. Any node that writes a column can name it whatever you like, and downstream nodes can read it back.

Open the spreadsheet view on any node to see its collection as a literal table — rows down, attribute columns across. It's the fastest way to understand what's actually flowing through a connection.

The kinds of collection

Every collection has a kind that tells DNA (and you) what the rows represent and how they draw. They all share the row/column structure — the kind just adds expectations on top.

There's also a kind for Gaussian splats (captured splat scenes) and one for Analytic shapes — perfectly smooth, resolution-free shapes carried as math rather than baked geometry (see Analytic shapes and the @analytic attribute).

Points, Geometry, Curves, splats, and Analytic shapes are visual — they draw straight into the viewport. Tables and Lists are data-only; they hold information for other nodes to use but don't render on their own.

How geometry moves between nodes

When you wire one node into another, what travels down the wire is a collection. A node reads the incoming collection, does its thing, and passes a new one out:

Because every kind is the same underlying table, you can freely mix steps: scatter points on a mesh, colour them from a table, then turn them into curves. Nodes that need a specific kind will convert what you give them automatically where it makes sense.

If a node isn't behaving, check the kind of its input. A node expecting Geometry won't have faces to work with if you hand it loose Points — the spreadsheet and the node's badges tell you which kind you're feeding it.

Some columns are always there

A few attributes come for free with certain kinds. Any Points or Geometry collection always carries @P and @id, so you can read a point's position or its unique id without anything having to create those columns first. Analytic shapes always carry their shape attribute too. You never have to set these up by hand — they're guaranteed by the kind.

See also