Uborder shaders

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!!!

6 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

6 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.

3 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

@Hyllian Another good feature to have would be if we could force Integer Scaling (possibly even Smart Integer Scaling) and independent X and Y integer scaling on the viewport.

It would definitely help with the moire patterns and uneven scanlines.

You already have that control. The FRAME params allow you to define integer resolutions: Image Scale, Viewport Size X and Viewport Size Y.

The only problem of using integers is that they will only work if the background is made for them. Most of the time you’ll need non-integer to fill the gaps. That’s why I’m using crt-nobody and crt-geom, because they’re very good at non-integer scalings.

2 Likes

I am having no luck downloading the shader. :frowning_face:

I get a security/permissions error.

1 Like

I’ll put on github soon. That first version was to see if other users could run without bugs. I’m doing a major change in folder organization before going to github, so it’s better to wait. I’ll upload just a vanilla version inside bezel folder (as I think it has similar features with koko-aio and mega bezel). All extra presets, shaders, textures will be in separated packs, so that RA main shaders_slang isn’t overloaded.

The vanilla version is already on RA repo: https://github.com/libretro/slang-shaders/tree/master/bezel/uborder

Vanilla, content_shaders_pack and borders_pack are here (Someone else’s borders aren’t available here, just presets that point to them): https://github.com/Hyllian/uborder/releases

First post updated.

5 Likes

Just updated slang shaders and playing around with the shader everything seems to work!

Noob question, I’m going to do some presets system specific, trying to keep integer scaling: for example tryng famicom I set:

box_scale = "4.000000"
in_res_x = "300.000000"
in_res_y = "224.000000"

Is it correct? (looks like it is :nerd_face:) I just want to start with the right foot!

3 Likes

That overlay is gorgeous!

It probably is (vertical is more important than horizontal for crt shaders), but if your game change res dynamically, I can’t assure integer scaling. I can assure the frame window will always be the same size.

2 Likes

Yeah that’s fine I think, does not have to be all the time IS, but probably, in the case of famicom/nes, there wont be so many cases of resolution changes, I guess…

2 Likes

Integer scaling + curvature? You’d need to bend the real panel :slight_smile:

2 Likes

ahah! :nerd_face:

yeah, you are right, but trying to keep the scanlines as even as possible will help a little with limiting side effects I think…

also, duimon’s overlays fits just right with 224 (x4)!

2 Likes

What are the recommended specifications for the background texture in terms of window/viewport size and location so that it easily lines up with the existing default presets?

Is there any advantage to the cutout being coloured, a void or alpha-transparency?

I notice that .jpgs are being used instead of .pngs so I guess this means transparency isn’t used at all?

1 Like

If you use the reflections preset, for now, you need the frame spot on your background to be frontal and isometric, which means a rectangle (or slightly curved), not rotated.

If you don’t use the reflections, you can use some slightly bended background. Like this one I just got on Internet:

Then, I renamed the BORDER inside the main uborder.slangp preset to point to this one and RA presented this:

In some 5 minutes, using the user params for frame and curvature, I’ve got this:

Obviously, it’s just for fun and to show you how you can bend the screen to fit some space.

If you plan to make something for gaming, you should increase the game frame to use most of the available 4:3 space in your screen. I think you can use the examples by Duimon and Orionsangel as your ideal backgorund organization.

Ok. Both of them are supported. You can put the frame in front of the background so that you can use a tiny jpg or you can put the frame behind the background and use a transparent png. The last is more believable, though harder to make and you need a bigger file. The former is easier, because you don’t need to tweak alpha and you get small files. Though the result is less believable.

1 Like

I’m not saying the moiré is caused by the crt shader alone. It’s caused by the whole thing combined. Sony Megatron uses strong masks (it’s compared to other masks at strength = 1.0), which is very strong. Besides that, my screenshot was too small to fit strong masks.

1 Like

I agree. I’ve now realized that I wasn’t seeing what I thought I was seeing. I originally zoomed in an viewed on my phone and the phosphors appeared like a Slot Mask pattern and seemed like they were skewed.

I just downloaded the image and zoomed in on my PC and it’s clearly a Shadow (Dot) Mask being used, therefore the anomalies are not in line with what I originally thought they were.

I’ve deleted the irrelevant post to keep things sanitary.

Lots to learn about this new beast. :wink:

Does the reflection not follow the screen curvature?

1 Like

Not yet, I intend to improve it. It was the last feature I got working, so it’s still in its infancy. I recommend using low reflection strength of up to 0.25 to give the illusion of accuracy. (you have to keep in mind that this shader is still kind of a showy potato megabezel. :stuck_out_tongue: )

For now there’s a small trick to “bend” the reflection bars: as they are transparent to the game frame, you can push the reflection bar to overlap the frame a bit so that the reflection bar appear to curve behind the frame. Then use the ‘reflection X and Y distance’ user params to adjust where the reflection start inside the reflection bars. On well done backgrounds as yours, it’s easy to do that.

I’ve seen other shader solutions is to create their own bezel to better control reflection spots. Looks like I’ve taken the hard path. :face_with_hand_over_mouth:

1 Like