xBR algorithm tutorial

Anyway, I’m back working on super-xbr shaders. After some years I decided to see its parameters and figured out I should change some of them. At the same time, I ported Anime4k hlsl shaders to cg and it work well after super-xbr by doing an slightly dilation and using gradients to enhances edges.

Some screens (super-xbr + anime4k):

Full size: https://img.onl/iFJbhA

Full size: https://img.onl/2Z3Gc7

Full size: https://img.onl/etEksE

Full size: https://img.onl/6jIuBM

Full size: https://img.onl/NyawaY

Full size: https://img.onl/2cIkTs

https://img.onl/zFbFDE

https://img.onl/N9czm5

https://img.onl/rTJEp

Oh wow, are these in your PS3 pack in the other thread, as well? I’ve tried to port the GLSL version to RA, but it was ~30 passes -_-

These screenshots look awesome, btw.

EDIT: also, did you do the proposed FXAA step (presumably between steps 4 and 5)?

No, RA 1.0.0.2 for PS3 can’t run. I’m using my old notebook to run them. They’re 11 passes! 2x3 sxbr + 1x1 catmull-rom + 1x4 anime4k passes. I didn’t use FXAA.

These anime4k shaders are the old ones in hlsl. They’re very simple. I like the layer it apply to the whole screen. It works by making a gentle dilation just before a push in edge gradients. I didn’t push it too much, because the effect can degrade in “xylograph” very fast.

I’ll let here a version without further optimizations if you’re interested in test:

super-xbr-6p-anime4k cg shaders and preset - beta

The super-xbr shaders on RA repo are using outdated params, so I have included the new ones.

1 Like

Great job on the shader Hyllian, if I may suggest to add some sort of noise effect to give the render a bit of “density” look instead of the “clay/wax” look .

See album

This is something to add, indeed. Though it should be an independent shader implemented on its own pass. The same way as anime4k is just a separated filter (a sharpening-like method), which can be used with any other.

Glad you’re considering the idea . Here is a preset I modified ,it works well for games with big sprites such as fighting games but it lacks the thin edges your xbr-Anime4k preset provide , it would be great to have the best of both worlds . Use it with vulkan render (it’s very hardware demanding)

https://mega.nz/file/YMBDxAII#5UXt5jzIhfFII2P3c3pwoGgF_6id4lU64kOCn74No3k

Here is an album for the preset I have posted , I like how the details are maintained and how the color graduate. On the other hand , edges and colors vibrance/fidelity leaves more to be desired:

Too many shaders there! kkk I doubt it doesn’t degrade image at some point.

A gentle sharpening method after an upscaling is recommended. But you are using so many sharpeners that the textures were chewed multiple times. It has created some kind of mosaic.

Yeah , I figured as much :sweat_smile: .I was going for close to ESRGAN sort of look Which is pretty much down right Impossible. sharping the NEDI3 too much gives an ugly artifacts which I masked with slow-bilateral. With your xbr-Anime4k that won’t be necessary.

Another day, another port. :wink:

Finesharp is another good sharpening shader I ported to Retroarch. It’s good because it only sharp fine edges and don’t touch small color transitions of backgrounds and textures. It works well with super-xbr-small-details.

I’ve made some tweakings on sxbr parameters to work well with finesharp. This preset works by preserving fine detail pixels and smoothing out only those clearly edges. And finesharp enhance visuals by sharpening relevant edges.

Download here (cg only): super-xbr-3p-small-details + finesharp shaders

Shader tip: Do you wanna unleash Nedi 3-pass preset power? Try swapping nedi-pass2 by super-xbr-small-details-pass2 (set param edge_strength_p2 = 0.0) and see what happens (experiment on action games like Demon’s Crest, Megaman, Maximum Carnage or Dracula XX, where small text details aren’t relevant).

1 Like

You can get some impressive results with nedi + sxbr-pass2:

Preset: https://anonymousfiles.io/Gl50rcLC/

1 Like

oh lawd, dat actraiser 2 final boss shot :open_mouth:

nedi 's signature is a little strong for my tastes at full res, usually, but those downsampled thumbnails look really fantastic.

2 Likes

