Please show off what crt shaders can do!

I’d love a glsl version of that, as I’m currently using guests whitepoint shader for this.

Alright, I edited the post with a GLSL version.

1 Like

@Syh @Nesguy - not only green, but any tones and gammas that you feel need corrections. I’m using crt images as reference. For example, in Sonic 2, the excessive yellows were fixed with green to blue, the too dark blues were mostly fixed (interestingly!) with a similar amount of blue to green, and the clipping whites (notice how the detail in the clouds was recovered?) were mostly fixed with adjustments to red gamma. It would of course be a pita to do this for every individual game, but I think that in time I could find some per channel color corrections that would work well in general, and deliver those “crt tones” I’m after.

@hunterk - this new shader sounds great, I will try it as soon as I get home. Also, seeing how easy it was for you to implement per channel gamma control, could you do the same with per channel saturation? That will complete your color mangler!

1 Like

Sure:

/*
   Color Mangler
   Author: hunterk
   License: Public domain
*/

#pragma parameter gamma_boost_r "Gamma Mod Red Channel" 0.0 -5.0 5.0 0.1
#pragma parameter gamma_boost_g "Gamma Mod Green Channel" 0.0 -5.0 5.0 0.1
#pragma parameter gamma_boost_b "Gamma Mod Blue Channel" 0.0 -5.0 5.0 0.1
#pragma parameter sat_r "Red Channel Saturation" 1.0 0.0 3.0 0.01
#pragma parameter sat_g "Green Channel Saturation" 1.0 0.0 3.0 0.01
#pragma parameter sat_b "Blue Channel Saturation" 1.0 0.0 3.0 0.01
#pragma parameter lum "Luminance" 1.0 0.0 5.0 0.01
#pragma parameter cntrst "Contrast" 1.0 0.0 2.0 0.01
#pragma parameter r "Red" 1.0 0.0 2.0 0.01
#pragma parameter g "Green" 1.0 0.0 2.0 0.01
#pragma parameter b "Blue" 1.0 0.0 2.0 0.01
#pragma parameter rg "Red-Green Tint" 0.0 0.0 1.0 0.005
#pragma parameter rb "Red-Blue Tint" 0.0 0.0 1.0 0.005
#pragma parameter gr "Green-Red Tint" 0.0 0.0 1.0 0.005
#pragma parameter gb "Green-Blue Tint" 0.0 0.0 1.0 0.005
#pragma parameter br "Blue-Red Tint" 0.0 0.0 1.0 0.005
#pragma parameter bg "Blue-Green Tint" 0.0 0.0 1.0 0.005
#pragma parameter blr "Black-Red Tint" 0.0 0.0 1.0 0.005
#pragma parameter blg "Black-Green Tint" 0.0 0.0 1.0 0.005
#pragma parameter blb "Black-Blue Tint" 0.0 0.0 1.0 0.005

#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 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
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;
}

#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)

#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float gamma_boost_r, gamma_boost_g, gamma_boost_b, sat, lum, cntrst, blr, blg, blb, r, g, b, rg, rb, gr, gb, br, bg, sat_r, sat_g, sat_b;
#else
#define gamma_boost_r 0.0
#define gamma_boost_g 0.0
#define gamma_boost_b 0.0
#define sat 1.0
#define lum 1.0
#define cntrst 1.0
#define blr 0.0
#define blg 0.0
#define blb 0.0
#define r 1.0
#define g 1.0
#define b 1.0
#define rg 0.0
#define rb 0.0
#define gr 0.0
#define gb 0.0
#define br 0.0
#define bg 0.0
#define sat_r 1.0
#define sat_g 1.0
#define sat_b 1.0
#endif

