Please show off what crt shaders can do!

Hi @Syh yes you are correct, that the bezel overlay will work at whatever resolution you are running. It will do this by scaling the bezel overlay image with the tube scaling. And I’ll include an oversized bezel so it can be scaled a fair bit while still covering the whole screen.

I do also like the shadertoy of generating a bezel in a pass, so I might add this later so one could have it generated automatically if they prefered.

3 Likes

In the below shot I’m actually maxing out the mask strength with the cgwg dotmask effect while still having scanlines and an adequately bright image (with my lcd backlight maxed out). Pretty cool! Weirdly, no TN panel inversion artifacts are noticeable while the game is running in RA, but if I open the image in GIMP and zoom to 100% the inversion artifacts are very noticeable across the entire screen. The inversion artifacts are still there when the game is running in RA, mind you, but you have to be really looking for it (kinda looks like what my Plasma TV does when operating normally). With the aperture grille pattern the inversion artifacts are painfully obvious in RA if mask strength is higher than 50%.

Which raises the question - is “overlay mix” in the reshade/blendoverlay shader doing the same thing as “mask strength” in CRT-aperture? I just kind of assumed it was the same thing.

pre-edit: what’s the best way to preserve color/tone as you increase the mask strength? Some shaders seem to do this better than others.

without further ado:

2 Likes

With CRT-aperture you can push halation to 0.40 (maximum) to regain color/tone with overlay mix 100% if lower shape and high are 1.0 ,don’t touch diffusion it make it worse. You can obtain this white level.

Here’s a exemple :

1 Like

I think I need to back up and look at my assumptions. Something weird happens to bright colors when I set overlay mix to 100. Check out this screenshot. (you’ll have to zoom in to see what I’m talking about)

now check out this one:

the very first row of pixels is dark, followed by the bright line (2 rows of pixels), followed by the dark line (2 rows of pixels), etc.

So basically the first image is the inverse of what you want; you want pure white to show up as 100% magenta and 100% green, and the space between should be darker. Instead, the white lines are less intense and the dark lines are more intense.

Any idea what’s going on?

It’s not clear to me what “overlay mix” is actually adjusting, and what should be adjusted instead. Basically, 100% white should show up as 100% magenta/green when using that LUT if you’re trying to get as close to a CRT as possible. (on a CRT, white is produced with phosphors that are at 100% R, G and B)

Here are the settings I’m using:

alias0 = ""
alias1 = ""
BRIGHTNESS = "1.000001"
filter_linear0 = "false"
filter_linear1 = "true"
float_framebuffer0 = "false"
float_framebuffer1 = "false"
GAMMA_INPUT = "2.400000"
GAMMA_OUTPUT = "2.200000"
GLOW_DIFFUSION = "0.000000"
GLOW_HALATION = "0.000000"
GLOW_HEIGHT = "0.500000"
GLOW_WIDTH = "0.500000"
LUTHeight = "2.000000"
LUTWidth = "2.000000"
MASK_COLORS = "2.000000"
MASK_SIZE = "1.000000"
MASK_STRENGTH = "0.000000"
mipmap_input0 = "false"
mipmap_input1 = "false"
overlay = "C:\Program Files\RetroArch\shaders\shaders_glsl\reshade\shaders\blendoverlay\aperture_1_2_bgr.png"
overlay_mipmap = "false"
overlay_wrap_mode = "clamp_to_border"
OverlayMix = "1.000000"
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;OverlayMix;LUTWidth;LUTHeight"
scale_type_x0 = "source"
scale_type_y0 = "source"
scale_x0 = "5.000000"
scale_y0 = "5.000000"
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"
shader1 = "C:\Program Files\RetroArch\shaders\shaders_glsl\reshade\shaders\blendoverlay\blendoverlay.glsl"
shaders = "2"
SHARPNESS_EDGES = "1.000000"
SHARPNESS_IMAGE = "2.000000"
srgb_framebuffer0 = "false"
srgb_framebuffer1 = "false"
textures = "overlay"
wrap_mode0 = "clamp_to_border"
wrap_mode1 = "clamp_to_border"

Bad scale, try with these values

