website articles
filterable procedurals

## Intro

As described in this article, checkerboard patterns can be filterable analytically, which makes them a great candiadate for quality procedural texturing. Many other patterns accept simple analytic integrals and can therefore be filterable (antialiased) analytically. This article is a short (for now) collection of them. Generalizations are pretty easy, for example getting a variery of dot/line patterns is straightforward, so I have only documented the basic ones for you to combine on your one:

## The List

 Box filtered checkerboard ```float checkers( in vec2 p, in vec2 dpdx, in vec2 dpdy ) { vec2 w = max(abs(dpdx), abs(dpdy)); vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)- abs(fract((p+0.5*w)*0.5)-0.5))/w; return 0.5 - 0.5*i.x*i.y; }``` Box filtered grid ```float grid( in vec2 p, in vec2 dpdx, in vec2 dpdy ) { const float N = 10.0; // grid ratio vec2 w = max(abs(dpdx), abs(dpdy)); vec2 a = p + 0.5*w; vec2 b = p - 0.5*w; vec2 i = (floor(a)+min(fract(a)*N,1.0)- floor(b)-min(fract(b)*N,1.0))/(N*w); return (1.0-i.x)*(1.0-i.y); }``` Box filtered squares ```float squaresid( in vec2 p, in vec2 dpdx, in vec2 dpdy ) { const float N = 3.0; vec2 w = max(abs(dpdx), abs(dpdy)); vec2 a = p + 0.5*w; vec2 b = p - 0.5*w; vec2 i = (floor(a)+min(fract(a)*N,1.0)- floor(b)-min(fract(b)*N,1.0))/(N*w); return 1.0-i.x*i.y; }``` Box filtered crosses ```float crosses( in vec2 p, in vec2 dpdx, in vec2 dpdy ) { const float N = 3.0; vec2 w = max(abs(dpdx), abs(dpdy)); vec2 a = p + 0.5*w; vec2 b = p - 0.5*w; vec2 i = (floor(a)+min(fract(a)*N,1.0)- floor(b)-min(fract(b)*N,1.0))/(N*w); return 1.0-i.x-i.y+2.0*i.x*i.y; }```