Sprites.Media.Shader
A shader image is a stack of GLSL layers rendered into an image, each layer taking the layer below as its input so they compose bottom to top. This module holds the model, the plain data the store keeps, the parameter values as a tagged union, and the pure text work that assembles each layer's full GLSL from the built-in prelude, the parameters, the shared globals and the layer code. It also holds the editor and its stage. The WebGL render driver that turns the GLSL into a texture is separate, so the editor stage shows a placeholder until it lands. The stored document format is described in reference/storage/shader/.
- Sprites.Media.Shader.Editor
- Sprites.Media.Shader.NewDocument
- Sprites.Media.Shader.NewLayer
- Sprites.Media.Shader.CloneLayer
- Sprites.Media.Shader.NewParameter
- Sprites.Media.Shader.DefaultParameter
- Sprites.Media.Shader.FloatValue
- Sprites.Media.Shader.Vec2Value
- Sprites.Media.Shader.Vec3Value
- Sprites.Media.Shader.Vec4Value
- Sprites.Media.Shader.ColourValue
- Sprites.Media.Shader.DefaultValue
- Sprites.Media.Shader.GlslType
- Sprites.Media.Shader.Declarations
- Sprites.Media.Shader.Source
- Sprites.Media.Shader.SelectedLayer
- Sprites.Media.Shader.Summary
- Sprites.Media.Shader.MinSide
- Sprites.Media.Shader.MaxSide
- Sprites.Media.Shader.DefaultWidth
- Sprites.Media.Shader.DefaultHeight
- Sprites.Media.Shader.Header
- Sprites.Media.Shader.Footer
- Sprites.Media.Shader.DefaultCode
- Sprites.Media.Shader.DefaultGlobals
- Sprites.Media.Shader.ClampSide
- Sprites.Media.Shader.Placeholder
Sprites.Media.Shader.Editor Void
Sprites.Media.Shader.Editor(data, thumb, info)
The shader editor. It composes the editor state, the layer selection, the current tool and the panel flags, mounts the Tools window, the Move tool window and the panel windows, and holds the stage. The canvas viewport, the per-layer preview and the render loop that Sets thumb and info arrive with the WebGL driver; until then the stage shows a placeholder, so the shell and every window work against the live model now. It builds interface and returns nothing.
| Input | Type | Description |
|---|---|---|
data | Sprites.Reactive.Value | The document, a two-way value of { media, w, h, globals, params, layers }. |
thumb | Sprites.Reactive.Value | A value the render loop will Set to a preview of the rendered image, once the driver lands. |
info | Sprites.Reactive.Value | A value the render loop will Set to the size and layer-count summary, once the driver lands. |
Returns nothing.
const data = Sprites.Media.Shader.NewDocument(512, 512);
const thumb = Sprites.Reactive.Value(undefined);
const info = Sprites.Reactive.Value(undefined);
Sprites.Media.Shader.Editor(data, thumb, info);
Sprites.Media.Shader.NewDocument Value
Sprites.Media.Shader.NewDocument(width, height)
A new shader document at the given size, or the default size: the { media, w, h, globals, params, layers } shape the store keeps, with the shared globals, no image parameters and one visible layer of the starter code. A composite the store snapshots to plain when it seeds the record.
| Input | Type | Description |
|---|---|---|
width | Sprites.Reactive.Value | The image width in pixels, clamped to the allowed range, or the default when absent. |
height | Sprites.Reactive.Value | The image height in pixels, clamped to the allowed range, or the default when absent. |
Returns a reactive document object.
const data = Sprites.Media.Shader.NewDocument(256, 256);
Sprites.Media.Shader.NewLayer Value
Sprites.Media.Shader.NewLayer(name, code)
A new layer: its name, a visible flag, its GLSL code and its own parameters, none to start. A composite over ReadOnly, so a click that adds a layer passes it as a fresh reactive value the array insert commits.
| Input | Type | Description |
|---|---|---|
name | Sprites.Reactive.Value | The layer's name. |
code | Sprites.Reactive.Value | The layer's GLSL code, which must define vec4 LayerMain(). |
Returns a reactive layer object.
const layer = Sprites.Media.Shader.NewLayer('Layer 1', '');
Sprites.Media.Shader.CloneLayer Value
Sprites.Media.Shader.CloneLayer(layer)
A copy of a layer: a fresh layer object holding the same name, visible flag, code and parameters. Rebuilding the object keeps the copy independent. A composite.
| Input | Type | Description |
|---|---|---|
layer | Sprites.Reactive.Value | The layer to copy. |
Returns a reactive layer object, independent of the original.
const layer = Sprites.Media.Shader.NewLayer('Layer 1', '');
const copy = Sprites.Media.Shader.CloneLayer(layer);
Sprites.Media.Shader.NewParameter Value
Sprites.Media.Shader.NewParameter(name, type, value)
A parameter object: its name, its type and its value. The name is the uniform name in the GLSL, the type one of float, vec2, vec3, vec4 or colour, and the value the tagged union that matches.
| Input | Type | Description |
|---|---|---|
name | Sprites.Reactive.Value | The uniform name in the GLSL. |
type | Sprites.Reactive.Value | One of float, vec2, vec3, vec4 or colour. |
value | Sprites.Reactive.Value | The tagged-union value that matches the type. |
Returns a reactive parameter object.
const value = Sprites.Media.Shader.FloatValue(0.5);
const param = Sprites.Media.Shader.NewParameter('amount', 'float', value);
Sprites.Media.Shader.DefaultParameter Value
Sprites.Media.Shader.DefaultParameter()
A fresh parameter for the Add button: a float named param set to zero. The editor renames it and changes its type from there.
| Input | Type | Description |
|---|---|---|
| None. | ||
Returns a reactive parameter object, a float named param set to zero.
const param = Sprites.Media.Shader.DefaultParameter();
Sprites.Media.Shader.FloatValue Value
Sprites.Media.Shader.FloatValue(n)
A parameter value holding a single float. The value is the tagged union { optionalFloat, optionalVec2, optionalVec3, optionalVec4 } with exactly one field present; here it is optionalFloat.
| Input | Type | Description |
|---|---|---|
n | Sprites.Reactive.Value | The float to hold in optionalFloat. |
Returns a reactive value object with optionalFloat set.
const value = Sprites.Media.Shader.FloatValue(0.5);
const n = Sprites.Object.Field(value, 'optionalFloat');
Sprites.Ui.Content.Text('optionalFloat = ', n);
Sprites.Media.Shader.Vec2Value Value
Sprites.Media.Shader.Vec2Value(x, y)
A parameter value holding a vec2, as { x, y }.
| Input | Type | Description |
|---|---|---|
x | Sprites.Reactive.Value | The x component. |
y | Sprites.Reactive.Value | The y component. |
Returns a reactive value object with optionalVec2 set.
const value = Sprites.Media.Shader.Vec2Value(0.25, 0.75);
Sprites.Media.Shader.Vec3Value Value
Sprites.Media.Shader.Vec3Value(x, y, z)
A parameter value holding a vec3, as { x, y, z }.
| Input | Type | Description |
|---|---|---|
x | Sprites.Reactive.Value | The x component. |
y | Sprites.Reactive.Value | The y component. |
z | Sprites.Reactive.Value | The z component. |
Returns a reactive value object with optionalVec3 set.
const value = Sprites.Media.Shader.Vec3Value(0.1, 0.2, 0.3);
Sprites.Media.Shader.Vec4Value Value
Sprites.Media.Shader.Vec4Value(x, y, z, w)
A parameter value holding a vec4, as { x, y, z, w }.
| Input | Type | Description |
|---|---|---|
x | Sprites.Reactive.Value | The x component. |
y | Sprites.Reactive.Value | The y component. |
z | Sprites.Reactive.Value | The z component. |
w | Sprites.Reactive.Value | The w component. |
Returns a reactive value object with optionalVec4 set.
const value = Sprites.Media.Shader.Vec4Value(0.1, 0.2, 0.3, 1.0);
Sprites.Media.Shader.ColourValue Value
Sprites.Media.Shader.ColourValue(r, g, b, a)
A parameter value holding a colour, red, green, blue and alpha each 0 to 1, stored in optionalVec4 like a vec4. The colour type declares the same vec4 in GLSL; it differs only in the control the editor shows, a colour picker rather than four number fields.
| Input | Type | Description |
|---|---|---|
r | Sprites.Reactive.Value | Red, 0 to 1. |
g | Sprites.Reactive.Value | Green, 0 to 1. |
b | Sprites.Reactive.Value | Blue, 0 to 1. |
a | Sprites.Reactive.Value | Alpha, 0 to 1. |
Returns a reactive value object with optionalVec4 set.
const value = Sprites.Media.Shader.ColourValue(1, 0.5, 0, 1);
Sprites.Media.Shader.DefaultValue Value
Sprites.Media.Shader.DefaultValue(type)
The default value for a parameter type: zero for a float and a vector, opaque white for a colour. A composite over Logic.Select, so switching a parameter's type in the editor can lay a value of the new shape in place.
| Input | Type | Description |
|---|---|---|
type | Sprites.Reactive.Value | One of float, vec2, vec3, vec4 or colour. |
Returns a reactive value object matching the type.
const value = Sprites.Media.Shader.DefaultValue('vec3');
Sprites.Media.Shader.GlslType String
Sprites.Media.Shader.GlslType(type)
The GLSL type name a parameter type declares as: float, vec2, vec3 or vec4, with colour a vec4. A composite over Logic.Select, chosen from the type, so it follows the type reactively and needs no lookup table. Anything unknown falls back to float.
| Input | Type | Description |
|---|---|---|
type | Sprites.Reactive.Value | One of float, vec2, vec3, vec4 or colour. |
Returns a reactive string, the GLSL type name.
const type = Sprites.Reactive.Value('vec3');
const glsl = Sprites.Media.Shader.GlslType(type);
Sprites.Ui.Content.Text('GLSL type: ', glsl);
Sprites.Ui.Input.Dropdown(type, () => {
Sprites.Ui.Input.Option('float', 'float');
Sprites.Ui.Input.Option('vec2', 'vec2');
Sprites.Ui.Input.Option('vec3', 'vec3');
Sprites.Ui.Input.Option('vec4', 'vec4');
Sprites.Ui.Input.Option('colour', 'colour');
});
Sprites.Media.Shader.Declarations String
Sprites.Media.Shader.Declarations(params)
The uniform declarations for a list of parameters: one uniform <glslType> <name>; line per parameter, joined by newlines. A composite over Array.Map and Text.Join, so it follows the parameter list reactively. Used for both the image parameters and a layer's own parameters.
| Input | Type | Description |
|---|---|---|
params | Sprites.Reactive.Value | The list of parameter objects to declare. |
Returns a reactive string, the newline-joined uniform declarations.
const param = Sprites.Media.Shader.NewParameter('amount', 'float', Sprites.Media.Shader.FloatValue(0));
const params = Sprites.Reactive.Value([param]);
const decls = Sprites.Media.Shader.Declarations(params);
Sprites.Media.Shader.Source String
Sprites.Media.Shader.Source(data, layer)
The full GLSL for one layer, in the order the built-in prelude, the image parameter uniforms, the layer parameter uniforms, the shared globals, the layer's own code, then the built-in main that calls LayerMain. data is the document, layer the layer to build. A composite over Declarations and Text.Concat, so the source follows every parameter, the shared code and the layer code reactively; the render driver recompiles when this text changes.
| Input | Type | Description |
|---|---|---|
data | Sprites.Reactive.Value | The document holding the image parameters and shared globals. |
layer | Sprites.Reactive.Value | The layer to build, with its own parameters and code. |
Returns a reactive string, the assembled GLSL for the layer.
const data = Sprites.Media.Shader.NewDocument(256, 256);
const layers = Sprites.Object.Field(data, 'layers');
const layer = Sprites.Array.At(layers, 0);
const source = Sprites.Media.Shader.Source(data, layer);
Sprites.Ui.Code.Editor(source);
Sprites.Media.Shader.SelectedLayer Value
Sprites.Media.Shader.SelectedLayer(data, layerIndex)
A two-way value over the layer at layerIndex, reading that layer and writing an edit back into the layers list. data is the document, layerIndex the editor's selection. The layer window binds the fields of this, so editing a name, a flag, the code or a parameter lays the whole layer back into that one slot, leaving every other layer be.
| Input | Type | Description |
|---|---|---|
data | Sprites.Reactive.Value | The document holding the layers list. |
layerIndex | Sprites.Reactive.Value | The index of the layer to read and write. |
Returns a two-way reactive value over the selected layer.
const data = Sprites.Media.Shader.NewDocument(256, 256);
const layerIndex = Sprites.Reactive.Value(0);
const selected = Sprites.Media.Shader.SelectedLayer(data, layerIndex);
Sprites.Media.Shader.Summary Value
Sprites.Media.Shader.Summary(width, height, layers)
The meta info summary for a shader image: its size and layer count as one short string, for the meta record a listing reads. A composite over Text.Concat and Array.Length.
| Input | Type | Description |
|---|---|---|
width | Sprites.Reactive.Value | The image width in pixels. |
height | Sprites.Reactive.Value | The image height in pixels. |
layers | Sprites.Reactive.Value | The layers list, counted for the summary. |
Returns a reactive string summarising the size and layer count.
const width = Sprites.Reactive.Value(512);
const height = Sprites.Reactive.Value(512);
const layers = Sprites.Reactive.Value([
Sprites.Media.Shader.NewLayer('Layer 1', ''),
Sprites.Media.Shader.NewLayer('Layer 2', '')
]);
const summary = Sprites.Media.Shader.Summary(width, height, layers);
Sprites.Ui.Content.Text(summary);
Sprites.Ui.Input.Number(width);
Sprites.Ui.Input.Number(height);
Sprites.Media.Shader.MinSide Number
The smallest a side may be, in pixels. A plain number, so it drops straight into a clamp as a constant argument.
Sprites.Ui.Content.Text('MinSide = ', Sprites.Media.Shader.MinSide);
Sprites.Media.Shader.MaxSide Number
The largest a side may be, in pixels. A plain number, so it drops straight into a clamp as a constant argument.
Sprites.Ui.Content.Text('MaxSide = ', Sprites.Media.Shader.MaxSide);
Sprites.Media.Shader.DefaultWidth Number
The default new image width, in pixels. A square, large enough to read a shader on. A plain number, so it drops straight into a new document as a constant argument.
Sprites.Ui.Content.Text('DefaultWidth = ', Sprites.Media.Shader.DefaultWidth);
Sprites.Media.Shader.DefaultHeight Number
The default new image height, in pixels. A square, large enough to read a shader on. A plain number, so it drops straight into a new document as a constant argument.
Sprites.Ui.Content.Text('DefaultHeight = ', Sprites.Media.Shader.DefaultHeight);
Sprites.Media.Shader.Header String
The built-in prelude every layer's GLSL opens with: the version and precision, the two built-in uniforms, the fragment output, and the built-in per-fragment values the layer code may read. uInput is the texture the layer below rendered, uResolution the image size in pixels. Resolution, Pixel, Uv and Unit are filled by the main below before it calls LayerMain, so the layer code reads them as plain globals. A plain string, so it drops straight into the source assembly as a constant.
const header = Sprites.Reactive.Value(Sprites.Media.Shader.Header);
Sprites.Ui.Code.Editor(header);
Sprites.Media.Shader.DefaultCode String
The code a fresh layer starts with: a LayerMain that lays a soft opaque tint, so a new layer renders something and shows the shape a LayerMain takes. It returns its own colour; the built-in main composites it over the layer below, so a lower alpha here would let the layer below show through. It must define vec4 LayerMain(), the function the built-in main calls.
const code = Sprites.Reactive.Value(Sprites.Media.Shader.DefaultCode);
Sprites.Ui.Code.Editor(code);
Sprites.Media.Shader.DefaultGlobals String
The shared global code a fresh image starts with: helpers every layer can call, added to each layer's GLSL ahead of the layer's own code.
const globals = Sprites.Reactive.Value(Sprites.Media.Shader.DefaultGlobals);
Sprites.Ui.Code.Editor(globals);
Sprites.Media.Shader.ClampSide Sprites.Reactive.Value
Sprites.Media.Shader.ClampSide(n)
Clamp a side to the allowed range, as a whole number. A composite: round, then hold between the smallest and largest a side may be.
| Input | Type | Description |
|---|---|---|
n | Sprites.Reactive.Value | The side to round and clamp, in pixels. |
Returns a reactive number, the side rounded and held between MinSide and MaxSide.
const n = Sprites.Reactive.Value(8000);
const side = Sprites.Media.Shader.ClampSide(n);
Sprites.Ui.Input.Number(n);
Sprites.Ui.Content.Text('Clamped side: ', side);
Sprites.Media.Shader.Placeholder Void
Sprites.Media.Shader.Placeholder(width, height)
The stage placeholder: a panel that fills the canvas area and names the render size, standing in for the WebGL canvas until the render driver lands. It keeps the shell usable and testable now, the windows, the model and the GLSL composition, without waiting on the driver. width and height are the reactive document size, shown so a size change reads back here.
| Input | Type | Description |
|---|---|---|
width | Sprites.Reactive.Value | The reactive document width, in pixels. |
height | Sprites.Reactive.Value | The reactive document height, in pixels. |
Returns nothing.
const width = Sprites.Reactive.Value(512);
const height = Sprites.Reactive.Value(512);
Sprites.Ui.Dom.Tag('div', () => {
Sprites.Ui.Dom.Style('position', 'relative');
Sprites.Ui.Dom.Style('height', '160px');
Sprites.Media.Shader.Placeholder(width, height);
});
Sprites.Ui.Input.Number(width);
Sprites.Ui.Input.Number(height);