Formations

Geometric projections of field data

Formations are Utomata's visual and geometric projection layer. Where fields store and evolve computational state, formations interpret that state as visible structure.

A formation does not store recurrent state of its own. Instead, its properties determine how geometry is constructed, transformed, sampled, displaced, colored, and rendered.

In the most direct case, a two-dimensional field is mapped across a two-dimensional surface formation so that corresponding field values determine color across the surface.

#A {
  dim = (64, 64, 1);
  set = C;
}

~surface {
  col = #A;
}

Here, the formation provides the visible geometry while #A provides the data projected onto it as color. This relationship is central to formations: fields describe computational state, while formations determine how that state is represented geometrically.

The same model can be extended in several directions. A 3D field can be projected across multiple surface layers, sampled values can displace the surface itself, and surfaces can be replaced or supplemented by repeated geometric instances. Each of these builds on the same underlying relationship between formation coordinates and field data.

Surface Geometry

By default, a formation consists of a single flat rectangular surface.

~surface {
  dim = (1, 1, 1);
}

For formations, dim describes the subdivision of the geometry, not its physical size. The default (1, 1, 1) produces a single rectangular region with no additional divisions across the surface.

Increasing dim adds geometry:

dim Surface structure
(1, 1, 1) one rectangular region
(2, 2, 1) surface divided into a 2 × 2 grid
(32, 1, 1) 32 × 1 = 31 divisions along x
(32, 32, 1) 32 × 32 grid

A formation may use the same dimensions as the field it visualizes, but it does not need to. Computational and visual resolution are independent.

Diagram: formation resolutions and field-to-formation resolution mapping — no divisions, same dim, different dims.

A 256 × 256 field, for example, may be projected onto a 1 × 1 formation:

#A {
  dim = (256, 256, 1);
  set = rand(1,2,3);
}

~surface {
  dim = (1, 1, 1);
  col = #A;
}

The field retains its full computational resolution while the formation uses only the amount of geometry required for rendering. This makes it possible to increase or reduce visual resolution independently of the underlying computation.

Coordinate Space

Like fields, formations have their own coordinate space. The built-in value C gives the coordinate currently being evaluated on the formation.

By default, formation coordinates use the same signed -1 to 1 convention introduced for fields. This gives fields and formations a common spatial frame even when their dimensions are completely different.

#A{
   dim = (32,32,1);
   run = rand(mlt(step, 1),mlt(step, 2),mlt(step, 3));
}

~A{
   col = #A[ mod(abs(C),0.25) ];
}

Each point evaluated across ~surface can use its own coordinate to sample one or more fields. A position near the center of the formation samples near the center of the field; a position near an edge samples the corresponding edge.

The mapping therefore follows coordinate position rather than subdivision index. A (32, 32, 1) field and a (512, 512, 1) field can both be projected across the same formation without changing its geometry or the expressions used to sample them.

This separation also means that several fields of different dimensions can participate in the same formation property:

~surface {
  col = mlt(#color, #light);
}

for each point along the formation, each field is sampled at the current coordinate C, and the resulting values are combined as any ordinary Utomata expression.

Formation properties are therefore not bindings to individual fields. They are expressions, and may combine any values, operators, macros, and field lookups.

Formation Transforms

So far, the surface has been described in its own local coordinate space. A formation also exists within the larger world coordinate system, where it can be positioned, rotated, and scaled as a complete object.

~surface {
  dim = (1);
  col = #A;
  pos = (1, 0, 0);
  rot = (-HALF_PI, 0, 0);
  scl = 0.5;
}
Property Role Units
dim subdivide the formation geometry geometric divisions
pos translate the complete formation world units
rot rotate the complete formation radians
scl scale the complete formation relative multiplier

Formation-level transforms are single values applied to the entire formation. They are not evaluated across the surface in the same way as properties such as col. These resolve only once for the formation as a whole and should therefore use an explicit absolute lookup to select a single field value. These properties are nevertheless ordinary Utomata expressions and can use any combination of static values, operators, and field lookups:

~surface {
  col = #A;
  pos = add(#B[0, 0], #C[0, 0.5]);
}

This distinction is easy to miss because both cases use ordinary Utomata expressions. The difference is the evaluation context of the property: a mapped surface property is evaluated repeatedly across the formation, while a formation transform expects one vector. Surface properties describe values distributed across the geometry; formation transforms describe the position, rotation, and scale of that geometry as a single object in world space.

Surface Displacement

Surface geometry does not have to remain flat. The disp property defines the displacement vector of the surface's vertices, allowing field data to dictate the shape of the geometry itself.

This is where the formation's dim property becomes especially important. For a surface formation, dim counts the divisions of the surface, and each axis with n divisions carries n + 1 vertices:

dim Surface divisions Surface vertices
(1, 1, 1) 1 × 1 2 × 2
(2, 2, 1) 2 × 2 3 × 3
(32, 32, 1) 32 × 32 33 × 33
#A {
  dim = (32, 32, 1);
  set = C;
}

~surface {
  dim = (32, 32, 1);
}

Here the field contains 32 × 32 cells and the formation contains 32 × 32 surface divisions. Because both occupy the same coordinate domain, the surface conforms exactly to the field: each division corresponds to exactly one field cell, and every vertex samples the field at its own coordinate.

Diagram: division grid and field-cell correspondence.

The correspondence does not depend on matching indices directly. Field cells and surface divisions occupy the same continuous coordinate space, so equal dimensions simply cause the two structures to coincide exactly.

By default, formation coordinates use the SIGNED domain. A flat surface therefore spans -1 to 1 along its active axes before any formation-level scaling is applied. disp defaults to C, which places every vertex at its own coordinate and produces the flat surface. Supplying a different expression moves the vertices:

#heightMap {
  dim = (16, 16, 1);
  set = rand(1);
}

