Skip to content
Sample of Hash without Sine — Dave Hoskins hash art

shader_legends · TaterHashArt

Hash without Sine — Dave Hoskins hash art

Dave Hoskins's celebrated 'Hash without Sine' family of cross-platform-stable pseudo-random hash functions, presented as art. The canvas is tiled or scattered with integer grid cells and at every cell we plot a coloured point whose position jitter, hue, size and stroke angle are all driven by hash22 (or hash33 for the 3D triptych mode). The artwork is a direct celebration of the shadertoy.com legend whose hash functions have become the default building block for procedural shaders.

Original: https://www.shadertoy.com/view/4djSRW

▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.

Family
shader_legends
Source
shader legends
Evolution
hash_function
Render
point_cloud
Complexity
low
Agents
0
Year
2014
Author
Dave Hoskins (Shadertoy 'Tater')

Math essence

hash22(p) is the canonical Hoskins 2014 fragment: p3 = fract(p * (0.1031, 0.1030, 0.0973)); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.xx + p3.yz) * p3.zy). hash33(p) is the 3D analog using a different mix. We sample one of {grid22, scatter22, scatter33, streaks} modes; in every case the integer cell id is hashed, and (jitter_x, jitter_y, hue, size) come from the hash output. The cosine palette maps hash.hue to an RGB triple.

Parameters

Name Type Default Range Description
dim int 360 120–800 Square output size in pixels.
cells int 40 8–80 Number of integer grid cells per side (grid22 and streaks modes).
mode string grid22 null–null Visualization mode: grid22, scatter22, scatter33 (triptych), or streaks.
point_size float 0.65 0.1–3 Multiplier on the per-point radius derived from the hash.
scatter_count int 2500 200–8000 Number of scatter points (scatter22 and scatter33 modes).
hue_shift float 0 0–1 Phase shift applied to the cosine palette.

Reference

First 60 lines of reference.py. Full source: library_external/shader_legends/TaterHashArt/reference.py

from __future__ import annotations

from typing import ClassVar

import numpy as np


def _hoskins_hash22(x: np.ndarray, y: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
    """Dave Hoskins's `hash22` (Shadertoy 'Hash without Sine', 4djSRW).

    vec2 hash22(vec2 p) {
        vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
        p3 += dot(p3, p3.yzx + 33.33);
        return fract((p3.xx + p3.yz) * p3.zy);
    }
    """
    p3 = np.stack([x, y, x], axis=-1).astype(np.float64)
    p3 = p3 * np.array([0.1031, 0.1030, 0.0973])
    p3 = p3 - np.floor(p3)
    p3 = p3 + np.sum(p3 * (p3[..., (1, 2, 0)] + 33.33), axis=-1, keepdims=True)
    xx = p3[..., 0]
    yz = np.stack([p3[..., 1], p3[..., 2]], axis=-1)
    out = (np.stack([xx, xx], axis=-1) + yz) * np.stack([p3[..., 2], p3[..., 1]], axis=-1)
    return (out[..., 0] - np.floor(out[..., 0])).astype(np.float32), (out[..., 1] - np.floor(out[..., 1])).astype(np.float32)


def _hoskins_hash33(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
    """Dave Hoskins's `hash33` (Shadertoy 'Hash without Sine', 4djSRW)."""
    p3 = np.stack([x, y, z], axis=-1).astype(np.float64) * np.array([0.1031, 0.1030, 0.0973])
    p3 = p3 - np.floor(p3)
    p3 = p3 + np.sum(p3 * (p3[..., (1, 0, 2)] + 33.33), axis=-1, keepdims=True)
    x_y = p3[..., 0]
    y_z = p3[..., 1]
    z_x = p3[..., 2]
    o1 = (x_y + y_z) * z_x
    o2 = (x_y + z_x) * y_z
    o3 = (y_z + z_x) * x_y
    return (o1 - np.floor(o1)).astype(np.float32), (o2 - np.floor(o2)).astype(np.float32), (o3 - np.floor(o3)).astype(np.float32)


class TaterHashArt:
    """Hash without Sine — Dave Hoskins (Shadertoy 'Tater').

    Re-creates Dave Hoskins's iconic *Hash without Sine* (Shadertoy
    `4djSRW`, 2014), a cross-platform-stable family of pseudo-random
    hash functions used as a building block in countless Shadertoy
    sketches. Rather than rendering the hashes invisibly as primitives,
    we *visualise* them: the canvas is tiled with regular 2D integer
    grids, and at every grid cell we plot a coloured point whose
    position, size and colour are driven by `hash22` or `hash33`.

    Modes:

    - `grid22` — large grid, each cell shows one `hash22` point.
    - `scatter22` — many `hash22` points scattered across the canvas.
    - `scatter33` — three sample planes (xy, yz, zx) of `hash33`
       composited side-by-side as a triptych.
    - `streaks` — for each cell, draw a short coloured stroke whose
       angle and length are driven by `hash22`.
    """

Try running it locally

The reference implementation is self-contained Python with numpy. Install the package and run:

python library_external/shader_legends/TaterHashArt/reference.py

Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.

More from shader legends

See all shader_legends artworks →