Converting MiSTer FPGA Composite Blending shader to GLSL

If it’s just the presets, yeah, that should be pretty straightforward to include. If it needed modifications to the lib, that would take some more due diligence.

I think we can move on this pretty quickly. If anyone wants to put in a PR for it, go for it. Otherwise, I’ll get one going later on.

3 Likes

You can go right ahead. How can I go about doing a PR though? Maybe this can be one of my first pull requests and additions to my so far unused GitHub Repo?

You fork the original libretro repo to your own account, make your changes locally, make a commit and push it up to your repo, then go to the ‘pull requests’ tab and make one against the parent repo (it chooses it automatically by default). Once submitted, we can check it out and review it and if everything looks good, we merge it into the main codebase.

3 Likes

Thanks a lot. I’ll try this over the next couple days. If I don’t get through, you can go ahead and add it.

One thing I noticed is that the built-in Genesis Composite Filter creates a rainbow effect but mine don’t, but they do de-dither and they do it cleanly. I use them in conjunction with presets with sharpness cranked to the highest point before unwanted artifacts.

I have those in my pack but users can also crank sharpness up in presets of their own and de-dithering will still work.

Update:

@hunterk Just created my first PR!

Do you need any additional information?

2 Likes

The two genesis filters in your pack both do de-dithering. Even the s-video one. I’m glad it does because the picture is cleaner than the composite one but also merges the dithering.

The built in s-video filter looks good but doesn’t completely merge the dithering, just slightly.

I imagine on the real machine the built in s-video filter is more accurate? Did s-video merge dithering as such?

Again, even if it’s not accurate, it would be better to rename it as “composite HQ” or something instead of fixing it. This is the best de-dithering filter i used so far.

2 Likes

I really don’t know. As a child I didn’t even notice things like the transparency on the waterfalls and I’ve never seen a Genesis with S-Video out.

I like the name as it is though. The terms Composite, S-Video and RGB are all relative here and my system is that consoles have their own characteristics and modules so that in the context of Genesis, which supposedly had degraded outputs compared to other systems (at least composite) this would be S-Video.

In the filter this is simply a resolution range with many possibilities in between the default Composite, S-Video and RGB settings.

So let’s pretend it’s S-Video for now. If users want “accurate” naming they can use the built-in filters.

I think 2 “Composite” presets for one system might be a bit confusing and messy.

Instead, my naming system is that Composite is lowest resolution, S-Video is higher than Composite resolution and RGB is higher than S-Video resolution.

I prefer things to be a bit more fun, casual, “dummy” friendly, commercial, marketing style than technical, nerdy and super precise so that even a caveman or baby can understand.

Users can also rename it internally to whatever is more meaningful to them.

I also wouldn’t want the naming to be out of sync with my internal development and naming.

I’m really glad you like it. You have to thank @Juandiegous who’s work showed me that it was possible to edit the filter presets.

You mentioned renaming as an alternative to fixing. I offer these presets simply as a way for others to enjoy what I experience, so there isn’t anything to fix because S-Video can de-dither better than the built-in. This is just the CyberLab experience at this point in time that more users can now experience for themselves without having to download my preset pack. That’s also why they’re called “CyberLab_Special-Edition”.

My unique twist on the way I do things is what makes them special.

1 Like

The real machine doesn’t have s-video without a mod. You can watch a video here, s-video makes it way cleaner.

3 Likes

@hunterk Is it possible to add 50% vertical blend to this shader? I always wanted simple and fast blur shader. I may as well use this one for that purpose.

// 50% horizontal blend; quick and dirty gamma correction
// by hunterk
// license: public domain

#if defined(VERTEX)

#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying 
#define COMPAT_ATTRIBUTE attribute 
#define COMPAT_TEXTURE texture2D
#endif

#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 TEX0;

uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;

// compatibility #defines
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

void main()
{
   gl_Position = MVPMatrix * VertexCoord;
   TEX0.xy = TexCoord.xy;
   TEX0.zw = TexCoord.xy - vec2(SourceSize.z, 0.);
}

