When whipping up Railgun in two weeks' time for a game jam, I aimed to make the entire experience look and feel as N64-esque as I could muster in that short span. But the whole game was constructed in Godot, a modern engine, and targeted for PC. I just tried to look the part.
Here is the same bedroom scene running on an actual Nintendo 64:
I cannot overstate just how fucking amazing this is.
Obviously this is not using Godot anymore, but an open source SDK for the N64 called Libdragon. The 3D support is still very much in active development, and it implements-- get this-- OpenGL 1.1 under the hood. What the heck is this sorcery...
UH OH, YOU'VE BEEN TRAPPED IN THE GEEK ZONE! NO ESCAPE NO ESCAPE NO ESCAPE EHUEHUHEUHEUHEUHUEH
While there is a gltf importer for models, I didn't want to put my faith in a kinda buggy importer with an already (in my experience) kinda buggy model format. I wanted more control over how my mesh data is stored in memory, and how it gets drawn. So instead I opted for a more direct solution: converting every vertex of every triangle of every object in the scene by fucking hand.
THERE ARE NEARLY NINE HUNDRED LINES OF THIS SHIT. THIS TOOK ME MONTHS.
And these are just the vertices. I had to figure out triangle drawing PER VERTEX. You have to construct each triangle counterclockwise in order for the front of the face to be, well, the front. In addition, starting the next tri with the last vertex of the previous tri is the most efficient, so I plotted out so many diagrams to determine how to most efficiently draw each mesh.
And god the TEXTURES.
When I painted the textures for this scene originally, I went no larger than 64 x 64 pixels for each. The N64 has an infamously minuscule texture cache of 4kb, and while there were some different formats to try and make the most of it, I previously understood this resolution to be the maximum.
Guess what? I was wrong!
You can go higher.
Tall textures, such as the closet and hallway doors, were stored as 32 x 64 in Godot. On the actual N64, however, I chose the CI4 texture format, aka 4-bit color index. I can choose a palette of 16 colors, and in doing so bump it up to 48 x 84.
On the left, the original texture in Godot at 32 x 64px. On the right, an updated texture on the N64 at 48 x 84px. Latter screenshot taken in the Ares emulator.
The window, previously the same smaller size, is now a full 64 x 64 CI4 texture mirrored once vertically. Why I didn't think of this previously in Godot I do not know lol
Similarly, the sides of the monitors in the room? A single 32 x 8 CI4 texture. The N64 does a neat thing where you can specify the number of times a texture repeats or mirrors on each axis, and clip it afterwards. So I draw a single vent in the texture, mirror it twice horizontally and 4 times vertically, adjusting the texture coordinates so the vents sit toward the back of the monitor.
The bookshelf actually had to be split up into two textures for the top and bottom halves. Due to the colorful array of books on display, a 16 color palette wasn't enough to show it all cleanly. So instead these are two CI8 textures, an 8-bit color index so 256 colors per half!! At a slightly bumped up resolution of 42 x 42.
You can now kind of sort of tell what the mysterious object on the 2nd shelf is. It's. It is a sea urchin y'all it is in the room of a character that literally goes by Urchin do ddo you get it n-
also hey do u notice anything coo,l about the color of the books on each shelf perhaps they also hjint at things about Urchin as a character teehee :3c
I redid the ceiling texture anyways cause the old one was kind of garbage, (simple noise that somehow made the edges obvious when tiled). Not only is it still 64px, but it's now an I4 texture, aka 4-bit intensity. There's no color information here, it's simply a grayscale image that gets blended over the vertex color. So it's half the size in memory now!
Similarly the ceiling fan shadow now has a texture on it (it was previously just a black polygon). The format is IA4, or 4-bit intensity alpha. 3 bits of intensity (b/w), 1 bit of alpha (transparency). It's super subtle but it now has some pleasing vertex colors that compliment the lighting in the room!
Left, Godot. Right, N64.
All of the texture resolutions either stayed the same, or got BIGGER thanks to the different texture formats the N64 provides. Simply put:
THE SCENE LOOKS BETTER ON THE ACTUAL N64.
ALSO IT RUNS AT 60FPS. MOSTLY*.
*It depends on the camera angle, as tried to order draw calls of everything in the scene to render as efficiently as I could for most common viewing angles. Even then there are STILL improvements I know I can make, particularly with disabling the Z-buffer for some parts of the room. And I still want to add more to the scene: ambient sounds, and if I can manage it, the particles of dust that swirl around the room.
Optimization is wild, y'all.
But more strikingly... fulfilling a childhood dream of making something that actually renders and works on the first video game console I ever played? Holy shit.
Seeing this thing I made on this nearly thirty-year-old console, on this fuzzy CRT, is such a fucking trip. I will never tire of it.
46 notes
·
View notes
DID YOU WATCH THE NEW EPISODE YET??? IM YELLING IT WAS SO GOOD
what
New episode of what!?!
WHICH OF MY FAVORITE SHOWS DO I NEED TO LOOK AT!?!?!
21 notes
·
View notes