Rules and limits
The language is small, and so are its rules. Here they all are, in one place, so that when something stops you, you can find out why.
When things go wrong
A shader can go wrong in three places, and I tell you about all of them.
The first is when I read it. A word I don’t know, a bracket that isn’t
closed, a <: I stop on the line it’s on, the way I would anywhere else in
your program.
SCREEN 320, 240
SHADER "unknown"
WHEN DRAWING
SET COLOR = RGBA(TAN(UV.x), 0.0, 0.0, 1.0)
END WHEN
END SHADER
TAN isn’t one of the shader language’s functions, so I stop at it.
The second is when I build it, as the SHADER line runs. A function given
the wrong number of values, a name that was never set, a setting you try to
change: I stop and say what it was.
SCREEN 320, 240
SHADER "short"
WHEN DRAWING
SET COLOR = RGBA(1.0, 0.0, 0.0)
END WHEN
END SHADER
RGBA takes four values, and this one has three, so I stop and say so.
(RGB is the one that takes three.)
SCREEN 320, 240
SHADER "early"
WHEN DRAWING
SET COLOR = RGBA(glow, 0.0, 0.0, 1.0)
glow = FRACT(TIME)
END WHEN
END SHADER
glow is used on the line before the one that sets it, so there’s no glow
yet where it’s used.
The third is when the graphics chip builds it. What reads as fine to me can still be something the chip won’t run: a color with three parts where it wants four, a sum of a color and a place. Then I stop the game with the chip’s own words for what was wrong, and the shader’s name.
SCREEN 320, 240
SHADER "three"
WHEN DRAWING
SET COLOR = VEC3(1.0, 0.0, 0.0)
END WHEN
END SHADER
SET COLOR wants four parts, and VEC3 has three.
Names
A variable’s name is letters, digits and _, starting with a letter. Big
and small letters are the same.
These names are taken, and a variable called any of them stops the shader:
- Names that start with one of the language’s own words.
IMAGE,UV,SCREEN,SCREEN_SIZE,TIMEandTICKare read first, sotimer,uvs,imagesandticksare read asTIME,UV,IMAGEorTICKwith something left over. I stop on the line, and say which word the name starts with. Call themclock,place,picturesandcountinstead. - A setting’s name. A variable can’t have the same name as one of the
shader’s
USEsettings: settings can be read, not changed. - The names I use to build the shader:
uv,in,uniformsandbalpha_out. - The graphics chip’s own words, such as
var,let,fn,if,for,loop,return,struct,type,target,smooth,filter,trueandfalse. The whole list is long, and mostly words nobody would use for a variable by accident. I know them all, and stop on any of them with the name you used.
SCREEN 320, 240
SHADER "clock"
WHEN DRAWING
timer = FRACT(TIME)
SET COLOR = RGBA(timer, 0.0, 0.0, 1.0)
END WHEN
END SHADER
What a line can be
name = expression, orSET COLOR = expression, and nothing else.- No
IF, loops,FUNCTION,PRINTorDIM. - No
<,>,=in a sum,AND,OR,NOTorMOD: see Choices without IF. - A number is digits with an optional point:
3,0.25. No1e-3. - A swizzle goes on a name, a word like
UV, or brackets, not straight on a function:c = OWNTEXTURE(UV)thenc.r. - A swizzle has one to four parts, all from
rgbaor all fromxyzw, and only the parts the thing has:UV.zdoesn’t exist. - You can’t change one part of a variable:
c.r = 1.0isn’t a line. Make a new color instead:c = RGBA(1.0, c.g, c.b, c.a). USElines come beforeWHEN DRAWING, and there’s oneWHEN DRAWING.
SCREEN 320, 240
SHADER "swizzled"
WHEN DRAWING
red = OWNTEXTURE(UV).r
SET COLOR = RGBA(red, 0.0, 0.0, 1.0)
END WHEN
END SHADER
How many
| What | How many |
|---|---|
Numbers in the settings, a USE NUMBER one and a USE COLOR four | 64 |
USE IMAGE pictures | 4 |
| Parts in a swizzle | 4 |
What I do for you
- Alpha. On a sprite, the alpha your shader hands back is multiplied by the sprite’s own, so fading a sprite works with any shader on it.
- Frames. On an animated sprite,
UV,PXandOWNTEXTUREare the frame’s, not the sheet’s. - Edges. Reading a picture outside 0 to 1 gets you its edge.
- Pixels, not blurs. Reading a picture between two of its pixels gets you the nearer one, not a blend. That’s what keeps pixel art crisp, and why a very slow scroll moves in steps.