In a software-rendered game, the CPU draws every pixel. There’s no 3D card involved: the game works out each frame in its own code and writes it straight to video memory
I think that’s the standard definition. If you mean that this style can be achieved with graphics hardware then that’s a different argument and why your first sentence is deemed contentiousI 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.
That said, historically, software rendering meant non-accelerated passes that could be carried out by a cpu at decent enough FPS.
ps: some could also say that a FPU is not software rendering since early x86 didn't have it in the cpu.
The whole process is standardized with GPU rendering, leading to ways of rendering and content authoring that's quite different from how things used to be, and while definitely possible, modern 'retro' games often render like GPU accelerated games and just disable texture filtering, which doesn't quite give you the look.
He mentions Build games, which are not strictly polygonal.
While general purpose computation exists on GPUs, and the standard rasterization pipeline can be implemented in software, graphics cards have pushed people towards a 'look and feel' which comes partly from standardized data structures, content authoring and rendering approaches, that have made games feel samey.
Whereas with software rendering, essentially you have an array of pixels which you can set to a certain color, and the rest is up to you, which made devs come up with unique ways of rendering and authoring content.
The intricate level designs that were made possible with BSP based tools and are basically 'free' to render in software, had hell of a time making the transition to GPUs, as they rely on traversing the tree while drawing pixels, whereas for the GPU, you need to submit a list of triangles (unless you go GPGPU)
There is some standardization in that, if you issue geometry and sample textures normally, you will be relying on hardware units for rasterization and texture sampling, and those do have a relatively limited set of options for how they work. However, those options encompass most if not all of what 3D engines could ever want or need, even the early 3D ones that had all sorts of hacks. The kinds of things GPUs can't actually rasterize in hardware are things like NURBS or metaballs, but this doesn't matter because the industry settled on triangles[0] as the medium of real-time 3D really early on.
A lot of the look of old 3D games comes down to them doing things the lazy way, and I'm proud to say the lazy way is still very much supported - so long as you turn off features that didn't exist later on and limit yourself. I'm not as familiar with old DOS games, so I'll use the PS1 as an example. The "PS1 look" is very much a result of its incredibly limited rasterizer, whose limitations can be trivially emulated in modern hardware:
1. Don't allocate or bind a depth buffer. You will need to Z-sort your geometry every frame. Part of the "PS1 look" is that some games did it wrong; if you do it correctly you'll be burning performance for no visual benefit. Pick a scheme that breaks in a visually interesting way. Likewise make sure to not allocate any multisampling since the PS1 didn't anti-alias either.
2. Restrict the precision of vertices in your vertex shader by rounding them. The PS1 did vertex math with incredibly low precision and it makes vertices wobble.
3. Restrict the precision of UVs in your fragment shader. PS1 UVs were 0-255, so you want 1/256 precision.
4. Aggressively discard geometry that clips the edge of the viewport. The PS1 did not have proper polygon clipping; you just couldn't render off the end of the viewport, so games had to discard geometry and subdivide polygons to avoid things disappearing. This is another "if you do it well, nobody will notice" thing.
5. Turn off perspective-correct attribute interpolation; this will make your UVs warp and distort at certain angles. You do this with the `noperspective` attribute in GLSL.
6. Disable bilinear filtering when sampling textures.
7. Allocate and render to a low-precision color buffer. Lots of games would change the color depth to match the available VRAM. This is probably the hardest aspect to emulate unless you are actively counting VRAM usage and sticking to realistic values.
8. Bitcrush your textures before uploading them. The same reasoning applies here. Also, don't upload any mipmaps.
9. Lighting was done through vertex colors, which were calculated on the CPU. You don't have to limit yourself to CPU lighting but you do have to make sure lighting is done in the vertex shader.
10. Optional: implement the early model PS1 texture banding bug in your fragment shader.
This will give you a rendering pipeline that is good for basically all purposes except bit-accurate PS1 emulation. Of course, if you were doing bit-accurate emulation, nothing stops you from issuing a screen-filling quad and writing a GPU shader that does software rasterization on the GPU. Or launching a compute shader that accesses the framebuffer arbitrarily - although you do have to worry about memory coherency across warps and workgroups. Texture sampling can also be done "in software" if you so wish - i.e. by doing unfiltered reads to the texture which are glorified array lookups, and then filtering those reads as you wish.
[0] There was a brief moment where quads might have been able to win - artists like to work with them, and Nvidia was shipping quad hardware. But the advantage died very quickly, and quads can be easily converted to triangles - not so much the other way around.
There's no single oldschool look, as people writing software renderers didn't have a sanctioned way of doing so - a lot of them weren't even using triangles, or were using a mix of techniques.
You are describing how to make a game look like the PS1 games, but the PS1 actually had a - somewhat flawed, but unique - GPU which kind of forced the limitations you outlined here, and forced a singular way of rendering.
That wasn't really true with Quake or Duke3D or the PC in general. You just drew to the screen with whatever technique you chose, which resulted in a unique look for each game.
Yeah you can hack configurations or create your own game to mimic this look.
If you read the post you will see it’s not only about the texture sampling, but also the color depth.
OP picked a good headline. You are fighting for semantics nobody cares about, and picking a more complicated synecdoche.
Is that the case?
https://fabiensanglard.net/3dfx_sst1/ has a side-by-side screenshot comparison of the two, and software Quake's colours and lighting look way more rich and vibrant; it's not just smoother textures. It's possible that GLQuake/one of the many source ports since has improved on this though.
Of course I know this is a particular quality of GLQuake and not an actual limitation of hardware rendering. And I agree with in general with the contention that this article is talking about a particular art style associated with mid 90s software rasterizers rather than about "software rendering" itself.
This could have been corrected on the art side, by recalibrating the texture maps to the voodoo gamma levels, and that’s why there are great arcade machines from that era with wonderful graphics (designed for the hardware they were running in production), but GLQuake looks all washed out.
DF Retro has good comparison of software Quake, GLQuake and VQuake (for the Rendition Verite).
(It even had graphic errors, green textures in the faces etc giving everything a very alien look. But that's not what I mean).
There's nothing special about the GPU besides doing certain kind of operations that are very useful for graphics (and AI, among other things) really efficiently. The distinction should never have been "software rendering" vs "hardware rendering", but "what CPU rendering could achieve when GPUs weren't widespread" versus "what GPU rendering has been able to achieve since they became available".
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.
Friends at LAN parties complained how ugly it was and my rebuttal was usually: "I'm afraid it stays unless you can buy me a better video card." The fact that the CRT slowly drifted to a yellow tinge on everything didn't help the asethetics--especially on de_dust. The GPU at the time might have been a Riva 128 ZX.
Video: https://www.youtube.com/watch?v=8TvVMzyxACc
Browser(shareware): https://quake-srp.pages.dev/
I love the graphics in your video, really interesting and fit the vibe of the original game too.
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
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.
TL;DR a software rendered game and a 3D accelerated game from that era looked VERY different, but that difference was largely down to a feature that was often implemented in the software renderer, and was only a couple of lines in the innermost loop. But rarely used outside of a few choice effects due to the massive performance impacts. On 3D accelerators it was free, and default-on.
(I’m an old fart that cut my teeth in programming writing software renderers with the community at Flipcode, if anyone remembers that.)
So when you say "this is incorrect", and also:
> Software renderers can do bilinear filtering.
What do you mean? Nobody is disputing they can. The author is talking, in my opinion, about how software and hardware renderers of that time behaved in practice in games you could buy at the time. It's just that peppering the text with "at the time", "typical" and "in practice" makes for very cumbersome reading.
I'm also an old fart, by the way :) I don't remember Flipcode, but I wrote software renderers for fun and also for my CS coursework. I read my Abrash and my Foley & van Dam, etc. I then lost track of that, time was finite and I had to choose my hobbies more carefully!
E.g.
> Software renderers generally sample textures pixel by pixel, so every texel stays a crisp square. Early 3D cards smoothed textures with bilinear filtering, which looked impressive in 1997 but turns everything soft and blurry to my eye now.
The author is a hobbyist discussing things in context. Early 3D cards, bilinear filtering as done in '97, etc. You cannot take random words and criticize the article. This seems to be a retrogaming hobbyist blog about doing stuff with old hardware and games.
Nitpicking is pointless.
The reason software rendering look different from 3D accelerated games (incl. 3Dfx) is nearest neighbor filtering and low resolution, which were necessary to keep a reasonable framerate. At the time, it was considered ugly, so if your hardware supported bilinear filtering for free, it was turned on, but it didn't have to.
In the time of fixed pipelines (3Dfx to GeForce 3), you couldn't do arbitrary operations on pixels, so some effects, like the kind that are common in the demoscene were software only. So games that used these effects, like Comanche voxels can indeed be thought as representative of software rendering, and they can, of course, be simulated on modern GPUs as everything that was done on software before can.
But the article uses Quake as an example. I may be wrong, but I don't think it does anything that can't be done by a fixed pipeline GPU. In fact, even keeping the same style (nearest neighbor filtering + low resolution), hardware rendering will probably look better because the GPU does proper perspective correction on every pixel. The tricks used by the Quake engine are awesome, but they don't beat raw power.
Yes, of course. That's what I meant. I didn't mean "simulate" as in fake, I meant it more as in "replicate the same effect". Ultimately, hardware and software are equivalent, give or take matters of costs, debugging and performance.
> In the time of fixed pipelines (3Dfx to GeForce 3), you couldn't do arbitrary operations on pixels, so some effects, like the kind that are common in the demoscene were software only. So games that used these effects, like Comanche voxels can indeed be thought as representative of software rendering, and they can, of course, be simulated on modern GPUs as everything that was done on software before can.
Yes, I think that's the spirit in which TFA's term "software rendering" must be taken. The context is old games and their pipelines as they were used at the time, not more recent GPUs or practices.
> The tricks used by the Quake engine are awesome, but they don't beat raw power.
I really don't think the article is contesting this.
It's called "nearest neighbour texture sampling", as opposed to bilinear/trilinear/anisotropic
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.
aka (just) anti-aliasing, we are talking original quake 1 era, after all.