Texture layers and shaders are stored in a SURF
chunk as BLOK sub-chunks, which, unlike the other surface sub-chunks,
contain sub-chunks of their own.
BLOK
BLOK { header[SUB-CHUNK], attributes[SUB-CHUNK] * }
The first sub-chunk is the header, whose ID gives the block type. The sub-chunks
after it depend on the type; texture layers usually include a TMAP.
| Header ID | Block |
|---|---|
IMAP | Image map texture |
PROC | Procedural texture |
GRAD | Gradient texture |
SHDR | Shader plug-in |
Block header
block-header { ordinal[S0], block-attributes[SUB-CHUNK] * }
| Sub-chunk | Layout | Meaning |
|---|---|---|
CHAN | texture-channel[ID4] | The surface channel the layer changes: COLR, DIFF, LUMI, SPEC, GLOS, REFL, TRAN, RIND, TRNL or BUMP. Required in texture layers; ignored in shaders |
ENAB | enable[U2] | Non-zero to evaluate the block; enabled when missing |
OPAC | type[U2], opacity[FP4], envelope[VX] | How the layer combines with the layers beneath it on the same channel; see below. Texture layers only; 100% additive when missing |
AXIS | displacement-axis[U2] | For displacement maps, the axis displacements are made along: 0 X, 1 Y, 2 Z |
| OPAC type | Combination |
|---|---|
| 0 | Normal |
| 1 | Subtractive |
| 2 | Difference |
| 3 | Multiply |
| 4 | Divide |
| 5 | Alpha: this layer is used as an alpha channel, the layers beneath showing where it is white and not where it is black |
| 6 | Texture displacement: this layer distorts the layers beneath |
| 7 | Additive |
Ordinal strings
When several blocks apply to one channel, or several shaders to the surface, the
ordinal string sets their order: a reader sorts the blocks by comparing ordinals as
C strings. An ordinal is a fraction written in base 255, using the byte values 1 to
255 as digits (0 ends the string), so a new block can always be placed between two
others, much as 0.55 fits between 0.5 and 0.6. An ordinal must not end in the digit
1, just as a decimal fraction gains nothing from a trailing 0: \x80 and
\x80\x01 would leave no room between them.
TMAP – Texture mapping
TMAP { attributes[SUB-CHUNK] * }, used by image maps and procedurals to
map object or world coordinates into texture space:
| Sub-chunk | Layout | Meaning |
|---|---|---|
CNTR | vector[VEC12], envelope[VX] | Texture centre in metres; 0 when missing |
SIZE | vector[VEC12], envelope[VX] | Texture size in metres; should always be given where it is used |
ROTA | vector[VEC12], envelope[VX] | Heading, pitch and bank in radians; 0 when missing |
OREF | object-name[S0] | A reference object whose position, rotation and scale in the scene also apply; (none) or missing for none |
FALL | type[U2], vector[VEC12], envelope[VX] | Falloff with distance from the centre, as a rate per unit along each axis: type 0 cubic (each axis separately), 1 spherical (by distance), 2 linear X, 3 linear Y, 4 linear Z (the other two components ignored) |
CSYS | type[U2] | 0 object coordinates (the default), 1 world coordinates |
IMAP – Image maps
| Sub-chunk | Layout | Meaning |
|---|---|---|
PROJ | projection-mode[U2] | How the image is projected; see below |
AXIS | texture-axis[U2] | Major axis for planar, cylindrical and spherical projection: 0 X, 1 Y, 2 Z |
IMAG | texture-image[VX] | The clip index of the image |
WRAP | width-wrap[U2], height-wrap[U2] | What lies outside the image, across and down: 0 reset (black), 1 repeat (the default), 2 mirror, 3 edge (the nearest edge pixel) |
WRPW | cycles[FP4], envelope[VX] | How many times the image repeats around, for cylindrical and spherical projection |
WRPH | cycles[FP4], envelope[VX] | The same, vertically |
VMAP | txuv-map-name[S0] | For UV projection, the name of the TXUV vertex map to use |
AAST | flags[U2], antialiasing-strength[FP4] | Bit 0 of flags enables antialiasing; the strength sets the width of the sample filter |
PIXB | flags[U2] | Bit 0 enables pixel blending, which widens the filter when it would be smaller than one pixel |
STCK | on-off[U2], time[FP4] | Sticky projection: when on, a front projection is fixed at the given time |
TAMP | amplitude[FP4], envelope[VX] | For bump layers, scales the bump height from the pixel values; default 1.0 |
| PROJ | Projection |
|---|---|
| 0 | Planar: along the major axis |
| 1 | Cylindrical: wrapped around the major axis, the image’s horizontal coordinate following longitude |
| 2 | Spherical: wrapped around the major axis, by longitude and latitude |
| 3 | Cubic: planar along whichever axis the surface’s normal is closest to |
| 4 | Front projection: onto the current camera’s view plane |
| 5 | UV: by the coordinates in the block’s VMAP |
PROC – Procedural textures
| Sub-chunk | Layout | Meaning |
|---|---|---|
AXIS | axis[U2] | The procedural’s axis, 0, 1 or 2, if it has one |
VALU | value[FP4] # (1, 3) | The other value the texture modulates towards: one number or three |
FUNC | algorithm-name[S0], data | The procedural’s name, often a plug-in’s, and its parameters, which belong to it |
GRAD – Gradients
A gradient maps an input value through a line of colour keys.
| Sub-chunk | Layout | Meaning |
|---|---|---|
PNAM | parameter[S0] | The input: “Previous Layer”, “Bump”, “Slope”, “Incidence Angle”, “Light Incidence”, “Distance to Camera”, “Distance to Object”, “X Distance to Object”, “Y Distance to Object”, “Z Distance to Object” or “Weight Map” |
INAM | item-name[S0] | The scene item the input is measured from, where needed |
GRST | input-range[FP4] | Start of the input range, for display only |
GREN | input-range[FP4] | End of the input range, for display only |
GRPT | repeat-mode[U2] | Repeat mode; not yet defined |
FKEY | ( input[FP4], output[FP4] # 4 )* | The keys: an input value and an RGBA output each. Between keys the output is interpolated; beyond the ends it is the nearest key’s |
IKEY | interpolation[U2] * | For each key, the interpolation of the span before it: 0 linear, 1 spline, 2 step |
SHDR – Shaders
Shaders run after all channels and texture layers, in ordinal order. Their header
uses only ENAB, and one sub-chunk describes them:
| Sub-chunk | Layout | Meaning |
|---|---|---|
FUNC | algorithm-name[S0], data | The shader’s name, often a plug-in’s, and its data |