# WebGL clipspace point visualization

Above you should see a black square with a little crosshair. The crosshair marks a point in space. This is drawn with WebGL. You can change the position of the point using the sliders to the right, representing four components of the point called X, Y, Z, and W.

By playing around with these sliders, you can discover many things about WebGL!

- The X component moves the point left/right, and the Y component moves the point up/down. So far, so expected.
- Increasing Y moves the point
*up*, not down! WebGL’s Y is opposite to CSS’s Y. - The mysterious W component acts as an inverse scale. As W increases, the point shrinks towards the origin. As W decreases towards zero, the point moves out to infinity. When W is negative, the point doesn’t show (what could negative mean here?).
- The Z component doesn’t make any difference. Z represents the axis perpendicular to the screen. But this distance does not affect the point’s “size” or distance to the origin, as might happen in a perspective view. (The W component is more like a perspective transformation than the Z component!)
- When Z goes out of the
`[-1, 1]`

range, the point disappears entirely! It is “clipped” because it’s no longer in “clip space”, the two-unit cube. This clipping happens*after*W-scaling: a point with Z=2 and W=2 still displays, because the final Z = Z/W = 1.

I implemented the above with a passthrough vertex shader, which passes on the vertex attributes as the vertex position:

```
attribute vec4 coord;
void main(void) {
gl_Position = coord;
}
```

Then, whenever the sliders change, I pass in the six vertices of a 3D crosshair:

```
function redraw() {
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
pos.x-CROSSHAIR_SIZE, pos.y, pos.z, pos.w,
pos.x+CROSSHAIR_SIZE, pos.y, pos.z, pos.w,
pos.x, pos.y-CROSSHAIR_SIZE, pos.z, pos.w,
pos.x, pos.y+CROSSHAIR_SIZE, pos.z, pos.w,
pos.x, pos.y, pos.z-CROSSHAIR_SIZE, pos.w,
pos.x, pos.y, pos.z+CROSSHAIR_SIZE, pos.w,
]), gl.STATIC_DRAW);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.LINES, 0, 6);
}
```

With Vidrio

With generic competitor

### More by Jim

- Your syntax highlighter is wrong
- Granddad died today
- The Three Ts of Time, Thought and Typing: measuring cost on the web
- I hate telephones
- The sorry state of OpenSSL usability
- The dots do matter: how to scam a Gmail user
- My parents are Flat-Earthers
- How Hacker News stays interesting
- Project C-43: the lost origins of asymmetric crypto
- The hacker hype cycle
- The inception bar: a new phishing method
- Time is running out to catch COVID-19
- A probabilistic pub quiz for nerds
- Smear phishing: a new Android vulnerability

Tagged . All content copyright James Fisher 2017. This post is not associated with my employer. Found an error? Edit this page.