Please do not post a support request without first reading and following the advice in https://retropie.org.uk/forum/topic/3/read-this-first

New CRT/LCD shaders for RPI3. They run at 60fps at higher resolutions and are configurable.



  • EDIT 2: These shaders are now in the RetroPie common shader git repository here: https://github.com/RetroPie/common-shaders/tree/rpi
    If there are new versions, then they should show up here first: https://github.com/ghogan42/common-shaders/tree/zfast_shaders

    Nearly everything in this first post is now out of date

    Hi Guys,

    I noticed a post in the Help/Support forum asking about an LCD shader and that reminded me that I never posted any of my shaders. So I'm posting three shaders here.

    They are in my Google Drive here: https://drive.google.com/drive/folders/0B5_cUiAJwMMvT1RJRjdHell3ckU?usp=sharing

    Here is a direct link to the zip file containing all three GLSL shaders and the GLSLP preset files (not really needed though):
    https://drive.google.com/file/d/0B5_cUiAJwMMvZFNDY09DZFJ5V1U/view?usp=sharing


    This is what's inside:

    EDIT: THESE NAMES WILL CHANGE TO AVOID CONFUSION WITH DAVEJ's CRT-PI SHADER

    Z_PI_CRT: A CRT shader that I wrote that could handle 1920x1080 fullscreen (not just 1440x1080).
    Z_PI_LCD: A modification of my CRT filter that just draws boxes around nearest neighbor scaled pixels. This works with non-integer scaling.
    Z_PI_LCD_INT: A simpler, (much) faster LCD shader that ONLY works correctly if you set retroarch to Integer Scaling in the video options.

    I assume you know how to use these, but basically you should drop the following files:

    Z_PI_CRT.glsl, Z_PI_LCD.glsl, and Z_PI_LCD_INT.glsl

    into the shaders folder of your retropie installation. This folder is accessible here on the network be default here:
    "\\RETROPIE\configs\all\retroarch\shaders\shaders"

    and then drop the preset files:

    Z_PI_CRT.glslp, Z_PI_LCD.glslp, and Z_PI_LCD_INT.glslp

    into the shader presets folder: "\\RETROPIE\configs\all\retroarch\shaders"

    Then you can select either a preset or select the shader file manually in the video options.


    They all should be able to chug along at a solid 60fps at any resolution up to a full 1920x1080 or 1600x1200 if your PI3 isn't throttling. The reason the CRT shader exists is mostly because crt-pi can only do 53-55fps for 1600x1200 or 1920x1080 type of resolutions.

    Here are screenshots of the default options on Z_PI_CRT and Z_PI_LCD:

    Castelevania - Aria of Sorrow: https://drive.google.com/file/d/0B5_cUiAJwMMvaTBXTjRwM05NSlE/view?usp=sharing
    Z_PI_LCD
    Streets of Rage 3 - https://drive.google.com/file/d/0B5_cUiAJwMMvbUdMeXFoTWFtck0/view?usp=sharing
    Z_PI_CRT


    Both LCD shaders have an option to adjust the border darkness and whether to apply Gameboy Advance fake gamma correction. This is enabled by default.

    The CRT shader has many more options. You might want to open Z_PI_CRT.glsl to change some of them. Here are some of the options that you can edit near the top of the file:


    #define BLURSCALEX -0.6
    #define BLURSCALEY -0.3

    A value of "-1.0" makes the shader use bilinear filtering (blurry)on that axis. A value of "-0.0" makes the shader use pure nearest neighbor scaling (perfectly sharp). Choosing something between lets you choose how blurry the scaling is.


    #define LOWLUMSCAN -6.0 //default is -6.0, larger negatives darken scanlines
    #define HILUMSCAN -14.0 //default is -14.0, larger negatives darken scanlines
    #define BRIGHTBOOST 1.2 // Low brightness pixels get boosted

    These are constants adjusting the scanline profiles. I'll be referring to th edark part of the scanline as the "scanline". The shader uses a a thicker, darker scanline for the lower brighness pixel, and a thinner, lighter scanline for brighter pixels. Also, there is a "brightness boost" for the lower scanline profile that helps counteract the fact that thicker scanlines darken the picture more than the thinner lines.


    #define FAKEGAMMA

    Most emulators don't offer gamma correction. So when you display the image meant for a gamma 2.4 display on a TV/Monitor that's around 2.2 the picture is too bright. If FAKEGAMMA is NOT commented out then an approximation of the need gamma adjustment is applied to the image. Please comment this line out if you think the image is too dark.


    //Mask options.
    #define MASK_DARK -0.3
    //#define FINE_MASK
    #define MASK_FADE 0.28

    By default, every third pixel is darkened to imitate an aperture grill. This is done as a monochrome effect because your get bad results with color aperture effects with chroma subsampling on most TVs. MASK_DARK lets you choose how dark the mask effect is. MASK_FADE adjusts how the mask fades out AND HOW THE THINNER SCANLINES FADE IN. If the mask looks too coarse for you, you can uncomment FINE_MASK and the shader will use a 2 pixel effect instead of 3 pixels. Expect to have to change MASK_DARK if you use FINE_MASK.


    I hope someone finds these useful!

    -SoltanGris42



  • Looks good.

    Your fake gamma hack is even simpler than mine in crt-pi. :)

    You've left INPUT_GAMMA and OUTPUT_GAMMA parameters defined in the shader even though you no longer use them. On the subject of parameters, it might be an idea to define some of your configuration options as parameters to make it easier for non technical users to alter them if it doesn't slow down your shader. (I put the ones that don't alter code flow as parameters in crt-pi as it didn't seem to alter performance.)

    Is the Z_PI_CRT name close enough to potentially cause confusion with crt-pi? I'll let others comment on whether they think it is since I might be a bit biased. ;)

    The (S)NES classic mini, and other Mali 400 GPU board, users are crying out for a decent crt shader that runs well for them. It might be worth getting them to try your shaders. There's someone asking about it on the libretro forum at the moment.



  • @davej said in New CRT/LCD shaders for RPI3. They run at 60fps at higher resolutions and are configurable.:

    Looks good.

    Your fake gamma hack is even simpler than mine in crt-pi. :)

    You've left INPUT_GAMMA and OUTPUT_GAMMA parameters defined in the shader even though you no longer use them. On the subject of parameters, it might be an idea to define some of your configuration options as parameters to make it easier for non technical users to alter them if it doesn't slow down your shader. (I put the ones that don't alter code flow as parameters in crt-pi as it didn't seem to alter performance.)

    Is the Z_PI_CRT name close enough to potentially cause confusion with crt-pi? I'll let others comment on whether they think it is since I might be a bit biased. ;)

    The (S)NES classic mini, and other Mali 400 GPU board, users are crying out for a decent crt shader that runs well for them. It might be worth getting them to try your shaders. There's someone asking about it on the libretro forum at the moment.

    Hi davej,

    I think you're right about the shader name. When I was writing it, I called it "pi_faster_scanlines" but then I got tired of scrolling to the file in the retroarch menu and I renamed it "Z_CRT" so it would be at the end of the list. I'll rename it something that differs from crt-pi by more than 2 typos to avoid confusion.

    As far as parameters go, I've never written a retroarch shader before, and MAME doesn't have parameters for glsl shaders. I intended to use retroarch paramters though (that's why I stole your parameter list including the gamma options!), but at the end I had a bunch of paramters to add and I just didn't bother. But I guess I'll take a stab at that later today. Step 1: how do you even change parameters in retroarch? ;)

    Regarding gamma tricks: OMG the pi is so slow! Two pow instruction costs at least 2 fps?! That's crazy. But it's pretty fast at multiplies. The gamma trick I used works pretty good for exponents larger than 1.0. I couldn't come up with a similarly fast trick for exponents like 1.0/2.2 unfortunately. I guess I could do fake gamma correct shading by using my trick for a 2.18ish power and then your square root trick for the inverse. Since 2.18/2 is close to 2.4/2.2 that would be pretty good I think.

    Gamma

    Regarding the SNES Classic, do you know how fast/slow the Mali 400 is compared to the pi? I didn't consider use at 720p but I'm sure I could make it look ok. CRT-PI might be fine for them too...

    Anyway, I have a small bug to fix, some parameters to figure out, and a shader name to change. So I'll do that and get back to this thread later today or tomorrow. Thanks for the input davej!



  • @ghogan42 said in New CRT/LCD shaders for RPI3. They run at 60fps at higher resolutions and are configurable.:

    As far as parameters go, I've never written a retroarch shader before, and MAME doesn't have parameters for glsl shaders. I intended to use retroarch paramters though (that's why I stole your parameter list including the gamma options!), but at the end I had a bunch of paramters to add and I just didn't bother. But I guess I'll take a stab at that later today. Step 1: how do you even change parameters in retroarch? ;)

    This post has some details about shader parameters you might find useful.

    Regarding gamma tricks: OMG the pi is so slow! Two pow instruction costs at least 2 fps?! That's crazy.

    Have you seen the VideoCore 4 3D documentation? It doesn't even have a divide instruction! It does have a reciprocal instruction and appears to do a / b as recip(b) * a. The Broadcom GLSL compiler isn't smart enough to notice it can precalculate divide by constants and I discovered that things like changing /3.0 to *0.333333 is faster.

    But it's pretty fast at multiplies. The gamma trick I used works pretty good for exponents larger than 1.0. I couldn't come up with a similarly fast trick for exponents like 1.0/2.2 unfortunately. I guess I could do fake gamma correct shading by using my trick for a 2.18ish power and then your square root trick for the inverse. Since 2.18/2 is close to 2.4/2.2 that would be pretty good I think.

    They look pretty good approximations. I noticed the Pi's GPU has a reciprocal square root instruction and I thought that's closeish to exp(1/2.2) and x*x is sort of close to exp(2.4) which is how my fake gamma came about. Since implementing that I managed to get the rest of the shader fast enough to allow correct gamma calculations at my target resolution.

    Regarding the SNES Classic, do you know how fast/slow the Mali 400 is compared to the pi? I didn't consider use at 720p but I'm sure I could make it look ok. CRT-PI might be fine for them too...

    Reports I've seen say it's not fast enough to run crt-pi without slowdowns.

    Anyway, I have a small bug to fix, some parameters to figure out, and a shader name to change. So I'll do that and get back to this thread later today or tomorrow. Thanks for the input davej!

    You're welcome.



  • So what exactly is an LCD shader and how does it differ from a CRT one? Specifically the CRT-Pi shader. I recently just started using shaders and from what I’ve researched the crt-pi is basically the best performance shader you can use on the pi, which is great because I think it looks pretty awesome for most stuff. Is the LCD comparable performance and image wise?



  • @cjax08 said in New CRT/LCD shaders for RPI3. They run at 60fps at higher resolutions and are configurable.:

    So what exactly is an LCD shader and how does it differ from a CRT one? Specifically the CRT-Pi shader. I recently just started using shaders and from what I’ve researched the crt-pi is basically the best performance shader you can use on the pi, which is great because I think it looks pretty awesome for most stuff. Is the LCD comparable performance and image wise?

    I suppose an LCD shader would attempt to imitate the LCD display of handheld devices like gameboys instead of a CRT screen. I figure it should have some of the following features:

    • Sharp pixels. Not blurred like a CRT shader would do
    • Pixels should be outlined if the pixels are large enough to be distinguished
    • Pixels should have a delayed response, or ghosting, to look like older types of LCDs

    The raspberry pi 3 can't hope to do the last one. It's just too slow. But the other stuff is doable.

    I still haven't had time to update/fix my shader's syntax to match the standard libretro shaders. But I'll get that done soon.



  • Both these shaders are really awesome! I'm gonna have to switch my setup to these tonight :D



  • @ghogan42 @davej so I just tried out your crt shader last night and it’s pretty awesome. I have a few questions though. When I was using the crt-pi shader at 1080p I would have my pi overheat after playing a while. After I changed rendering to 720p I no longer had the issues. I think it was made for 1080p though so I’m not sure if it’s ideal. Is the Z-pi-crt shader made with 1080p in mind? And if so do you happen to know if it has any issues with increased heat over semi long play periods? I’m trying to decide whether to stick with crt-pi across the board or switch to yours.

    Also I saw on your libretto post that you were still working on the shaders for the snes mini. Are the shaders you have posted here the actual final most up to date versions?



  • Hello All, I spent quite a while getting versions of these shaders up and running on the SNES Classic. The gpu it has is a big downgrade from the Raspberry Pi 3. Then I got busy at work and haven't had time to come back to this.

    Here's how things stand now with the current version as of Jan 07, 2018 . The newest files are at the bottom of this post.

    1. I changed the names of the shaders to zfast_crt_standard, zfast_lcd_standard, zfast_crt_720p_SNES, zfast_crt_720p_PI3, zfast_lcd_720p. Hopefully they won't get confused with the crt-pi shaders.

    2. There were bugs in the horizontal scaling I used. It's now completely different. I've made a sharper version of the algorithm here: http://www.iquilezles.org/www/articles/texture/texture.htm that works well for scaling pixel graphics with a good tradeoff between blur/shimmer

    3. Most shaders now have RetroArch shader paramters that you can adjust. So if you don't like the defaults you no longer have to edit the files. Just go into the retroarch "Preview Shader Parameters" and edit them. Then you can save a preset with the options you like.

    Here's what the current versions look like. You won't see much difference, but under the hood things have changed.

    zfast_crt_standard: https://drive.google.com/file/d/12-auksKKlw0-78caUUYh2nX4rMgLArvf/view?usp=sharing
    zfast_crt_standard

    zfast_lcd_standard: https://drive.google.com/file/d/1pc3nZUeuQTGVvC2rPVFIWPnjlryqqSit/view?usp=sharing
    zfast_lcd_standard

    Here's some tips for setting the shaders up:

    1. You can drop all of the files in the zip file into any folder on your PI3. The GLSLP files and GLSL files go in the same folder. That's not how retropie usually does things, but it's how I did it.

    So either:
    \RETROPIE\configs\all\retroarch\shaders

    or:
    \RETROPIE\configs\all\retroarch\shaders\shaders

    should be fine for the location.

    1. You can load the shaders in retroarch with either "Load Shader Preset" and selecting the ".glslp" file OR by loading the shaders ".glsl" file
      directly. If you select the shader file directly then you should set the "Filter" to "Linear" and the "Scale" to "Don't Care".

    2. Three of the shaders should give correct output at 1080p or 720p: zfast_crt_standard, zfast_lcd_standard, zfast_lcd_720p. The 720p version of the lcd shader just has one pixel borders which the 1080p version can't replicate (it can only darken two pixels at a minimum). So you can use these at any resolution where they look good.

    3. There are two version of the 720p crt shader: zfast_crt_720p_SNES and zfast_crt_720p_PI3. The difference between them is that the SNES version is faster but requires you to manually ensure that you're getting 3x Integer Scaling on the vertical axis. That's what you SHOULD get at 720p from all of the old consoles with Intger Scaling set. However it turns out that many/most cores seem to lie about the resolution they produce! So you get non-integer scaling even when you turn on "Integer Scaling" in the Video Options!! So I made the zfast_crt_720p_PI3 version that tries to ensure integer scaling on it's own. It doesn't always center the image correcly though. I'm not sure why... The punchline is that if you're stuck running 720P and you see some artifacts in zfast_crt_standard then you probably want to try zfast_crt_720p_PI3 and not zfast_crt_720p_SNES.

    4. There is a "bonus" shader called sharp_quilez_gamma in the zip file. This is a modified "quilez" shader that is sharper than the default (but blurrier than nearest neighbor). It also does an approximate 2.45 to 2.2 gamma adjustment. It might be useful to people that want sharp-ish scaling without shimmering when things move.

    Answers to some questions that have come up:

    Q: Can you add curvature?
    A: Nope. I wrote these to be full speed at a full 1920x1080 or 1600x1200 on a rpi3 and fullspeed on an SNES Classic at 720p. They won't be if I added curvature.

    Q: Will these make my pi overheat?
    A: They shouldn't! My pi3 is an an case with a retrotink on top blocking air flow and I don't have problems. Make sure you have a heatsink on there though. And if your pi is only stable at 720p, well then, go ahead and use that.

    Newest Versions of the shaders as of January 07 2018:
    https://drive.google.com/file/d/1f4B1lzTRnjuYySh1iZazT_KlWY1Bj2Oc/view?usp=sharing



  • @ghogan42 Well this answer my question the other day over at libretro.

    Great job, love it!
    To bad about the curved option but I can understand why you cut it out.



  • @rion said in New CRT/LCD shaders for RPI3. They run at 60fps at higher resolutions and are configurable.:

    Great job, love it!
    To bad about the curved option but I can understand why you cut it out.

    Well maybe I can give curvature a shot. Here's a work in progress. It's way too slow right now though... But if I get anywhere I'll post it here.

    zfast_crt_curve: https://drive.google.com/open?id=1uusySOl0IkxMWDfybRfUaiPeLMV3evVT
    zfast_crt_curve



  • @ghogan42

    Making moves! But..

    I'm trying to figure out what tradeoffs I can make. Right now I've had to lose the sharpness slider and have it fixed to the sharpest setting. And we went from having different scanline beam profiles based on luminance to a constant beam width. And I've simplified the way the scanline/mask fades out as pixels get brighter.

    So we're at 60fps but with caveats. The problem is that although we get 60fps most of the time, in some games/systems we drop below 60fps when the emulation gets heavy. This is because the rpi3 shares memory bandwidth between cpu/gpu I think. This is the problem I came across with crt-pi that motivated me to write the zfast shaders in the first place (my shaders get more than 60fps at 1440x1080 so I don't have to worry about drops). So I'm not really happy with the version with curvature yet and I need to think more about how to get a little more speed.

    But we're getting there! And I thought it wouldn't be possible on rpi3 class hardware.

    Here's my current progress with fps counter

    zfast_crt_curve_fps: https://drive.google.com/open?id=15cWelo3aeQNIDqMsMemBJhVabiv2jmmG
    zfast_crt_curve_fps



  • @ghogan42 Now I'm excited to see what you will come up with 😎



  • Hi !

    I love your shaders, and have included them in my overlays compilation pack : https://github.com/cosmo0/retropie-overlays
    I hope you don't mind :)

    I had renamed them "ghogan-crt/lcd" but zfast is fine by me ;)

    I am eagerly awaiting your curvature CRT shaders :)



  • @cosmo0 Nice, I like your overlay pack Thomas, it makes me happy :)



  • I tried these shaders out and I quite like them. With the limitations of the Pi, they might be the best scanline/gridding shaders possible. I am very thankful for the Raspberry Pi and also the Retropie community as it brought me back to retro gaming as my primary hobby.

    I do wish that you had a version of your scanline shader that had a little stronger video smoothing or biliniar filtering. I think with scanlines and some slightly stronger blending you could achieve an approximation of analog signal distortion. It would go a long way in restoring transparency effects and color enhancement via dithering.



  • @beldar said in New CRT/LCD shaders for RPI3. They run at 60fps at higher resolutions and are configurable.:

    I tried these shaders out and I quite like them. With the limitations of the Pi, they might be the best scanline/gridding shaders possible. I am very thankful for the Raspberry Pi and also the Retropie community as it brought me back to retro gaming as my primary hobby.

    I do wish that you had a version of your scanline shader that had a little stronger video smoothing or biliniar filtering. I think with scanlines and some slightly stronger blending you could achieve an approximation of analog signal distortion. It would go a long way in restoring transparency effects and color enhancement via dithering.

    Yeah I know what you mean. On the standard versions there is a parameter that ranges from 0 to 1. You get sharp scaling at 0 and pure bilinear at 1. Values in between get something in between. I have the default set pretty sharp (0.3? 0.4?) but you can change it and save the settings.

    A problem I'm having now is that with the curvature calculations I can't afford the "inbetween" calculations and I'm stuck with full blurry or full sharp. I'm currently rewriting the whole shader to use look up tables in textures to hopefully make it run faster. If this doesn't work well enough, I'll post two versions of the curvature shader. One fully blurry and the other fully sharp. Either way, I'll have a version with curvature posted here by/on Monday.



  • @cosmo0 said in New CRT/LCD shaders for RPI3. They run at 60fps at higher resolutions and are configurable.:

    Hi !
    I love your shaders, and have included them in my overlays compilation pack : https://github.com/cosmo0/retropie-overlays
    I hope you don't mind :)
    I had renamed them "ghogan-crt/lcd" but zfast is fine by me ;)
    I am eagerly awaiting your curvature CRT shaders :)

    I don't mind that at all. Making settings/configuration files/overly packs and things that "just work" takes a lot of effort. I tried to do the same for the snes classic and it was a pain. So it's a great service when people like you do these packs. There are a lot of people that can't do all of the configuration work on their own.



  • Well here is the best I could do right now for a version with curvature.

    EDIT: The file was broken and also included unnecessary files. You probably need to re-download it.

    NEW LINK: https://drive.google.com/file/d/1DqKVPccsnXBq5WFL7g4ncyvbatMOflWh/view?usp=sharing

    Unfortunately, we lost some features to squeeze in curvature. You can't control the sharpness anymore. The shader loads a look up texture now that essentially tells it how to fix the texture coordinates. I wanted to load two LUT textures (sharp and blurry) and then give you a mix... but it was just too slow on the rpi3. We also don't have a variable scanline profile with pixel brightness anymore. And the mask doesn't fade out at higher brightness either. So we give up a lot. If you don't need curvature then I'd recommend you use zfast_crt_standard and not zfast_crt_curve.

    However, we still have good texture filtering so we don't get much aliasing. Usually none.

    It looks good I think! And it's pretty fast. at 1920x1080 (stretched to 16x9) it gets 47fps to 58fps depending on emulator load. This is a few fps faster than crt-pi still (which tops out at 54fps at this res). And it's much faster than crt-pi-curvature.

    So we still get 60fps constantly at the normal 1440x1080 you get when emulating 4x3
    aspect ratio systems.

    This version MUST be loaded by loading the zfast-crt-curve.glslp preset. Otherwise the shader won't know about the LUT textures it needs to load.

    If you don't like the amount of curvature than check out the settings in the retroarch shader menu. You can control the shader and the curved corners independently.

    I hope you this is useful for some of you.. Let me know if you have any problems with it!

    zfast_crt_curve_fps: https://drive.google.com/open?id=1hSXRj0yYGth-dU4iZhdybY6yEuhNoQ3f
    zfast_crt_curve_fps



  • I have been using CRT-Pi for a while but thought I'd give this a try. I switched my Mega Drive emulation to 16:9 (not sure what people's views are on aspect rations for consoles?) as I wanted to test it out (been using core since setup) and applied zfast_crt_standard and fired up Streets of Rage 2. I have to say it looked and performed superbly! I have promptly switched all my CRT-Pi instances over to zfast!

    Thanks @ghogan42 for investing the time in this, great result!


 

Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.

Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.

Looks like your connection to RetroPie Forum was lost, please wait while we try to reconnect.