scale_x0 = "6.000000"
scale_y0 = "6.000000"
SCANLINE_SIZE_MAX = "1.000000"
SCANLINE_SIZE_MIN = "1.000000"

Or if you really want 0.50 and 1.50 min and max, then put scanline shape to 2.50 with blend overlay

Still the same problem. (the below close up isn’t from the settings you suggested, but still getting the same issue regardless)

Basically, the white lines, if we’re trying to get as close to a crt as possible, should be the ones that are 100% magenta and green. The dark gaps between the white lines should be less intense/bright. In the below close up, it’s actually doing the reverse. In the below image, the 100% magenta/green lines are actually the dark lines. Seems like this would be an easy fix if you know the right variable to adjust, but I think you might actually need to change the shader code. It seems like something is being added instead of subtracted, or something.

Basically, white should be 100% magenta/green and then you should add a certain amount of black to the dark lines. Instead it looks like it’s adding white to the white lines…?

image

EDIT: okay, I can confirm that this is an “issue” with how the blend overlay shader is working. Here is CRT-aperture with the mask strength at 100%, showing the expected behavior:

image

The 100% white lines are 100% magenta/green and the dark lines have a certain % of black added to them. The blend overlay shader instead adds a certain % of white to the white lines. So it’s probably a simple fix for those who know shader coding (I don’t).

I found this in the shader code

float Luminance = 0.299Picture.x + 0.587Picture.y + 0.114*Picture.z;

And this explanation

For images in color spaces such as [Y’UV] and its relatives, which are used in standard color TV and video systems such as [PAL], [SECAM], and [NTSC], a nonlinear [luma]) component ( Y’ ) is calculated directly from gamma-compressed primary intensities as a weighted sum, which, although not a perfect representation of the colorimetric luminance, can be calculated more quickly without the gamma expansion and compression used in photometric/colorimetric calculations. In the [Y’UV] and [Y’IQ] models used by PAL and NTSC, the [rec601] [luma]) ( Y’ ) component is computed as

Y ′ = 0.299 R ′ + 0.587 G ′ + 0.114 B ′

where we use the prime to distinguish these nonlinear values from the sRGB nonlinear values (discussed above) which use a somewhat different gamma compression formula, and from the linear RGB components. The [ITU-R BT.709] standard used for [HDTV] developed by the [ATSC] uses different color coefficients, computing the luma component as

Y ′ = 0.2126 R ′ + 0.7152 G ′ + 0.0722 B ′

Although these are numerically the same coefficients used in sRGB above, the effect is different because here they are being applied directly to gamma-compressed values rather than to the linearized values. The [ITU-R BT.2100] standard for [HDR] television uses yet different coefficients, computing the luma component as

Y ′ = 0.2627 R ′ + 0.6780 G ′ + 0.0593 B ′

Normally these colorspaces are transformed back to nonlinear R’G’B’ before rendering for viewing. To the extent that enough precision remains, they can then be rendered accurately.

But if the luma component Y’ itself is instead used directly as a grayscale representation of the color image, luminance is not preserved: two colors can have the same luma Y’ but different CIE linear luminance Y (and thus different nonlinear Y srgb as defined above) and therefore appear darker or lighter to a typical human than the original color. Similarly, two colors having the same luminance Y (and thus the same Y srgb) will in general have different luma by either of the Y’ luma definitions above.

Or maybe we should just wait for hunterk and forget this long text haha :joy:

2 Likes

lol, I think this is a “wait for hunterk” issue. This stuff is waaay over my head.

@hunterk is there a simple change we can make to the blend overlay shader to make the “overlay mix” parameter work the same as “mask strength” in CRT-Aperture? Or… is there an easy way to add the cgwg dotmask as an option to CRT-Aperture?

1 Like

What you want is a straight multiply. Blend-overlay does screen combines (ala the Photoshop combine method) with some luminance-based stuff (like ProfessorBraun was alluding to) mostly to preserve brightness.

It’s easy/simple to do a multiply action (phosphorlut pass0 is basically just that), but it really kills brightness. (obviously not a problem for Nesguy lol)

I’ve been thinking of how to do the green/magenta masks without external LUTs, so I’ll try to post something about that soon.

EDIT: here’s an unoptimized LUT-less version that does a straight multiply (GLSL only for now):

