Material Visualization from Layers

Use inline layer ... material { ... } properties when an FCS model should look good directly in the viewer, generated HiScene JSON, or rendered images. These visual materials live in the model script itself; they do not require a separate .fcsdrs draw-settings file.

This is especially useful for Golem-generated models: assign meaningful layers and give each layer a small material preset so surfaces read as metal, glass, timber, concrete, terrain, highlights, or translucent helper geometry.

1. Basic syntax

layer {steel} color Silver material {
    SurfaceColor := {R := 0.75, G := 0.78, B := 0.82},
    Roughness := 0.35,
    Metalness := 0.85,
    Side := "Front"
}

The material block is an attribute object parsed by the layer keyword:

layer {name} color SomeColor material { Property := value, Property2 := value2 }

Then assign geometry to the layer:

area {panel} boundary curve {c1} {c2} {c3} {c4} layer {steel}
volume {solid} boundary area {a1} {a2} {a3} layer {concrete}
gblock {part} gclass {partClass} lcs GCS layer {steel}

The layer color remains useful as a fallback and for pens/lines. SurfaceColor overrides the face/fill color used by the material.

2. Why layer materials are preferred for visual models

3. Recommended material presets

Steel / painted metal

layer {paintedSteel} color LightSteelBlue material {
    SurfaceColor := {R := 0.62, G := 0.68, B := 0.74},
    Roughness := 0.42,
    Metalness := 0.65,
    Side := "Front"
}

Use moderate roughness for painted steel. Use higher metalness and lower roughness only for polished metal.

Concrete

layer {concrete} color Gray material {
    SurfaceColor := {R := 0.55, G := 0.55, B := 0.52},
    Roughness := 0.85,
    Metalness := 0.0,
    Side := "Front"
}

Concrete should be rough and non-metallic.

Timber

layer {timber} color BurlyWood material {
    SurfaceColor := {R := 0.72, G := 0.48, B := 0.28},
    Roughness := 0.65,
    Metalness := 0.0,
    Side := "Front"
}

For simple generated models, a warm SurfaceColor is usually enough. Add texture maps only when the target viewer/runtime can resolve the URLs.

Glass / translucent panels

layer {glass} color LightCyan material {
    SurfaceColor := {R := 0.78, G := 0.92, B := 1.0},
    Transparent := True,
    Opacity := 0.32,
    Roughness := 0.05,
    Metalness := 0.0,
    Side := "Front"
}

Use Transparent := True with Opacity below 1.0. For glass, keep roughness low.

Ghost / helper geometry

layer {ghost} color LightGray material {
    SurfaceColor := {R := 0.75, G := 0.78, B := 0.82},
    Transparent := True,
    Opacity := 0.18,
    Roughness := 0.5,
    Metalness := 0.0,
    Side := "Double"
}

Use this for envelopes, clearance boxes, construction previews, and optional geometry. Double can be helpful for transparent helper surfaces that should be visible from both sides.

Emissive highlights

layer {selection} color Orange material {
    SurfaceColor := {R := 1.0, G := 0.55, B := 0.05},
    EmissiveColor := {R := 1.0, G := 0.28, B := 0.0},
    EmissiveIntensity := 0.35,
    Roughness := 0.4,
    Metalness := 0.0,
    Side := "Front"
}

Use emissive materials sparingly for selected parts, warnings, active elements, or light strips. Too much emissive intensity can flatten shading.

4. One-sided vs double-sided materials

Side controls which polygon side is rendered:

FCS value Scene value Use case
"Front" front Preferred default for closed solids and correctly oriented surfaces
"Back" back Rare; inside faces, section/cut views, or debugging orientation
"Double" double Thin sheets that must be visible from both sides, transparent helper surfaces

Prefer Side := "Front" for beautiful production models. It is faster and gives better visual cues for surface orientation. Use Double only when there is a real need: membrane sheets, signage, single-surface panels visible from both sides, or ghost/helper geometry.

5. Supported material properties

All properties are optional. Only specify what is meaningful for the material.

