Uborder shaders

Uborder shaders

First release: uborder-v01


What’s this?

It’s a simple and fast alternative to more complex bezel shaders like Mega Bezel or Koko-aio.

Why?

I really appreciate the features offered by Mega Bezel and, more recently, by Koko-aio shaders. Being complex shaders, they tend to require a powerful machine to run. This made me wonder if it might be possible to create something simpler that could still provide some of their impressive features, like reflections, in a fast way. As a result, I came up with this first release.

How to use?

  1. Copy zip contents to the main ‘shaders’ folder inside Retroarch;
  2. On Retroarch, choose ‘FULL’ aspect ratio;
  3. Optional: to use Orion’s presets, it’s mandatory to install Orionsangel-Original-Console pack from Duimon inside ‘Mega_Bezel_Packs’ folder.

For now, there are three types of presets you can load:

  1. ambient-light-crt.slangp
  2. uborder.slangp
  3. uborder-reflections.slangp

Compatible content-shaders:

  • crt-nobody (default)
  • crt-geom

crt-nobody is a modified version to support interlaced signal (test psx games like SH or Tekken3 and you’ll see how it behaves). To use crt-geom, edit the main presets ‘ambient-light-crt.slangp’, ‘uborder.slangp’ or ‘uborder-reflections.slangp’, commenting the crt-nobody line and uncommenting the crt-geom line. Doing that, all presets will load the correct crt shader. I’ll probably add other known shaders in the future.

Can I prepend shaders to it?

YES! Some great shaders can be prepended to this one. I have tested ntsc-adaptive and it worked prepended out of the box! Though by doing this you’re adding a layer of complexity and may slow the results.

Can I use my own background?

YES! It’s called Uborder for a reason, it’s easy to add your own background. BTW, in this first release I’ve provided a Spooky TV preset (I’ll probably exclude it in future releases) to show how easy it is to create your preset using your backgrounds.

To add your own background, create a folder inside the ‘presets’ directory, similar to the ‘Spooky TVs’ folder. Copy the ‘Spooky.slangp’ file into your folder and rename it as desired. Within the preset file, update the BORDER texture to reference your background image. Then, run the preset and use the user parameters in Retroarch to adjust the frame and reflections to fit your image. Once done, save it as a simple preset and copy the parameters back into your preset file to ensure it loads correctly next time.


Optional packs compatibility

Presets for community packs are found inside ‘presets’ folder. Example from Orionsangel below:

Orionsangel-Original-Console pack: Orionsangel-Original-Console pack

The presets only work if the pack is installed here: ‘shaders/Mega_Bezel_Packs/’

OBS: I won’t demand a new folder to install these packs. They were made to work with MegaBezel at its MegaBezelPack folder, so, my presets will just point to them to save space.


Screenshots:


Credits to @Orionsangel for the permission to point the presets to his overlays.

Credits to @TreyM for the default background image: https://github.com/TreyM/classic-crt-collection/tree/master/CRT

Thanks to @hunterk for the image border and ambilight shader codes.

Thanks to @HyperspaceMadness and @kokoko3k for their awesome shaders that inspired me to work on this one.

And, since the beginning, thanks to cgwg, maister and DOLLS for the original curvature code.

And to all libretro shader coders, of course!


Feedbacks are welcomed!

8 Likes

Very nice Hyllian!

Lately I was wondering if I could strip down mine from some bloat or made specific lighter versions, but I guess we’re covered there now!

If you have time, please, take a look to mine Ambilight code, I think it is very light, so you can include it as well :wink:

Another quick tip for grainy look on the reflections, the same HSM gave me, is to displace reflections sampling coords via pseudo-random numbers.

2 Likes

Yes, it’s very lightweight not only to run. It loads very instantaneously.

I surely will look into your ambilight code. I just didn’t have the time to concentrate on it, because I was fixing bugs on this first release. :stuck_out_tongue:

I’ll just not add any feature that deviates from the main objectives: simple and fast shaders. (I measure it by looking at my GPU temperature, if it’s below 63º C, then it’s ok.)

For a full-featured bezel/overlay shaders, I recommend using yours or Mega Bezel.

2 Likes

