48

This happens a lot on older consoles than this, but for this specific example, I'm picking what I spotted today: Harvest Moon for PlayStation.

Here is a screenshot of the player just about to exit an area, thus causing a "fade to black":

1

Here is what it actually looks like halfways (or 75%) finished:

2

This is what it would have looked like if the game had unlimited colors and instead used a semi-transparent black rectangle over laid over the entire screen:

3

While the "black rectangle" thing may look good on a still picture, it most certainly does not "in motion". The actual fade method, however, looks really good, and it seems to be "gradual" or "uneven", where the bright parts of the image appear to linger on longer, as if somebody had been making the lights gradually go out in a studio with a film camera in the early 20th century.

What I wonder is: What exactly causes this cool effect? I assume that it's somehow related to the relatively few colors available, so that it's not possible to use a "black rectangle" covering the screen which gradually changes transparency.

You can often very easily spot a "fake retro" video game by how it fades to black using the "black rectangle" method, which looks extremely jarring when coupled with the pixely sprites that try so hard to look retro. However, I'd like to finally understand what exactly is involved in creating that beautiful kind of "uneven lights out" effect.

Final Fantasy VII on PlayStation also did this. Example: https://youtu.be/h0mqRkhOvtY?t=14318

4
  • 10
    A mode using a palette instead of direct colors and then just lowering all the values by one pr frame down to zero? – Thorbjørn Ravn Andersen Jan 5 at 10:05
  • If you look closely, the fading time is proportional to the brightness of a pixel. So it could just be a transparent black rectangle being blitted over with opacity being increased at each frame. – aybe Jan 5 at 11:33
  • 4
    How careful were you about gamma here? Could the answer be as simple as the non-linear brightness scale provided by a CRT versus a linear progression through the scale in software? – Tommy Jan 5 at 12:12
  • 3
    Some systems actually had brightness registers for the video hardware to make a nice clean, efficient fade. Otherwise, palette based video modes allow easy update of all colors by modifying only a few bytes in the palette tables. – Michael Dorgan Jan 5 at 20:16
61

@user253751 and @WimC are correct, this fade is achieved by drawing a semi-transparent rectangle over the screen, but using a transparency mode where the rectangle's color is subtracted from the color of the background.

The PS1 has four semi-transparency modes (search this for "Semi Transparency"). The one used here is mode 2 in which the result of drawing a color is

(result) = (background ie. color in framebuffer) - (foreground ie. color being drawn)

(In Open GL, this corresponds to the blend equation GL_FUNC_REVERSE_SUBTRACT.)

At the beginning of the fade, a black rectangle is drawn over the screen with this transparency mode (foreground = 0 so result = background), and the color gradually increases until at the end of the fade the rectangle is white (so result = 0).

Pseudo-code for Back to Nature:

def start_fade():
    fade_color = 0

def update_fade():
    fade_color += 25  # approximate
    frames_til_next_fade_update = 2

def draw():
    draw_regular_scene()
    if fading:
        set_semitransparency_mode(BackgroundMinusForeground)
        draw_fullscreen_quad(color=rgb(fade_color, fade_color, fade_color))

I applied this method to a screenshot to check it (GIF slowed down for easier viewing).

This method applied to a screenshot

(All of this was discovered by hacking on the neat duckstation emulator to check what Back to Nature was doing.)

18

This effect happens when the luminosity curve of the image is adjusted like so:

enter image description here

This is called gamma correction and is a fairly common feature of graphics processing software and GPUs. My research has not turned up anything to suggest that the PS1 supports this feature natively in hardware, although it can be emulated in software fairly easily.

5
  • 1
    You beat me to it; I also noted that if the author is playing his modern games on Windows then actual output gamma is still fairly variable unless you've put a lot of effort into calibration. It's nominally 2.2, as was NTSC, but results may vary. Conversely, if the author is more used to PAL then the nominal gamma there was 2.8 so you'd expect all current computers to render differently if the software isn't doing additional correction of its own. The Mac also historically had a closer-to-linear gamma of 1.8 but switched to 2.2 about 15 years ago. – Tommy Jan 5 at 16:42
  • 4
    Could it also be a subtraction from the colour value? – user253751 Jan 5 at 19:20
  • 4
    @user253751 That seems most likely indeed. The PSX GPU does not support gamma correction. It does however, support a subtract blend mode. So this effect could possibly be achieved by drawing a rectangle over the image with subtract blend mode and a color value that increases to white. An excellent overview of the GPU’s capabilities can be found here. – WimC Jan 6 at 6:26
  • It's not a simple subtraction though, the amount subtracted depends on the starting luminosity. – user Jan 6 at 17:16
  • 3
    Even if there was an efficient way to do gamma correction on the PSX, a pixel of 100% brightness always remains at 100% brightness regardless of how high a gamma you use, so it can't be used for a fade to black by itself. – wrosecrans Jan 11 at 4:59
