A simple sharp pixel shader config for RetroPie with integer prescale and no pixelwobble
I made a very simple shader config. It results in sharp pixels without wobble and minimal blurring. It applies a 2x integer prescale with point filtering, and then scales only "the remainder" using bilinear filtering.
Sharp-Bilinear Shaders for Retroarch
This is a collection of shaders for sharp pixels without pixel wobble and minimal blurring in RetroArch/Libretro.
There are two shaders included.
This shader does a fixed 2x integer prescale resulting in a small amount of image blurring but no pixelwobble. This is a simple two-pass shader configuration. First, an integer 2x prescale is applied, followed by a bilinear scaling to fullscreen.
This shader does an automatic optimum integer prescale (2x, 3x, 4x etc.), depending on game and screen resolution. I recommend this shader since the autoscaling results in sharper images for some games than the fixed 2x prescale.
Both shader configurations give sharp pixels with zero pixel wobble in all games.
Compared to the "video smoothing=ON" setting with no shaders, pixels are less blurry. Compared to the "video smoothing=OFF" setting with no shaders, the pixels do not change shape/wobble as they move across the screen.
I tried TheMaister's autoscaling shader from the libretro repo, "retro/sharp-bilinear.glslp," but, for some reason, that shader did not work well with vertical games for me.
To install this shader in RetroPie:
- Copy the contents of the included "Copy_To_RetroPie" folder to /opt/retropie/emulators/retroarch/shader/
- open the RetroPie-Setup menu and choose "Edit RetroPie/RetroArch Configurations"-> "configure basic libretro emulator options"-> "configure default options for all libretro emulators"
- set "Video Shader Enable" to "True"
- set "Video Shader File" to "sharp-bilinear-simple.glslp," or "2x-prescale-sharp-bilinear.glslp" depending on your preference.
shader "sharp-bilinear-simple.glslp" on:
shader off, smoothing on (too much blur):
shader off, smoothing off:
On first glance, the above looks sharp and good, but looking at a detail, we can see pixel wobble that happens if no shader is used. The pixels along the black diagonal should all be the same, square shape, but some of them appear rectangular:
Compare the above detail to the result with the shader on:
Now all pixels have the same shape, at the cost of a slight reduction in sharpness.
@rsn8887 can you show an example screenshot?
I added screenshots to the original post but akismet.com flagged it as spam???
Here they are again:
@rsn8887 your 'without shader' one seems to have video_smooth on, or something like that? it's not on by default. the image should be crisp
No, the shader does that for the final scaling. It is there to remove pixelwobble.
If it is perfectly crisp, then the pixels change shape as they scroll. This is because the scaling from source res to target res is usually not an integer. Therefore, a square pixel becomes a slight rectangle then a square again as it moves across the screen. This is a very annoyting effect and that is why I created this shader.
If pixelwobble does not annoy you, you can just disable shaders, turn video smoothing off, and you get that perfectly crisp image. But you will have pixelwobble, e.g. pixels change shape noticably across the screen, unless your TV res is an exact integer multiple of the game res.
Here is an example:
smoothing off, no shader:
If you look at the pixels in detail you will see they change shape from square to rectangular:
I call this pixelwobble, because during slow scrolling you will see the pixels change from square to squished rectangles, back to square again creating a wobble effect.
sharp-bilinear shaders eliminate this effect at the expense of some blurriness.
rsn8887 last edited by
Sorry for the image formatting. Akismet.com is so annoyting it will not let me edit my posts to fix the images.
ohmycommodore last edited by ohmycommodore
well damn, it's like i don't need my glasses. ok i still do... but still :) haven't started playing with shaders yet so this might be a useful first attempt for me.
how does this fare across a number of different systems? i suppose you're shooting for an above-average improvement on as many systems as possible?
i've seen a lot of scan-line based shaders, which in a round about way sharpen things up. i take it this is a different approach to a similar end result?
lilbud last edited by
@rsn8887 I'd first like to say that this shader looks amazing. Second, there actually is a in depth reason about pixel sizing.
I know this happens on many 8 & 16 bit systems. When the game is scaled up at an integer scale, the pixels aren't meant to be perfect squares. At least on the NES, the pixels are meant to be stretched 1.2x wider by your display, like an old CRT. When the pixels are unevenly scaled, this can lead to a shimmer effect (or "framewobble" as you so affectionately named it.)
If you want a really good example on the above, play Contra at a non integer scale and look at the cliffside on the first level, you will never unsee the shimmer.
@Lilbud, yes my mistake. The pixels should not always be square and they will not always be square with this shader. Depending on the system, they might be rectangles and that is fine.
The only important thing is that each pixel should be the same shape (rectangle or square) they should all appear the same. That is the goal here.
Note you can easily change the pre-scale factor from 2.0 to 3.0 or 4.0 or any integer just edit the file 2x-sharp-bilinear.glslp with a text editor. The higher you make the number, the less blurry the image becomes. However, the shader only eliminates the pixelwobble effect if the pre-scaled game screen is smaller than your display resolution.
For example, if I take a game that has 256x224 like Mario and scale it by the integer 2 then it already becomes 512x448. If my TV runs at 720p that's 1280x720 so in principle I could go to an integer prescale of 3 which gives 768x672, still smaller than the TV resolution. The shader still works well in that case, and produces an even sharper image without wobble.
However, for a game that runs in higher resolution than Mario, or for a vertical shooting game where the dimensions are rotated, a pre-scaling factor of three might already be too high. If the prescaling is too large, some wobble will again appear, because the shader will use bilinear filtering to shrink the image to the TV resolution. It is not terrible in that case, but not perfect either.
Therefore, I chose the factor 2.0 because it works with all games, even the vertical shooting games in Mame.
Note that the "retro/sharp-bilinear.glslp" shader in the libretro repo https://github.com/libretro/glsl-shaders/tree/master/retro is designed to do an autoscale and find the best integer automatically for each game that is loaded. However, I get pixelwobble when I play Air Gallet with it, so something might be wrong with it.
EDIT: Forgot downlaod link, here it is:
No, the shader does that for the final scaling. It is there to remove pixelwobble.
sorry, i meant the screenshots 'without shader', although you seem to have fixed those.
yes i get the reason and like the effect you have with these shaders! you should submit them to the rpi branch of this repo: https://github.com/RetroPie/common-shaders/tree/rpi - this means they will be included in retropie. maybe you also want to consider submitting them to libretro's shader repo? but i think they should replace the existing sharp-bilinear, if they improve it (?)
pjft last edited by
Thanks for creating these and sharing them!
I'll second the request to submit them. I'm not sure I'd replace the current ones, given - as you say - you lose a bit of the sharpness (which is core to the name) but you can certainly rename them if it's better and submit them.
Thanks, I appreciate it! I will submit them to both repos as soon as I get to it.
Concerning improvements to sharp-bilinear from the libretro repo:
There's a small improvement to the existing sharp-bilinear that makes sharp-bilinear-simple work better with vertical games (shmups etc.): The autoscale is calculated for both the horizontal and vertical dimension, e.g. the integer prescale could be 4 for the horizontal, and 2 for the vertical. The original sharp-bilinear that is included in libretro's shader repo only used the vertical dimension to calculate the auto-prescale, and then used the same integer for both x and y.
There was originally another improvement: In my shader, the autoscaling factors were originally pre-calculated in the vertex shader, instead of re-calculating for every pixel. However, that only worked on Windows but not on the Raspberry Pi (driver not supporting the pipelining between shaders?!?!), so I reverted that feature.
The 2x-prescale-sharp-bilinear filter is very simple, much simpler than the sharp-bilinear from libretro: it is a simple shader config that applies two passes of the stock.glsl "Null shader," and therefore contains almost no calculations, and should be superfast.
lilbud last edited by
Finally got time to test your shaders, and they look frickin amazing. One request if possible, could you add an option to enable scanlines? No curvature or and fancy stuff like that, just thick, dark scanlines.
I could try to implement scanlines in sharp-bilinear-simple, e.g. sharp-bilinear-scanlines. That should be quite easy.
However, I honestly don't understand scanlines very well. For example, how thick should they be?
a) half a pixel of the game screen, e.g. 240 thick scanlines on screen for a 240p game?
b) one pixel of the resulting display resolution, e.g. 540 dark lines on a 1080p display, regardless of game resolution?
Intuitively, I feel like scanlines should be based on display resolution and independent of game resolution. I will look into it.
EDIT: After some testing, a) is the way to go. I updated the repository with an additional scaler with scanlines, here
@dankcushions I tested the shaders some more. I added a sharp-bilinear-scanline version in addition to sharp-bilinear-simple and sharp-bilinear-2x-prescale (renamed for clarity). I then made a pull request to the RetroPie/common-shaders rpi branch you mentioned.
My PR for RetroPie is here:
I also made a PR for the libretro glsl-shaders repo here:
Please tell me if you need me to change anything...
DickHams last edited by
I came across your shader while messing around with settings last night, and I just want to say that you did a phenomenal job. This is the shader I have been looking for and didn't even realize I was looking for it. Finally I can turn off integer scaling and get rid of all that pixel wobble.
I highly advise everyone to give this shader a shot. If you like that "perfect pixel" look but can't stand the artifacts that come with it, this is the shader for you.