Model loading · interface

DrftPart

Explained in Importing models.

interface DrftPart
import type { DrftPart } from '@driftengine/assets';

Properties

NameTypeDescription
meshreadonlyMeshHandle
albedoreadonlynumberWhich of the asset's images this surface wears, or -1 for none.
ormreadonlynumberWhich image carries its occlusion, roughness and metallic, or -1 for none.
normalreadonlynumberWhich image carries its surface-space normals, or -1 for none.
More

Carried by the container since MATL reached stride 72 and dropped here until 2026-08-23, which is the whole of why a bought model looked smoother than the one its maker shipped: the baker wrote the index, the reader read it, the renderer has taken a normal map through SurfaceMaterial.normal since normal maps landed, and this was the one step that did not pass it on. Panel seams, stitching, tread and every other detail an exporter bakes into a normal map rather than into geometry was arriving and going nowhere.

emissivereadonlynumberWhich image carries its emission, or -1 for none.
More

The fourth and last index MATL carries, passed on from 2026-08-24. It was written by the baker, read by the reader and dropped here for the same stretch the normal map was — but for a stated reason rather than by oversight: no renderer took an emissive map until now, so there was nowhere to pass it. SurfaceMaterial.emissive is that somewhere.

roughnessScalereadonlynumberglTF's three factors, in the shape SurfaceMaterial takes them.
More

Carried on the part rather than looked up from the material, because a caller building a setMaterial call has the part and not the index that produced it.

metallicScalereadonlynumber
occlusionStrengthreadonlynumber
opacityreadonlynumber
reflectivityreadonlynumber
cutoutreadonlynumberAlpha below which this surface's fragments are discarded, 0 for one that discards nothing.
More

The pair to opacity and not a weaker version of it: a cutout decides which texels of the surface exist, an opacity decides how much light passes through the ones that do. It is what SurfaceMaterial.cutout takes, and until MATL grew the field there was no way for a source format to say it — a masked grille arrived as a solid rectangle, and a vehicle format's alpha test was being spent on the opacity, which drew nine surfaces of a hundred and two as nothing at all.

blendreadonlybooleanWhether the part blends: its texture's alpha is coverage, so it is drawn translucent whatever its opacity says. glTF's BLEND with a factor of 1 is the case: a leaf's shape is in its alpha.
doubleSidedreadonlybooleanWhether both faces are seen: glTF's doubleSided. Drawn without culling, each face lit as the front.
glassreadonlyGlassOptions | nullThe glass this part is, from its file or from DrftLoaderOptions.surface, or null for a part that lets no light through. A glass part is also blend, so a caller drawing blended parts translucent passes this as the draw's glass and every pane arrives as the file or the override said. One object per merged group, shared by its parts, so it is not rebuilt per draw.
instancesreadonlyDrftPartInstances | nullThe copies this part is drawn as, or null for a part drawn once.
More

A mesh the file places many times (INST, 1.18) is uploaded once and drawn through the engine's instanced path: drawInstanced(batch, data), and sink.instanced for a shadow. The placements are uploaded when the part is made and carry the fit, so a caller passes them as they are. Null for every part of a file with no instances, which is every file before 1.18.

revealnumber0 to 1 as this part arrives, for a caller that would rather it faded in than appeared.
More

Advanced by update, so it follows the frame's own clock and holds when the frame holds. A caller that wants parts to pop in can ignore it; one that wants a build fades on it.