I agree, keep it lean and mean, especially for the folks who want reflections and borders/overlays/bezels. Anything else, you can probably create additional shaders or versions for those like the way we have multiple variations of CRT-Guest-Advanced.

Great job, I asked the universe for this and you answered!

Screenshots are looking really good!

How would I go about integrating this with my existing Sony Megatron Presets? I tried prepending the uborder-reflections.slangp but that already includes scanlines and Sony Megatron already includes scanlines so everything looked weird and ran slowly. Also, Sony Megatron applied scanlines and mask to the whole screen, including the overlay.

1 Like

IT’s not that easy as you may think. The only crt shaders compatible for now are the ones I provided: crt-nobody and crt-geom, because they’re single pass (easy to work with). Each one I had to make some changes for them to work with the framework.

Sony Megatron is a multipass shader, so it’s much more complex to tweak it to work and achieve what you want. For now I only converted single pass crt shaders.

I’m not saying it’ impossible, though. It’s just not plug’nplay.

When I mentioned the prepend option, it was for shaders that work to prepare the input for another shader (the crt shader). So, you can easily prepend ntsc or dithering shaders. CRT Shaders aren’t these types of shaders.

1 Like

I have good and bad news for you!

Firstly the good: I got Sony Megatron working. The bad news: no NTSC presets yet, and looks like this crt isn’t very good at small screens, because it is plagued by moiré if you curve the screen, so, it’s recommended only for higher resolutions, which means at least windows of 1080 vertical resolutions. The default jpg isn’t suitable for it, you need to use another background with a big window. Other than that, it isn’t good for non-integer scalings too, so, beware of it.

Here you can grab it: uborder-v0.1-special edition with partial sony megatron support

Screenshot of “crt-sony-megatron-viewsonic-A90f±sdr.slangp” on my small 1080p monitor (see the moiré):

You can load the presets inside 'base_presets/hdr/" directly. Or you can load the main uborder-reflections preset. I didn’t create presets for ambilight or uborder only, though.

1 Like

Great job!

I give it a try and is super fast!

I think this will be very useful for a lot of people/rigs!

Also the sharder choice is nice, no moire to be noticed and with just prepending ntsc adaptive it can be a very viable choice!

:+1:

3 Likes

Nice usage of spooky tv. Which game is that?

I put that to play some survival horrors. If you turn the lights out, it gives the perfect feeling. I have some other weird tv backgrounds here, it’s fun to use with the right games.

2 Likes

Splatterhouse - Wanpaku Graffiti for Famicom, is a SD version of splatterhouse!

Yeah, spooky tv looks very nice!

2 Likes

I don’t intend to go any further in this Sony Megatron stuff, to tell the truth. I made that because I thought you were trying to achieve something with it and I could help. That’s just some side work of this and won’t be integrated in the main line, because,well, the objective here is to keep it simple and fast. Nothing against it, though. Sony Megatron is a great shader if you have the right hardware with hdr, but I don’t see how it’s necessary for this project.

1 Like

Hyllian delivering as usual! I never thought those reflection shaders could be made fast, but here we are again. I tested the presets for about an hour and, so far, they’re great. I don’t have the optionals, since I don’t use them, so I couldn’t test everything, but the essential parts are working and they’re working good. Feedback is always hard with your shaders, as you tend to get things polished from the get-go, so I will need to test it further to see if I can find something that needs improvement.

Anyway, as an initial suggestion, I could only think of:

  1. You could add a night preset of your own, to pair it with default uborder.
  2. Perhaps the viewport for uborder is a bit small. While it’s expected for this kind of shader to not have a full vertical viewport, it could be somewhat larger, just like the ambient-light-crt variant, which has a pleasant size.

Once again, I congratulate you for your continuous hard work and achievements.

3 Likes

It’s easier to integrate than Mega Bezel or Koko-aio, but not plug n’play as you expect. It needs some carefull coding to port another crt inside it. And some crt shaders do not ‘like’ curvature code.

As I said, it isn’t a good fit because its masks are very strong and produce moiré easily, being very visible at small resolutions. And without curvature you can only use it with flat tv backgrounds. Besides, it needs higher resolutions to work at non integer scalings. So, it isn’t a good fit for this project if it has so many conditions to work properly.

