by Xav de Matos, Jan 19, 2011 5:00pm PST

• 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
• Sure thing! It's always interesting to go back to first principals on 3D math, and getting someone else excited about it is a super mega bonus. :)

Let me know if you have any questions about the math, you can post them on shack or just sm me. So if you switch to using homogeneous coordinates like the canonical 3D pipeline, what you would do is:

1) Multiply by the perspective matrix
2) Perform clipping and culling
3) Perform the perspective divide (you'll have some coordinate x, y, z, w, where w is > 0--the perspective divides x, y and z by w, then stores 1/w in w).

What you could consider doing to get "proper" triangle ordering with (hopefully) less of a cost is to do this the way the hardware pipeline does it:

Add a z buffer. This buffer should (conceptually) be a two dimensional buffer of floats that matches your canvas resolution. At the beginning of each frame, you set the values in the buffer to 1.

Then, you take the post-perspective divide z, and you test it against the location in that z-buffer that matches the location you want to write your color to. So if you're going to write out pixel 37, 48, you test in the z-buffer at 37, 48. If the value you have is < the value in the zbuffer (the value you have will be between 0 and 1), you write out the z-value you have and write out the color value.

If the value you compute for Z is greater than the value in the z-buffer, you write out neither color nor z.

After you get that working, you can implement Carmack's old trick to avoid having to clear the buffer every frame, which should get you significant performance benefits.
• good work! : moshman