Gamasutra is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Gamasutra: The Art & Business of Making Gamesspacer
arrowPress Releases

If you enjoy reading this site, you might also want to check out these UBM Tech sites:


Project MD's 3D mirror effect

by Javier Degirolmo on 02/02/16 01:37:00 pm   Featured Blogs

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.


Quick recap for those who aren't aware: Project MD is an old unfinished homebrew platformer for the Mega Drive known for its weird aesthetics remiscent of Pulseman. Here's a YouTube playlist showcasing all the levels in the game.

The first level of Project MD (Infinite Field) is notorious because it has a reflection on a 3D floor. People keep thinking it's impressive (even those who should have known better) but normally I shrug it off because honestly it's not really CPU intensive. Now that I look at it though it's a horrible mess in terms of layers, so maybe it'd be a good idea to dissect it.

For context, this is how the level looks like:

The level scenery is made up of blue and pink blocks acting as walls, and also some sign posts saying

Quick hardware overview

First let's do a quick recap of what the Mega Drive video hardware is capable of doing. There are four layers (besides background):

  • Scroll plane A
  • Scroll plane B
  • Window plane
  • Sprites

(the window plane is not used in-game so I won't mention it anymore)

On top of that, there's a priority bit for each tile in the scroll planes and for each sprite. High priority layers will appear above low priority layers. When two layers with the same priority overlap, they're sorted in this order: background < plane B < plane A < sprites. Also, sprites are sorted based on their order in the sprite table (earlier sprites appear over later sprites).


Just to get it out of the way. The HUD is just high priority sprites and the earliest ones in the list, so this means it'll appear above everything else, period. Let's move on.

The 3D floor

The 3D floor is just a graphic that already has perspective, and the 3D effect is done by changing its scroll value every line (the hardware provides a table just for this), so lines at the top scroll slower than lines at the bottom.

Also just to make it clear, the computation is absurdly simple because the deformation is linear. This means that for every line it just adds a fixed delta value (OK, internally done in fixed point since it needs subpixel accuracy, but point stands). This is rather trivial for the 68000.

The foreground reflection

This is where the mess starts.

The objects and the level scenery (blocks, etc.) are high priority sprites and plane A, respectively. Their reflections are done by drawing them twice, but the reflection is low priority, flipped upside down, and using darker palettes. (well sorta, for the level scenery the reflection is part of the scenery itself, only sprites are actually drawn twice)

The floor in the portion where the reflection happens is high priority plane B. What this means is that the objects and scenery will appear over it, but the reflections will appear under it. The reflections show through transparent pixels in the floor. The background color happens to be black, which together with the darker reflections, makes it look like the floor is made out of polarized glass.

Also a nifty trick: the grid is crafted such as to ensure scenery tiles will intersect with the columns. When put together with the reflections, that makes it look like it's going through the grid, which helps enhance the 3D-ness effect. That's a really subtle trick that's easy to overlook.

The background reflection

"But wait, what about the trees in the background?"

Things get messier! Those trees are also sprites, but they're low priority. This goes both for the tree itself and its reflection. (the reflection is still upside down and darker) This is needed to ensure they appear below the foreground, but then how do trees appear above the floor?

Priority on tilemaps is per-tile. In this area, the floor is low priority above the tree base, and high priority below the tree base. This means the reflection ends up under it, but the tree itself doesn't (since sprites appear over plane B by default). Note that this means the base of the trees have to be aligned to a tile boundary as well, since that's the granurality for priority in the scroll planes.

How is their position calculated, since the 68000 sucks at division and that scaling is most likely not a power of two? I don't remember the exact details right now but I recall the value being related to 14. That sounds bad, until you realize it can be computed as 16 - 2, and that's exactly what the game does: use bit shifting to get 16 and 2, then use those subtotals to get the final value. (mind you, I was still definitely lucky that it was an easy value to compute)


For the sake of completeness. They're just in plane B (above the floor), and this portion just scrolls much slower than everything else. That's all there's to it.


From a CPU standpoint, this effect is not really impressive, and it doesn't really push the video hardware either. However, it requires a really contrived layer setup, complex enough that I could just make a whole article out of it =P

Hope you enjoyed it! (・ω・)b

Related Jobs

Insomniac Games
Insomniac Games — Burbank, California, United States

Technical Artist - Pipeline
Insomniac Games
Insomniac Games — Burbank, California, United States

Engine Programmer
Legends of Learning
Legends of Learning — Baltimore, Maryland, United States

Senior Gameplay Engineer - $160k - Remote OK
Bytro Labs GmbH
Bytro Labs GmbH — Hamburg, Germany

Senior Product Owner / Live-Ops Owner (f/m/x)

Loading Comments

loader image