So, pretty quiet day today, huh? Oh wait a minute...

### HOT STORIES

• For a while now I've wanted to learn how to do the whole '3d projection onto a 2d viewing area' thing. Like, the actual maths, not using a library.
I've also been spending a lot of time learning how to write javascript 'correctly' (that is, passing jslint, no accidental global variable, even compiling with closure on advanced.)

I present to you the fruits of my labour:
Multicoloured sperm flying around in 3d shooting lasers at each other.

http://jsfiddle.net/ctrlfrk/hNaYu/30/

Thread Truncated. Click to see all 53 replies.

• Looks neat! : guido anchovy
• SPERM WARS : GloriousCow
• Pretty cool dude. May I offer some constructive criticism about the maths? (Apologies if you already are all over this shit).

You don't seem to ever use the w coordinate, which I find surprising. (I haven't really dug into your math yet, though). In 3D rasterization, all 3D vectors really carry around a hidden component: the w component. By default, the value is 1, and in fact if it's ever not 1, then the vector is really normalized so that it is 1 before evaluation.

So the point (1, 2, 37) is really (1, 2, 37, 1). Which is equivalent to (2, 4, 74, 2), assuming I didn't fuck up my multiplication.

This is useful, because then you can represent all of the usual transforms for a 3D point with a 4x4 matrix:
- Scale goes along the diagonal
- Rotation is the upper left 3x3
- Translation is the bottom row (in left-handed matrix operations--the D3D convention)

The one other thing I didn't see you do was the perspective divide. I imagine it's in there somewhere, I just didn't see it. The canonical projection matrix looks like this:

```x 0 0  0
0 y 0  0
0 0 zs 1
0 0 zb 0
```

Assuming you are doing left-handed matrix operations (D3D convention). The 1 in the last column is important: what it says is that you need to just copy the eye-space Z value (or planar distance in camera space) to the W coordinate. The result of this calculation should be 4-component vector in what we call Homogeneous Clip Space. This space is really useful for implementing clipping and culling (for example, you need to clip any value that gets a -w value or interesting things will happen--try it).

There's actually a section of my 3D Vision whitepaper that covers all this stuff in fair detail, mostly because I was tired of rederiving it myself over and over again. The first section of this has a fair amount of detail about the 3D pipeline, including what the matrices look like: http://developer.download.nvidia.com/whitepapers/2010/3DV_BestPracticesGuide.pdf

Cheers, and again: very cool.
• good work! : moshman