One folder, one sketch.glsl. No page, no render loop, no boilerplate -
Sialk supplies all of that, and the audio as uniforms.
my-shader/
sketch.glsl
Drag the folder onto Sialk. Dragging the .glsl file in directly works too;
the folder is incidental.
The smallest one that works
void main() {
vec2 uv = gl_FragCoord.xy / sialkResolution;
fragColor = vec4(uv.x, uv.y, sialkLevel, 1.0);
}
Nothing is imported, declared or polled. The values are simply there, updated once per composited frame.
Both dialects
Sialk accepts GLSL ES 3.00 and GLSL ES 1.00, and works out which one you
wrote from what is in it - gl_FragColor and texture2D mean 1.00.
Most shaders on the internet are still 1.00, and they should simply run:
precision highp float;
void main() {
vec2 uv = gl_FragCoord.xy / sialkResolution;
gl_FragColor = vec4(uv, sialkBass, 1.0);
}
Note that ES 1.00 requires constant loop bounds. That is the language, not Sialk.
What Sialk gives you
Every one of these is supplied as a uniform. They carry the same meanings as the audio contract, which is where the detail lives.
| Uniform | Type | |
|---|---|---|
sialkResolution |
vec2 |
The surface being composited, in pixels. |
sialkTime |
float |
Show transport position, in seconds. |
sialkDelta |
float |
Seconds since the previous frame. |
sialkFrame |
float |
Frames since this sketch loaded. |
sialkLevel |
float |
Broadband loudness, 0-1. |
sialkBass sialkMid sialkHigh |
float |
The three bands, 0-1. |
sialkHits |
float |
Onset counter. |
sialkOnBeat |
float |
1 on the beat, decaying. |
sialkBeatPhase |
float |
Ramps 0 → 1 between beats. |
sialkBpm sialkBpmConfidence |
float |
Tempo, and how much to trust it. |
sialkSilent |
float |
1 when the input has been quiet for a second. |
sialkSpectrum |
sampler2D |
64 bins as a texture. |
sialkLevelTrail |
sampler2D |
128 frames of level as a texture. |
Two helpers save you the texture lookup, in both dialects:
float sialkBand(float t); // t 0..1 across the spectrum
float sialkTrail(float t); // t 0..1 back through the level trail
#define SIALK_CONTRACT 1 is set, so a shader can compile both inside Sialk and
outside it.
A shader you wrote for Shadertoy
iTime, iResolution, iFrame and iMouse are defined, so a shader you wrote
in that dialect yourself should run as it is. iMouse is a constant zero,
pointer input arrives with v1.
Making it react
The whole point. Instead of a constant, reach for a band:
float radius = 0.2 + sialkBass * 0.3;
Leave headroom, see the audio for why a value that saturates at 0.9 makes a loud room and a very loud room look identical.
sialkBeatPhase is usually better than sialkOnBeat for anything that should
decay: 1.0 - sialkBeatPhase is a fall that is in time with the music rather
than with a number you picked.
Cost
GLSL cares about pixels, and about nothing else. A loop that always runs to the end costs its full length at every pixel, at 4K that is 8.3 million times. A distance field that converges early is cheap; step count alone tells you very little.
If a shader collapses at 4K but is fine at 720p, that is the shape of the problem, and it is not something Sialk can fix for you.