Metadata-Version: 2.4
Name: vcti-shader-foundry
Version: 3.0.0
Summary: Shader artifact-set builder: composes the installed shader features into the pipeline matrix, drives the compiler, and emits the artifact set for VCollab renderers
Author: Visual Collaboration Technologies Inc.
License-Expression: LicenseRef-Proprietary
Project-URL: Repository, https://github.com/vcollab/vcti-python-shader-foundry
Project-URL: Changelog, https://github.com/vcollab/vcti-python-shader-foundry/blob/main/CHANGELOG.md
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: <3.15,>=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: vcti-shader-compiler>=4.1.0
Requires-Dist: vcti-shader-base>=1.0.2
Requires-Dist: vcti-shader-deform>=1.1.0
Requires-Dist: vcti-shader-derive>=2.1.0
Requires-Dist: vcti-shader-fringe>=1.1.0
Requires-Dist: vcti-derived<5,>=4.0
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-cov; extra == "test"
Provides-Extra: gl
Requires-Dist: vcti-shader-compiler[gl]>=4.1.0; extra == "gl"
Requires-Dist: numpy>=1.26; extra == "gl"
Provides-Extra: lint
Requires-Dist: ruff; extra == "lint"
Provides-Extra: typecheck
Requires-Dist: mypy; extra == "typecheck"
Dynamic: license-file

# vcti-shader-foundry

The shader artifact-set **builder**: composes the installed shader features into the pipeline matrix, drives the compiler, and emits the artifact set for VCollab renderers.

## Overview

`vcti-shader-foundry` is the assembler of the shader system — the offline build
tool that turns the installed shader features into the committed artifact set
the runtime ships. It composes the features it lists (`vcti-shader-deform`,
`-derive`, `-fringe`) into the pipeline matrix, drives `vcti-shader-compiler`
to emit and validate GLSL ES, checks every result against its contract, and
packs the shaders, one envelope per pipeline and the `registry.json` index into
a single archive, written atomically, for a consumer to take as it likes.

Composition is the whole job, and it is the part no feature can do: each
feature declares its own fields and cannot see what it is combined with, so the
builder is where the clip-space transform that belongs to nobody is added,
where a field name two features declare differently is rejected, and where the
manifest — the only contract the runtime reads — is written.

It is **not** the toolchain and **not** the vocabulary: the `.slang → GLSL ES`
machinery lives in `vcti-shader-compiler`, the specs you declare fields with in
`vcti-shader-base`, and each shader feature in its own package. See
[docs/design.md](docs/design.md) for the system design and
[docs/extending.md](docs/extending.md) for adding a shader feature.

## Installation

```bash
pip install vcti-shader-foundry
```

This is a build tool, not a runtime dependency; install it in the authoring
environment alongside the feature packages you want built. The shader compilers
(`slangc`, `spirv-cross`, `glslang`) are external and pinned — discovered via
`SLANG_DIR` / `SPIRV_CROSS_DIR` / `GLSLANG_DIR` or `PATH`.

## Quick Start

Build the artifact set as one archive:

```console
$ shader-foundry emit
wrote shaders-3.0.0-1fc4c3a7.zip: 15 pipeline(s), 531,073 bytes, sha256 1fc4c3a7f81222b59c74378dab9c5f46610b55276b319b5d200c62b0a6df9919
  registry.json, pipelines/*.json (15), shaders/*.glsl (30)
  toolchain slangc 2026.12.0.1, spirv-cross vulkan-sdk-1.4.357.0, glslang 11:16.5.0 (pinned)
```

One file, three kinds of content, because the same build is read three ways:
`registry.json` for a consumer choosing a pipeline, one self-contained envelope
per pipeline — contract, uniform layout and sources inline — for one rendering
it, and the `.glsl` files for a person. The archive is written whole or not at
all: everything is built and checked in memory, then written to a temporary
file and renamed into place. It is also reproducible, so identical inputs give
an identical file and the hash above identifies the set. The default name
carries both facts a reader wants — the version that built it and the first
eight digits of that hash — and `--out` takes any path, with `{version}` and
`{sha8}` filled in wherever they appear; a plain `shaders.zip` is a fixed name.

Give a directory instead of a `.zip` path and the same files are unpacked into
it — to read them, or to build a subset with `--pipeline ID` (repeatable) while
iterating on one shape. A subset carries no `registry.json`, because the index
is what a consumer selects from and must not list a pipeline that was not
built, and it cannot become an archive. `shader-foundry pipelines` lists the
ids, and needs no toolchain installed.

The executable versions a set is built with are pinned in the package. `emit`
warns when the installed tools differ from the pins and refuses with
`--strict-toolchain`; the manifest records what was actually used either way.

The same from Python, when a build needs to do more around it:

```python
# requires: the shader toolchain (slangc, spirv-cross, glslang)
from vcti.shader.compiler import discover_toolchain
from vcti.shader.foundry import build_artifact_set, build_manifest, toolchain_info, write_archive

toolchain = discover_toolchain()
artifact_set = build_artifact_set(build_manifest(toolchain_info(toolchain)), toolchain)
print(write_archive(artifact_set))          # shaders-<version>-<sha8>.zip, the default name
```

Inspect the matrix without compiling anything — 12 continuous-fringe pipelines
over four data families and three vertex variants, plus 3 discrete-fringe ones:

```python
from vcti.shader.foundry import build_pipelines

for pipeline in build_pipelines():
    print(pipeline.id, list(pipeline.capabilities))
# deform3.symtensor.fringe-float ['deform3', 'symtensor', 'fringe-float']
```

## Dependencies

`vcti-shader-compiler`, `vcti-shader-base`, the feature packages
(`vcti-shader-deform`, `-derive`, `-fringe`), plus `vcti-derived`. The shader
toolchain executables (`slangc`, `spirv-cross`, `glslang`) are external, not pip
dependencies. Nothing here needs a GL context: `moderngl` and `numpy` live in
the `gl` extra, for the tests that prove each emitted pair links, draws, and
computes what its file says it does; `pip install "vcti-shader-foundry[gl]"`
pulls them in on a machine that has a GL stack.

## Documentation

| If you want to… | Read |
|---|---|
| Understand the system design and decisions | [docs/design.md](docs/design.md) |
| Add a new shader feature | [docs/extending.md](docs/extending.md) |
| See practical build workflows | [docs/patterns.md](docs/patterns.md) |
| Navigate and modify the builder source | [docs/source-guide.md](docs/source-guide.md) |
| Look up a specific function or type | [docs/api.md](docs/api.md) |