#elif defined(FRAGMENT)

#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif

uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;

// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy

#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

void main()
{
   vec3 curr_px = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
   vec3 prev_px = COMPAT_TEXTURE(Source, TEX0.zw).rgb;

   curr_px *= curr_px;
   prev_px *= prev_px;

   FragColor = vec4(sqrt((curr_px + prev_px) / 2.), 1.0);
} 
#endif

Sure, that’s possible, but I think you’re better off using the 3x3 blur from the ‘blurs’ directory.

3x3 is not available in GLSL. Also tried .slang version on pc and it doesnt blend genesis dithering unlike the one you converted.

Greetings @hunterk,

Were you able to merge my pull request with the main repo or is it still under review? I’m asking because this is my first pull request and I just want to know if I did everything correctly.

This morning I opened GitHub Desktop and they said I was a few changes behind the main so I clicked the fetch (i think) and then it seemed to have said that I made another Commit.

Looks like it’s still under review. I’ll see if I can get some eyes on it.

You won’t need to fetch upstream unless there’s a conflict in the PR, which isn’t likely to happen, since you’re just adding new files. The conflicts occur when someone commits changes to a file you’re trying to change, as well.

1 Like

Okay great, thanks!

Thanks, I just click fetch becuase I like to keep things up to date. Lol. I guess that commit they were referring to was the commit from the Git Desktop that was made to my clone repo?

I was also thinking that if I had to update my presets in the future that I might have to first fetch in order to be up to date. So it’s more about me trying to understand and get my head around how GitHub works.

yes, you’ll have to update it to make future PRs, but each time you make a commit while it’s waiting to be merged, you add a new commit to the log, which gets messy and is best avoided unless you actually need to do it (e.g., due to a conflict).

1 Like

doing it in 2 dimensions gets a little tricky, as you have to decide how much each texel contributes to the final image. That is, do you average one vertical texel with one horizontal texel? or do you average each of them with the center texel and then average those averages? etc.

Each option looks quite different, but I think I understand what you’re wanting out of it, and this seems to be the best option:

// 50% vertical and horizontal blend; quick and dirty gamma correction
// by hunterk
// license: public domain

#if defined(VERTEX)

#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying 
#define COMPAT_ATTRIBUTE attribute 
#define COMPAT_TEXTURE texture2D
#endif

#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 TEX0;

uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;

// compatibility #defines
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

void main()
{
   gl_Position = MVPMatrix * VertexCoord;
   TEX0.xy = TexCoord.xy;
   TEX0.zw = TexCoord.xy - vec2(SourceSize.z, SourceSize.w);
}

#elif defined(FRAGMENT)

#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif

#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif

uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;

// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy

#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)

void main()
{
   vec3 curr_px = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
   vec3 left_px = COMPAT_TEXTURE(Source, TEX0.xy - vec2(SourceSize.z, 0.)).rgb;
   vec3 down_px = COMPAT_TEXTURE(Source, TEX0.xy - vec2(0., SourceSize.w)).rgb;
   vec3 right_px = COMPAT_TEXTURE(Source, TEX0.xy + vec2(SourceSize.z, 0.)).rgb;
   vec3 up_px = COMPAT_TEXTURE(Source, TEX0.xy + vec2(0., SourceSize.w)).rgb;

   curr_px *= curr_px;
   left_px *= left_px;
   down_px *= down_px;
   right_px *= right_px;
   up_px *= up_px;

   vec3 vert_blend1 = (curr_px + down_px) / 2.;
   vec3 vert_blend2 = (curr_px + up_px) / 2.;
   vec3 horz_blend1 = (curr_px + left_px) / 2.;
   vec3 horz_blend2 = (curr_px + right_px) / 2.;

   FragColor = vec4(sqrt((vert_blend1+vert_blend2+horz_blend1+horz_blend2) / 4.), 1.0);
} 
#endif
3 Likes

