The .drft container · interface
MeshData
A description of vertex data, and the check that it is coherent.
Explained in The .drft container.
interface MeshDataimport type { MeshData } from '@driftengine/drft';In depth
It lives in the format package rather than the renderer because it is the boundary object
between them: the container's whole job is to carry one of these, and every import the
format code took from render was this type or its validator. Putting it here is what lets
the container be read and written by something that never draws.
The renderer re-exports both, so nothing that consumed them from there has to move.
Properties
| Name | Type | Description |
|---|---|---|
positions | Float32Array | |
normals | Float32Array | |
colors | Float32Array | |
emissive | Float32Array | One float per vertex: self-illumination, revealed only at night. |
specularoptional | Float32Array | One float per vertex, 0–1: how sharply this surface takes a sun highlight.MoreOptional, and that is a cost decision rather than a convenience one. Seventeen
places build a |
tangentsoptional | Float32Array | Four floats per vertex: a tangent, and the handedness of the bitangent in w.MoreOptional for the same cost reason as
|
uvsoptional | Float32Array | Two floats per vertex: where this vertex sits in a surface texture.MoreOptional for the same cost reason as Only meaningful alongside a |
emissiveColoroptional | Float32Array | Three floats per vertex: the colour this vertex emits, independent of its albedo.MoreOptional, and absent means what this engine always did — the emissive term is the
surface's own colour scaled by A negative component means "inherit the albedo", which is what an absent array supplies for every vertex — so a mesh that names a colour for some of its geometry and not the rest is one buffer rather than two meshes. |
roughnessoptional | Float32Array | One float per vertex, 0–1: how rough this surface is, which is the shape of its
highlight rather than its strength.MoreAbsent means the old constant, so nothing existing changes. It matters because a
highlight's width is not something intensity can express: a polished floor seen at a
grazing angle smears a lamp into a long streak down the view direction, and a tight
fixed lobe can only ever make a small round dot brighter. |
grainoptional | Float32Array | One float per vertex, 0–1: how much visible mineral structure this surface has.MoreAbsent means none, which is the one thing the previous two attempts could not say.
Grain was first gated on So it is its own attribute, exactly as |
reliefoptional | Float32Array | How much microscopic relief a surface has, 0 to 1. Absent means a perfectly smooth one.MoreThe sibling of Absent means none, so every mesh built before this existed is unchanged. How coarse the
relief is and how strong belongs to the material rather than the geometry, since that is what
separates asphalt from plaster, and the pass states it: see |
lightmapUvsoptional | Float32Array | A second set of texture coordinates, two floats a vertex, for a baked lightmap: where on its
page a surface's baked light is, as a material made with lightmapModel reads it. Absent means
a mesh nothing has baked light for.MoreIt rides the grain and relief attributes, which a lightmapped surface gives up: a renderer's vertex attributes and the stage's inter-stage values are spent to the last one, and baked stage geometry carries neither procedural grain nor relief. So a mesh with any grain or relief that is not zero is refused with these, rather than one of the two quietly lost; lanes of zeros, which a builder writes for every mesh, are what a surface without either carries. |
layersoptional | Float32Array | Which image of a texture array each vertex's face wears: one whole number a vertex, 0 the first
layer. Absent means layer 0, which is the only layer a plain texture has.MoreWhat it is for is a merged mesh wearing many images in one draw. A block of forty buildings
with forty facades is forty materials — forty draws, forty material changes — when each image
is its own texture; with the facades as the layers of one array and each face naming its layer,
it is one. It travels in the texture-coordinate attribute, as its third component, because all
sixteen of WebGL2's guaranteed vertex locations are spent in the instanced variant. So it needs
Whole numbers, checked, because the shader rounds to the nearest layer and a 1.5 would land on whichever side rounding favoured on that device. |
channeloptional | Float32Array | Four floats per vertex, and the only attribute whose lanes mean four different things.More
One attribute and not three, because locations are the scarce resource here. WebGL2
guarantees sixteen vertex attribute locations, eleven are already spent, and an instanced
draw spends all sixteen. A
Absent means Sway is authored, not derived. |
jointsoptional | Float32Array | Four floats per vertex: which joints move this vertex, as indices into a skinning palette.MoreOptional for the same cost reason as every attribute above it, and the reason is strongest here: only a skinned character has any use for one, and a world of walls and props allocates nothing and uploads nothing. Absent means unskinned, and an unskinned mesh takes exactly the draw path it took before skinning existed. Four here, and four more in
|
weightsoptional | Float32Array | Four floats per vertex: how much each of joints' four influences moves this vertex.MoreNormalised by the importer rather than by the shader, because normalising per vertex per frame
costs a divide on every vertex to correct data that should have been fixed once. Absent means unskinned, and it must be absent exactly when |
joints2optional | Float32Array | Four floats per vertex: the fifth to eighth joints that move this vertex, for a rig authored with
eight influences. The same encoding as joints, and the same both-or-neither with weights2.MorePresent only with |
weights2optional | Float32Array | Four floats per vertex: how much each of joints2' influences moves the vertex. |
morphTargetsoptional | Float32Array | Morph target position deltas: morphTargetCount targets, three floats a vertex each.MoreLaid out interleaved by vertex — every target of one vertex adjacent — because the shader
reads all of a vertex's targets together and nothing reads one target across many vertices.
So the index of target A delta rather than an absolute position, which is what makes them additive: several targets apply at once by weight, and a weight of zero contributes nothing rather than dragging the vertex toward some other shape. Positions only. A target that also moved normals would double this array and add a second fetch per target in the vertex stage; what it gives up is shading that lags a strongly morphed surface. What would make it wrong is a face rig, where the lighting is most of the effect. |
morphTargetCountoptional | number | How many targets morphTargets holds. Absent means none, whatever the array says. |
indices | Uint32Array |