Procedural Textures with Hash Functions and Hash Playground I'm the sort of person who gets very excited when simple rules create complex behaviour. The other day, I needed a simple hash function that maps $(x, y)$ coordinates to a colour, and found a straightforward equation that ended up being astoundingly rich. Hence this post; to talk about and play with this function. TL;DR: The boolean predicate $(c_x \, x + c_y \, y + c_{xy} \, x \, y + c_{x^2} \, x^2 + c_{y^2} \, y^2)$ $\mathrm{mod} \, m < \tau \, m$, is richly varied and beautiful. For example, varying $c_{xy}$ with the other parameters fixed: For the rest of this post, we'll try to unpick the function. If you'd prefer to play with it yourself, check out the hash playground. The idea I was trying to make a game that obeyed a 2-bit colour palette. With a strict interpretation of the rules, this means no interpolation or antialiasing — the pixels onscreen should only be one of 4 colours. So I needed textures that could align perfectly to the screen. The not-at-all novel solution: Hash the (x, y) screen-space pixel coordinate, and use it to choose a colour. It turns out that this works fine, as long as the camera and viewports are fixed, and this very simple hash function is remarkably varied and interesting: $$(c_x \, x + c_y \, y + c_{xy} \, x \, y + c_{x^2} \, x^2 + c_{y^2} \, y^2) \,\mathrm{mod} \, m < \tau \, m$$ In Python, for example: c_x, c_y, c_xy, c_xx, c_yy = 1, 1, 0, 1, 1 m, t, w, h = 64, 0.5, 128, 128 x = np.arange(w)[:, None] y = np.arange(h)[None, :] h = (c_x*x + c_y*y + c_xy*x*y + c_xx*x**2 + c_yy*y**2) % m < t*m display(PIL.Image.fromarray(h)) A little understanding Let's try to build up the maths to understand some of the structure behind these patterns. We'll call the expression between $()$ the body. Note that everything in this section uses a canvas width of $128$, divisor $m\!=\!64$ and threshold $\tau\!=\!0.5$. What if our body is just $(x)$? The hash won't depend on $y$ and should be $\...
First seen: 2025-04-18 06:15
Last seen: 2025-04-18 09:15