Please show off what crt shaders can do!

Were you able to download the Zomb pack? I get told the file is unavailable :frowning:

1 Like

Make sure you have a account on the launchbox forums and be signed in, then you should be able to download it.

That was my issue.

@Dogway I think that having the vignette in color_mangler washes out blacks when the vignette is visible.

Also, saturation is separated in rgb in code but the user settings is only a single channel, so the shader fails to load. I got it working, though

Yes sorry, it wasn’t meant for sharing, it was a personal attempt to fit it into crt-royale (along gadapt, white_point, etc). I went ahead and made it stand alone so it can be placed before or after color mangler. If hunterk wants to make some fixes and/or port it to slang it would be very welcome.

/*
   Vignette
   License: Public domain
*/

#pragma parameter vignette "Vignette Toggle" 1.0 0.0 1.0 1.0
#pragma parameter inner "Inner Ring" 0.25 0.0 1.0 0.01
#pragma parameter outer "Outer Ring" 0.60 0.0 1.0 0.01


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

vec4 _oPosition1; 
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;

void main()
{
   gl_Position = MVPMatrix * VertexCoord;
   TEX0.xy = TexCoord.xy;
}

#elif defined(FRAGMENT)

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

#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

struct output_dummy {
    vec4 _color;
};

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 vignette;
uniform COMPAT_PRECISION float inner;
uniform COMPAT_PRECISION float outer;
#else
#define vignette 1.0
#define inner 0.0
#define outer 1.0
#endif

void main()
{

    vec3 vcolor = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
// a simple calculation for the vignette effect
	vec2 mid = vec2(0.49999, 0.49999) * InputSize / TextureSize;
	vec2 middle = TEX0.xy - mid;
	float len = length(middle);
	float vig = smoothstep(inner, outer, len);

	vcolor *= (vignette > 0.5) ? (1.0 - vig) : 1.0; // Vignette

	FragColor = vec4(vcolor,1.0);
	
} 
#endif
2 Likes

Sorry I wasn’t trying to complain, I was wanting to let you know because if other people tried to use.

I ported libretro’s white_point shader to pcsx2 GSdx. I didn’t know it was going to work, but it did! I don’t know if it’s still in need for PS2 but I think games were still designed with CRT in mind?

https://pasteboard.co/IiEmkfp.png

https://pasteboard.co/IiEmq4J.png

4 Likes

After playing around with black frame insertion and shaders for a while, I became bothered by the moire-like patterns that I was seeing with scanlines. With BFI enabled and using 5x vertical scale, the scanlines never looked quite uniform, even though screenshots confirmed that the scanlines were pixel-perfect. After looking into this, I discovered that the problem is the inversion pattern used by the LCD’s subpixels, which is inevitable when using BFI. The solution to this problem is that you just have to use an even-numbered integer scale (2x, 4x, 6x, etc.) when using BFI if you want scanlines to look right.

At 4x scale using BFI, you can also get away with using the magenta-green mask from CRT-Easymode and CRT-Aperture. This winds up looking like the slotmask simulation from the dotmask shader, except at the level of the LCD’s subpixels. The image using CRT-Aperture at 4x scale with the mask enabled is very nice IMO, looking like a 400 - 500 TVL slotmask CRT using RGB.

(again, this is with BFI enabled and my backlight at 100%, so brightness and gamma look very different in person)

Here are the settings I used for these shots. I wound up increasing MASK_STRENGTH to 0.15 and GAMMA_INPUT to 2.70.

