surfaceMaterialToJson function
surface's own scalar and colour fields, keyed the way writeFmat nests
them into a .fmat — everything but its texture slots, which
surfaceMaterialFromJson takes as separate, already-resolved arguments
rather than reading here.
doc-25's own remaining half, once mat-01 absorbed the rest: the
one place these eleven field names and shapes are spelled out, so a
material editor's own SetMaterialField and this format's own writer
cannot drift the way two hand-written lists of the same fields always
eventually do.
Texture slots stay out on purpose. SurfaceMaterial holds a
TextureBinding for each, but a binding's own imageIndex only means
anything against the MaterialDocument it came from — resolving a path
to one, or interning a new one, is a whole document's business, not one
material's, which is why readFmat still does that part itself before
handing the result to surfaceMaterialFromJson.
Implementation
Map<String, Object?> surfaceMaterialToJson(SurfaceMaterial surface) =>
<String, Object?>{
if (surface.name != null) 'name': surface.name,
'baseColor': <double>[
_cleanFloat32(surface.baseColor.r),
_cleanFloat32(surface.baseColor.g),
_cleanFloat32(surface.baseColor.b),
_cleanFloat32(surface.baseColor.a),
],
if (surface.metallic != 0.0) 'metallic': surface.metallic,
if (surface.roughness != 0.5) 'roughness': surface.roughness,
if (surface.normalScale != 1.0) 'normalScale': surface.normalScale,
if (surface.occlusionStrength != 1.0)
'occlusionStrength': surface.occlusionStrength,
if (surface.emissive.length2 != 0.0)
'emissive': <double>[
_cleanFloat32(surface.emissive.r),
_cleanFloat32(surface.emissive.g),
_cleanFloat32(surface.emissive.b),
],
if (surface.emissiveStrength != 1.0)
'emissiveStrength': surface.emissiveStrength,
if (surface.alphaMode != SurfaceAlphaMode.opaque)
'alphaMode': surface.alphaMode.name,
if (surface.alphaCutoff != 0.5) 'alphaCutoff': surface.alphaCutoff,
if (surface.doubleSided) 'doubleSided': true,
if (surface.unlit) 'unlit': true,
if (surface.lightingModel case final LightingModel model)
'lightingModel': _writeLighting(model),
};