Ever figured the ‘?’ icon at the bottom-right of the source area 🙂 ?

And the “shader Inputs>” on top-left ? 🙂

These are, respectively, a GLSL ES summary, and a list of the Shadertoy variable.

**GLSL already knows vectors and matrices**

- comprising operations like
*length, distance, normalize, dot, cross*and*mat*vec* - Many operations directly work on vectors (acting on each components)
- Some special operations do boolean operations on vectors (
*all, any, lessthan*…) - Many operations implictely expend floats to vectors (
*v+2., v/=2., step(0.,v)*… ) - and constructors are also casters ( e.g.
*V=vec4(x>y, 0, vec2(x))*). - GLSL already knows 3D graphics operations such as
*reflect, refract*,*faceforward* - GLSL provides many goodies like
*clamp, mix*(linear interpolation),*smoothstep*(Hermite weighting)

**NB: Complex calculus easily implements as vector and matrices** :

- Use
*vec2*for definition, + – between complexes, + – * / with a float - complex multiplication of
*z1*by*z2*is*mat2(z1,-z1.y,z1.x) * z2* - complex division of
*z1*by*z2*is*z1 * mat2(z2,-z2.y,z2.x) / dot(z2,z2)*

### C tricks are good for GLSL perfs and programming ease

*pow(x,y)*is doing*exp(y*log(x))*: costly, not valid for x<0, not perfect precision.- for
*x^2*, do prefer*x*x*! - for
*2^x*use*exp2(x)*. the reverse*log2*also exist (both in most langages 🙂 ).

- for
*atan*API also includes the 2 parameters version doing*atan2(y,x)**x = cond ? v1 : v0*can be useful, especially for cascaded small expressions.- There should be a law punishing people using
*if cond then x=true else x=false*. Just do directly*x= cond*😉 - macros can be a convenient substitutes for templates (e.g. expressions valid for
*floats, vec2, vec3, vec4*).

### Uncomplete integer operations

Many integer operations are missing. Sometime the simplest is to do them on floats then cast (or not). But be careful to precision loss. Still,

- integers up to 16,777,216 are exactly represented by IEEE floats on 32bits
- + – * will thus be exact… But not the division:
*x/x*might not be exactly 1. *fract*and*log2*are directly reading the mantissa and exponent so are lossless- In particular,
*<<*and*>>*can be represented by**exp2(n)*and**exp2(-n)* *mod*on int-in-floats has precision bugs.

You can do mod directly on ints with a % b = a-a/b*b- Note that you can loop on floats to avoid loads of casts.

### GLSL run pixels in parallel

- So it can computes derivative of any variable for free !
*dFdx, dFdy, fwidth*

(The precision is approximate, though: uncentered finite differences within 2×2 blocks) - Think parallel. Doing long initializations and definition of arrays won’t be factored through pixels since the whole shader is called at every pixels. So most of the time you save code, memory, registers, by merging the initialization and action loops.
- A reminder that local memory and number of registers is an ultra-critical resource on GPU.
- Think procedural: to draw 1000 objects on screen, don’t draw and clamp all of them in your shader – i.e. full set checked at each pixel. Try to find the one(s) that cover the pixel, then render only this one.

### Texture tricks (GLSL or Shadertoy)

- MIPmap is simply activated by switching the texture mode. Still,
- You can bias it (force less or more blur) via a third parameter at texture call.
- At parameterization discontinuity the automatic estimation on the LOD might be very wrong. => you can force it using
*texture…LodEXT* - Note that MIPmap can be used to approximate integrals.

*texture…gradEXT*directly computes the texture derivative- Noise color texture: G and A channels are R and B translated by (37.,17.) , if no vflip. This allows to fake interpolated 3D noise.
- is an ordered Bayer matrix : first made for easy half-toning (just threshold it with the grey level), it also provides a permutation table in [0,63].
- Shadertoy buffers can be used to precompute data.

More generally, in a multi-buffer algorithm if the result of a buffer is not expected to change do the computation only at iFrame==0 (or up to a delay, if asynchroneous data such as images are used). - Note that sound texture includes the FFT of the music.
- Check for the magic keyboard matrix 🙂

### More “touchy” tricks (e.g. for code golfing)

- The final alpha is ignored, so you can work directly on
*pixelColor*or do*vec4(myGreyShader)*. - The final color is naturally clamped (your screen pixel won’t be negative or surbright 🙂 ) so for the final image operation you can forget the last clamp.

( Of course this can be wrong for intermediate calculations, and buffers do store unclamped floats. ) - You must initialize variables, comprising
*out*parameters (such as*pixelColor*).

But*v -= v*will work 99.9999% of the times. The only theoretical issue is when the reused register occurred to value*NaN*by chance (which I’ve never seen occurring up to now).

### Advanced super-tricks

You want to use your own texture ? read section Extending Shadertoy & more.`
`(But it won’t save and others people won’t see it if they don’t do the same insert.)

### Readings

- A beginners guide to coding graphics shaders
- the Book of Shaders
- The Graphics Codex
- OpenGL-ES Shading Language – Reference manual

Advertisements