#version 130
#pragma parameter phosphor_layout "Phosphor Layout" 1.0 1.0 3.0 1.0

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

// vertex 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;

// fragment 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 phosphor_layout;
#else
#define phosphor_layout 1.0
#endif

const vec3 green = vec3(0.7, 1.0, 0.7);
const vec3 magenta = vec3(1.0,0.7,1.0);
const vec3 black = vec3(0.,0.,0.);

// classic aperture
vec3 aperture_weights = mix(magenta, green, floor(mod(gl_FragCoord.x, 2.0)));

// 2x2 shadow mask
vec3 inverse_aperture = mix(green, magenta, floor(mod(gl_FragCoord.x, 2.0)));
vec3 shadow_weights   = mix(aperture_weights, inverse_aperture, floor(mod(gl_FragCoord.y, 2.0)));

// slot mask
// Can't do 2D arrays until version 430, so do this stupid thing instead
// first lay out the horizontal pixels
vec3 slotmask_x1[6] = vec3[](magenta,green,black,magenta,green,black);
vec3 slotmask_x2[6] = vec3[](magenta,green,black,black,black,black);
vec3 slotmask_x3[6] = vec3[](magenta,green,black,magenta,green,black);
vec3 slotmask_x4[6] = vec3[](black,black,black,magenta,green,black);

// find the horizontal index
int slot_index_x = int(floor(mod(gl_FragCoord.x, 6.0)));
int j = slot_index_x; // use a single letter for variable to make comparison easier to read later

// find the vertical index
int slot_index_y = int(floor(mod(gl_FragCoord.y, 4.0)));

// do a big, dumb comparison in place of a 2D array
vec3 slot_weights = (slot_index_y == 1) ? slotmask_x1[j] : (slot_index_y == 2) ? slotmask_x2[j] : (slot_index_y == 3) ? slotmask_x3[j] : slotmask_x4[j];

void main()
{
   vec3 mask_weights = (phosphor_layout == 1.) ? aperture_weights : (phosphor_layout == 2.) ? shadow_weights : slot_weights;
	vec4 screen = vec4(COMPAT_TEXTURE(Texture, vTexCoord).rgb, 1.0);
   FragColor = vec4(screen.rgb * mask_weights, 1.0);
} 
#endif
6 Likes

Good job :man_mechanic: I was able to get this brightness with phosphor layout 1 and 2.

PL 1.0

PL 2.0

PL 3.0

One more think,to have even scanlines with crt-aperture coupled to another passes,you need these values

scale_x0 = "9.000000"
scale_y0 = "9.000000"

I tried 1,2,3....... and 9 was perfect for crt-aperture

Edit: with 3840x2160 resolution integer scale core provided ratio in video settings (retroarch)

2 Likes

Those look very nice with my LCD backlight adjusted to 100%! That slotmask looks surprisingly good at 4k. I might tone down the beam width variation a bit since slotmask CRTs didn’t show quite as much beam width variation as aperture grille CRTs. However, adjusting the beam width parameters in CRT-Aperture seems to do weird stuff to colors and results in clipping/large jumps when viewing a color bars pattern; seems like it’s optimized at the default settings.

Or you can just use “custom” aspect ratio and integer scaling.

EDIT: how do you go about stacking these shaders? Can you post the settings you used for the above shots?

2 Likes

Something I’ve always wanted to capture is the gross smearing of reds (apparently other colors can do it, too, but I’ve only ever seen it with reds) on a failing CRT, so I’ve been playing around with that lately:

6 Likes

I haven’t been able to get this shader to have the intended effect.

If I set CRT-Aperture to scanline shape 1.00 and mask strrength to 100%, this is what it looks like:

image

The white lines are 100% magenta/green and the black lines have a % black added.

This is what I get if I add this shader to CRT-Aperture with the mask strength at 0:

image

:thinking:

Nostalgic! I had totally forgotten about this effect until I visited an arcade the other day and checked out all the old, busted monitors.

1 Like

Try this one (the first one was hardcoded to 30% mask strength, which is probably why you’re getting the faint mask in your second shot):

#version 130
#pragma parameter phosphor_layout "Phosphor Layout" 1.0 1.0 3.0 1.0
#pragma parameter mask_strength "Mask Strength" 0.3 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 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;