Thank you! I think I understand your code good enough to experiment with different blending options.

2 Likes

@hunterk

I just downloaded the latest Nightly and I see that my video filter presets have been renamed and “CyberLab” removed from the filenames. Why would someone try to divorce me from my work like this?

My filter presets go hand in hand with my shader presets so shader presets go together with filter presets matching their names.

I find this a bit insulting as a creator especially since no one asked me if it was okay to do so or how I would have felt beforehand.

In addition to that some of the names were butchered in such a way so as to omit the primary console they were designed for and tested on.

These presets were designed to simulate differences in outputs of various consoles and to omit the name of the console that it was designed to simulate is a disgrace.

This work I do here, while its not commercial, at least at this time, is my legacy and a reflection of my style. My name should be on my work if I named it that way.

Blargg’s name is there

Hyllian’s name is there

Guest’s name is there

HSM’s name is there

Lottes’s name is there

Why do something to take away and hurt someone who has only tried to share, to contribute and to give?

Revert this change and proceed to consultation before any renaming is done please. I deserve that respect.

Either that or I’ll have to ask you to remove my presets and return things to status quo.

The name changes weren’t intended as a slight, just bringing them in-line with the rest of the RetroArch codebase.

The shaders are different from RetroArch itself. We don’t typically put people’s names on files in RetroArch, or else we’d end up with a bunch of files named ‘maister-super-duper-vulkan-driver.c’ etc. (the only reason the shaders have them is because there needs to be some way to differentiate among 10x different NTSC implementations that are functionally identical; you’ll notice maister’s NTSC doesn’t have a name attached at all, since it was the first and was functionally unique at the time; ditto for crt-geom).

We can put your name into a comment at the top of the file, though, which is typically where those credits go.

As for the naming of the files, Tatsuya (who modified the NTSC library to allow modifying those settings in the first place) rightly pointed out that they’re using the SNES flavor of the NTSC filter, while blargg has other flavors of the filter designed to reproduce various characteristics of those consoles’ signals, so it’s technically inaccurate/misleading to say that one of them is, for example, the Genesis/MD flavor when that’s a different library altogether.

As for consulting on future changes, that’s unfortunately just a part of open source contributions: you give up a measure of control to be a part of something bigger. I vouched for you to get your contributions merged in the first place, but if you’d like to remove them, you can send a PR to do so.

1 Like

I understand and appreciate that.

Okay, that’s understandable.

Well this would be an honour and greatly appreciated.

I understand. My naming really connects the filters with shader presets in my preset pack that should be used with them to achieve certain effects/looks so the naming is not an attempt to be inaccurate/misleading in any way nor to rebrand the purpose of the filter. Just using whatever tools are available to achieve an end. If I had a Genesis or PCE dll, I might have used those but I made the SNES work for my purposes and it worked well enough.

The other issue I had with the naming was that PCE was left out of the naming for 2 out of 3 presets while that was the system they were designed to be used with in the first place. This is something that I’ve been working on for a number of years due to the fact that Beetle/Mednafen never came with Blargg NTSC filters. In the past I had tried the SNES ones but they were always too dark or just looked weird.

Can the PCE be added to the “Blargg_NTSC_SNES_Custom_pseudo_PSX_SNES_Composite.filt” and “Blargg_NTSC_SNES_Custom_pseudo_PSX_SNES_RGB.filt” please because those filter presets were designed, customized and tested for that console?

So the naming would be consistent with “Blargg_NTSC_SNES_Custom_pseudo_PCE_PSX_SNES_S-Video.filt”.

Okay, well I guess this is just due to me being new to this aspect of things and the way things work. I’m sure to learn as time goes by. Thanks for vouching for me. I appreciate the honour.

There’s no need to remove them. At the end of the day, I understand and accept that there must be some compromise.

Thanks again!

1 Like

I think adding PCE to the name should be very doable, and I’ll make sure we get your credits in the file, too. Thanks for your understanding.

2 Likes