A 3D Rasterizer For Embedded Devices

Once upon a time, doing graphics on a microcontroller was challenging, to say nothing of the concept of going into three dimensions. But modern microcontrollers are far more powerful, and you might find yourself wanting to do all sorts of graphical wizardry with one. To that end, you might find Jet useful.

Created by [CubeCoders], Jet is a compact 3D rasterizer built for modern chips like the ESP32 and STM32. It’s dependency free, relatively tiny, and is written in C++17 with an eye towards working well on memory-limited platforms. It runs entirely in software, uses only integer arithmetic, and is built around 16-bit RGB565 color — intended to make it easy to use with parts like the ST7796, ILI9488, and other similar displays interfaced via SPI.

As a point of reference, on a ESP32-S3 Jet can render around 650 on-screen triangles (post-culling) at 60 frames per second on a 480×320 display, or 1300 triangles at 30 FPS. The developers note that 3D performance lands somewhere between the Sega 32X and Sega Saturn — not bad for a microcontroller you can buy for under $20. The Wipeout-like demo shows off the capabilities of Jet rather fantastically, we think.

You’d be foolish to expect your next microcontroller project to render Crysis. However, if you want some retro 3D graphics for your next ESP32-based build, you might just consider exploring what Jet can do for you.

Continue reading “A 3D Rasterizer For Embedded Devices” →

Investigating The S3 Virge’s Reputation As A 3D Decelerator Card

The special 512x384 mode with S3 card installed. (Credit: Bits und Bolts, YouTube)
The special 512×384 mode with S3 card installed. (Credit: Bits und Bolts, YouTube)

Back in 1996 the 3D gaming market on PC was beginning to heat up, with hot new titles like Tomb Raider coming out that year and requiring much more graphics power than what was needed for old titles like Doom and Duke Nukem 3D to experience good graphics. Thus you had to pick some kind of 3D accelerator card to buy. Here a common joke was that of the available options, the S3 Virge GPU was so bad that it was actually worse than running in software rendering, but was this true? Cue [Bits und Bolts]’s investigation to finally put this myth to rest.

On software rendering mode a zippy Pentium 166 would struggle to render at 640×480 resolution, so if you wanted more than 320×240, or really knock down graphical fidelity, you had to get that 3D accelerator card. After combining a P166 with an S3 Virge/DX – a minor update to the original Virge – the Tomb Raider game was first compared while running in 512×384 resolution, which the game offers you with an S3 card installed along with bilinear filtering.

After hitting a capped 30 FPS on that first test, 640×480 was tried and hit a solid 15 FPS with bilinear filtering enabled, but the conclusion is basically that the special 512×384 resolution mode is pretty good. Perhaps the main causes of the myth was the wide variability in quality of the various GPUs using the S3 Virge chip, as well as trying to run at anything other than this special resolution which appears to target the card’s strengths.

Continue reading “Investigating The S3 Virge’s Reputation As A 3D Decelerator Card” →

The 3DFX Voodoo Lives Again In An FPGA

The 3DFX Voodoo was not the first dedicated 3D graphics chipset by any means, but it became the favourite for gamers among the early mass-market GPUs. It would be found on a 3D-processing-only PCI card that sat on the feature connector of your SVGA card. The Voodoo took any game that supported its Glide API into the world of (for the time) smooth and beautiful 3D. They’re worth a bit now, but if you don’t fancy forking out for mid-’90s silicon in 2026, there’s another option. [Francisco Ayala Le Brun] has implemented the 3DFX Voodoo 1 in SpinalHDL for FPGAs.

Continue reading “The 3DFX Voodoo Lives Again In An FPGA” →

Real-time Shader, Running On A Game Boy Color

[Danny Spencer] has a brilliant graphical demo that, like all great demos, flexes a deep understanding of the underlying system: a real-time 3D shader on the Game Boy Color.

If you’re not familiar with shaders, they were originally mathematical lighting models (hence the name) and are an integral part of the modern 3D graphics pipeline. One no longer draws pixels directly to a screen to represent objects. Instead, 3D object data is sent to the Graphics Processing Unit (GPU) which handles the drawing. Shaders are what control things like an object’s lighting, textures, and more.