// vertex 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;

// fragment 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 phosphor_layout, mask_strength;
#else
#define phosphor_layout 1.0
#define mask_strength 0.3
#endif

vec3 mask_weights(vec2 coord, float mask_strength){
   vec3 weights = vec3(0.,0.,0.);
   vec3 green = vec3(1.-mask_strength, 1.0, 1.-mask_strength);
   vec3 magenta = vec3(1.0,1.-mask_strength,1.0);
   vec3 black = vec3(1.-mask_strength,1.-mask_strength,1.-mask_strength);

   // classic aperture
   vec3 aperture_weights = mix(magenta, green, floor(mod(coord.x, 2.0)));

   // 2x2 shadow mask
   vec3 inverse_aperture = mix(green, magenta, floor(mod(coord.x, 2.0)));
   vec3 shadow_weights   = mix(aperture_weights, inverse_aperture, floor(mod(coord.y, 2.0)));

   // slot mask
   // Can't do 2D arrays until version 430, so do this stupid thing instead
   // first lay out the horizontal pixels in arrays
   vec3 slotmask_x1[6] = vec3[](magenta,green,black,magenta,green,black);
   vec3 slotmask_x2[6] = vec3[](magenta,green,black,black,black,black);
   vec3 slotmask_x3[6] = vec3[](magenta,green,black,magenta,green,black);
   vec3 slotmask_x4[6] = vec3[](black,black,black,magenta,green,black);

   // find the horizontal index
   int slot_index_x = int(floor(mod(coord.x, 6.0)));
   int j = slot_index_x; // use a single letter for variable to make comparison easier to read later

   // find the vertical index
   int slot_index_y = int(floor(mod(coord.y, 4.0)));

   // do a big, dumb comparison in place of a 2D array
   vec3 slot_weights = (slot_index_y == 1) ? slotmask_x1[j] : (slot_index_y == 2) ? slotmask_x2[j] : (slot_index_y == 3) ? slotmask_x3[j] : slotmask_x4[j];
   
   if(phosphor_layout == 1.) weights = aperture_weights;
   else if(phosphor_layout == 2.) weights = shadow_weights;
   else weights = slot_weights;
   
   return weights;
}

void main()
{
   vec3 mask_weights = mask_weights(gl_FragCoord.xy, mask_strength);
	vec4 screen = vec4(COMPAT_TEXTURE(Texture, vTexCoord * 1.0001).rgb, 1.0);
   FragColor = vec4(screen.rgb * mask_weights, 1.0);
} 
#endif

I also made a slang version here:

#version 450

layout(push_constant) uniform Push
{
	vec4 SourceSize;
	vec4 OriginalSize;
	vec4 OutputSize;
	uint FrameCount;
   float phosphor_selector, mask_strength;
} params;

#pragma parameter phosphor_selector "Phosphor Layout" 1.0 1.0 3.0 1.0
#pragma parameter mask_strength "Mask Strength" 0.3 0.0 1.0 0.01

int phosphor_layout = int(params.phosphor_selector);
#define mask_strength params.mask_strength

layout(std140, set = 0, binding = 0) uniform UBO
{
   mat4 MVP;
} global;

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

void main()
{
   gl_Position = global.MVP * Position;
   vTexCoord = TexCoord;
}

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

vec3 mask_weights(vec2 coord, float mask_intensity){
   vec3 weights = vec3(0.,0.,0.);
   vec3 green   = vec3(1.-mask_intensity, 1.0, 1.-mask_intensity);
   vec3 magenta = vec3(1.0,1.-mask_intensity,1.0);
   vec3 black   = vec3(1.-mask_intensity,1.-mask_intensity,1.-mask_intensity);
   
   vec3 aperture_weights = mix(magenta, green, floor(mod(coord.x, 2.0)));

   if(phosphor_layout == 1){
      // classic aperture
      weights  = aperture_weights;
   }

   if(phosphor_layout == 2){
      // 2x2 shadow mask
      vec3 inverse_aperture = mix(green, magenta, floor(mod(coord.x, 2.0)));
      weights               = mix(aperture_weights, inverse_aperture, floor(mod(coord.y, 2.0)));
   }

   if(phosphor_layout == 3){
      // slot mask
      vec3 slotmask[4][6] = {
         {magenta, green, black, magenta, green, black},
         {magenta, green, black, black,   black, black},
         {magenta, green, black, magenta, green, black},
         {black,   black, black, magenta, green, black}
      };

      // find the vertical index
      int j = int(floor(mod(coord.y, 4.0)));

      // find the horizontal index
      int k = int(floor(mod(coord.x, 6.0)));

      // use the indexes to find which color to apply to the current pixel
      weights = slotmask[j][k];
   }

   return weights;
}


