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.

13 thoughts on “Texture Scaling in Emulators

  1. Pingback: Baixar Emulaador PSP para Android (PPSSPP) Ver 0.9.1 APK (Funciona até em Galaxy ACE) Grátis | Gamer de Celular | Jogos para Celular

  2. Ok thanks, was just hoping for a holy grail solution I guess! Now where did I leave that CRT…

  3. I’ve been trying to find a way for years to upscale the original FF7 PS game without ruining the pre-rendered backgrounds. I have very little knowledge of how any of this works but was wondering if any of this would work, or if it’s a separate issue due to the backgrounds not being textures as such?

    • It’s generally the same, the backgrounds are also textures. However, the upscaling options described here sadly wouldn’t really do all that much for those backgrounds. They primarily work well with clear geometric shapes that can be recognized, a pre-rendered background doesn’t really fall into that.

  4. This was a really interesting post. I always wondered how emulators were able to improve so much on visual quality. Now I know a little more :) Thanks!

  5. Greetings!

    That’s an excellent usage of xBR algorithm, I’m glad you like it.

    xBR isn’t finished yet. I have been keeping my research on it in my free time. It’s in constant evolution.

    Only to clarify a point in your text, I don’t agree xBRz is an improved xBR, but a question of taste. It’s a different flavor, I’d say. The core idea is the same, it’s just different in corner detection. It’s great the parallel implementation from Zenju could be useful in PPSSPP (an awesome emulator).

    Congrats,
    Hyllian

    • Hi, thanks for your great work on xBR! I agree with you that xBRz is a different flavor more than a straight up improvement, I formulated that poorly.

      Since you are the one who originally came up with the algorithm, do you have any ideas on how to deal with the problems at texture edges? This is something that doesn’t really occur when scaling an entire screen or sprites.

      • One idea would be to use black borders instead replicating texture edge pixels. It should take care of most artifacts.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">