Indeed. NEDI is a rough beast for little details, it needs to be tamed to work with small resolutions, kkk. I think the 3-pass swap works on that way. Maybe there are other forms to improve this even further.

But, believe me, for action-paced games where you don’t need to pay atention to small details, that preset is very good. It cleanup the whole screen and give a better sensation of movement. Still screens aren’t good measures for that preset.

1 Like

Hey mate, tanks for being active lately.

If you have the time , would you please have a look at this shader and if possible suggest a way to pixelate it.

https://mega.nz/file/VF4EDBiA#MRBArT2h1nxbLNC_Sp2qnMgIEODoYkJsJwKU054FbUM

what I mean is to add a layer that would use the shader as a reference and downscale it to small pixels similar to that of Hi-res pixel art. It would have tiny pixels for the edges instead of a round shape , preferably whiteout losing a lot of detail

I think it would be an interesting look

As i see your preset, you’re upscaling by a whopping factor of 16x, kkk.

You’ll need to downscale increasing sharpness.

The easiest way to do this is using a bicubic shader as a last pass with very soft params (because when downscaling, it provides sharpness instead softness), like B-spline one. In resume, add this last pass to your preset:

shader13 = “shaders_slang/cubic/shaders/bicubic.slang” wrap_mode13 = “clamp_to_border” filter_linear13 = “false” scale_type_x13 = “source” scale_x13 = “0.250000” scale_type_y13 = “source” scale_y13 = “0.250000”

And edit bicubic param to be a B-Spline (B=1.0 and C=0.0).

Thanks for replying, not exactly what I had in mind lol

Well, I’ve got a different result:

shaders = "14"
shader0 = "shaders_slang/nnedi3/shaders/nnedi3-nns64-win8x4-pass1-rgb.slang"
filter_linear0 = "false"
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
alias0 = ""
float_framebuffer0 = "false"
srgb_framebuffer0 = "false"
scale_type_x0 = "source"
scale_x0 = "1.000000"
scale_type_y0 = "source"
scale_y0 = "2.000000"
shader1 = "shaders_slang/nnedi3/shaders/nnedi3-nns64-win8x4-pass2-rgb.slang"
filter_linear1 = "false"
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
alias1 = ""
float_framebuffer1 = "false"
srgb_framebuffer1 = "false"
scale_type_x1 = "source"
scale_x1 = "2.000000"
scale_type_y1 = "source"
scale_y1 = "1.000000"
shader2 = "shaders_slang/omniscale/shaders/omniscale.slang"
filter_linear2 = "false"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
alias2 = ""
float_framebuffer2 = "false"
srgb_framebuffer2 = "false"
scale_type_x2 = "source"
scale_x2 = "1.000000"
scale_type_y2 = "source"
scale_y2 = "1.000000"
shader3 = "shaders_slang/nnedi3/shaders/nnedi3-nns32-win8x4-pass1-rgb.slang"
filter_linear3 = "false"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "false"
alias3 = ""
float_framebuffer3 = "false"
srgb_framebuffer3 = "false"
scale_type_x3 = "source"
scale_x3 = "1.000000"
scale_type_y3 = "source"
scale_y3 = "2.000000"
shader4 = "shaders_slang/nnedi3/shaders/nnedi3-nns32-win8x4-pass2-rgb.slang"
filter_linear4 = "false"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "false"
alias4 = ""
float_framebuffer4 = "false"
srgb_framebuffer4 = "false"
scale_type_x4 = "source"
scale_x4 = "2.000000"
scale_type_y4 = "source"
scale_y4 = "1.000000"
shader5 = "shaders_slang/xsoft/shaders/4xsoft.slang"
filter_linear5 = "false"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
alias5 = ""
float_framebuffer5 = "false"
srgb_framebuffer5 = "false"
scale_type_x5 = "source"
scale_x5 = "2.000000"
scale_type_y5 = "source"
scale_y5 = "2.000000"
shader6 = "shaders_slang/windowed/shaders/jinc2.slang"
filter_linear6 = "false"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = ""
float_framebuffer6 = "false"
srgb_framebuffer6 = "false"
shader7 = "shaders_slang/sharpen/shaders/fast-sharpen.slang"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = ""
float_framebuffer7 = "false"
srgb_framebuffer7 = "false"
shader8 = "shaders_slang/sharpen/shaders/fast-sharpen.slang"
wrap_mode8 = "clamp_to_border"
mipmap_input8 = "false"
alias8 = ""
float_framebuffer8 = "false"
srgb_framebuffer8 = "false"
shader9 = "shaders_slang/sharpen/shaders/adaptive-sharpen.slang"
wrap_mode9 = "clamp_to_border"
mipmap_input9 = "false"
alias9 = ""
float_framebuffer9 = "false"
srgb_framebuffer9 = "false"
scale_type_x9 = "source"
scale_x9 = "1.000000"
scale_type_y9 = "source"
scale_y9 = "1.000000"
shader10 = "shaders_slang/deblur/shaders/deblur.slang"
wrap_mode10 = "clamp_to_border"
mipmap_input10 = "false"
alias10 = ""
float_framebuffer10 = "false"
srgb_framebuffer10 = "false"
scale_type_x10 = "source"
scale_x10 = "2.000000"
scale_type_y10 = "source"
scale_y10 = "2.000000"
shader11 = "shaders_slang/warp/shaders/smart-morph.slang"
wrap_mode11 = "clamp_to_border"
mipmap_input11 = "false"
alias11 = ""
float_framebuffer11 = "false"
srgb_framebuffer11 = "false"
shader12 = "shaders_slang/blurs/sharpsmoother.slang"
wrap_mode12 = "clamp_to_border"
mipmap_input12 = "false"
alias12 = ""
float_framebuffer12 = "false"
srgb_framebuffer12 = "false"
shader13 = "shaders_slang/cubic/shaders/bicubic.slang"
filter_linear13 = "false"
wrap_mode13 = "clamp_to_border"
mipmap_input13 = "false"
alias13 = ""
float_framebuffer13 = "false"
srgb_framebuffer13 = "false"
scale_type_x13 = "source"
scale_x13 = "0.250000"
scale_type_y13 = "source"
scale_y13 = "0.250000"
parameters = "RESOLUTION_X;RESOLUTION_Y;CONTRAST;JINC2_WINDOW_SINC;JINC2_SINC;JINC2_AR_STRENGTH;SHARPEN;CONTR;DETAILS;CURVE_HEIGHT;OFFSET;DEBLUR;SMART;SM_MODE;SM_PWR;SM_STRMIN;SM_STRMAX;SM_CUTLO;SM_CUTHI;SM_DEBUG;max_w;min_w;smoot;lumad;mtric;B;C"
RESOLUTION_X = "0.000000"
RESOLUTION_Y = "0.000000"
CONTRAST = "3.000000"
JINC2_WINDOW_SINC = "0.440000"
JINC2_SINC = "0.820000"
JINC2_AR_STRENGTH = "0.500000"
SHARPEN = "2.000000"
CONTR = "0.070000"
DETAILS = "1.000000"
CURVE_HEIGHT = "2.000000"
OFFSET = "2.000000"
DEBLUR = "7.000000"
SMART = "1.000000"
SM_MODE = "1.000000"
SM_PWR = "0.900000"
SM_STRMIN = "0.000000"
SM_STRMAX = "1.000000"
SM_CUTLO = "0.000000"
SM_CUTHI = "1.000000"
SM_DEBUG = "0.000000"
max_w = "0.000000"
min_w = "-0.150000"
smoot = "0.000000"
lumad = "0.100000"
mtric = "0.700000"
B = "1.000000"
C = "0.000000"

Yeah that’s because I have used 0.140000 instead of 0.250000 for the scale_x13 value

The idea that I have is to keep the color graduating (which the shader does well) intact and have tiny pixels for the edges giving it a crisp look . Something a bit like this

Iori Yagami_0

Iori Yagami_1

As I mentioned like having Hi-res pixel art

Unfortunately , lowering scale_x13 value will only give jaggies

1 Like

That’s not easy, because you’d have to determine exactly the edges that should be sharpened and the edges that should keep untouched. Deblur shader does something like that, or at least try. You should use deblur as last shader and tweak its params to see if you get something good.