alias0 = ""
BRIGHTNESS = "1.750000"
filter_linear0 = "false"
float_framebuffer0 = "false"
GAMMA_INPUT = "2.600000"
GAMMA_OUTPUT = "2.400000"
GLOW_DIFFUSION = "0.050000"
GLOW_HALATION = "0.100000"
GLOW_HEIGHT = "0.500000"
GLOW_WIDTH = "0.500000"
MASK_COLORS = "2.000000"
MASK_SIZE = "1.000000"
MASK_STRENGTH = "0.100000"
mipmap_input0 = "false"
parameters = "SHARPNESS_IMAGE;SHARPNESS_EDGES;GLOW_WIDTH;GLOW_HEIGHT;GLOW_HALATION;GLOW_DIFFUSION;MASK_COLORS;MASK_STRENGTH;MASK_SIZE;SCANLINE_SIZE_MIN;SCANLINE_SIZE_MAX;SCANLINE_SHAPE;SCANLINE_OFFSET;GAMMA_INPUT;GAMMA_OUTPUT;BRIGHTNESS"
SCANLINE_OFFSET = "0.000000"
SCANLINE_SHAPE = "1.000000"
SCANLINE_SIZE_MAX = "1.500000"
SCANLINE_SIZE_MIN = "0.500000"
shader0 = "C:\Program Files\RetroArch\shaders\shaders_glsl\crt\shaders\crt-aperture.glsl"
shaders = "1"
SHARPNESS_EDGES = "2.000000"
SHARPNESS_IMAGE = "1.000000"
srgb_framebuffer0 = "false"
wrap_mode0 = "clamp_to_border"
3 Likes

Finally got a CRT curvature effect I like. I got a side-view photo of a disassembled CRT, loaded it into Blender as a reference image, made a heavily subdivided plane, used lattice with an expanded center to blow out the plane into a curve that matched the CRT’s curvature, rendered the UV values of the plane in an orthographic view, collected data points from it, regressed a curve that matches (almost exactly 1-(1-x)^0.835), and applied this to signed (-1 to 1 instead of 0 to 1) texCoords by first dividing the texCoords by their distance from the center, applying the equation, then multiplying by the distance to put it all back, and then scaling it up such that the image meets the edges based on how much it’s distorted.

Here’s the curvature effect found in the CRT-Geom / cgwg-CRT-deconstructed / beam4 shaders that I’ve been using:

Here’s crt-geom with distortion matched as close as I could:

Here’s my new curvature shader:

Notice the lack of sharp pinched corners and a less bumped center compared to the first shader.

14 Likes

@torridgristle That is beautiful, look forward to trying this out eventually, lol.

I was playing around with it some last night and it’s very easy to drop into existing shaders, and it looks much more natural. I’ll get some examples pushed up to the repos this evening so people can check it out.

4 Likes

@torridgristle

I don’t really care for curvature, but even I may have to give this a try. Looks much better than what I typically see in shaders. I also appreciate the scientific approach you took. Well done!

I haven’t heard of the latter two. Are these available in Retroarch?

CRT-Geom is an old favorite of mine for being easy to use and looking great. EDIT: In fact, CRT-Geom is still my second-favorite shader after all these years. Only CRT-Aperture is better IMO, providing the best balance between ease of use and objective picture quality.

They’re quark shaders (bsnes/higan). The deconstructed one is just the various bits broken out into individual shaders, while beam4 was a very similar shader from cgwg that includes some beam rise/fall dynamics (doesn’t look noticeably different AFAICT; might be better at higher scales, dunno)

2 Likes

Great, looking forward to play with it. Do you think the glass refraction would have an effect on the perceived curvature?

1 Like

This might be the first curvature shader I would be happy to use :slight_smile: The other ones all just felt off for me.

1 Like

@hunterk I’m sad no curvature, cry cry. :sob::grin: Lol

Is it even possible to have curvature without moire? I think some slight curvature a la torridgristle’s shader could give the image a more analog look and help with immersion, but moire kinda kills it for me :confused:

No, it’s like uneven scanlines: it’s a manifestation of aliasing and you can minimize it but there’s no escaping it. It occurs on actual CRTs, as well, though it’s caused by different things: http://www.displaymate.com/moire.html

4 Likes

Or alternatively (if RetroArch currently supports it) – an odd-numbered sequence of refresh cycles (e.g. 60fps @ 180Hz using 2:1 or 1:2 BFI:Visible ratio), or repeat-refresh (e.g. 60fps @ 240Hz BFI using 2:2 BFI:Visible ratio).

That is an alternative to fix the inversion artifacts too without needing an even-numbered integer scale, for emulators that support these odd BFI ratios (2:1, 1:2, or 2:2) instead of the usual BFI (1:1 50%:50% black:visible ratios). That fixes accidental interactions with software blackframe insertion with inversion/FRC/temporal dither algorithms.

The technical explanation why is moved into this thread.

2 Likes

Yeah, EWA. I haven’t made an EWA version of it yet but it should work fine.