builtInMaterialHints top-level property
Hints for the fields every material has, held here rather than written into every file.
Why the engine keeps this and .fmat does not. The fields below are the
same in every material ever authored: roughness runs nought to one in all of
them, and baseColor is a colour in all of them. Writing that into each file
would put a hundred lines of identical text in front of the six lines an
artist actually edits, and the readable diff is the property the format was
chosen for. A file carries hints only for the parameters this table cannot
know about — the ones a studio's own shader declares.
So an inspector reads a field's hint from here and a parameter's from MaterialDocument.hints, and a field the table says nothing about is shown however the inspector shows an unhinted number.
Implementation
final Map<String, MaterialHint> builtInMaterialHints = <String, MaterialHint>{
'baseColor': const MaterialHint(
ColorHint(),
label: 'Base colour',
help: 'The colour the surface is painted, and its opacity.',
),
'metallic': const MaterialHint(
RangeHint(0.0, 1.0, step: 0.01),
label: 'Metallic',
help:
'Nought is a dielectric, one is bare metal. The values between the '
'two describe no real material and are there for blending between them.',
),
'roughness': const MaterialHint(
RangeHint(0.0, 1.0, step: 0.01),
label: 'Roughness',
help: 'How wide the highlight spreads. Nought is a mirror.',
),
'occlusionStrength': const MaterialHint(
RangeHint(0.0, 1.0, step: 0.01),
label: 'Occlusion strength',
help: 'How much of the occlusion map is applied. Nought ignores it.',
),
'occlusionAffects': MaterialHint(
EnumHint(<EnumHintValue>[
for (final affects in OcclusionAffects.values)
EnumHintValue(
affects.name,
label: switch (affects) {
OcclusionAffects.both => 'All light',
OcclusionAffects.direct => 'The lights only',
OcclusionAffects.indirect => 'Ambient and reflections only',
_ => affects.name,
},
),
]),
label: 'Occlusion darkens',
help:
'Which light the occlusion map takes away. A map of the sun\'s '
'visibility darkens the lights only.',
),
'normalScale': const MaterialHint(
RangeHint(0.0, 1.0, step: 0.01),
label: 'Normal scale',
help: 'How far the normal map is allowed to tilt the surface.',
),
'emissive': const MaterialHint(
ColorHint(channels: 3),
label: 'Emissive',
help:
'The colour the surface glows in. It has no alpha: a surface does '
'not glow transparently.',
),
// The enums are derived from the lists the engine already keeps rather than
// spelled out again. `SurfaceAlphaMode.values` in a `switch` with no default
// is what makes a fourth mode a compile error here instead of a picker that
// quietly cannot offer it; `LightingModel.builtIn` is described where it is
// declared as the list a picker should show, and this is that picker.
'alphaMode': MaterialHint(
EnumHint(<EnumHintValue>[
for (final mode in SurfaceAlphaMode.values)
EnumHintValue(
mode.name,
label: switch (mode) {
SurfaceAlphaMode.opaque => 'Opaque',
SurfaceAlphaMode.mask => 'Cut out at the threshold',
SurfaceAlphaMode.blend => 'Blended',
_ => mode.name,
},
),
]),
label: 'Alpha',
),
'lightingModel': MaterialHint(
EnumHint(<EnumHintValue>[
for (final model in LightingModel.builtIn)
EnumHintValue(model.shaderName, label: model.label),
]),
label: 'Shader',
help:
'The shaders this engine ships. A material may name one of its own '
'instead, and must then say what that shader binds.',
),
};