I didn’t even try to port the ntsc, because the short time, but it can be done. Your presets wouldn’t be of help in this case because they’re just pointing to Sony Megatron, they’re not part of it. I can try to port the ntsc IF you intend to use, but I won’t integrate to the main line for the reasons I explained.

I got all that aren’t ntsc. Try loading the ones inside ‘base-presets/hdr’ I provided to you in that zip. They all work, except the ones with ntsc.

An easier way to use ntsc is just using the presets in the zip I provided to you , load a working preset and prepend ntsc-adaptive.

It can’t, without some massive work inside Sony Megatron code. Something I won’t do, because not my priority.

Anyway, let’s get back to the focus of this thread. I won’t be working to improve other crt shaders. I only port they as they are now. If they fit, ok, if don’t, I’ll just try another.

It’s a good suggestion and can be done in a number of ways: dynamic background, static (multiple backgrounds), multiple presets or just a preset param. I’ll have to think further about it.

Indeed. Though I would have to find an alternative for the default background. I’m not an artist and don’t have the skills to create an image of my own. And, it’s not an easy task to find a background that fit and is free to use in the Internet. So I accept contributions from artists in this regard.

1 Like

@Hyllian Is it possible to get img_mod.slangp to work with this shader?

I tried it and it failed to load. It would add a little polish to the pixels and allow me to fine crop, add some noise and more.

As it has curvature code inside it, it’s necessary some coding to make it work without conflicting with uborder curvature one. I’ll put your suggestion in the TODO list.

1 Like

Thanks, not sure if this would make a difference but I use a customized version which only contains, the cropping (Overscan Mask), film grain, rounded corners and gamma correction, I think.

#version 450

//   Modular Image Adjustment
//   Author: hunterk
//   License: Public domain

layout(push_constant) uniform Push
{
	vec4 SourceSize;
	uint FrameCount;
	vec4 OutputSize;
} registers;

layout(std140, set = 0, binding = 0) uniform UBO
{
   mat4 MVP;
#include "../../include/img/param_floats.h"
} global;

#include "../../include/img/helper_macros.h"

/////////////////////////////// INCLUDES ////////////////////////////////
// comment the #include and corresponding line to remove functionality //
/////////////////////////////////////////////////////////////////////////

// Flip image vertically or horizontally
// #include "../../include/img/image_flip.h"

// Stretching, Zooming, Panning
// #include "../../include/img/stretch_zoom_pan.h"

// Film grain effect
#include "../../include/img/film_grain.h"

// Sharp, antialiased pixels; use with linear filtering
// #include "../../include/img/sharpening.h"

// Saturation and Luminance
//#include "../../include/img/sat_lum.h"
// #include "../../include/img/lum_chrom.h"

// Gamma correction
// exp_gamma is basic pow function 
//#include "../../include/img/exp_gamma.h"
#include "../../include/img/gamma_srgb.h"

// Mask edges to hide unsightly garbage
#include "../../include/img/border_mask.h"

// Change the whitepoint to warmer/cooler
// #include "../../include/img/white_point.h"

// Add a phosphor mask effect onto the image
// #include "../../include/img/subpx_masks.h"

// Force integer scaling and custom aspect ratio
//#include "../../include/img/int_ar.h"

// Vignette; Darkens image around edges
//#include "../../include/img/vignette.h"


// Black level
// uncomment only one of the next 2 lines to set black level method
//#include "../../include/img/black_lvl.h"
// #include "../../include/img/black_lvl_dogway.h"

// Brightness and Contrast control
// uncomment only one of the next 2 lines to set contract complexity;
// sigmoidal_con is advanced, bright_con is basic
// #include "../../include/img/sigmoidal_con.h"
//#include "../../include/img/bright_con.h"

// Adjust color balance and tint
// uncomment only one of the next 2 lines to set color channel complexity;
// color mangler is advanced, channel mixer is basic
//#include "../../include/img/col_mangler.h"
// #include "../../include/img/channel_mix.h"

// 2D screen curvature
//#include "../../include/img/gristle_warp.h"
//#include "../../include/img/lottes_warp.h"
// #include "../../include/img/cgwg_warp.h"

