Reverse Antialiasing Shader

Hi, long time no see!

I’m here to present a new filter that was developed by some other guy (in this link http://kdepepo.wordpress.com/2012/08/15/reverse-antialiasing-for-image-scaling/ )

It’s called Reverse Antialiasing, because it almost completely reverts the anti-aliasing effect when upscaling an image.

I’m amazed by some results of this filter. Take this example (from the site):

The original image shows a anti-aliasing effect. The last image is the filter result. See how it scales the image by 2 and doesn’t blur it (much better than the bilinear filter).

So, I tested it on some other samples to see how the filter would perform. Here’s some:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

As you can see, it’s very good with real world pictures in general.

One of its weaknesses is that it can’t filter high frequency graphics. So, games like Mario and Zelda wouldn’t look much different from a nearest neighbour filter.

In particular, one game which works well with this filter is Mortal Kombat. Look at these images:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

Original2x Filtered:

I’ve got the C sources from the guy and implemented a shader version that works in Retroarch.

Here: http://pastie.org/4687743

1 Like

Those are some pretty incredible results!

Hmm. It doesn’t look good to me; looks like a broken mix of point and bilinear most of the time. It definitely looks bad for pixel art. Bicubic or Lanczos would probably look better for all of these examples.

Of course, thanks for the contribution. It’s useful for those who wish to experiment!

It’s a question of taste, indeed.

The shader only works at 2x scale for now, so you have to put a second shader like lanczos16, bicubic or ddt to see how it performs in higher resolutions (and POINT-POINT as hardware filtering).

What I like about this filter is that it does something completely new, it upscales the image without blurring it and nor destroying its geometry. It’s effective with digitized games like mortal kombat or “modern” games which are plagued with anti-aliasing technique.

I was most impressed with its performance with text, which remains smooth yet sharp. I suspect it will look very nice with prerendered scenes from PSX games, as well, such as the backgrounds in Resident Evil and/or Final Fantasy games.

Yes, all digitized and anti-aliased games will look good with it.

One more example, Final Fantasy Tactics for PSP. It’s a game plagued with anti-aliasing technique. See how it performs with various filters:

Enter this link --> http://i.imgur.com/pWYaw.png

(I didn’t post directly here because the forum resizes the image and destroys the filter ouputs.)

Of those, nearest neighbor (aka point) looks the best to me.

Comparisons with Resident Evil:

Original … Nearest Neighbor … Bilinear

DDT2x … 2xBR … Reverse AA

Original … Nearest Neighbor … Bilinear

DDT2x … 2xBR … Reverse AA

Original … Nearest Neighbor … Bilinear

DDT2x … 2xBR … Reverse AA

A combination of xBR and ReverseAA in genesis games:

2 Likes

Those screenshots look fantastic, especially the bubbly text, which sometimes gets distorted by xBR.

Yes. I need to evolute it a bit more, but the current version is already showing good results. If you wanna test, it’s already available:

Use this as first shader: https://github.com/libretro/common-shaders/blob/master/xBR-Hybrid/2xbr-hybrid.cg

Use this as second shader: https://github.com/libretro/common-shaders/blob/master/ddt.cg

Choose:

  • 2x scale
  • POINT
  • POINT

The ddt let the image slightly smooth.

Three more shots of Genesis games: http://imgur.com/a/UzdJ7

And many from SNES games: http://imgur.com/a/sGOTj

SNES - part 2 : http://imgur.com/a/cE3Xn

Ah, I was going to write a cgp file that would configure the xBR-hybrid and ddt shaders together but maister beat me to it :stuck_out_tongue:

The result is indeed very nice. I’m going to use it for any/all RPGs and other text-heavy games from now on.

Yes, I convinced him yesterday! :stuck_out_tongue:

There´s room to improve the rule to switch between algorithms. For now, it´s the best I can get. It´s specially good with more digitized games. And should have excellent results with NDS e psx 2D games.

Tried running several “Reverse AA” filters. All made RetroArch crash.

First things first: This shader is AMAZING Quite possibly the best thing since sliced bread.

Now the problem: While I can stack 2xbr-hybrid.cg and ddt.cg just fine using the “render to texture” setting in retroarch, I’m getting an error off the .cgp posted in this thread. Specifically:

RetroArch [ERROR] :: [D3D9 Cg]: Vertex error: C:/Program Files/RetroArch/CG Shaders/metashaders/xbr-hybrid-ddt.cgp(1) : error C0000: syntax error, unexpected ‘=’, expecting “::” at token “=”

I’m probably doing something stupid here. Anyone care to set me on the right path?

time to revive the thread. I’m currently working on ScaleFX and there is also a variant similar to Hyllians xBR-hybrid which combies ScaleFX and reverseAA. while improving my shader I noticed that rAA causes some artifacts especially with high sharpness values. this is called ringing which reminded me of a no-ring workaround for sharp resize filters I saw a while back on avisynth discussions on doom9. it’s actually rather simple:

LanczosResize(dest_x,dest_y).Repair(Gaussresize(dest_x,dest_y,p=100),1)

so what does it do? well the picture is resized with some filter (in this case Lanczos) and then we clamp the pixels by taking the min and max of the 3x3 pixels around it (Repair mode 1) of the point resized picture at the same resolution (gaussresize with harpness 100). this completely eliminates all ringing artifacts. I used the same concept on rAA. if you look at the code you’ll see that the algorithm uses the following pixels:


      B1
      B
D0 D  E  F  F4
      H
      H5

this is what I changed:

// original
float3 res = saturate(E + fp.y*t1 + fp.x*t2);

return float4(res, 1.0);

-----------------------------------------------------------------

// no-ring
float3 res = E + fp.y*t1 + fp.x*t2;
float3 a   = min(min(min(min(B,D),E),F),H);
float3 b   = max(max(max(max(B,D),E),F),H);

return float4(clamp(res, a, b), 1.0);

download: https://mega.nz/#!uF4BELTa!311U9Z-MH2I4yKtS0zITSqbxjnThlkJCfYvs3A86XCE

and two examples of it in action (rAA_sharpness = 2.0): http://screenshotcomparison.com/comparison/165611/

the original frames:

Humm, ReverseAA already has a rudimentary anti-ringing in its own code. I’ll have to evaluate if it’s better to take out it. I’ve noticed that it leaks some ringing here and there.

you mean the clamp call in the helper function res2x? I just tested it without it with unpleasant results. it seems that it is necessary.

Yes. That’s a hard anti-ring.