Saturday, October 11, 2014

Year ago I explained why it is so difficult to implement N64 mip-mapping. The problem is divided on two parts:

calculate per-pixel Level Of Details (LOD)

use calculated LOD to select texture mip levels and blend them with each other using LOD fraction.

The first task was completed year ago. I wrote pixel shader program, which calculated LOD and LOD_fraction. However, the plugin’s texture management subsystem did not support load and use of mip-mapped textures. Everything was designed to work with no more than two tiles. Thus, my LOD could be used only to blend the two most detailed levels of mip-map texture. This is perfectly enough for Peach-Bowser portrait transition in Super Mario 64, and absolutely unsuitable for textures with number of mip-map levels above two. Users, who have access to weekly betas, may notice how bad ground texture looks in Golden Eye for example with LOD emulation on.

Complete mip-mapping emulation became my task N1 for next week. It was necessary to implement load of N64 mip-mapped textures and write a pixel shader which fetch texels from right mip level. The task was done within one day, but it was not easy. The first-shot implementation worked so bad that I started to doubt that the task is possible. Long debugging started. I found several bugs in my LOD calculation shader, few ones in my texture loading code. Thus, step by step I approached to the goal. When at midnight I squeezed the last bug I could not believe my eyes: the tested game (it was Perfect Dark) is totally transfigured. The smooth change of textures level details looks charming. The difference between high and low detail levels brings feeling of distance to the picture. It looks like a different game. The result I can be proud of.

I’ll make a comparison video later. Now just one example, Perfect Dark.

The metal floor looks the same near and far without mip-mapping, because the most detailed texture level is always used.