void main()
{
   vec4 screen = pow(COMPAT_TEXTURE(Source, vTexCoord), vec4(2.2)).rgba;
   vec4 avglum = vec4(0.5);
   screen = mix(screen, avglum, (1.0 - cntrst));

                   //  r    g    b  alpha ; alpha does nothing for our purposes
   mat4 color = mat4(  r,  rg,  rb, 0.0,  //red tint
                      gr,   g,  gb, 0.0,  //green tint
                      br,  bg,   b, 0.0,  //blue tint
                     blr, blg, blb, 0.0); //black tint

   mat4 adjust = mat4((1.0 - sat_r) * 0.2126 + sat_r, (1.0 - sat_r) * 0.2126, (1.0 - sat_r) * 0.2126, 1.0,
                      (1.0 - sat_g) * 0.7152, (1.0 - sat_g) * 0.7152 + sat_g, (1.0 - sat_g) * 0.7152, 1.0,
                      (1.0 - sat_b) * 0.0722, (1.0 - sat_b) * 0.0722, (1.0 - sat_b) * 0.0722 + sat_b, 1.0,
                      0.0, 0.0, 0.0, 1.0);
   color *= adjust;
   screen = clamp(screen * lum, 0.0, 1.0);
   screen = color * screen;
	vec3 out_gamma = vec3(1.) / (vec3(2.2) - vec3(gamma_boost_r, gamma_boost_g, gamma_boost_b));
	FragColor = pow(screen, vec4(out_gamma, 1.0));
}
#endif
4 Likes

I’ll be adding this in the official version, np. The preset will probably be in the “crt/shaders/guest/” folder and once loaded and altered, it can be saved anywhere. Just a question. Will a hybrid version do? Same shaders are used for the 256 and 320 preset, first scales up to 1024, latter to 1280 or 4x the basic resolution. I just used 4x, so it will be 1024 for 256x content and 1280 for x320 content. It looks fine for LCD’s with me.

1 Like

So you altered the gb, bg, and gamma_boost_r settings?

@hunterk should I run your white temperature shader before color-mangler or after?

I don’t suppose it matters. I guess the order might come into play with regards to clipping, but I’m not sure.

1 Like

My assumption would be to first do color-mangler then white temperature.

I don’t know how to answer this technical part, unfortunately…

When do you pretend to release the official version?

I already thank you for your work!

:clap:t2:

We are currently working on crt color profiles. Once it gets finished, i think the new version will be ready in a couple of days.

4 Likes

Could you elaborate on the crt color profiles for your shader?

2 Likes

It’s a couple of CRT color presets, Sony trinitron, Philips TVL…maybe a cooler 9300K preset. I wrote a simple color altering shader which helps a bit to match the colors to a real CRT. It’s has to be done by hand and using a human eye :grin: so it’s kind of limited to a few of owned crt models.

7 Likes

Would torridgristle’s LUTs help any as reference for CRT’s you don’t own?

This sounds awesome by the way.

2 Likes

I’ll leave this to Dr. Venom, but torridgristle has some nice LUTs indeed. Probably a matrix/LUT combo will be implemented.

3 Likes

@guest.r @hunterk - you guys rock. I’m really happy about all the new developments regarding color!

5 Likes

I’m in the process of converting my 2D and 3D presets to @guest.r latest CRT shader posted on the other forum (been at it for the last 1 month or so! :sweat_smile:) . The latest shader has the ability to use LUT colour profiles, combined with one of the LUT images @torridgristle created I’ve got a decent scanline effect and rich colours that work really well for my setup. I really like the parameters @guest.r shader offers and the way it handles scanlines/masks over bright white areas.

7 Likes

This… BLEW MY MIND. When I was playing with LUTs I found myself so incredibly and inexplicably focused on the yellow-green areas as this ‘problem’ zone of sorts. I mean, I have my own theories about the human eye and that part of the color spectrum… but to have a possible technical/artistic explanation… mind explosion

1 Like

@SkyHighGam3r - haha well I don’t know if it’s correct, but it’s a hunch that I’ve had for quite a while, and all these tests kind of confirm it, at least perceptually. Shifting green to blue AND blue to green results in really nice, “cathodic” tones indeed!

Also, thumbs up to @hunterk new white point shader; I believe I will still be color mangling things in the future, since that gives me more control and I can manage all three channels independently from one another, but it works like a charm.

And does anyone know of a good website for good quality crt captures from games that I can use as reference? They are not particularly easy to come by.

1 Like

neo-geo.com forums and various arcade forums are good options, as well as r/crtgaming on reddit.

1 Like

Example of some of the threads:

3 Likes