> "3D cards smoothed textures with bilinear filtering"
You can just not do that.
From a programming perspective I do completely get the desire to have the CPU do all the work though - if you want absolutely everything under your control it's easier, and especially if your game is single-threaded.
If you mean rendering a frame entirely in the main memory by the CPU, then there is nothing making it impossible. I mean, most major 3D rendering software still have CPU renderers as an option. Slow, but doable.
P.S: I am using offline renderers here as an extreme example. A game renderer - especially for scenes like Quake’s - are definitely going to be far simpler and cheaper.
Of course, offline rendering is a different story.
Even the standard desktop experience is a 3D graphics application these days.
[1] https://store.steampowered.com/app/5277420/Omega_Transmissio... [2] https://news.ycombinator.com/item?id=45270981 [3] https://totenarctanz.itch.io/a-scavenging-trip
A common "Trick" was to buy cards that had essentially their own processors to handle this stuff - SoundBlasters, 3Com nics, IDE drive controllers that had their own processor (hell, even up to their own OS) since that freed the CPU up for doing actual work - gaming. Even an external or other
CPUs were a bottle neck but most people didnt tax the single core machines doing most daily work (office work, browsing the web) so it was fine, but once you load up a game that needs sound, 3d, networking, disk access all at once it would start stealing clock cycles trying to do all of that in one place.
Way back in the day there were some very impressive (given the technology) arcade ports to things like the Apple ][. That system's audio required running an assembly function that literally touched a memory address over and over again at a specific time rate; each touch flipped the electromagnet on the speaker. So games with theme music had to time slice hanging out in the audio routine versus doing anything else.
I grew up with a copy of Moon Patrol on Apple ][c and I didn't know for years that the theme song isn't supposed to sound like it's being played through a tea kettle.
Sound, like a lot of things, could be seen as a peripheral and a lot of peripherals back then needed their own cpu to perform well. One interesting fact I recently learned is the commodore 64 was so resource starved, the external floppy drive you could buy had its own 6502, just like the C64 did as its main processor. It just had to off-load that to another cpu because its own cpu was too busy to reliably run a disk drive. There are other reasons for this like commodore's experience in drives previously was this kind of architecture so they went with what they knew, but its a bit interesting to know your floppy drive was essentially another C64 with its own commodore OS and ram and 6502.
Programmable shader pipelines weren't a thing until Geforce 3 in 2001.
The tech specifics covered have been out of use for decades. But, it's still a very fun read about thinking through the process of optimization.
The Build engine's rendering was stunningly simple (and dare I say: elegant). You could run hundreds of instances of Shadow Warrior on a single EPYC (since they mentioned Xeon) at that resolution and framerate if you rewrote the engine with modern mechanical sympathy in mind. On a modern desktop CPU it'd probably be over a hundred instances.
People, including many programmers, just don't grasp how much power we have under the hood nowadays...
Edit: my old iPhone SE, fully utilized, can produce the same GFLOPS as the Cray T3E (the one with thousands of DEC Alphas inside). This is our reality.
Additionally Shadow Warrior used some newer rendering techniques, so it's possible they don't scale well to higher resolutions.
Sources: * https://framebuffer.io/project/quake * https://browser.geekbench.com/geekbench2/327940 * https://browser.geekbench.com/geekbench2/529270
Presently, Plan 9 in general lacks 3D graphics but has an in-kernel 2D rendering engine referred to as devdraw. Quake 2 software rendering is done in-engine by rendering full frames to a bitmap displayed by devdraw. A fun experiment was to rcpu into my industrial DIN rail PC, a 1.2 GHz 4 core Atom, from the Thinkpad and play Quake 2. When I run Quake 2, it runs on the CPU server but graphics are sent to my laptop. However, since Q2 is rendered in-engine on the remote iPC, full frames are copied over gigE to my laptop. Q2 full screen was stuttering badly but at about 1/4 screen size it was surprisingly playable.
An other example is a port of cave story done by a 9dront dev where he integrated devdraw so the game renders by loading its assets into devdraw and issuing rendering commands. It is likely the first Plan 9 native game. It plays perfectly over an rcpu session at full screen as the rendering is done by the client side devdraw.
Another 9front dev is doing a lot of graphics work and implemented affine warping in devdraw which is useful for rapidly transforming bitmaps, e.g. scaling the output of the gameboy emulator and Doom. He and others are interested in implementing a concurrent 3D rendering software devdraw engine as we have many-core machines now. When GPU's first hit the streets, we were on single core machines. SMP machines were not affordable by mere mortals when the 3Dfx Voodoo hit the market. So the idea is, why struggle with the gargantuan task of implementing a "modern" GPU stack when you have all these CPU cores now? Why not take a step back, think about what we have learned, and extract all the performance we can from modern many-core CPUs with all sorts of vector extensions. In a Plan 9 context, you could run the game on a many core machine to handle game logic and play remotely with a bigger many-core spraying pixels at a display. Distributed gaming. Might even be able to do multiplayer with a single engine instance with multiple rendering clients attached. Fun system to play with.
Amazing game BTW, best shooter I've played in many years. I never really got into build engine games back then, so it's not just my rose-tinted glasses, that game is a masterpiece.
That said, the Build Engine had software voxels in 1997. Which was pretty cool.
(Then LLMs started taking off and I decided I needed to reskill out of the industry, just in case)
I can add more:
Unreal (and Unreal Tournament), Thief, Quake II (a slight improvement over Quake), Half-Life (a great improvement over Quake), Shadow Warrior, Any modern port of Doom supporting software rendering, Heretic, Hexen, Descent, System Shock, Homeworld.
That colored lighting, though.
Why do you believe these things? In VFX and film, the GPU shaders and rendering is identical to CPU, they use the exact same programmable shaders on either side, so there is no difference in look or capability. Today’s GPUs have out of core streaming and caching and access to host memory. Pixar showed off their pixel-matching between GPU and CPU at Siggraph this year, and mentioned that today’s consumer GPUs are big enough to render IIRC ~98% of their scenes without much ‘out-of-core’ tech. Lots of film and VFX studios are using GPUs in production today to render pretty big shots. I think your story is a bit out of date; GPUs being size limited was somewhat true in the past, but is quickly going away. The CPU vs GPU look question has never been true for VFX or film, and was only true in games if you chose different rendering algorithms.
Now that will truly blow his mind, at least on this setup and older games.
The ability to shift resolutions natively was neat, though, I missed that in the pre-4K days.
The original Marathon allowed you to look up and down, but it wasn't actually tilting the camera frame; it was applying a distortion on the field of view and then basically vertical scrolling the render target. Essentially, you can think of it like you were playing the game in vertical phone mode all the time but you were looking at the middle third of that possible output domain, and looking up and down pretty much just scrolled what you were looking at and applied a trapezoid transform.
This is why you couldn't look straight up or straight down, the trapezoid transform would become painfully obvious quickly and the actual algorithm did not really tilt your field of view.
But it was good enough that they could slap it on the box as a novel feature for Wolfenstein style first person shooters.
(And I actually do like their sound, but I wouldn't want to be stuck with only tubes)
I've softened on the issue of non-white lights, but I 100% am still full of nostalgia about unflitered low-res textures.
Nanite is a bit weird because it doesn't use the hardware rasterization of the GPU, but it's still doing rasterization on the GPU, so it doesn't really fit this dichotomy.
A mix of software and gpu
You're not doing traditional application programming once you get into 3D graphics. You are driving a microcomputer at arm's length. Every aspect of that challenge comes into play, from the fact that it's a black box to how you can have it working perfectly in one configuration of hardware, and then find it doesn't work on another configuration.
My favorite reasons for this include "there is a legitimate bug in the closed-source shader compiler" and "this graphics card advertises a capability but in reality it implements it in software so if you turned that flag on your render speed suddenly went to seconds per frame."
The CUDA era helped some with this problem because there was suddenly massive pressure on making the GPU into less of a bundle of pipelines and specialty hardware accelerators strapped together and more into standardized massively parallel fabric, because card manufacturers suddenly found themselves not wanting to be left out in the cold if they invested their time in building a very very fancy specialty hardware circuit for doing texture manipulation or something... And that proved to be useless for mining Bitcoin, or whatever they suspected might replace Bitcoin in the future. I think there are far less gotchas now regarding weird architecture than there were in the 2010s.
Also, modern spatial anti-aliasing works by multisampling within a pixel (or even neighbouring pixels) and taking the average, rather than filtering across singly-sampled pixels, which massively reduces the quality. Not to mention temporal and machine learning AA techniques including DLSS, XeSS, FSR, and all the TAA implementations in many games.
This actually what I have also returned to in my latest demoscene demo: https://www.pouet.net/prod.php?which=106969
It’s 100% software rendering on CPU just multithreaded. But no metal/direct3d just framebuffer and rest is yours routines… and I actually added bilinear filtering…
Still fun project to do and remind yourself about fundamental algorithms behind elementary 3D graphics
I really ought to have been more specific with my first sentence to ward off any hair-splitting.
The author claimed to love software rendering, but the examples given to highlight the supposed positives of software rendering can all be achieved on GPUs. If the author had instead highlighted the ability to easily debug and inspect the inner workings of the rasterisation pipeline with a software renderer, that might have been a much more relevant argument.
You can do nearest neighbor in hardware rendering and you can do bilinear in software rendering. Rendering mode and texture sampling are two totally different things.
(It even had graphic errors, green textures in the faces etc giving everything a very alien look. But that's not what I mean).
Any look in older games, 2d or 3d, can be achieved on modern GPUs, so that seems like a vacuous thing to state.
That's unfair, especially if you read his other articles.
> Someone unfamiliar with graphics
... is probably not the intended audience of a hobbyist, specialized blog such as the one we're discussing.
It turns out what they like is physical knobs and dials. You can have those in automatic transmission cars. It so happens that most modern automatics also have shitty touchscreens.
(I know this analogy isn’t precise because there was a long period of automatics with physical controls, but bear with me.)
The point is that there’s nothing _inherent_ to software rendering that’s responsible for the thing he likes. The distinction is useful because, for example, he could go seek out modern games with the look he likes. Or make games. And if he thought the thing he likes comes from having a software renderer, he’d leave a lot of performance and power efficiency on the table for no good reason. He likes a certain rendering style that’s equally achievable with both GPU and CPU rendering. The choice of hardware should probably be driven by considerations like performance, debuggability, platform support, availability of libraries, etc.
Can it be simulated on GPUs? Sure. But it was typical of software renderers of that era, and NOT typical of GPUs, and it has to do with how they were used.
These days you can use different presets to override those choices, and have your 8K, 240Hz Quake look software rasterized, if you want.
Incorrect how? It's correct in that software renderers of the time TFA describes mostly looked like this, and GPU renderers didn't (of course, they weren't called GPUs back then), and there's a reason for this. Even you admit it later in your comment.
So saying "it has nothing to do" with software renderers (of the time) is wrong. It has something to do with how software renderers vs GPUs were used during that era in practice. It's also true you can simulate one with the other, but that doesn't make it incorrect or unrelated.
> So to show off, every 3D game back then turned it on (an OpenGL/Glide/D3D configuration option) and everything got smoothed out, often with no option to turn it off. That's why it ends up looking different
So it had something to do after all! So TFA has a point. He means software renderers in the sense you're describing here, and it's clear from the text. He's not implying you cannot use a GPU to achieve the same result.
aka (just) anti-aliasing, we are talking original quake 1 era, after all.
Hardware rendering took over because generating a 3D scene is embarrassingly parallel, and the industry quickly learned that you can have thousands of reasonably simple "cores" that can divide and conquer a scene in parallel. There was a no way a general purpose CPU could keep up.
It is the sheer amount of compute and memory bandwidth that mogs a CPU but the parallel processing doesn't help much, at least in realistic 3D: an 8 core AVX-512 march CPU has an order of magnitude more SIMD lanes than something like RSX in PS3 yet it still wouldn't be able to match its performance in rendering textured z-buffered triangles. 3D graphics can really go wide only on wireframe/points, z-buffer forces sequencing between polys so the parallelism there is very limited.
I'm not sure what the PS3 comparison is for, or why we're comparing a 2026 AVX-512 CPU with a 2006 gaming console. Okay? A modern GPU can obliterate any CPU in SIMD, presuming you conform with the types it wants. Add that it's weird to bring up as AVX and other SIMD techniques are basically the same sort of architecture, parallelizing a problem.
> 3D graphics can really go wide only on wireframe/points, z-buffer forces sequencing between polys so the parallelism there is very limited.
Rendering a 3D is scene is the very definition of embarrassingly parallel. While optimizers can cull the scene, you know that the entire depth within the frustum (there are a variety of optimizing techniques to minimize the overdraw, but it's a part of rendering a scene) is "rendered" and in amalgamation the Z-buffer values are compared and discarded, blended, or whatever? It is an extraordinarily parallel operation.
Voodoo Graphics came out in 1995, we had commercial GPUs since early 1980s. Also it's funny that you believe it was "full force" parallel because specifically Voodoo (SST-1) drew a single pixel per clock (and had no geometry processing) so it was not parallel at all, even inside a poly. This statement shows your level of expertise though.
> Voodoo Graphics came out in 1995, we had commercial GPUs since early 1980s.
I mean, if you think you're going to get me in a gotcha, you should know that the first thing we considered a "GPU" came out three years after the Voodoo. The GeForce 256.
But since we're talking about gaming, the first real 3D accelerator in that market was the 3dfx Voodoo, and it revolutionized gaming because even though we had graphics cards, their abilities were laughably limited (blitting was a big feature).
> so it was not parallel at all
You, uh, really should look this up. Are you consulting an LLM or something, because it's like someone who has no idea what they're talking about just randomly saying stuff. PS3! AVX-512!
"drew a single pixel" is a funny comment that kind of gives away the game. Do you have any idea what is involved in drawing "a single pixel"? This is rhetorical, because you seem to have no idea at all.
I'm just going to ignore you, but Christ you know you don't have to double down on this stuff.