The first game I got when I finally had enough money (this include the money I made from saling my Sega Megadrive/Genesis and few games I owned) to buy the PSX was Tomb Raider II.
I didn't have enough to buy a memory card at first, so for a time, I just played the game from the beginning each time. I also remember leaving the game on pause all night with the tv off, hoping my parents would'nt notice the green light and strange humming noise from the cd reader, only for me to return in the morning and finding all my progress gone…
This could explain why I remember so fondly of this game (appart of course from Lara's other assets that might have enticed me as a 11 year old back then), and especially of the first four levels.
Playing through one of these a few years ago, I noticed something that almost shocked me upon realizing what I was looking at. It looked like the developers at Core design managed to include some kind of reflections in the PSX version of the game !
I was learning about shaders and PSX dev at the time, and thought, no way the PSX had this capability. Or did it ? I did a bit of research about it and it seems this effect is achieved through a clever hack involving the PSX's framebuffer.
First, a few pictures to see what I'm babling about:
Do you see it ?
Ok, once again with stills :
Do you see it now ? On the PSX version, on the blade, you can see what looks like a reflection of the surroundings…on a ps1…in 1997…3 years before DirectX 8 and its shader language. Isn't that crazy ? At this point, I thought it had something to do with a special capability of the PSX's GTE or something like that. So I looked into it in order to have more info on this feat.
So, I first checked in the whole game to see if there were other occurences of this effect.
There was. You can find this effect in a few places, and at least in:
You can also find all over the place in Tomb Raider 1, in the form of blue cristals that allows you to save the game :
The effect is not present in the Sept. 30th 1997 beta :
so this means this feature was added at the last minute between the end of september and the release in November 11th 1997.
Whas it a sneaky dev that inserted this code at the last moment ? Who knows …
I reached to the skilled devs at psxdev.net and talked about my findings. Soon enough, a few theories were offered and user sicklebrick seems to have nailed it in this comment :
The TL;DR is that the PSX uses double buffering, so at any time resides in the frame buffer the actual frame, and the one being composed. This effect maps the next frame to the objects on which a reflection is wanted and that's it.
Let's hear him explain it in more details:
Re: Question regarding “shaders” on Psx ( TR2 )
Post by sicklebrick » September 21st, 2016, 3:16 am
I think gwald's onto something here. I just tested on actual hardware. Here's the VRAM as it is normally:
To the left we see both frames in the VRAM… Essentially one is drawn while the other is being created, then it's 'flipped' and the process continues (Double buffering). The drawn area is the one being sent to the screen at any particular time.
On the right (red outline) we see the Colour Lookup Table (CLUT). So instead of textures being stored as groups of RGB triples (e.g. one byte for Red, one for Green, one for Blue for each pixel)… generally a texture will just use something like 64 colours, and each of its pixels will be 'indexed' to that colour. Those colour indexes are the little swatches on the right. The fucked up looking unrecognisable bit at the top is the actual indexed texture data, since it's not stored like a normal bitmap it's not very clear to the human eye. I drew a dick on the stone texture though, so you can see it works. All of the colour swatches have been replaced by random solid colours to make things a little clearer too.
And here are the alterations in game. So much easier to see detail/shapes.
I think in a way this effect exeplifies playstation graphics - “it's crude but it works”. Instead of the UV map for these things covering the indexed colour area, as you'd expect, it looks like it's just covering the actual frame area…so costs no more to render than if it were any other texture. Obviously this approach comes with its fair share of issues including the weird warping you see from some angles, the fact it renders itsself, its also likely mapped to the previous frame, the colour reproduction is a little off (see shadows), and it seems to attempt to render different bits of the screen based on viewing angle + position… but it's pretty cool - and actually very clear from the other side with textures cleaned up a bit.
You can get decently fast pixel effects on small areas but you can't operate on the VRAM as if it were a regular chunk of memory and uploading to and downloading from VRAM is kinda slow (for a full frame) and would take up a massive chunk of the main RAM.
For obvious reasons they skipped this effect on the PC because directx doesn't work the same way and seriously… would you want to be the guy in charge of compatibility acrross all of those old 1997 DOS/DirectX machines? I mean we can't even get decent compatibility on open hardware like Android a lot of the time.
Cool effect though, cheers for sharing.
Ok so now we have an idea of how it's achieved but something bugs me still.
The levels in the Tomb raider games are just files (*.TR2 files in the present case). These files are the same for the Saturn, PSX and PC versions (and I suspect the Android version too). You can diff them, they're the same !
So it's on the engine side to check if an object should “reflect”. How does it know that ? For now, I can only speculate but two solutions that come to mind are :
I've gone and asked for these “reflections” to be implemented in the opensource TR engine Openlara, so maybe some more infos will surface in the discussion there…
In the meantime, if you happen to be in touch with the developers at that time, feel free to ask them and keep me updated !
psxdev discussion : http://www.psxdev.net/forum/viewtopic.php?f=48&t=976 archived version : https://web.archive.org/web/20200216110124/http://www.psxdev.net/forum/viewtopic.php?f=48&t=976
openlara's issue on github : https://github.com/XProger/OpenLara/issues/240
To comment, elaborate, correct, contact me : contact at arthus.net