Sayonara 544p

Sayonara Umihara Kawase recently got a PC port. I was pretty enthused about this since I like quirky physics platformers. Sadly, the port turned out to be resolution locked in perhaps one of the worst ways seen to date. People believed it to render at 960×544 (Vita resolution), but the truth is even stranger.

Anyway, this sunday at around noon I thought I could give fixing it a try, given that the game should be DX9 according to the Steam requirements. Well, after buying it, the first thing I learned was that it is actually DX11. This turned what I was hoping for would be a quick fix into a longer struggle, but nonetheless I managed to unlock the resolution (it’s what I do after all).

In the process of that I also learned that internally, the game actually renders to a 896×512 portion of a 1024×512 rendertarget !! That’s, IMHO, even more insane than the 960×544 1:1 Vita port people expected.

Anyway, the result looked like this:

Which is a pretty decent upgrade from this:

However, the background texture, specifically the bricks on the right, are really really awful. Too awful to be truly improved by anything other than someone going in and replacing them with a redrawn version, but nonetheless I was apparently hyper-motivated today so I tried.

I integrated the texture scaling code I wrote for PPSSPP a while back into GeDoSaTo, and (somewhat surprisingly to me) even managed to apply it to Umihara without making everything explode. It’s very limited in when it works right now, but there’s nothing in principle preventing it from being potentially applied to all kinds of DX9 and DX11 games if there is a desire for that.

Anyway, the final result, with hybrid xbrz+bicubic texture scaling, looks like this:

Which clears up the pixelly mess of bricks slightly, though obviously you can’t expect miracles from an automatic process.

I started at around noon, and what I intended to be a fun few hours coding romp leaves me here at 22:40, but I think it was worth it. I hope the other 2 people who are both into ultra-niche Japanese physics platformers and rendering quality enjoy it!

All of this is integrated in the latest version of GeDoSaTo, 0.18 “Disharmonized Genesis”. You can get the latest version with the installer provided here. And, as always, you can donate to support GeDoSaTo development here.

Texture Scaling in Emulators

PPSSPP is a great PSP emulator for all kinds of platforms, including Windows and Android. I recently started using it to play some of my PSP games, and I was surprised how nice a few of them (particularly the stylized ones) can look with some AA and a higher rendering resolution.

However, the texture resolution on many of the games is a huge blemish on the visuals. Look at this example (from Fate: Extra): DefaultParticularly the hair is absurdly pixelized, but the clothing and tree texture aren’t much better. In general, trying to make a higher resolution image from a lower resolution one is a fool’s errand, as the information just isn’t there. However, for stylized textures such as these I thought something might be done.

The first idea was to use HQ4x, an image scaling algorithm designed for pixel art. Hacking that into PPSSPP yielded the following result:
hq4xAs you can see, it was pretty effective on the hard transparency edges of the hair and tree textures, but only increased the pixelation on the soft, anti-aliased edges of the cloth.

Luckily, scaling of image art has advanced quite a bit since HQx was created, and I soon found an algorithm called xBR created by Hyllian on the byuu.org message boards. The source code for xBRZ, a slightly improved and parallelizable implementation of xBR is available as part of the HqMAME project. It deals much better with anti-aliased edges, and integrating it into PPSSPP ended up looking like this:xbrzIt’s a generally great result, and better than HQ4x, with one drawback: the posterization of gradients. It’s not too apparent in the image above, but it can be very distracting in other scenes and games (e.g. it can look really bad in sky textures).

To circumvent that effect I had to take to Matlab. I came up with an algorithm that calculates a mask based on the local contrast of a texture, and then chooses between xBRZ and bilinear/bicubic texture scaling based on the mask value.
maskPutting all of that together, and adding an additional deposterization step which improves the quality of compressed textures, I arrived at this:
hybridThe initial version was very slow, particularly with bicubic scaling. So I also parallelized everything and added a SSE 4.1 version of the scaling function. You can try the final result in any recent build of PPSSPP.

There are still many things that could be explored for even better automatic texture scaling in emulators. One particular deficiency of xBR for texture scaling is how it deals with the borders of images. It simply assumes that the texture continues as on the border (i.e. replicates it). A better idea for textures could be to assume that the edge direction continues as it does on the border – this could reduce some tiling artifacts that appear when scaling.

Another interesting topic would be the replication of noise or small-scale detail on an upscaled texture, but it would require some in-depth analysis of the texture images which might not be feasible in real-time.