~surface {
  dim = (256, 256, 1);
  disp = (C.x, C.y, mlt(#heightMap.x, 0.25));
  col = #heightMap;
}

Here each vertex keeps its position on the plane while its z component is taken from the sampled field, turning field data into displaced geometry.

Increasing dim gives the surface more vertices that can respond independently to sampled data, while decreasing it produces a coarser geometric representation of the same underlying field. A formation may use lower or higher resolution than the fields affecting displacement: a lower resolution can optimize rendering by reducing the size of the generated geometry, while a higher resolution can produce more visual detail from low-resolution fields via interpolation.

Instance Formations

Surface formations generate connected surface geometry. Instance formations instead place repeated geometric elements throughout the formation coordinate space. A formation is evaluated as an instance formation when it any of the instance properties are set, or explicitly using the property type = INSTANCE.

#A {
  dim = (16, 16, 1);
  set = rand(1,2,3);
}

~surface {
  dim = (16,16, 1);
  col = #A;
  shape = ICO;
}

Here dim creates 16 × 16 × 1 = 256 independent instances. As with surfaces, dim describes the formation's geometry rather than physical size. With the default SIGNED coordinate domain, the instances are distributed from -1 to 1 across the xy plane. The formation, along with all of its instances, can then be positioned, rotated, or scaled as a whole using its formation-level transforms.

Each instance is positioned at the coordinate C by default. Expressions evaluated as instance properties run independently across the formation, allowing every instance to derive its own color and transformation from fields, macros, and operators, just like any other Utomata expression.

A field and an instance formation do not need matching dimensions. As with surface formations, correspondence is established through coordinate space rather than cell or instance indices.

#A {
  dim = (4, 4, 1);
  set = rand(1, 2, 3);
}

~instances {
  dim = (16, 16, 1);
  col = #A;
  shape = CONE;
  i_pos = C;
  i_scl = (0.75);
  i_rot = add(#A, mlt(step,0.01));
}

The 16 × 16 instances sample the 4 × 4 random field at their corresponding coordinates to retrieve their colors. The position of each instance uses C, and all instances are scaled to 3/4 of their full size.

Note that the dimension of an instance formation also determines the initial size of each instance, since all instances must fit into the same 2 × 2 × 2 cubic space. This can be tuned using the formation's scl property.

Instance formations provide per-instance position, rotation, and scale using the prefix i_. Unlike the formation-level pos, rot, and scl properties introduced earlier, these transformations are evaluated independently for every instance and can sample entire fields, just like col. This allows a single formation to contain many elements with different transformations while the formation itself remains one object in world space.

The two transform levels therefore serve different purposes:

Transform Evaluation Effect
formation transform once moves, rotates, or scales the complete formation
instance transform once per instance moves, rotates, or scales each repeated element independently

These levels can be combined. A computed arrangement of individually transformed instances can itself be translated, rotated, or scaled as a single formation.

Instance Geometry

Instance formations repeat a geometric primitive at every element of the formation domain. The primitive is selected independently of the formation dim, which controls how many instances exist. However, the instance geometry properties determine the shape shared by all instances of that formation.

The simplest case uses one of Utomata's built-in primitive shapes:

Shape Description
QUAD flat quadrilateral (default)
CUBE unit cube
CONE cone
ICO subdivided icosphere
SPHERE sphere

For shapes that cannot be expressed using the built-in primitives, instance geometry can instead be generated procedurally using the Playtoh geometry model. Custom geometry is defined through the i_geo and i_res properties:

~instances {
  type = INSTANCE;
  dim = (16, 16, 1);

  i_geo = (1, 0, -0.4615385);
  i_res = (0, 2, 0);
}

i_geo describes the geometric form using three parameters:

Component Role
x profile
y bias
z silhouette

i_res controls the resolution and construction of that form:

Component Role
x rings
y segments
z twist

When i_geo and i_res define custom geometry, they override the primitive selected by shape.

Shade and Filter Modes

Formation expressions determine values such as color and displacement, but the final appearance of the geometry also depends on how those values are interpreted during rendering.

The shade property controls how surface normals are produced:

Value Description
FACE (default) use a single normal for each face, producing faceted shading
SMOOTH interpolate normals across vertices, producing a continuous shaded surface
~surface {
  dim = (32, 32, 1);
  disp = #height;
  shade = SMOOTH;
}

FACE preserves the visible structure of the underlying geometry. SMOOTH instead interpolates the displaced surface normals across vertices, making coarse geometry appear visually continuous without increasing the formation resolution itself.

The filter property controls how field values are sampled when they are mapped onto formation geometry:

Value Description
NEAREST (default) sample the nearest field cell
INTERP interpolate between neighboring field cells
#A {
  dim = (16, 16, 1);
  set = C;
}

