Step46: Doing 3D

The aim of this article is to explain roughly how 3 dimensionnals elements can be represented on screen. Amiga is a very limited machine and doing 3D is very limited. But lot of nice things are doable on Amiga.

Basically, the Amiga hardware have been thought to create 2D games. But it is possible to display 3D world on it. It took time to acheive this but some great 3D demos and 3D games have been done on Amiga 500.

What is 3D ?

3D is the ability to express the «depth» of somes graphic elements. In early days of computers, somes games and demos used tricks to give the sensations of a 3D world.

In 1974 the game Spasim («Space Simulator») can be considered as the first 3D game.

In 1983 Star wars arcade game with wireframe display (and voice digits).

In 1984 Rescue on Fractalus with some landscapes (voxels landscapes), running on the small 8 bits Commodore 64.

1983, I robot from Atari (Arcade game), surely the first 3D game with filled faces.

There are also «fake» 3D representations, like the 2D technic called isometric 3D. An example is Desert Strike on Amiga.

In demos, the first effect that was done in 3D was the starfield.

For example Unit A intro in 1988:

Projection

The first things when you want to do realtime 3D on a computer is to transform point. The transformation convert a point in a 3D world into a point on screen (2D space). This is called a projection.

In today hardware it is very common to do complexe transformation & projection of 3D points. To compute screen coordinates of a 3D object viewed from a camera, you need to transform its local coordinates to screen coordinates going through several transformations:

Local coordinates -> Apply local animation (rotation) -> Apply world translation -> Apply camera rotation and position -> Projection on screen.

The computing imply floating points multiplications and divisions. Sadly the Amiga does not have any floating point computation. Moreover the integer division and multiplication cost a lot of time. Result can be very slow execution. So we used some tricks:

  • Integers to stores the coordinates
  • Replace floating point computing by integer fixed point system (for example int part on 8 bits, decimal part on 8 bits).
  • Sinus and cosinus where precomputed into tables
  • All the above transformation can be baked into one single matrix. Using 12 multiplications per point, you could acheived a full 3D transformation. Of course, the first Amiga 3D were simplified: Only rotating objects, non world translation, no camera. The operations could be reduced to 9 multiplication per points with optimisation. Another trick is to use self modyfying code to get some faster execution. But even with all these tricks, the 3D computing is very expensive.

    Perspective

    The perspective is the 3D to 2D projection that allow farer point to look closer to the center of screen. This give the impression of depth.

    You can acheive this effect by adding an offset and divide by depth of point. This can be pre-computed into a table to get faster result. Starfields effects use this for example.

    Rotation

    For more complexe 3D, you can do rotations of the points in 3D space. For doing this you have to use sinus and cosinus. We compute a matrix and apply it to all points. On Amiga to have fastest running time, self modified code can be used. That means the values of the matrix were diretly changed into the memory so that the code can do immediate multiplications instead of always asking a the values into from memory location (cost more than immediate operations).

    A 2D rotation is:

    A 3D Rotation is the multiplication of 3 rotations around axis X Y and Z.

    (c is cosinus, s is sinus)

    As said, cosinus and sinus can be precomputed into a table. All elements of the formula can also be computed only once, as the three angles are constant for all points. This formula is for rotation. If you also want to add translations, you have to use a 4×4 matrix.

    The cost of such a formula is huge because there are multiplications.

    In term of cpu cycles, here are some comparaisons:

  • ADD in byte (or word) take 4 to 8 cycles (cpu clock).
  • MULS or MULU take 70 cycles.
  • and DIVU 140 cycles.
  • Displaying 3D

    Here are the different possible representations of 3D objects.

    Wireframe

    The first 3D objects where displayed in wireframe. On Amiga, the blitter can draw lines. You only had to compute positions of point. The clipping (lines going out of screen) can be the tricky part here. I'll not explain how to manage this, you can search for some algorithm on the internet.

    Here is a sample of a simple wireframe demo:

    Hidden faces variant:

    Filled faces / Flat shading

    Using blitter, you could also filled the surfaces. The line drawing was planned to support fill (one point per line). This was « easy » to draw vectors then fill them. On Amiga, you have bitplanes. So first filled 3D objects where using few colors (4), but also transparency (mix of bitplanes). This is « glenz » effect.

    As mentionned in this EAB discussion, a sample of 3D filled vectors have been released on Fred Fish #12 public domain disk in 1986. I captured the execution of it:

    Textures

    That’s the tricky part. On Amiga, there was nothing to display textured 3D. To acheive this, you had to compute the 3d polygones pixel per pixel and then convert the result to bitplanes. This is very expensive in computing. Some people used a chunky to planar algorithm. The texture mapping had to be done line by line using a scanline algorithm.

    One of the first textured cube have been done in 1991 in the demo Cub-O-Matic by Spreadpoint:

    Link

    If you want to get more info about how to code 3D on Amiga, here is an excellent page giving all details:

    https://amigasourcecodepreservation.gitlab.io/amiga-real-time-3d-graphics/

    Example of nice 3D demos

    Top to mars (1990)

    An excellent demo by french programmer Thomas Landspurg.

    Odyssey by Alcatraz (dec 1991)

    A mythic demo of 43 minutes, including lot of 3D.

    Example of nice 3D games

    Mercenary (1988) (wireframe)

    Elite (1988) (port from 8 bits computers)

    Carrier Command (1988)

    Excellent game.

    Castle Master (1990)

    Made with the 3D engine FreeScape (8 bits and 16 bits).

    Midwinter (1990)

    Open world game.

    Hunter (1991)

    Open world game.

    No second prize (1992)

    Maybe one of the fastest 3D engine on Amiga at that time.

    Step45 Step47