void main()
{
   vec3 mask_weights = mask_weights(vTexCoord.xy * params.OutputSize.xy, mask_strength);
	vec4 screen = vec4(texture(Source, vTexCoord * 1.0001).rgb, 1.0);
   FragColor = vec4(screen.rgb * mask_weights, 1.0);
}

It’s much cleaner (and about 50% faster in my testing), thanks to being able to use a 2D array.

Both of these are set up with the mask bits in an easy-to-copy/paste function that you can add to other shaders without too much trouble, to avoid having it as a follow-on pass.

EDITEDIT: you might need to rename the ‘mask_strength’ variable if you add it to something else. I think that’s a pretty generic name that probably has collisions with other shader variable names.

3 Likes

I kept the same settings between each screenshot by laziness but I also have a preset for slotmask.

> shaders = "2"
> shader0 = "shaders_glsl/crt/shaders/crt-aperture.glsl"
> wrap_mode0 = "clamp_to_border"
> mipmap_input0 = "false"
> alias0 = ""
> float_framebuffer0 = "false"
> srgb_framebuffer0 = "false"
> scale_type_x0 = "source"
> scale_x0 = "9.000000"
> scale_type_y0 = "source"
> scale_y0 = "9.000000"
> shader1 = "shaders_glsl/crt/shaders/masks.glsl"
> wrap_mode1 = "clamp_to_border"
> mipmap_input1 = "false"
> alias1 = ""
> float_framebuffer1 = "false"
> srgb_framebuffer1 = "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;phosphor_layout"
> SHARPNESS_IMAGE = "2.000000"
> SHARPNESS_EDGES = "2.000000"
> GLOW_WIDTH = "0.650000"
> GLOW_HEIGHT = "0.650000"
> GLOW_HALATION = "0.390000"
> GLOW_DIFFUSION = "0.010000"
> MASK_COLORS = "2.000000"
> MASK_STRENGTH = "0.000000"
> MASK_SIZE = "1.000000"
> SCANLINE_SIZE_MIN = "1.000000"
> SCANLINE_SIZE_MAX = "1.000000"
> SCANLINE_SHAPE = "1.000000"
> SCANLINE_OFFSET = "0.000000"
> GAMMA_INPUT = "2.500000"
> GAMMA_OUTPUT = "2.200000"
> BRIGHTNESS = "2.000000"
> phosphor_layout = "2.000000"
> textures = "overlay"
> overlay = "shaders_glsl/reshade/shaders/blendoverlay/aperture_1_2_bgr.png"
> overlay_wrap_mode = "clamp_to_border"
> overlay_mipmap = "false"

For aperture like my screenshots above,just change halation value to 29 and scanline min and max to 0.5 ans 1.5, you can also increase diffusion to have a perfect circle glow on bright areas but i don’t know how it looks on your screen so the value is low.

edit: Just saw your post about slang i’m gonna test it

That’s definitely better, but it’s still significantly darker than CRT-Aperture with mask strength at 100%, and white is still not 100% magenta/green, more like 75-80%.

CRT-Aperture mask strength 100%:

New shader mask strength 100% (crt-aperture mask strength at 0):

pre-edit: just saw the bit about changing variable names; that might have something to do with it.

composite its cool … looks better when using it live … sshot is a bit messed up

Seriously, no offense, but how can you play with an image like that?! My eyes are bleeding. Have you ever really seen a crt in action?

1 Like

I tried changing all instances of “mask_strength” to “mask_strengthh” and I got the same result; it’s significantly darker than CRT-Aperture with mask strength at 100% (I made sure I was setting CRT-Aperture’s mask_strength to 0).