13

There can't be a simple answer, as there are many ways to reach that effect depending on console/hardware used.

  • Using some 'overlay' needs incredible computing power and is usually tied to rather high end 3D engines. A way simpler method is
  • cycling/dampening the colours. Here each colour used is replaced by a dimmer variant. An effect that is already easy to produce on hardware as simple and early as the Atari 2600 (*1). It takes even less effort
  • if the display hardware used a dedicated, programmable palette. Now all needed to do is changing them colours (*2).
  • If organized as indices, then some elaborate translate table may do it (*3).
  • If these table entries are RGB values, then a fading can be created by simply counting them down by one for each colour and cycle (*4).

All of this does only need to manipulate a few bytes of colour definition instead of manipulating several kilobytes of screen memory (like a 'overlay' would do).

[Since this effect is so handy and easy to perform it is part of the basic toolset for all classic (i.e. non 3D engine based) games and used in many variations. Like cycling only a few colours to create a force field, a glow around a character or item, or, well, a flickering fire. With well created scenes (and enough colours available), it can replace several sprites or modifications of large screen areas that would otherwise be simply impossible.

With the right colour distribution this can be used to enhance fade-out/-in sequences by using colours for the player avatar which will not be changed, so only the playfield vanishes, while the avatar stays. When reaching black, the new playfield is drawn and the reverse effect is used for fade-in. Incredible visuals with minimal hardware requirements.]

Of course one could

  • apply the same methods to the whole screen if there is no colour table to be manipulated.

But that would require going thru al of the screen data. Not impossible, especially on fast machines like the PS1, but I do not think any game programmer would do it if it can be avoided. Doing whole screen modifications are brute force modern - fit for modern devices, but not elegant in any way.


*1 - Here colours are loaded into the registers each time they are used. By loading from a definition table instead of fixed values the effect can be reached by using a series of tables in ROM (there is rarely enough RAM in the 2600 to manipulate such a table, so having a bunch in ROM is the way to go).

*2 - Much like before, except now replacement is by whatever colours are there

*3 - A translate table defining a sequence. Like in a system with 8 colours colour 5 could become 7 and then 3 followed by 2 and 0. This table would look like 0,1,0,2,4,7,6,3. Note that colours 1, 4 and 6 doesn't change, so they can be used for titles, scores or any other static content

*4 - RGB means that for each colour the 'brightness' for each of the three components are stored. So by decreasing a components value (linear or relative) it will dim. On a 3-3-2 colour system bright white is 7-7-3 while black is 0-0-0. so counting down all components will fade a white spot to black. The same for other colours, like 7-0-0 is bright red and any decrease of the red component will let it fade.

Having RGB even offers an easy and low effort way to do fading in more colourful ways - like fading to red in the 'evening' or green in a forest and so on.

5

For PC VGA, which definitely has just 256 colours on screen that are picked from the 16 million available via a look up table, such fades are definitely done by changing just the palette definition every 0.1 seconds or something like that.

If you do it naively, you just substract a fixed value from each R, G, B component on each frame. The consequence is that brighter colours take longer to reach black (zero) since they start from higher RGB values. That's what seems to be happening in your screenshots.

I'm not familiar with the PS1 capabilities enough to guess exactly at what's happening there, but Harvest Moon seems to have been available on less powerful devices as well, that were definitely paletted. So I'm guessing that's what you're seeing there.

Edit: Oh ok, the PS1 does it differently as @scurest said. My answer is only good for older, paletted devices.

2
  • 2
    Minor error: The VGA palette is defined using 6 bits per channel, not 8, so the total size is only 262144 colours, not 16777216. Easy mistake to make. I know I did back in the day. – Rohan Jan 7 at 7:42
  • Back in the day I actually knew how many colours I have available... but it has been a while :) – Torp Jan 10 at 20:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.