Questions about shaders. How to mix them effectively?

Hello guys, it’s me again, this time I want to discuss about Shaders. Before start, I want to say that I love Shaders since back to 2012, I remember the very first time I saw HQ4x and thought “This is the best Shader ever” and them I found xBr and recently the ScaleFx… I love anything that make my squares something like a draw using a pen that outline and shape the graphics to make it looks like a remaked or upscaled game.

Since last year, I’m using an HDMI cable that I decided to buy to improve my gaming experience using my TV, but now that the video image is bigger, my eyes are not satisfied with the effect of only one shader effect, I picked some shaders that I liked it’s standalone effects and now I’m trying to mix them. No good result until then, the best I can do is mixing 2 shaders but I want something between 3 to 5 shaders at the same time.

So I decided to search for topics here but found nothing like a tutorial, the best I could find was topics of some users asking if it’s possible to combine shader X with shader Y to make Z effect and most of them got a replay with the shaders settings, but not explained how one can figure out the result. Other than that, I found topics about some people who made some specific shader and explains the reasons behind the creation and why it’s useful to apply in some consoles or specific games, also interesting but not that useful for learning shader combos.

Now that I said all this preamble, I’ll go direct to the questions:

1-Loading Shader Presets, I see CG, GLSL and SLANG, I got that GLSL is for OpenGL and SLANG for Vulkan, I can run GLSL but CG also works and looks that both have the very same Shaders, so why should I choose GLSL over CG and vice-versa? This is just pure curiosity.

2-Ok, so I decided and picked one Shader, it comes with some preset as Shader Filter and Shader Scale, talking about Filter, what is the difference between Don’t Care, Linear and Nearest? Most of the ones I picked is Nearest. Talking about Scale, why someone should choose anything between Don’t care and x5? I feel this info is necessary to mix shaders effective.

3-How one can say if two different shaders will give a good result? it is just trying and trying over again until get the result, hit and miss? Or there’s some logic I can use to deduce the shaders I picked will not work together as I expected?

Thanks for your attention.

1 Like

1.) Cg is a proprietary language from Nvidia that is extremely similar to HLSL (IIRC, Microsoft hired Nvidia to make the HLSL shader language, so when Nvidia made Cg for themselves it turned out almost identically). We chose it because you could write shaders once and it would run on directx9, OpenGL and PS3 platforms, which covered all of the shader-capable platforms at the time. Then, 3 or 4 yrs ago, Nvidia announced that they were killing off Cg and would not open-source it, so it became a dead language. We’ve kept it alive as long as we could, but since it’s proprietary, we knew the runtime/compiler would eventually fall out of compatibility with modern OSes and toolchains, and that time has apparently come (MSYS2’s Cg toolkit package has an un-resolvable dependency that keeps it from installing).

So, when we learned that Nvidia was killing it, I converted (almost) all of the Cg shaders to GLSL by hand (we have a script, cg2glsl, that can do it programmatically, but it’s error-prone and the output is unreadable garbage).

Slang is a new thing that has a lot of similarities to the useful aspects of Cg (that is, you write it once and it compiles to match a variety of different drivers), but with the major advantages of being an open project (glslang) and using an open language for its syntax (GLSL #version 450), so even if glslang went defunct for whatever reason, the shaders would still be usable as bog-standard GLSL.

So for us, slang is the top priority, GLSL is second priority (legacy GL) and Cg is deprecated. Cg is only really still hanging around because of its similarities to HLSL, which we hope to get a native driver for at some point. With that in mind, I would recommend using glcore, vulkan and/or d3d11 with slang shaders whenever possible.

2.) Filters correspond to the GPU’s built-in texture filtering silicon. Linear = bilinear (blurry), Nearest = nearest neighbor (sharp, prone to uneven pixel sizes at non-integer scales). “Don’t Care” means: use whatever the user has in their video settings (Bilinear filtering on/off). Since you like the smoothing/interpolation shaders, they typically require “nearest” to do their pixel detection comparisons.

Scale sets the scale of the output framebuffer. Some shaders want/need an explicit output scale, either for predictable analysis in a later pass or because the algorithm only knows how to output a certain size (e.g., hq2x, 2xBR, ScaleFx). If you leave it to “Don’t Care”, it will use an implicit 1x scale for all passes, with every pass using “source” scaling (which means it’s based on 1x the original framebuffer size the core puts out) except for the last pass, which is 1x “viewport” (which means the scale is based on the size of the output window, including full screen; that is, “scale to fit”).

3.) It’s largely hit or miss / trial and error, but you can often figure out whether it will work based on how the shader code works. For example, I know most CRT shaders freak out if you hand them high-res content, so it’s usually not worth even bothering to scale something with xBR or whatever and then just slap a CRT shader on there unless the CRT shader has some logic for handling higher resolutions. Conversely, I know most color/signal shaders (NTSC, etc.) don’t need to scale at all, so you can put them before just about anything running at 1x scale.

The danger is that, since RetroArch lets people mix and match shader passes with no understanding of what’s actually going on in the code, you can end up with some really monstrous, inefficient combinations that look nice but are difficult to maintain (see: the “Analog Shader Pack”)


Loved your answer! But I’m kinda dummy so let’s talk a bit more the second point, about the Scale. Let’s suppose I applied one Shader and choosed the second, but don’t know what to set (anything between don’t care and x5). What should I do? Is it any good if I memorize it’s standalone native settings and apply it?

And one more doubt: Does the order that I apply the shaders makes difference? or the order of the factors does not change the result?

Yes, remembering the output size of the standard preset can be helpful, though many of them are going to use the final “don’t care” scale, which isn’t very helpful. Again, you’ll just have to try some things and use some common sense. If it’s a scaling shader, you’ll need to give it some room to scale.

Yes, the order makes a big difference. The shader passes are applied in order, so each one builds on the one before it.

Ok, so shading is pure science, test, test and test again until uncover the best result. Logic and common sense are my teammates, pacience and persistence are my best friends. Applying in different orders might be the solution if something didn’t worked as intended. Thank you!

1 Like