Skip to main content

Camera Projection Pipelines

Every Vonk render pipeline has the same middle and the same end. Whatever makes the points — a procedural generator, a font, an imported mesh — they all pass through vArrayCameraProjection to become screen-space coordinates, and then into vArrayShapeRender to be drawn.

Learn that core once and the rest of the family is just swapping the ends:

any generatorvArrayPointsOnCirclevArrayPointsOnSpherevArrayTextFontvArrayFromOBJmodifiers (optional)vArrayDisplaceValuesvArrayCameraProjectionvArrayShapeRenderArrayPointArrayEdgeArrayShapeArrayGroupsBackgroundArray AArray PointInput

If you haven't built the basic version of this yet, start with Your First Comp — this guide assumes you have that three-node chain running and want to push it further.

1. Animate the camera, not the geometry​

This is the single most useful habit in the whole pipeline. vArrayCameraProjection is a full virtual camera, and every one of its transform values is a standard animatable Fusion control — so you can move through a static point cloud instead of animating the points themselves. The results feel different, and usually better: the geometry stays coherent while the viewpoint does the work.

What you wantWhat to animate
Orbit around a 3D cloudY Rotation
Push in / pull outZ Offset — the primary framing control; default 1.0
Roll the whole outputZ Rotation
Pan without changing distanceX Offset, Y Offset
Tilt through a cloudX Rotation

Two more controls worth knowing:

  • Field of view (default 90). Lower values flatten the perspective towards orthographic — good for technical or diagrammatic looks. Higher values exaggerate foreshortening, which is what makes depth read on a 3D cloud. If your 3D scatter looks flat, this is usually why.
  • Lock X/Y and X Scale. Locked (the default) scales the projection uniformly. Unlock it to stretch the output on one axis — useful for anamorphic or deliberately skewed layouts.

For a flat generator like vArrayPointsOnCircle there's no real depth, so leave the rotations alone and just set Z Offset to frame the ring. Depth is where the camera starts earning its place.

2. 3D point clouds​

vArrayPointsOnSphere is the natural partner for a moving camera — it's the first generator where orbiting actually reveals something:

  • Amount of points (100) — how many points to distribute.
  • Sphere size (0.3) — the radius of the cloud.
  • Distribution — switches between evenly spread (Fibonacci) and clustered placement.
  • Trim Top and Trim Bottom — at their defaults (-1 and 1) you get the whole sphere; tightening them cuts it back to a hemisphere or a band, which is often a cleaner mograph element than a full ball.
  • Random Distance and Random seed — push points in and out along their radius for a shell with thickness, reseeding for a different scatter.

Then keyframe the camera's Y Rotation from 0 to 360 and you have an orbit. Add a little Z Offset movement on top and it stops looking mechanical.

3. Real geometry: meshes from an OBJ​

vArrayFromOBJ imports vertex positions from a Wavefront .OBJ — hero geometry out of Blender, Cinema 4D or Maya, dropped into a Vonk pipeline.

  • Input Source picks where the mesh comes from: 0 reads a file from disk via Filename, 1 fetches a remote URL, and 2 takes raw OBJ text from another node's Input — which is how you feed procedurally generated geometry in.
  • Scale File Units By normalises the geometry into Fusion's coordinate space. Exporting applications disagree about units — if your mesh arrives microscopic or enormous, this is the control that fixes it.

The node has two outputs, and the second one is easy to miss:

vArrayFromOBJ.Points -> vArrayCameraProjection.ArrayA
vArrayFromOBJ.Edges -> vArrayShapeRender.ArrayEdge
vArrayCameraProjection.Output -> vArrayShapeRender.ArrayPoint
Background.Output -> vArrayShapeRender.Input

Edges carries the mesh's actual topology. Connect it to the render node's Array Edge input, then enable Use Edge Data — and the line layer draws the mesh's real edges instead of joining sequential points, which would otherwise scribble diagonally across your model. That one checkbox is the difference between a wireframe and a mess.

Note that this gives you the mesh's vertices, not its surface — a coarse mesh stays coarse. Add vArrayDisplaceValues (below) if you want more points or more life in them.

4. Text through the same pipeline​

