Skip to content

Reusable materials ​

Read time 8 minutes

Authored materials support up to 26 named numeric properties. Constant data must fit the retail runtime's 1008-byte aligned limit; oversized or misaligned exports are rejected before packaging. Photo-mode luminance uses padding beside texture tiling and does not extend that buffer.

Use one .ltsurface graph for shader logic and create .ltmaterial files for different appearances. Each material stores a reference to the master and only its overridden properties, texture paths and surface settings.

For an existing specialized shader, choose a native .material as the master instead. This preserves its glass, hair, skin or water-effect shader programs while giving the instance independent constants, textures and render fields.

Create and edit ​

  1. Open or create a Material Surface in the Asset Wizard. Use property nodes for values that materials should customize, and texture nodes for texture inputs. Literal nodes and graph connections remain controlled by the master.
  2. Save the surface. Saving older graphs assigns persistent parameter IDs.
  3. Click Create Material… in the surface toolbar. Alternatively choose Material in the Asset Wizard and select the saved master .ltsurface.
  4. Enable Override beside a property, texture or field to edit it. Reset restores inheritance for that row; Reset All removes all local overrides. Color pickers display sRGB and store linear RGB values. Numeric controls use the master node's range, step, suffix and precision.
  5. Save the .ltmaterial. Use Open Master to edit shared logic. Dependent material tabs refresh when the saved master changes. Unsaved master edits remain in the master tab until saved. Refresh Master retries manually.

The preview uses the same sphere/model, scene and render controls as surface graphs. Numeric preview changes reuse compiled programs and update independent constant data. Texture replacements can reuse compatible compiled shader slots; the renderer reloads their bindings. Structural changes rebuild the preview.

Named properties, including custom property node definitions, are editable. Texture nodes in the master are editable by stable identity too. Embedded subgraph internals and literal nodes are not instance parameters. Texture paths must reference native .texture assets; use a texture project to build images. Field controls cover texture tiling and lit/unlit shading, plus native draw distance, shadow bias, voxel order bias and screen-space reflection gloss range. Native fields apply on export. Leave them unchecked to preserve the destination material's settings; a new asset inherits the build profile's settings. Reflection thresholds use 0–1 controls and are stored with 8-bit precision. The maximum must exceed the minimum after quantization, or both can be zero for engine defaults. Reset removes an override without changing shared shader logic.

Stage layout and export ​

The Asset Wizard uses the normal authoring layout:

text
MyStage/
  info.json
  sources/
    materialgraphs/shared.ltsurface
    materials/red.ltmaterial
    materials/blue.ltmaterial
  0/
    materials/red.material
    materials/blue.material
    materialgraph/lunatools/surfaces/<content-hash>.materialgraph

For a material inside the active stage's sources folder, Export Game Material… suggests the corresponding path under 0. Choose the asset path referenced by the target model; creating a material does not automatically change a model's assignments. Native export requires the existing Windows shader tools and supported game shader data. Luna can prepare its build profile from the loaded game TOC, using its existing toc.BAK if a mod replaced the source asset. This writes an application cache and leaves game files untouched. A separately supplied certified profile also works. See local data.

Use Shared shader under Game export and click Export Game Material… for each appearance, then export the stage. Export saves the material source's current edits. Each native material contains its own values and texture overrides and references a shared compiled .materialgraph. Luna writes that dependency inside span 0 automatically. Materials using the same master and shading mode share it; changing instance colors, numeric values, texture paths or tiling does not create another shader template. Lit/unlit is a shader variant.

The first export builds Forward, GBuffer and Voxel for SM5 and DXIL, together with an authored RT hit library. Further compatible exports reuse the editor's recent game program cache; a new session or an evicted program needs compilation again. Existing material render settings are preserved from the selected native output, or from the loaded game TOC for that asset path. A new asset uses the supported build profile's settings, then applies explicit native field overrides. Both shared and baked instance exports preserve these settings. Choose the right profile and model assignment; this feature does not make arbitrary shader families interchangeable.

Baked material (compatibility) uses the existing self-contained material export. Different effective numeric values require different compiled variants. Direct export from the surface graph editor also keeps this baked behavior.

For shared exports outside the active stage, select the asset root that contains the material's logical game path. Luna creates the materialgraph dependency folder under that root. Keep both assets together when moving them into a stage. For normal stage work, save sources inside that stage's sources folder first.

