upvote
He likes the look of nearest neighbor texture sampling, not software rendering.

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.

reply
Technically you're right, a gpu is just a bunch of ALU and FPU in a way, we just defer computation to a massive array of them so the cpu can do other things, what you do on these gpu cores is up to you.

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.

reply
I think there's more to it. In Quake, the software renderer decides the color of each pixel, based on running some code on the CPU, which can do anything. GPU rasterization is far more standardized, with standards defining how each triangle ought to be sampled at each pixel coordinate (and the fact that you're sampling triangles in the first place).

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)

reply
Modern games look samey because they all want the same result - photorealism - and aren't fussy about using an off-the-shelf solution - i.e. UE5 and Unity. We have absolutely insane levels of control over the rendering pipeline and almost everything is programmable; the GPU is an endless fountain of parallel programming. But in order to take advantage of any of that you have to actually start changing engine code, or write your own renderer, and games don't care because the default UE5 look is "good enough".

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.

reply
However well intentioned your post may be in explaining this, it misses my point.

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.

reply
The author likes the look of the tradeoff made due to the limitations CPU power imposed on the rendering model for real time 3D games 30 years ago.

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.

reply
But if you want to experience GLQuake that looks like software-rendered Quake, that's a simple settings change in your GPU driver, overriding the texture sampling mode. That's literally the only difference. I'm not sure the author is aware that it is a viable option to tweak the hardware rendering this way.
reply
> if you want to experience GLQuake that looks like software-rendered Quake, that's a simple settings change in your GPU driver, overriding the texture sampling mode. That's literally the only difference.

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.

reply
In the caption under the image it explains that the 3Dfx card lacked gamma correction, which is why it looked so saturated. The Voodoo was a pass-through card: it had its own DAC for generating display signal when a full screen 3D game was running, but otherwise your 2D accelerator was used. So on the same machine a software rendered game and a 3D accelerated game had different output even if the frame buffer was identical, due to different circuitry (and the Voodoo card’s circuitry lacking gamma correction made it hella saturated as you see here).

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.

reply
It's not just the gamma correction. Things like water are different in GLQuake.

DF Retro has good comparison of software Quake, GLQuake and VQuake (for the Rendition Verite).

https://www.youtube.com/watch?v=0KxRXZhQuY8

reply
Are you sure? I haven't played enough Quake to know either way, but I did play Deus Ex in software mode (unreal engine), and that had a lot of differences to the other renderers. I very much doubt texture sampling mode alone would reach a similar result.

(It even had graphic errors, green textures in the faces etc giving everything a very alien look. But that's not what I mean).

reply
It's not correct. A notable example is the water effects.
reply
It depends on particular renderer, obviously. Not all software renderers were being given appropriate care.
reply
May be a couple settings. IIRC full bright textures didn't translate well in early GPU renderers. Often they'd appear shaded as if they weren't light sources at all.
reply