glitcher-api 0.1.0

WebAssembly Interface Types for Glitcher Engine plugins
Documentation

Glitcher API

WebAssembly Interface Types for Glitcher Engine render node plugins.

Overview

This crate provides the WIT-generated Rust types that define the contract between the Glitcher Engine host and WASM plugins. Plugins act as "Definition Providers" - they supply node metadata and WGSL shader source code.

Architecture

WASM Plugin (Guest)          Glitcher Engine (Host)
┌─────────────────┐          ┌─────────────────────┐
│ get-manifest()  │────WIT──>│ Load metadata       │
│ get-shader()    │────WIT──>│ Compile WGSL        │
└─────────────────┘          │ Execute on GPU      │
                             └─────────────────────┘

Usage

For Plugin Authors (Guest)

use glitcher_api::*;

wit_bindgen::generate!({
    world: "plugin",
    exports: {
        "glitcher:engine/render-node": MyNode,
    }
});

struct MyNode;

impl Guest for MyNode {
    fn get_manifest() -> NodeManifest {
        NodeManifest {
            api_version: 1,
            display_name: "My Effect".into(),
            model: ExecutionModel::FragmentShader,
            parameters: vec![
                ShaderParam {
                    name: "strength".into(),
                    data_type: ParamType::F32,
                    widget: WidgetConfig::Slider(SliderConfig {
                        min: 0.0,
                        max: 1.0,
                        step: 0.01,
                    }),
                }
            ],
            textures: vec![
                TexturePort {
                    name: "input".into(),
                    binding_slot: 0,
                    writable: false,
                }
            ],
            output_resolution_scale: 1.0,
        }
    }

    fn get_shader_source() -> String {
        r#"
        struct Params {
            strength: f32,
        }

        @group(1) @binding(0) var<uniform> params: Params;
        @group(2) @binding(0) var input_texture: texture_2d<f32>;

        @fragment
        fn fs_main(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
            // Your shader code here
            return textureSample(input_texture, sampler, uv);
        }
        "#.into()
    }
}

For Host Implementation

use glitcher_api::*;
use wasmtime::*;

// Load and instantiate WASM plugin
let module = Module::from_file(&engine, "plugin.wasm")?;
let instance = linker.instantiate(&mut store, &module)?;

// Call WIT functions
let get_manifest = instance
    .get_typed_func::<(), NodeManifest>(&mut store, "get-manifest")?;
let manifest = get_manifest.call(&mut store, ())?;

// Validate and use manifest
assert_eq!(manifest.api_version, 1);

Type System

All types are strongly typed through WIT, eliminating string-based parsing:

  • [ParamType]: WGSL-compatible parameter types (f32, vec3, mat4, etc.)
  • [WidgetConfig]: UI widget configurations (slider, color-picker, etc.)
  • [ExecutionModel]: Fragment shader or compute shader
  • [NodeManifest]: Complete node definition

Memory Layout

The host calculates GPU buffer layouts using std140 rules based on [ParamType]. Plugins don't need to worry about alignment or padding.

Binding Conventions

Shaders must follow these binding group conventions:

  • Group 0: System globals (time, resolution, mouse) - Host-managed
  • Group 1: Node parameters - Single uniform buffer at binding 0
  • Group 2: Textures - Bindings match [TexturePort::binding_slot]

API Versioning

The [NodeManifest::api_version] field ensures compatibility:

  • Current version: 1
  • Host rejects plugins with mismatched versions
  • Breaking changes increment the version number