S-buffer: how the Model 3 handles anti-aliasing and translucency
Posted: Sun Nov 12, 2023 11:22 pm
I had been pondering for a while about exactly how translucency worked on the Model 3, but recently after studying this patent and looking into the Real3D firmware, I believe I may have discovered the key to how not just translucency, but also anti-aliasing is implemented on Model 3: the S-buffer.
First of all, what does the S in S-buffer stand for? Actually, I have no idea. But I do know that it contains metadata used to help Jupiter convert the video output into an anti-aliased image.
In the Real3D firmware it is possible to perform an "Earth snap test" that captures and displays some of the data being processed by the pixel processor (Earth), including what appears to be the output to the frame buffer:
Each Earth ASIC outputs 16-bit data to three 3D-RAMs, for 48 bits in total. I'm presuming that IRNG stands for "ignoring" so that the remaining data fits into a 48-bit word, spread across the three 3D-RAMs. Xing stands for "edge crossing"; the patent describes these in (somewhat convoluted) detail, but what these do is describe how close a rendered polygon edge is to the pixel sample point. Xluc stands for translucency; there are two flags used to determine if anti-aliasing should be performed for this particular pixel.
Anti-aliasing is performed by taking the video output and blending adjacent pixels together using weighted averages calculated from the edge crossing values. Let's take a look at an example:

A, B, C and D represent the sample points; each of these contains a 24-bit RGB color value, and top, bottom, left and right edge crossing values. In this particular case, A and C have right edge crossings and B and D have left edge crossings. (If an edge has no crossing, the value is set to zero.) The overall color of the pixel uses a weighted average of A, B, C and D depending on the values of the edge crossings; this pixel will be more weighted towards the color of sample points A and C.
Let's look at another example:

This pixel will be weighted more towards the colors of sample points B, C and D.
I should point out now that this will not be a practical way to implement anti-aliasing in Supermodel; calculating the edge crossing values for each pixel when rendering on a GPU would be extremely difficult, if not outright impossible. It would be a lot more practical to implement a more conventional anti-aliasing method such as SSAA or MSAA; I believe that Ian is having thoughts about implementing SSAA.
So where does translucency come into this? Well, using the S-buffer it is possible to implement translucency by rendering only to every other pixel and then manipulating the edge crossing values to bias the color of the pixels. For example, suppose that we are rendering a red triangle onto a black background. The triangle is rendered like this, regardless of the translucency level:

The edge crossing values are manipulated to bias the displayed pixels towards the red or black sample points depending on the desired translucency level. For example, at 50% translucency the triangle will end up being displayed like this:

All of this means that translucency can be achieved without alpha blending at all, which means there is no need to sort polygons. However, there are a few caveats:
First of all, what does the S in S-buffer stand for? Actually, I have no idea. But I do know that it contains metadata used to help Jupiter convert the video output into an anti-aliased image.
In the Real3D firmware it is possible to perform an "Earth snap test" that captures and displays some of the data being processed by the pixel processor (Earth), including what appears to be the output to the frame buffer:
Code: Select all
xxxxxxxx xxxxxxxx -------- -------- -------- -------- -------- -------- IRNG
-------- -------- --xxxxx- -------- -------- -------- -------- -------- Top Xing
-------- -------- -------x xxxx---- -------- -------- -------- -------- Bottom Xing
-------- -------- -------- ----xxxx x------- -------- -------- -------- Left Xing
-------- -------- -------- -------- -xxxxx-- -------- -------- -------- Right Xing
-------- -------- -------- -------- ------x- -------- -------- -------- Xluc Flag
-------- -------- -------- -------- -------x -------- -------- -------- Poly Xluc Flg
-------- -------- -------- -------- -------- xxxxxxxx xxxxxxxx xxxxxxxx Pix Color (RGB)
Anti-aliasing is performed by taking the video output and blending adjacent pixels together using weighted averages calculated from the edge crossing values. Let's take a look at an example:

A, B, C and D represent the sample points; each of these contains a 24-bit RGB color value, and top, bottom, left and right edge crossing values. In this particular case, A and C have right edge crossings and B and D have left edge crossings. (If an edge has no crossing, the value is set to zero.) The overall color of the pixel uses a weighted average of A, B, C and D depending on the values of the edge crossings; this pixel will be more weighted towards the color of sample points A and C.
Let's look at another example:

This pixel will be weighted more towards the colors of sample points B, C and D.
I should point out now that this will not be a practical way to implement anti-aliasing in Supermodel; calculating the edge crossing values for each pixel when rendering on a GPU would be extremely difficult, if not outright impossible. It would be a lot more practical to implement a more conventional anti-aliasing method such as SSAA or MSAA; I believe that Ian is having thoughts about implementing SSAA.
So where does translucency come into this? Well, using the S-buffer it is possible to implement translucency by rendering only to every other pixel and then manipulating the edge crossing values to bias the color of the pixels. For example, suppose that we are rendering a red triangle onto a black background. The triangle is rendered like this, regardless of the translucency level:

The edge crossing values are manipulated to bias the displayed pixels towards the red or black sample points depending on the desired translucency level. For example, at 50% translucency the triangle will end up being displayed like this:

All of this means that translucency can be achieved without alpha blending at all, which means there is no need to sort polygons. However, there are a few caveats:
- Rendering a translucent polygon on top of another with the same translucency pattern erases the previous polygon.
- If two polygons of opposing translucency patterns overlap, the result is opaque as the background is completely overwritten.
- Resolution is effectively halved for translucent polygons.