Building a Tiny 3D Renderer for a Tiny Handheld - KATAVATIS by Cristina RamosView all by Cristina RamosCreator<br>Follow Cristina RamosFollowFollowing Cristina RamosFollowing<br>Add To CollectionCollection<br>Comments<br>Devlog<br>KATAVATIS
Building a Tiny 3D Renderer for a Tiny Handheld<br>KATAVATIS » Devlog
56 days ago by Cristina RamosShare this post: Share on BlueskyShare on TwitterShare on Facebook
Today I want to talk about my journey writing a 3D software renderer for the Playdate .
At the beginning, I didn't have any performance baseline. I had no idea how feasible my idea was, so I started with a simple test: a raycaster.
I had written one many years ago, based on the code examples from Ken Silverman's webpage, and since then it has basically become what I write whenever I want to test the 3D processing power and screen drawing performance of a low-power device.
You don't need much to write, compile, and run this kind of test, and it gives you a rough idea of the device's processing power. More specifically, it lets you benchmark the areas that matter most for a 3D renderer: how fast it handles floats and vector math, how fast it performs memory operations, how quickly it can draw to the screen, and whether there are any issues with setting up and using a framebuffer.
The initial results were worse than I expected. The performance was bad enough that it became clear this was not going to be an easy project.
To be clear, my raycaster was not written with top performance in mind. This was never about getting a raycasting engine working on Playdate . I'm pretty sure that, with enough optimizations, that can be done. The point was to get a feeling of how much of a powerhouse this device is (or isn't).
This test helped me to get a better understanding of the capabilities of the handheld. It was clear that it didn't have enough power to draw 3D scenes at the level of early 3D accelerators, such as the 3dfx Voodoo , or compete with what you can do on the original PlayStation . But there was hope. The Playdate has a small, low resolution screen, and because it uses a 1-bit display, there are huge memory gains to be had.
From the results I was still confident that I could make something that, from a player's perspective, felt close to the 3DO or Sega Saturn era.
I should clarify what I mean by that. When I talk about something similar to a 3DO or Saturn game, I mean the perceived result on screen. I don't mean it in a technical sense, because the hardware of those consoles is very different from the Playdate .
Both the 3DO and Saturn had custom hardware for drawing polygons (i.e. quads) and modest CPUs. Since the graphics hardware was supposed to do most of the heavy lifting, the manufacturers could get away with a cheaper CPU. The downside was that these machines were not very flexible. They were good at rendering graphics in the specific way their hardware was designed for, but struggled when a game needed a different approach. This is one of the reasons why their Doom ports performed so poorly: Doom's renderer was not a natural fit for the way those consoles wanted to draw 3D.
The Playdate , on the other hand, does not have 3D hardware. If we want to render 3D graphics, everything has to be done on the CPU.
There is no polygon sorting. No rasterization hardware. No depth buffer. No automatic clipping of triangles against the view frustum. No texture mapping, filtering or perspective correction. Nothing.
A quick 101 on 3D graphics
Before going further, it's worth explaining what we actually mean when we talk about 3D graphics.
We live in a three dimensional world. Objects have depth, height, and width. They can be far away or close to us, above or below us, to the left or to the right. We are able to perceive these three spatial dimensions and move through them.
But our eyes only receive flat, two dimensional images projected from that world onto the retina. Our brains infer the 3D world through cues such as perspective, motion, scale, shadows, and occlusion.
Computer graphics use similar tricks.
A 3D game does not draw a world in actual 3D. The screen is flat. Even what we call 3D screens still work by displaying flat, 2D images. What we do is process the information that describes a 3D scene, place a camera inside that space, then project the scene onto a 2D plane, in a similar way to how the real 3D world is projected onto the 2D plane of our eyes.
The rasterizer is the part of the renderer that takes the projected geometry and turns it into pixels, which is what we use to draw on computer screens. It's the one that figures out how to paint the textures, handles overlapping polygons, clipping, etc. and writes the results in the framebuffer.
That framebuffer contains the 2D image of what we call a frame, and it is what gets displayed on the screen.
On modern hardware, most of this work is done by the GPU. On the Playdate , since there is no GPU, the CPU has to transform the polygon vertices,...