Skip to main content
Glama
README.md
<p align="center">
  <img src="./assets/banner.png" width="100%" alt="TAIGA Texture">
</p>

<p align="center"><code>deterministic procedural materials · browser workbench · CLI · MCP</code></p>

---

> **TAIGA Texture** is a compact procedural-material laboratory with a deterministic **Texture DSL** that can be authored by people or driven by an LLM.

**TTX** is the technical shorthand taken from **Taiga TeXture**. It names the file format and toolchain; the language itself is called **Texture DSL**.

Edit materials in the browser, inspect PBR channels and a cube preview, then automate the same engine through the CLI or MCP.

## `[ MATERIAL GALLERY ]`

<table>
  <tr>
    <td align="center"><img src="./assets/gallery/crackle-ceramic.png" width="220"><br><sub>CRACKLE CERAMIC</sub></td>
    <td align="center"><img src="./assets/gallery/saddle-leather.png" width="220"><br><sub>SADDLE LEATHER</sub></td>
    <td align="center"><img src="./assets/gallery/quarter-sawn-oak.png" width="220"><br><sub>QUARTER-SAWN OAK</sub></td>
  </tr>
  <tr>
    <td align="center"><img src="./assets/gallery/granite.png" width="220"><br><sub>GRANITE</sub></td>
    <td align="center"><img src="./assets/gallery/waxed-canvas.png" width="220"><br><sub>WAXED CANVAS</sub></td>
    <td align="center"><img src="./assets/gallery/rusted-steel.png" width="220"><br><sub>RUSTED STEEL</sub></td>
  </tr>
</table>

## Features

- **Texture DSL** — pure, forward-only fields with deterministic seeds and compile-time cost limits.
- **Material workbench** — live source editing, PBR channel views, tiling checks, parameter sliders, and an interactive studio-lit cube.
- **PBR ZIP export** — download the current browser material as Base Color, Height, OpenGL Normal, Roughness, Metallic, metadata, and its `.ttx` source.
- **Procedural library** — ceramic, leather, stitched leather, oak, granite, canvas, rusted steel, marble, and multiscale parched earth.
- **LLM tool surface** — structured validation diagnostics, deterministic analysis, PNG rendering, multiscale inspection, CLI, and stdio MCP.
- **No runtime packages** — the browser workbench is one HTML file; the automation tools use Node.js built-ins.

## Run locally

Clone the repository and open [`ttx-bench.html`](./ttx-bench.html) in a WebGL 2 capable browser.

```bash
git clone https://github.com/kawaiiTaiga/taigas-texture.git
cd taigas-texture
```

On Windows:

```powershell
Start-Process .\ttx-bench.html
```

Optional verification:

```bash
npm test
```

### Export to Blender, Unity, Unreal, or Godot

In the browser workbench, choose the preview resolution and press **PBR export → download .zip**. The archive contains five standard PNG maps, `material.json`, a short integration note, and the authoritative `.ttx` source.

Use Base Color as sRGB. Load Height, Normal, Roughness, and Metallic as Non-Color/Linear data. The normal map follows OpenGL (+Y); invert its green channel for a DirectX normal workflow.

## CLI

```bash
# Discover bundled and library materials
node ttx-cli.mjs examples --json

# Validate one example
node ttx-cli.mjs validate --example saddle --json

# Render PBR views
node ttx-cli.mjs render --example ceramic --out renders/ceramic --resolution 256 --json

# Inspect the same point across scales
node ttx-cli.mjs render-scales materials/parched-earth.ttx \
  --out renders/parched-earth --zooms 1,4,16,64 --center 0.5,0.5 --json
```

## MCP

Start the dependency-free stdio server:

```bash
node ttx-mcp-server.mjs
```

Example MCP configuration:

```json
{
  "mcpServers": {
    "taigas-texture": {
      "command": "node",
      "args": ["<ABSOLUTE_PATH>/ttx-mcp-server.mjs"]
    }
  }
}
```

Exposed tools:

- `list_material_examples`
- `get_material_example`
- `validate_material`
- `render_material`
- `render_material_multiscale`

## Material example

```ttx
seed = 17
tile = 1
var glaze_h = 0.53

field cells = worley(u, v, freq=15, jitter=1, out=edge, seed=3)
field crack = 1 - smoothstep(0.004, 0.052, cells)
field h = clamp(0.52 - 0.11*crack, 0, 1)

out height = h
out albedo = hsv(glaze_h, 0.42, 0.72*(1 - 0.48*crack))
out rough = clamp(0.20 + 0.44*crack, 0, 1)
out metal = 0
```