Property Type / example Meaning
Side "Front", "Back", "Double" Which side of faces is rendered
SurfaceColor {R := 0.7, G := 0.7, B := 0.7} Base material color; RGB components are 0.0 .. 1.0
MapUrl "textures/wood.jpg" Base color texture
MixMapWithSurfaceColor True Mix texture with SurfaceColor
EmissiveColor {R := 1.0, G := 0.4, B := 0.0} Self-lit color
EmissiveMapUrl "textures/glow.png" Emissive texture
EmissiveIntensity 0.4 Strength of emissive effect
Transparent True Enables transparency
Opacity 0.35 Alpha opacity; 1.0 opaque, 0.0 invisible
AlphaMapUrl "textures/alpha.png" Alpha texture
AlphaTest 0.5 Cutout threshold for alpha
AoMapUrl "textures/ao.jpg" Ambient occlusion texture
AoMapIntensity 0.8 Ambient occlusion strength
BumpMapUrl "textures/bump.jpg" Bump map texture
BumpScale 0.05 Bump map strength
NormalMapUrl "textures/normal.jpg" Normal map texture
NormalScale 0.5 Normal map strength
NormalMapType "TangentSpace" Normal map convention, viewer-dependent
DisplacementMapUrl "textures/height.jpg" Displacement texture
DisplacementScale 0.02 Displacement strength
DisplacementBias -0.01 Displacement offset
RoughnessMapUrl "textures/roughness.jpg" Roughness texture
Roughness 0.65 Surface microsurface roughness
MetalnessMapUrl "textures/metalness.jpg" Metalness texture
Metalness 0.0 Metallic factor
MicromeshSize 0.1 Fine mesh/material rendering hint
UvMappingType "Box" Texture mapping hint, viewer-dependent
TextureSize 2.0 or {X := 2.0, Y := 2.0, Z := 1.0} Physical/repeat texture size hint
PolygonOffsetFactor -1.0 Polygon offset factor for z-fighting control
PolygonOffsetUnits -4.0 Polygon offset units for z-fighting control

Boolean values in FCS use True / False.

6. Texture size and maps

TextureSize accepts either a single scalar or an object:

layer {brick} color Firebrick material {
    SurfaceColor := {R := 0.75, G := 0.22, B := 0.16},
    MapUrl := "textures/brick-basecolor.jpg",
    NormalMapUrl := "textures/brick-normal.jpg",
    RoughnessMapUrl := "textures/brick-roughness.jpg",
    Roughness := 0.8,
    Metalness := 0.0,
    TextureSize := {X := 2.0, Y := 1.0, Z := 1.0},
    Side := "Front"
}

Texture URLs must be resolvable by the renderer or viewer. For portable Golem examples, prefer good procedural colors and roughness/metalness values first; use texture URLs only when the deployment provides those texture files.

7. Avoiding z-fighting with polygon offset

Use polygon offset for decals, overlays, highlight faces, or coplanar helper surfaces:

layer {warningOverlay} color Orange material {
    SurfaceColor := {R := 1.0, G := 0.45, B := 0.0},
    Transparent := True,
    Opacity := 0.55,
    PolygonOffsetFactor := -1.0,
    PolygonOffsetUnits := -4.0,
    Side := "Front"
}

Negative offset values pull the overlay slightly toward the camera in typical WebGL usage and help prevent flickering against the underlying face.

8. Complete example

layer {roofMetal} color LightSteelBlue material {
    SurfaceColor := {R := 0.58, G := 0.64, B := 0.70},
    Roughness := 0.38,
    Metalness := 0.75,
    Side := "Front"
}

layer {wallPanel} color WhiteSmoke material {
    SurfaceColor := {R := 0.86, G := 0.86, B := 0.82},
    Roughness := 0.62,
    Metalness := 0.15,
    Side := "Front"
}

layer {windowGlass} color LightCyan material {
    SurfaceColor := {R := 0.75, G := 0.90, B := 1.0},
    Transparent := True,
    Opacity := 0.35,
    Roughness := 0.05,
    Metalness := 0.0,
    Side := "Front"
}

vertex {a} xyz 0 0 0
vertex {b} xyz 6 0 0
vertex {c} xyz 6 0 3
vertex {d} xyz 0 0 3

curve {ab} vertex {a} {b}
curve {bc} vertex {b} {c}
curve {cd} vertex {c} {d}
curve {da} vertex {d} {a}

area {wall} boundary curve {ab} {bc} {cd} {da} layer {wallPanel}

9. Golem guidance

When generating a model for visual quality:

  1. Create semantic layers first: steel, concrete, glass, timber, terrain, helper, highlight.
  2. Use SurfaceColor, Roughness, Metalness, and Side as the baseline material properties.
  3. Prefer Side := "Front" for normal closed solids and oriented faces.
  4. Use Transparent + Opacity for glass, ghost geometry, and construction envelopes.
  5. Use EmissiveColor/EmissiveIntensity only for highlights or active/warning elements.
  6. Use PolygonOffsetFactor/PolygonOffsetUnits for coplanar overlays.
  7. Do not rely on .fcsdrs for material identity; use .fcsdrs for camera, visibility, and general drawing style.

10. Validation

To check that materials survive into the scene, export or inspect the HiScene/ThreeJS JSON and look for materialData under face materials. For example, Side := "Front" serializes as:

{
  "materialData": {
    "side": "front"
  }
}

The renderer serializes material properties such as roughness, metalness, transparent, opacity, emissive, mapUrl, and polygonOffsetFactor into materialData.