News for hackers. Stuff that matters.
Re:Building a PS1 style retro 3D renderer by moth-fuzz on Wednesday December 08, 2021 @12:24PM (#29487606)
This is an excellent article, a good insight into the particularities of the hardware. I particularly admire the explanation of why the polygons snap to the pixel, and why that's not the fault of floating-point mathematics but rather the rasterizer itself. One thing the article approaches, but doesn't really quite get to the bottom however, and which is the crux of all the ps1's 'flaws' is that its GPU was 2-dimensional fundamentally. That's why things snap to pixels, that's why the textures do not have a depth component and are thus not perspective-correct, that's why there is no z-buffer, because it had no z-coordinate. Essentially, every single PS1 game 'faked' 3D by using the GTE (which was separate from the GPU) to project 3D points and polygons into a 2D rasterizer. And it worked quite well! For the time.

Another thought - I also wrote a similar renderer under similar constraints a while back, just for funsies, and I'm wondering what would have came if I thought "I should write an article about this". I generally don't think to write articles over every side project I do, what's the impulse for when someone decides to detail their work to the internet?

Re:Building a PS1 style retro 3D renderer by munificent on Wednesday December 08, 2021 @12:45PM (#29487879)
> what's the impulse for when someone decides to detail their work to the internet?

When it comes to writing, I think the biggest factor that determines if/what/and how you write is the audience you imagine. When you write, you sort of picture yourself telling the story to someone. And the way that scene plays out in your mind depends entirely on who that person is.

If your mental image of the audience is "some random Internet user whose interests are different from mine", then you can't imagine them standing there patiently while you laboriously walk through all the details of your renderer. So you don't.

But if you imagine an audience that is "another retro renderer enthusiast who has similar projects", then you can imagine them getting hyped up by what you're saying and gleaning bits of useful stuff from it that they can apply to their own side projects. It almost feels wrong to not write it and let them down.

Re:Building a PS1 style retro 3D renderer by akdas on Wednesday December 08, 2021 @03:02PM (#29489706)
Adding to this, if you imagine the audience is _you_, then you might feel motivated to write the article you _wished_ you had before embarking on your project. That audience falls under your second one ("another retro renderer enthusiast who has similar projects"), but maybe is even more targeted.

One advantage of this is being able to look back on previous projects in the future, as a form of documentation. That helps me pick up on a project I haven't worked on in a bit. True, you don't need to publish the documentation publicly, but since I wrote it, putting it up publicly is almost no effort now that I have a blog.

Re:Building a PS1 style retro 3D renderer by vondro on Thursday December 09, 2021 @05:57AM (#29496029)
I'd add there is a third category, "curious technology enthusiasts", that just like to read well-written article on some new topic.

I personally am not "retro renderer enthusiast" nor have similar project, but this article was joy to read.

Re:Building a PS1 style retro 3D renderer by munificent on Thursday December 09, 2021 @01:10PM (#29500844)
That's a good audience too. You'll note that choosing this one significantly changes how you'd write: You would naturally find yourself including a lot more context and background information because you don't assume the reader has it already.

Either audience choice is fine, I just think it's interesting how it impacts the resulting writing.

Re:Building a PS1 style retro 3D renderer by flipacholas on Wednesday December 08, 2021 @01:41PM (#29488623)
> Essentially, every single PS1 game 'faked' 3D by using the GTE (which was separate from the GPU) to project 3D points and polygons into a 2D rasterizer.

While it's true that the PS1 handles perspective projection through the GTE (as the GPU is a primitive rasterizer, after all) I don't think it's fair to call it 'faked 3D' since, in my understanding, 3D projection is another fundamental stage in the graphics pipeline (our displays are 2D grids of pixels, so we need to transform the 3D world into something it can be displayed there). Other consoles like the Nintendo 64 provided more capability on the GPU side (the RCP) which allowed to move part of the matrix operations away from the CPU chip.

Be as it may, I've seen the 'fake 3D' claim before and I'm starting to wonder if I'm missing something in my understanding of this technology, maybe someone can offer a third opinion?

P.S I'm the one that wrote https://www.copetti.org/writings/consoles/playstation which is referenced at the bottom of the article (the 'Other reading'), I'm glad the author found it helpful (or interesting)!

Re:Building a PS1 style retro 3D renderer by codeflo on Wednesday December 08, 2021 @04:54PM (#29491037)
Fake/real is not the most precise terminology, but I think it gets the important point across, so I’ll use it.

In a "real 3D" rasterizer, you interpolate the depth coordinate for each individual pixel. You need this value to perform two steps in the pixel pipeline that are required to get the correct look: First, you use the depth coordinate the perform depth testing (reject pixels that should be hidden). Then, you use it to perform a perspective correct texture lookup (make straight lines on the texture obey the laws of perspective).

If you throw out the depth coordinate anywhere earlier in the pipeline, as the PS1 did, you can’t do either of those things, so you get artifacts where objects flicker and warp when rotating. The rasterizer really needs to be "3D aware" right until writing out the final pixel values.

Note that both artifacts can be lessened, to some degree at least, with workarounds. For depth testing, you simply sort the polygons (which doesn’t work in every case, as triangles can overlap in cycles). And for the texture lookup problem, you subdivide the polygons (this helps because the vertex calculations are perspective correct, but it's expensive and you'd need infinite subdivision to fully solve the problem).

As an aside, the PS1 had another issue where the rasterizer didn’t support subpixel precision, which also leads to artifacts. But IMO that’s mostly unrelated to the 3D coordinate problems — 2D games need that as well to get smooth movement.

Re:Building a PS1 style retro 3D renderer by moth-fuzz on Wednesday December 08, 2021 @02:33PM (#29489320)
> Be as it may, I've seen the 'fake 3D' claim before and I'm starting to wonder if I'm missing something in my understanding of this technology, maybe someone can offer a third opinion?

I agree that all 3D is 'faked' in the sense that it's drawn to a 2D grid of lights eventually, I guess it just depends on where in the pipeline you make that fundamental transformation. I only meant faked in that the GPU itself is 2D, whereas the GTE is just math. So it's kinda like doing CSS transformations to make a web page all 3D-looking (a gross understatement I know, but, nevertheless). Though, semantically, I guess the '3D' part of a modern GPU is also 'just math'. Well now you've got me thinking about it harder...

Wonderful article by the way! I've read yours a few times myself.

Re:Building a PS1 style retro 3D renderer by yumaikas on Wednesday December 08, 2021 @02:32PM (#29489288)
I could see an argument being made for 'fake 3D' pretty strongly here. DF Retro has a few videos comparing various consoles, and one of the things that the PS1 and Saturn both got wrong, IIRC, was that textures would warp*, because the 3D look was being provided by affine transforms (as I understand, I may be misremembering the details), rather than perspective correct rasterization.

So, like, the vertexes are in the right spots, but the texture mapping is off. So it kinda depends on if you need texture mapping to be perspective correct to consider a given example of 3D "real" vs "fake". Dark Forces also has perspective warping that happens in it's engine when you look up/down, as an example.

* https://youtu.be/VutzIK3DqZE?t=341 DF Retro analyzes ports of Tomb Raider

Re:Building a PS1 style retro 3D renderer by codeflo on Wednesday December 08, 2021 @06:18PM (#29491869)
Exactly, straight lines on a texture should obey perspective (think rows of bricks on a wall). I think this wasn't as widely understood back then, but notably, id software already got it right a few years earlier in the original Wolfenstein.

Great link. The artifacts are especially apparent when the walls are near the camera, for example at this timestamp: https://www.youtube.com/watch?v=VutzIK3DqZE&t=398s And note that here, the seemingly flat walls are already heavily subdivided into smaller polygons to lessen the impact of the problem. (Why they wouldn't then make use of those additional polygons to include more geometry details for free is beyond me, however.)

Re:Building a PS1 style retro 3D renderer by AnIdiotOnTheNet on Wednesday December 08, 2021 @06:51PM (#29492151)
The way you've worded this makes it sound as though programmers of the era were somehow unaware of perspective mapping, which I can assure you is not the case at all. Affine texturing was a tradeoff of performance, nothing more.

Wolfenstein's correct texture mapping is due to it using raycasting in a 2D plane and rendering scaled vertical strips of texture, which just happens to be perspective correct because you only ever have surfaces at 90deg angles in the vertical.

As to why those extra triangles weren't used for detailing, it's likely because that would take up extra level data. Tessellation of an existing triangle into smaller triangles doesn't.

Re:Building a PS1 style retro 3D renderer by rasz on Thursday December 09, 2021 @02:08AM (#29494692)
From the horses mouths (minus Abrash/Carmack) 'HandmadeCon 2016 - History of Software Texture Mapping in Games' https://www.youtube.com/watch?v=xn76r0JxqNM

Wolfenstein and Doom are 100% correct because Carmack 'cheated' by deciding to never look down/up or draw slopes :-) so whole game is drawn with 'lines of constant Z'. Or as they put it

Chris Hecker (Microsoft/Maxis/etc): that's a classic Carmack thing which is like Fuck those general problems, Im gonna solve this other problem perfectly

John Miles (ORIGIN/Miles Design/etc): Its all about not doing the math, we were still at a point in time when you won by not doing the math

Re:Building a PS1 style retro 3D renderer by xgkickt on Wednesday December 08, 2021 @01:28PM (#29488455)
The GTE truncated too early, and in too many places and there is a register for adding a fraction to the post-perspective-pre-truncate result to round instead. I didn't implement this back in the day, but thought about scaling the target dimensions in the GTE (watching for overflow) to get 1 bit of fraction back to refine the screen coordinate.
Re:Building a PS1 style retro 3D renderer by mywittyname on Wednesday December 08, 2021 @04:59PM (#29491100)
> what's the impulse for when someone decides to detail their work to the internet?

The company I work for considers this kind of writing to be fundamental to being a considered a principal engineer. I can't imagine they invented this idea; it's probably relatively common in the startup world.

While this might not have been the author's motivation, having a popular tech blog certainly doesn't hurt one's employment prospects.

Re:Building a PS1 style retro 3D renderer by jayd16 on Wednesday December 08, 2021 @03:21PM (#29489968)
>that's why there is no z-buffer, because it had no z-coordinate

Z-buffer is just an array of values you can sample, often as a texture. There is no inherit coordinates, unlike, say, vertices. Z-buffer is a 2d map anyway. The offset into that buffer would be the x and y.

Or do you just mean there's no hardware accelerated z-buffer?

Re:Building a PS1 style retro 3D renderer by codeflo on Wednesday December 08, 2021 @05:53PM (#29491632)
In early 3D hardware, the Z buffer was a bit more special cased than it is now, where you quite literally allocate a texture. In either case, the interesting (and expensive to emulate in software) part is of course using the depth buffer to perform depth testing, that is, rejecting pixels that would be hidden.
Re:Building a PS1 style retro 3D renderer by jayd16 on Wednesday December 08, 2021 @10:54PM (#29493642)
Sure, the depth was not calculated or tested in hardware. But its not because buffers did not have a z-coordinate.