Each export writes a .material.build.json report alongside the native output. For stage materials, that report identifies the source and resolved build. Stage packaging rejects missing builds, changed sources/masters, changed native outputs and missing, changed or mismatched shared templates. Save and export affected materials again. Visual node rearrangement does not invalidate an otherwise unchanged build. Keep reports with the project; they, authoring sources and the sources folder are excluded from installable stage archives. Failed builds preserve the previous native output, dependency and report. Shared templates use content-derived paths to avoid overwriting another shader. Existing identical templates are reused. Old template files are retained locally so other outputs remain valid; Luna does not delete assets.

References and master changes ​

Stage references are logical paths, resolved in the active stage's sources folder before legacy copies in span 0. Without an active stage, a saved material can discover its containing stage through info.json. Move the whole stage together to preserve those references. Local materials use paths relative to the .ltmaterial; Save As rebases those paths and its undo history.

Each exposed node has a persistent parameter_id. Renaming a property preserves its override. Copying a node creates a new identity. Removing a property, changing its type or narrowing its valid range preserves incompatible overrides as visible issues. Export stays disabled until the material's overrides are reset or corrected. Locate Master… recovers a moved or missing master. Only one master level is supported. A master can be a .ltsurface graph or native .material; a .ltmaterial cannot inherit from another .ltmaterial.

Try the synthetic red and blue examples, which share one surface.

Reuse a native shader ​

  1. In Asset Wizard → Material, set Material master type to Native game material (.material). Choose a game, staged or local material as the master.
  2. Save the .ltmaterial in the stage's sources folder. Its inspector shows inherited numeric constants and texture slots. Native files identify numeric slots by hashes, so their original hashes are shown instead of guessed names. Vectors stay numeric; they are not assumed to be colors. Enable Override to change a slot; Reset restores the master value.
  3. Native masters also expose Opacity and Alpha test threshold, alongside the usual instance render fields. Their behavior follows the master's blend and cutout shader; changing opacity does not turn an opaque shader into glass.
  4. Export Game Material… uses Native shader (preserve) automatically. It edits only instance values and explicit header fields. Shader bytes, shader variations, engine globals and unknown sections remain intact. This needs no shader compiler and preserves the master's specialized rendering behavior.

A native master can be game-relative (master_scope: "game"), stage-relative or relative to the source file. Stage assets take precedence over the loaded TOC when resolving native references. Game masters require that game's TOC to be loaded. Keep local master files and any custom shader templates with the project; keep custom runtime templates under span 0 when packaging them. Unchanged stock templates stay game references and are not duplicated in the stage.

The native inspector can preview the master's existing Forward shader where the renderer supports it. Refraction, special lighting, water simulation and other game-only passes still require the game. An unavailable Forward preview produces a diagnostic and does not replace the native shader with an opaque shader. Unsupported effect-parameter table edits are rejected before publication. Native masters whose serialized constant widths differ from their template declarations are currently rejected as well. This occurs with some original suit materials; support for a native shader family does not imply every material using it is accepted.

Native reuse customizes an existing shader; adding new glass/hair/skin BRDF logic to a surface graph is a separate backend capability. Authored .ltsurface exports continue to target opaque surfaces.

Gameplay and scene inputs ​

Authored graphs bind camera position/direction, object position/scale, player position/speed, world weather values, photo-mode luminance and time of day. Object scale is the length of each object-to-world basis axis, not bounding-box dimensions. Player position uses the native engine global already declared by the profile; its fourth component is movement speed. The old Heading port remains as a speed alias so existing connections are preserved.

Weather exposes surface wetness, surface density, weather particle density and wind-vector magnitude from the world shader buffer. These are not independent rain-only measurements. Photo-mode luminance uses a native material-global declaration and defaults to one when the engine has not supplied a value. Engine globals remain live in baked exports too. The standalone preview uses its own scene constants and cannot simulate the player's live game state.

Imported definitions without verified bindings are labeled (source only) in the node library and rejected if connected during export. This includes melee impact, actor wet height, ambient temperature, world position, vertex color and hero mask. Time of Day supplies the verified time input separately from the older Atmosphere definition. Native shader reuse preserves an existing shader's own inputs; it does not add those missing bindings to authored surface graphs.

Luna Tools Documentation