GUIDE 06 · SHADERS

Custom surfaces.
Engine lighting intact.

Shader graphs replace the material surface calculation while reusing Glint's static or skinned vertex path, PBR lighting, HDR environment, punctual lights, fog, and shadows.

Author a typed JSON graph

assets/shaders/hologram.shadergraph.jsonJSON
{
  "nodes": [
    { "id": "base", "type": "baseTexture" },
    {
      "id": "tint",
      "type": "parameter",
      "properties": {
        "name": "tint",
        "default": [0.08, 0.75, 1.0, 1.0]
      }
    },
    {
      "id": "tinted",
      "type": "multiply",
      "inputs": { "a": "base", "b": "tint" }
    },
    { "id": "rough", "type": "constant",
      "properties": { "value": 0.25 } }
  ],
  "output": {
    "baseColor": "tinted",
    "roughness": "rough"
  }
}

Graphs can use UV, time, world position/normal/view direction, arithmetic, combine/split nodes, parameters, custom textures, Fresnel, and procedural noise. Outputs include base color, opacity, emissive, metallic, roughness, and world-space normal.

Compile with a build hook

hook/build.dartDART
import 'package:glint_engine/shader_graph_build.dart';
import 'package:hooks/hooks.dart';

Future<void> main(List<String> arguments) async {
  await build(arguments, (input, output) async {
    await buildGlintShaderGraphBundle(
      buildInput: input,
      buildOutput: output,
      bundleName: 'glint_materials',
      graphs: const {
        'HologramFragment':
          'assets/shaders/hologram.shadergraph.json',
      },
    );
  });
}

The hook validates graphs, generates fragment source, and asks Impeller to compile a multi-backend shader bundle. There is no runtime GLSL compiler.

Include the generated bundle

pubspec.yamlYAML
flutter:
  assets:
    - assets/shaders/hologram.shadergraph.json
    - build/shaderbundles/glint_materials.shaderbundle

Keep the graph JSON available when you construct the runtime program. The binary bundle contains the compiled GPU entry point.

Create a runtime material

hologram_material.dartDART
final graph = GlintShaderGraph.parse(
  await rootBundle.loadString(
    'assets/shaders/hologram.shadergraph.json',
  ),
);
final program = const GlintShaderGraphCompiler().compile(graph);

final hologram = GlintShaderGraphMaterial(
  bundleAsset: 'build/shaderbundles/glint_materials.shaderbundle',
  fragmentEntry: 'HologramFragment',
  program: program,
  parameters: const {
    'tint': [0.08, 0.75, 1.0, 1.0],
  },
);

final instance = GlintGameInstance(
  model: 'character',
  animationPose: pose,
  shaderMaterial: hologram,
);

The same material interface supports static and skinned instances. Pipeline caching includes bundle, entry point, and vertex layout.

Validate in CI or an editor

TerminalSHELL
dart run glint_engine:glint_shader_graph \
  assets/shaders/hologram.shadergraph.json \
  /tmp/hologram.frag

The CLI checks parsing, node ids, edge references, value types, cycles, parameter limits, texture limits, and required outputs without starting a Flutter application.

Design within predictable limits

Parameters

Up to 16 graph parameters per material.

Textures

Up to 8 custom graph textures in addition to the authored base texture.

Compilation

Offline only through Impeller shader bundles; runtime source mutation requires a rebuild.

PBR context

Engine lights, shadows, HDR IBL, fog, base texture, and skinned/static vertex paths remain available.