To recap, a large part of the graphics pipeline is carried out by the GTE. This includes perspective transformation (which projects the 3D space onto a 2D plane using the camera's perspective) and lighting. The processed data is then sent to Sony's proprietary Graphics Processor Unit (GPU) for rendering.
Organising the content
The system features 1 MB of Video RAM (VRAM) that will be used to store the frame buffer, textures, and other resources the GPU will require to render the scene. The CPU can populate this area using DMA.
The type of chip fitted (VRAM) is dual-ported, like the Virtual Boy's. VRAM uses two 16-bit buses, which enables concurrent access by the CPU, DMA, GPU and the video encoder.
Though in later revisions of this console, Sony switched to Synchronous Graphics RAM (SGRAM) chips (the single-ported alternative, using an individual 32-bit data bus). Boo!... Well, to be fair, each one comes with its pros and cons.
One thing for sure is that, due to timing differences, later games (such as Jet Moto 3) display glitched graphics when run on VRAM-based systems. If you want to know the details, Martin Korth's 'Nocash PSX Specifications' document the various timings and such .
Drawing the scene
If you've been reading the Sega Saturn article, let me tell you that the design of this GPU is a lot simpler! For starters, the GPU is made of a single chip.

The graphics chipset on my motherboard revision: the GPU (right), 1 MB SGRAM (top left), and video DAC (bottom left).
Now, to show how a scene is drawn, I will mainly use Insomniac's Spyro: Year of the Dragon as an example.
Commands
To start with, the CPU sends geometry data (vertices) to the GPU by filling its internal 64-byte FIFO buffer with commands (up to three). These commands may request the GPU to render something, change a setting or manipulate VRAM.
Essentially, a render command states how and where to draw a primitive. The GPU can draw lines, rectangles and triangles individually - the latter being the fundamental ingredient for constructing rich 3D models.
Once the geometry is received, clipping is applied to skip operations on unseen polygons (residing outside the camera's viewport).
The position of each primitive is defined using an X/Y coordinate system that maps directly to the frame buffer. The PS1's GPU employs an integer coordinate model, in which each coordinate corresponds to the centre point of a pixel (known as sampling point). In other words, there are no fractional coordinates.
Visibility approach

Crash Bandicoot (1996) made use of pre-ordered geometry to gain performance . Consequently, its camera only moves forwards or backwards.
Just like the competition, the PS1 doesn't include any hardware feature that tackles the visibility problem. Nonetheless, the GPU handles sorted polygons by providing an ordering table: a dedicated structure in which each entry is indexed by a depth value (also called 'Z-value') and contains the address where the corresponding GPU command resides .
The CPU must manually sort the polygons first, and then place references in the appropriate entries of the table. Finally, the CPU orders the DMA to send the table to the GPU. This process enables the GPU to render the geometry in the correct order.
Multiple DMA functions are also provided to assist both the CPU and GPU with the creation and traversal of this table.
Rasterisation
Once the commands are decoded by the GPU, it's time to convert the received geometry (vertices) into pixels. This enables the system to apply texture mapping and effects, ultimately displaying the result on a two-dimensional panel (such as your TV or monitor). To do this, the GPU allocates a pixel matrix as its working area, this is called a frame buffer. Compared to the more complex Sega Saturn, the GPU requires only a single frame buffer.
The rasteriser is the unit in charge of converting vectors into lines, triangles, or rectangles - and finally into pixels. Now, the process differs drastically depending on the requested primitive :
- Triangles are the most complex (and versatile) type, which can be textured and shaded.
- Lines are quicker to draw but naturally unsuitable for textured surfaces. Shading is still supported.
- Rectangles are also faster but can only fit a sprite of up to 256 x 256 pixels; larger rectangles will only duplicate the sprite's graphic. Even so, they offer no affine transformation (aside from X/Y flipping), nor shading or effects. I suspect rectangles were only implemented to assist the development of 2D games.
In the case of the triangle, being the only textured polygon, the rasteriser will:
- Grab each three-point vertex and calculate the edges. This forms a triangle.
- Analyse the triangle's area to determine which pixels of the frame buffer they occupy. Only the portion of the polygon covering the sampling points gets turned into pixels.
The generated pixels are not written into the frame buffer right away. Instead, they are passed to the next stages of the pipeline for further processing. I cover this in the subsequent paragraphs.
Shaders
In order to apply lighting effects to triangles or lines, the GPU offers two algorithms:
- Flat shading: Each primitive has a constant light level.
- Gouraud shading: Each vertex embeds its own light level. Then, the brightness is automatically interpolated between points.
- As you can imagine, this type offers more realistic results than flat shading.
The rationale behind providing this choice comes down to performance: flat shading fills ~2.5 times more polygons per second than Gouraud shading. Thus, it's important to optimise which polygons truly benefit from more realistic lighting than others.
Textures
Triangle surfaces may also be blended with textures (2D bitmaps) to produce the final result.
The GPU performs inverse texture mapping, where it traverses each rasterised pixel and looks for its corresponding pixel in the texture map (called texel). Texels are calculated by linearly interpolating the texture map (found in VRAM) to match the shape of the polygon. The interpolation routine is called Affine Texture Mapping, which operates solely on 2D coordinates (X and Y values), discarding the third coordinate (Z or 'depth') that would otherwise account for perspective.
Because texture maps rarely match the exact dimensions of rasterised polygons, aliasing (incorrect rendering results) tend to appear. This manifests as unwanted distortions, such as missing or oversized texels. To remedy this, sophisticated GPUs employ texture filtering to smooth out (interpolate) abrupt colour changes. Now, the PS1's GPU does not implement any filter, so it resorts to an algorithm known as nearest neighbour to correct scales without smoothing out the results. This is very fast and cheap, but it also explains why textured models may look 'blocky'.
The GPU also supports the following effects, available for use on triangles:
- Semi-transparency: Simulates light passing through overlapping textures.
- Dithering: Softens sudden changes in colour while adhering to the same colour palette.
It's worth noting that the PS1 happened to excel at these effects!
Remaining steps
Once finished, the GPU writes the pixels to the frame buffer area in VRAM, which is in turn picked up by the video encoder and broadcasted to the screen.
Designs
Let's take a break now from all this theory. Here are some examples of game characters designed specifically for the 3D era. Notice the use of triangles and nearest-neighbour textures. I encourage you to compare them with the models featured in the other articles.

Interactive model available in the modern edition
Spyro the Dragon (1998).
413 triangles.

Interactive model available in the modern edition
Crash Bandicoot (1996).
732 triangles.
Optimising texture storage
On the PS1, textures are stored inside texture pages. These are blocks of 256x256 pixels, and their storage size can range from 4 to 16 bits per pixel (bpp) in VRAM . The more bits, the richer they look, but also the more space they occupy.
Be that as it may, 4bpp and 8bpp texture pages are not restricted to a predefined set of colours. Instead, they rely on a Colour Lookup Table (CLUT) - a customisable colour palette that can be placed anywhere in VRAM.
When the CPU commands the GPU to draw a textured triangle, the command also embeds the location of both the texture page and the CLUT.
Playing with VRAM
Given the available amount of VRAM (a whole megabyte), one could allocate a massive frame buffer of 1024×512 pixels with 16-bit colours, or a realistic one of 960×512 pixels with 24-bit colours - allowing to draw some of the finest frames ever seen in gaming... This sounds pretty impressive, right? Well, it does raise a few issues, for instance:
- These dimensions would need to be rescaled to comply with standardised formats (e.g. 480i NTSC or 576i PAL), so the video encoder can broadcast them on consumer TVs.
- How is the GPU supposed to render anything decent if there isn't any space left for other assets (e.g. textures and colour tables)?
- The PS1's GPU can only render frame buffers of up to 640×480 pixels and 16-bit colours.
All right, let's use a 640x480 buffer with 16-bit colour instead, which leaves 424 KB of VRAM for materials. So far, so good? Again, such resolution may look fine on CRT monitors, but it's not particularly noticeable on those 90s TVs everyone had in their homes. Then, is there any way to optimise VRAM space? Introducing adjustable frame-buffers.

VRAM visualisation in the NO$PSX debugger. You can spot the dual frame buffer, along with texture pages. The latter are translated using a colour lookup table, also stored there.
In essence, rather than hoarding VRAM with the frame buffer, this console's GPU allows to decrease the dimensions of the frame buffer, effectively increasing the space available for other resources. In a demonstration from 'Gears Episode 2' , Halkun shows a setup that divides the 640x480 frame buffer into two 320x480 ones, employing a technique called page flipping to render multiple scenes at the same time.
Page flipping involves alternating the location of the frame for display between two buffers whenever required, allowing the game to render one scene while displaying another. Thus, hiding any flickering effect and improving loading times (something that the player will certainly appreciate!).
Overall, Halkun's layout consumes only 600 KB of VRAM. The remaining 424 KB can be used to store colour lookup tables and texture pages which, paired with 2 KB of texture cache available, result in a very convenient and efficient setup.
Finally, it is also worth mentioning that VRAM can be mapped using multiple colour depths simultaneously, meaning that programmers can allocate a 16 bpp frame buffer next to 24 bpp bitmaps (commonly used by FMV frames, for instance). This is another avenue for further optimisation of space.
Secrets and Limitations
Whereas the PS1 had a straightforward and suitable architecture, problems still arose. Surprisingly, certain issues were tackled through rather clever workarounds.
Distorted models/textures

Video - Square Soft's Final Fantasy VIII (1999). As is common with PS1 games, textures jiggle a bit when they move.
The routines used for handling geometry and applying textures are known to carry some inaccuracies.
Firstly, the rasteriser only handles pixel units: While vertex coordinates are expressed as integers, the calculated triangle edges may occupy only a fraction of a pixel. However, the rasteriser will draw the pixel only if the triangle's area covers the pixel's sampling point, and it does not keep track of the fraction occupied . This brings up some problems:
- The outer edges of models will make sudden jumps when moved slightly.
- Triangles within a mesh (which share the same vertices and edges) will often 'compete' to draw over the same pixels. Taking into account the ordering table, the GPU renders following a 'last-come, first-served' basis, which will cause triangle intersections to flicker or overlap when moved slightly.
This is commonly tackled by implementing sub-pixel resolution, which allows the rasteriser to keep track of the fractions of pixels occupied by each triangle area . As a result, anti-aliasing methods can then be applied to soften jagged edges or abrupt changes in colour.
Moving on, the ordering table puts the burden on the developer/program to show the geometry in the right order. In some cases, the underlying calculations rely on excessive approximations to gain performance. This may result in flickering or occluded surfaces that ought to have been displayed.
Furthermore, setting a low-resolution frame buffer can amplify all these aliasing issues.
Finally, as you know, affine transformations lack any sense of depth. This may confuse the user's perception, especially when the camera is positioned close to the model and perpendicular to the viewer's line of sight . The anomaly is known as texture warping. Hence, some games resorted to tessellation (splitting large polygons into smaller ones) to reduce distortion, while others opted to swap textures with solid colours. In general, a GPU ultimately tackles this issue by implementing perspective correction, which interpolates textures using the depth value.
Contradicting claims
If you check other technical channels or forums, you'll find alternative explanations for the PS1's wobbling, warping, and distortion effects. While some may align with my previous explanations, others argue differently. Therefore, I'd like to offer my perspective on why the following statements are inaccurate:
Models and textures wobble due to lack of an FPU
An FPU does not dictate whether a system can operate fractional numbers. The PS1, like any other computer without a hardware FPU, can still perform fixed-point arithmetic. Furthermore, floating-point numbers can also be computed (just slower) through software. In essence, FPUs are accelerators; do not confuse them with the concept of decimal numbers or with an ALU (the critical portion of a CPU responsible for arithmetic operations).
Models and textures wobble due to the GPU's integer coordinate system
Employing integer coordinates is a common approach to make calculations less expensive in the GPU. What turns this into a visible problem is the lack of sub-pixel resolution. This is because anti-aliasing can be applied to smooth out sudden changes of colours - provided the rasteriser tracked the fraction of the pixel occupied by the triangle.
Textures warp due to lack of mipmapping
GPUs that implement inverse texture mapping, such as this one, are subject to a measurement error known as 'undersampling' (one pixel is mapped to multiple texels). This produces aliasing (wrong results). The behaviour is noticeable when rendering geometry located far from the camera. To remedy this, modern texture mappers apply 'trilinear filtering', which softens texels using the same texture stored at different scales (mipmaps) and does some interpolation in-between. To sum up, mipmapping is a method for reducing aliasing. It is affine texture mapping (with its lack of perspective correction) that interpolates textures on three-point surfaces without taking into account the depth. Hence, the 'warping' effect.
Models and textures flicker due to lack of Z-buffering
A GPU equipped with a Z-buffer solves the visible surface determination problem at the hardware level. In contrast, the PS1 relies on an ordering table, meaning developers are in charge of determining what geometry is in front of other. In short, flickering triangles are caused by the sorting routines (software).
Pre-rendered graphics

Square Soft's Final Fantasy VII (1997) features many scenes with pre-rendered backgrounds. The interaction and movement of 3D models play a key role in tricking the viewer's perception.
Let's highlight a positive feature now for a change...
When a game strived for a more realistic scenery than the GPU could provide in real time, one available option was to stack two triangles and use the Motion Decoder to stream pre-rendered cinematics onto them. FMV sequences required lots of storage space, but luckily, the CD-ROM was well-prepared for this.
Some titles relied on this technique to compose backgrounds and, honestly, it looked quite convincing on a CRT television. Of course, modern emulators with upscaling capabilities will give it away very quickly.
Video out

Four different PlayStation 1 revisions stacked together , notice the reduction in ports over the years. From bottom to top: SCPH-1000 (1994), SCPH-3000 (1995), SCPH-5501 (1996), and SCPH-9001 (1999).
The first revision of this console carries a surprisingly wide range of video signals, accessible via the following ports:
- RFU DC: Designed to connect an RF modulator.
- RCA: Outputs composite video and stereo audio.
- S-Video: Provides a combined Luma + Sync, and a separate Chroma signal.
- AV Multi Out: Offers all the aforementioned signals, excluding RFU. It additionally carries RGB and a 5+ Volts line.
In subsequent revisions, most of these ports were phased out, leaving only the 'AV Multi Out' on late models.





