Anti-Dithering Filter
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
Anti-Dithering Filter
I'm not 100% sure what SNES emulator is still under development, if any at all, but it'd be really sweet if Higan or SNES9x could have an Anti Dithering filter.
Attached is an example of what this filter would do for games with Dithering in them. Jurassic Park is pictured, as it makes heavy use of dithering in the grass and shadows.
Fusion and NESTopia already have such filters.
In the menu screenshot attached, I show how to activate these filters in NEStopia and Fusion.
In NESTopia's case, I show how to configure the NTSC filter so that it eliminates most composite artifacts and keep the image as sharp as possible.
It seems to me that the Fusion CVBS filter is set up like that to begin with, so didn't need such tweaking. (and doesn't have tweaking options)
I'm not a dev, I don't know any coding languages. It also seems strange to me that Sega and NES emulators have such capabilities while the SNES emulators lack them. : (
These are the best video game consoles ever! One of them shouldn't be lacking such an important feature.
Attached is an example of what this filter would do for games with Dithering in them. Jurassic Park is pictured, as it makes heavy use of dithering in the grass and shadows.
Fusion and NESTopia already have such filters.
In the menu screenshot attached, I show how to activate these filters in NEStopia and Fusion.
In NESTopia's case, I show how to configure the NTSC filter so that it eliminates most composite artifacts and keep the image as sharp as possible.
It seems to me that the Fusion CVBS filter is set up like that to begin with, so didn't need such tweaking. (and doesn't have tweaking options)
I'm not a dev, I don't know any coding languages. It also seems strange to me that Sega and NES emulators have such capabilities while the SNES emulators lack them. : (
These are the best video game consoles ever! One of them shouldn't be lacking such an important feature.
Re: Anti-Dithering Filter
I seem to remember one of them has an TV emulation filter (maybe snes9x). That should have a similar effect of blurring out dither.
EDIT, I'm wrong, that filter only seems to darken every other scanline. No blurring effect.
EDIT, I'm wrong, that filter only seems to darken every other scanline. No blurring effect.
Last edited by dougeff on Sat Nov 12, 2016 11:42 am, edited 1 time in total.
nesdoug.com -- blog/tutorial on programming for the NES
Re: Anti-Dithering Filter
As far as I can tell, your proposed anti-dither filter is just a [1 1]/2 convolution applied horizontally over the whole 256x224-pixel picture. I've attached an example of what that filter would do to the title screen of RHDE, an NES game whose title screen uses lots of dithering. It does an OK job with the 50:50 dithered areas, but the text at bottom becomes a blur-fest.
GIMP operations applied to right side:
- Transform into power domain (Colors > Levels, gamma=0.50)
- Low-pass filter (Filters > Generic > Convolution Matrix, matrix = [0 0 1 1 0]/2)
- Transform back into voltage domain (Colors > Levels, gamma=2.00)
Re: Anti-Dithering Filter
I did anyway. It's sort of complicated to describe in GIMP but should be practical to do with SIMD intrinsics or pixel shaders.
Create edge mask using the Sobel gradient detector:
Create edge mask using the Sobel gradient detector:
- Duplicate into new layer
- Colors > Desaturate (Luminosity)
- Filters > Generic > Convolution Matrix [[-1 0 1][-2 0 2][-1 0 1]], offset 128
- Create new layer filled with #808080
- Change layer's blending mode from Normal to Difference
- Layer > Merge Down
- Filters > Generic > Convolution Matrix [[1 2 1]]/4
- Colors > Threshold (50)
- Duplicate into new layer
- Colors > Levels, gamma .5
- Filters > Generic > Convolution Matrix [-1 2 6 2 -1]/8
- Colors > Levels, gamma 2
- Add alpha channel
- Select all white pixels in the mask layer
- Switch to the blur layer and delete those pixels
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Anti-Dithering Filter
Blargg's NTSC filter has several parameters; in particular one for "sharpness". SNES9X has Blargg's filter but unfortunately doesn't appear to expose any parameters for it. This is what it could look like with the sharpness turned down:
Personally, I'd try to start with Blargg's NTSC filter with the sharpness down, if you can find an emulator that gives you the option. Any horizontal blurring of the image will generally reduce the appearance of dither.
The Fusion emulator for Sega consoles has a "TV mode" but it looks like a very simple horizontal blend rather than an attempt at accurate signal emulation, i.e. making something that looks "good" rather than trying to match the original.
In the case of NES, it might be just because it's the system with the most emulators. You have a lot of options for NES.
The Fusion emulator for Sega consoles has a "TV mode" but it looks like a very simple horizontal blend rather than an attempt at accurate signal emulation, i.e. making something that looks "good" rather than trying to match the original.
I think in the case of Genesis/MegaDrive the "flagship" game Sonic has very prominent waterfalls in its first and second level that look a lot different with no filtering than they do on the real thing. (Some info here.)PimpUigi wrote:I'm not a dev, I don't know any coding languages. It also seems strange to me that Sega and NES emulators have such capabilities while the SNES emulators lack them.
In the case of NES, it might be just because it's the system with the most emulators. You have a lot of options for NES.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Anti-Dithering Filter
BizHawk seems to support custom filter shaders, though the collection included with the program seems a bit small.
Libretro has a large collection of filters too: https://github.com/libretro/common-shaders
I don't have a Libretro emulator running, but I suspect one of those NTSC "gauss" filters might be close to what you want? (If not, there's a lot of filters in there you could try.)
Libretro has a large collection of filters too: https://github.com/libretro/common-shaders
I don't have a Libretro emulator running, but I suspect one of those NTSC "gauss" filters might be close to what you want? (If not, there's a lot of filters in there you could try.)
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: Anti-Dithering Filter
Probably because most SNES games put much less emphasis on dithering than Genesis or NES games due to having more color palette entries.PimpUigi wrote:It also seems strange to me that Sega and NES emulators have such capabilities while the SNES emulators lack them.
I'm not sure what most of this is, but I find it interesting that in the shot you posted how some of the spots are dithered while others aren't, even if they're the same size. It sounds like to me you're doing blending and various GPU accelerated stuff, but it seems to me the best way to blend dithered areas would be to look for a pattern of alternating pixels, where you'd look at the first pixel, and then the third, and if it's the same, get the color of the second pixel and average it together and make the three pixels that color. From then on check every pixel, checking the color of odd pixels against the first one and the color of even pixels against the second one. If the colors match, replace the pixel with the blended color. If they don't, stop the search and go back to step one. This would work by rows, so checkerboard and vertical line patterns would work, but not horizontal line patterns, but you never see those anyway. I'm sure this would have to be done by the CPU, but with how powerful they are nowadays, I'm sure it wouldn't matter.tepples wrote:I did anyway. It's sort of complicated to describe in GIMP but should be practical to do with SIMD intrinsics or pixel shaders.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Anti-Dithering Filter
Here's two simple shaders for BizHawk (put them in BizHawk's "Shaders" folder and select the CGP from Config > Display > Scaling Filter > User).
horizontal_filter is a [ 1 2 1 ] convolution (blend each pixel with half of each neighbouring pixel)
horizontal_filter_hires is a [ 1 1 2 2 1 1 ] convolution (similar but with doubled width)
Jurassic Park has double resolution, so it needs the hires version. The result looks like this: Again, not "accurate" to the original, IMO, but it seems similar to the "TV" filter in Fusion.
horizontal_filter is a [ 1 2 1 ] convolution (blend each pixel with half of each neighbouring pixel)
horizontal_filter_hires is a [ 1 1 2 2 1 1 ] convolution (similar but with doubled width)
Jurassic Park has double resolution, so it needs the hires version. The result looks like this: Again, not "accurate" to the original, IMO, but it seems similar to the "TV" filter in Fusion.
- Attachments
-
- horizontal_filters.zip
- (1.52 KiB) Downloaded 166 times
Re: Anti-Dithering Filter
With Fusion setup the way I showed in the attached configuration screenshot in the first post, and my PC connected my 34 inch CRT HDTV via HDMI, it is virtually indistinguishable from my Sega Genesis connected via composite when switching back and forth to look for differences.rainwarrior wrote:The Fusion emulator for Sega consoles has a "TV mode" but it looks like a very simple horizontal blend rather than an attempt at accurate signal emulation, i.e. making something that looks "good" rather than trying to match the original.
The only difference really, is that colors are *slightly* muted via Composite vs. Fusion over HDMI, but I can actually adjust that via the TV's service menu. (which can adjust the color settings per input)
My CRT HDTV doesn't display scanlines, and I dislike scanlines anyway.
- nothingtosay
- Posts: 39
- Joined: Mon May 19, 2014 11:46 pm
Re: Anti-Dithering Filter
These shaders already exist. https://filthypants.blogspot.com/2013/0 ... aders.html
MDAPT tries to detect parts of the image to work on and leave the others alone rather than blurring the whole scene. It's in the libretro shader pack (as is CBOD, which is also covered on the linked page).
MDAPT tries to detect parts of the image to work on and leave the others alone rather than blurring the whole scene. It's in the libretro shader pack (as is CBOD, which is also covered on the linked page).
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Anti-Dithering Filter
If you want to target dithering specifically, I'm thinking it would be better to try to detect dither, rather than reject edges.tepples wrote:(used sobel gradient to detect edges, then blur anything that isn't an edge)
Dithered pixels should be a neighbourhood of "high low high" or "low high low", as opposed to monotonically increasing (an "edge") or flat.
So maybe:
1. Apply a median filter that is 3 pixels wide.
2. Create the filter mask to operate anywhere the pixel does not match the median.
3. Use a [ 1 2 1 ] convolution filter to blur each "dithered" pixel with its two neighbours.
Result: GIMP doesn't directly have a median filter (it sort of does as "despeckle") but here's a python example. I filtered the RGB channels separately, but you might take a different approach to do a shared median test. Areas containing 3 different colours in a row are a casualty here.
Edit: Python scripts were later disallowed on this forum. Uploading a ZIP with what I think was the original script.
- Attachments
-
- median_dither.py.zip
- (625 Bytes) Downloaded 79 times
-
[The extension py has been deactivated and can no longer be displayed.]
Last edited by rainwarrior on Tue Jun 12, 2018 12:38 pm, edited 1 time in total.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Anti-Dithering Filter
What I meant specifically is that it doesn't seem to do any emulation of the colour artifacts which I was used to seeing on my CRT back when I had a Genesis. The easiest example of this is a "rainbow" pattern on Sonic's waterfalls that are missing here. (This article I linked earlier has a really good photograph of this.) I don't know if every TV does the same thing, but mine did.PimpUigi wrote:With Fusion setup the way I showed in the attached configuration screenshot in the first post, and my PC connected my 34 inch CRT HDTV via HDMI, it is virtually indistinguishable from my Sega Genesis connected via composite when switching back and forth to look for differences.rainwarrior wrote:The Fusion emulator for Sega consoles has a "TV mode" but it looks like a very simple horizontal blend rather than an attempt at accurate signal emulation, i.e. making something that looks "good" rather than trying to match the original.
I don't know precisely what Fusion's filters are doing, as it doesn't appear to be open source, so it's really hard to speculate. As far as I can tell, the "RF" and "CVBS" TV filters appear to blend rows of 3 and 2 pixels respectively, before any upscaling, which I don't think accurately models any particular analog signal process, but it is a horizontal blur that does reduce the appearance of dither (and it's common for some kind of horizontal blur to occur in the real thing).
Anyhow, no emulation is perfect. If you like what you see, then you should use it. I don't really consider NTSC artifacts and scanlines to be the "best" way to experience things; I'm just saying that if hardware accuracy is your goal then the way to get there is probably through NTSC signal emulation. Filters designed to target just dither specifically are an artificial thing that don't really relate to the hardware.
Re: Anti-Dithering Filter
In 320px mode, the Genesis VDP's dot clock is ~6.712 MHz, and an alternating dark and light pattern would oscillate at half that (~3.356 MHz). But this is very close to the NTSC chroma subcarrier frequency (~3.580 MHz) and thus well within the conventional 3.0-4.2 MHz chroma band. Thus the TV interprets the signal as rainbows repeating every 30 horizontal pixels.
Exact values: NTSC color burst is 315/88 MHz, and Genesis 320px mode dot clock is 15/8 times color burst
Exact values: NTSC color burst is 315/88 MHz, and Genesis 320px mode dot clock is 15/8 times color burst
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Anti-Dithering Filter
Thought of an alternative to the median test. If you consider dither to be an alternation of 2 colours only, then the test for whether to apply dither blend can simply be whether the left neighbour is the same as the right neighbour. (This is more restricted than the median approach, as it avoids all 3 colour cases.)rainwarrior wrote:Areas containing 3 different colours in a row are a casualty here.
This approach would fail on Sonic waterfalls, though, since they don't meet that definition of dither. Depends what you're trying to accomplish.
In the attached example, note there's less corruption of the "furniture fight" text overlaid on the red "rhde":
Edit: Python scripts were later disallowed on this forum. Uploading a ZIP with what I think was the original script.
- Attachments
-
- 2colour_dither.py.zip
- (597 Bytes) Downloaded 78 times
-
[The extension py has been deactivated and can no longer be displayed.]