Many useful procedural patterns are based on just a few standard functions, most notably various kinds of "noise" functions. These functions are not included in GLSL by default, but the lab page includes definitions of the following functions which you can use to create patterns.
float perlinnoise(vec2 st) float perlinnoise(float s, float t) float perlinnoise(vec3 xyz) float perlinnoise(float x, float y, float z) float perlinnoise(vec2 xy, float z) float perlinnoise(vec4 xyzw) float perlinnoise(float x, float y, float z, float w)
All these return one value (float), in the range -1 to +1. To rescale it to the range 0 to 1 for use as a color component, multiply it by 0.5 and add 0.5:
float n = 0.5 + 0.5*perlinnoise(st); gl_FragColor = vec4(n, n, n, 1.0);
To make the details of the pattern smaller, scale the texture coordinates:
float n = 0.5 + 0.5*perlinnoise(10.0 * st); gl_FragColor = vec4(n, n, n, 1.0);
To animate the pattern over time, add a third coordinate that depends on time:
float n = 0.5 + 0.5*perlinnoise(10.0 * st, time); gl_FragColor = vec4(n, n, n, 1.0);
float worleynoise1(vec2 st) float worleynoise1(vec3 xyz) float worleynoise1(vec2 xy, float z) vec2 worleynoise2(vec2 st) vec2 worleynoise2(vec3 xyz) vec2 worleynoise2(vec2 xy, float z)
These return one or two values (float or vec2), in the range 0 to slightly above 1. The values are the distance to the center of the nearest "cell" and (if two values are returned) the second nearest cell.
A cell-like pattern of white blobs:
float d = worleynoise1(5.0 * st); float n = 1.0 - d*d; gl_FragColor = vec4(n, n, n, 1.0);
A flagstone-like pattern of tiles:
vec2 d = worleynoise2(5.0 * st); float n = d.y - d.x; gl_FragColor = vec4(n, n, n, 1.0);
float flownoise(vec2 st, float rot, out vec2 g) float flownoise(vec2 st, float rot)
The first version returns a noise value, much like 2-D Perlin noise, but the small local wiggles of noise can be rotated by an angle, which makes the pattern swirl. The version with the "out vec2" argument also returns the gradient (derivative) of the noise function.
float filterstep(float a, float x)
This creates an anti-aliased threshold, a transition between black and white that is one pixel wide and has a smoother appearance than an all-or-nothing thresholding like an if-else clause or the built-in GLSL function step().
A circle with a nice looking edge:
float dx = st.s - 0.5; float dy = st.t - 0.5; float d = sqrt(dx*dx + dy*dy); float n = filterstep(0.3, d); gl_FragColor = vec4(n, n, n, 1.0);A crisp Worley tile pattern:
vec2 d = worleynoise2(5.0 * st); float e = d.y - d.x; float n = filterstep(0.1, e); gl_FragColor = vec4(n, n, n, 1.0);