// Rounded corners
#include "../../include/img/corner.h"

////////////////////////////// END INCLUDES //////////////////////////////

#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;

void main()
{ 
   vec4 pos = Position;
   
// apply axis flip
//   pos = flip_pos(pos);
   
   gl_Position = global.MVP * pos;
   
   vec2 coord = TexCoord.st;
   
// apply crop/zoom/pan
//   coord = crop_zoom_pan(TexCoord);
   
// apply integer scaling and aspect ratio
//   coord = int_ar(coord, registers.SourceSize, registers.OutputSize);
   
   vTexCoord = coord;
}

#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;

//////////////////////////////// LUTS ///////////////////////////////////
// Use either 1 or 2 color-grading LUTs
// uncomment only one of the next 2 lines
//#include "../../include/img/lut1.h"
//#include "../../include/img/lut2.h"
////////////////////////////// END LUTS /////////////////////////////////

void main()
{
// declare texture coordinates
   vec2 coord = vTexCoord.xy;
   
// apply sharpening to coords
//   coord = sharp(vTexCoord, registers.SourceSize);
   
// apply screen curvature
//   coord = warp(coord);

// sample the texture   
   vec3 res = texture(Source, coord).rgb;

// apply grain (expects to run in gamma space)
   res = luma_grain(res, vTexCoord.xy, ia_GRAIN_STR, registers.FrameCount);
// res = rgb_grain(res, vTexCoord.xy, ia_GRAIN_STR, registers.FrameCount);

// saturation and luminance (expects to run in gamma space)
//   res = sat_lum(res);
   
// contrast
//   res = cntrst(res);
   
// apply first gamma transform (linearize)
// (whether LUT or gamma should come first depends on LUT)
   res = gamma_in(res);
   
// apply LUT1
//   res = lut1(res);

// apply white point adjustment
//   res = white_point(res);

// black level
//   res = black_level(res);
   
// channel mix
//   res = channel_mix(res);
   
// overscan mask
   res = border_mask(res, coord.xy);
   
// apply LUT2 (whether LUT or gamma should come first depends on LUT)
//   res = lut2(res);
   
// apply gamma curve
   res = gamma_out(res);

// apply mask effect
//   res *= mask_weights(gl_FragCoord.xy, mask_strength, mask);
   
// apply vignette effect
//   res = vignette(res, vTexCoord.xy);
   
// apply rounded corners
   res *= corner(coord);
    
   FragColor = vec4(res, 1.0);
}

Ah! But the Mega Bezel can keep you and your GPU warm at night!

Nice Stuff @Hyllian!!!

4 Likes

There is also this project by @Duimon that is very easy to use with Uborder, lots of nice overlays to add variety!

I used this parameters with the uborder-reflections.slangp if anybody is interested

ub_border_top = "1.000000"
box_scale = "3.680000"
in_res_x = "325.000000"
in_res_y = "244.000000"
geom_center_x = "-0.000000"
geom_center_y = "0.002000"
geom_curvature = "1.000000"
geom_R = "2.000000"
geom_d = "1.600000"
geom_cornersize = "0.011000"
geom_cornersmooth = "280.000000"
CN_SCAN_SIZE = "0.800000"
CN_BRIGHTBOOST = "1.080000"
CN_VIG_TOGGLE = "1.000000"
CN_VIG_BASE = "26.000000"
CN_VIG_EXP = "0.140000"
frame_w = "0.626001"
frame_h = "0.825001"
bezel_w = "0.024000"
bezel_h = "0.038000"
reflection_strength = "0.240000"
bezel_center_y = "-0.001000"

BORDER = "path/to/the/overlay.png"

two example

4 Likes

Very nice finding! You’ve got the spirit of this project! It’s very easy to point to other overlay packs and adjust the frame to the window, as well as the reflection bars to the bezels. I intend to release separate packs of some real and weird tvs along their presets.

2 Likes

img_mod shader/components are meant to be modular. The shader itself is really just meant to be an example of how someone could pull in the various included functions and apply them, so if there are a few functions someone likes, they’re easy to pull into any other shader rather than using the actual img_mod shader.

2 Likes