Super Mario 64 – 1996 Developer Interviews
shmuplations.com
shmuplations.com
This was a huge advantage for them. In contrast, for Crash Bandicoot -- which came out for the PS1 at the same time -- we had to use over an hour of pre-computation distributed across a dozen SGI workstations for each level to get a high poly count on hardware lacking a Z-buffer.
A Z-buffer is critical, because sorting polygons is O(n^2), not O(n lg n). This is because cyclic overlap breaks the transitive property required for an N lg N sorting algorithm.
The PS2 got Sony to parity; at that point both Nintendo and Sony had shipped hardware with Z-buffers.
After that, I started noticing subtle clipping issues in a few games including Daxter.
I would have never guessed that any 3D video game console didn't have a Z-Buffer, including a relic like the PSX.
[1] https://www.neoflash.com/forum/index.php/topic,3035.0.html
[2] http://forums.dashhacks.com/psp-programming-development/2399...
My email's in my profile if you want to chat
Z-Buffer's are still a major advantage.
That still fails to resolve cycles.
"The Z-buffer could not be used because it alone consumed the already constrained texture fill rate."
-- https://en.wikipedia.org/wiki/Nintendo_64_programming_charac...
I vaguely remember a technical analysis on the N64 that explained using the Z-Buffer had such a dramatic negative impact on performance, that only a very small handful of games actually used it. The general theme of the technical analysis was that the N64 had a lot of "features" that had a massive performance impact to use, so many of them went unused.
If I remember correctly -- most games implemented their own pseudo z-buffer in microcode, which is why a lot of games on the N64 have issues with textures popping through each other incorrectly -- Goldeneye's bullet hole textures stick out in my mind as a good example of this.
However, I'm trying to find the analysis, and I'm not having any luck. Maybe I'm just remembering things incorrectly.
N64 had a form of antialiasing support https://www.google.com/patents/US6999100 That was the motivation for the "9-bit RAM". Worked well enough for the time and was cheap enough to use. Much cheaper than running at a higher rez.
> most games implemented their own pseudo z-buffer in microcode.
Just two or three IIRC. Mainly Factor 5 games.
Goldeneye use Z-Buffer, bullet texture overlaps because the poly offset value used to apply bullet texture on walls is always the same.
> The general theme of the technical analysis was that the N64 had a lot of "features" that had a massive performance impact to use, so many of them went unused.
I wouldn't say that.
1) The N64 is a complex console. It still inherit the "all electric" tradition of 16/32 bits consoles but focusing on 3d computation and shading so it need skilled peoples and time to do interesting things with it (in its last days, N64 had very impressive games).
2) With that, Nintendo devs provides GBI (graphic binary interface) which was not such efficient on the vector computation side (but generic enough to allow peoples to use it).
3) N64 had a all-wired per pixel processing unite (a GPU named RDP), meaning it could provide high quality pixels like never before but this was costly.
4) Because texture had to be stored physically "inside" the RDP chip for efficient processing (remember, 3DFX didn't even exists at this time and the GPU word was a concept), memory cost (and, I suppose, size limitation) were important so they choosed to focus on pixel quality over texture definition (there is actually many hack to "visually" improve texture definition: http://imgur.com/2EeH5Yg).
In the case of Mario 64 though, many of the models and polygons didn't have textures but used super-simple single-color flat shading. So texture fill rate wouldn't not have been a constraint.
Most games also didn't use a custom microcode, but used one of a handful of microcode libraries for the RCP that Nintendo provided. A notable exception to this is Factor 5, which did write their custom microcode to improve graphics performance, with great results.
http://all-things-andy-gavin.com/2011/03/12/making-crash-ban...
Did you consider any other alternatives? Curious if you had any other ideas that you sidelined as being too crazy.
Can you expand on how the precompute trick works further? So you're precomputing the order of the scenery/level polygons because of their predictable movement but how does that combine with objects with unpredictable movement (Crash, enemies etc.) when you render a frame? Did the limitations of this trick limit the gameplay you wanted?
We wrote a software renderer for the SGI that exactly replicated how the PS1 hardware would render. I wrote an imperfect clone for Crash 1, then Stephen White wrote a pixel-accurate one for Crash 2. (This is why Crash 1 has "crispies", as Andy called them -- little pixel-sized glitches in the background -- and Crash 2 does not.)
When computing a level, we'd sample N points along the rail as we moved the camera forward through the level. At each point, we'd render the entire scene using the software renderer, then recover the rendered list of polygons, in sorted order, from the (software) Z buffer. We'd then store this sorted list of polygons for each of the N frames, using delta compression between frames to keep the size manageable. The pre-computation phase would choose N empirically, based on much change happened from frame to frame in any given section of the level; basically it would make N as large as it could be without blowing out the page allocation (which was in turn determined by how fast we could read from the CD).
This handled all the polygons in the background, which was completely static. For foreground objects like Crash, enemies, gems, etc, we'd bucket sort them in as we rendered the background. This required manual tuning in some cases, so we had an editor where we could manually adjust the "push-back" (i.e., bucket adjustment) for each object in real time while playing the game. These magic values were then stored with the associated objects as part of the level data. If we couldn't make an object sort in right via bucket adjustment, we'd change the background slightly until it worked. In other words, it was a massive hack. :)
In terms of gameplay, we took our inspiration primarily from Donkey Kong Country, which had linear gameplay. So the rail model actually worked really well for the gameplay we were trying to achieve. (DKC is still an awesome SNES game; check it out if you haven't played it recently.)
I've also written rendering engines for hardware lacking Z-buffers, and our approach was to build a BSP tree of the level, which gets you part of the way to working around no Z buffer, since there's no Z overlap in static polygons after being partitioned, but the downside is you split triangles and increase the triangle count, so it reduces model complexity if the splitting blows your poly budget.
Once you have your BSP cells, you can precompute all the visible cells from any given cell - heh, we too did this on SGI's, but by rendering each cell is a unique color and seeing which colors were visible in an output frame.
Then, within each cell, we'd have six draw orders for triangles, picking whichever was closest to the eye vector. Not pretty, and sometimes this produces quite a bit of overdraw, but it works. I'm guessing your approach minimized overdraw as compared to a heavily pre-computed BSP approach.
Anyhow, thanks for the post, it's fun to read about the the hacks form the early days of graphics hardware.
We essentially rendered every frame with a Z-buffer; it's just that the Z-buffer was running in software on the SGI ahead of time, as the level was processed.
We needed pixel accuracy so that the occlusion was perfect. The BSP tree technique was well understood by then, thanks to Carmack's work on Quake, but we didn't want to split polygons so we used this brute force method instead.
However, as a little bit of disinformation to other developers, we put a big file of random data on the Crash CD called BSPTREE.DAT. You still have to download this huge, pointless data file when you buy the game on PSN. I feel slightly guilty about that. :)
Sounds like one of those hacks where you're simultaneously laughing and shocked at how "kludgy yet it works" it is but relieved you've actually solved the problem in a way that meets the limitations and deadlines you have. Thanks for the replies, great to know this background information on a classic game!
While the FPU is busy doing that, the CPU can do the linear interpolation. Once the CPU is done with the 16 pixels, the FPU has also completed the divide and the CPU can do the next 16 pixels, and so on.
Looks pretty decent but is not 100% accurate.
¹ http://all-things-andy-gavin.com/2011/02/02/making-crash-ban...
Unlike most previous Mario games, there was no timer either. This only further encouraged players to really explore the 3D environment, collect the side-quest coins, and not be stressed out.
Mario 64, however, felt like something completely new. It was like the intro to Sonic 3D Blast[1], but with infinitely higher frame rate, and not pre-rendered!
[1]: https://youtu.be/oNS4_8ZX_tc Yep, not the most exciting of Sonic games by any stretch, but kids used to the Genesis graphics may had found a lot of promise for the future of 3D graphics on that now-crappy-looking intro (i know i did).
Picked up a Vive a few months ago--Valve created a program for it called Destinations where people can upload 3D environments with optional simple animation triggers, and you can teleport through the environment in VR. Somebody uploaded the exterior of Princess Peach's castle and the Shadow Temple boss area to it. Checking out Peach's castle in the headset was breathtaking, got that same kick to my chest and feeling of wonder I remember having as a kid and felt like I really recognized the environment in a way I didn't when I booted the games up in emulators. Being there in VR made the graphics look worse--the tiny textures originally meant to be viewed on a CRT get blown up across the several literal football fields and the polygons are huge sharp edges several feet across for the hills. I'm not sure why it provoked that emotional response in me. I would guess that I felt more immersed, and that immersion affected my perceptions as a kid.
Think back to the Nes and SNes era (apologies, I'm a Nintendo fanboy) and the booklets you always got with them. You might recall those booklets had character art in them.
I'm fairly convinced that because of that type of artwork, in combination with a lively fantasy, we recall our childhood heroes as real beings, rather than polygons or even pixels on a screen.
This, in combination with the power of empathy, has resulted in lively memories of heroes and villains duking it out in epic battles... that when revisited can take a while to get back into :)
http://www.infendo.com/wp-content/uploads/2010/07/1277784470...
That said, if you want to experience a truly good Zelda with perfect graphics on any display (even the Vive), try out the Wind Waker on Dolphin. It is arguably the best Zelda ever made, and it looks absolutely stunning on modern hardware.
There's also https://www.reddit.com/r/VideoGameScience for more technical material.
BTW: The linked site has a whole lot more articles like this one http://shmuplations.com/games/
Also, there are 2 more Infocom articles here: http://www.filfre.net/sitemap/
You can combine that with another trick: chaining long jumps works as long as you're close enough to the ground to kick off the ground, so if you hit the jump button rapidly enough, you'll jump repeatedly without leaving the ground. Notice in the linked video that you'll hear many jumping sounds rapidly, but occasionally the player will miss the timing and do a full-height jump.
That same trick also works to bypass the "infinite" staircase without having 70 stars (because you move past the looping portion in one frame).
Human players can successfully use this to warp through walls and bypass star/key requirements, to complete the game with 50, 16, 1, or 0 stars. Tool-assisted speedruns also use this to move rapidly through levels, but that requires a series of frame-perfect inputs.
(There's also a secret sister channel, pannenkeok2012, for lower-effort videos. Among other things, there's a comprehensive search of the game's PRNG in there!)
..yup! I have no idea how anyone has the degree of patience and passion to put that much effort into totally breaking down a game's limitations, but it's really something else to see in practice.
> Miyamoto: Ever since Donkey Kong, it’s been our thinking that for a game to sell, it has to excite the people who are watching the player—it has to make you want to say, “hey, gimme the controller next!” ...
The simple approach is to say, "to make a great game, it should be fun for the person playing it." But they've already taken a step back and approached it from the perspective that great gaming happens socially. Maybe this is one reason I cherished all the Nintendo games as much as I did. It's because the memories of playing them are always with other people and we're all having fun. It wasn't a solo act.
What is wrong with you people, these games are only 13 years old!!! ;)
> Miyamoto: That actually came from a prototype for Mario Paint 3D (that we’re still going to release).
I wonder, was Miyamoto referring to Mario Artist?
Reading this interview now, it sounds like they had plenty ideas for new stuff.
It is great to read that they actually had players like me in mind when they created the game. This article actually makes me want to dig up the game and play it through again.
The other comments reminded me of this fan-made video of an Unreal Engine-powered Super Mario 64. It's stunning.
Note: keep playing past 0:50 - it's not just the non-Mario environment.
Super Mario 64 was such an amazing game back in the day. It totally changed my life.