Two more examples of downsampled mask size 2 mask 10:
Aperture:
Slot mask:
New Release Version (2023-06-04-r1):
Notable changes:
Download link:
https://mega.nz/file/toBGBAYR#9uljee1NWY4-9LUg09d1f3sfOROaYgeN3fXVF2hccZw
I would also kindly ask @hunterk for a repository update (this one is just copy-over also).
Edit: thanks @hunterk for the update. Newest versions are now available through the RA shader updater.
Yay! I hope we get more frequent updates on the repository.
Not only is it more convenient to update, but itās also easier to check what changed between versions.
Nice. With this update I can remove the note in my thread about users needing to manually having to download your latest update since everyone can now get it simply by updating their slang shaders, until you drop another new update on us that is lol.
For anyone using my pack it works with my presets, I tested it and nothing is affected at all from what I see.
@guest.r, Iād like to thank you for the amazing work that youāve done with this shader. The depth of it is incredible. Iāve been playing with it for the last couple of weeks for 10-15 minutes a day, and I still have a lot to learn. Most of what Iāve done so far is explore the masks, scanlines, and parts of bloom/glow/halation.
To my eye, 8K and a display that put out a gazillion nits would be ideal, but Iāve found the mask zoom feature particularly interesting to increase TVL perception for systems where that look is more appropriate.
I wish the shader was documented, but itās also been fun to play with the sliders and learn what things do. Below Iāve included a screenshots which I hope do your shader some justice.
Hello Guest, I was having a look at your fast grade shaders and saw some optimization tricks.
You can multiply linear transformation matrices to create a new joint matrix, maybe the same can be applied to other shaders of your pack but in pre-shaders.slang at line 315:
color = (m_in*m_out)*color;
color = clamp(color, 0.0, 1.0);
color = pow(color, vec3(1.0/p));
if (CP == -1.0) color = c;
vec3 scolor1 = plant(pow(color, vec3(wp_saturation)), max(max(color.r,color.g),color.b));
float luma = dot(color, vec3(0.299, 0.587, 0.114));
vec3 scolor2 = mix(vec3(luma), color, wp_saturation);
color = (wp_saturation > 1.0) ? scolor1 : scolor2;
color = plant(color, contrast(max(max(color.r,color.g),color.b)));
p = 2.2;
color = clamp(color, 0.0, 1.0);
color = pow(color, vec3(p));
mat3 warm = ToSRGB*D65_to_D55;
vec3 warmer = warm*color;
mat3 cool = ToSRGB*D65_to_D93;
vec3 cooler = cool*color;
Yeah, these two (warm and cool) can be pre-calculated since there are constant values involved. Otherwise mat3x3 * mat3x3 should require 3x more ops compared with mat3x3 * vec3. Nevertheless, an optimization is possible, thanks for the hint.
ācolorā is a vec3 array variable so itās like running mat3vec3pixels, if you precompute (not necessarily a constant) a mat3 * mat3 you save one mat3vec3pixels operation which is huge. Maybe try to profile them, not sure how though not an expert on shaders (fps?)
You still need to use resources for a mat3*mat3 multiply doing it on the fly. But you know the mathā¦(9 dot products)
It can be done very fast due to parallelism, true, but mat3*vec3 should be simpler (3 dot products).
Moving it to the vertex shader should help indeed though, maybe itās a good trade.
Hey, I noticed in the ReShade port the Integer Scaling
setting also scales the mask and not just the game. Iām not sure if this is an issue on my end or intended functionality, but Iād like to request that it be fixed/changed if possible.
(Also just a friendly nudge to update the port in general, please!)
For anyone interested Iāve ported CRT-Guest-Advanced, HD and NTSC to ReShade.
Some screenshots at default settings.
Advanced -
HD -
NTSC -
Thatās amazing. I need to figure how to convert shaders to Reshade, Iāve gotten multiple requests to port my presets over there but donāt have the slightest idea on how to do it but your pics make me want to learn.
Great work, @DevilSingh, i will put a link to your git page in my first post also.
Good timing, lol, you can now try and use the newest versions ported to ReShade.
Thanks! This port wouldnāt be as good as it is without your help and testing.
*Says āIve been away for awhileā⦠*proceeds to go away for awhile
Anyway the reason I never made that third preset I promised was a lack of ideas. I have ideas now.
Recent screenshots look great guys.
@guest.r Could it be possible also apart from negative mask bloom, you could implement negative post brightness? just a numb question
A question @guest.r about handling non-square aspect ratios in CRT shaders (Iām just asking you as you must be familiar with the concept because of your Amiga shaders that handle 640x256 and 320x512 and similar resolutions properly).
The beam illuminating the phosphors in a CRT has the shape of a perfect circle with Gaussian falloff. So far so good, and if you feed such a CRT shader 1:1 pixel aspect ratio content (e.g. 640x480 or 320x240, assuming a 4:3 DAR emulated monitor), the shape of the emulated beam will remain a perfect circle in the shaded output.
But when dealing with non-square aspect ratios, typically ~1:2 PAR āwideā or ~2:1 PAR ātallā pixels (or anything in between or much beyond that, e.g. the 1280x200 Super-HiRes Amiga mode featuring 1:4.8 PAR āsuper tallā pixels!), the shader effectively processes a say 640x200 image, which then gets stretched to 4:3 display aspect ratio, meaning the shape of the emulated beam effectively gets elongated.
Iāve inspected the source code of some CRT shaders, and I havenāt noticed any mechanism in any of them that would āpre-distortā the shape of the beam by the inverse of the pixel aspect ratio so when the result is stretched to the final 4:3 display aspect ratio output, the shape of the beam would come out as a perfect circle. Moreover, output resolution is not taken into account either; an accurate CRT shader should not produce a āmore blurryā picture for 320x240 input vs 640x480 input, for example (the CRT does not āvaryā the size of the electron beam based on what signal is fed to it).
This is a bit of a problem for me because without such pre-distortion, itās just not possible to use a single shader with a single preset that would handle say 320x240, 640x240, 320x480 and 640x480 so that the size of the emulated beam remains a perfect circle with the exact same radius in all resolutions (I need this for my authentic CGA/EGA/VGA shader presets where such variations are common).
Iām guessing most people just donāt care about such detail? Or maybe itās technically very hard to apply such pre-distortion at the shader level to keep the beam shape and size constant no matter the variation in input dimensions (and of the PAR, by extension)?
Thanks, and I hope I managed to explain all this slightly complicated topic clearly
Yes, this is an issue with CRT emulation and the most common way is to use a filtering approach which works properly only with low resolution input.
The main problem is that CRT emulation isnāt done on a low level, but uses HW features of an adapter (like point or bilinear filtering), a basic filtering approach (like adapted bilinear, quilezā¦), a standard filtering approach (like lanczos, spline, sinc, gaussianā¦) or something more advanced.
Currently i donāt know many CRT shaders that would consider advanced filtering, because special kernels need to be implemented which consider doubled (tripled) pixels and thus donāt skip details.
From my Retroarch repertoire the only shader capable of doing so properly is the guest-advanced-HD version, where itās simple to change the internal resolution parameter, but itās not automated for an input resolution for various reasons.
On the WinUAE side i needed to write special kernels to handle the hires (only hires, not superhiresā¦) mode properly, but interlacing support (for example) is missing due to limited capabilities of the emulatorās shader environment.
There exists a ReShade version of the āHDā shader, but you need to manually input the resolution every time it changes etc.
What iām saying is that these problems arenāt addressed in general and itās also hard to address them. A good and persisting example is the SNES game Trials of Mana (Seiken Densetsu 3), which changes the resolution to the āhiresā when talking and going to menues. Most common way is to āderezā the game to 256x224, but here details are going missing.
So, a single preset or a single configured shader to cover every resolutional situation properly hasnāt been developed yet afaik and trends show there is much more probability that any shader will require manual tuning for special cases.
Unless there is something done from scratch especially for these.
Thanks for sharing your great insights into the matter @guest.r!
For the record, I started down this path because I wasnāt content with how an emulated 320x200 EGA image looks like when using the Hyllian shader (which is fantastic for 640x400+ content, otherwise, e.g. for double-scanned VGA). I just couldnāt get the results look like a real EGA monitor; there was always too much softness horizontally.
When I width-doubled the input of the shader to 640x200, the results were a lot closer to the output of a typical sharp EGA monitor, but then I started to think about how realistic this is. In a way, it is because the same 320x200 image displayed in 320x200 mode, or width-doubled to 640x200 and displayed in 640x200 mode yields the exact same results, just like on a real CRT. On the other hand, I have effectively squashed the circular beam shape into an ovalā¦
Iām still vacillating whether this is the right solution or not. I have a bit of a distaste for it as literally sending a double-width image to the shader seems kind of crude. On the other hand, thatās literally what we have to do for accurate line and pixel doubled VGA emulation (e.g. low-res 320x200 gets doubled to 640x400; from the VGA monitorās perspective, āfake 320x200ā (doubled by the VGA adapter) and āreal 640x400ā screen modes are 100% identical down to the signal level).
So maybe thatās what Iāll do after all; at least, then itās consistent with the VGA pixel/line-doubling emulation. Plus the beam shape will get distorted in the myriad of tweaked VGA modes anyway (320x400, 360x200, 360x480, 320x400, 360x270, 376x308 ā itās an unending listā¦)
Comparison screenshots for reference.
320x200 sent to the shader
640x200 sent to the shader
Closeup
Horizontal resolutions are managable with my current codebase, but iām not this confident with vertical resolutions and scanlines.
A 4k display should be mandatory for everything above 250px or/and double scan. But i guess the āstrangerā the resolution the seldom it appears.