89 lines
2.0 KiB
Markdown
89 lines
2.0 KiB
Markdown
# Shader Package Contract
|
|
|
|
Each shader package lives under `shaders/<id>/` and includes:
|
|
|
|
- `shader.json`
|
|
- `shader.slang`
|
|
|
|
## Manifest fields
|
|
|
|
`shader.json` defines:
|
|
|
|
- `id`
|
|
- `name`
|
|
- `description`
|
|
- `category`
|
|
- `entryPoint`
|
|
- `parameters`
|
|
- optional `temporal`
|
|
|
|
Supported parameter types:
|
|
|
|
- `float`
|
|
- `vec2`
|
|
- `color`
|
|
- `bool`
|
|
- `enum`
|
|
|
|
## Temporal manifests
|
|
|
|
Shaders can optionally declare temporal history needs:
|
|
|
|
```json
|
|
{
|
|
"temporal": {
|
|
"enabled": true,
|
|
"historySource": "source",
|
|
"historyLength": 4
|
|
}
|
|
}
|
|
```
|
|
|
|
Supported temporal history sources:
|
|
|
|
- `source` - decoded source-video history from previous frames
|
|
- `preLayerInput` - history of the input arriving at that layer before the shader runs
|
|
|
|
`historyLength` is requested by the shader and clamped by `config/runtime-host.json` via `maxTemporalHistoryFrames`.
|
|
|
|
Temporal history resets automatically when:
|
|
|
|
- layers are added, removed, or reordered
|
|
- a layer bypass state changes
|
|
- a layer changes to a different shader
|
|
- a shader is reloaded or recompiled
|
|
|
|
## Slang contract
|
|
|
|
The runtime owns the fragment entry point, the UYVY-to-RGBA decode pass, and final mix/bypass behavior.
|
|
|
|
Your `shader.slang` file implements:
|
|
|
|
```slang
|
|
float4 shadeVideo(ShaderContext context)
|
|
{
|
|
return context.sourceColor;
|
|
}
|
|
```
|
|
|
|
Available built-ins through `ShaderContext`:
|
|
|
|
- `uv`
|
|
- `sourceColor` - the already-decoded full-resolution RGBA video color at `uv`
|
|
- `inputResolution`
|
|
- `outputResolution`
|
|
- `time`
|
|
- `frameCount`
|
|
- `mixAmount`
|
|
- `bypass`
|
|
- `sourceHistoryLength`
|
|
- `temporalHistoryLength`
|
|
|
|
Manifest parameters are exposed to the shader as globals named by their `id`.
|
|
|
|
Helper function:
|
|
|
|
- `sampleVideo(float2 uv)` returns decoded full-resolution RGBA video from the live DeckLink input.
|
|
- `sampleSourceHistory(int framesAgo, float2 uv)` samples the most recent available source history frame, clamping to the oldest available frame if needed.
|
|
- `sampleTemporalHistory(int framesAgo, float2 uv)` samples the most recent available pre-layer history frame for temporal shaders, clamping to the oldest available frame if needed.
|