~surface {
  dim = (128, 128, 1);
  col = #A;
  filter = INTERP;
}

With NEAREST, several nearby formation coordinates may resolve to the same source cell, preserving the discrete structure of the field. INTERP blends neighboring samples and is useful when low-resolution field data is rendered across higher-resolution geometry.

These modes operate at different stages. filter affects how field data is sampled into formation expressions, while shade affects how the resulting geometry responds to lighting. Neither changes the underlying field data or formation topology.


Full Reference

Formation properties are declared inside a ~formation { ... } block. Defaults are shown where applicable.

Property Type Default / Values Description
type enum SURFACE (default), INSTANCE selects surface or instance topology
shape enum QUAD (default), CUBE, CONE, ICO, SPHERE primitive used by instance formations
dim vec (1, 1, 1) formation-domain dimensions; determines surface divisions or instance counts
col expr (1.0, 1.0, 1.0) color evaluated across the formation
disp expr C displaced surface position
pos expr (0.0, 0.0, 0.0) position of the complete formation in world space
rot expr (0.0, 0.0, 0.0) rotation of the complete formation
scl expr (1.0, 1.0, 1.0) scale of the complete formation
i_pos expr C per-instance position
i_rot expr (0.0, 0.0, 0.0) per-instance rotation
i_scl expr (1.0, 1.0, 1.0) per-instance scale
i_piv expr (0.0, 0.0, 0.0) per-instance pivot used as the center of rotation and scale
i_geo vec / expr (1, 0, -0.4615385) custom Playtoh geometry parameters [profile, bias, silhouette]; overrides shape
i_res vec / expr (0, 2, 0) custom Playtoh geometry parameters [rings, segments, twist]; overrides shape
rot_unit enum TAU (default), SIGNED, UNIT determines how rotation values are converted to radians
coord_dom enum SIGNED (default), UNIT coordinate domain used by formation C
shade enum FACE (default), SMOOTH controls faceted or interpolated normal shading
filter enum NEAREST (default), INTERP controls nearest-cell or interpolated field sampling during rendering
sample enum SOURCE (default), DEST selects the coordinate frame used for cross-field sampling
cull enum AUTO (default), NONE, BACK, FRONT controls face culling for instance geometry

Formation Types

Value Meaning
SURFACE generate surface geometry from the formation domain
INSTANCE generate one independent geometric instance for every formation-domain element

Coordinate Domain

Value Range
SIGNED (default) -1 to 1
UNIT 0 to 1

Formation coordinates define the local spatial domain. Physical size is controlled separately through scl.

Rotation Units

Value Interpretation
TAU (default) rotation values interpreted using tau-based angular units
SIGNED -1..1 maps to -PI..PI radians
UNIT 0..1 maps to 0..TAU radians

Shading

Value Behavior
FACE (default) one normal per face; faceted appearance
SMOOTH interpolated vertex normals; continuous appearance

Filtering

Value Behavior
NEAREST (default) nearest source-cell sampling
INTERP interpolated sampling between neighboring cells

Sampling Frame

Value Behavior
SOURCE (default) sample from the source frame
DEST sample from the in-progress destination frame

Face Culling

Value Behavior
AUTO (default) choose culling based on geometry; closed solids cull backs while quads and custom geometry render both sides
NONE render both front and back faces
BACK cull back-facing polygons
FRONT cull front-facing polygons

Formation Built-ins

Identifiers available inside formation expressions:

Name Role Description
C coordinate current formation coordinate
step value global simulation step counter

The central distinction throughout formation properties is their evaluation context. Properties such as col, disp, and the i_* instance properties are evaluated across formation coordinates, while pos, rot, and scl resolve once for the formation as a whole.

Together, these properties separate computation, topology, geometry, transformation, sampling, and rendering without changing the underlying field model. Fields determine and evolve data; formations decide how that data occupies and appears in space.