The following code looks like @Mark Wibrow's answer but takes only 20 seconds to compile. The idea is that instead of drawing millions of points, we draw thousands of dotted lines with various width
, phase
, pattern
, and shift
, which corresponding to \a
, \b
, \c
, and \d
in my code.

\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{backgrounds,decorations.pathreplacing}
\begin{document}
\def\iterate{400}
\def\rollabcd{
\pgfmathsetmacro\a{(1+rnd)/4}
\pgfmathsetmacro\b{5+5*rnd}
\pgfmathsetmacro\c{\b*rnd}
\pgfmathsetmacro\d{rnd*3}
}
\tikzset{
draw abcd/.style={
white,line cap=round,
line width=\a,
dash pattern=on 0 off \b,
dash phase=\c,
shift={(rnd*360:\d pt)}
},
chalk/.style={
decorate,
decoration={
show path construction,
lineto code={
\foreach\i in{1,...,\iterate}{
\rollabcd
\draw[draw abcd](\tikzinputsegmentfirst)--(\tikzinputsegmentlast);
}
},
curveto code={
\foreach\i in{1,...,\iterate}{
\rollabcd
\draw[draw abcd](\tikzinputsegmentfirst)..controls(\tikzinputsegmentsupporta)
and(\tikzinputsegmentsupportb)..(\tikzinputsegmentlast);
}
},
closepath code={
\foreach\i in{1,...,\iterate}{
\rollabcd
\draw[draw abcd](\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
}
}
}
}
}
\tikz[background rectangle/.style={fill=black},show background rectangle,looseness=0.25]{
\path [chalk] (1/8,2) -- (0,1/2) arc (180:315:1/2) (-1/2,3/2)
to [bend right] (5/8,3/2);
\path [chalk, shift=(0:1)] (1/8,1) to [bend left] (0,0);
\path [chalk, shift=(0:3/2)] (1/8,2) to [bend left] (0,0)
(2/3,1) -- (1/16,2/3) -- (2/3,0);
\path [chalk, shift=(0:5/2)] (0,1) to [bend left] (1,1)
to [bend left] (0,0) to [bend left] (1,0);
\path [chalk] (-1,-3/4) to [bend left] (9/2,-1/2);
}
\end{document}
Possible Optimization
The alphabet is taken from Custom line cap to simulate inked line in TikZ.
The current approach replace each Bezier curve by 32 dotted curves.
For each dotted curve, roll dice to determine
- the
dash pattern
and dash phase
shift
line cap
(either round
or rect
)
- color (either black or white)
It takes 10 seconds to compile
\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{backgrounds,decorations.pathreplacing}
\begin{document}
\def\niterate{32}
\def\rolldice{
\pgfmathsetmacro\rndlinewidth{32/(8+\i)}
\pgfmathsetmacro\rndoff{4+8*rnd}
\pgfmathsetmacro\rndshift{((4-\rndlinewidth)*256*rnd)^.25}
\pgfmathrandomitem\rndcap{cap}
\pgfmathsetmacro\rnddark{rnd<.3?100:0}
}
\pgfmathdeclarerandomlist{cap}{{round}{rect}}
\tikzset{
put dots/.style={
/utils/exec=\rolldice,
line width=\rndlinewidth,
dash pattern=on 0 off \rndoff,
dash phase=(1+\rndoff)*rnd,
shift={(rnd*360:\rndshift pt)},
line cap=\rndcap,
black!\rnddark,
},
chalk/.style={
decorate,
decoration={
show path construction,
lineto code={
\foreach\i in{1,...,\niterate}{
\draw[put dots]
(\tikzinputsegmentfirst)--(\tikzinputsegmentlast);
}
},
curveto code={
\foreach\i in{1,...,\niterate}{
\draw[put dots]
(\tikzinputsegmentfirst)..controls
(\tikzinputsegmentsupporta)and(\tikzinputsegmentsupportb)
..(\tikzinputsegmentlast);
}
},
closepath code={
\foreach\i in{1,...,\niterate}{
\draw[put dots]
(\tikzinputsegmentfirst)--(\tikzinputsegmentlast);
}
}
}
},
}
\tikzset{
A/.pic={\draw[chalk]
(0,-0.55) -- (0.3,0.4) -- (0.6,-0.55);
\draw[chalk](0.1,1/3-0.45) --
(0.5,1/3-0.45);
\path (0.7,0);},
B/.pic={\draw[chalk] (0,-0.45) -- (0,0.45)
to[out=0,in=0,looseness=2.5] (0,0) to[out=0,in=0,looseness=3] cycle;},
C/.pic={\draw[chalk]
(0,0) to[out=90,in=110,looseness=2] (0.5,0.25);
\draw[chalk](0,0) to[out=-90,in=-110,looseness=2] (0.5,-0.25);
\path (0.7,0);},
D/.pic={\draw[chalk] (0,-0.45) -- (0,0.45)
to[out=0,in=0,looseness=2.25] cycle;
\path (0.7,0);},
E/.pic={\draw[chalk]
(0.5,-0.45) --(0,-0.45) -- (0,0.45) -- (0.5,0.45);
\draw[chalk] (0,0) -- (0.5,0);
\path (0.7,0);},
F/.pic={\draw[chalk]
(0,-0.45) -- (0,0.45) -- (0.5,0.45);
\draw[chalk] (0,0) -- (0.5,0);
\path (0.7,0);},
G/.pic={\draw[chalk]
(0,0) to[out=90,in=110,looseness=2] (0.5,0.25);
\draw[chalk] (0,0) to[out=-90,in=-110,looseness=2]
(0.5,-0.25);
\draw[chalk] (0.54,-0.25) to (0.3,-0.25);
\path (0.7,0);},
H/.pic={\draw[chalk]
(0,-0.5) -- (0,0.5);
\draw[chalk] (0.5,-0.5) -- (0.5,0.5);
\draw[chalk] (0,0) -- (0.5,0);
\path (0.7,0);},
I/.pic={\draw[chalk] (0,-0.45) -- (0,0.45);
\path (0.25,0);},
J/.pic={\draw[chalk] (0.2,0.45) -- (0.2,-0.35) to[out=-90,in=0]
(0.1,-0.45) to[out=180,in=-90] (0,-0.35);
\path (0.45,0);},
K/.pic={\draw[chalk]
(0,-0.45) -- (0,0.45);
\draw[chalk] (0.4,0.45) -- (0.02,0) -- (0.4,-0.45);
\path (0.6,0);},
L/.pic={\draw[chalk]
(0,0.5) -- (0,-0.45) -- (0.4,-0.45);
\path (0.6,0);},
M/.pic={\draw[chalk] (0,-0.45) -- (0,0.45) --
(0.3,0.25) -- (0.6,0.45) -- (0.6,-0.45);
\path (0.8,0);},
N/.pic={\draw[chalk] (0,-0.45) -- (0,0.45) -- (0.6,-0.4) --
(0.6,0.45);
\path (0.8,0);},
O/.pic={\draw[chalk] (0.3,0) circle(0.3 and 0.48);
\path (0.8,0);},
P/.pic={\draw[chalk] (0,-0.45) -- (0,0.45)
to[out=0,in=0,looseness=2.5] (0,0);
\path (0.6,0);},
Q/.pic={\draw[chalk]
(0.3,0) circle(0.3 and 0.48);
\draw[chalk](0.35,-0.25) -- (0.6,-0.45);
\path (0.8,0);},
R/.pic={\draw[chalk]
(0,-0.45) -- (0,0.45)
to[out=0,in=0,looseness=2.5] (0.05,0) -- (0.4,-0.45);
\path (0.6,0);},
S/.pic={\draw[chalk] (0.5,0.4)
to[out=160,in=165,looseness=2] (0.3,0)
to[out=-15,in=-20,looseness=2] (0.1,-0.4);
\path (0.65,0);},
T/.pic={\draw[chalk] (0.35,-0.45) -- (0.35,0.45) (0,0.45) -- (0.7,0.45);
\path (0.85,0);},
U/.pic={\draw[chalk] (0,0.5) -- (0,0) to[out=-90,in=-90,looseness=2.5]
(0.6,0) -- (0.6,0.5);
\path (0.8,0);},
V/.pic={\draw[chalk] (0,0.5) -- (0.3,-0.4) -- (0.6,0.5);
\path (0.8,0);},
W/.pic={\draw[chalk] (0,0.45) -- (0.3,-0.4) -- (0.45,-0.1)
-- (0.6,-0.4) -- (0.9,0.45);
\path (1.1,0);},
X/.pic={\draw[chalk]
(0,0.45) -- (0.6,-0.45);
\draw[chalk] (0.6,0.45)
-- (0,-0.45);
\path (0.8,0);},
Y/.pic={\draw[chalk]
(0,0.45) -- (0.3,0);
\draw[chalk] (0.6,0.45)
-- (0,-0.45);
\path (0.8,0);},
Z/.pic={\draw[chalk] (0,0.45) --(0.6,0.45) -- (0,-0.45)
-- (0.6,-0.45);
\path (0.8,0);},
space/.pic={\path (0,0) (0.2,0);},
}
\tikz[every pic/.style={scale=4},scale=3]{
\fill(0,-2)rectangle(9,8);
\begin{scope}[overlay]
\path foreach\X[count=\x]in {A,...,G}{(\x,6)pic{\X}};
\path foreach\X[count=\x]in {H,...,N}{(\x,4)pic{\X}};
\path foreach\X[count=\x]in {O,...,U}{(\x,2)pic{\X}};
\path foreach\X[count=\x]in {V,...,Z}{(\x,0)pic{\X}};
\end{scope}
}
\message{^^J^^J time = \the\numexpr\pdfelapsedtime*1000/65536 ms ^^J^^J}
\end{document}

For this fine of a texture, LuaLaTeX must be used (dynamic memory allocation). For samples=100 or fewer, any modern engine can be used.
Did you reduce the number of samples sufficiently to use pdfLaTeX i.e. to no more than 100?