vArrayTextFont turns styled text into a point array, which means text renders through exactly the same camera-projection chain as everything else:

  • Styled Text is the string; Size, Character Spacing and Justification lay it out; Letter Case and the offset/rotation/scale controls position it in 3D.
  • It also outputs ScriptVal_Groups — the group membership that says which points belong to which character.

That second output is what makes text behave:

vArrayTextFont.Output -> vArrayCameraProjection.ArrayA
vArrayTextFont.ScriptVal_Groups -> vArrayShapeRender.ArrayGroups
vArrayCameraProjection.Output -> vArrayShapeRender.ArrayPoint
Background.Output -> vArrayShapeRender.Input

With ArrayGroups connected, enabling Connect Text Groups on the render node draws lines within each group rather than between consecutive points across the whole array — so letters don't get joined to each other by a stray line.

For text that follows a path rather than sitting on a baseline, there's a dedicated terminal node, vArrayRenderTextPath — it renders text onto an array of XY points, with Path Width and Show Path controlling the guide the characters sit on.

5. Modifiers go between the generator and the camera​

Everything in the pipeline up to the projection is world-space geometry, so this is where you disturb it:

  • vArrayDisplaceValues — noise-driven displacement with a spherical falloff. Noise Scale and Noise Rate set the shape and speed of the noise, Amplitude how far points travel, and FallOff Sphere X/Y/Z, FallOff Radius and FallOff Tightness localise the effect — a bulge, a ripple, a shockwave. Invert Falloff flips it from pushing out to pulling in.
  • vArrayPointsJitter — the simpler tool: Jitter X/Y/Z offsets, a Seed, and Uniform Jitter to keep the direction consistent. This is the fastest way to stop a perfect grid or ring from looking machine-made.

Order matters: displace before the projection, because the projection is what collapses your 3D geometry into 2D. Push displacement downstream of it and you're animating screen-space coordinates instead of world-space ones, which is a different (and usually less useful) effect.

6. The render hub: four inputs, five layers​

vArrayShapeRender is where the pipeline converges, and it has more inputs than the basic chain uses:

InputComes fromWhat it does
Array PointvArrayCameraProjectionThe positions. Always required.
Array EdgevArrayFromOBJ, vArrayPointsConnectExplicit point-to-point connections, used when Use Edge Data is on
Array ShapevArrayCustom2DShapes, vArrayCustom3DShapesA polygon to draw at each point instead of a dot
Array GroupsvArrayTextFont and other font/path generatorsGroup membership, so lines connect within groups
JSON Custom ColorvArrayColorPer-point colour, overriding the layer colour

The five layers — Show Dots, Show Lines, Show Custom, Show Index and the outline toggles — are independent and can all be on at once. A few things that aren't obvious from the parameter names:

  • Line Width, Dot Radius and the shape outline widths are in normalised units, relative to composition size. A width that looks right at 1920×1080 will look thin at 4K.
  • Line Type switches between Solid, Dashed, Dotted and Dash-Dot, and Join Type controls how corners meet (Miter, Bevel, Round) — the cheapest way to change the character of a wireframe.
  • Show Index draws the array index at each point. It's a debug switch: invaluable while building, and it should be off before the final render. All layer toggles are animatable, so you can also drive them from keyframes for reveal sequences.
  • Performance scales with point count and enabled layers, and Lines and Custom Shapes are the expensive ones. Disable them while designing a large array.
  • For per-point colour, connect a vArrayColor node to JSON Custom Color — its Color By control can drive colour from the index, a gradient or a pattern, so a ring isn't limited to one flat colour.

When it doesn't render​

Almost every "it's broken" in this pipeline is one of five things:

SymptomCause
Frame is blackNothing on the render node's Input. Connect a Background node — the shapes composite over an image.
A single dotThe generator's count control is at its default. On vArrayPointsOnCircle that's Round Segments = 1.
Index labels render but the dots don'tShow Dots is off, Dot Radius is too small to see, or the camera's Z Offset has pushed the output out of frame.
Nothing connects to the projection nodeIts Array A port is hidden. Enable Show Input.
The layout looks flatThere's no depth in the points, or Field of view is so low the projection has gone effectively orthographic.

And when points are landing in an order you didn't expect: turn on Show Index. It answers "how is this array actually ordered?" faster than any other tool in the set — and point order is what decides which points the line layer joins.

Reference​