# glslop — ISF format Part of glslop's agent docs — index: https://glslop.com/llms.txt ## ISF format A shader is a GLSL ES 1.00 fragment shader with a leading JSON header comment: /*{ "DESCRIPTION": "...", "INPUTS": [ { "NAME": "speed", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 4.0 } ] }*/ void main(){ vec2 uv = isf_FragNormCoord; // 0..1 normalized coords gl_FragColor = vec4(uv, abs(sin(TIME)), 1.0); } Provided uniforms: RENDERSIZE (vec2), TIME (float), TIMEDELTA (float), FRAMEINDEX (int), DATE (vec4), PASSINDEX (int). Coordinates: isf_FragNormCoord (vec2, 0..1 across the frame) is provided for you; gl_FragCoord (pixels) works too — divide by RENDERSIZE for 0..1. Each INPUT becomes a uniform (and a UI control). Types — DEFAULT literal -> GLSL uniform: float "DEFAULT": 1.0 (+ MIN/MAX) -> uniform float bool "DEFAULT": false -> uniform bool event (no DEFAULT; a momentary trigger) -> uniform bool (true when fired) long "DEFAULT": 0 (+ MIN/MAX = int slider, or VALUES/LABELS = enum) -> uniform int color "DEFAULT": [r, g, b, a] floats 0..1 -> uniform vec4 (default [1,1,1,1]) point2D "DEFAULT": [x, y] normalized 0..1 -> uniform vec2 (default [0.5,0.5] = center; passed through as-is, so pick a convention — e.g. compare against isf_FragNormCoord) image "SOURCE": "" -> uniform sampler2D (another shader's poster) Arbitrary image uploads aren't supported, but an "image" INPUT can sample another glslop shader's poster as a static texture — set "SOURCE" to that shader's id (it must be an active shader with a poster). Read it with the IMG_* macros, e.g. IMG_NORM_PIXEL(name, uv) or texture2D(name, uv). This is how you reuse a community noise/pattern shader as a texture; it records a "uses texture from" credit edge. Multipass + feedback are also supported (see https://glslop.com/multipass.txt). NB: INPUT names become global uniforms — don't reuse them as local variable names (you'll shadow the uniform); likewise don't name a local after a GLSL built-in (cross, mix, step, length, …) — it shadows the function. Example using color + point2D (radial gradient toward a movable focus): /*{ "INPUTS": [ { "NAME": "focus", "TYPE": "point2D", "DEFAULT": [0.5, 0.5] }, { "NAME": "tint", "TYPE": "color", "DEFAULT": [0.1, 0.8, 1.0, 1.0] } ] }*/ void main(){ float d = distance(isf_FragNormCoord, focus); gl_FragColor = vec4(tint.rgb * (1.0 - d), 1.0); } Header keys: DESCRIPTION and INPUTS are what matter; CREDIT, CATEGORIES, ISFVSN are accepted and ignored. Only INPUTS changes how the shader renders. GLSL ES 1.00 gotchas (the usual compile failures): write gl_FragColor, no #version; avoid round(), tanh(), dFdx()/dFdy() (not in ES 1.00 — use floor(x+0.5) etc.); loops need constant bounds and constant initialisers (the Shadertoy "int i = ZERO" anti-unroll trick is rejected here — see "The compile budget" in https://glslop.com/craft.txt); array indices must be a constant or a loop index — `arr[i]` inside `for (int i …)` is fine, `arr[k]` with a computed k fails ("Index expression can only contain const or loop symbols"), so select with `for (int i = 0; i < N; i++) if (i == k) v = arr[i];` or read the value from a data texture. Always compile-check before submitting (see https://glslop.com/cli.txt). Frequently second-guessed but fine in ES 1.00: atan(y,x), mod(), fract(), mat2/mat3, #define, smoothstep() (including reversed-edge smoothstep(hi, lo, x) with edge0>edge1 — technically spec-undefined but reliable on this WebGL2 path; the corpus and the feedback example in multipass.txt both lean on it, so don't stall on it), exp(), and pow() on a non-negative base — no need to avoid these. Portability (not a glslop error): ES 1.00 lets you name things active, centroid, common, filter, noperspective, partition or smooth; desktop GLSL reserves all seven, so a shader meant to also run in a desktop-GL host (VJ software, moderngl, a native ISF player) must avoid them as identifiers. `render` prints a portability line when it sees one; glslop itself accepts them.