Raspberry Pi friendly CRT shader

Hi Dave, just curious do you have a .cg version of this shader?

No. As its name implies, I wrote it specifically to work well on the Raspberry Pi so it’s GLSL only. The availability of better looking .cg shaders and the ability to run GLSL ones on Windows anyway mean it’s not really worth producing a .cg version.

@dave j: Is this shader supposed to simulate the NTSC/PAL composite artifacting? These would be great for Genesis/MegaDrive games that rely on artifacting for new colors and transparency effects. I tried the shader but I can’t see these simulated. Maybe I am missing something?

None of the CRT shaders have that built-in by default (some have NTSC shaders mixed in via presets). It’s an entirely different task that the RPi GPU isn’t really up to handling.

[QUOTE=vanfanel;37526]@dave j: Is this shader supposed to simulate the NTSC/PAL composite artifacting? These would be great for Genesis/MegaDrive games that rely on artifacting for new colors and transparency effects. I tried the shader but I can’t see these simulated. Maybe I am missing something?[/QUOTE]

It doesn’t simulate composite artifacts. The Pi’s GPU is pretty limited and in order to get it to do 1080P@60Hz I had to severely limit what it does - changing most of the options from the defaults prevent it from achieving that. I was aiming for something that was reminiscent of a low resolution monitor or a TV fed by RGB because that’s what I was used to seeing old systems on.

Hi ! I had already tried the “video_scale_integer” option which doesn’t solve the issue. I tried to tweak the two latter values but I got no obvious result. I must admit I’m quite clueless :slight_smile: so I probably didn’t choose relevant values :slight_smile:

Out of curiosity I tried MASK_TYPE 2 and for some reason it reduces my artifacts a lot. I’m not sure what it does else, though :slight_smile: If anyone uses it too with a 1280x1024 screen I’m curious to know what you think :slight_smile:

Thanks again for this cool shader !

Edit : oh, some other games don’t like MASK_TYPE 2 at all (wide vertical coloured lines artifacts). Like GunBird 2. While DDPDOJ is way better with MASK_TYPE 2 :slight_smile:

