Now we have a working camera, and triangles are drawn from the most distant to the nearest. We’re getting very close to a complete renderer. The main issue remaining is when we walk into one of the cubes, everything goes haywire. This is down to the division by z in the projection function. If z is 0, then we get infinity as a result and odd results. If z is negative, then we get warped triangles and inverted rendering. What we need to do is detect when triangles are too close to the screen, or are behind the camera and skip rendering them.
Stuff about Pico 8
So now we have a working camera, we can move around and look at objects that are moving independently from us. There are two obvious issues remaining though, firstly, no matter which direction we look at the cubes the same one is always drawn in front. The other is corruption when we walk into them. I’m going to fix the first one now.
As of the last post in this series we had a textured floating cube in space. You could rotate it, move it and zoom in and out. This falls down as soon as you have multiple objects however. That rotation and movement was performed directly on the cube, with the camera effectively staying in place looking down the z axis. We need to pick apart two concepts which are currently tied together. First we need to be able to move and rotate objects in the world, and then we need to be able to move the camera and look at things without them being related to each other.
Now it’s time to add a texture to the cube. I’ve done this with the use of the tline function in Pico 8.
After the last post we have solid triangles. The cube is no longer a wireframe. Unfortunately it’s possible to count the frame rate by eye. In this post I replace the implementation with another approach, called scanline rasterisation, which is significantly faster when implemented with a CPU.
For the latest update to my Pico 8 software renderer I have filled in the triangles with colour so that the cube is no longer a wireframe. To do this I reused the front function in the previous culling post. The function takes three points, a, b, and c. Previously I used the three points of the triangle I was drawing. The function returns true if the points go in a clockwise direction, and false if not. The triangle is made of three lines (a->b), (b->c), and (c->a). For any arbitrary screen pixel, if we use the points of one of the lines and then the coordinates of the pixel the function will return whether the clockwise direction is unchanged. If that direction is unchanged when using the pixel coordinates with all three lines, then that point must be inside the triangle. We can then walk through the pixels of the screen and set a colour when this condition is true.
Part 4 of my ongoing series creating a 3D software renderer for Pico 8. Click here to give it a try, and here to download it. Here are the previous posts:
This is part 3 of me walking through the process of software rendering 3D objects on Pico 8. Click here to give it a try, and here to download it. Here are the previous posts:
This is part 2 of me walking through the process of software rendering 3D objects on Pico 8, click here for part 1. In this post I’m projecting a wireframe cube made up of triangles. Click here to give it a try, and here to download it.
This Pico 8 cart projects the points of a square in 3D space onto the screen. Click here to give it a try, and here to download it.
I made a Pico 8 cart which produces a SNES Mode 7 style floor. The trick is in the function tline, which draws a line between two points, sampling from the map data along the way. You give it the map position to start from, as well as dx and dy values it should use as an increment after each pixel. The other main thing is setting a depth value per scanline, the closer to the bottom of the screen the nearer to the player’s view. The rest is just trigonometry, applying angles to vectors using sin and cos.
I’ve been playing around with Pico 8, making small games and experimenting to amuse myself. It’s a lovely little program which they call a “fantasy console”. This means the games for it look quite similar to something like the Game Boy Advance, they are low resolution, with low fidelity sound and are generally quite compact experiences. It’s actually a program which you run on your computer, with a full development environment built in. It includes a code editor, a sprite designer, a map layout tool as well as sound and music creation tools. Each one is very constrained, but in a way that makes it interesting to use. It forces you to not overcomplicate things. You have to focus on the core idea.