crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come)
-
@riverstorm you're injecting yourself into this conversation and i don't appreciate it.
open source development isn't just about forking whenever you want. you can do that, of course, but it's the nuclear option. i am happy to collaborate!
i changed my mind about introducing new features - i made the comment flippantly after being overwhelmed with the waffle in this thread. this script was a simple, fun thing for me to attempt some (terrible) python, that is definitely not the last word in scaling (actually i think the last word would be introducing better options in retroarch's aspect ratio settings... that's on my list). however i can't just copy and paste a complete re-write of my code - features have to be submitted as single PRs so i can understand them and evaluate them individually. that's the same for ALL open source projects.
in that context i would be likely to accept re-writes of the old scaling algorithm and all the rest - just one at a time :)
i'm going to lock this thread for a while because there's nothing more to say - @AndrewH, please don't take this to be anything about your work which is cool and I appreciate it! i'll see you on git! i'll unlock when we have something to show.
-
@dankcusions - yes, mame uses the exact aspect ratio every time, because it doesn't care about integer scaling. what mame does is say, "ok, this is a 4:3 game, so I will do a 4:3 image - i will simply stretch the tiny 320x240 (say) image to the biggest 4:3 image that fits on the screen"
@AndrewH - It's not that you're not explaining yourself well it's my lack of understanding. I have little loose ends that probably aren't related but I feel it helps in understanding but also keeps me going in circles. I just need time to process the information. Let that subconscious do the work. :) I was up way to late reading. One thing drifted to another.
With that thought (Dank's comment above) it would be safe to say 100% of arcade games (due to lack of PAR calculations in upscaling) are stretched on x, y or both and we've just become accustomed or consider it correct because it's close enough for our memories?
If not integer scaling what is the MAME/Retroarch(?) process to stretch the image resolution to max 4:3 aspect ratio on modern displays (that have different resolutions)?
With integer scaling off and no custom config. How is MAME (set to defaults) filling the screen? This seems important to know what it does with no modifications. Basically what the developers decided for default settings.
I think of integer scaling as multiplying the original resolution by whole numbers (no fractions) until either the x or y exceeds the display resolution then it backs down 1 to fit the screen. Hence almost always leaving black borders all the way around the play area.
I know more pixels allow the shader to look better. Is it pixel density or an evenly divisible x scale (y on horizontal games) that is more important to looking better?
An observation is with Dank's script I didn't think he was taking pixel squareness into account and Andrew's does. What I find interesting is when using Andrews's "wide" flag both Dank's and Andrew's scripts produce the same viewport dimensions. How is that possible? (If Dank's isn't doing pixel squareness calculations). I just don't quite understand the sort array in Dank's script so maybe there's more happening there than I understand?
I was on one thread last night that was having Donkey Kong discussion that one guy said it was actually a 9:6, another guy said it was a 8:7, a 3rd guy says if you fill the screen horizontally (with h-sync?) it's 8:7 or if adjusted down a bit it's 9:6 so it can be either depending on the arcade operator settings, then a 4th guy says it's what you're used to and by changing what you're used to it can take hours to re-acclimate with the springs (elevators at higher levels) when changing the aspect ratio to something you're not used to playing on.
Others were deep into 31 to 15Khz conversions from hardware to software, display cards, etc. to get proper looking games. It kind of goes on and on.
I look forward to how the scripts turn out.
-
Just found these cfg's, thanks for posting them! I placed them in the correct directory and they work fine. I also added a line of code to specify a bezel. I was curious to see what would happen if I made any changes through the RGUI so I changed the shader to the curvature variant for the game sf2 and then did a save game override. I then opened sf2.cfg in notepad++ and noticed the code wasn't right and my line specifying the bezel was gone. Any idea why this happens? I was expecting to see the change to the curvature shader with nothing else changed.
-
@riverstorm said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@dankcusions - yes, mame uses the exact aspect ratio every time, because it doesn't care about integer scaling. what mame does is say, "ok, this is a 4:3 game, so I will do a 4:3 image - i will simply stretch the tiny 320x240 (say) image to the biggest 4:3 image that fits on the screen"
With that thought (Dank's comment above) it would be safe to say 100% of arcade games (due to lack of PAR calculations in upscaling) are stretched on x, y or both and we've just become accustomed or consider it correct because it's close enough for our memories?
PAR isn't neccesarily correct to the original, though. DAR is correct, but to get from original game image to display via DAR, you have to stretch.
if you run our example 320x224 image on a 1080p display, by default it will be 1440x1080 (4:3). 320 isn't an integer factor of 1440, nor is 224 an integer factor of 1080, so if you zoomed in you would see that (for example) the grid of 320x224 pixels from the original game are blurred slightly during the scaling process. you don't get clean edges. however, the aspect ratio of the image will be correct (4:3).
the blurring ("scaling artefacts") aren't usually a problem on a HD screen viewed at distance, but they are a problem if you use a scanline shader.
that's what the script tries to solve - it compromises on aspect ratio but reduces scaling artefacts. if you want to have a precise aspect ratio, don't use these .cfgs. don't do anything!
If not integer scaling what is the MAME/Retroarch(?) process to stretch the image resolution to max 4:3 aspect ratio on modern displays (that have different resolutions)?
it's bilinear, i believe.
I think of integer scaling as multiplying the original resolution by whole numbers (no fractions) until either the x or y exceeds the display resolution then it backs down 1 to fit the screen. Hence almost always leaving black borders all the way around the play area.
actually retroarch doesn't quite do it like that. it is mindful of the intended aspect ratio, so it will scale by whole numbers to get at close to the target aspect ratio as possible. so it might end up with something like X axis * 5, Y axis * 4, or whatever.
I know more pixels allow the shader to look better. Is it pixel density or an evenly divisible x scale (y on horizontal games) that is more important to looking better?
well, ideally you'd have an evenly divisible scale, but since retro gaming has so many different resolutions, that's impossible for one digital display. however, once you start going into 4k, then the pixels are so small that the artefacts are essentially invisible.
An observation is with Dank's script I didn't think he was taking pixel squareness into account and Andrew's does.
i do take it into account. it's just a different approach.
I was on one thread last night that was having Donkey Kong discussion that one guy said it was actually a 9:6, another guy said it was a 8:7, a 3rd guy says if you fill the screen horizontally (with h-sync?) it's 8:7 or if adjusted down a bit it's 9:6 so it can be either depending on the arcade operator settings, then a 4th guy says it's what you're used to and by changing what you're used to it can take hours to re-acclimate with the springs (elevators at higher levels) when changing the aspect ratio to something you're not used to playing on.
Others were deep into 31 to 15Khz conversions from hardware to software, display cards, etc. to get proper looking games. It kind of goes on and on.
i defer to what mame use in their drivers, here.
-
@yardley said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
Just found these cfg's, thanks for posting them! I placed them in the correct directory and they work fine. I also added a line of code to specify a bezel. I was curious to see what would happen if I made any changes through the RGUI so I changed the shader to the curvature variant for the game sf2 and then did a save game override. I then opened sf2.cfg in notepad++ and noticed the code wasn't right and my line specifying the bezel was gone. Any idea why this happens? I was expecting to see the change to the curvature shader with nothing else changed.
i already created curvature cfgs in the original post, so i would just use those as a base :) retroarch does strange things with regard to saving overrides, so i can't really guess the problem here.
-
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
PAR isn't neccesarily correct to the original, though. DAR is correct, but to get from original game image to display via DAR, you have to stretch.
I am not sure I am explaining myself correctly but this seems not quite what I was trying to say. If you have a 3:4 ratio and a resolution of 224 x 298 and another game that is a ratio of 3:4 and a resolution of 253 x 310. I thought the difference is the PAR not the DAR. They are both 3:4 DAR but the pixel width vs. height is what not the same between the two games.
The thought is most arcades games do not use square pixels. So when you display the original game on a modern display and force it to use square pixels it would be squished or stretched due forcing the pixels to be square.
it's bilinear, i believe.
I thought bilinear is a smoothing technique not scaling.
actually retroarch doesn't quite do it like that. it is mindful of the intended aspect ratio, so it will scale by whole numbers to get at close to the target aspect ratio as possible. so it might end up with something like X axis * 5, Y axis * 4, or whatever.
So integer scaling is per axis? If you have (x * 5 ) & (y * 4) wouldn't you destroy you 3:4 aspect ratio? I thought both axis where scaled by the same number and it has to be whole numbers or you will create an uneven stretch in pixel dimensions. To me doing it like that would be completely opposite of what it's trying to achieve?
i do take it into account. it's just a different approach.
Can you explain that a little more?
-
@riverstorm said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
PAR isn't neccesarily correct to the original, though. DAR is correct, but to get from original game image to display via DAR, you have to stretch.
I am not sure I am explaining myself correctly but this seems not quite what I was trying to say. If you have a 3:4 ratio and a resolution of 224 x 298 and another game that is a ratio of 3:4 and a resolution of 253 x 310. I thought the difference is the PAR not the DAR. They are both 3:4 DAR but the pixel width vs. height is what not the same between the two games.
The thought is most arcades games do not use square pixels. So when you display the original game on a modern display and force it to use square pixels it would be squished or stretched due forcing the pixels to be square.
it’s stretched either way. either you’re stretching the raw image from its PAR (“square pixels”) to DAR (the correct aspect ratio), or you’re stretching away from the DAR to make your pixels square (PAR)
mame is DAR by default. the aspect ratio is right, but to get there it gets scaling artefacts.
it's bilinear, i believe.
I thought bilinear is a smoothing technique not scaling.
they’re the same thing. if you can’t apply an integer scale and still hit 4:3 with no (top and bottom) borders, then you have to use a scaling algorithm. bilinear or nearest neighbour are most common. even integer scaling is a scaling algorithm, i suppose - just a very ‘brute force’ one.
actually retroarch doesn't quite do it like that. it is mindful of the intended aspect ratio, so it will scale by whole numbers to get at close to the target aspect ratio as possible. so it might end up with something like X axis * 5, Y axis * 4, or whatever.
So integer scaling is per axis? If you have (x * 5 ) & (y * 4) wouldn't you destroy you 3:4 aspect ratio?
that depends on the raw image. street fighter 2 is a great example of this. if you scaled both axis by the same number, it will be the wrong aspect ratio (fat ryu).
I thought both axis where scaled by the same number and it has to be whole numbers or you will create an uneven stretch in pixel dimensions. To me doing it like that would be completely opposite of what it's trying to achieve?
not at all. again the raw pixel image does not have a direct connection to the aspect ratio on the CRT. CRTs don’t need square pixels. if you integer scale up from the raw pixel image you will often be off from the proper aspect ratio.
i do take it into account. it's just a different approach.
Can you explain that a little more?
it’s just fundamental. you must know the difference between your DAR and PAR to generate the CFGs
-
@dankcushions thanks, I was using curvature just for testing. So I guess the verdict is RA is temperamental so don't try to save any new settings over your configs?
Someone over at the Libretro forum said that "shaders aren’t saved reliably in config overrides. There’s a separate per-core/per-game preset that you should use instead."
Trying to look at that although it sounds like I would have to make all the configs from scratch which defeats the purpose.
-
maybe it's best to describe this scaling stuff in pictures.
here's street fighter 2 - the raw 384x224 image sent from the game:
but wait! widescreen tvs weren't around in 1991. and how fat is guile now? BAD! the actual arcade cabinet looked like this:
a regular 4:3 tv. CRTs can receive images in a number of different horizontal resolutions, due to the way they work. rather than go into detail, let's just concentrate on the end result: SF2 is a 4:3 game.
so, to get the image displaying correctly on a 1080p HDTV, mame needs to stretch the original raw image vertically so it gets to 4:3, and also enlarge it ("upscale") so is 1080 pixels high, rather than 224.
we can work out what resolution the end image is going to be:
4/3 = 0.75
x/1080 = 0.75
x = 1440so, mame knows our end image has to be 1440x1080 to fill the screen, but how does it get there? it uses a simple upscaling algorithm.you can repeat more or less what it does by just opening an image editor. eg, here's 'preview' on my mac:
notice i've unticked 'scale proportionally', because we know that the source image has the wrong proportions (it's not 4:3). i've also ticked 'resample image', because this will apply a (presumably bilinear) to obfuscate scaling artifacts - more on that after. here's what it produces:
great, 4:3! but if you look closely:
no pixel sharpness. actually mame's algorithm would be sharper than this, but you'll still get that blurring between pixel edges when you look closely, because the original image does not fit into the target resolution neatly (ie, by an integer scale).
what would it look like without resampling? here's a closeup of that output:
...well, dang - apple's default image editor doesn't let you turn off 'scale proportionally' when resampling is off - which makes sense i suppose. even nearest neighbour is a type of resampling.
hypothetically, nearest neighbour would have sharp pixel edges, but every so often you'd have a row of sf2 pixels that have a different width than the others. this looks especially obvious when the image is scrolling up and down. same story on the columns of pixels and horizontally scrolling images.
so, bilinear resampling is a good compromise for mame, but neither approach work very well when you're using a scanline shader, and that brings us to the start of this thread.
hopefully this makes a bit more sense!
-
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
it’s stretched either way. either you’re stretching the raw image from its PAR (“square pixels”) to DAR (the correct aspect ratio), or you’re stretching away from the DAR to make your pixels square (PAR)
I don't think you can stretch an image from it's PAR. Unless you just worded that incorrectly? The PAR is a static ratio of the of width in proportion to the height. You can with an old CRT by adjusting the v-sync/h-sync which does change the aspect ratio like they where discussing with Donkey Kong in a prior post.
I believe they get around those "oblong" 2:1-ish pixels by "concatenating pixels" on modern displays via doubling the x or y axis. I am sure there are more advanced techniques in displaying the DAR properly for old games.
not at all. again the raw pixel image does not have a direct connection to the aspect ratio on the CRT. CRTs don’t need square pixels. if you integer scale up from the raw pixel image you will often be off from the proper aspect ratio.
No, that's still not I am trying to say. I read that article too.
If I have three 16:9 monitors and display one is 1280×720, display two is 1600×900 and display three is 1920×1080 (these are real monitor examples). If I program a game that is 100 x 200 pixels using display one it's going to look different on display two and three keeping in mind they are all three 16:9. The difference? The pixel aspect ratio (PAR).
All 3 have different resolutions and pixel counts but maintain the 16:9 aspect ratio. The pixel size is changing. You can remove/add pixels all you want but to compensate and maintain the 16:9 AR the PAR needs to change. If you move from an old arcade monitor to a modern display it's going to display differently due to the PAR. That was the point I was trying to make.
If I create a monitor with a resolution of 1 pixel and the DAR/AR is 3:4. Then I decided to create one with 2 pixels but want to keep the 3:4 aspect ratio something needs to change. That would be the pixel aspect ratio again (PAR). Ratio is only a correlation between the width and height.
they’re the same thing. if you can’t apply an integer scale and still hit 4:3 with no (top and bottom) borders, then you have to use a scaling algorithm. bilinear or nearest neighbour are most common. even integer scaling is a scaling algorithm, i suppose - just a very ‘brute force’ one.
Ok it seems like you're doing quick reads & cutting and pasting? You're confusing 2 different things. It's a smoothing technique for textures when you scale up or down such as walking closer or further from an object in game. You can scale in either direction but it's a texture smoothing technique that is supposed to improve the image quality detail when scaling not for scaling. It's very common option in PC games when deciding if your PC has enough horse power to do bilinear, trilinear or anisotropic filtering. Each puts more demands on the ol' CPU cycles. I take it you're not a PC gamer or just use defaults.
it’s just fundamental. you must know the difference between your DAR and PAR to generate the CFGs
It was like I had originally written and I agree you are correct. It is fundamental when you understand it properly. I do appreciate your script and have fun. It's a neat project.
-
@riverstorm said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
it’s stretched either way. either you’re stretching the raw image from its PAR (“square pixels”) to DAR (the correct aspect ratio), or you’re stretching away from the DAR to make your pixels square (PAR)
I don't think you can stretch an image from it's PAR. Unless you just worded that incorrectly? The PAR is a static ratio of the of width in proportion to the height. You can with an old CRT by adjusting the v-sync/h-sync which does change the aspect ratio like they where discussing with Donkey Kong in a prior post.
yes, the PAR is static. so to get a funky PAR image (eg sf2) to fit into a screen with 'square' pixels, we must stretch/distort that original image so it hits the right DAR.
I believe they get around those "oblong" 2:1-ish pixels by "concatenating pixels" on modern displays via doubling the x or y axis. I am sure there are more advanced techniques in displaying the DAR properly for old games.
who's "they"? mame? because that's not how it works in mame2003. they don't double axis, they just use an upscaling algorithm (like i describe in my next 'picture' post). doubling the x or y axis wouldn't give the proper DAR.
not at all. again the raw pixel image does not have a direct connection to the aspect ratio on the CRT. CRTs don’t need square pixels. if you integer scale up from the raw pixel image you will often be off from the proper aspect ratio.
No, that's still not I am trying to say. I read that article too.
If I have three 16:9 monitors and display one is 1280×720, display two is 1600×900 and display three is 1920×1080 (these are real monitor examples). If I program a game that is 100 x 200 pixels using display one it's going to look different on display two and three keeping in mind they are all three 16:9. The difference? The pixel aspect ratio (PAR).
yes - actually this is something neither script does. we don't take into account the aspect ratio of the target screen. we assume they have square pixels. for HDTVs this is almost always right. for PC monitors, yeah... it would be simple to add, though.
side note i wonder how PC games handle this kind of things? maybe pc monitors report their PAR through HDMI handshake. for all i know retroarch does this also, but that doesn't help our scripts. we'd have to get that info from the user.
they’re the same thing. if you can’t apply an integer scale and still hit 4:3 with no (top and bottom) borders, then you have to use a scaling algorithm. bilinear or nearest neighbour are most common. even integer scaling is a scaling algorithm, i suppose - just a very ‘brute force’ one.
Ok it seems like you're doing quick reads & cutting and pasting? You're confusing 2 different things. It's a smoothing technique for textures when you scale up or down such as walking closer or further from an object in game.
again, that's the same thing, more or less. if you show a thing of one resolution, into a thing with another, you have to resample (or upscale/downscale). to hide the artefacts of this, you use bilinear (or similar). if you like, you can consider the current frame of sf2 to be the 'texture', that you are standing very close to in a FPS game, to the extent that it is filling the screen.
You can scale in either direction but it's a texture smoothing technique that is supposed to improve the image quality detail when scaling not for scaling. It's very common option in PC games when deciding if your PC has enough horse power to do bilinear, trilinear or anisotropic filtering. Each puts more demands on the ol' CPU cycles. I take it your not a PC gamer?
*GPU cycles. you're confusing a lot of things here. just look at the code:
https://github.com/libretro/RetroArch/blob/b11620e1ebbc19937d675a48bdefc04c1b0b7421/libretro-common/gfx/scaler/scaler_filter.c#L202
retroarch's default upscaler with the GL driver is "point", but bilinear is right there as an alternative ('video smooth' option). point filtering is just a slightly less 'blurred' version. it's less expensive, also. there are lots of ways to skin this cat but bilinear is totally one of them. -
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
If I have three 16:9 monitors and display one is 1280×720, display two is 1600×900 and display three is 1920×1080 (these are real monitor examples). If I program a game that is 100 x 200 pixels using display one it's going to look different on display two and three keeping in mind they are all three 16:9. The difference? The pixel aspect ratio (PAR).
yes - actually this is something neither script does. we don't take into account the aspect ratio of the target screen. we assume they have square pixels. for HDTVs this is almost always right. for PC monitors, yeah... it would be simple to add, though.
For all of those displays, assuming they're advertised as 16:9, then the PAR should be the same for each (i.e. square).
1280 / 720 = 1.77777777777777
1600 / 900 = 1.77777777777777
1920 / 1080 = 1.77777777777777
and
16 / 9 = 1.77777777777777The only thing that's changing is the size of the pixels to suit whatever the physical display size is. Similarly, for other displays;
1280 /1024 = 1.25
5/4 = 1.251600 / 1200 = 1.33333333
4 / 3 = 1.3333333333333Overall, it's a very safe assumption that all current digital displays have square pixels.
Back to the earlier point - as Dank points out just above, it's possible to work out the degree of 'stretch' to apply in order to map from a display with one PAR to another. This is what I've done in the latest Pull Request that I submitted to Dank's script a few minutes ago, and interestingly, it gives results a little different, but more 'correct' than previous for some of these cases.
Dank's script currently produces the following output for Street Fighter 2 for a 1920 x 1080 display :
# Auto-generated crt-pi.glslp .cfg # Game Title : sf2 , Width : 384, Height : 224, Aspect : 4:3 # Screen Width : 1920, Screen Height : 1080 # Place in /opt/retropie/configs/all/retroarch/config/MAME 2003/ video_shader_enable = "true" video_shader = "/opt/retropie/configs/all/retroarch/shaders/crt-pi.glslp" # To avoid horizontal rainbow artefacts, use integer scaling for the width aspect_ratio_index = "22" custom_viewport_width = "1536" custom_viewport_height = "1080" custom_viewport_x = "192" custom_viewport_y = "0"
Here's the output using my method (again, SF2 on a 1920 x 1080 screen) :
# Auto-generated crt-pi.glslp .cfg # Game Title : sf2 , Width : 298, Height : 224, Aspect : 4:3 # Screen Width : 1920, Screen Height : 1080 # Place in /opt/retropie/configs/all/retroarch/config/MAME 2003/ video_shader_enable = "true" video_shader = "/opt/retropie/configs/all/retroarch/shaders/crt-pi.glslp" aspect_ratio_index = "22" custom_viewport_width = "1436" custom_viewport_height = "1080" custom_viewport_x = "242" custom_viewport_y = "0"
You'll see that the viewport width in my output is closer to the 1440 manual calculation.
(I've just realised that I'm also showing the 'resampled' game width in the header - 298 vs. the original 384. I can fix this, although it's purely informational and has no bearing on the operation of the script)Comparing across the wider range of games, I've managed to preserve a lot of the important stuff - on 1920 x 1080 displays, the vertical games should have the same width as using the original method, but for 1600 x 1200 displays they'll now be more proportional :-)
And in general, it looks like they should fill the screen a little better - I've re-purposed the 'tolerance' variable so that now, if the difference between the viewport width or height is less than that percentage of the original game width or height, we just stretch to fit. This means, that on a 1600 x 1200 display you get the following;New method :
# Auto-generated crt-pi.glslp .cfg # Game Title : sf2 , Width : 298, Height : 224, Aspect : 4:3 # Screen Width : 1600, Screen Height : 1200 # Place in /opt/retropie/configs/all/retroarch/config/MAME 2003/ video_shader_enable = "true" video_shader = "/opt/retropie/configs/all/retroarch/shaders/crt-pi.glslp" aspect_ratio_index = "22" custom_viewport_width = "1600" custom_viewport_height = "1200" custom_viewport_x = "0" custom_viewport_y = "0"
vs. old method :
# Auto-generated crt-pi.glslp .cfg # Game Title : sf2 , Width : 384, Height : 224, Aspect : 4:3 # Screen Width : 1600, Screen Height : 1200 # Place in /opt/retropie/configs/all/retroarch/config/MAME 2003/ video_shader_enable = "true" video_shader = "/opt/retropie/configs/all/retroarch/shaders/crt-pi.glslp" # To avoid horizontal rainbow artefacts, use integer scaling for the width aspect_ratio_index = "22" custom_viewport_width = "1536" custom_viewport_height = "1200" custom_viewport_x = "32" custom_viewport_y = "0"
-
@andrewh I may be missing the point reading along here, but I cannot help but notice that it looks like your new method the example doesn't integer scale the width. I thought that was the whole point: You integer scale the width so that you eliminate unsightly CRT-PI shader artifacts, then expand (or contract) the Y dimension to fit the display (whichever offers the least distortion). If you just ignore the integer scaling within a tolerance, why bother?
-
@caver01 said in crt-pi shader users - reduce scaling artifactsbolded text with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@andrewh I may be missing the point reading along here, but I cannot help but notice that it looks like your new method the example doesn't integer scale the width. I thought that was the whole point: You integer scale the width so that you eliminate unsightly CRT-PI shader artifacts, then expand (or contract) the Y dimension to fit the display (whichever offers the least distortion). If you just ignore the integer scaling within a tolerance, why bother?
Integer scaling of the width is only necessary for vertical games, not horizontal. The new method (like the old one) does integer scaling for vertical games and tries to achieve the best balance of filling the screen and matching the original aspect ratio.
I just posted the examples above because they were relevant to the discussion about Street Fighter 2’s non-square pixels and how they’re treated.
-
@andrewh So it behaves differently with vertical? That makes sense.
-
@andrewh said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
If I have three 16:9 monitors and display one is 1280×720, display two is 1600×900 and display three is 1920×1080 (these are real monitor examples). If I program a game that is 100 x 200 pixels using display one it's going to look different on display two and three keeping in mind they are all three 16:9. The difference? The pixel aspect ratio (PAR).
yes - actually this is something neither script does. we don't take into account the aspect ratio of the target screen. we assume they have square pixels. for HDTVs this is almost always right. for PC monitors, yeah... it would be simple to add, though.
For all of those displays, assuming they're advertised as 16:9, then the PAR should be the same for each (i.e. square).
1280 / 720 = 1.77777777777777
1600 / 900 = 1.77777777777777
1920 / 1080 = 1.77777777777777
and
16 / 9 = 1.77777777777777you're right - i didn't bother to do the maths but yes - all of @Riverstorm's displays have the same PAR (1:1).
Back to the earlier point - as Dank points out just above, it's possible to work out the degree of 'stretch' to apply in order to map from a display with one PAR to another. This is what I've done in the latest Pull Request that I submitted to Dank's script a few minutes ago, and interestingly, it gives results a little different, but more 'correct' than previous for some of these cases.
Dank's script currently produces the following output for Street Fighter 2 for a 1920 x 1080 display :
# Auto-generated crt-pi.glslp .cfg # Game Title : sf2 , Width : 384, Height : 224, Aspect : 4:3 # Screen Width : 1920, Screen Height : 1080 # Place in /opt/retropie/configs/all/retroarch/config/MAME 2003/ video_shader_enable = "true" video_shader = "/opt/retropie/configs/all/retroarch/shaders/crt-pi.glslp" # To avoid horizontal rainbow artefacts, use integer scaling for the width aspect_ratio_index = "22" custom_viewport_width = "1536" custom_viewport_height = "1080" custom_viewport_x = "192" custom_viewport_y = "0"
Here's the output using my method (again, SF2 on a 1920 x 1080 screen) :
# Auto-generated crt-pi.glslp .cfg # Game Title : sf2 , Width : 298, Height : 224, Aspect : 4:3 # Screen Width : 1920, Screen Height : 1080 # Place in /opt/retropie/configs/all/retroarch/config/MAME 2003/ video_shader_enable = "true" video_shader = "/opt/retropie/configs/all/retroarch/shaders/crt-pi.glslp" aspect_ratio_index = "22" custom_viewport_width = "1436" custom_viewport_height = "1080" custom_viewport_x = "242" custom_viewport_y = "0"
You'll see that the viewport width in my output is closer to the 1440 manual calculation.
(I've just realised that I'm also showing the 'resampled' game width in the header - 298 vs. the original 384. I can fix this, although it's purely informational and has no bearing on the operation of the script)1436/384 = 3.73
that's not a in integer scale. my script tries to get an integer scale on the X axis for horizontal AND vertical games. i believe i discussed my reasoning for this earlier in the thread, but it is intentional. i could be convinced otherwise, but in my experience at 1080p the difference from the correct ratio is not noticeable. maybe at lower resolutions you'd not want it.
remember that the scaling artefacts are always present in both dimensions, just more noticeable in the axis perpendicular to the scanlines. my "priority of needs" on a 16:9 HDTV is something like:
- no top/bottom borders
- no scanline artefacts
- no scaling artefacts
- as close to correct aspect ratio as possible
but i could be convinced otherwise. are there any horrible examples where the image looks really stretched?
Comparing across the wider range of games, I've managed to preserve a lot of the important stuff - on 1920 x 1080 displays, the vertical games should have the same width as using the original method, but for 1600 x 1200 displays they'll now be more proportional :-)
And in general, it looks like they should fill the screen a little better - I've re-purposed the 'tolerance' variable so that now, if the difference between the viewport width or height is less than that percentage of the original game width or height, we just stretch to fit. This means, that on a 1600 x 1200 display you get the following;New method :
# Auto-generated crt-pi.glslp .cfg # Game Title : sf2 , Width : 298, Height : 224, Aspect : 4:3 # Screen Width : 1600, Screen Height : 1200 # Place in /opt/retropie/configs/all/retroarch/config/MAME 2003/ video_shader_enable = "true" video_shader = "/opt/retropie/configs/all/retroarch/shaders/crt-pi.glslp" aspect_ratio_index = "22" custom_viewport_width = "1600" custom_viewport_height = "1200" custom_viewport_x = "0" custom_viewport_y = "0"
vs. old method :
# Auto-generated crt-pi.glslp .cfg # Game Title : sf2 , Width : 384, Height : 224, Aspect : 4:3 # Screen Width : 1600, Screen Height : 1200 # Place in /opt/retropie/configs/all/retroarch/config/MAME 2003/ video_shader_enable = "true" video_shader = "/opt/retropie/configs/all/retroarch/shaders/crt-pi.glslp" # To avoid horizontal rainbow artefacts, use integer scaling for the width aspect_ratio_index = "22" custom_viewport_width = "1536" custom_viewport_height = "1200" custom_viewport_x = "32" custom_viewport_y = "0"
again this is the same x scaling thing as i mentioned before. i guess with a 4:3 display you don't want borders, so i can see how this would be preferable in that situation.
-
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
remember that the scaling artefacts are always present in both dimensions, just more noticeable in the axis perpendicular to the scanlines. my "priority of needs" on a 16:9 HDTV is something like:
- no top/bottom borders
- no scanline artefacts
- no scaling artefacts
- as close to correct aspect ratio as possible
but i could be convinced otherwise. are there any horrible examples where the image looks really stretched?
At the moment, the most obvious example would be vertical games on 4:3 displays, which, by default, are still getting output at 1120 x 1200 (i.e. almost square)
So, my approach can definitely be adapted to match your priorities, but I think had them ordered a little differently, and I tried to accommodate more than just 16:9 displays, focusing also on getting best results for 5:4 and 4:3 displays;
(the displays I have at hand for testing are 5:4 and 4:3 - resolutions of 1280x1024 and 1600x1200 respectively)- No / minimal borders
- Keep close to original aspect ratio
- No scanline artefacts for vertical games (where they're most evident)
- Minimal scaling artefacts
I think it's pretty apparent that our differing perspectives on the priorities are what bring about the differences.
I've done a fair bit of testing with the output of my script on the screens I have available, and I've been pleased with the results. Using non-integer scaling on horizontal games doesn't appear to introduce any scaling or scanline artefacts that I could readily detect. The screen is well filled for horizontal games, and the display is nicely proportioned for the vertical games.At the end of the day, though, looking at numbers in config files will only get us so far..
If you can spare some time to test my script and give some feedback on your subjective impression of its output, that would be great. I'm open to suggestions for further changes (maybe we can make some selectable options to allow users to better fine-tune it to their particular needs?)
-
@andrewh said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
remember that the scaling artefacts are always present in both dimensions, just more noticeable in the axis perpendicular to the scanlines. my "priority of needs" on a 16:9 HDTV is something like:
- no top/bottom borders
- no scanline artefacts
- no scaling artefacts
- as close to correct aspect ratio as possible
but i could be convinced otherwise. are there any horrible examples where the image looks really stretched?
At the moment, the most obvious example would be vertical games on 4:3 displays, which, by default, are still getting output at 1120 x 1200 (i.e. almost square)
So, my approach can definitely be adapted to match your priorities, but I think had them ordered a little differently, and I tried to accommodate more than just 16:9 displays, focusing also on getting best results for 5:4 and 4:3 displays;
(the displays I have at hand for testing are 5:4 and 4:3 - resolutions of 1280x1024 and 1600x1200 respectively)- No / minimal borders
- Keep close to original aspect ratio
- No scanline artefacts for vertical games (where they're most evident)
- Minimal scaling artefacts
I think it's pretty apparent that our differing perspectives on the priorities are what bring about the differences.
I've done a fair bit of testing with the output of my script on the screens I have available, and I've been pleased with the results. Using non-integer scaling on horizontal games doesn't appear to introduce any scaling or scanline artefacts that I could readily detect. The screen is well filled for horizontal games, and the display is nicely proportioned for the vertical games.At the end of the day, though, looking at numbers in config files will only get us so far..
If you can spare some time to test my script and give some feedback on your subjective impression of its output, that would be great. I'm open to suggestions for further changes (maybe we can make some selectable options to allow users to better fine-tune it to their particular needs?)
absolutely! i have to set up a retropie for a friend (i am waiting for stretch support so i can test that also) so will take that opportunity to try your configs. i suspect i will prefer them :)
-
sigh...I thought about replying to your comments about my comments but I know it's kinda like going down a rabbit hole creating constant doubt with comments, code or methods you understand little to no more than I do from reading your replies. It just seems you always have a retort to everything but sometimes not knowing is ok. I kind feel like you'd stand at the pearly gates and kick St. Peter right in the teeth...before you'd let somebody play you.
From the get go Andrew not only answers questions but backs them up with the math. I could never even get you to explain two lines of code let alone get you to confirm you coded the whole script yourself out of curiosity.
Collaboration requires communication but you would never explain any of your script which lead me to doubt the validity of it's authenticity. It's not just waiting for someone who knows more to come along and do the work. There's no way I could have done better then Andrew but I was willing to try and would have learned a good bit. In fact I offered to help Andrew right away in a prior post but as it turns out he's a one man show that needs no help.
I don't imagine that you would be accountable and own it but the side poke was really unnecessary. You discretely closed the other thread, ignoring the post & encouraged everyone back to this post. Then promptly started challenging and trashing every comment I was writing. For what?! To show folks how smart you are at the expense of others. It does no one any good or help them learn to make them afraid or second guess what they don't know.
I was sincerely hoping for a bygone as I enjoy being part of this community. I was here on good faith to learn a bit about the process of the configs. I know I asked a lot of questions but it's how I learn and absorb information. I like to understand to the last detail. Truly understanding all aspects is the only way to write code or scripts. In fact you can't write code that works unless you fully understand the challenge at hand.
Honestly now I don't really care about the configs at this point due to the endless conflict. While they show a slight enhancement zoomed in they don't offer much un-zoomed. DaveJ's vertical shader fixed most of the issue. The slight artifacts I can live with. Not to mention they are completely incompatible with HD overlays.
Anyway If you had something to say about what I wrote I would had rather you addressed it directly instead of acting out with backhand comments. There's just a point where someone has to be the bigger person and walk away. Not that I am the bigger person but I am ok with walking away.
@AndrewH - Yes I did confuse pixel dimensions vs PAR. I still hope the same idea holds true. Porting from old arcade monitors to modern displays is a fundamental challenge the requires several different techniques to overcome PAR/DAR discrepancies from one to the other.
Just out of curiosity are you the same Andrew with a page full of utilities JavaScript & CSS experiments? Who's #1 app is about aspect ratios? Github account. I was wondering how you were picking this & Github up so incredibly quick. If so it's nice to see someone of your caliber leading the project. Your work looks pretty incredible with many helpful utilities!
-
@riverstorm Hey, I read your above note and think you probably don't need to feel the way you do. I have been on the outside of this discussion injecting my own observations/comments here and there, but also learning from your more specific attempts to understand the details.
I think it is easy to read into responses that are written to be very direct and interpret them as offensive. It's one of the problems with text, as you cannot truly detect the tone. That said, as I read through Dank's notes, I find them to be short, meaning they are pointed and brief, not necessarily impolite. I expect the original intent of this thread was to provide technical guidance to scripting the construction of custom viewports to avoid shader artifacts and not as much of a training guide for understanding DAR, PAR, AR, scaling algorithms, github, and so on. When you started the other thread, I was hopeful it could serve as the place for friendly discourse about all of that. The fact is, these custom configs are connected in principle to a very long list of side topics worthy of discussion that would produce (and has produced) tidbits of detail that many folks will benefit from. Yet, much of it distracts from Dank's original intention for opening this thread, while Andrew's efforts to enhance the script do not.
I guess I am saying, don't feel bad about this. I'd like to discuss some of the side topics. For example, I have a few notes to share about bilinear interpolation that I think will bring the idea of scaling vs. smoothing to a conclusion.
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.