Mednafen/Beetle PSX has made another significant stride forward! iCatButler has contributed a working backport of PGXP for Mednafen/Beetle PSX.
PlayStation rasterization issues
Several issues can be noticed in most PlayStation games’ graphics.
Wobbly polygons (lack of subpixel precision)
This can often be noticed on character models. In addition to the models looking very glitchy/wobbly, you can also often notice that their face textures look deformed. If you apply very granular movement to the character, you can often notice a character model’s head deforming based on its distance from the camera. For examples of this, try to find a scene in Final Fantasy VIII/Resident Evil 1 where the characters are very close to the camera. With no subpixel precision, you would see a continuously changing and deformed face texture on the main characters.
Dancing/warping textures (lack of perspective correct texturing)
In many games, you will see the texture maps on the ground dancing/warping as you move around the environment. See the video above for an example of what we are talking about.
In addition to this, other games (like Ridge Racer Revolution, or Tomb Raider 2) can also sometimes show random color outlines around texture maps while the camera is moving.
All of the aforementioned issues can be traced back to the lack of perspective correct texturing.
This, combined with the lack of subpixel precision, can result in a very glitchy look in many a PlayStation game. Most PlayStation-to-PC ports didn’t put the extra effort in to fix these issues either. For instance, the aforementioned issues were fixed in Resident Evil 1 PC but then by the time we get to Resident Evil 3: Nemesis for PC, we can spot wobbling polygons again on the character models. A similar thing happened with the Final Fantasy series. The issues were fixed for Final Fantasy VII but Final Fantasy VIII’s PC port featured the same subpixel precision issues as the PSX version. Lack of time/effort and optimizing specifically around the PSX’s limitations are probably a reason for developers taking shortcuts even on far more capable hardware.
Geometry Transfer engine and integer precision math
The PlayStation’s MIPS R3000A processor was a very barebones MIPS CPU, very outdated even by 1994 standards. What made it special at the time was the coprocessor attached to it which made it very adequate at 3D rendering: the Geometry Transfer Engine. It’s a coprocessor (attached to COP2) which has fixed-function functionality allowing the programmer to do perspective transforms, rotations, light sourcing, depth cuing, etc. Being able to do this at nearly zero cost was the envy of many a PC around that time period. Without this coprocessor, the paltry 33MHz main CPU would have been unable to render most of the graphics at full speed performance.
The PSX had no floating point unit installed as COP1 (coprocessor 1), and neither did the GTE have any float support. It deals mainly in fixed point math, and because of the rotate and translation transformations involved that occur on the GTE side, precision errors will build up and this will result in the ‘wobbling’ effect you can see manifested onscreen. At the very end when the GTE has done its processing, it will output the results of the perspective transform to the GPU as integer pixel coordinates. The GPU then has to draw the scene. Polygons will snap into place until one of the vertices moves enough to snap into a different pixel.
The N64 had a similar configuration to the PSX, except that the equivalent to GTE was called RSP there – also installed as COP2 (coprocessor 2). Unlike the PSX, though, the N64 also had an FPU installed as COP1 (coprocessor 1). Like the GTE, RSP deals mainly with integer fixed-point math, but unlike the GTE, custom microcode can be uploaded to the RSP, making it more flexible and capable of performing custom tasks programmed by the game developer specifically for the game. In certain games you can see similar wobbling issues (F-Zero X’ vehicles is a good example), but it’s far less severe.
Furthermore, what made the difference in terms of the N64 having more stable rendering compared to the PSX is the lack of perspective correct texturing, which the N64 does have. Calculating the coordinates so that a texture would look correct from any angle would be computationally expensive, costing maybe 2 divisions per sample. By only applying perspective-correct sample coordinates at certain intervals, rendering could be done much quicker on the PSX, but at the cost of the ‘warping/dancing’ polygons that you can see in so many PSX games. To combat these issues, you’d see developers like Psygnosis using many tricks in games like Wipeout to ‘mask’ these issues (for instance by subdividing textures into many parts).
The solution: PGXP
PGXP attempts to kill two birds with one stone. First, it introduces subpixel precision to get rid of the wobbling polygon issues. Second, it adds perspective correct texturing to stop the ‘textue warping/dancing’ issues.
iCatButler first started integrating PGXP into the emulator PCSX-R (by injecting it into Pete’s OGL2 plugin, a closed-source plugin). It seems this attempt has been successful and was the first one out of the starting gates, but there are some geometry issues which seems partly can be attributed to the ageing fixed-function Pete’s OGL2 renderer.
iCatButler now has backported this functionality to Mednafen/Beetle PSX’s GL renderer. According to iCatButler, there are less geometry issues with Mednafen/Beetle PSX’s GL renderer. See this screenshot for instance –
This video shows a before/after example of PGXP + perspective correct texturing with the game Tomb Raider.
How to use it?
You need to use the latest version of Mednafen/Beetle PSX HW. In case you don’t already have it or you are not on the latest version, you can get it from RetroArch’s Online Updater.
You need to be using the OpenGL renderer in order to use PGXP. To make sure of this, go to Quick Menu -> Options and make sure it says ‘opengl’ at ‘Renderer (restart)’.
To enable PGXP, you set ‘PGXP operation mode’ to a value other than ‘OFF’.
‘memory’ – the default enabled mode. This is a less CPU-intensive version of PGXP, and it also tends to be less buggy than the other one. Try this by default unless you want to experiment.
‘memory + CPU’ – the secondary enabled mode. This is more CPU intensive and can result in geometry glitches. However, it has been demonstrated that it can help reduce wobblyness in polygons even more for certain games (such as Resident Evil 3: Nemesis).
There are two other PGXP options which you might want to experiment with:
‘PGXP vertex cache’ – maintains a cache for all the vertices. This might result in better performance but we recommend you leave it off for the majority of games since it can result in graphics glitches.
‘PGXP perspective correct texturing’ – This enables or disables ‘perspective correct textures’. For most games you definitely want this enabled, otherwise enabling PGXP will only get you subpixel precision.
The GL renderer is still in a very inoptimal state overall. In order to increase performance, you can turn V-Sync off. To do this, go to Settings -> Video and turn off V-Sync.
Other things that can help is reducing the internal resolution and/or setting Texture filtering to ‘nearest’. ‘3point N64’ and ‘bilinear’ can result in more visual glitches and definitely has a negative impact on performance.
What’s next for Mednafen/Beetle PSX?
The GL renderer is definitely not as optimal as it could be, and we are trying to find solutions for making it much faster. Stay tuned!