Implementing even a basic real-time shader in software on a Game Boy Color is pretty wild. Not only is it a pixels-and-sprites (and not 3D graphics) kind of system, but the Game Boy’s SM83 CPU doesn’t even have a multiply instruction, nor does it support floats. As [Danny] puts it: given that the entire mathematical foundation of his shader rests on multiplying non-integer numbers, he had to get creative. That makes his demo a very round peg in an extremely square hole.

In the case of [Danny]’s demo, the user can manipulate the position of, and lighting around, a classic Utah teapot in real time. He explains the workflow and shows how the process can be applied to other objects. The ROM is available on GitHub and there’s a video, embedded below.

[Danny] is no stranger to performing feats of technical prowess that are as creative as they are playful, like implementing a working adding machine in a DOOM level.

Continue reading “Real-time Shader, Running On A Game Boy Color” →

Ray Marching In Excel

3D graphics are made up of little more than very complicated math. With enough time, you could probably compute a ray marching by hand. Or, you could set up Excel to do it for you!

Ray marching is a form of ray tracing, where a ray is stepped along based on how close it is to the nearest surface. By taking advantage of signed distance functions, such an algorithm can be quite effective, and in some instances much more efficient than traditional ray marching algorithms. But the fact that ray marching is so mathematically well-defined is probably why [ExcelTABLE] used it to make a ray traced game in Excel.

Under the hood, the ray marching works by casting a ray out from the camera and measuring its distance from a set of three-dimensional functions. If that distance is below a certain value, this is considered a surface hit. On surface hits, a simple normal shader computes pixel brightness. This is then rendered out by variable formatting in the cells of the spreadsheet.

For those of you following along at home, the tutorial should work just fine in any modern spreadsheet software, including Google Sheets and LibreOffice Calc. It also provides a great explanation of the math and concepts of ray marching, so is worth a read regardless your opinions on Excel’s status as a so-called “programming language.”

This is not the first time we have come across a ray tracing tutorial. If computer graphics are your thing, make sure to check out this ray tracing in a weekend tutorial next!

Thanks [Niklas] for the tip!

Signed Distance Functions: Modeling In Math

What if instead of defining a mesh as a series of vertices and edges in a 3D space, you could describe it as a single function? The easiest function would return the signed distance to the closest point (negative meaning you were inside the object). That’s precisely what a signed distance function (SDF) is. A signed distance field (also SDF) is just a voxel grid where the SDF is sampled at each point on the grid. First, we’ll discuss SDFs in 2D and then jump to 3D.

SDFs in 2D

A signed distance function in 2D is more straightforward to reason about so we’ll cover it first. Additionally, it is helpful for font rendering in specific scenarios. [Vassilis] of [Render Diagrams] has a beautiful demo on two-dimensional SDFs that covers the basics. The naive technique for rendering is to create a grid and calculate the distance at each point in the grid. If the distance is greater than the size of the grid cell, the pixel is not colored in. Negative values mean the pixel is colored in as the center of the pixel is inside the shape. By increasing the size of the grid, you can get better approximations of the actual shape of the SDF. So, why use this over a more traditional vector approach? The advantage is that the shape is represented by a single formula calculated at many points. Most modern computers are extraordinarily good at calculating the same thing thousands of times with slightly different parameters, often using the GPU. GLyphy is an SDF-based text renderer that uses OpenGL ES2 as a shader, as discussed at Linux conf in 2014. Freetype even merged an SDF renderer written by [Anuj Verma] back in 2020. Continue reading “Signed Distance Functions: Modeling In Math” →

OpenGL In 500 Lines (Sort Of…)

How difficult is OpenGL? How difficult can it be if you can build a basic renderer in 500 lines of code? That’s what [Dmitry] did as part of a series of tiny applications. The renderer is part of a course and the line limit is to allow students to build their own rendering software. [Dmitry] feels that you can’t write efficient code for things like OpenGL without understanding how they work first.

For educational purposes, the system uses few external dependencies. Students get a class that can work with TGA format files and a way to set the color of one pixel. The rest of the renderer is up to the student guided by nine lessons ranging from Bresenham’s algorithm to ambient occlusion. One of the last lessons switches gears to OpenGL so you can see how it all applies.

Continue reading “OpenGL In 500 Lines (Sort Of…)” →