Common and Geometric Functions

The common functions shape numbers: abs(), sign(), floor(), ceil(), round(), fract(), mod(), min(), max() and clamp(), plus three that fragment shaders use everywhere: step(edge, x) (0 below the edge, 1 above), smoothstep(e0, e1, x) (an S-curve from 0 to 1) and mix(a, b, t) (linear blend). The geometric functions treat vectors as points and directions: length(), distance(), dot(), cross(), normalize(), faceforward(), reflect() for mirror directions and refract() for glass and water:

Common and geometric functions evaluated on the GPUJavaScript
show('result = vec4(step(0.5, 0.4), smoothstep(0.0, 1.0, 0.25), mix(10.0, 20.0, 0.25), 0.0);');
show('result = vec4(mod(-1.0, 3.0), fract(-1.25), sign(-2.0), clamp(1.5, 0.0, 1.0));');
show(`result = vec4(reflect(vec3(1.0, -1.0, 0.0), vec3(0.0, 1.0, 0.0)),
                   length(vec2(3.0, 4.0)));`);
show(`vec3 ray = normalize(vec3(1.0, -1.0, 0.0));        // 45 degrees down, into water
      result = vec4(refract(ray, vec3(0.0, 1.0, 0.0), 1.0 / 1.33), 0.0);`);
Output
0, 0.15625, 12.5, 0
2, 0.75, -1, 1
1, 1, 0, 5
0.531659, -0.846958, 0, 0

smoothstep(0.0, 1.0, 0.25) is 0.15625, not 0.25: the curve eases in, which is why it softens edges so well. Unlike C's %, mod(-1.0, 3.0) is 2, because GLSL defines it as x - y * floor(x / y). The refracted ray bends toward the normal, and Directional and Point Lighting builds lighting from dot(), normalize() and reflect().

step, smoothstep, mod and fract plotted, and a light ray split by reflect() and refract()HTMLLive
<!doctype html>
<style>
  body { margin: 0; font: 12px system-ui, sans-serif; background: #f7f4ee; color: #333; }
  canvas { display: block; width: 100%; max-width: 600px; }
  .names { display: flex; max-width: 600px; text-align: center; font-family: monospace; font-size: 11px; }
  .names div { padding: 4px 2px; }
</style>
<canvas id="view" width="600" height="200"></canvas>
<div class="names">
  <div style="width:25%">step / smoothstep</div><div style="width:25%">mod(x, 0.5), fract(x * 3)</div>
  <div style="width:50%">reflect() and refract() at a water surface (eta = 1 / 1.33)</div>
</div>
<script>
const gl = document.getElementById('view').getContext('webgl2');
const vs = `#version 300 es
void main() { gl_Position = vec4(gl_VertexID == 1 ? 3.0 : -1.0, gl_VertexID == 2 ? 3.0 : -1.0, 0.0, 1.0); }`;
const fs = `#version 300 es
precision highp float;
uniform float uTime;
out vec4 outColor;
float curve(float y, float f) { return 1.0 - smoothstep(0.0, 1.5, abs(y - f) / fwidth(y - f)); }
// Distance from p to the segment a-b, built from dot(), clamp() and length().
float segment(vec2 p, vec2 a, vec2 b) {
  vec2 ab = b - a;
  float t = clamp(dot(p - a, ab) / dot(ab, ab), 0.0, 1.0);
  return length(p - (a + ab * t));
}
void main() {
  vec2 px = gl_FragCoord.xy;
  vec3 color = vec3(0.97, 0.96, 0.93);
  if (px.x < 150.0) {
    vec2 uv = (px - vec2(10.0)) / vec2(130.0, 180.0);
    color = mix(color, vec3(0.71, 0.27, 0.18), curve(uv.y, step(0.5, uv.x)));
    color = mix(color, vec3(0.12, 0.37, 0.55), curve(uv.y, smoothstep(0.2, 0.8, uv.x)));
  } else if (px.x < 300.0) {
    vec2 uv = (px - vec2(160.0, 10.0)) / vec2(130.0, 180.0);
    color = mix(color, vec3(0.25, 0.49, 0.23), curve(uv.y, mod(uv.x, 0.5) * 2.0));
    color = mix(color, vec3(0.88, 0.6, 0.06), curve(uv.y, fract(uv.x * 3.0) * 0.5));
  } else {
    vec2 p = px - vec2(450.0, 100.0);               // origin: where the ray meets the water
    if (p.y < 0.0) color = mix(vec3(0.75, 0.87, 0.93), vec3(0.45, 0.65, 0.8), -p.y / 100.0);
    float a = 0.35 + 0.35 * sin(uTime);             // swing the incoming ray
    vec3 ray = normalize(vec3(sin(a), -cos(a), 0.0));
    vec3 n = vec3(0.0, 1.0, 0.0);
    vec3 bounce = reflect(ray, n);                  // mirror direction
    vec3 bent = refract(ray, n, 1.0 / 1.33);        // bends toward the normal
    float w = 1.6;
    if (segment(p, -ray.xy * 120.0, vec2(0.0)) < w) color = vec3(0.1);
    if (segment(p, vec2(0.0), bounce.xy * 120.0) < w) color = vec3(0.88, 0.6, 0.06);
    if (segment(p, vec2(0.0), bent.xy * 120.0) < w) color = vec3(0.71, 0.27, 0.18);
    if (abs(p.x) < 0.6 && abs(p.y) < 90.0 && mod(p.y, 8.0) < 4.0) color = vec3(0.5);   // dashed normal
  }
  outColor = vec4(color, 1.0);
}`;
const program = gl.createProgram();
for (const [type, src] of [[gl.VERTEX_SHADER, vs], [gl.FRAGMENT_SHADER, fs]]) {
  const s = gl.createShader(type);
  gl.shaderSource(s, src); gl.compileShader(s);
  if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) throw new Error(gl.getShaderInfoLog(s));
  gl.attachShader(program, s);
}
gl.linkProgram(program);
gl.useProgram(program);
gl.bindVertexArray(gl.createVertexArray());
const uTime = gl.getUniformLocation(program, 'uTime');
function frame(ms) {
  gl.uniform1f(uTime, ms * 0.0008);
  gl.drawArrays(gl.TRIANGLES, 0, 3);
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
</script>