Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sharp bilinear postprocessing shader. #9860

Merged
merged 1 commit into from
Feb 4, 2023

Conversation

AdmiralCurtiss
Copy link
Contributor

Attempt at porting this shader to Dolphin, for those who prefer a more pixel-y look. Honestly it looks pretty bad to me for 3D games, but ymmv.

I'm not sure this algorithm is completely correct; I attempted to do the equivalent with ImageMagick like this:

magick RSBP01_2021-07-04_01-56-21.png -scale 1920x1704! native_scaled_point.png
magick native_scaled_point.png -filter triangle -resize 1920x1096! native_scaled_final.png

and the resulting image is slightly different. So... not sure. I'll need to experiment a bit more so I actually understand how this code works, I think.

For reference:

Native resolution screenshot
As displayed by Dolphin
As displayed by Dolphin if we were to force point filtering
As displayed by Dolphin with this shader
As scaled by ImageMagick

Oh, and the postproc shader config system seems to be completely broken, they fail to compile if they have an option. Someone should probably look at that...

@MayImilae
Copy link
Contributor

MayImilae commented Jul 4, 2021

Pixel peeping, true point filtered is definitely sharper than Sharp Bilinear in these results, though the difference isn't that much. The blurring occurs when there is a "half pixel" when point sampling is doing shenanigans to fit the pixel grind, and it's sharp in point filtering but blurred in sharp bilinear. you can see it in the lamp especially the top slit.

Is Sharp Bilinear's behavior more desirable than simply point filtering? Regardless either solution would probably be fine for sharp pixels fans, but just asking.

Point Filter
pointerfilter-zoom

Sharp Bilinear
shader-zoom

@iwubcode
Copy link
Contributor

iwubcode commented Jul 4, 2021

Oh, and the postproc shader config system seems to be completely broken, they fail to compile if they have an option. Someone should probably look at that...

Please wait just a little longer :)

@AdmiralCurtiss
Copy link
Contributor Author

Pixel peeping, true point filtered is definitely sharper than Sharp Bilinear in these results, though the difference isn't that much. The blurring occurs when there is a "half pixel" when point sampling is doing shenanigans to fit the pixel grind, and it's sharp in point filtering but blurred in sharp bilinear. you can see it in the lamp especially the top slit.

Is Sharp Bilinear's behavior more desirable than simply point filtering? Regardless either solution would probably be fine for sharp pixels fans, but just asking.

The reason you want something like Sharp-Bilinear instead of straight Point filtering is to avoid uneven pixel sizing, which can look quite bad in motion. This is probably less of a big deal at GC/Wii resolutions and 3D games, but here's an example of NES Super Mario Bros, scaled 2x vertically and slightly above 2x horizontally to achieve the aspect ratio a real NES would have appoximately had on a real CRT back in the day:

shimmer_point_test

Look at the floor. Notice how the outlines of the blocks create a distracting pattern in motion? This has become known as 'shimmering' artifacts in enthusiast circles and happens because the individual columns of source pixels are unevenly sized -- some are 3 pixels wide, some are 2 wide -- so a pattern moving across them stands out poorly. Now if we instead scale with a bilinear filter:

shimmer_bilin_test

The distracting effect is gone! But now the whole picture is blurry. So what if we instead want both? Well, the commonly accepted solution has become to first scale up to the nearest-but-not-smaller integer multiple resolution (individually per axis), so in this case 2x vertically and 3x horizontally, then scaling back down to the desired actual resolution with a bilinear filter. This ends up with:

shimmer_sharpbilin_test

There, nice as can be given the limitations of modern fixed pixel grid displays.

This shader, if I'm understanding it correctly, attempts to do this exact thing but in a single scaling step by fudging with the bilinear scaling coefficients so they end up at a position where they produce an identical result.

@MayImilae
Copy link
Contributor

That is an extremely good point and well explained, thanks.

Comment on lines 6 to 16
/*
[configuration]

OptionRangeFloat
GUIName = Prescale Factor (set to 0 for automatic)
OptionName = PRESCALE_FACTOR
MinValue = 0.0
MaxValue = 16.0
StepAmount = 1.0
DefaultValue = 0.0

[/configuration]
*/
Copy link
Contributor

@TryTwo TryTwo Jun 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/*
[configuration]
OptionRangeFloat
GUIName = Prescale Factor (set to 0 for automatic)
OptionName = PRESCALE_FACTOR
MinValue = 0.0
MaxValue = 16.0
StepAmount = 1.0
DefaultValue = 0.0
[/configuration]
*/
/*
[configuration]
[OptionRangeFloat]
GUIName = Prescale_Factor
OptionName = PRESCALE
MinValue = 0.0
MaxValue = 16.0
StepAmount = 1.0
DefaultValue = 0.0
[/configuration]

I just figured this out.

@AdmiralCurtiss AdmiralCurtiss marked this pull request as ready for review February 4, 2023 20:21
@AdmiralCurtiss AdmiralCurtiss changed the title [WIP] Add sharp bilinear postprocessing shader. Add sharp bilinear postprocessing shader. Feb 4, 2023
@AdmiralCurtiss AdmiralCurtiss merged commit c10758e into dolphin-emu:master Feb 4, 2023
@MayImilae
Copy link
Contributor

MayImilae commented May 16, 2023

The reason you want something like Sharp-Bilinear instead of straight Point filtering is to avoid uneven pixel sizing, which can look quite bad in motion. This is probably less of a big deal at GC/Wii resolutions and 3D games, but here's an example of NES Super Mario Bros, scaled 2x vertically and slightly above 2x horizontally to achieve the aspect ratio a real NES would have appoximately had on a real CRT back in the day:

shimmer_point_test

Look at the floor. Notice how the outlines of the blocks create a distracting pattern in motion? This has become known as 'shimmering' artifacts in enthusiast circles and happens because the individual columns of source pixels are unevenly sized -- some are 3 pixels wide, some are 2 wide -- so a pattern moving across them stands out poorly. Now if we instead scale with a bilinear filter:

shimmer_bilin_test

The distracting effect is gone! But now the whole picture is blurry. So what if we instead want both? Well, the commonly accepted solution has become to first scale up to the nearest-but-not-smaller integer multiple resolution (individually per axis), so in this case 2x vertically and 3x horizontally, then scaling back down to the desired actual resolution with a bilinear filter. This ends up with:

shimmer_sharpbilin_test

There, nice as can be given the limitations of modern fixed pixel grid displays.

@AdmiralCurtiss These images are great! Can I have them? Ok seriously, where are they from and do they have any licensing attached? I want to know if I can use them in the report directly or if I need to recreate them in Dolphin. If I can reuse them, it would save me like 6 hours of recording and video editing. I'll do it if I have to but I'd rather not!

@AdmiralCurtiss AdmiralCurtiss deleted the sharp-bilinear branch May 16, 2023 03:27
@AdmiralCurtiss
Copy link
Contributor Author

AdmiralCurtiss commented May 16, 2023

Yeah sure, you can use them. They're not from Dolphin but a NES emulator, but for explaining the concept it totally works.

(Specificially, I recorded a lossless 1x 1:1 pixel AR video and then did the scaling/filtering/gif export with Avisynth.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
4 participants