Material graphs
A material asset can carry a typed node graph. The graph computes the surface’s base colour, roughness, metallic, emission, opacity and a vertex offset, and compiles to a shader. The editor, the command API, validation, previews and the runtime all use the same graph and the same compiler, so a graph built by hand and one built by an agent behave identically.
Materials without a graph keep the standard or toon path described in Materials.
Start from a template
Section titled “Start from a template”- Open Window → Materials & textures and select the Material Graph tab.
- Select a material, or click + New graph material.
- Open Templates ▾ and choose a template.
- Assign the material to objects as usual.
Applying a template replaces the material’s graph and sets the matching surface defaults (alpha, roughness, two-sided rendering and shading) in one undo step.
| Template | Result |
|---|---|
| Toon Basic | Constant colour and roughness with toon surface settings |
| Facade Windows | A window grid on walls, with some windows lit warm at night (Windows, Night) |
| Glowing Crystal | A rim glow (Fresnel Glow) |
| Dissolve | World-space noise animated over time |
| Hologram | Animated scan lines (Scanline) |
| Stylized Water | Animated world-space noise |
| Wind Foliage | Vertex sway (Wind Sway) |
| Lava | Animated world-space noise |
Clear graph removes the graph and returns the material to the standard path. Fit graph frames every node on the canvas.
Edit a graph
Section titled “Edit a graph”The workspace has the node palette on the left, the canvas in the centre, and a large live preview with the inspector and diagnostics on the right.
- Find a node in the Node palette, or type in Search nodes…. Fresnel Glow and Wind Sway are pinned as quick effect nodes.
- Add the node and drag it into place. Pan and zoom the canvas to navigate.
- Drag from an output pin to an input pin of the same type. Connecting to an input that already has a wire replaces the old wire.
- Select a node to edit its values in the inspector.
Pins and wires are colour-coded by type: Float, Vector2, Vector3 and Color. Every node shows a small preview, and the large preview renders the material with its compiled shader. The status line shows Compiled with the node count and shader size, or Compile error with the reason.
Every canvas edit goes through the same commands agents use, so each one is a single undo step and an invalid edit is rejected without changing the project.
Material Output
Section titled “Material Output”Each graph has exactly one Material Output node. Unconnected inputs keep the material’s own values.
| Input | Type | Description |
|---|---|---|
| Base Color | Color | Surface colour |
| Roughness | Float | |
| Metallic | Float | |
| Emissive | Color | Emitted light |
| Opacity | Float | Used with the Cutout and Transparent alpha modes |
| World Position Offset | Vector3 | Moves vertices, for wind and waves |
Node reference
Section titled “Node reference”| Group | Node | Outputs | Description |
|---|---|---|---|
| Constants | Scalar | Value | A float constant |
| Constants | Color | Color | An sRGB colour constant |
| Constants | Vector 2, Vector 3 | Vector | Vector constants |
| Inputs | Base Color | Color | The material’s colour and base texture after sampling |
| Inputs | Texture Coordinates | UV | Mesh UVs after the material’s UV tiling |
| Inputs | World Position | Position | Position in world metres |
| Inputs | Surface Normal | Normal | World-space normal |
| Inputs | Time | Seconds | Elapsed game time |
| Inputs | Night | Value | 0 in daylight, 1 at night, smooth through dusk and dawn |
| Math | Add, Subtract, Multiply, Divide, Lerp | Result | Typed as Float, Vector2, Vector3 or Color. Divide is safe against zero. Lerp blends A to B by Alpha |
| Math | Sine, One Minus | Result | Float operations |
| Math | Clamp | Result | Clamps a float between min and max |
| Math | Power | Result | Raises a non-negative float to exponent (0.01–32) |
| Math | Smoothstep | Result | Smooth threshold between low and high |
| Math | Posterize | Result | Quantizes a float into steps bands (2–32) |
| Effects | Noise | Value | Animated, seamless value noise in world space; scale, speed |
| Effects | Scanline | Value | Animated horizontal scan lines; scale, speed, width |
| Effects | Windows | Glass, Lit | A window grid on walls in world metres, none on roofs. Glass masks the panes; Lit picks windows to glow at night |
| Effects | Colorize | Color | Multiplies a colour by a float mask |
| Effects | Fresnel Glow | Color | Rim glow; color, power, strength |
| Effects | Wind Sway | Offset | World-position offset for foliage and cloth-like surfaces; direction, strength, speed, scale |
Fresnel Glow and Wind Sway have defaults on their optional inputs, so you can wire only their result. Time, Noise, Scanline and Wind Sway animate from a per-material clock. Combine Night with Windows → Lit and Emissive to light buildings after dark.
Runtime behaviour
Section titled “Runtime behaviour”Each graph material compiles to one shader. It keeps the material’s textures, alpha mode and lighting, and applies the graph’s outputs on top. A graph takes precedence over a toon shading setting; clearing the graph restores the normal path. Invalid graphs are reported during validation and never reach the renderer.
Limits
Section titled “Limits”- Up to 96 nodes and 192 wires per graph.
- Generated shader code is limited to 64 KiB.
- Each input takes one wire, pin types must match exactly, and cycles are rejected.
- Disconnected nodes are allowed, so you can build a graph step by step.
Automate it
Section titled “Automate it”Create a material from a template, add a Fresnel Glow node, and wire it into the emission. Use the material ID and node ID that each command returns:
feather-cli --connect .feather-session.json command material.create \ --json '{"name":"Crystal","graph_template":"Glowing Crystal"}'
feather-cli --connect .feather-session.json command material.add_node \ --json '{"id":1,"operation":{"type":"FresnelGlow","color":[0.2,0.8,1.0],"power":2.5,"strength":4.0},"position":[280,160]}'
feather-cli --connect .feather-session.json command material.connect \ --json '{"id":1,"from":20,"from_pin":"Color","to":1,"to_pin":"Emissive"}'| Command | Purpose |
|---|---|
material.nodes |
Lists the node palette with operation JSON, typed pins and templates; filter with query or group |
material.get |
With id, returns the graph, each node’s typed pins, the compiled WGSL and diagnostics |
material.add_node |
Adds a node; creates the Material Output graph when absent |
material.set_node |
Changes a node’s operation or position; wires to removed pins are dropped |
material.connect |
Wires an output pin to an input pin of the same type |
material.disconnect |
Removes a wire by edge, or the wires on a node and optional pin |
material.remove_node |
Removes a node and its wires; the Material Output cannot be removed |
material.create / material.update |
Apply a graph_template, or replace the whole graph |
See Agents & automation for connecting a live session.