delta_p_delta_x
This isn't software rendering, it's called turning off spatial anti-aliasing. You can still do that in the modernest of modern games. Software rendering went out of the window because the CPU tends to have other things to do whilst playing the game besides only multiplying 4x4 matrices, which was shifted to the shader cores of GPUs. The look-and-feel that the author is discussing including shadow and texture LUTs can also be done on GPUs by passing the tables in to shaders as constant read-only storage buffers; that is not specific to software rendering. It bears mentioning that many modern software renderers (LLVMpipe/Lavapipe, OpenSWR, WARP) are basically full D3D/OpenGL/Vulkan devices in their own right, including shader compilers.
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.
squidmasterreply
How is it not software rendering? These games shipped without hardware renderers. Yes, they also don't have AA, but how does that make it not software rendering?
spider-marioreply
They mean that what the OP prefers about it is not the fact that it’s done in software. “This” is “the thing the OP seems to prefer”.
BugsJustFindMereply
The point is that the thing that OP likes has nothing to do with whether something is rendered in software or hardware.
the_afreply
"Nothing to do" is a bit strong. It has something to do, and the explanation is in the history of how these games worked.
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.
articulatepangreply
Here’s an analogy. Suppose someone said, “I love manual transmission cars” and then described in detail the physical knobs and dials that all the cars from the 1950s had.
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.
squidmasterreply
Ah, I see. Maybe: somebody says they love audio cassette players, and start talking about the super tactile mechanical buttons and switches that go chunk in a satisfying way. You could rightly object that that you can put buttons like that on an mp3 player. But it's a historical fact that these things are actually linked, in a way that's meaningful to people, namely in their personal nostalgic experiences.
llm_nerdreply
"Software rendering went out of the window because the CPU tends to have other things to do besides just multiply 4x4 matrices, which was shifted to the shader cores of GPUs."
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.
pandamanreply
Not so quickly. The shader cores were a breakthrough from early 2000s. First consumer GPUs were built as same as the 1980s GPUs but everything had been integrated in a single chip.
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.
llm_nerdreply
Parallel processing was fully in force in the very first GPUs, like the Voodoo. Not like a modern GPU with thousands of more flexible shader cores, but the first iteration had a pipeline architecture that saw multiple blocks operating on rendering separate parts of the pipeline in parallel. This was revolutionary. Especially given that CPUs at the time had a single core.
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.
seritoolsreply
yup, it should be renamed to "I Love GL_NEAREST_MIPMAP_NEAREST"
maelnreply
You have to admit, it makes for a less catchy title
Gravitylossreply
Real players know you us the coarsest mipmap level the whole time, so every texture is something like 4 pixels. And 320x200 and directmouse. It's the smooth movement, high fps and direct control that provides the sense of "being there". Not the graphical fidelity.
sm-silversightreply
Is there a video somewhere (or easy download/install on linux) so I can see/play what this looks like
Terr_reply
I think you've almost exactly described my Counter-Strike setup 25 years ago.
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.
hollowoneplreply
Of course you can but I think author’s point is to actually test/evaluate maximum performance of true software rendering on modern machines, and this is fine and refreshing exercise, even with filtering.
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
MisterTea
I recently got to try out Quake 2 on 9front, a Plan 9 fork, which ran surprisingly fast on my very, very modest Thinkpad T410i with a 2.4 GHz dual core i3 at 1440x900. Plan 9 has no GPU support so all rendering is software. Even had a little lan party with other devs. I really enjoyed the software rendering, it bought back early memories of playing Q2 before we bought our Voodoo2. I even used my ploopy trackball to play. Fun times.
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 th
charcircuit
UE5's nanite uses software rendering, but it doesn't look pixelated, does not need a high end computer, and does not require DOS.
originireply
Its probably not correct to state this. Its probably a combination of how nanite itself is doing Lob, lightning etc.
A mix of software and gpu
dist-epochreply
At this point words get blurry. Is using CUDA or a compute shader "software rendering" or not?
joshheitzmanreply
I call it "like software rendering". Its certainly software rendering in spirit since no fixed function rendering hardware is being used.
mvx64reply
Yeah, it may not be in the spirit of 90s software rasterizing, but since you don't offload the transform, lighting, and rasterizing procedures to specialized hardware, you technically do it "with code". The parallelization goes against the spirit though.
stymaarreply
“Software rendering” usually means “doing rasterization on the CPU”, as opposed to “hardware rendering” that is done by the rasterization primitives of the GPU.
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.
0x0203
I share the same opinion as the author. That said, it's also important to remember that the display devices of the time were different than they are now and the sharp pixelated textures we see now would look a bit different on a CRT from that period. The sharp, gritty look that he (and I) admire would have been just a little fuzzier back then.
jerfreply
A tiny bit fuzzier but not in a way that mattered back then. If you're running a software renderer it could well have been at 320x200 and on any monitor that comes out still looking pretty much like an LCD display, with slight blending on the edges technically but still large, large pixels not being blended. Even at 640x480 there was noticeable blockiness not being blended away. Monitors were designed to be sharper than the televisions the consoles were outputting to. Software rendering at anything high enough to be blended looking was a slideshow.
Narishmareply
Unless you were playing on a TV CRT, I don't think so. PC monitors of the time were pretty sharp already.
kbolinoreply
A lot of the fuzziness of TVs vs. PC monitors was down to the poor signaling (RF modulators, composite video). Some lucky/picky folks had TVs with component video (YPbPr) which produced images about as good as VGA monitors (RGB).
However, CRTs do not have fixed pixel geometries, and even when they produced relatively sharp images, they would seem fuzzier or softer in a side-by-side comparison with an LCD of the same size and resolution.