Meanwhile the only solution is to use MASK_TYPE 0 :slight_smile: (or 2 for most other games :slight_smile:

@bidinou Your last post has made it clear what is happening. The shadow mask calculations the shader does don’t get rotated and they really interfere with the vertical scan lines.

You could change the bits of the shader that use gl_FragCoord.x to gl_FragCoord.y. This will rotate the shadow mask calculation to suit the vertical scan lines.

It will mess up horizontal games though. For a single setting that works with both, setting MASK_TYPE to 0 is your best bet.

Thanks for your reply :slight_smile: Yes, I remember Lottes’ CRT shader for sdlmame was released in 2 versions : horizontal and vertical. It was not an issue as it was possible to specify a distinct shader for horizontal and vertical games, which is probably not the case with libretro :slight_smile: For some reason, MASK_TYPE=2 gives a good result with most games here. I tried a dozen of vertical ones and only GunBird 2 looked bad so I’ll probably keep it until a better solution arises !

[QUOTE=dave j;37573]@bidinou Your last post has made it clear what is happening. The shadow mask calculations the shader does don’t get rotated and they really interfere with the vertical scan lines.

You could change the bits of the shader that use gl_FragCoord.x to gl_FragCoord.y. This will rotate the shadow mask calculation to suit the vertical scan lines. [/QUOTE]

I’ve made this change and it seems to improve how these vertical games look. you can’t really tell with the below embeds, but the rainbow effect is less in the second image, in game:

attached the variant. would it be ok for me to add this -vertical version to the various repos? NOTE: the default mask_type was 1, in the one i grabbed from the repos before, and i haven’t changed that, just the X/Y.

also, if it’s not a silly question (and i’m sure it is!), how does the shader ‘know’ the game is a vertical one when applying scanlines, but not when applying the shadowmask?

You can put in a little branching if statement that tells it to use the vertically oriented mask whenever the height exceeds the width:

float relcoord;
if (TextureSize.y > TextureSize.x)
relcoord = gl_FragCoord.y;
else
relcoord = gl_FragCoord.x;

and then replace the later instances of gl_FragCoord with this relcoord. However, it could lead to occasional false-positives when interlacing is involved (e.g., sonic 2’s splitscreen 2-player mode), and the branch may push performance below full speed on RPi, as I know dave j was already purposely cutting it very close.

Thanks ! IMHO, it would be better to have by default a shader which has some false positives in few cases but is compatible with both horizontal and vertical games, than a shader that shows important artifacts with vertical games. But we should check first whether we still achieve full speed. (and on which Pi version as the GPU is a little overclocked on the Pi 3 apparently).

A branch will cause performance to drop below full speed so I’d definitely recommend a separate version of the shader for vertical - the main goal of crt-pi was to run with 1080P@60Hz on a Pi after all.

Given the popularity of sticking Pi Zeros in small spaces I don’t think relying on overclocking the GPU is a good idea. My experiments with overclocking a Pi B showed the temperature increases quickly - and that wasn’t in a confined space with no ventilation which is what people do to Pi Zeros by putting them in game controllers.

Indeed. I might try the modification on my Pi 3 as the GPU is at a higher frequency by default. I guess in other cases we’ll have to wait for libretro to support distinct configuration files for vertical & horizontal games. :slight_smile:

[QUOTE=hunterk;37965]You can put in a little branching if statement that tells it to use the vertically oriented mask whenever the height exceeds the width: [/QUOTE]

Thinking about it, might that cause a problem if you have a portrait oriented screen?

Yeah, probably. The subpixels won’t line up properly, so you’ll likely get that same rainbowing from the unrotated mask on vertical games.

[QUOTE=hunterk;37965]You can put in a little branching if statement that tells it to use the vertically oriented mask whenever the height exceeds the width:

float relcoord;
if (TextureSize.y > TextureSize.x)
relcoord = gl_FragCoord.y;
else
relcoord = gl_FragCoord.x;

and then replace the later instances of gl_FragCoord with this relcoord. However, it could lead to occasional false-positives when interlacing is involved (e.g., sonic 2’s splitscreen 2-player mode), and the branch may push performance below full speed on RPi, as I know dave j was already purposely cutting it very close.[/QUOTE]

i tried this (i have a pi3 and wanted to check whether it affected performance there) and it doesn’t work for whatever reason. the vertical (and horizontal) games were still using horizontal masks. attached, if anyone wants to look!

EDIT: deleted attachment - not an official crt-pi shader.

TextureSize is the size of the OpenGL texture the screen data is stored in. Some hardware only supports power-of-two textures so Libretro uses a power-of-two texture for compatibility purposes. The game screen size is held in InputSize so you should use that rather than TextureSize. Details here in the bit on uniforms. (Note: CG uses video_size rather than InputSize).

A good test of performance is the 240p Test Suite drop shadow test - look out for glitches in the shadow. It’s not comprehensive though. It’s a very lightweight application and memory bandwidth heavy games can cause frame drops that the 240p test suite doesn’t. You need to enable debug logging and look at the video stats output for that.

Given the problems this will cause with rotated screens and the issue of slow down, it would be better if versions implementing auto switching not include crt-pi in the name. I want to continue to be able to say “crt-pi will do 1080P@60Hz on all Pis with the recommended configuration” to keep things simple for non technical end users. If there are alternative slower versions with similar names, it may cause confusion.

I’ll produce a version with the rotated mask, I’ve an update that fixes a minor problem to release in any case. The question is what to call the one with the rotated mask? Adding ‘vertical’ to the name will confuse those with vertical screens but adding ‘rotated mask’ will confuse non technical users. Any suggestions?

[QUOTE=dave j;38005]TextureSize is the size of the OpenGL texture the screen data is stored in. Some hardware only supports power-of-two textures so Libretro uses a power-of-two texture for compatibility purposes. The game screen size is held in InputSize so you should use that rather than TextureSize. Details here in the bit on uniforms. (Note: CG uses video_size rather than InputSize).

A good test of performance is the 240p Test Suite drop shadow test - look out for glitches in the shadow. It’s not comprehensive though. It’s a very lightweight application and memory bandwidth heavy games can cause frame drops that the 240p test suite doesn’t. You need to enable debug logging and look at the video stats output for that.[/quote]

thanks for the help! i’ll do this shortly and let you know my findings.

Given the problems this will cause with rotated screens and the issue of slow down, it would be better if versions implementing auto switching not include crt-pi in the name. I want to continue to be able to say “crt-pi will do 1080P@60Hz on all Pis with the recommended configuration” to keep things simple for non technical end users. If there are alternative slower versions with similar names, it may cause confusion.

that’s a very good point. i’ve deleted the attachment from my previous post to avoid confusion and if i get it working i will keep it to myself or call it something different. ultimately there’s no end to the features that could be added, but if the performance stops being there then the point is lost!

I’ll produce a version with the rotated mask, I’ve an update that fixes a minor problem to release in any case. The question is what to call the one with the rotated mask? Adding ‘vertical’ to the name will confuse those with vertical screens but adding ‘rotated mask’ will confuse non technical users. Any suggestions?

i think ‘vertical’ is used for other similar shaders, so i guess that boat has sailed? also, regarding the non technical users, currently in the retropie shader repo there are a 3 different crt-pi shader presets and it’s not immediately obvious what the differences are:

(what’s crt-pi-mask? for example) probably nothing you’ve done, but happy to clean it up if you have suggestions!

Sorry it’s been a while since my last update.

Attached is a new version of the crt-pi shader with the bug fix I mentioned and a new crt-pi-vertical shader which has the rotated mask we’ve been discussing in this thread.

@dankcussions The crt-pi-mask was to help people create overlays but since you can get the same functionality by loading the 240p test suite with the crt-pi shader I consider it redundant. Similarly with the crt-pi-barrel shader. It does curved screens but without any extra processing so you get aliasing. The crt-pi shader can be configured to do curved screen without scanlines but with anti-aliasing (described in this post). Unless anybody is particularly keen on them, I can see no reason not to remove them.