Here’s something I was playing with over the summer and never got round to posting. Most of the WebGL stuff in my tutorials aims at something like realism; this post by my friend and colleague Jonathan Hartley persuaded me that there’s much more to creating interesting 3D stuff.

So let’s take a look at some WebGL code that uses the cross-hatching technique used in drawing, where shading is done using layers of perpendicular lines. Here’s a first example, a cross-hatched sphere:

(Click here for the live version)

The JavaScript code is really very simple — it’s just the moon demo from lesson 11 with the texture and mouse-handling stuff stripped out. The interesting bit is in the fragment shader where, once we’ve worked out how bright the fragment is going to be and put it in a variable `lightWeighting`

, we do this:

gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); if (length(lightWeighting) < 1.00) { if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) { gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); } } if (length(lightWeighting) < 0.75) { if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) { gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); } } if (length(lightWeighting) < 0.50) { if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) { gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); } } if (length(lightWeighting) < 0.3465) { if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) { gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); } }

The interesting thing here is the GLSL built-in variable `gl_FragCoord`

. According to the OpenGL ES 2.0 GLSL specification, this holds "holds the window relative coordinates x, y, z, and 1/w values for the fragment". For our purposes, what matters here is that the *x* and *y* parts hold 2D coordinates that tell us what pixel the current fragment will be rendered to. Given that, a bit of simple geometry lets us work out how to detect whether or not our current fragment lies on a particular line, and that makes it easy to draw increasing numbers of cross-hatch lines as the shadows get darker.

So having done the hard work by writing that shader, it was easy to put together something more fun: a spinning cross-hatched teapot!